import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import { Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { AuthService } from '../../auth/auth.service'; import { BillViewItem } from '../../core/bill-view-item'; import { Customer } from '../../core/customer'; import { Table } from '../../core/table'; import { ToasterService } from '../../core/toaster.service'; import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component'; import { TableService } from '../../tables/table.service'; import { BillService } from '../bill.service'; import { ChooseCustomerComponent } from '../choose-customer/choose-customer.component'; import { PaxComponent } from '../pax/pax.component'; import { QuantityComponent } from '../quantity/quantity.component'; import { TablesDialogComponent } from '../tables-dialog/tables-dialog.component'; import { Bill } from './bill'; import { BillSelectionItem } from './bill-selection-item'; import { BillsDataSource } from './bills-datasource'; import { Inventory } from './inventory'; import { Kot } from './kot'; import { VoucherType } from './voucher-type'; @Component({ selector: 'app-bills', templateUrl: './bills.component.html', styleUrls: ['./bills.component.sass'], }) export class BillsComponent implements OnInit { dataSource: BillsDataSource = new BillsDataSource(this.bs.dataObs); /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns: string[] = ['select', 'info', 'quantity']; constructor( private route: ActivatedRoute, private router: Router, private dialog: MatDialog, private toaster: ToasterService, private auth: AuthService, public bs: BillService, private tSer: TableService, ) {} ngOnInit() { this.route.data.subscribe((value) => { const data = value as { item: Bill; updateTable: boolean }; this.bs.loadData(data.item, data.updateTable); }); this.getPax(); this.dataSource = new BillsDataSource(this.bs.dataObs); } getPax(): void { if (this.bs.bill.id || this.bs.bill.customer) { return; } this.choosePax(); } choosePax(): void { const dialogRef = this.dialog.open(PaxComponent, { // width: '750px', data: this.bs.bill.pax, }); dialogRef.afterClosed().subscribe((result: boolean | number) => { if (!result) { return; } this.bs.bill.pax = result as number; }); } chooseCustomer() { const dialogRef = this.dialog.open(ChooseCustomerComponent, { maxWidth: '100%', width: '50%', data: this.bs.bill.customer?.id, }); dialogRef.afterClosed().subscribe((result: boolean | Customer) => { if (!result) { this.bs.bill.customer = null; } else { this.bs.bill.customer = result as Customer; } }); } isAllSelected(kotView: BillViewItem): boolean { const kot = this.bs.bill.kots.find((k) => k.id === kotView.kotId) as Kot; return kot.inventories.reduce( (p: boolean, c: Inventory) => p && this.bs.selection.isSelected( JSON.stringify( new BillSelectionItem({ kotId: kot.id, inventoryId: c.id, productId: c.product.id, isHappyHour: c.isHappyHour, }), ), ), true, ); } toggle(invView: BillViewItem) { const key = JSON.stringify( new BillSelectionItem({ kotId: invView.kotId, inventoryId: invView.id, productId: invView.productId, isHappyHour: invView.isHappyHour, }), ); this.bs.selection.toggle(key); } isSelected(invView: BillViewItem): boolean { const key = JSON.stringify( new BillSelectionItem({ kotId: invView.kotId, inventoryId: invView.id, productId: invView.productId, isHappyHour: invView.isHappyHour, }), ); return this.bs.selection.isSelected(key); } isAnySelected(kotView: BillViewItem) { const kot = this.bs.bill.kots.find((k) => k.id === kotView.kotId) as Kot; let total = 0; let found = 0; for (const item of kot.inventories) { const key = JSON.stringify( new BillSelectionItem({ kotId: kot.id, inventoryId: item.id, productId: item.product.id, isHappyHour: item.isHappyHour, }), ); total += 1; if (this.bs.selection.isSelected(key)) { found += 1; } } return found > 0 && found < total; } masterToggle(kotView: BillViewItem) { const isAllSelected = this.isAllSelected(kotView); const kot = this.bs.bill.kots.find((k) => k.id === kotView.kotId) as Kot; for (const item of kot.inventories) { const key = JSON.stringify( new BillSelectionItem({ kotId: kot.id, inventoryId: item.id, productId: item.product.id, isHappyHour: item.isHappyHour, }), ); if (isAllSelected) { this.bs.selection.deselect(key); } else { this.bs.selection.select(key); } } } addOne(item: BillViewItem): void { this.bs.addOne(item); } quantity(item: BillViewItem): void { const dialogRef = this.dialog.open(QuantityComponent, { // width: '750px', data: item.quantity, }); dialogRef.afterClosed().subscribe((result: boolean | number) => { if (!result) { return; } this.bs.quantity(item, result as number); }); } subtractOne(item: BillViewItem): void { const canEdit = this.auth.allowed('edit-printed-product'); this.bs.subtractOne(item, canEdit); } modifier(item: BillViewItem): void { this.bs.modifier(item); } confirmMoveKotDialog(table: Table): Observable { return this.dialog .open(ConfirmDialogComponent, { width: '250px', data: { title: 'Move KOT?', content: 'Are you sure?' }, }) .afterClosed() .pipe( map((x: boolean) => { if (!x) { throw new Error('Please confirm move'); } return table; }), ); } chooseTable(allowMerge: boolean): Observable
{ return this.dialog .open(TablesDialogComponent, { // width: '750px', data: { list: this.tSer.running(), canChooseRunning: allowMerge, }, }) .afterClosed() .pipe( map((x: Table) => { if (!x) { throw new Error('Please choose a table'); } return x; }), ); } moveKot(kot: BillViewItem) { const canMergeTables = this.auth.allowed('merge-tables'); this.chooseTable(canMergeTables) .pipe( switchMap((table: Table) => this.confirmMoveKotDialog(table)), switchMap((table: Table) => { if (this.bs.bill.kots.length === 1 && table.status) { return this.bs.mergeTable(table); } if (this.bs.bill.kots.length === 1 && !table.status) { return this.bs.moveTable(table); } if (table.status) { return this.bs.mergeKot(kot.kotId as string, table); } return this.bs.moveKot(kot.kotId as string, table); }), ) .subscribe( () => { this.toaster.show('Success', ''); this.router.navigate(['/sales']); }, (x) => { this.toaster.show('Error', x); }, ); } rowQuantityDisabled(row: BillViewItem) { if (!row.isPrinted) { return false; } if (this.bs.bill.voucherType === VoucherType.Void) { return true; } if (!this.auth.allowed('edit-printed-product')) { return true; } return false; } }