diff --git a/bookie/src/app/sales/bills/bills-datasource.ts b/bookie/src/app/sales/bills/bills-datasource.ts new file mode 100644 index 0000000..dd418a2 --- /dev/null +++ b/bookie/src/app/sales/bills/bills-datasource.ts @@ -0,0 +1,52 @@ +import { DataSource } from '@angular/cdk/collections'; +import { map, Observable, tap } from 'rxjs'; + +import { BillRow } from './bill-row'; +import { Kot } from './kot'; + +export class BillsDataSource extends DataSource { + private data: Kot[] = []; + constructor(private readonly dataObs: Observable) { + super(); + } + + connect(): Observable { + return this.dataObs.pipe( + tap((x) => { + this.data = x; + }), + map((d) => + d.flatMap((k) => { + const kotRow: BillRow = new BillRow({ kind: 'kot', kot: k, id: k.id! }); + const rows: BillRow[] = []; + for (const inv of k.inventories) { + if (!inv.id) { + inv.clientId = inv.clientId || crypto.randomUUID(); + } + rows.push(new BillRow({ kind: 'inv', kot: k, inv, id: `${k.id}-${inv.id || inv.clientId}` })); + if (inv.type === 'bundle') { + for (const child of inv.children) { + if (!child.id) { + child.clientId = child.clientId || crypto.randomUUID(); + } + child.parentId = inv.id || inv.clientId; + rows.push( + new BillRow({ + kind: 'child', + kot: k, + parent: inv, + inv: child, + id: `${k.id}-${child.id || child.clientId}`, + }), + ); + } + } + } + return [kotRow, ...rows]; + }), + ), + ); + } + + disconnect() {} +} diff --git a/bookie/src/app/sales/bills/bills.component.ts b/bookie/src/app/sales/bills/bills.component.ts index 4a81686..1806899 100644 --- a/bookie/src/app/sales/bills/bills.component.ts +++ b/bookie/src/app/sales/bills/bills.component.ts @@ -1,5 +1,5 @@ import { CommonModule, CurrencyPipe } from '@angular/common'; -import { Component, OnInit, inject, input, effect } from '@angular/core'; +import { Component, OnInit, inject, computed, effect, input } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatDialog } from '@angular/material/dialog'; @@ -24,9 +24,11 @@ import { QuantityComponent } from '../quantity/quantity.component'; import { TablesDialogComponent } from '../tables-dialog/tables-dialog.component'; import { Bill } from './bill'; import { BillRow } from './bill-row'; +import { BillsDataSource } from './bills-datasource'; import { Inventory } from './inventory'; import { Kot } from './kot'; import { VoucherType } from './voucher-type'; +import { VoucherService } from './voucher.service'; @Component({ selector: 'app-bills', @@ -52,10 +54,27 @@ export class BillsComponent implements OnInit { private auth = inject(AuthService); bs = inject(BillService); private tSer = inject(TableService); - updateTable = input.required(); - item = input.required(); + private voucherService = inject(VoucherService); + + table = input(null); + guest = input(null); + voucher = input(null); + bill = input(null); + + updateTable = computed(() => this.bill() !== null && this.voucher() !== null); + + dataSource: BillsDataSource = new BillsDataSource(this.bs.dataObs); + + billResource = this.voucherService.getFromBill(this.bill); + + tableResource = this.voucherService.getFromTable(this.table, this.voucher, this.guest); + + idResource = this.voucherService.getFromId(this.voucher); + + item = computed( + () => this.billResource.value() ?? this.tableResource.value() ?? this.idResource.value() ?? new Bill(), + ); - dataSource = this.bs.dataObs; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ kotColumns: string[] = ['selectKot', 'infoKot', 'kotActions']; displayedColumns: string[] = ['selectInv', 'infoInv', 'quantity']; @@ -266,7 +285,10 @@ export class BillsComponent implements OnInit { constructor() { effect(() => { - this.bs.loadData(this.item(), this.updateTable()); + const bill = this.item(); + if (bill) { + this.bs.loadData(bill, this.updateTable()); + } }); } } diff --git a/bookie/src/app/sales/bills/voucher.service.ts b/bookie/src/app/sales/bills/voucher.service.ts index 081a364..a673758 100644 --- a/bookie/src/app/sales/bills/voucher.service.ts +++ b/bookie/src/app/sales/bills/voucher.service.ts @@ -1,5 +1,5 @@ import { HttpParams, HttpClient, httpResource, HttpResourceRef } from '@angular/common/http'; -import { Injectable, inject } from '@angular/core'; +import { Injectable, inject, Signal } from '@angular/core'; import { Observable } from 'rxjs'; import { catchError } from 'rxjs/operators'; @@ -19,41 +19,50 @@ export class VoucherService { private http = inject(HttpClient); private log = inject(ErrorLoggerService); - get(id: string): HttpResourceRef { - return httpResource(() => `${url}/from-id/${id}`); + get(id: Signal): HttpResourceRef { + return httpResource(() => { + const i = id(); + return i ? `${url}/from-id/${i}` : undefined; + }); } - getFromTable(tableId: string, voucherId: string | null, guestId: string | null): Observable { - let params = new HttpParams(); - if (voucherId !== null) { - params = params.set('v', voucherId); - } - if (guestId !== null) { - params = params.set('g', guestId); - } + getFromTable( + tableId: Signal, + voucherId: Signal, + guestId: Signal, + ): HttpResourceRef { + return httpResource(() => { + const tId = tableId(); + if (!tId) return undefined; - return this.http - .get(`${url}/from-table/${tableId}`, { params }) - .pipe( - catchError( - this.log.handleError( - serviceName, - `getFromTable tableId=${tableId} voucherId=${voucherId} guestId=${guestId}`, - ), - ), - ) as Observable; + const searchParams = new URLSearchParams(); + const vId = voucherId(); + if (vId !== null && vId !== undefined) { + searchParams.set('v', vId); + } + const gId = guestId(); + if (gId !== null && gId !== undefined) { + searchParams.set('g', gId); + } + + const query = searchParams.toString(); + return `${url}/from-table/${tId}${query ? '?' + query : ''}`; + }); } - getFromBill(billId: string): Observable { - return this.http - .get(`${url}/from-bill/${billId}`) - .pipe(catchError(this.log.handleError(serviceName, `getFromBill billId=${billId}`))) as Observable; + getFromBill(billId: Signal): HttpResourceRef { + return httpResource(() => { + const id = billId(); + console.log(id); + return id ? `${url}/from-bill/${id}` : undefined; + }); } - getFromId(voucherId: string): Observable { - return this.http - .get(`${url}/from-id/${voucherId}`) - .pipe(catchError(this.log.handleError(serviceName, `getFromId voucherId=${voucherId}`))) as Observable; + getFromId(voucherId: Signal): HttpResourceRef { + return httpResource(() => { + const id = voucherId(); + return id ? `${url}/from-id/${id}` : undefined; + }); } save(voucher: Bill, voucherType: VoucherType, guestBookId: string | null, updateTable: boolean): Observable {