barker/barker/barker/printing/bill.py

98 lines
3.8 KiB
Python

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