Spaces:
Running
Running
| """Output generators for custom food orders: receipt, customer message, pickup | |
| reminder, ingredient shopping list. | |
| Pure string formatting from a normalized order dict β no model calls, no I/O. | |
| Storage keys are generic; their meaning here: services=items, next_appointment=pickup, | |
| supplies=ingredients, amount_paid=deposit/payment. | |
| """ | |
| from __future__ import annotations | |
| from datetime import datetime | |
| from config import BUSINESS_NAME, CURRENCY | |
| def money(x) -> str: | |
| try: | |
| return f"{CURRENCY}{float(x or 0):,.2f}" | |
| except (TypeError, ValueError): | |
| return f"{CURRENCY}0.00" | |
| def _balance(order: dict) -> float: | |
| return round(float(order.get("amount_charged") or 0) - float(order.get("amount_paid") or 0), 2) | |
| def _item_lines(order: dict) -> str: | |
| items = order.get("services") or [] | |
| if not items: | |
| return " β’ Order" | |
| return "\n".join(f" β’ {s}" for s in items) | |
| def invoice(order: dict) -> str: | |
| """Order receipt for the customer.""" | |
| customer = order.get("customer") or "Customer" | |
| date = (order.get("created_at") or datetime.now().isoformat())[:10] | |
| balance = _balance(order) | |
| paid = float(order.get("amount_paid") or 0) | |
| header = BUSINESS_NAME or "ORDER RECEIPT" | |
| lines = [ | |
| header, | |
| "=" * max(len(header), 28), | |
| f"Date: {date}", | |
| f"Customer: {customer}", | |
| "", | |
| "Order:", | |
| _item_lines(order), | |
| ] | |
| if order.get("next_appointment"): | |
| lines.append(f"\nPickup/Delivery: {order['next_appointment']}") | |
| lines += [ | |
| "", | |
| f"Order total: {money(order.get('amount_charged'))}", | |
| f"Paid: {money(paid)}" | |
| + (f" ({order['payment_method']})" if order.get("payment_method") else ""), | |
| f"Balance: {money(balance)}", | |
| ] | |
| if balance <= 0: | |
| lines.append("\nStatus: PAID IN FULL β thank you!") | |
| elif paid > 0: | |
| lines.append(f"\nStatus: DEPOSIT PAID β {money(balance)} due on collection") | |
| else: | |
| lines.append(f"\nStatus: UNPAID β {money(balance)} due on collection") | |
| return "\n".join(lines) | |
| _HONORIFICS = {"mr", "mrs", "ms", "miss", "madam", "mdm", "auntie", "aunty", "uncle", "dr"} | |
| def followup(order: dict) -> str: | |
| """Ready-to-send WhatsApp/SMS order confirmation, tone depends on payment.""" | |
| name = (order.get("customer") or "").strip() | |
| first = name.split()[0] if name else "there" | |
| # "Mrs Tan" must not become "Hi Mrs," β keep the full name after an honorific. | |
| customer = name if first.lower().rstrip(".") in _HONORIFICS else first | |
| balance = _balance(order) | |
| paid = float(order.get("amount_paid") or 0) | |
| items = order.get("services") or [] | |
| item_txt = " and ".join(items).lower() if items else "your order" | |
| if balance <= 0: | |
| msg = f"Hi {customer}, thanks so much for your order of {item_txt} β all paid, " | |
| msg += "and it'll be ready for you." | |
| elif paid > 0: | |
| msg = (f"Hi {customer}, thanks for your order of {item_txt}! " | |
| f"Total {money(order.get('amount_charged'))}, deposit of {money(paid)} received β " | |
| f"just {money(balance)} to settle on collection.") | |
| else: | |
| msg = (f"Hi {customer}, confirming your order of {item_txt}. " | |
| f"That's {money(order.get('amount_charged'))}, payable on collection.") | |
| if order.get("next_appointment"): | |
| msg += f" Ready for {order['next_appointment']}. See you then!" | |
| return msg | |
| def reminder(order: dict) -> str: | |
| customer = order.get("customer") or "Customer" | |
| when = order.get("next_appointment") | |
| items = ", ".join(order.get("services") or []) or "order" | |
| if not when: | |
| return "No pickup/delivery time set." | |
| return f"π§ {when}: {customer} β {items}" | |
| def supplies_list(order: dict) -> str: | |
| items = order.get("supplies") or [] | |
| if not items: | |
| return "No ingredients to buy." | |
| return "π Ingredients to buy:\n" + "\n".join(f" β {i}" for i in items) | |
| def generate_all(order: dict) -> dict: | |
| """Convenience: all four outputs in one dict, for the UI.""" | |
| return { | |
| "invoice": invoice(order), | |
| "followup": followup(order), | |
| "reminder": reminder(order), | |
| "supplies": supplies_list(order), | |
| } | |