package com.google.appengine.codelab;
import static com.google.appengine.api.datastore.FetchOptions.Builder.withLimit;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
//import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
@SuppressWarnings("serial")
public class UserStory12Servlet extends BaseServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doGet(req, resp);
insertEntities();
PrintWriter out = resp.getWriter();
out.println(consulta3());
return;
}
private String consulta3() {
DatastoreService ds = Util.getDatastoreServiceInstance();
Query query = new Query("Fraude");
long total = ds.prepare(query).countEntities(withLimit(1000));
long c1 = countFraudeBetweenValores(new Float(0), new Float(500));
long c2 = countFraudeBetweenValores(new Float(500.01), new Float(2000));
long c3 = countFraudeBetweenValores(new Float(2000.01), new Float(5000));
long c4 = countFraudeBetweenValores(new Float(5000.01), new Float(0));
String s = "{\"data\": [{\"interval1\" : \"" +
"%d - %.2f%%\",\"interval2\" : \"" +
"%d - %.2f%%\",\"interval3\" : \"" +
"%d - %.2f%%\",\"interval4\" : \"" +
"%d - %.2f%%\"}]}";
return String.format(s,
c1, new Float((c1 * 100) / (double) total),
c2, new Float((c2 * 100) / (double) total),
c3, new Float((c3 * 100) / (double) total),
c4, new Float((c4 * 100) / (double) total));
}
private void insertEntities() {
Localidade.createOrUpdateLocalidade("1", new Float(-13.58), new Float(-51.85), "", "", "", "", "");
Localidade.createOrUpdateLocalidade("2", new Float(-15.78), new Float(-47.92), "", "", "", "", "");
Cliente.createOrUpdateCliente("1", "joao", "Joao", "Costa", "", "", "", "1");
Cliente.createOrUpdateCliente("2", "jose", "JOSE", "SILVA", "", "", "", "1");
Cliente.createOrUpdateCliente("3", "maria", "MARIA", "BENEDITA", "", "", "", "1");
Estabelecimento.createOrUpdateEstabelecimento("1", "", "ESTABELECIMENTO1", "1");
Estabelecimento.createOrUpdateEstabelecimento("2", "", "ESTABELECIMENTO2", "2");
Midia.createOrUpdateMidia("1", "MIDIA", "", "", "", "1");
Midia.createOrUpdateMidia("2", "MIDIA", "", "", "", "2");
Midia.createOrUpdateMidia("3", "MIDIA", "", "", "", "3");
Transacao.createOrUpdateTransacao("1", "", new Double(10), "20130501", "", "1", "1", "1", "1");
Transacao.createOrUpdateTransacao("2", "", new Double(10), "20130501", "", "1", "2", "2", "1");
Transacao.createOrUpdateTransacao("3", "", new Double(500.1), "20130501", "", "1", "2", "2", "1");
Transacao.createOrUpdateTransacao("4", "", new Double(25), "20130501", "", "1", "2", "2", "1");
Transacao.createOrUpdateTransacao("5", "", new Double(80), "20130501", "", "1", "3", "3", "1");
Transacao.createOrUpdateTransacao("6", "", new Double(500), "20130501", "", "1", "3", "3", "2");
Fraude.createOrUpdateFraude("1", "FRAUDE1", "TIPO1", "", "", "2");
Fraude.createOrUpdateFraude("2", "FRAUDE2", "TIPO", "", "", "3");
Fraude.createOrUpdateFraude("3", "FRAUDE3", "TIPO1", "", "", "6");
}
public static long countFraudeBetweenValores(Float iniValue, Float finValue) {
FiltroFaixaValores filtrosView = new FiltroFaixaValores();
Iterable<Entity> transacoes = getTransacoesBetweenValores(iniValue, finValue, filtrosView);
long count = 0;
for (Entity transacao : transacoes) {
if (transacao != null) {
count += getFraudesByTransId((String)transacao.getProperty("trans_id"),filtrosView).countEntities(withLimit(1000));
}
}
return count;
}
public static long countFraudeByLocalidadeBetweenValores(Float latitude, Float longitude,
Float iniValue, Float finValue) {
Iterable<Entity> localidades = getLocalidadeByLatitudeLongitude(latitude, longitude);
long count = 0;
for (Entity localidade : localidades) {
if (localidade != null) {
Iterable<Entity> transacoes = getTransacoesByLocalidadeBetweenValores(
(String)localidade.getProperty("localidade_id"), iniValue, finValue);
for (Entity transacao : transacoes) {
if (transacao != null) {
count += getFraudesByTransId((String)transacao.getProperty("trans_id"),new FiltroFaixaValores()).countEntities(withLimit(1000));
}
}
}
}
return count;
}
private static PreparedQuery getFraudesByTransId(String trans_id, FiltroFaixaValores filtro) {
DatastoreService ds = Util.getDatastoreServiceInstance();
Query query = new Query("Fraude");
List<Filter> filtros = new ArrayList<Filter>();
filtros.add( new FilterPredicate("trans_id", FilterOperator.EQUAL, trans_id) );
if( ! filtro.getFraude_type().isEmpty() ){
filtros.add( new FilterPredicate("fraude_type", FilterOperator.EQUAL, filtro.getFraude_type()) );
}
if( filtro.getFraude_data_inicial() != null ){
filtros.add( new FilterPredicate("fraude_data_deteccao", FilterOperator.GREATER_THAN_OR_EQUAL, Common.dateToInt(filtro.getFraude_data_inicial()) ) );
}
if( filtro.getFraude_data_final() != null && filtro.getFraude_data_final().after(filtro.getFraude_data_inicial()) ){
filtros.add( new FilterPredicate("fraude_data_deteccao", FilterOperator.LESS_THAN_OR_EQUAL, Common.dateToInt(filtro.getFraude_data_final()) ) );
}
query.setFilter( filtros.size() == 1 ? filtros.get(0) : CompositeFilterOperator.and(filtros) );
return ds.prepare(query);
}
public static Iterable<Entity> getFraudeByType(String fraude_type) {
return Util.listEntities("Fraude", "fraude_type", fraude_type);
}
public static Iterable<Entity> getLocalidadeByLatitudeLongitude(Float latitude,
Float longitude) {
DatastoreService ds = Util.getDatastoreServiceInstance();
Query query = new Query("Localidade");
Filter f1 = new FilterPredicate("localidade_latitude", FilterOperator.EQUAL, latitude);
Filter f2 = new FilterPredicate("localidade_longitude", FilterOperator.EQUAL, longitude);
Filter fc = CompositeFilterOperator.and(f1, f2);
query.setFilter(fc);
return ds.prepare(query).asIterable();
}
public static List<String> getNomeClienteByFraudeBetweenValores(Float iniValue,
Float finValue) {
DatastoreService ds = Util.getDatastoreServiceInstance();
Iterable<Entity> transacoes = getTransacoesBetweenValores(iniValue, finValue, new FiltroFaixaValores());
List<String> result = new ArrayList<String>();
for (Entity transacao : transacoes) {
if (transacao != null) {
Query query = new Query("Fraude");
Filter filter = new FilterPredicate("trans_id", FilterOperator.EQUAL,
transacao.getKey());
query.setFilter(filter);
if (ds.prepare(query).countEntities(withLimit(1000)) != 0) {
query = new Query("Cliente");
filter = new FilterPredicate(Entity.KEY_RESERVED_PROPERTY,
FilterOperator.EQUAL, transacao.getProperty("cliente_id"));
query.setFilter(filter);
Entity cliente = ds.prepare(query).asSingleEntity();
if (cliente != null) {
String s = cliente.getProperty("cliente_firstName") + " " +
cliente.getProperty("cliente_lastName");
if (!result.contains(s)) result.add(s);
}
}
}
}
return result;
}
public static List<Entity> getTransacoesBetweenValores(Float iniValue, Float finValue, FiltroFaixaValores filtrosView)
{
DatastoreService ds = Util.getDatastoreServiceInstance();
Query query = new Query("Transacao");
List<Filter> filtros = new ArrayList<Filter>();
filtros.add( new FilterPredicate("trans_price", FilterOperator.GREATER_THAN_OR_EQUAL, iniValue) );
if (finValue != null && finValue >= iniValue){
filtros.add( new FilterPredicate("trans_price", FilterOperator.LESS_THAN_OR_EQUAL, finValue) );
}
if( ! filtrosView.getTrans_type().isEmpty() ){
filtros.add( new FilterPredicate("trans_type", FilterOperator.EQUAL, filtrosView.getTrans_type() ));
}
query.setFilter( filtros.size() == 1 ? filtros.get(0) : CompositeFilterOperator.and(filtros) );
List<Entity> transacoes = new ArrayList<Entity>();
for( Entity transacao : ds.prepare(query).asIterable() )
{
if( filtrosView.getTrans_data_inicial() != null && Common.dateToInt(filtrosView.getTrans_data_inicial()) > (Integer.parseInt((String)transacao.getProperty("trans_data")))){
continue;
}
if( filtrosView.getTrans_data_final() != null ){
Integer dataFinal = Common.dateToInt(filtrosView.getTrans_data_final());
if( dataFinal > Common.dateToInt(filtrosView.getTrans_data_inicial()) && dataFinal < (Integer.parseInt((String)transacao.getProperty("trans_data"))) ){
continue;
}
}
Entity localidade = Localidade.getSingleLocalidade((String) transacao.getProperty("localidade_id"));
if( ! filtrosView.getPais().isEmpty() && ! filtrosView.getPais().equals(localidade.getProperty("localidade_country"))){
continue;
}
if( ! filtrosView.getEstado().isEmpty() && ! filtrosView.getEstado().equals(localidade.getProperty("localidade_state"))){
continue;
}
if( ! filtrosView.getCidade().isEmpty() && ! filtrosView.getCidade().equals(localidade.getProperty("localidade_city"))){
continue;
}
Entity midia = Midia.getSingleMidia((String) localidade.getProperty("midia_id") );
if( ! filtrosView.getMidia_bandeira().isEmpty() && ! midia.getProperty("midia_bandeira").toString().equals(filtrosView.getMidia_bandeira()) ){
continue;
}
transacoes.add(transacao);
}
return transacoes;
}
public static Iterable<Entity> getTransacoesByLocalidadeBetweenValores(String localidade_id,
Float iniValue, Float finValue) {
DatastoreService ds = Util.getDatastoreServiceInstance();
Query query = new Query("Transacao");
Filter f1 = new FilterPredicate("trans_price", FilterOperator.GREATER_THAN_OR_EQUAL,
iniValue);
Filter f2 = new FilterPredicate("trans_price", FilterOperator.LESS_THAN_OR_EQUAL,
finValue);
Filter f3 = new FilterPredicate("localidade_id", FilterOperator.EQUAL, localidade_id);
Filter fc = CompositeFilterOperator.and(f1, f2, f3);
query.setFilter(fc);
return ds.prepare(query).asIterable();
}
/**
* @author cassiano
*
* Requirement: "The system shall filter frauds by multiple parameters."
* Specification: filter by type, fraud date, transaction date, transaction type,
* card brand, geographic location and values range;
*/
public static List<Entity> getFraudesByParameters(String fraude_type,
String Fraude_data_inicial, String fraude_data_final, String trans_data_inicial,
String trans_data_final, String trans_type, String midia_bandeira,
String pais, String estado, String cidade, String trans_price_inicial, String trans_price_final) {
FiltroFaixaValores filtrosView = new FiltroFaixaValores(fraude_type,
getData(Fraude_data_inicial),
getData(fraude_data_final),
getData(trans_data_inicial),
getData(trans_data_final),
trans_type, midia_bandeira, pais, estado, cidade);
Iterable<Entity> transacoes = getTransacoesBetweenValores(new Float(trans_price_inicial), new Float(trans_price_final), filtrosView);
List<Entity> result = new ArrayList<Entity>();
for (Entity transacao : transacoes) {
result.addAll( getFraudesByTransId((String)transacao.getProperty("trans_id"),filtrosView).asList(FetchOptions.Builder.withDefaults()) );
}
return result;
}
private static Date getData(String data){
if( data == null || data.isEmpty() ){
return null;
}
return Common.cDate(data);
}
/**
* @author cassiano
*
* Testing requisite: "The system shall get transaction information by filtered frauds"
* Specification: return transactions related to the given fraud list
*/
public static Iterable<Entity> getTransacoesByFraudesList(Iterable<Entity> fraudes) {
//TODO
return null;
}
}