diff --git a/old/pmdsys/src/app/app.component.ts b/old/pmdsys/src/app/app.component.ts
index f410c64..e2de314 100644
--- a/old/pmdsys/src/app/app.component.ts
+++ b/old/pmdsys/src/app/app.component.ts
@@ -1,12 +1,12 @@
-import { Component } from '@angular/core';
-import { Platform } from 'ionic-angular';
-import { StatusBar, Splashscreen } from 'ionic-native';
+import { Component } from "@angular/core";
+import { Platform } from "ionic-angular";
+import { StatusBar, Splashscreen } from "ionic-native";
-import { TabsPage } from '../pages/tabs/tabs';
+import { TabsPage } from "../pages/tabs/tabs";
@Component({
- templateUrl: 'app.html'
+ templateUrl: "app.html"
})
export class MyApp {
rootPage = TabsPage;
diff --git a/old/pmdsys/src/app/app.module.ts b/old/pmdsys/src/app/app.module.ts
index 3064473..5baae09 100644
--- a/old/pmdsys/src/app/app.module.ts
+++ b/old/pmdsys/src/app/app.module.ts
@@ -1,10 +1,10 @@
-import { NgModule, ErrorHandler } from '@angular/core';
-import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
-import { MyApp } from './app.component';
-import { AboutPage } from '../pages/about/about';
-import { ContactPage } from '../pages/contact/contact';
-import { HomePage } from '../pages/home/home';
-import { TabsPage } from '../pages/tabs/tabs';
+import { NgModule, ErrorHandler } from "@angular/core";
+import { IonicApp, IonicModule, IonicErrorHandler } from "ionic-angular";
+import { MyApp } from "./app.component";
+import { AboutPage } from "../pages/about/about";
+import { ContactPage } from "../pages/contact/contact";
+import { HomePage } from "../pages/home/home";
+import { TabsPage } from "../pages/tabs/tabs";
@NgModule({
declarations: [
diff --git a/old/pmdsys/src/app/main.ts b/old/pmdsys/src/app/main.ts
index 6af7a5b..9c5532a 100644
--- a/old/pmdsys/src/app/main.ts
+++ b/old/pmdsys/src/app/main.ts
@@ -1,5 +1,5 @@
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
-import { AppModule } from './app.module';
+import { AppModule } from "./app.module";
platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/old/pmdsys/src/pages/about/about.ts b/old/pmdsys/src/pages/about/about.ts
index 1b4c5ad..0c46cff 100644
--- a/old/pmdsys/src/pages/about/about.ts
+++ b/old/pmdsys/src/pages/about/about.ts
@@ -1,10 +1,10 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
-import { NavController } from 'ionic-angular';
+import { NavController } from "ionic-angular";
@Component({
- selector: 'page-about',
- templateUrl: 'about.html'
+ selector: "page-about",
+ templateUrl: "about.html"
})
export class AboutPage {
diff --git a/old/pmdsys/src/pages/contact/contact.ts b/old/pmdsys/src/pages/contact/contact.ts
index a344720..a5c40de 100644
--- a/old/pmdsys/src/pages/contact/contact.ts
+++ b/old/pmdsys/src/pages/contact/contact.ts
@@ -1,10 +1,10 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
-import { NavController } from 'ionic-angular';
+import { NavController } from "ionic-angular";
@Component({
- selector: 'page-contact',
- templateUrl: 'contact.html'
+ selector: "page-contact",
+ templateUrl: "contact.html"
})
export class ContactPage {
diff --git a/old/pmdsys/src/pages/home/home.ts b/old/pmdsys/src/pages/home/home.ts
index e9f7e6a..5d93db4 100644
--- a/old/pmdsys/src/pages/home/home.ts
+++ b/old/pmdsys/src/pages/home/home.ts
@@ -1,10 +1,10 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
-import { NavController } from 'ionic-angular';
+import { NavController } from "ionic-angular";
@Component({
- selector: 'page-home',
- templateUrl: 'home.html'
+ selector: "page-home",
+ templateUrl: "home.html"
})
export class HomePage {
diff --git a/old/pmdsys/src/pages/tabs/tabs.ts b/old/pmdsys/src/pages/tabs/tabs.ts
index a95cdf4..032c8d0 100644
--- a/old/pmdsys/src/pages/tabs/tabs.ts
+++ b/old/pmdsys/src/pages/tabs/tabs.ts
@@ -1,11 +1,11 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
-import { HomePage } from '../home/home';
-import { AboutPage } from '../about/about';
-import { ContactPage } from '../contact/contact';
+import { HomePage } from "../home/home";
+import { AboutPage } from "../about/about";
+import { ContactPage } from "../contact/contact";
@Component({
- templateUrl: 'tabs.html'
+ templateUrl: "tabs.html"
})
export class TabsPage {
// this tells the tabs component which Pages
diff --git a/package.json b/package.json
index 4a9185a..d0fcfc8 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"@ionic-native/toast": "^3.6.1",
"@ionic/storage": "^2.0.1",
"@types/node": "^7.0.18",
+ "chart.js": "^2.6.0",
"ionic-angular": "^3.2.1",
"ionic-orm": "0.0.5",
"ionic-typeorm": "^0.0.15",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 9f45ab8..1957da9 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -21,6 +21,10 @@ import { PageListaCompras } from '../pages/ListaCompras/main';
import { PageFormCompras } from '../pages/FormCompras/main';
import { PageListaItensCompra } from '../pages/ListaItensCompra/main';
import { PageFormItensCompra } from '../pages/FormItensCompra/main';
+import { PageListaPrecos } from '../pages/ListaPrecos/main';
+import { PageFormPrecos } from '../pages/FormPrecos/main';
+import { PageRelatorioEscolhe } from '../pages/RelatorioEscolhe/main';
+import { PageRelatorioExibe } from '../pages/RelatorioExibe/main';
import { OrmDatabase } from '../persistence/OrmDatabase.service';
import { Relatorios } from '../providers/Relatorios.service';
@@ -45,6 +49,10 @@ import { CrudSupermercado } from '../providers/CrudSupermercado.service';
PageFormCompras,
PageListaItensCompra,
PageFormItensCompra,
+ PageListaPrecos,
+ PageFormPrecos,
+ PageRelatorioEscolhe,
+ PageRelatorioExibe,
],
imports: [
BrowserModule,
@@ -67,6 +75,10 @@ import { CrudSupermercado } from '../providers/CrudSupermercado.service';
PageFormCompras,
PageListaItensCompra,
PageFormItensCompra,
+ PageListaPrecos,
+ PageFormPrecos,
+ PageRelatorioEscolhe,
+ PageRelatorioExibe,
],
providers: [
StatusBar,
@@ -82,6 +94,7 @@ import { CrudSupermercado } from '../providers/CrudSupermercado.service';
CrudNecessidade,
CrudPlanejamento,
CrudSupermercado,
+ PageRelatorioExibe,
]
})
export class AppModule { }
diff --git a/src/app/app.scss b/src/app/app.scss
index a967d6f..bf7ab2c 100644
--- a/src/app/app.scss
+++ b/src/app/app.scss
@@ -14,3 +14,10 @@
// To declare rules for a specific mode, create a child rule
// for the .md, .ios, or .wp mode classes. The mode class is
// automatically applied to the
element in the app.
+
+.deleteToast{
+ color: #cc3333 !important;
+}
+.cancelToast{
+ color: #387ef5 !important;
+}
diff --git a/src/entities/_entidadeAbstrata.ts b/src/entities/_entidadeAbstrata.ts
index 357bac5..c4d19f9 100644
--- a/src/entities/_entidadeAbstrata.ts
+++ b/src/entities/_entidadeAbstrata.ts
@@ -1 +1,3 @@
-export abstract class EntidadeAbstrata {}
+export abstract class EntidadeAbstrata {
+ abstract id: number;
+}
diff --git a/src/pages/FormPrecos/main.spec.ts b/src/pages/FormPrecos/main.spec.ts
new file mode 100644
index 0000000..293864c
--- /dev/null
+++ b/src/pages/FormPrecos/main.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, async } from '@angular/core/testing';
+import { TestUtils } from '../../test';
+import { PageFormPrecos } from './main';
+
+let fixture: ComponentFixture = null;
+let instance: any = null;
+
+declare var describe: any;
+declare var it: any;
+declare var expect: any;
+declare var beforeEach: any;
+
+describe('Pages: Forms: Precos', () => {
+ beforeEach(async(() => TestUtils.beforeEachCompiler([PageFormPrecos]).then(compiled => {
+ fixture = compiled.fixture;
+ instance = compiled.instance;
+ })));
+
+ it('should create the page', async(() => {
+ expect(instance).toBeTruthy();
+ }));
+});
diff --git a/src/pages/FormPrecos/main.ts b/src/pages/FormPrecos/main.ts
new file mode 100644
index 0000000..cd0a12c
--- /dev/null
+++ b/src/pages/FormPrecos/main.ts
@@ -0,0 +1,32 @@
+import { Component } from '@angular/core';
+import { NavController } from 'ionic-angular';
+import { NavParams } from 'ionic-angular';
+import { ToastController } from 'ionic-angular';
+import { PageForm } from '../generico_form/main';
+import { Consulta } from '../../entities/Consulta';
+
+@Component({
+ selector: 'page-form',
+ templateUrl: '../generico_form/main.html'
+})
+export class PageFormPrecos extends PageForm {
+ constructor(
+ public navCtrl: NavController,
+ public navParams: NavParams,
+ public toastCtrl: ToastController,
+ ){
+ super(navCtrl, navParams, toastCtrl);
+ console.log(this.editing)
+ this.postSuper();
+ }
+ public textOption(field: string, item: any): string{ return ''; };
+ public titulo: string = "preço";
+ public fields: object[] = [
+ {
+ type: 'number',
+ label: 'Preco unitário',
+ entity: 'preco',
+ verifywith: 'gtz'
+ },
+ ];
+}
diff --git a/src/pages/ListaCompras/main.ts b/src/pages/ListaCompras/main.ts
index e9b2e46..8f0520a 100644
--- a/src/pages/ListaCompras/main.ts
+++ b/src/pages/ListaCompras/main.ts
@@ -10,6 +10,8 @@ import { CrudSupermercado } from '../../providers/CrudSupermercado.service';
import { PageLista } from '../generico_lista/main';
import { PageFormCompras } from '../FormCompras/main';
import { PageListaItensCompra } from '../ListaItensCompra/main';
+import { PageListaPrecos } from '../ListaPrecos/main';
+import { PageRelatorioEscolhe } from '../RelatorioEscolhe/main';
@Component({
selector: 'page-lista',
@@ -48,7 +50,9 @@ export class PageListaCompras extends PageLista {
role: 'manage',
icon: 'cash',
handler: () => {
- this.navCtrl.setRoot(PageListaCompras)
+ this.navCtrl.push(PageListaPrecos,{
+ 'sujeito': this.getClicado()
+ })
}
})
this.contextoExibe['personalizado'].push({
@@ -56,7 +60,9 @@ export class PageListaCompras extends PageLista {
role: 'manage',
icon: 'cart',
handler: () => {
- this.navCtrl.setRoot(PageListaCompras)
+ this.navCtrl.push(PageRelatorioEscolhe,{
+ 'sujeito': this.getClicado()
+ })
}
})
}
diff --git a/src/pages/ListaPrecos/main.spec.ts b/src/pages/ListaPrecos/main.spec.ts
new file mode 100644
index 0000000..2347d0f
--- /dev/null
+++ b/src/pages/ListaPrecos/main.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, async } from '@angular/core/testing';
+import { TestUtils } from '../../test';
+import { PageListaPrecos } from './main';
+
+let fixture: ComponentFixture = null;
+let instance: any = null;
+
+declare var describe: any;
+declare var it: any;
+declare var expect: any;
+declare var beforeEach: any;
+
+describe('Pages: Listas: Precos', () => {
+ beforeEach(async(() => TestUtils.beforeEachCompiler([PageListaPrecos]).then(compiled => {
+ fixture = compiled.fixture;
+ instance = compiled.instance;
+ })));
+
+ it('should create the page', async(() => {
+ expect(instance).toBeTruthy();
+ }));
+});
diff --git a/src/pages/ListaPrecos/main.ts b/src/pages/ListaPrecos/main.ts
new file mode 100644
index 0000000..d188fb3
--- /dev/null
+++ b/src/pages/ListaPrecos/main.ts
@@ -0,0 +1,146 @@
+import { Component } from '@angular/core';
+import { NavController } from 'ionic-angular';
+import { NavParams } from 'ionic-angular';
+import { ActionSheetController } from 'ionic-angular';
+import { AlertController } from 'ionic-angular';
+import { LoadingController } from 'ionic-angular';
+import { Toast } from "@ionic-native/toast";
+import { Necessidade } from '../../entities/Necessidade';
+import { Planejamento } from '../../entities/Planejamento';
+import { Consulta } from '../../entities/Consulta';
+import { CrudNecessidade } from '../../providers/CrudNecessidade.service';
+import { CrudPlanejamento } from '../../providers/CrudPlanejamento.service';
+import { CrudSupermercado } from '../../providers/CrudSupermercado.service';
+import { CrudConsulta } from '../../providers/CrudConsulta.service';
+import { PageListacolapsavel } from '../generico_lista_colapsavel/main';
+import { PageFormPrecos } from '../FormPrecos/main';
+
+@Component({
+ selector: 'page-lista',
+ templateUrl: '../generico_lista_colapsavel/main.html'
+})
+export class PageListaPrecos extends PageListacolapsavel {
+ constructor(
+ public navCtrl: NavController,
+ public navParams: NavParams,
+ public actionSheetCtrl: ActionSheetController,
+ public alert: AlertController,
+ public toast: Toast,
+ public loadingCtrl: LoadingController,
+ public necessidadeCrud: CrudNecessidade,
+ public consultaCrud: CrudConsulta,
+ public planejamentoCrud: CrudPlanejamento,
+ public supermercadoCrud: CrudSupermercado,
+ ){
+ super(
+ navCtrl,
+ navParams,
+ actionSheetCtrl,
+ alert,
+ toast,
+ loadingCtrl,
+ necessidadeCrud,
+ consultaCrud,
+ );
+ this.planejamento = navParams.get('sujeito')
+ this.externosMonitorados = (this.planejamento).necessidades
+ }
+ public planejamento: Planejamento;
+ public textos: object = {
+ "titulo": "Anotar preços",
+ };
+ public iconeI: string = 'cart';
+ public itemField: string = 'consultas';
+ public textoExterno(item: Necessidade):string{
+ return (item.produto || {nome:''}).nome
+ }
+ public textoInterno(item: Consulta):string{
+ return (item.supermercado || {nome:''}).nome
+ }
+ public posTextoExterno(item: Necessidade):string{
+ let consultas: number = 0
+ for(let consulta of item.consultas){
+ if(consulta.preco>0){
+ consultas+=1
+ }
+ }
+ return consultas+' de '+item.consultas.length+' consultas'
+ }
+ public posTextoInterno(item: Consulta):string{
+ return ((item.necessidade || {quantidade:'???'}).quantidade)+' \u00d7 '+String((item.preco || '???'))
+ }
+ public ordenaExibicaoInterno(items: Consulta[]):Consulta[]{
+ items.sort((a, b) => {
+ if ((a.supermercado || {nome:''}).nome > (b.supermercado || {nome:''}).nome) { return 1; }
+ if ((a.supermercado || {nome:''}).nome < (b.supermercado || {nome:''}).nome) { return -1; }
+ return 0;
+ })
+ return items;
+ }
+ public ordenaExibicaoExterno(items: Necessidade[]):Necessidade[]{
+ items.sort((a, b) => {
+ if ((a.produto || {nome:''}).nome > (b.produto || {nome:''}).nome) { return 1; }
+ if ((a.produto || {nome:''}).nome < (b.produto || {nome:''}).nome) { return -1; }
+ if (a.quantidade > b.quantidade) { return 1; }
+ if (a.quantidade < b.quantidade) { return -1; }
+ return 0;
+ })
+ return items;
+ }
+ public clickInterno(item: Consulta){
+ this.navCtrl.push(
+ PageFormPrecos,
+ {
+ sujeito: item,
+ crud: this.crudInterno,
+ selecionaveis: {},
+ },
+ )
+ }
+ beforeRefreshList():Promise{
+ return new Promise((resolve, reject)=>{
+ this.planejamentoCrud.recarregarUm(this.planejamento).then(planejamento=>{
+ this.planejamento = planejamento
+ this.necessidadeCrud.recarregarAlguns(planejamento.necessidades).then(necessidades => {
+ this.items = necessidades
+ let consultas: Consulta[] = []
+ for(let necessidade of necessidades){
+ for(let consulta of necessidade.consultas){
+ consultas.push(consulta)
+ }
+ }
+ this.consultaCrud.recarregarAlguns(consultas).then(consultas => {
+ let consultasId: {[id: number]: Array;} = {}
+ for(let consulta of consultas){
+ if(typeof(consultasId[(consulta.necessidade || {id:0}).id])==='undefined'){
+ consultasId[(consulta.necessidade || {id:0}).id]=[]
+ }
+ consultasId[(consulta.necessidade || {id:0}).id].push(
+ (consulta.supermercado || {id:0}).id
+ )
+ }
+ this.supermercadoCrud.recarregarAlguns(this.planejamento.supermercados).then(supermercados=>{
+ let promises: Promise[] = []
+ for(let necessidade of necessidades){
+ for(let supermercado of supermercados){
+ if(
+ typeof(consultasId[necessidade.id])==='undefined'
+ ||
+ consultasId[necessidade.id].indexOf(supermercado.id)===-1
+ ){
+ let consulta: Consulta = this.consultaCrud.criar()
+ consulta.necessidade = necessidade
+ consulta.supermercado = supermercado
+ consulta.preco = 0
+ promises.push(this.consultaCrud.salvar(consulta))
+ }
+ }
+ }
+ Promise.all(promises).then(resolve,reject)
+ },reject)
+ },reject)
+ },reject)
+ },reject)
+ })
+ }
+}
diff --git a/src/pages/RelatorioEscolhe/main.html b/src/pages/RelatorioEscolhe/main.html
new file mode 100644
index 0000000..93a7956
--- /dev/null
+++ b/src/pages/RelatorioEscolhe/main.html
@@ -0,0 +1,28 @@
+
+
+
+ Ir às compras
+
+
+
+
+
+
+
+
+ ...no menor preço...
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/RelatorioEscolhe/main.scss b/src/pages/RelatorioEscolhe/main.scss
new file mode 100644
index 0000000..bdff159
--- /dev/null
+++ b/src/pages/RelatorioEscolhe/main.scss
@@ -0,0 +1,17 @@
+page-inicio {
+ .fundoEspecial{
+ background: color($colors, logotipoFundo, secondary);
+ background: linear-gradient(to right, color($colors, logotipoFundo, secondary), $background-color);
+ border-width: 1pt;
+ border-style: solid;
+ border-image: linear-gradient(to right, color($colors, logotipoFundoEscuroEscuro, secondary), $background-color) 100% 1;
+ border-left-style: none;
+ border-right-style: none;
+ }
+ .noHSpace{
+ padding-left: 0px !important;
+ padding-right: 0px !important;
+ margin-left: 0px !important;
+ margin-right: 0px !important;
+ }
+}
diff --git a/src/pages/RelatorioEscolhe/main.spec.ts b/src/pages/RelatorioEscolhe/main.spec.ts
new file mode 100644
index 0000000..a45fa80
--- /dev/null
+++ b/src/pages/RelatorioEscolhe/main.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, async } from '@angular/core/testing';
+import { TestUtils } from '../../test';
+import { PageRelatorioEscolhe } from './main';
+
+let fixture: ComponentFixture = null;
+let instance: any = null;
+
+declare var describe: any;
+declare var it: any;
+declare var expect: any;
+declare var beforeEach: any;
+
+describe('Pages: Relatorio: Escolhe', () => {
+
+ beforeEach(async(() => TestUtils.beforeEachCompiler([PageRelatorioEscolhe]).then(compiled => {
+ fixture = compiled.fixture;
+ instance = compiled.instance;
+ })));
+
+ it('should create the start page', async(() => {
+ expect(instance).toBeTruthy();
+ }));
+
+});
diff --git a/src/pages/RelatorioEscolhe/main.ts b/src/pages/RelatorioEscolhe/main.ts
new file mode 100644
index 0000000..0a45f5b
--- /dev/null
+++ b/src/pages/RelatorioEscolhe/main.ts
@@ -0,0 +1,59 @@
+import { Component } from '@angular/core';
+import { NavController } from 'ionic-angular';
+import { NavParams } from 'ionic-angular';
+import { Consulta } from '../../entities/Consulta';
+import { Planejamento } from '../../entities/Planejamento';
+import { Relatorios } from '../../providers/Relatorios.service';
+
+import { PageRelatorioExibe } from '../RelatorioExibe/main'
+
+@Component({
+ selector: 'page-inicio',
+ templateUrl: 'main.html'
+})
+export class PageRelatorioEscolhe {
+ constructor(
+ public navCtrl: NavController,
+ public navParams: NavParams,
+ public relatorioService: Relatorios,
+ ){
+ this.planejamento = this.navParams.get('sujeito')
+ }
+ planejamento: Planejamento;
+ menorPrecoMedio(){
+ this.relatorioService.menorPrecoMedio(
+ this.planejamento
+ ).then(
+ (consultas:Consulta[]) => {
+ this.navCtrl.push(PageRelatorioExibe,{
+ titulo: 'O menor preço médio',
+ consultas: consultas,
+ })
+ }
+ )
+ }
+ menorPrecoUm(){
+ this.relatorioService.menorPrecoEmUmSupermercado(
+ this.planejamento
+ ).then(
+ (consultas:Consulta[]) => {
+ this.navCtrl.push(PageRelatorioExibe,{
+ titulo: 'O mais barato',
+ consultas: consultas,
+ })
+ }
+ )
+ }
+ menorPrecoTodos(){
+ this.relatorioService.menorPrecoEmTodosSupermercados(
+ this.planejamento
+ ).then(
+ (consultas:Consulta[]) => {
+ this.navCtrl.push(PageRelatorioExibe,{
+ titulo: 'O menor orçamento',
+ consultas: consultas,
+ })
+ }
+ )
+ }
+}
diff --git a/src/pages/RelatorioExibe/main.spec.ts b/src/pages/RelatorioExibe/main.spec.ts
new file mode 100644
index 0000000..40a0016
--- /dev/null
+++ b/src/pages/RelatorioExibe/main.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, async } from '@angular/core/testing';
+import { TestUtils } from '../../test';
+import { PageRelatorioExibe } from './main';
+
+let fixture: ComponentFixture = null;
+let instance: any = null;
+
+declare var describe: any;
+declare var it: any;
+declare var expect: any;
+declare var beforeEach: any;
+
+describe('Pages: Relatorios: Exibe', () => {
+ beforeEach(async(() => TestUtils.beforeEachCompiler([PageRelatorioExibe]).then(compiled => {
+ fixture = compiled.fixture;
+ instance = compiled.instance;
+ })));
+
+ it('should create the page', async(() => {
+ expect(instance).toBeTruthy();
+ }));
+});
diff --git a/src/pages/RelatorioExibe/main.ts b/src/pages/RelatorioExibe/main.ts
new file mode 100644
index 0000000..473f729
--- /dev/null
+++ b/src/pages/RelatorioExibe/main.ts
@@ -0,0 +1,129 @@
+import { Component } from '@angular/core';
+import { NavController } from 'ionic-angular';
+import { NavParams } from 'ionic-angular';
+import { ActionSheetController } from 'ionic-angular';
+import { AlertController } from 'ionic-angular';
+import { LoadingController } from 'ionic-angular';
+import { Toast } from "@ionic-native/toast";
+import { Consulta } from '../../entities/Consulta';
+import { Necessidade } from '../../entities/Necessidade';
+import { CrudProduto } from '../../providers/CrudProduto.service';
+import { CrudConsulta } from '../../providers/CrudConsulta.service';
+import { CrudNecessidade } from '../../providers/CrudNecessidade.service';
+import { PageLista } from '../generico_lista/main';
+
+@Component({
+ selector: 'page-lista',
+ templateUrl: '../generico_lista/main.html'
+})
+export class PageRelatorioExibe extends PageLista {
+ constructor(
+ public navCtrl: NavController,
+ public navParams: NavParams,
+ public actionSheetCtrl: ActionSheetController,
+ public alert: AlertController,
+ public toast: Toast,
+ public loadingCtrl: LoadingController,
+ public consultaCrud: CrudConsulta,
+ public necessidadeCrud: CrudNecessidade,
+ public produtoCrud: CrudProduto,
+ ){
+ super(
+ navCtrl,
+ actionSheetCtrl,
+ alert,
+ toast,
+ loadingCtrl,
+ consultaCrud
+ );
+ this.contextoExibe['excluir'] = false
+ this.contextoExibe['editar'] = false
+ this.textos['titulo'] = this.navParams.get('titulo')
+ this.items = this.navParams.get('consultas')
+ }
+ refreshList(){
+ this.mostraCarregando();
+ this.consultaCrud.recarregarAlguns(this.items).then( consultas => {
+ this.items = consultas
+ let necessidades: Necessidade[] = []
+ for(let consulta of consultas){
+ necessidades.push(consulta.necessidade)
+ }
+ this.necessidadeCrud.recarregarAlguns(necessidades).then(necessidades => {
+ this.produtoCrud.listar().then(produtos => {
+ for(let necessidade in necessidades){
+ for(let produto of produtos){
+ if(
+ necessidades[necessidade].produto
+ &&
+ necessidades[necessidade].produto.id == produto.id
+ ){
+ necessidades[necessidade].produto = produto
+ }
+ }
+ }
+ for(let consulta in consultas){
+ for(let necessidade of necessidades){
+ if(
+ consultas[consulta].necessidade
+ &&
+ consultas[consulta].necessidade.id === necessidade.id
+ ){
+ consultas[consulta].necessidade = necessidade
+ break
+ }
+ }
+ }
+ this.items = this.ordenaExibicao(consultas);
+ this.escondeCarregando()
+ })
+ });
+ })
+ }
+ public items: Consulta[] = new Array();
+ public icone: string = "arrow-dropright";
+ public textos: object = {
+ "titulo": "",
+ "adicionar": "",
+ "entidadeGenero": "",
+ "artigoentidade": "",
+ "capitalEntidade": "",
+ };
+ public texto(item: Consulta):string{
+ return ''+
+ ((item.necessidade || {produto:null}).produto || {nome: ''}).nome
+ +' ('
+ +((item.necessidade || {quantidade:'???'}).quantidade)
+ +' '
+ +((((item.necessidade || {produto:null}).produto || {unidadeMedida:null}).unidadeMedida || {nome:'iten'}).nome)
+ +(((item.necessidade || {quantidade:0}).quantidade)>1 ? 's' : '')
+ +')';
+ };
+ public posTexto(item: Consulta):string{ return item.supermercado.nome; };
+ public classesPara(item: Consulta):string{
+ return item.necessidade.satisfeita?'tickado':''
+ }
+ public add():void{return}
+ public abreEdicao(item: Consulta):void{return}
+ public click(item: Consulta):void{
+ item.necessidade.satisfeita = !item.necessidade.satisfeita
+ this.necessidadeCrud.recarregarUm(item.necessidade).then(necessidade => {
+ necessidade.satisfeita = item.necessidade.satisfeita
+ this.necessidadeCrud.salvar(necessidade)
+ })
+ };
+ public ordenaExibicao(items: Consulta[]):Consulta[]{
+ items.sort((a, b) => {
+ if (a.supermercado.nome > b.supermercado.nome) { return 1; }
+ if (a.supermercado.nome < b.supermercado.nome) { return -1; }
+ if (a.necessidade.produto.nome > b.necessidade.produto.nome) { return 1; }
+ if (a.necessidade.produto.nome < b.necessidade.produto.nome) { return -1; }
+ if (a.preco > b.preco) { return 1; }
+ if (a.preco < b.preco) { return -1; }
+ if (a.necessidade.id > b.necessidade.id) { return 1; }
+ if (a.necessidade.id < b.necessidade.id) { return -1; }
+ return 0;
+ })
+ return items;
+ }
+}
diff --git a/src/pages/generico_lista/main.html b/src/pages/generico_lista/main.html
index d5eff27..531a287 100644
--- a/src/pages/generico_lista/main.html
+++ b/src/pages/generico_lista/main.html
@@ -20,7 +20,7 @@
{{ posTexto(item) }}
-
+
{{ texto(item) }}
diff --git a/src/pages/generico_lista/main.scss b/src/pages/generico_lista/main.scss
index eefd22c..0bf00a1 100644
--- a/src/pages/generico_lista/main.scss
+++ b/src/pages/generico_lista/main.scss
@@ -6,10 +6,11 @@ page-lista {
.text-muted{
opacity: 0.5;
}
-}
-.deleteToast{
- color: #cc3333 !important;
-}
-.cancelToast{
- color: #387ef5 !important;
+ .text-main{
+ transition: all 200ms ease-in-out;
+ }
+ .tickado{
+ text-decoration: line-through;
+ opacity: 0.5;
+ }
}
diff --git a/src/pages/generico_lista/main.ts b/src/pages/generico_lista/main.ts
index b7379b1..4b3f6c6 100644
--- a/src/pages/generico_lista/main.ts
+++ b/src/pages/generico_lista/main.ts
@@ -39,6 +39,7 @@ export abstract class PageLista {
public abstract posTexto(item: T):string;
public abstract abreEdicao(item: T):void;
public abstract ordenaExibicao(items: T[]):T[];
+ public classesPara(item: T):string{return ''}
public add():void{
this.abreEdicao(this.crud.criar());
};
@@ -105,6 +106,9 @@ export abstract class PageLista {
if(this.contextoExibe['editar']){ botoes.push(botaoEditar) };
for(let personalizado of this.contextoExibe['personalizado']){ botoes.push(personalizado) };
if(this.contextoExibe['excluir']){ botoes.push(botaoExcluir) };
+ if(botoes.length == 0){
+ return
+ }
botoes.push(botaoCancelar)
let actionSheet = this.actionSheetCtrl.create({
title: 'Escolha uma das opções abaixo:',
diff --git a/src/pages/generico_lista_colapsavel/main.html b/src/pages/generico_lista_colapsavel/main.html
new file mode 100644
index 0000000..f0fe1bc
--- /dev/null
+++ b/src/pages/generico_lista_colapsavel/main.html
@@ -0,0 +1,33 @@
+
+
+
+ {{ textos.titulo }}
+
+
+
+
+
+
+
+
+
+
+ {{ posTextoInterno(subitem) }}
+
+
+
+ {{ textoInterno(subitem) }}
+
+
+
+
+
diff --git a/src/pages/generico_lista_colapsavel/main.scss b/src/pages/generico_lista_colapsavel/main.scss
new file mode 100644
index 0000000..f0ec424
--- /dev/null
+++ b/src/pages/generico_lista_colapsavel/main.scss
@@ -0,0 +1,42 @@
+page-lista {
+ .text-end{
+ display: relative;
+ float: right;
+ }
+ .text-muted{
+ opacity: 0.5;
+ }
+ .collapsible button:first-of-type ion-icon:first-of-type{
+ transition: transform 200ms ease-in-out;
+ }
+ .collapsible:not(.collapsed) button:first-of-type ion-icon:first-of-type{
+ transform: rotate(90deg);
+ }
+ .collapsible>ion-list{
+ transition: all 300ms ease-in-out;
+ transform: scaleY(1);
+ opacity: 1;
+ }
+ .collapsible.collapsed>ion-list{
+ transform: scaleY(0);
+ opacity: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+ .collapsible>ion-list ion-item{
+ transition: all 300ms ease-in-out;
+ max-height: 4.4rem;
+ }
+ .collapsible.collapsed>ion-list ion-item{
+ max-height: 0rem;
+ min-height: 0rem;
+ }
+}
+.deleteToast{
+ color: #cc3333 !important;
+}
+.cancelToast{
+ color: #387ef5 !important;
+}
diff --git a/src/pages/generico_lista_colapsavel/main.ts b/src/pages/generico_lista_colapsavel/main.ts
new file mode 100644
index 0000000..d85f6d7
--- /dev/null
+++ b/src/pages/generico_lista_colapsavel/main.ts
@@ -0,0 +1,103 @@
+import { NavController } from 'ionic-angular';
+import { NavParams } from 'ionic-angular';
+import { ActionSheetController } from 'ionic-angular';
+import { AlertController } from 'ionic-angular';
+import { LoadingController } from 'ionic-angular';
+import { Loading } from 'ionic-angular';
+import { Toast } from "@ionic-native/toast";
+import { CrudService } from '../../providers/_crudService';
+
+export abstract class PageListacolapsavel{
+ constructor(
+ public navCtrl: NavController,
+ public navParams: NavParams,
+ public actionSheetCtrl: ActionSheetController,
+ public alert: AlertController,
+ public toast: Toast,
+ public loadingCtrl: LoadingController,
+ public crudExterno: CrudService,
+ public crudInterno: CrudService,
+ ){
+ }
+ public mostraCarregando(){
+ this.initialLoad = this.loadingCtrl.create({ content: 'Carregando...' }); this.initialLoad.present();
+ }
+ public escondeCarregando(){
+ this.initialLoad.dismiss()
+ }
+ public contextoExibe: object = {
+ excluir: true,
+ editar: true,
+ personalizado: [],
+ };
+ ionViewWillEnter(){
+ this.refreshList();
+ }
+ externosMonitorados: E[] = [];
+ abstract beforeRefreshList():Promise;
+ refreshList(){
+ this.mostraCarregando();
+ this.beforeRefreshList().then(()=>{
+ let externoLista: Promise;
+ if(this.externosMonitorados.length==0){
+ externoLista = this.crudExterno.listar();
+ }else{
+ externoLista = this.crudExterno.recarregarAlguns(this.externosMonitorados)
+ }
+ externoLista.then(
+ (lista: E[]) => {
+ let recuperar: I[] = new Array()
+ for(let item of lista){
+ for(let interno of item[this.itemField]){
+ recuperar.push(interno)
+ }
+ }
+ this.crudInterno.recarregarAlguns(recuperar).then( (internos: I[]) => {
+ for(let indiceExterno in lista){
+ for(let indiceInterno in lista[indiceExterno][this.itemField]){
+ for(let interno of internos){
+ if (lista[indiceExterno][this.itemField][indiceInterno]['id'] == interno['id']){
+ lista[indiceExterno][this.itemField][indiceInterno] = interno
+ }
+ }
+ }
+ }
+ this.items = this.ordenaExibicaoExterno(lista);
+ for(let indiceExterno in this.items){
+ if(this.items[indiceExterno]['id']>0){
+ this.items[indiceExterno][this.itemField] = this.ordenaExibicaoInterno(this.items[indiceExterno][this.itemField]);
+ }
+ }
+ this.escondeCarregando()
+ })
+ }
+ );
+ });
+ }
+ public items: Array;
+ public initialLoad: Loading;
+ public abstract textos: object;
+ public abstract iconeI: string;
+ public abstract itemField: string;
+ public abstract textoExterno(item: E):string;
+ public abstract textoInterno(item: I):string;
+ public abstract posTextoExterno(item: E):string;
+ public abstract posTextoInterno(item: I):string;
+ public abstract ordenaExibicaoExterno(items: E[]):E[];
+ public abstract ordenaExibicaoInterno(items: I[]):I[];
+ public collapsed: number[] = [];
+ public collapse(item: E):void{
+ if(this.isCollapsed(item)){
+ this.collapsed.splice(this.collapsed.indexOf(item['id']),1)
+ }else{
+ this.collapsed.push(item['id'])
+ }
+ };
+ public isCollapsed(item: E):boolean{
+ return this.collapsed.indexOf(item['id']) != -1
+ }
+ public abstract clickInterno(item: I):void;
+ public getSubitems(item: E):I[]{
+ return item[this.itemField]
+ }
+}
diff --git a/src/persistence/OrmDatabase.service.ts b/src/persistence/OrmDatabase.service.ts
index 1d67dfe..ffc391c 100644
--- a/src/persistence/OrmDatabase.service.ts
+++ b/src/persistence/OrmDatabase.service.ts
@@ -79,4 +79,13 @@ export class OrmDatabase{
}
})
}
+ dropDatabase(){
+ return new Promise((resolve, reject) => {
+ this.getConnection().then(connection =>{
+ connection.dropDatabase().then(()=>{
+ connection.close().then(resolve,reject)
+ }, reject)
+ },reject)
+ })
+ }
}
diff --git a/src/providers/Relatorios.service.ts b/src/providers/Relatorios.service.ts
index c5d9be7..83f3833 100644
--- a/src/providers/Relatorios.service.ts
+++ b/src/providers/Relatorios.service.ts
@@ -1,24 +1,130 @@
import { Injectable } from '@angular/core';
import { OrmDatabase } from '../persistence/OrmDatabase.service';
+
+import { CrudConsulta } from './CrudConsulta.service';
+import { CrudSupermercado } from './CrudSupermercado.service';
+import { CrudNecessidade } from './CrudNecessidade.service';
+import { CrudPlanejamento } from './CrudPlanejamento.service';
+
import { Planejamento } from '../entities/Planejamento';
import { Supermercado } from '../entities/Supermercado';
+import { Necessidade } from '../entities/Necessidade';
import { Consulta } from '../entities/Consulta';
@Injectable()
export class Relatorios{
constructor(
- public ormDatabase: OrmDatabase
+ public ormDatabase: OrmDatabase,
+ public consultaCrud: CrudConsulta,
+ public supermercadoCrud: CrudSupermercado,
+ public necessidadeCrud: CrudNecessidade,
+ public planejamentoCrud: CrudPlanejamento,
){
return
}
- menorPrecoMedio(planejamento: Planejamento):Promise{
- return
+ _menorUm(planejamento: Planejamento, orderBy: string):Promise{
+ return new Promise((resolve, reject) => {
+ this.planejamentoCrud.recarregarUm(planejamento).then(planejamento => {
+ this.ormDatabase.getConnection().then(connection =>{
+ this.consultaCrud._seleciona(connection.getRepository(Consulta))
+ .leftJoinAndSelect("necessidade.planejamento", "planejamento")
+ .where("tbl.preco <> 0")
+ .andWhere("planejamento.id = "+planejamento.id)
+ .addGroupBy("tbl.supermercado")
+ .orderBy(orderBy)
+ .having("SUM(tbl.preco) > 0")
+ .getMany()
+ .then((consultas:Consulta[])=>{
+ /* nota: esta consulta apenas contem os supermercados com o
+ /* preco medio em ordem crescente, foi decisao de codificacao
+ /* visando melhorar a performance desta consulta, que esta
+ /* O(nlogn), e seria pelo menos O(n2) caso feito da outra
+ /* forma; em contrapartida, virao mais queries a seguir,
+ /* menos complexas.
+ /**/
+ if(consultas.length <= 0){
+ reject('Preços não foram pesquisados')
+ }else{
+ let supermercado: Supermercado = consultas[0].supermercado
+ this.necessidadeCrud.recarregarAlguns(planejamento.necessidades)
+ .then(
+ (necessidades: Necessidade[]) => {
+ let consultasARecarregar: Consulta[] = []
+ for(let necessidade of necessidades){
+ for(let consulta of necessidade.consultas){
+ consultasARecarregar.push(consulta)
+ }
+ }
+ this.consultaCrud.recarregarAlguns(consultasARecarregar).then(
+ (consultas:Consulta[])=>{
+ let selecionadas: Consulta[] = []
+ for(let consulta of consultas){
+ if(supermercado.id == consulta.supermercado.id){
+ selecionadas.push(consulta)
+ }
+ }
+ resolve(selecionadas)
+ },reject
+ )
+ },reject
+ )
+ }
+ },reject)
+ },reject)
+ })
+ })
}
- menorPrecoEmUmSupermercado(planejamento: Planejamento):Promise>{
- return
+ menorPrecoMedio(planejamento: Planejamento):Promise{
+ return this._menorUm(planejamento, "SUM(tbl.preco)/COUNT(*)")
}
- menorPrecoEmTodosSupermercados(planejamento: Planejamento):Promise>{
- return
+ menorPrecoEmUmSupermercado(planejamento: Planejamento):Promise{
+ return this._menorUm(planejamento, "SUM(tbl.preco*necessidade.quantidade)")
+ }
+ menorPrecoEmTodosSupermercados(planejamento: Planejamento):Promise{
+ return new Promise((resolve, reject) => {
+ this.planejamentoCrud.recarregarUm(planejamento).then((planejamento:Planejamento) => {
+ this.necessidadeCrud.recarregarAlguns(planejamento.necessidades).then((necessidades:Necessidade[])=>{
+ let consultasARecarregar: Consulta[] = []
+ for(let necessidade of necessidades){
+ for(let consulta of necessidade.consultas){
+ consultasARecarregar.push(consulta)
+ }
+ }
+ this.consultaCrud.recarregarAlguns(consultasARecarregar).then((consultas:Consulta[])=>{
+ let menorPreco: {[id:number]: {consulta:Consulta,preco:number};} = {}
+ for(let necessidade of necessidades){
+ menorPreco[necessidade.id] = {
+ consulta: null,
+ preco: 0,
+ }
+ }
+ for(let consulta of consultas){
+ if(
+ menorPreco[consulta.necessidade.id].consulta==null
+ ||
+ (
+ menorPreco[consulta.necessidade.id].preco > consulta.preco * consulta.necessidade.quantidade
+ &&
+ consulta.preco > 0
+ )
+ ){
+ menorPreco[consulta.necessidade.id].consulta = consulta
+ menorPreco[consulta.necessidade.id].preco = consulta.preco * consulta.necessidade.quantidade
+ }
+ }
+ let comprar: Consulta[] = []
+ for(let necessidade of necessidades){
+ comprar.push(menorPreco[necessidade.id].consulta)
+ if(menorPreco[necessidade.id].consulta === null){
+ reject('Preços não foram pesquisados')
+ return
+ }
+ }
+ resolve(comprar)
+ },reject)
+ },reject)
+ },reject)
+ })
}
}
diff --git a/src/test.ts b/src/test.ts
index ce857c8..8a24ab5 100644
--- a/src/test.ts
+++ b/src/test.ts
@@ -26,6 +26,7 @@ import { CrudNecessidade } from './providers/CrudNecessidade.service';
import { CrudPlanejamento } from './providers/CrudPlanejamento.service';
import { CrudSupermercado } from './providers/CrudSupermercado.service';
import { OrmDatabase } from './persistence/OrmDatabase.service'
+import { Relatorios } from './providers/Relatorios.service';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
@@ -90,6 +91,7 @@ export class TestUtils {
CrudNecessidade,
CrudPlanejamento,
CrudSupermercado,
+ Relatorios,
],
imports: [
FormsModule,