From 56ae7500cc0b674016e56f59ac6b04e5c783c308 Mon Sep 17 00:00:00 2001 From: Amritanshu Date: Fri, 24 Mar 2023 09:09:13 +0530 Subject: [PATCH] Feature: Allow bills without items so that tables can be seated from the guest book. Feature: Allow guest book entries to be associated with running vouchers Feature: Allow removing customer from voucher --- barker/barker/routers/voucher/__init__.py | 2 + barker/barker/routers/voucher/save.py | 14 ++++-- barker/barker/routers/voucher/show.py | 10 ++--- barker/barker/routers/voucher/update.py | 10 +++-- bookie/src/app/sales/bill.service.ts | 45 ++++++++++++++----- bookie/src/app/sales/bills/bill.ts | 3 +- bookie/src/app/sales/bills/bills.component.ts | 5 ++- 7 files changed, 64 insertions(+), 25 deletions(-) diff --git a/barker/barker/routers/voucher/__init__.py b/barker/barker/routers/voucher/__init__.py index 572036b..f6c11d5 100644 --- a/barker/barker/routers/voucher/__init__.py +++ b/barker/barker/routers/voucher/__init__.py @@ -46,6 +46,8 @@ def do_update_table(item: Voucher, guest_book: GuestBook | None, db: Session): db.add(item.status) else: item.status.status = status_ + if guest_book is not None: + item.status.guest_book_id = guest_book.id def check_permissions(item: Voucher | None, voucher_type: VoucherType, permissions: list[str]): diff --git a/barker/barker/routers/voucher/save.py b/barker/barker/routers/voucher/save.py index 88de77b..232cff0 100644 --- a/barker/barker/routers/voucher/save.py +++ b/barker/barker/routers/voucher/save.py @@ -53,13 +53,15 @@ def save( voucher_type = VoucherType(p) guest_book = get_guest_book(g, db) item: Voucher = do_save(data, voucher_type, guest_book, db, user) + need_to_print_kot = sum(len(k.inventories) for k in item.kots) > 0 if update_table: do_update_table(item, guest_book, db) db.commit() voucher_id = item.id with SessionFuture() as db: - print_kot(voucher_id, db) - if item.voucher_type != VoucherType.KOT: + if need_to_print_kot: + print_kot(voucher_id, db) + if need_to_print_kot and item.voucher_type != VoucherType.KOT: print_bill(voucher_id, db) except SQLAlchemyError as e: traceback.print_exc() @@ -169,7 +171,13 @@ def do_save( db.flush() do_update_settlements(item, [], db) do_update_bill_numbers(item, db) - if len(item.kots) == 0 or len(item.kots[0].inventories) == 0: + + if ( + sum(len(k.inventories) for k in item.kots) == 0 + and guest_book is None + and data.pax == 0 + and data.customer is None + ): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Please add some products", diff --git a/barker/barker/routers/voucher/show.py b/barker/barker/routers/voucher/show.py index 941052a..2421840 100644 --- a/barker/barker/routers/voucher/show.py +++ b/barker/barker/routers/voucher/show.py @@ -69,6 +69,7 @@ def from_table( user: UserToken = Security(get_user), ): with SessionFuture() as db: + guest = None if g is None else db.execute(select(GuestBook).where(GuestBook.id == g)).scalar_one() if v is not None: item = ( db.execute( @@ -86,12 +87,10 @@ def from_table( detail="Voucher not found", ) else: + if guest is not None: + item.voucher.customer = guest.customer return voucher_info(item.voucher, db) table = db.execute(select(FoodTable).where(FoodTable.id == id_)).scalar_one() - if g is not None: - guest = db.execute(select(GuestBook).where(GuestBook.id == g)).scalar_one() - else: - guest = None return voucher_blank(table, guest) @@ -149,8 +148,7 @@ def voucher_info(item: Voucher, db: Session): "billId": ", ".join(f"{x.regime.prefix}-{x.bill_number}" for x in item.bills), "table": {"id": item.food_table_id, "name": item.food_table.name}, "customer": {"id": item.customer_id, "name": item.customer.name} if item.customer is not None else None, - "guest": None, # TODO: Wire this functionality - "narration": item.narration, # TODO: Wire this functionality + "narration": item.narration, "reason": item.reason, "voucherType": item.voucher_type, "kots": [ diff --git a/barker/barker/routers/voucher/update.py b/barker/barker/routers/voucher/update.py index 5c7b37b..860d6f6 100644 --- a/barker/barker/routers/voucher/update.py +++ b/barker/barker/routers/voucher/update.py @@ -61,11 +61,15 @@ def update_route( check_permissions(item, voucher_type, user.permissions) item.pax = data.pax - if guest_book is not None: - item.pax = guest_book.pax - item.food_table_id = data.table.id_ if data.customer is not None: item.customer_id = data.customer.id_ + else: + item.customer_id = None + if guest_book is not None: + item.pax = guest_book.pax + item.customer_id = guest_book.customer_id + item.food_table_id = data.table.id_ + if item.voucher_type != VoucherType.KOT: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, diff --git a/bookie/src/app/sales/bill.service.ts b/bookie/src/app/sales/bill.service.ts index 1a2d660..a3f3494 100644 --- a/bookie/src/app/sales/bill.service.ts +++ b/bookie/src/app/sales/bill.service.ts @@ -26,6 +26,7 @@ import { ModifiersComponent } from './modifiers/modifiers.component'; export class BillService { public dataObs: BehaviorSubject; public bill: Bill = new Bill(); + private originalBill: Bill = new Bill(); public grossAmount: BehaviorSubject; public discountAmount: BehaviorSubject; public hhAmount: BehaviorSubject; @@ -93,6 +94,7 @@ export class BillService { this.updateTable = updateTable; bill.kots.push(new Kot()); this.bill = bill; + this.originalBill = JSON.parse(JSON.stringify(this.bill)); this.selection.clear(); this.displayBill(); } @@ -223,31 +225,52 @@ export class BillService { this.displayBill(); } + isBillDiffent(bill: Bill, guestBookId: string | null): boolean { + const newItems = bill.kots + .filter((k: Kot) => k.id === undefined) + .reduce((p: number, k: Kot) => p + k.inventories.filter((i) => i.quantity !== 0).length, 0); + if (newItems > 0) { + return true; + } + if (guestBookId !== null) { + return true; + } + if (bill.pax != this.originalBill.pax) { + return true; + } + if (bill.customer !== this.originalBill.customer) { + return true; + } + return false; + } + printKot(guestBookId: string | null): Observable { const item = JSON.parse(JSON.stringify(this.bill)); - const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot; - if (newKot.inventories.filter((x) => x.quantity !== 0).length === 0) { - return throwError('Cannot print a blank KOT\nPlease add some products!'); + if (!this.isBillDiffent(item, guestBookId)) { + return throwError(() => Error('Cannot print a blank KOT\nPlease add some products!')); } if (!this.happyHourItemsBalanced() || this.happyHourItemsMoreThanRegular()) { - return throwError('Happy hour products are not balanced.'); + return throwError(() => Error('Happy hour products are not balanced.')); } return this.ser .saveOrUpdate(item, VoucherType.Kot, guestBookId, this.updateTable) .pipe(tap(() => (this.allowDeactivate = true))); } - printBill(guest_book_id: string | null, voucherType: VoucherType): Observable { + printBill(guestBookId: string | null, voucherType: VoucherType): Observable { const item = JSON.parse(JSON.stringify(this.bill)); - const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot; - if (item.kots.length === 1 && newKot.inventories.length === 0) { - return throwError('Cannot print a blank Bill\nPlease add some products!'); + const products = item.kots.reduce( + (p: number, k: Kot) => p + k.inventories.filter((i) => i.quantity !== 0).length, + 0, + ); + if (products === 0) { + return throwError(() => Error('Cannot print a blank Bill\nPlease add some products!')); } if (!this.happyHourItemsBalanced() || this.happyHourItemsMoreThanRegular()) { - return throwError('Happy hour products are not balanced.'); + return throwError(() => Error('Happy hour products are not balanced.')); } return this.ser - .saveOrUpdate(item, voucherType, guest_book_id, this.updateTable) + .saveOrUpdate(item, voucherType, guestBookId, this.updateTable) .pipe(tap(() => (this.allowDeactivate = true))); } @@ -364,6 +387,8 @@ export class BillService { } private happyHourItemsMoreThanRegular(): boolean { + // This is for the whole bill. eg. Kot 1 => Reg 2 + HH 2; Kot 2 => Reg 4; Kot 3 => Reg - 4 + // This is pass okay in happy hours items balanced, but overall this is wrong. Hence this check const invs: { [id: string]: { normal: number; happy: number } } = {}; for (const kot of this.bill.kots) { for (const inventory of kot.inventories) { diff --git a/bookie/src/app/sales/bills/bill.ts b/bookie/src/app/sales/bills/bill.ts index f3123bb..0d6b27c 100644 --- a/bookie/src/app/sales/bills/bill.ts +++ b/bookie/src/app/sales/bills/bill.ts @@ -18,7 +18,7 @@ export class Bill { kotId: string; billId: string; table: Table; - customer?: { id: string; name: string }; + customer: { id: string; name: string } | null; guest: GuestBook; reason: string; voucherType: VoucherType; @@ -37,6 +37,7 @@ export class Bill { this.billId = ''; this.kotId = ''; this.table = new Table(); + this.customer = null; this.guest = new GuestBook(); // this.settlements = []; this.reason = ''; diff --git a/bookie/src/app/sales/bills/bills.component.ts b/bookie/src/app/sales/bills/bills.component.ts index 0a9b87f..9073683 100644 --- a/bookie/src/app/sales/bills/bills.component.ts +++ b/bookie/src/app/sales/bills/bills.component.ts @@ -83,9 +83,10 @@ export class BillsComponent implements OnInit { dialogRef.afterClosed().subscribe((result: boolean | Customer) => { if (!result) { - return; + this.bs.bill.customer = null; + } else { + this.bs.bill.customer = result as Customer; } - this.bs.bill.customer = result as Customer; }); }