Commit 0a7146ac4fd84440d41fa3135ead29188e55fdeb

Authored by Marcelo Puebla
Exists in develop

Merge branch 'develop' into 'develop'

Develop

See merge request !97
src/app/modules/seleccion-articulos/seleccion-articulos.component.ts
1 import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit } from '@angular/core'; 1 import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit } from '@angular/core';
2 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; 2 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
3 import { ArticuloService } from 'src/app/services/articulo/articulo.service'; 3 import { ArticuloService } from 'src/app/services/articulo/articulo.service';
4 import { IArticulo } from 'src/app/interfaces/IArticulo'; 4 import { IArticulo } from 'src/app/interfaces/IArticulo';
5 import { APP_SETTINGS } from 'src/etc/AppSettings'; 5 import { APP_SETTINGS } from 'src/etc/AppSettings';
6 import { ICategoria } from 'src/app/interfaces/ICategoria'; 6 import { ICategoria } from 'src/app/interfaces/ICategoria';
7 import { ISinonimo } from 'src/app/interfaces/ISinonimo'; 7 import { ISinonimo } from 'src/app/interfaces/ISinonimo';
8 import { PromocionComponent } from 'src/app/shared/promocion/promocion.component'; 8 import { PromocionComponent } from 'src/app/shared/promocion/promocion.component';
9 import { InactiveScreenService } from 'src/app/services/inactive-screen/inactive-screen.service'; 9 import { InactiveScreenService } from 'src/app/services/inactive-screen/inactive-screen.service';
10 import { SinonimoService } from 'src/app/services/sinonimo/sinonimo.service'; 10 import { SinonimoService } from 'src/app/services/sinonimo/sinonimo.service';
11 import { SinonimoComponent } from 'src/app/shared/sinonimo/sinonimo.component'; 11 import { SinonimoComponent } from 'src/app/shared/sinonimo/sinonimo.component';
12 import { FiltroCategoriasComponent } from './filtro-categorias/filtro-categorias.component'; 12 import { FiltroCategoriasComponent } from './filtro-categorias/filtro-categorias.component';
13 import * as _ from 'lodash'; 13 import * as _ from 'lodash';
14 import { ANIMATIONS } from 'src/app/utils/animations'; 14 import { ANIMATIONS } from 'src/app/utils/animations';
15 15
16 @Component({ 16 @Component({
17 selector: 'app-seleccion-articulos', 17 selector: 'app-seleccion-articulos',
18 templateUrl: './seleccion-articulos.component.html', 18 templateUrl: './seleccion-articulos.component.html',
19 styleUrls: ['./seleccion-articulos.component.scss'], 19 styleUrls: ['./seleccion-articulos.component.scss'],
20 animations: [ANIMATIONS.EnterLeaveY] 20 animations: [ANIMATIONS.EnterLeaveY]
21 }) 21 })
22 export class SeleccionArticulosComponent implements OnInit, AfterViewInit, OnDestroy { 22 export class SeleccionArticulosComponent implements OnInit, AfterViewInit, OnDestroy {
23 loading = true; 23 loading = true;
24 timeoutHandler: any; 24 timeoutHandler: any;
25 urlImagenes = `${APP_SETTINGS.apiImagenes}/imagenes/`; 25 urlImagenes = `${APP_SETTINGS.apiImagenes}/imagenes/`;
26 articulos: IArticulo[] = []; 26 articulos: IArticulo[] = [];
27 auxArticulos: IArticulo[] = []; 27 auxArticulos: IArticulo[] = [];
28 showQuantity = 100; 28 showQuantity = 100;
29 searchTerm = ''; 29 searchTerm = '';
30 ordenandoByVendidos = true; 30 ordenandoByVendidos = true;
31 modalRef: BsModalRef; 31 modalRef: BsModalRef;
32 total = 0; 32 total = 0;
33 @ViewChild(FiltroCategoriasComponent, { static: false }) filtroCategorias: FiltroCategoriasComponent; 33 @ViewChild(FiltroCategoriasComponent, { static: false }) filtroCategorias: FiltroCategoriasComponent;
34 34
35 constructor( 35 constructor(
36 public articuloService: ArticuloService, 36 public articuloService: ArticuloService,
37 private sinonimoService: SinonimoService, 37 private sinonimoService: SinonimoService,
38 private modalService: BsModalService, 38 private modalService: BsModalService,
39 private inactiveScreen: InactiveScreenService, 39 private inactiveScreen: InactiveScreenService,
40 ) { } 40 ) { }
41 41
42 ngOnInit() { } 42 ngOnInit() { }
43 43
44 ngAfterViewInit(): void { 44 ngAfterViewInit(): void {
45 this.filtroCategorias.getCategorias(); 45 this.filtroCategorias.getCategorias();
46 this.mediaPantalla(); 46 this.mediaPantalla();
47 } 47 }
48 48
49 ngOnDestroy() { 49 ngOnDestroy() {
50 for (let i = 1; i <= this.modalService.getModalsCount(); i++) { 50 for (let i = 1; i <= this.modalService.getModalsCount(); i++) {
51 this.modalService.hide(i); 51 this.modalService.hide(i);
52 } 52 }
53 } 53 }
54 54
55 getProductos() { 55 getProductos() {
56 this.articuloService.getAll() 56 this.articuloService.getAll()
57 .subscribe((result: IArticulo[]) => { 57 .subscribe((result: IArticulo[]) => {
58 this.articuloService.setArticulosSinImagen(result); 58 this.articuloService.setArticulosSinImagen(result);
59 if (this.filtroCategorias.queMostrar === 'ordenar') { 59 if (this.filtroCategorias.queMostrar === 'ordenar') {
60 this.filtroCategorias.categorias.forEach((categoria: ICategoria) => { 60 this.filtroCategorias.categorias.forEach((categoria: ICategoria) => {
61 const tempArticulos = result.filter((articulo: IArticulo) => { 61 const tempArticulos = result.filter((articulo: IArticulo) => {
62 return articulo.categoria_selfservice === categoria.id; 62 return articulo.categoria_selfservice === categoria.id;
63 }); 63 });
64 result = tempArticulos; 64 result = tempArticulos;
65 }); 65 });
66 } 66 }
67 localStorage.setItem('articulos', JSON.stringify(result)); 67 localStorage.setItem('articulos', JSON.stringify(result));
68 this.setProductos(); 68 this.setProductos();
69 }, (error) => { 69 }, (error) => {
70 console.error(error); 70 console.error(error);
71 }); 71 });
72 } 72 }
73 73
74 setProductos() { 74 setProductos() {
75 this.articulos = JSON.parse(localStorage.getItem('articulos')); 75 this.articulos = JSON.parse(localStorage.getItem('articulos'));
76 this.filterItems(); 76 this.filterItems();
77 this.loading = false; 77 this.loading = false;
78 } 78 }
79 79
80 filterItems() { 80 filterItems() {
81 if (this.filtroCategorias.categoriaActive === 0) { 81 if (this.filtroCategorias.categoriaActive === 0) {
82 this.auxArticulos = this.articulos; 82 this.auxArticulos = this.articulos;
83 return; 83 return;
84 } 84 }
85 this.auxArticulos = this.articulos.filter(x => { 85 this.auxArticulos = this.articulos.filter(x => {
86 return x.categoria_selfservice === this.filtroCategorias.categoriaActive; 86 return x.categoria_selfservice === this.filtroCategorias.categoriaActive;
87 }); 87 });
88 this.ordenar(); 88 this.ordenar();
89 } 89 }
90 90
91 ordenar() { 91 ordenar() {
92 if (this.ordenandoByVendidos) { 92 if (this.ordenandoByVendidos) {
93 this.auxArticulos.sort((a, b) => { 93 this.auxArticulos.sort((a, b) => {
94 return b.cantidadVendida - a.cantidadVendida; 94 return b.cantidadVendida - a.cantidadVendida;
95 }); 95 });
96 } 96 }
97 } 97 }
98 98
99 selectArticulo(articulo: IArticulo) { 99 selectArticulo(articulo: IArticulo) {
100 this.getByID(articulo.id); 100 this.getByID(articulo.id);
101 } 101 }
102 102
103 getByID(id: number) { 103 getByID(id: number) {
104 this.articuloService.getById(id) 104 this.articuloService.getById(id)
105 .subscribe((res: IArticulo) => { 105 .subscribe((res: IArticulo) => {
106 if (res.FPP) { 106 if (res.FPP) {
107 this.openModalPromos(res); 107 this.openModalPromos(res);
108 } else { 108 } else {
109 this.getSinonimos(res); 109 this.getSinonimos(res);
110 } 110 }
111 }, err => console.error(err)); 111 }, err => console.error(err));
112 } 112 }
113 113
114 getSinonimos(articulo: IArticulo) { 114 getSinonimos(articulo: IArticulo) {
115 this.sinonimoService.getSinonimos(articulo.CodSec, articulo.CodArt) 115 this.sinonimoService.getSinonimos(articulo.CodSec, articulo.CodArt)
116 .subscribe((res: any[]) => { 116 .subscribe((res: any[]) => {
117 if (res.length) { 117 if (res.length) {
118 const sinonimos = []; 118 const sinonimos = [];
119 const gruposArticulos = _.groupBy(res[0].productos, 'ID_SIN'); 119 const gruposArticulos = _.groupBy(res[0].productos, 'ID_SIN');
120 Object.keys(gruposArticulos).forEach(key => { 120 Object.keys(gruposArticulos).forEach(key => {
121 sinonimos.push({ productos: gruposArticulos[key] }); 121 sinonimos.push({ productos: gruposArticulos[key] });
122 }); 122 });
123 res = sinonimos; 123 res = sinonimos;
124 this.openModalSinonimos(res, articulo); 124 this.openModalSinonimos(res, articulo);
125 } else { 125 } else {
126 this.articuloService.setArticulo(articulo); 126 this.articuloService.setArticulo(articulo);
127 } 127 }
128 }); 128 });
129 } 129 }
130 130
131 openModalPromos(articulo: IArticulo) { 131 openModalPromos(articulo: IArticulo) {
132 if (this.modalRef) return;
132 this.articuloService.setArticulosSinImagen([articulo]); 133 this.articuloService.setArticulosSinImagen([articulo]);
133 this.modalRef = this.modalService.show(PromocionComponent, { 134 this.modalRef = this.modalService.show(PromocionComponent, {
134 initialState: { articulosPromo: [articulo] }, 135 initialState: { articulosPromo: [articulo] },
135 class: 'modal-dialog-centered' 136 class: 'modal-dialog-centered',
137 ignoreBackdropClick: true,
136 }); 138 });
139 this.modalRef.content.onClose
140 .subscribe(() => this.modalRef = null);
137 this.mediaPantalla(); 141 this.mediaPantalla();
138 } 142 }
139 143
140 openModalSinonimos(sinonimosData: ISinonimo[], articulo: IArticulo) { 144 openModalSinonimos(sinonimosData: ISinonimo[], articulo: IArticulo) {
145 if (this.modalRef) return;
141 this.modalRef = this.modalService.show(SinonimoComponent, { 146 this.modalRef = this.modalService.show(SinonimoComponent, {
142 initialState: { 147 initialState: {
143 sinonimos: sinonimosData, 148 sinonimos: sinonimosData,
144 articulo 149 articulo
145 }, 150 },
146 class: 'modal-dialog-centered' 151 class: 'modal-dialog-centered',
152 ignoreBackdropClick: true,
147 }); 153 });
148 154
149 this.modalRef.content.onClose 155 this.modalRef.content.onClose
150 .subscribe((res: any) => { 156 .subscribe((res: any) => {
157 this.modalRef = null;
151 for (const a of articulo.productos) { 158 for (const a of articulo.productos) {
152 for (const aRes of res.articulos) { 159 for (const aRes of res.articulos) {
153 if (a.idSinonimo === aRes.ID_SIN) { 160 if (a.idSinonimo === aRes.ID_SIN) {
154 a.CODA = aRes.CodArt; 161 a.CODA = aRes.CodArt;
155 a.CodArt = aRes.CodArt; 162 a.CodArt = aRes.CodArt;
156 a.SECA = aRes.CodSec; 163 a.SECA = aRes.CodSec;
157 aRes.CodSec = aRes.CodSec; 164 aRes.CodSec = aRes.CodSec;
158 a.PreVen = aRes.PreVen; 165 a.PreVen = aRes.PreVen;
159 a.id = aRes.id; 166 a.id = aRes.id;
160 a.DET_LAR = aRes.DET_LAR; 167 a.DET_LAR = aRes.DET_LAR;
161 a.DetArt = aRes.DetArt; 168 a.DetArt = aRes.DetArt;
162 } 169 }
163 } 170 }
164 } 171 }
165 this.articuloService.setArticulo(articulo); 172 this.articuloService.setArticulo(articulo);
166 }); 173 });
167 this.mediaPantalla(); 174 this.mediaPantalla();
168 } 175 }
169 176
170 deleteArticulo(index: number) { 177 deleteArticulo(index: number) {
171 this.articuloService.deleteArticulo(index); 178 this.articuloService.deleteArticulo(index);
172 } 179 }
173 180
174 increaseShow() { 181 increaseShow() {
175 this.showQuantity += 100; 182 this.showQuantity += 100;
176 } 183 }
177 184
178 @HostListener('scroll', ['$event']) 185 @HostListener('scroll', ['$event'])
179 scrollEvent(event: Event) { 186 scrollEvent(event: Event) {
180 clearTimeout(this.inactiveScreen.timerReposo); 187 clearTimeout(this.inactiveScreen.timerReposo);
181 this.inactiveScreen.startTimeOutInactividad(); 188 this.inactiveScreen.startTimeOutInactividad();
182 } 189 }
183 190
184 mouseup() { 191 mouseup() {
185 if (!this.timeoutHandler) return; 192 if (!this.timeoutHandler) return;
186 clearInterval(this.timeoutHandler); 193 clearInterval(this.timeoutHandler);
187 } 194 }
188 195
189 scrollY(el: HTMLElement, value) { 196 scrollY(el: HTMLElement, value) {
190 el.scroll({ behavior: 'smooth', top: value + el.scrollTop }); 197 el.scroll({ behavior: 'smooth', top: value + el.scrollTop });
191 this.timeoutHandler = setInterval(() => { 198 this.timeoutHandler = setInterval(() => {
192 el.scroll({ behavior: 'smooth', top: value + el.scrollTop }); 199 el.scroll({ behavior: 'smooth', top: value + el.scrollTop });
193 }, 500); 200 }, 500);
194 } 201 }
195 202
196 scrollX(el: HTMLElement, value) { 203 scrollX(el: HTMLElement, value) {
197 el.scroll({ behavior: 'smooth', left: value + el.scrollLeft }); 204 el.scroll({ behavior: 'smooth', left: value + el.scrollLeft });
198 this.timeoutHandler = setInterval(() => { 205 this.timeoutHandler = setInterval(() => {
199 el.scroll({ behavior: 'smooth', left: value + el.scrollLeft }); 206 el.scroll({ behavior: 'smooth', left: value + el.scrollLeft });
200 }, 500); 207 }, 500);
201 } 208 }
202 209
203 mediaPantalla() { 210 mediaPantalla() {
204 if ($('body').hasClass('media-pantalla')) { 211 if ($('body').hasClass('media-pantalla')) {
205 $(`.cat-content,#cat-content,#content,.cat-btn,#boxCarrito, 212 $(`.cat-content,#cat-content,#content,.cat-btn,#boxCarrito,
206 .cat-box,.img-categoria, .modal-content`) 213 .cat-box,.img-categoria, .modal-content`)
207 .addClass('media-pantalla') 214 .addClass('media-pantalla')
208 .addBack('media-pantalla'); 215 .addBack('media-pantalla');
209 } 216 }
210 } 217 }
211 } 218 }
212 219
src/app/services/articulo/articulo.service.ts
1 import { Injectable } from '@angular/core'; 1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http'; 2 import { HttpClient } from '@angular/common/http';
3 import { APP_SETTINGS } from '../../../etc/AppSettings'; 3 import { APP_SETTINGS } from '../../../etc/AppSettings';
4 import { IArticulo } from '../../interfaces/IArticulo'; 4 import { IArticulo } from '../../interfaces/IArticulo';
5 import { ClienteService } from '../cliente/cliente.service'; 5 import { ClienteService } from '../cliente/cliente.service';
6 import { Observable } from 'rxjs'; 6 import { Observable } from 'rxjs';
7 7
8 @Injectable() 8 @Injectable()
9 export class ArticuloService { 9 export class ArticuloService {
10 carrito: IArticulo[] = []; 10 carrito: IArticulo[] = [];
11 articuloAcargar: IArticulo; 11 articuloAcargar: IArticulo;
12 promoAcargar: IArticulo; 12 promoAcargar: IArticulo;
13 mostrar: string; 13 mostrar: string;
14 esPromoPersonalizada = false; 14 esPromoPersonalizada = false;
15 urlDeboSuite = APP_SETTINGS.apiDeboSuite; 15 urlDeboSuite = APP_SETTINGS.apiDeboSuite;
16 medioPago: number; 16 medioPago: number;
17 idComanda: number; 17 idComanda: number;
18 subTotal = 0; 18 subTotal = 0;
19 maxCantidad = 50; 19 maxCantidad = 50;
20 20
21 constructor( 21 constructor(
22 private http: HttpClient, 22 private http: HttpClient,
23 private clienteService: ClienteService, 23 private clienteService: ClienteService,
24 ) { } 24 ) { }
25 25
26 getById(id) { 26 getById(id) {
27 return this.http.get(`${this.urlDeboSuite}/articulos/${id}`); 27 return this.http.get(`${this.urlDeboSuite}/articulos/${id}`);
28 } 28 }
29 29
30 getAll() { 30 getAll() {
31 return this.http.get(`${this.urlDeboSuite}/articulos/`); 31 return this.http.get(`${this.urlDeboSuite}/articulos/`);
32 } 32 }
33 33
34 getAllWithPaginator(page: number = 1) { 34 getAllWithPaginator(page: number = 1) {
35 return this.http.get(`${this.urlDeboSuite}/articulos/${page}`); 35 return this.http.get(`${this.urlDeboSuite}/articulos/${page}`);
36 } 36 }
37 37
38 substractCant(articulo: IArticulo) { 38 substractCant(articulo: IArticulo) {
39 if (articulo.cantidad === 1) return; 39 if (articulo.cantidad === 1) return;
40 articulo.cantidad--; 40 articulo.cantidad--;
41 this.calcularTotal(); 41 this.calcularTotal();
42 } 42 }
43 43
44 addCant(articulo: IArticulo) { 44 addCant(articulo: IArticulo) {
45 if (articulo.cantidad >= this.maxCantidad) return; 45 if (articulo.cantidad >= this.maxCantidad) return;
46 articulo.cantidad++; 46 articulo.cantidad++;
47 this.calcularTotal(); 47 this.calcularTotal();
48 } 48 }
49 49
50 calcularTotal() { 50 calcularTotal() {
51 this.subTotal = 0; 51 this.subTotal = 0;
52 this.carrito.forEach(articulo => { 52 this.carrito.forEach(articulo => {
53 this.subTotal += (articulo.PreVen * articulo.cantidad); 53 this.subTotal += (articulo.PreVen * articulo.cantidad);
54 }); 54 });
55 } 55 }
56 56
57 setArticulo(articulo: IArticulo) { 57 setArticulo(articulo: IArticulo) {
58 articulo.cantidad = 1; 58 articulo.cantidad = 1;
59 for (const articuloCarrito of this.carrito) { 59 for (const articuloCarrito of this.carrito) {
60 if (articuloCarrito.id === articulo.id && !articulo.productos.length) { 60 if (articuloCarrito.id === articulo.id && !articulo.productos) {
61 articuloCarrito.cantidad++; 61 articuloCarrito.cantidad++;
62 this.calcularTotal(); 62 this.calcularTotal();
63 return; 63 return;
64 } 64 }
65 } 65 }
66 this.setArticulosSinImagen([articulo]); 66 this.setArticulosSinImagen([articulo]);
67 this.carrito.unshift(articulo); 67 this.carrito.unshift(articulo);
68 this.calcularTotal(); 68 this.calcularTotal();
69 } 69 }
70 70
71 deleteArticulo(index: number) { 71 deleteArticulo(index: number) {
72 this.carrito.splice(index, 1); 72 this.carrito.splice(index, 1);
73 this.calcularTotal(); 73 this.calcularTotal();
74 } 74 }
75 75
76 pay(dataPago: any) { 76 pay(dataPago: any) {
77 return new Observable((observer) => { 77 return new Observable((observer) => {
78 this.clienteService.getById(-1) 78 this.clienteService.getById(-1)
79 .subscribe(cliente => { 79 .subscribe(cliente => {
80 this.markArticuloInPromoAsRemoved(); 80 this.markArticuloInPromoAsRemoved();
81 this.http.post(`${this.urlDeboSuite}/comprobante/guardar/${this.medioPago}`, { 81 this.http.post(`${this.urlDeboSuite}/comprobante/guardar/${this.medioPago}`, {
82 productos: this.carrito, 82 productos: this.carrito,
83 cliente, 83 cliente,
84 origen: 'autoservicio', 84 origen: 'autoservicio',
85 codigoVendedor: 5, 85 codigoVendedor: 5,
86 puntoVenta: APP_SETTINGS.puntoVenta, 86 puntoVenta: APP_SETTINGS.puntoVenta,
87 pedidoAnombreDe: dataPago.pedidoAnombreDe, 87 pedidoAnombreDe: dataPago.pedidoAnombreDe,
88 numeroPlanilla: APP_SETTINGS.numeroPlanilla, 88 numeroPlanilla: APP_SETTINGS.numeroPlanilla,
89 pedidoParaLlevar: localStorage.getItem('pedidoParaLlevar'), 89 pedidoParaLlevar: localStorage.getItem('pedidoParaLlevar'),
90 }) 90 })
91 .subscribe((data) => { 91 .subscribe((data) => {
92 observer.next(data); 92 observer.next(data);
93 observer.complete(); 93 observer.complete();
94 }); 94 });
95 }); 95 });
96 }); 96 });
97 } 97 }
98 98
99 cleanShoppingCar() { 99 cleanShoppingCar() {
100 this.articuloAcargar = undefined; 100 this.articuloAcargar = undefined;
101 this.promoAcargar = undefined; 101 this.promoAcargar = undefined;
102 this.carrito = []; 102 this.carrito = [];
103 } 103 }
104 104
105 setArticulosSinImagen(articulos: IArticulo[]) { 105 setArticulosSinImagen(articulos: IArticulo[]) {
106 articulos.forEach((articulo: IArticulo) => { 106 articulos.forEach((articulo: IArticulo) => {
107 articulo.imagenes = !articulo.imagenes ? [{ imagen: 'noImage.jpg' }] : 107 articulo.imagenes = !articulo.imagenes ? [{ imagen: 'noImage.jpg' }] :
108 !articulo.imagenes.length ? [{ imagen: 'noImage.jpg' }] : articulo.imagenes; 108 !articulo.imagenes.length ? [{ imagen: 'noImage.jpg' }] : articulo.imagenes;
109 }); 109 });
110 } 110 }
111 111
112 markArticuloInPromoAsRemoved() { 112 markArticuloInPromoAsRemoved() {
113 this.carrito.forEach((articuloCarrito: IArticulo) => { 113 this.carrito.forEach((articuloCarrito: IArticulo) => {
114 if (articuloCarrito.PRO) { 114 if (articuloCarrito.PRO) {
115 articuloCarrito.productos.forEach((articulo: IArticulo) => { 115 articuloCarrito.productos.forEach((articulo: IArticulo) => {
116 if (articulo.cantidadAdicionada === 0) { 116 if (articulo.cantidadAdicionada === 0) {
117 articulo.cantidad = 0; 117 articulo.cantidad = 0;
118 articulo.importeValorExtra = 0; 118 articulo.importeValorExtra = 0;
119 } 119 }
120 }); 120 });
121 } 121 }
122 }); 122 });
123 } 123 }
124 } 124 }
125 125
src/app/shared/promocion/promocion.component.ts
1 import { Component, OnInit, HostListener } from '@angular/core'; 1 import { Component, OnInit, HostListener } from '@angular/core';
2 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; 2 import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
3 import { IArticulo } from 'src/app/interfaces/IArticulo'; 3 import { IArticulo } from 'src/app/interfaces/IArticulo';
4 import { ArticuloService } from 'src/app/services/articulo/articulo.service'; 4 import { ArticuloService } from 'src/app/services/articulo/articulo.service';
5 import { PromocionService } from 'src/app/services/promocion/promocion.service'; 5 import { PromocionService } from 'src/app/services/promocion/promocion.service';
6 import { Subject } from 'rxjs'; 6 import { Subject } from 'rxjs';
7 import { APP_SETTINGS } from 'src/etc/AppSettings'; 7 import { APP_SETTINGS } from 'src/etc/AppSettings';
8 import { InactiveScreenService } from 'src/app/services/inactive-screen/inactive-screen.service'; 8 import { InactiveScreenService } from 'src/app/services/inactive-screen/inactive-screen.service';
9 import { SinonimoService } from 'src/app/services/sinonimo/sinonimo.service'; 9 import { SinonimoService } from 'src/app/services/sinonimo/sinonimo.service';
10 import { ISinonimo } from 'src/app/interfaces/ISinonimo'; 10 import { ISinonimo } from 'src/app/interfaces/ISinonimo';
11 import { SinonimoComponent } from '../sinonimo/sinonimo.component'; 11 import { SinonimoComponent } from '../sinonimo/sinonimo.component';
12 import * as _ from 'lodash'; 12 import * as _ from 'lodash';
13 13
14 @Component({ 14 @Component({
15 selector: 'app-promocion', 15 selector: 'app-promocion',
16 templateUrl: './promocion.component.html', 16 templateUrl: './promocion.component.html',
17 styleUrls: ['./promocion.component.scss'] 17 styleUrls: ['./promocion.component.scss']
18 }) 18 })
19 export class PromocionComponent implements OnInit { 19 export class PromocionComponent implements OnInit {
20 articulosPromo: IArticulo[] = []; 20 articulosPromo: IArticulo[] = [];
21 promociones: IArticulo[] = []; 21 promociones: IArticulo[] = [];
22 onClose: Subject<any>; 22 onClose: Subject<any>;
23 urlImagenes = `${APP_SETTINGS.apiImagenes}/imagenes/`; 23 urlImagenes = `${APP_SETTINGS.apiImagenes}/imagenes/`;
24 loading = true; 24 loading = true;
25 modalSinonimo: BsModalRef;
26 isPromoSelected = false;
25 27
26 constructor( 28 constructor(
27 public modalPromocion: BsModalRef, 29 private modalPromocion: BsModalRef,
28 private modalService: BsModalService, 30 private modalService: BsModalService,
29 private articuloService: ArticuloService, 31 private articuloService: ArticuloService,
30 private promocionService: PromocionService, 32 private promocionService: PromocionService,
31 private sinonimoService: SinonimoService, 33 private sinonimoService: SinonimoService,
32 private inactiveScreen: InactiveScreenService, 34 private inactiveScreen: InactiveScreenService,
33 ) { 35 ) {
34 this.onClose = new Subject(); 36 this.onClose = new Subject();
35 } 37 }
36 38
37 ngOnInit() { 39 ngOnInit() {
38 this.getPromociones(); 40 this.getPromociones();
39 } 41 }
40 42
41 selectPromo(promo: IArticulo) { 43 selectPromo(promo: IArticulo) {
44 if (this.isPromoSelected) return;
45 this.isPromoSelected = true;
42 this.sinonimoService.getSinonimos(promo.CodSec, promo.CodArt) 46 this.sinonimoService.getSinonimos(promo.CodSec, promo.CodArt)
43 .subscribe((res: ISinonimo[]) => { 47 .subscribe((res: ISinonimo[]) => {
44 if (res.length) { 48 if (res.length) {
45 const sinonimos = []; 49 const sinonimos = [];
46 const gruposArticulos = _.groupBy(res[0].productos, 'ID_SIN'); 50 const gruposArticulos = _.groupBy(res[0].productos, 'ID_SIN');
47 Object.keys(gruposArticulos).forEach(key => { 51 Object.keys(gruposArticulos).forEach(key => {
48 sinonimos.push({ productos: gruposArticulos[key] }); 52 sinonimos.push({ productos: gruposArticulos[key] });
49 }); 53 });
50 res = sinonimos; 54 res = sinonimos;
51 this.openModalSinonimos(res, promo); 55 this.openModalSinonimos(res, promo);
52 } else { 56 } else {
53 promo.cantidad = 1; 57 promo.cantidad = 1;
54 this.articuloService.setArticulo(promo); 58 this.articuloService.setArticulo(promo);
59 this.onClose.next();
55 this.modalPromocion.hide(); 60 this.modalPromocion.hide();
56 } 61 }
57 }, err => console.error(err)); 62 }, err => console.error(err));
58 this.mediaPantalla(); 63 this.mediaPantalla();
59 } 64 }
60 65
61 openModalSinonimos(sinonimosData: ISinonimo[], articulo: IArticulo) { 66 openModalSinonimos(sinonimosData: ISinonimo[], articulo: IArticulo) {
62 const modalSinonimo = this.modalService.show(SinonimoComponent, { 67 if (this.modalSinonimo) return;
68 this.modalSinonimo = this.modalService.show(SinonimoComponent, {
63 initialState: { 69 initialState: {
64 sinonimos: sinonimosData, 70 sinonimos: sinonimosData,
65 articulo 71 articulo
66 }, 72 },
67 class: 'modal-dialog-centered' 73 class: 'modal-dialog-centered',
74 ignoreBackdropClick: true,
68 }); 75 });
69 76
70 modalSinonimo.content.onClose 77 this.modalSinonimo.content.onClose
71 .subscribe((res: any) => { 78 .subscribe((res: any) => {
79 this.modalSinonimo = null;
80 if (!res) {
81 this.onClose.next();
82 this.modalPromocion.hide();
83 return;
84 }
72 for (const a of articulo.productos) { 85 for (const a of articulo.productos) {
73 for (const aRes of res.articulos) { 86 for (const aRes of res.articulos) {
74 if (a.idSinonimo === aRes.ID_SIN) { 87 if (a.idSinonimo === aRes.ID_SIN) {
75 a.CODA = aRes.CodArt; 88 a.CODA = aRes.CodArt;
76 a.CodArt = aRes.CodArt; 89 a.CodArt = aRes.CodArt;
77 a.SECA = aRes.CodSec; 90 a.SECA = aRes.CodSec;
78 aRes.CodSec = aRes.CodSec; 91 aRes.CodSec = aRes.CodSec;
79 a.PreVen = aRes.PreVen; 92 a.PreVen = aRes.PreVen;
80 a.id = aRes.id; 93 a.id = aRes.id;
81 a.DET_LAR = aRes.DET_LAR; 94 a.DET_LAR = aRes.DET_LAR;
82 a.DetArt = aRes.DetArt; 95 a.DetArt = aRes.DetArt;
83 } 96 }
84 } 97 }
85 } 98 }
86 this.articuloService.setArticulo(articulo); 99 this.articuloService.setArticulo(articulo);
100 this.onClose.next();
87 this.modalPromocion.hide(); 101 this.modalPromocion.hide();
88 }); 102 });
89 } 103 }
90 104
91 getPromociones() { 105 getPromociones() {
92 const sector = this.articulosPromo[0].CodSec; 106 const sector = this.articulosPromo[0].CodSec;
93 const codigo = this.articulosPromo[0].CodArt; 107 const codigo = this.articulosPromo[0].CodArt;
94 this.promocionService.getPromociones(sector, codigo) 108 this.promocionService.getPromociones(sector, codigo)
95 .subscribe((res: IArticulo[]) => { 109 .subscribe((res: IArticulo[]) => {
96 this.promociones = res; 110 this.promociones = res;
97 this.loading = false; 111 this.loading = false;
98 }, error => { console.error(error); }); 112 }, error => { console.error(error); });
99 } 113 }
100 114
101 @HostListener('document:click', ['$event']) 115 @HostListener('document:click', ['$event'])
102 eventListener(event: Event) { 116 eventListener(event: Event) {
103 clearTimeout(this.inactiveScreen.timerReposo); 117 clearTimeout(this.inactiveScreen.timerReposo);
104 this.inactiveScreen.startTimeOutInactividad(); 118 this.inactiveScreen.startTimeOutInactividad();
105 } 119 }
106 120
107 @HostListener('scroll', ['$event']) 121 @HostListener('scroll', ['$event'])
108 scrollEvent(event: Event) { 122 scrollEvent(event: Event) {
109 clearTimeout(this.inactiveScreen.timerReposo); 123 clearTimeout(this.inactiveScreen.timerReposo);
110 this.inactiveScreen.startTimeOutInactividad(); 124 this.inactiveScreen.startTimeOutInactividad();
111 } 125 }
112 126
113 mediaPantalla() { 127 mediaPantalla() {
114 if ($('body').hasClass('media-pantalla')) { 128 if ($('body').hasClass('media-pantalla')) {
115 $('.modal-content').addClass('media-pantalla'); 129 $('.modal-content').addClass('media-pantalla');
116 } 130 }
117 } 131 }
118 } 132 }
119 133
src/app/shared/sinonimo/sinonimo.component.ts
1 import { Component, OnInit } from '@angular/core'; 1 import { Component, OnInit } from '@angular/core';
2 import { ISinonimo } from 'src/app/interfaces/ISinonimo'; 2 import { ISinonimo } from 'src/app/interfaces/ISinonimo';
3 import { IArticulo } from 'src/app/interfaces/IArticulo'; 3 import { IArticulo } from 'src/app/interfaces/IArticulo';
4 import { BsModalRef } from 'ngx-bootstrap/modal'; 4 import { BsModalRef } from 'ngx-bootstrap/modal';
5 import { Subject, forkJoin } from 'rxjs'; 5 import { Subject, forkJoin } from 'rxjs';
6 import { ArticuloService } from 'src/app/services/articulo/articulo.service'; 6 import { ArticuloService } from 'src/app/services/articulo/articulo.service';
7 import { element } from 'protractor'; 7 import { element } from 'protractor';
8 8
9 @Component({ 9 @Component({
10 selector: 'app-sinonimo', 10 selector: 'app-sinonimo',
11 templateUrl: './sinonimo.component.html', 11 templateUrl: './sinonimo.component.html',
12 styleUrls: ['./sinonimo.component.scss'] 12 styleUrls: ['./sinonimo.component.scss']
13 }) 13 })
14 export class SinonimoComponent implements OnInit { 14 export class SinonimoComponent implements OnInit {
15 sinonimos: ISinonimo[] = []; 15 sinonimos: ISinonimo[] = [];
16 isValid: boolean; 16 isValid: boolean;
17 onClose: Subject<any>; 17 onClose: Subject<any>;
18 articulosSelected: IArticulo[] = []; 18 articulosSelected: IArticulo[] = [];
19 articulo: IArticulo; 19 articulo: IArticulo;
20 isSinonimoSelected = false;
20 21
21 constructor( 22 constructor(
22 private modalRef: BsModalRef, 23 private modalRef: BsModalRef,
23 private articuloService: ArticuloService, 24 private articuloService: ArticuloService,
24 ) { 25 ) {
25 this.onClose = new Subject(); 26 this.onClose = new Subject();
26 this.articulosSelected.length = this.sinonimos.length; 27 this.articulosSelected.length = this.sinonimos.length;
27 } 28 }
28 29
29 ngOnInit() { } 30 ngOnInit() { }
30 31
31 selectSinonimo(index: number, articulo: IArticulo) { 32 selectSinonimo(index: number, articulo: IArticulo) {
32 for (const a of this.sinonimos[index].productos) { 33 for (const a of this.sinonimos[index].productos) {
33 a.seleccionado = false; 34 a.seleccionado = false;
34 } 35 }
35 articulo.seleccionado = true; 36 articulo.seleccionado = true;
36 this.articulosSelected[index] = articulo; 37 this.articulosSelected[index] = articulo;
37 } 38 }
38 39
39 validate() { 40 validate() {
40 this.isValid = true; 41 this.isValid = true;
41 for (const s of this.sinonimos) { 42 for (const s of this.sinonimos) {
42 for (const a of s.productos) { 43 for (const a of s.productos) {
43 this.isValid = (!a.seleccionado) ? false : true; 44 this.isValid = (!a.seleccionado) ? false : true;
44 if (this.isValid) break; 45 if (this.isValid) break;
45 } 46 }
46 if (!this.isValid) break; 47 if (!this.isValid) break;
47 } 48 }
48 return !this.isValid ? 'disabled' : 'btn-effect'; 49 return !this.isValid ? 'disabled' : 'btn-effect';
49 } 50 }
50 51
51 continue() { 52 continue() {
52 if (!this.isValid) return; 53 if (!this.isValid) return;
54 if (this.isSinonimoSelected) return;
55 this.isSinonimoSelected = true;
53 const ID_SINS = []; 56 const ID_SINS = [];
54 const observables = []; 57 const observables = [];
55 58
56 for (const articulo of this.articulosSelected) { 59 for (const articulo of this.articulosSelected) {
57 ID_SINS.push(articulo.ID_SIN); 60 ID_SINS.push(articulo.ID_SIN);
58 } 61 }
59 62
60 for (const articulo of this.articulosSelected) { 63 for (const articulo of this.articulosSelected) {
61 observables.push(this.articuloService.getById(articulo.id)); 64 observables.push(this.articuloService.getById(articulo.id));
62 } 65 }
63 66
64 forkJoin(observables) 67 forkJoin(observables)
65 .subscribe((res: IArticulo[]) => { 68 .subscribe((res: IArticulo[]) => {
66 for (const articulo of res) { 69 for (const articulo of res) {
67 for (const ID_SIN of ID_SINS) { 70 for (const ID_SIN of ID_SINS) {
68 articulo.ID_SIN = ID_SIN; 71 articulo.ID_SIN = ID_SIN;
69 } 72 }
70 } 73 }
71 this.modalRef.hide(); 74 this.modalRef.hide();
72 this.onClose.next({ 75 this.onClose.next({
73 articulos: res, 76 articulos: res,
74 }); 77 });
75 }, err => console.error(err)); 78 }, err => console.error(err));
76 } 79 }
77 80
78 scrollTo(index: number) { 81 scrollTo(index: number) {
79 const el = document.getElementById(index.toString()); 82 const el = document.getElementById(index.toString());
80 el.scrollIntoView({ behavior: 'smooth' }); 83 el.scrollIntoView({ behavior: 'smooth' });
81 } 84 }
82 85
83 close() { 86 close() {
84 this.modalRef.hide(); 87 this.modalRef.hide();
88 this.onClose.next();
85 } 89 }
86 90
87 } 91 }
88 92
src/scss/scroll.scss
1 @import "node_modules/bootstrap/scss/variables"; 1 @import "node_modules/bootstrap/scss/variables";
2 2
3 .scroll-y { 3 .scroll-y {
4 overflow-y: auto; 4 overflow-y: auto;
5 overflow-x: hidden;
5 scrollbar-width: none; 6 scrollbar-width: none;
6 &::-webkit-scrollbar { 7 &::-webkit-scrollbar {
7 display: none; 8 display: none;
8 } 9 }
9 } 10 }
10 11
11 .scroll-y-visible { 12 .scroll-y-visible {
12 overflow-y: auto; 13 overflow-y: auto;
14 overflow-x: hidden;
13 &::-webkit-scrollbar { 15 &::-webkit-scrollbar {
14 width: 0.75em; 16 width: 0.75em;
15 } 17 }
16 &::-webkit-scrollbar-track { 18 &::-webkit-scrollbar-track {
17 border-radius: 10px; 19 border-radius: 10px;
18 box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.4); 20 box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.4);
19 -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.4); 21 -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.4);
20 background-color: $white; 22 background-color: $white;
21 } 23 }
22 &::-webkit-scrollbar-thumb { 24 &::-webkit-scrollbar-thumb {
23 box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.7); 25 box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.7);
24 -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.7); 26 -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.7);
25 outline: 1px solid slategrey; 27 outline: 1px solid slategrey;
26 border-radius: 10px; 28 border-radius: 10px;
27 height: 12px; 29 height: 12px;
28 &:active { 30 &:active {
29 box-shadow: inset 0 0 8px $primary; 31 box-shadow: inset 0 0 8px $primary;
30 -webkit-box-shadow: inset 0 0 8px $primary; 32 -webkit-box-shadow: inset 0 0 8px $primary;
31 } 33 }
32 } 34 }
33 &::-webkit-scrollbar-corner { 35 &::-webkit-scrollbar-corner {
34 border-radius: 10px; 36 border-radius: 10px;
35 } 37 }
36 } 38 }
37 39
38 .scroll-x { 40 .scroll-x {
39 overflow-x: auto; 41 overflow-x: auto;
42 overflow-y: hidden;
40 scrollbar-width: none; 43 scrollbar-width: none;
41 &::-webkit-scrollbar { 44 &::-webkit-scrollbar {
42 display: none; 45 display: none;
43 } 46 }
44 } 47 }
45 48
src/scss/styles-bootstrap.scss
1 @import "node_modules/bootstrap/scss/functions"; 1 @import "node_modules/bootstrap/scss/functions";
2 @import "node_modules/bootstrap/scss/variables"; 2 @import "node_modules/bootstrap/scss/variables";
3 @import "node_modules/bootstrap/scss/mixins"; 3 @import "node_modules/bootstrap/scss/mixins";
4 4
5 $primary: #aa006b; 5 $primary: #aa006b;
6 $secondary: #00acd8; 6 $secondary: #00acd8;
7 $info: #f4b223; 7 $info: #f4b223;
8 $light: #e6e7e9; 8 $light: #e6e7e9;
9 $dark: #61666c; 9 $dark: #61666c;
10 $theme-colors: ( 10 $theme-colors: (
11 primary: $primary, 11 primary: $primary,
12 secondary: $secondary, 12 secondary: $secondary,
13 info: $info, 13 info: $info,
14 light: $light, 14 light: $light,
15 dark: $dark 15 dark: $dark
16 ); 16 );
17 $border-radius: 1.5rem; 17 $border-radius: 1.5rem;
18 $border-radius-lg: 2.5rem; 18 $border-radius-lg: 2.5rem;
19 $border-radius-sm: 0.5rem; 19 $border-radius-sm: 0.5rem;
20 20
21 .custom-modal { 21 .custom-modal {
22 max-width: 90% !important; 22 max-width: 90% !important;
23 & > .modal-content { 23 & > .modal-content {
24 background-color: $primary !important; 24 background-color: $primary !important;
25 color: white; 25 color: white;
26 border: none !important; 26 border: none !important;
27 border-radius: $border-radius !important; 27 border-radius: $border-radius !important;
28 box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; 28 box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
29 } 29 }
30 } 30 }
31 31
32 .carousel-control { 32 .carousel-control {
33 visibility: hidden !important; 33 visibility: hidden !important;
34 } 34 }
35 35
36 .carousel, 36 .carousel,
37 .carousel-inner, 37 .carousel-inner,
38 .carousel-item, 38 .carousel-item,
39 .item { 39 .item {
40 height: 100% !important; 40 height: 100% !important;
41 } 41 }
42 42
43 .custom-checkbox .custom-control-label::before { 43 .custom-checkbox .custom-control-label::before {
44 border-radius: 50% !important; 44 border-radius: 50% !important;
45 } 45 }
46 46
47 .custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { 47 .custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
48 background-color: $primary !important; 48 background-color: $primary !important;
49 } 49 }
50 50
51 .custom-checkbox .custom-control-input:checked:focus ~ .custom-control-label::before { 51 .custom-checkbox .custom-control-input:checked:focus ~ .custom-control-label::before {
52 box-shadow: none !important; 52 box-shadow: none !important;
53 } 53 }
54 .custom-checkbox .custom-control-input:focus ~ .custom-control-label::before { 54 .custom-checkbox .custom-control-input:focus ~ .custom-control-label::before {
55 box-shadow: none !important; 55 box-shadow: none !important;
56 } 56 }
57 57
58 .custom-control-input:checked ~ .custom-control-label::before { 58 .custom-control-input:checked ~ .custom-control-label::before {
59 background-color: white !important; 59 background-color: white !important;
60 border-color: white !important; 60 border-color: white !important;
61 border-width: 2px; 61 border-width: 2px;
62 } 62 }
63 63
64 .custom-checkbox .custom-control-input:active ~ .custom-control-label::before { 64 .custom-checkbox .custom-control-input:active ~ .custom-control-label::before {
65 background-color: $primary !important; 65 background-color: $primary !important;
66 } 66 }
67 67
68 .modal { 68 .modal {
69 background-color: #0000004d; 69 background-color: #0000004d;
70 } 70 }
71 71
72 .modal-content {
73 border: none !important;
74 }
75
72 .modal-content.media-pantalla { 76 .modal-content.media-pantalla {
73 margin-top: auto !important; 77 margin-top: auto !important;
74 margin-bottom: 50px !important; 78 margin-bottom: 50px !important;
75 } 79 }
76 80
77 .card { 81 .card {
78 border: none !important; 82 border: none !important;
79 } 83 }
80 84
81 @import "node_modules/bootstrap/scss/bootstrap"; 85 @import "node_modules/bootstrap/scss/bootstrap";
82 86