import uuid from decimal import Decimal from typing import List, Tuple from sqlalchemy.orm import Session from barker.models import SectionPrinter, Printer, Voucher, Inventory, DbSetting, VoucherType from barker.worker import sent_to_printer def print_bill(voucher_id: uuid.UUID, db: Session): voucher: Voucher = db.query(Voucher).filter(Voucher.id == voucher_id).first() printer = ( db.query(Printer) .join(SectionPrinter.printer) .filter(SectionPrinter.section_id == voucher.food_table.section_id) .filter(SectionPrinter.menu_category_id == None) .first() ) items_dict = {} tax = {} for i in [i for k in voucher.kots for i in k.inventories]: key = (i.product_id, i.is_happy_hour, tuple(m.modifier_id for m in i.modifiers if m.modifier.show_in_bill)) if key in items_dict: items_dict[key].quantity += i.quantity else: items_dict[key] = i if i.tax_id in tax: tax[i.tax_id] = (i.tax.name, tax[i.tax_id][1] + i.tax_amount) else: tax[i.tax_id] = (i.tax.name, i.tax_amount) data = design_bill(voucher, items_dict.values(), tax.values(), db) sent_to_printer.delay(data, printer.address, printer.cut_code) def design_bill(voucher: Voucher, items: List[Tuple[Inventory, Decimal]], tax: List[Tuple[str, Decimal]], db: Session): # Header s = "\n\r" + db.query(DbSetting).filter(DbSetting.name == "Header").first().data['Text'] if voucher.voucher_type == VoucherType.REGULAR_BILL: s += "\n\r" + "Retail Invoice".center(42) s += "\n\r" elif voucher.voucher_type == VoucherType.NO_CHARGE: s += "\n\r" + "NO CHARGE - THIS IS NOT A BILL - DON'T PAY".center(42) s += "\n\r" elif voucher.voucher_type == VoucherType.STAFF: s += "\n\r" + "STAFF CONSUMPTION -- THIS IS NOT A BILL".center(42) s += "\n\r" # Products s += "\n\r" + f"Bill No: {voucher.full_bill_id:>12} {voucher.date:%d-%b-%Y %H:%M}" s += "\n\r" + "Table No.: " + voucher.food_table.name s += "\n\r" + "-" * 42 s += "\n\r" + "Qty. Particulars Price Amount" s += "\n\r" + "-" * 42 for item in [i for i in items if i.quantity != 0]: name = "H H " + item.product.full_name if item.is_happy_hour else item.product.full_name s += "\n\r" + f"{item.quantity: >5.2f} {name:<22.22} {item.price: >6.2f} {item.price * item.quantity: >6.2f}" for m in [m for m in item.modifiers if m.modifier.show_in_bill]: s += f"\n\r -- {m.modifier.name: <38.38}" s += "\n\r" + "------------------------------------------" # Totals amount = sum(i.quantity * i.price for i in items) s += f"\n\r{'Subtotal :': >32} {amount: >9.2f}" amount = sum(i.quantity * i.price for i in items if i.is_happy_hour) if amount != 0: s += f"\n\r{'Happy Hour Discount :': >32} {amount: >9.2f}" amount = sum(i.quantity * i.effective_price * i.discount for i in items) if amount != 0: s += f"\n\r{'Discount :': >32} {amount: >9.2f}" for t in tax: if t[1] != 0: s += f"\n\r{t[0]: >30} : {t[1]: >9.2f}" s += f"\n\r{'Total Amount :',32} {round(voucher.amount): >9.2f}" s += "\n\r" + "-" * 42 if voucher.voucher_type != VoucherType.REGULAR_BILL: s += "\n\r" + "THIS IS NOT A BILL - DON'T PAY".center(42) s += "\n\r" + "-" * 42 if voucher.narration: s += f"\n\r{voucher.narration: ^42}" s += "\n\r" + "-" * 42 if voucher.customer: s += f"\n\r{voucher.customer.name}\n\r{voucher.customer.phone}\n\r{voucher.customer.address}" s += "\n\r" + "-" * 42 s += "\n\r" + "Cashier : " + voucher.user.name s += "\n\r" + db.query(DbSetting).filter(DbSetting.name == "Footer").first().data['Text'] return s