import html as _html import json def _e(s): return _html.escape(str(s if s is not None else "")) def render_receipt_html(sale, items, customer, st): """One self-contained receipt (inline CSS) used by both the print window and the email body.""" cur = st.get("currency_symbol", "$") def m(v): try: return f"{cur}{float(v or 0):.2f}" except (TypeError, ValueError): return f"{cur}0.00" store = st.get("store_name") or "RecordGod" addr = st.get("store_address") or "" footer = st.get("receipt_footer") or "thanks for digging" logo = st.get("store_logo") or "" logo_html = (f'
') if logo else "" date = str(sale.get("sale_date") or "")[:16].replace("T", " ") who = (customer or {}).get("name") or "Guest" rows = "" for i in items: disc = float(i.get("discount") or 0) dtag = f' −{m(disc)}' if disc > 0 else "" rows += (f'{i.get("qty",1)}× {_e(i.get("item_name") or i.get("sku"))}{dtag}' f'{m(i.get("line_total"))}') sub = sale.get("subtotal") disc_total = float(sale.get("discount_amount") or 0) tax = float(sale.get("tax_amount") or 0) incl = (st.get("tax_type") or "exclusive") == "inclusive" trade = float(sale.get("trade_in_credit") or 0) tot = float(sale.get("total") or 0) summ = f'Subtotal{m(sub)}' if disc_total > 0: summ += f'Discount−{m(disc_total)}' if tax > 0: summ += f'GST{" incl" if incl else ""} ({st.get("tax_rate","0")}%){m(tax)}' if trade > 0: summ += f'Trade-in credit−{m(trade)}' # split-payment lines, else the single method + (cash) tender/change pay = "" method = sale.get("payment_method") or "" splits = sale.get("split_payments") if isinstance(splits, str): try: splits = json.loads(splits) except ValueError: splits = None if splits and isinstance(splits, list): for p in splits: if p.get("method") and p.get("amount"): pay += f'{_e(p["method"].title())}{m(p["amount"])}' else: pay += f'{_e(method.title() or "Paid")}{m(sale.get("amount_paid", tot))}' tendered = sale.get("amount_tendered") if method == "cash" and tendered: pay += f'Tendered{m(tendered)}' pay += f'Change{m(float(tendered) - tot)}' bal = round(tot - float(sale.get("amount_paid") or 0), 2) bal_line = (f'Balance due' f'{m(bal)}') if bal > 0.005 else "" notes = f'
{_e(sale.get("notes"))}
' if sale.get("notes") else "" return f"""
{logo_html}
{_e(store)}
{f'
{_e(addr)}
' if addr else ''}
{_e(sale.get('sale_number',''))} · {_e(date)} · {_e(who)}
{rows}
{summ}{pay}{bal_line}
Total{m(tot)}
{notes}
{_e(footer)}
"""