Commit 530021e7a87abffa0fb7d61b05c4a8002987496e
Exists in
master
and in
1 other branch
Merge branch 'master' of http://git.focasoftware.com/angular/autoservicio
Showing
46 changed files
Show diff stats
package.json
src/app/app.module.ts
... | ... | @@ -8,6 +8,7 @@ import { TooltipModule } from 'ngx-bootstrap/tooltip'; |
8 | 8 | import { PopoverModule } from 'ngx-bootstrap/popover'; |
9 | 9 | import { CarouselModule } from 'ngx-bootstrap/carousel'; |
10 | 10 | import { PaginationModule } from 'ngx-bootstrap/pagination'; |
11 | +import { ModalModule } from 'ngx-bootstrap/modal'; | |
11 | 12 | //#endregion |
12 | 13 | |
13 | 14 | //#region Keyboard |
... | ... | @@ -31,6 +32,8 @@ import { CancelarCompraComponent } from './components/cancelar-compra/cancelar-c |
31 | 32 | import { MensajeFinalComponent } from './components/mensaje-final/mensaje-final.component'; |
32 | 33 | import { ComandaComponent } from './components/comanda/comanda.component'; |
33 | 34 | import { PedidosSalientesComponent } from './components/pedidos-salientes/pedidos-salientes.component'; |
35 | +import { PagoConTarjetaComponent } from './components/pago-con-tarjeta/pago-con-tarjeta.component'; | |
36 | +import { ConfiguracionComponent } from './components/configuracion/configuracion.component'; | |
34 | 37 | //#endregion |
35 | 38 | |
36 | 39 | @NgModule({ |
... | ... | @@ -48,7 +51,9 @@ import { PedidosSalientesComponent } from './components/pedidos-salientes/pedido |
48 | 51 | CancelarCompraComponent, |
49 | 52 | MensajeFinalComponent, |
50 | 53 | ComandaComponent, |
51 | - PedidosSalientesComponent | |
54 | + PedidosSalientesComponent, | |
55 | + PagoConTarjetaComponent, | |
56 | + ConfiguracionComponent | |
52 | 57 | ], |
53 | 58 | imports: [ |
54 | 59 | BrowserModule, |
... | ... | @@ -63,9 +68,11 @@ import { PedidosSalientesComponent } from './components/pedidos-salientes/pedido |
63 | 68 | MatKeyboardModule, |
64 | 69 | MatButtonModule, |
65 | 70 | CarouselModule.forRoot(), |
66 | - PaginationModule.forRoot() | |
71 | + PaginationModule.forRoot(), | |
72 | + ModalModule.forRoot(), | |
67 | 73 | ], |
68 | 74 | providers: [], |
69 | - bootstrap: [AppComponent] | |
75 | + bootstrap: [AppComponent], | |
76 | + entryComponents: [PagoConTarjetaComponent, ConfiguracionComponent] | |
70 | 77 | }) |
71 | 78 | export class AppModule { } |
src/app/components/configuracion/configuracion.component.html
... | ... | @@ -0,0 +1,75 @@ |
1 | +<form [formGroup]="form" class="modal-body" id="modal-body"> | |
2 | + | |
3 | + <div class="row"> | |
4 | + <div class="col-12"> | |
5 | + | |
6 | + <p>¿Este punto de venta trabaja con planilla propia?</p> | |
7 | + | |
8 | + <!-- RADIO BUTTONS --> | |
9 | + <div class="text-center"> | |
10 | + <div class="disabled form-check form-check-inline"> | |
11 | + <input | |
12 | + class="form-check-input" | |
13 | + type="radio" | |
14 | + id="radio1" | |
15 | + formControlName="usePlanillaPropia" | |
16 | + [value]="true"> | |
17 | + | |
18 | + <label class="form-check-label" for="radio1">Si</label> | |
19 | + </div> | |
20 | + <div class="form-check form-check-inline"> | |
21 | + <input | |
22 | + class="form-check-input" | |
23 | + type="radio" | |
24 | + id="radio2" | |
25 | + formControlName="usePlanillaPropia" | |
26 | + [value]="false"> | |
27 | + <label class="form-check-label" for="radio2">No</label> | |
28 | + </div> | |
29 | + </div> | |
30 | + <div *ngIf="form.get('usePlanillaPropia').value === false" class="form-group"> | |
31 | + <select | |
32 | + formControlName="puntoVenta" | |
33 | + class="form-control form-control-sm w-50 mx-auto mt-2"> | |
34 | + <option [ngValue]="null" disabled>Seleccione una opción</option> | |
35 | + <option | |
36 | + *ngFor="let ptoVenta of puntosVenta" | |
37 | + [ngValue]="ptoVenta.ID"> | |
38 | + {{ptoVenta.ID}} {{ptoVenta.NOM}} | |
39 | + </option> | |
40 | + </select> | |
41 | + </div> | |
42 | + </div> | |
43 | + </div> | |
44 | + | |
45 | + <div *ngIf="impresoras.length > 0" class="row"> | |
46 | + <div class="col-12"> | |
47 | + <p>Salida de impresión de comprobantes</p> | |
48 | + <select | |
49 | + formControlName="impresora" | |
50 | + class="form-control form-control-sm w-50 mx-auto mt-2"> | |
51 | + <option [ngValue]="null" disabled>Seleccione una opción</option> | |
52 | + <option | |
53 | + *ngFor="let imp of impresoras" | |
54 | + [ngValue]="imp.PVE"> | |
55 | + {{imp.PVE}} {{imp.DES}} | |
56 | + </option> | |
57 | + </select> | |
58 | + </div> | |
59 | + </div> | |
60 | + | |
61 | +</form> | |
62 | + | |
63 | +<div class="modal-footer py-1"> | |
64 | + <button | |
65 | + class="btn btn-sm btn-secondary" | |
66 | + type="button" | |
67 | + (click)="close()">Cancelar | |
68 | + </button> | |
69 | + <button | |
70 | + class="btn btn-sm btn-primary" | |
71 | + type="button" | |
72 | + (click)="acept()" | |
73 | + >Aceptar | |
74 | + </button> | |
75 | +</div> |
src/app/components/configuracion/configuracion.component.scss
src/app/components/configuracion/configuracion.component.spec.ts
... | ... | @@ -0,0 +1,25 @@ |
1 | +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { ConfiguracionComponent } from './configuracion.component'; | |
4 | + | |
5 | +describe('ConfiguracionComponent', () => { | |
6 | + let component: ConfiguracionComponent; | |
7 | + let fixture: ComponentFixture<ConfiguracionComponent>; | |
8 | + | |
9 | + beforeEach(async(() => { | |
10 | + TestBed.configureTestingModule({ | |
11 | + declarations: [ ConfiguracionComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + })); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(ConfiguracionComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/components/configuracion/configuracion.component.ts
... | ... | @@ -0,0 +1,78 @@ |
1 | +import { Component, OnInit } from '@angular/core'; | |
2 | +import { BsModalRef } from 'ngx-bootstrap'; | |
3 | +import { PuntoVentaService } from 'src/app/services/punto-venta.service'; | |
4 | +import { PuntoVenta } from 'src/app/wrappers/puntoVenta'; | |
5 | +import { ImpresoraService } from 'src/app/services/impresora.service'; | |
6 | +import { Impresora } from 'src/app/wrappers/impresora'; | |
7 | +import { FormGroup, FormControl } from '@angular/forms'; | |
8 | + | |
9 | +@Component({ | |
10 | + selector: 'app-configuracion', | |
11 | + templateUrl: './configuracion.component.html', | |
12 | + styleUrls: ['./configuracion.component.scss'] | |
13 | +}) | |
14 | +export class ConfiguracionComponent implements OnInit { | |
15 | + | |
16 | + puntosVenta: PuntoVenta[] = []; | |
17 | + impresoras: Impresora[] = []; | |
18 | + form: FormGroup; | |
19 | + | |
20 | + constructor( | |
21 | + private activeModal: BsModalRef, | |
22 | + private puntoVentaService: PuntoVentaService, | |
23 | + private impresoraService: ImpresoraService, | |
24 | + ) { } | |
25 | + | |
26 | + ngOnInit() { | |
27 | + | |
28 | + this.form = new FormGroup({ | |
29 | + usePlanillaPropia: new FormControl(false, []), | |
30 | + puntoVenta: new FormControl(null, []), | |
31 | + impresora: new FormControl(null, []), | |
32 | + }) | |
33 | + | |
34 | + this.puntoVentaService.getAll() | |
35 | + .subscribe((res: PuntoVenta[]) => { | |
36 | + | |
37 | + this.puntosVenta = res; | |
38 | + this.setPuntoVenta(); | |
39 | + }, console.error); | |
40 | + | |
41 | + this.impresoraService.getAll() | |
42 | + .subscribe((res: Impresora[]) => { | |
43 | + | |
44 | + this.impresoras = res; | |
45 | + this.setImpresora(); | |
46 | + }, console.error); | |
47 | + | |
48 | + } | |
49 | + | |
50 | + close() { | |
51 | + | |
52 | + this.activeModal.hide(); | |
53 | + } | |
54 | + | |
55 | + acept() { | |
56 | + | |
57 | + let auxPuntoVenta = this.puntosVenta.find(p => p.ID === this.form.get('puntoVenta').value); | |
58 | + let auxImpresora = this.impresoras.find(p => p.PVE === this.form.get('impresora').value); | |
59 | + localStorage.setItem('pve', auxPuntoVenta ? auxPuntoVenta.ID.toString() : null); | |
60 | + localStorage.setItem('impresoraPVE', auxImpresora ? auxImpresora.PVE.toString() : null); | |
61 | + this.close(); | |
62 | + } | |
63 | + | |
64 | + setPuntoVenta() { | |
65 | + | |
66 | + let pve = parseInt(localStorage.getItem('pve')); | |
67 | + let auxPuntoVenta = this.puntosVenta.find(x => x.ID === pve); | |
68 | + this.form.get('puntoVenta').setValue(auxPuntoVenta ? auxPuntoVenta.ID : null); | |
69 | + } | |
70 | + | |
71 | + setImpresora() { | |
72 | + | |
73 | + let impresoraPVE = parseInt(localStorage.getItem('impresoraPVE')); | |
74 | + let auxImpresora = this.impresoras.find(x => x.PVE === impresoraPVE); | |
75 | + this.form.get('impresora').setValue(auxImpresora ? auxImpresora.PVE : null); | |
76 | + } | |
77 | + | |
78 | +} |
src/app/components/confirmacion-carrito/confirmacion-carrito.component.html
... | ... | @@ -27,6 +27,19 @@ |
27 | 27 | <div class="col-sm-9 my-auto"> |
28 | 28 | <p class="h4">Por favor, controle y confirme su compra.</p> |
29 | 29 | </div> |
30 | + <label for="customLabel" class="col-auto font-weight-bold h4 m-0"> | |
31 | + Pedido a nombre de: | |
32 | + </label> | |
33 | + <div class="col-12 col-sm-6 col-md-5 col-lg-5"> | |
34 | + <input | |
35 | + type="text" | |
36 | + class="form-control text-center" | |
37 | + id="customLabel" | |
38 | + maxlength="24" | |
39 | + [(ngModel)]="pedidoAnombreDe" | |
40 | + autofocus | |
41 | + > | |
42 | + </div> | |
30 | 43 | </div> |
31 | 44 | |
32 | 45 | <div [ngClass]="{'mt-5': verQR}" class="row m-0"> |
... | ... | @@ -168,7 +181,8 @@ |
168 | 181 | </div> |
169 | 182 | |
170 | 183 | <!-- TARJETA --> |
171 | - <div class="row card-effect card-forma-pago mx-1 my-3 rounded-sm shadow-sm bg-white"> | |
184 | + <div class="row card-effect card-forma-pago mx-1 my-3 rounded-sm shadow-sm bg-white" | |
185 | + (click)="abrirPagoConTarjeta()"> | |
172 | 186 | <div class="col-7 text-center my-auto px-2"> |
173 | 187 | <span class="h5 font-weight-bold">Tarjeta</span> |
174 | 188 | </div> |
src/app/components/confirmacion-carrito/confirmacion-carrito.component.ts
... | ... | @@ -5,6 +5,8 @@ import { ProductoService } from 'src/app/services/producto.service'; |
5 | 5 | import { Producto } from 'src/app/wrappers/producto'; |
6 | 6 | import { Router } from '@angular/router'; |
7 | 7 | import { Subscription } from 'rxjs'; |
8 | +import { BsModalService } from 'ngx-bootstrap'; | |
9 | +import { PagoConTarjetaComponent } from '../pago-con-tarjeta/pago-con-tarjeta.component'; | |
8 | 10 | |
9 | 11 | @Component({ |
10 | 12 | selector: 'app-confirmacion-carrito', |
... | ... | @@ -13,19 +15,21 @@ import { Subscription } from 'rxjs'; |
13 | 15 | }) |
14 | 16 | export class ConfirmacionCarritoComponent implements OnInit, OnDestroy { |
15 | 17 | |
16 | - private productos: Producto[] = []; | |
17 | - private total: number = 0; | |
18 | 18 | private apiImagenes: string = appSettings.apiImagenes; |
19 | - private timerReposo: any; | |
20 | 19 | private compraConEfectivofinalizada: boolean = false; |
21 | 20 | private compraConQRfinalizada: boolean = false; |
21 | + private productos: Producto[] = []; | |
22 | + private total: number = 0; | |
23 | + private timerReposo: any; | |
22 | 24 | private verQR: boolean = false; |
23 | 25 | private subscribePago: Subscription; |
26 | + private pedidoAnombreDe: string = ''; | |
24 | 27 | |
25 | 28 | constructor( |
26 | 29 | private location: Location, |
27 | 30 | private productoService: ProductoService, |
28 | - private router: Router | |
31 | + private router: Router, | |
32 | + private modalService: BsModalService, | |
29 | 33 | ) { } |
30 | 34 | |
31 | 35 | ngOnInit() { |
... | ... | @@ -39,13 +43,17 @@ export class ConfirmacionCarritoComponent implements OnInit, OnDestroy { |
39 | 43 | |
40 | 44 | ngOnDestroy() { |
41 | 45 | |
42 | - this.subscribePago.unsubscribe(); | |
46 | + if (this.subscribePago !== undefined) { | |
47 | + this.subscribePago.unsubscribe(); | |
48 | + } | |
43 | 49 | clearTimeout(this.timerReposo); |
44 | 50 | } |
45 | 51 | |
46 | 52 | volverPreviousPage() { |
47 | 53 | |
48 | - this.subscribePago.unsubscribe(); | |
54 | + if (this.subscribePago !== undefined) { | |
55 | + this.subscribePago.unsubscribe(); | |
56 | + } | |
49 | 57 | |
50 | 58 | if (this.verQR) { |
51 | 59 | this.verQR = !this.verQR; |
... | ... | @@ -77,21 +85,19 @@ export class ConfirmacionCarritoComponent implements OnInit, OnDestroy { |
77 | 85 | //#region METODOS PARA LA FORMA DE PAGO |
78 | 86 | pagar(medioPago: number) { |
79 | 87 | |
80 | - if (medioPago === 9) { | |
81 | - | |
82 | - this.verQR = true; | |
88 | + this.verQR = medioPago === 9 ? true : false; | |
89 | + let dataPago = { | |
90 | + medioPago: medioPago, | |
91 | + pedidoAnombreDe: this.pedidoAnombreDe | |
83 | 92 | } |
84 | - | |
85 | - this.subscribePago = this.productoService.pagar(medioPago) | |
86 | - .subscribe(() => { | |
93 | + this.subscribePago = this.productoService.pagar(dataPago) | |
94 | + .subscribe((res: any) => { | |
87 | 95 | |
88 | 96 | clearTimeout(this.timerReposo); |
89 | - | |
97 | + | |
90 | 98 | if (medioPago === 1) { |
91 | - | |
92 | 99 | this.compraConEfectivofinalizada = true; |
93 | 100 | } else if (medioPago === 9) { |
94 | - | |
95 | 101 | this.compraConQRfinalizada = true; |
96 | 102 | } |
97 | 103 | |
... | ... | @@ -100,10 +106,19 @@ export class ConfirmacionCarritoComponent implements OnInit, OnDestroy { |
100 | 106 | this.router.navigate(['mensaje-final']); |
101 | 107 | }, 10000); |
102 | 108 | }, err => { |
103 | - console.log(err); | |
104 | - alert('algo salió mal'); | |
109 | + | |
110 | + console.error(err); | |
111 | + alert('Algo salió mal'); | |
105 | 112 | }) |
106 | 113 | } |
107 | 114 | //#endregion |
108 | 115 | |
116 | + abrirPagoConTarjeta() { | |
117 | + | |
118 | + this.modalService.show(PagoConTarjetaComponent, { | |
119 | + class: 'modal-lg', | |
120 | + ignoreBackdropClick: true, | |
121 | + initialState: { importeTotal: this.total }, | |
122 | + }); | |
123 | + } | |
109 | 124 | } |
src/app/components/header/header.component.html
1 | 1 | <div class="row m-0 bg-light p-3 justify-content-between"> |
2 | 2 | <div class="col-6"> |
3 | - <img class="w-25 float-left" src="{{apiImagenes}}/imagenes/logoempresa.png"> | |
3 | + <img | |
4 | + draggable="false" | |
5 | + ondragstart="return false;" | |
6 | + (contextmenu)="false" | |
7 | + (press)="openConfigurationScreen()" | |
8 | + class="w-25 float-left" | |
9 | + src="{{apiImagenes}}/imagenes/logoempresa.png"> | |
4 | 10 | </div> |
5 | 11 | <div class="col-6"> |
6 | 12 | <img class="w-25 float-right" src="{{apiImagenes}}/imagenes/logodebo.png"> |
src/app/components/header/header.component.ts
1 | -import { Component, OnInit } from '@angular/core'; | |
1 | +import { Component, OnInit, HostListener } from '@angular/core'; | |
2 | 2 | import { appSettings } from 'src/etc/AppSettings'; |
3 | +import { BsModalService } from 'ngx-bootstrap'; | |
4 | +import { ConfiguracionComponent } from '../configuracion/configuracion.component'; | |
3 | 5 | |
4 | 6 | @Component({ |
5 | 7 | selector: 'app-header', |
... | ... | @@ -9,10 +11,37 @@ import { appSettings } from 'src/etc/AppSettings'; |
9 | 11 | export class HeaderComponent implements OnInit { |
10 | 12 | |
11 | 13 | private apiImagenes : string = appSettings.apiImagenes; |
14 | + timer: any; | |
15 | + isShowModalConfiguration = false; | |
12 | 16 | |
13 | - constructor() { } | |
17 | + constructor( | |
18 | + private modalService: BsModalService, | |
19 | + ) { } | |
14 | 20 | |
15 | 21 | ngOnInit() { |
16 | 22 | } |
17 | 23 | |
24 | + @HostListener('document:keydown.Control.Shift.A', ['$event']) | |
25 | + openConfigurationScreen(delay: number = 3000) { | |
26 | + | |
27 | + if (this.isShowModalConfiguration) return; | |
28 | + | |
29 | + this.modalService.onHide | |
30 | + .subscribe(() => this.isShowModalConfiguration = false); | |
31 | + | |
32 | + this.timer = setTimeout(() => { | |
33 | + | |
34 | + this.isShowModalConfiguration = true; | |
35 | + this.modalService.show(ConfiguracionComponent, { | |
36 | + class: 'modal-md', | |
37 | + ignoreBackdropClick: true, | |
38 | + }); | |
39 | + }, delay); | |
40 | + } | |
41 | + | |
42 | + resetCountDown() { | |
43 | + | |
44 | + clearTimeout(this.timer); | |
45 | + } | |
46 | + | |
18 | 47 | } |
src/app/components/pago-con-tarjeta/pago-con-tarjeta.component.html
... | ... | @@ -0,0 +1,134 @@ |
1 | +<div class="modal-header p-2"> | |
2 | + <div class="row m-0 w-100"> | |
3 | + <div class="col"> | |
4 | + <span class="h4 m-0">Pago con tarjeta</span> | |
5 | + </div> | |
6 | + </div> | |
7 | +</div> | |
8 | + | |
9 | +<div class="modal-body" id="modal-body"> | |
10 | + <!-- TARJETAS --> | |
11 | + <div class="w-75 mx-auto card-columns"> | |
12 | + <div | |
13 | + class="card card-effect shadow-sm rounded-sm" | |
14 | + [ngClass]="{'active': tarjetaSeleccionada && tarjetaSeleccionada.ID === tarjeta.ID}" | |
15 | + (click)="seleccionarTarjeta(tarjeta)" | |
16 | + *ngFor="let tarjeta of tarjetas"> | |
17 | + <img | |
18 | + class="w-100 p-1" | |
19 | + src="../../../assets/img/{{tarjeta.nombreImagen ? tarjeta.nombreImagen : 'generica.png'}}"> | |
20 | + </div> | |
21 | + </div> | |
22 | + <!-- FORMULARIO --> | |
23 | + <div class="border-top w-75 mx-auto" *ngIf="showForm"> | |
24 | + <div class="row mt-2 fade-in"> | |
25 | + <form [formGroup]="form" class="col" novalidate> | |
26 | + <!-- TARJETA SELECCIONADA --> | |
27 | + <div class="row py-2"> | |
28 | + <div class="col-auto pr-1"> | |
29 | + <span class="font-weight-bold">{{tarjetaSeleccionada.ID}}</span> | |
30 | + </div> | |
31 | + <div class="col-auto pl-2"> | |
32 | + <span class="font-weight-bold">{{tarjetaSeleccionada.NOM}}</span> | |
33 | + </div> | |
34 | + </div> | |
35 | + <!-- IMPORTE --> | |
36 | + <div class="row pb-2"> | |
37 | + <div class="col-auto pr-1"> | |
38 | + <span>Importe</span> | |
39 | + </div> | |
40 | + <div class="col-auto pl-2"> | |
41 | + <span class="font-weight-bold">{{ importeTotal | currency}}</span> | |
42 | + </div> | |
43 | + </div> | |
44 | + <!-- NUMERO TERMINAL --> | |
45 | + <div class="row pb-2"> | |
46 | + <div class="col-auto pr-1"> | |
47 | + <span>Terminal Nº</span> | |
48 | + </div> | |
49 | + <div class="col-12 col-md-auto pl-md-1"> | |
50 | + <div class="input-group"> | |
51 | + <input | |
52 | + formControlName="terminal" | |
53 | + class="form-control form-control-sm" | |
54 | + maxlength="45"> | |
55 | + </div> | |
56 | + <p | |
57 | + *ngIf="form.get('terminal').errors?.required && form.get('terminal').dirty" | |
58 | + class="m-0 wobble-hor-bottom text-danger font-weight-light"> | |
59 | + <small>Campo requerido*</small> | |
60 | + </p> | |
61 | + <p | |
62 | + *ngIf="form.get('terminal').errors?.pattern && form.get('terminal').dirty" | |
63 | + class="m-0 wobble-hor-bottom text-danger font-weight-light"> | |
64 | + <small>Solo números*</small> | |
65 | + </p> | |
66 | + </div> | |
67 | + </div> | |
68 | + <!-- NUMERO DE CUPON --> | |
69 | + <div class="row pb-2"> | |
70 | + <div class="col-auto pr-1"> | |
71 | + <span>Número de Cupón</span> | |
72 | + </div> | |
73 | + <div class="col-12 col-md-auto pl-md-1"> | |
74 | + <div class="input-group"> | |
75 | + <input | |
76 | + formControlName="numeroCupon" | |
77 | + class="form-control form-control-sm" | |
78 | + maxlength="45"> | |
79 | + </div> | |
80 | + <p | |
81 | + *ngIf="form.get('numeroCupon').errors?.required && form.get('numeroCupon').dirty" | |
82 | + class="m-0 wobble-hor-bottom text-danger font-weight-light"> | |
83 | + <small>Campo requerido*</small> | |
84 | + </p> | |
85 | + <p | |
86 | + *ngIf="form.get('numeroCupon').errors?.pattern && form.get('numeroCupon').dirty" | |
87 | + class="m-0 wobble-hor-bottom text-danger font-weight-light"> | |
88 | + <small>Solo números*</small> | |
89 | + </p> | |
90 | + </div> | |
91 | + </div> | |
92 | + <!-- CUOTAS --> | |
93 | + <div class="row pb-2"> | |
94 | + <div class="col-auto pr-1"> | |
95 | + <span>Cuotas</span> | |
96 | + </div> | |
97 | + <div class="col-12 col-md-auto pl-md-1"> | |
98 | + <div class="input-group"> | |
99 | + <input | |
100 | + formControlName="cuotas" | |
101 | + class="form-control form-control-sm" | |
102 | + maxlength="45"> | |
103 | + </div> | |
104 | + <p | |
105 | + *ngIf="form.get('cuotas').errors?.required && form.get('cuotas').dirty" | |
106 | + class="m-0 wobble-hor-bottom text-danger font-weight-light"> | |
107 | + <small>Campo requerido*</small> | |
108 | + </p> | |
109 | + <p | |
110 | + *ngIf="form.get('cuotas').errors?.pattern && form.get('cuotas').dirty" | |
111 | + class="m-0 wobble-hor-bottom text-danger font-weight-light"> | |
112 | + <small>Solo números*</small> | |
113 | + </p> | |
114 | + </div> | |
115 | + </div> | |
116 | + </form> | |
117 | + </div> | |
118 | + </div> | |
119 | +</div> | |
120 | + | |
121 | +<div class="modal-footer py-1"> | |
122 | + <button | |
123 | + class="btn btn-sm btn-secondary" | |
124 | + type="button" | |
125 | + (click)="close()"> | |
126 | + Cancelar | |
127 | + </button> | |
128 | + <button | |
129 | + class="btn btn-sm btn-primary" | |
130 | + type="button" | |
131 | + [disabled]="!form.valid"> | |
132 | + Guardar | |
133 | + </button> | |
134 | +</div> |
src/app/components/pago-con-tarjeta/pago-con-tarjeta.component.scss
... | ... | @@ -0,0 +1,28 @@ |
1 | +app-pago-con-tarjeta { | |
2 | + user-select: none !important; | |
3 | +} | |
4 | + | |
5 | +.card-columns { | |
6 | + column-count: 6 !important; | |
7 | + column-gap: 0.5rem !important; | |
8 | + @media (max-width: 576px) { | |
9 | + column-count: 3 !important; | |
10 | + } | |
11 | +} | |
12 | + | |
13 | +.card-effect { | |
14 | + border-width: 2px !important; | |
15 | + &:hover { | |
16 | + background-color: #c9c9c9b3 !important; | |
17 | + transition: background-color 0.3s; | |
18 | + } | |
19 | + &:active { | |
20 | + border-color: #2872ae !important; | |
21 | + transition: background-color 0.3s; | |
22 | + } | |
23 | +} | |
24 | + | |
25 | +.active { | |
26 | + border-color: #2872ae !important; | |
27 | + transition: background-color 0.3s; | |
28 | +} |
src/app/components/pago-con-tarjeta/pago-con-tarjeta.component.spec.ts
... | ... | @@ -0,0 +1,25 @@ |
1 | +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { PagoConTarjetaComponent } from './pago-con-tarjeta.component'; | |
4 | + | |
5 | +describe('PagoConTarjetaComponent', () => { | |
6 | + let component: PagoConTarjetaComponent; | |
7 | + let fixture: ComponentFixture<PagoConTarjetaComponent>; | |
8 | + | |
9 | + beforeEach(async(() => { | |
10 | + TestBed.configureTestingModule({ | |
11 | + declarations: [ PagoConTarjetaComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + })); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(PagoConTarjetaComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/components/pago-con-tarjeta/pago-con-tarjeta.component.ts
... | ... | @@ -0,0 +1,55 @@ |
1 | +import { Component, OnInit } from '@angular/core'; | |
2 | +import { BsModalRef } from 'ngx-bootstrap'; | |
3 | +import { TarjetasService } from 'src/app/services/tarjetas.service'; | |
4 | +import { Tarjeta } from 'src/app/wrappers/tarjeta'; | |
5 | +import { FormGroup, FormControl, Validators } from '@angular/forms'; | |
6 | + | |
7 | +@Component({ | |
8 | + selector: 'app-pago-con-tarjeta', | |
9 | + templateUrl: './pago-con-tarjeta.component.html', | |
10 | + styleUrls: ['./pago-con-tarjeta.component.scss'], | |
11 | +}) | |
12 | +export class PagoConTarjetaComponent implements OnInit { | |
13 | + | |
14 | + private showForm = false; | |
15 | + private importeTotal: number; | |
16 | + private tarjetas: Tarjeta[] = []; | |
17 | + private tarjetaSeleccionada: Tarjeta; | |
18 | + private form: FormGroup; | |
19 | + | |
20 | + constructor( | |
21 | + private modalRef: BsModalRef, | |
22 | + private tarjetasService: TarjetasService, | |
23 | + ) { } | |
24 | + | |
25 | + ngOnInit() { | |
26 | + | |
27 | + this.tarjetasService.getTarjetas() | |
28 | + .subscribe((res: Tarjeta[]) => { | |
29 | + | |
30 | + this.tarjetas = res; | |
31 | + }, err => console.error(err)); | |
32 | + | |
33 | + this.setForm(); | |
34 | + } | |
35 | + | |
36 | + setForm() { | |
37 | + | |
38 | + this.form = new FormGroup({ | |
39 | + terminal: new FormControl('', [Validators.required, Validators.pattern("^[0-9]*$")]), | |
40 | + numeroCupon: new FormControl('', [Validators.required, Validators.pattern("^[0-9]*$")]), | |
41 | + cuotas: new FormControl('', [Validators.required, Validators.pattern("^[0-9]*$")]), | |
42 | + }) | |
43 | + } | |
44 | + | |
45 | + seleccionarTarjeta(tarjeta: Tarjeta) { | |
46 | + | |
47 | + this.tarjetaSeleccionada = tarjeta; | |
48 | + this.showForm = true; | |
49 | + } | |
50 | + | |
51 | + close() { | |
52 | + | |
53 | + this.modalRef.hide() | |
54 | + } | |
55 | +} |
src/app/services/impresora.service.spec.ts
... | ... | @@ -0,0 +1,12 @@ |
1 | +import { TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { ImpresoraService } from './impresora.service'; | |
4 | + | |
5 | +describe('ImpresoraService', () => { | |
6 | + beforeEach(() => TestBed.configureTestingModule({})); | |
7 | + | |
8 | + it('should be created', () => { | |
9 | + const service: ImpresoraService = TestBed.get(ImpresoraService); | |
10 | + expect(service).toBeTruthy(); | |
11 | + }); | |
12 | +}); |
src/app/services/impresora.service.ts
... | ... | @@ -0,0 +1,22 @@ |
1 | +import { Injectable } from '@angular/core'; | |
2 | +import { appSettings } from 'src/etc/AppSettings'; | |
3 | +import { HttpClient } from '@angular/common/http'; | |
4 | +import { Observable } from 'rxjs/internal/Observable'; | |
5 | + | |
6 | +@Injectable({ | |
7 | + providedIn: 'root' | |
8 | +}) | |
9 | +export class ImpresoraService { | |
10 | + | |
11 | + private apiAutoservicio = appSettings.apiUrl; | |
12 | + | |
13 | + constructor( | |
14 | + private http: HttpClient, | |
15 | + ) { } | |
16 | + | |
17 | + getAll(): Observable<any> { | |
18 | + | |
19 | + return this.http.get(`${this.apiAutoservicio}/get/impresoras`); | |
20 | + } | |
21 | + | |
22 | +} |
src/app/services/producto.service.ts
... | ... | @@ -77,19 +77,23 @@ export class ProductoService { |
77 | 77 | } |
78 | 78 | |
79 | 79 | getCategorias() { |
80 | + | |
80 | 81 | return this.http.get(`${appSettings.apiUrl}/categorias`); |
81 | 82 | } |
82 | 83 | |
83 | - pagar(medioPago: number) { | |
84 | + pagar(dataPago: any) { | |
84 | 85 | |
85 | 86 | return new Observable((observer) => { |
86 | 87 | |
87 | 88 | this.clienteService.getClienteById(-1).subscribe(cliente => { |
88 | 89 | |
89 | - this.http.post(`${appSettings.apiUrl}/comprobante/guardar/${medioPago}`, { | |
90 | + this.http.post(`${appSettings.apiUrl}/comprobante/guardar/${dataPago.medioPago}`, { | |
90 | 91 | productos: this.productos, |
91 | 92 | cliente: cliente, |
92 | - origen: 'autoservicio' | |
93 | + origen: 'autoservicio', | |
94 | + codigoVendedor: 5, | |
95 | + puntoVenta: parseInt(localStorage.getItem('impresoraPVE')), | |
96 | + pedidoAnombreDe: dataPago.pedidoAnombreDe, | |
93 | 97 | }).subscribe((data) => { |
94 | 98 | |
95 | 99 | observer.next(data); |
src/app/services/punto-venta.service.spec.ts
... | ... | @@ -0,0 +1,12 @@ |
1 | +import { TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { PuntoVentaService } from './punto-venta.service'; | |
4 | + | |
5 | +describe('PuntoVentaService', () => { | |
6 | + beforeEach(() => TestBed.configureTestingModule({})); | |
7 | + | |
8 | + it('should be created', () => { | |
9 | + const service: PuntoVentaService = TestBed.get(PuntoVentaService); | |
10 | + expect(service).toBeTruthy(); | |
11 | + }); | |
12 | +}); |
src/app/services/punto-venta.service.ts
... | ... | @@ -0,0 +1,32 @@ |
1 | +import { Injectable } from '@angular/core'; | |
2 | +import { Observable } from 'rxjs/internal/Observable'; | |
3 | +import { appSettings } from 'src/etc/AppSettings'; | |
4 | +import { HttpClient } from '@angular/common/http'; | |
5 | + | |
6 | +@Injectable({ | |
7 | + providedIn: 'root' | |
8 | +}) | |
9 | +export class PuntoVentaService { | |
10 | + | |
11 | + private apiAutoservico = appSettings.apiUrl; | |
12 | + | |
13 | + constructor( | |
14 | + private http: HttpClient | |
15 | + ) { } | |
16 | + | |
17 | + getAll(): Observable<any> { | |
18 | + | |
19 | + return this.http.get(`${this.apiAutoservico}/get/puntos-venta`); | |
20 | + } | |
21 | + | |
22 | + getByID(id: number): Observable<any> { | |
23 | + | |
24 | + return this.http.get(`${this.apiAutoservico}/get/punto-venta/${id}`); | |
25 | + } | |
26 | + | |
27 | + getVendedor(filter: any = {}): Observable<any> { | |
28 | + | |
29 | + return this.http.get(`${this.apiAutoservico}/get/vendedor/${JSON.stringify(filter)}`); | |
30 | + } | |
31 | + | |
32 | +} |
src/app/services/tarjetas.service.spec.ts
... | ... | @@ -0,0 +1,12 @@ |
1 | +import { TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { TarjetasService } from './tarjetas.service'; | |
4 | + | |
5 | +describe('TarjetasService', () => { | |
6 | + beforeEach(() => TestBed.configureTestingModule({})); | |
7 | + | |
8 | + it('should be created', () => { | |
9 | + const service: TarjetasService = TestBed.get(TarjetasService); | |
10 | + expect(service).toBeTruthy(); | |
11 | + }); | |
12 | +}); |
src/app/services/tarjetas.service.ts
... | ... | @@ -0,0 +1,17 @@ |
1 | +import { Injectable } from '@angular/core'; | |
2 | +import { HttpClient } from '@angular/common/http'; | |
3 | +import { Observable } from 'rxjs'; | |
4 | +import { appSettings } from 'src/etc/AppSettings'; | |
5 | + | |
6 | +@Injectable({ | |
7 | + providedIn: 'root' | |
8 | +}) | |
9 | +export class TarjetasService { | |
10 | + | |
11 | + constructor(private http: HttpClient) { } | |
12 | + | |
13 | + getTarjetas(): Observable<any> { | |
14 | + | |
15 | + return this.http.get(`${appSettings.apiUrl}/tarjetas`); | |
16 | + } | |
17 | +} |
src/app/wrappers/impresora.ts
... | ... | @@ -0,0 +1,66 @@ |
1 | +export interface Impresora { | |
2 | + PVE: number; | |
3 | + TIP: string; | |
4 | + MAR: string; | |
5 | + DES: string; | |
6 | + IMP: string; | |
7 | + PVM: number; | |
8 | + COM: string; | |
9 | + LPT: string; | |
10 | + LRE: string; | |
11 | + CAJ: boolean; | |
12 | + NUI: string; | |
13 | + EFA: boolean; | |
14 | + NCA: number; | |
15 | + OPE: number; | |
16 | + EJE: number; | |
17 | + IDF: number; | |
18 | + POS: number; | |
19 | + UCZ: Date; | |
20 | + MIH: number; | |
21 | + EPS: boolean; | |
22 | + BAU: number; | |
23 | + RSP: string; | |
24 | + ERR: string; | |
25 | + HAC: boolean; | |
26 | + CAI: string; | |
27 | + FCAI: Date; | |
28 | + PNFF: boolean; | |
29 | + PVERS: boolean; | |
30 | + NOIMPCYNC: boolean; | |
31 | + H23L_CC: number; | |
32 | + SINCRO: boolean; | |
33 | + COM_CTRLM: number; | |
34 | + TCAE: boolean; | |
35 | + USA_FT_NC: boolean; | |
36 | + RNFH: boolean; | |
37 | + NDF: boolean; | |
38 | + MAX_ITEM: string; | |
39 | + CTRL_NUM: boolean; | |
40 | + MULTI_PV: boolean; | |
41 | + MOD_SLIP: boolean; | |
42 | + NCC_FISCAL: boolean; | |
43 | + CT_FISCAL: boolean; | |
44 | + CPI: number; | |
45 | + E_HD: string; | |
46 | + C_HD: string; | |
47 | + ITEM_EXT_PR4: boolean; | |
48 | + BMAIL: boolean; | |
49 | + RE_PDF_ELEC: boolean; | |
50 | + LX300_DIR3: number; | |
51 | + TIP_AP_CAJ: number; | |
52 | + RNREU: boolean; | |
53 | + PUERTO: number; | |
54 | + IP: string; | |
55 | + AUTORIZA_CAE_MANUAL: boolean; | |
56 | + MUE_FEV_IMP: boolean; | |
57 | + FAC_LX300: boolean; | |
58 | + IMAGEN_FE_A: string; | |
59 | + IMAGEN_FE_B: string; | |
60 | + CanItemRem: number; | |
61 | + TCAEA: boolean; | |
62 | + CaCoRe: number; | |
63 | + RCUYT: boolean; | |
64 | + CanItemFE: string; | |
65 | + ImprimeElecTermica: boolean; | |
66 | +} |
src/app/wrappers/puntoVenta.ts
... | ... | @@ -0,0 +1,41 @@ |
1 | +export interface PuntoVenta { | |
2 | + ID: number; | |
3 | + NOM: string; | |
4 | + DES: string; | |
5 | + LUG: string; | |
6 | + EST: string; | |
7 | + MAR: string; | |
8 | + NSE: string; | |
9 | + MOD: string; | |
10 | + MEM: number; | |
11 | + OBS: string; | |
12 | + PVE: number; | |
13 | + EJE: number; | |
14 | + OPE: number; | |
15 | + IDC: boolean; | |
16 | + TER_TOUCH: boolean; | |
17 | + ARQ_PENDIENTE: boolean; | |
18 | + FAT: boolean; | |
19 | + COM_VISOR: number; | |
20 | + TIPO_VISOR: number; | |
21 | + DireccionNavegador: string; | |
22 | + ES_FE: boolean; | |
23 | + LECTORHUELLA_TER: boolean; | |
24 | + MK_TIPOTRX: string; | |
25 | + INTERFAZ_TC: number; | |
26 | + PUERTO_PRISMA: string; | |
27 | + PVOS: boolean; | |
28 | + RutaExp: string; | |
29 | + ImpRenParc: boolean; | |
30 | + PUERTO_POSNET: string; | |
31 | + EXTRACASH: boolean; | |
32 | + FIRMA_DIGITAL: boolean; | |
33 | + contactless: boolean; | |
34 | + MensajeExtraCash: boolean; | |
35 | + PLA: number; | |
36 | + FON: number; | |
37 | + PVE_CI: number; | |
38 | + PVE_RE: number; | |
39 | + GRP_PLA: number; | |
40 | + ImpRecCob: boolean; | |
41 | +} |
src/app/wrappers/tarjeta.ts
... | ... | @@ -0,0 +1,29 @@ |
1 | +export interface Tarjeta { | |
2 | + ID: number; | |
3 | + NOM: string; | |
4 | + NCO: string; | |
5 | + DTO: number; | |
6 | + DCO: number; | |
7 | + PAU: string; | |
8 | + BCO: number; | |
9 | + CBD: string; | |
10 | + CCA: number; | |
11 | + NEM: number; | |
12 | + NPR: string; | |
13 | + UPR: number; | |
14 | + FPR?: string; | |
15 | + ULIQ: number; | |
16 | + UFEC?: string; | |
17 | + CUIT: string; | |
18 | + PRO: number; | |
19 | + TIP: string; | |
20 | + E_HD: string; | |
21 | + C_HD: string; | |
22 | + COD_PRISMA: string; | |
23 | + PAGOELEC: boolean; | |
24 | + COD_POSNET: string; | |
25 | + ExtraCash: boolean; | |
26 | + MuestraPlanes: boolean; | |
27 | + CodPosnetLiquidacion: string; | |
28 | + nombreImagen?: string; | |
29 | +} | |
0 | 30 | \ No newline at end of file |
src/assets/img/americanExpress.png
10.4 KB
src/assets/img/argencard.png
7.48 KB
src/assets/img/cabal.png
7.38 KB
src/assets/img/cencosud.png
10.6 KB
src/assets/img/galiciaRural.png
10.1 KB
src/assets/img/generica.png
6.44 KB
src/assets/img/macro.png
9.1 KB
src/assets/img/macroAgro.png
11.8 KB
src/assets/img/maestro.png
9 KB
src/assets/img/mastercard.png
9.46 KB
src/assets/img/mercadoPago.png
13.9 KB
src/assets/img/naranja.png
10.4 KB
src/assets/img/nativa.png
12.1 KB
src/assets/img/tarjetaShopping.png
15.2 KB
src/assets/img/visa.png
7.03 KB
src/assets/img/visaCredito.png
10.3 KB
src/assets/img/visaDebito.png
10.1 KB
src/assets/img/visaElectron.png
9.8 KB
src/assets/scss/animation.scss
... | ... | @@ -250,3 +250,68 @@ |
250 | 250 | animation-timing-function: ease-out; |
251 | 251 | } |
252 | 252 | } |
253 | + | |
254 | +.wobble-hor-bottom { | |
255 | + -webkit-animation: wobble-hor-bottom 0.8s both; | |
256 | + animation: wobble-hor-bottom 0.8s both; | |
257 | +} | |
258 | + | |
259 | +@-webkit-keyframes wobble-hor-bottom { | |
260 | + 0%, | |
261 | + 100% { | |
262 | + -webkit-transform: translateX(0%); | |
263 | + transform: translateX(0%); | |
264 | + -webkit-transform-origin: 50% 50%; | |
265 | + transform-origin: 50% 50%; | |
266 | + } | |
267 | + 15% { | |
268 | + -webkit-transform: translateX(-30px) rotate(-6deg); | |
269 | + transform: translateX(-30px) rotate(-6deg); | |
270 | + } | |
271 | + 30% { | |
272 | + -webkit-transform: translateX(15px) rotate(6deg); | |
273 | + transform: translateX(15px) rotate(6deg); | |
274 | + } | |
275 | + 45% { | |
276 | + -webkit-transform: translateX(-15px) rotate(-3.6deg); | |
277 | + transform: translateX(-15px) rotate(-3.6deg); | |
278 | + } | |
279 | + 60% { | |
280 | + -webkit-transform: translateX(9px) rotate(2.4deg); | |
281 | + transform: translateX(9px) rotate(2.4deg); | |
282 | + } | |
283 | + 75% { | |
284 | + -webkit-transform: translateX(-6px) rotate(-1.2deg); | |
285 | + transform: translateX(-6px) rotate(-1.2deg); | |
286 | + } | |
287 | +} | |
288 | + | |
289 | +@keyframes wobble-hor-bottom { | |
290 | + 0%, | |
291 | + 100% { | |
292 | + -webkit-transform: translateX(0%); | |
293 | + transform: translateX(0%); | |
294 | + -webkit-transform-origin: 50% 50%; | |
295 | + transform-origin: 50% 50%; | |
296 | + } | |
297 | + 15% { | |
298 | + -webkit-transform: translateX(-30px) rotate(-6deg); | |
299 | + transform: translateX(-30px) rotate(-6deg); | |
300 | + } | |
301 | + 30% { | |
302 | + -webkit-transform: translateX(15px) rotate(6deg); | |
303 | + transform: translateX(15px) rotate(6deg); | |
304 | + } | |
305 | + 45% { | |
306 | + -webkit-transform: translateX(-15px) rotate(-3.6deg); | |
307 | + transform: translateX(-15px) rotate(-3.6deg); | |
308 | + } | |
309 | + 60% { | |
310 | + -webkit-transform: translateX(9px) rotate(2.4deg); | |
311 | + transform: translateX(9px) rotate(2.4deg); | |
312 | + } | |
313 | + 75% { | |
314 | + -webkit-transform: translateX(-6px) rotate(-1.2deg); | |
315 | + transform: translateX(-6px) rotate(-1.2deg); | |
316 | + } | |
317 | +} |
src/main.ts
... | ... | @@ -3,6 +3,7 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; |
3 | 3 | |
4 | 4 | import { AppModule } from './app/app.module'; |
5 | 5 | import { environment } from './environments/environment'; |
6 | +import 'hammerjs'; | |
6 | 7 | |
7 | 8 | if (environment.production) { |
8 | 9 | enableProdMode(); |
src/styles.scss
... | ... | @@ -15,6 +15,7 @@ body { |
15 | 15 | -webkit-filter: blur(10px); |
16 | 16 | } |
17 | 17 | |
18 | +app-pago-con-tarjeta, | |
18 | 19 | .disable-user-select { |
19 | 20 | -webkit-user-select: none; |
20 | 21 | -moz-user-select: none; |
... | ... | @@ -40,13 +41,14 @@ body { |
40 | 41 | } |
41 | 42 | |
42 | 43 | .card-effect { |
44 | + transition: background-color 0.3s; | |
43 | 45 | &:active { |
44 | 46 | background-color: #c9c9c9b3 !important; |
45 | - transition: background-color 0.5s; | |
47 | + transition: background-color 0.3s; | |
46 | 48 | } |
47 | 49 | &:focus { |
48 | 50 | background-color: #c9c9c9b3 !important; |
49 | - transition: background-color 0.5s; | |
51 | + transition: background-color 0.3s; | |
50 | 52 | } |
51 | 53 | } |
52 | 54 | |
... | ... | @@ -83,19 +85,11 @@ body { |
83 | 85 | } |
84 | 86 | |
85 | 87 | .bg-primary-gradient { |
86 | - background: linear-gradient( | |
87 | - 135deg, | |
88 | - rgba(40, 112, 175, 1) 0%, | |
89 | - rgba(0, 32, 66, 1) 100% | |
90 | - ); | |
88 | + background: linear-gradient(135deg, rgba(40, 112, 175, 1) 0%, rgba(0, 32, 66, 1) 100%); | |
91 | 89 | } |
92 | 90 | |
93 | 91 | .bg-primary-gradient-horizontal { |
94 | - background: linear-gradient( | |
95 | - 90deg, | |
96 | - rgba(40, 112, 175, 1) 0%, | |
97 | - rgba(0, 32, 66, 1) 100% | |
98 | - ); | |
92 | + background: linear-gradient(90deg, rgba(40, 112, 175, 1) 0%, rgba(0, 32, 66, 1) 100%); | |
99 | 93 | } |
100 | 94 | |
101 | 95 | .icon-dim { |