mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 12:23:13 +00:00
Add discount settings and two-tier pricing to order aggregation
Settings CRUD (get_settings/put_settings) for DynamoDB CONFIG#SETTINGS item. Aggregation now tracks bulk_price and employee_price separately, with grand_total (company cost) and employee_total (payroll deductions).
This commit is contained in:
parent
a8adbdc116
commit
e6bef44a74
4 changed files with 53 additions and 9 deletions
|
|
@ -1,8 +1,11 @@
|
|||
{
|
||||
"menu_url": "https://redefinemeals.com/menu",
|
||||
"order_deadline": "Wednesday 11:59 PM",
|
||||
"order_deadline": "Thursday at 11:59 PM",
|
||||
"output_dir": "output",
|
||||
"orders_dir": "orders",
|
||||
"bulk_discount_percent": 10,
|
||||
"company_subsidy_percent": 50,
|
||||
"google_client_id": "",
|
||||
"roster": [
|
||||
{"name": "Example Employee", "email": "example@seahavenind.com"}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -65,13 +65,18 @@ def lambda_handler(event, context):
|
|||
|
||||
|
||||
def build_summary(orders: list[dict], week: str) -> dict:
|
||||
meal_totals = defaultdict(lambda: {"quantity": 0, "unit_price": 0})
|
||||
meal_totals = defaultdict(
|
||||
lambda: {"quantity": 0, "bulk_price": 0, "employee_price": 0}
|
||||
)
|
||||
for order in orders:
|
||||
for item in order.get("items", []):
|
||||
name = item["name"]
|
||||
qty = int(item.get("quantity", 0))
|
||||
meal_totals[name]["quantity"] += qty
|
||||
meal_totals[name]["unit_price"] = float(item.get("price", 0))
|
||||
meal_totals[name]["bulk_price"] = float(
|
||||
item.get("bulk_price", item.get("price", 0))
|
||||
)
|
||||
meal_totals[name]["employee_price"] = float(item.get("price", 0))
|
||||
|
||||
meals = []
|
||||
for name, data in sorted(meal_totals.items()):
|
||||
|
|
@ -79,8 +84,12 @@ def build_summary(orders: list[dict], week: str) -> dict:
|
|||
{
|
||||
"meal": name,
|
||||
"quantity": data["quantity"],
|
||||
"unit_price": data["unit_price"],
|
||||
"line_total": round(data["unit_price"] * data["quantity"], 2),
|
||||
"unit_price": data["bulk_price"],
|
||||
"employee_unit_price": data["employee_price"],
|
||||
"line_total": round(data["bulk_price"] * data["quantity"], 2),
|
||||
"employee_line_total": round(
|
||||
data["employee_price"] * data["quantity"], 2
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -90,6 +99,7 @@ def build_summary(orders: list[dict], week: str) -> dict:
|
|||
"total_employees": len(orders),
|
||||
"total_meals": sum(m["quantity"] for m in meals),
|
||||
"grand_total": round(sum(m["line_total"] for m in meals), 2),
|
||||
"employee_total": round(sum(m["employee_line_total"] for m in meals), 2),
|
||||
"meals": meals,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,12 +41,17 @@ def load_orders(week: str) -> list[dict]:
|
|||
|
||||
def generate_order_summary(orders: list[dict]) -> dict:
|
||||
"""Aggregate all meals across employees into a single order for Redefine."""
|
||||
meal_totals = defaultdict(lambda: {"quantity": 0, "unit_price": 0})
|
||||
meal_totals = defaultdict(
|
||||
lambda: {"quantity": 0, "bulk_price": 0, "employee_price": 0}
|
||||
)
|
||||
for order in orders:
|
||||
for item in order.get("items", []):
|
||||
name = item["name"]
|
||||
meal_totals[name]["quantity"] += item.get("quantity", 0)
|
||||
meal_totals[name]["unit_price"] = item.get("price", 0)
|
||||
meal_totals[name]["bulk_price"] = item.get(
|
||||
"bulk_price", item.get("price", 0)
|
||||
)
|
||||
meal_totals[name]["employee_price"] = item.get("price", 0)
|
||||
|
||||
summary = []
|
||||
for name, data in sorted(meal_totals.items()):
|
||||
|
|
@ -54,12 +59,17 @@ def generate_order_summary(orders: list[dict]) -> dict:
|
|||
{
|
||||
"meal": name,
|
||||
"quantity": data["quantity"],
|
||||
"unit_price": data["unit_price"],
|
||||
"line_total": round(data["unit_price"] * data["quantity"], 2),
|
||||
"unit_price": data["bulk_price"],
|
||||
"employee_unit_price": data["employee_price"],
|
||||
"line_total": round(data["bulk_price"] * data["quantity"], 2),
|
||||
"employee_line_total": round(
|
||||
data["employee_price"] * data["quantity"], 2
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
grand_total = sum(s["line_total"] for s in summary)
|
||||
employee_total = sum(s["employee_line_total"] for s in summary)
|
||||
total_meals = sum(s["quantity"] for s in summary)
|
||||
|
||||
return {
|
||||
|
|
@ -68,6 +78,7 @@ def generate_order_summary(orders: list[dict]) -> dict:
|
|||
"total_employees": len(orders),
|
||||
"total_meals": total_meals,
|
||||
"grand_total": round(grand_total, 2),
|
||||
"employee_total": round(employee_total, 2),
|
||||
"meals": summary,
|
||||
}
|
||||
|
||||
|
|
@ -150,6 +161,10 @@ def main():
|
|||
print(f"{meal['meal']:<45} {meal['quantity']:>4} ${meal['line_total']:>7.2f}")
|
||||
print("-" * 60)
|
||||
print(f"{'TOTAL':<45} {summary['total_meals']:>4} ${summary['grand_total']:>7.2f}")
|
||||
if summary.get("employee_total") is not None and summary["employee_total"] != summary["grand_total"]:
|
||||
print(f"{'PAYROLL DEDUCTIONS':<45} ${summary['employee_total']:>7.2f}")
|
||||
subsidy = round(summary["grand_total"] - summary["employee_total"], 2)
|
||||
print(f"{'COMPANY SUBSIDY':<45} ${subsidy:>7.2f}")
|
||||
print(f"\n{summary['total_employees']} employees ordered")
|
||||
|
||||
print("\nFiles generated:")
|
||||
|
|
|
|||
|
|
@ -128,3 +128,19 @@ def put_roster(employees: list[dict]):
|
|||
"updated_at": datetime.now(EASTERN).isoformat(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def get_settings() -> dict:
|
||||
resp = _get_table().get_item(Key={"PK": "CONFIG", "SK": "SETTINGS"})
|
||||
return resp.get("Item", {})
|
||||
|
||||
|
||||
def put_settings(settings: dict):
|
||||
_get_table().put_item(
|
||||
Item={
|
||||
"PK": "CONFIG",
|
||||
"SK": "SETTINGS",
|
||||
**_to_decimal(settings),
|
||||
"updated_at": datetime.now(EASTERN).isoformat(),
|
||||
}
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue