""" This module is used to calculate the split of the bill among people. Author: Sarath Rajan S Date: 26-01-2026 """ def splitCalculator(receipt_data: dict, matched_items: list, final_amount_paid: float = None): """ Calculates the split of the bill. 1. Calculate Raw Individual Total 2. Ratio = Individual Total / Raw Receipt Total 3. Final Split = Ratio * Final Amount Paid """ # The denominator for ratios should be the sum of all individual item costs being split. # This ensures that even if tax/service charge are not itemized, # the total split will still add up to final_amount_paid proportionally. subtotal = sum(float(item.get("price", 0)) * int(item.get("quantity", 1)) for item in matched_items) # If final_amount_paid is not provided or zero, assume no discount/tax (subtotal is the total) if final_amount_paid is None or final_amount_paid <= 0: final_amount_paid = subtotal person_data = {} # {name: {"items": [], "raw_sum": 0}} # Avoid division by zero if subtotal == 0: return [] for item in matched_items: iname = item.get("name", "Unknown") iprice = float(item.get("price", 0)) iqty = int(item.get("quantity", 1)) item_total = iprice * iqty people = item.get("people", []) if not people: people = ["Unassigned"] share = item_total / len(people) for person in people: if person not in person_data: person_data[person] = {"items": [], "raw_sum": 0} # Since items are now exploded in the matching phase, iqty is usually 1 here item_display = f"{iname} @ ${iprice}" if iqty > 1: item_display = f"{iname} (x{iqty}) @ ${iprice}" person_data[person]["items"].append(item_display) person_data[person]["raw_sum"] += share table_data = [] for person, data in person_data.items(): # Step: Ratio of person raw total vs subtotal ratio = data["raw_sum"] / subtotal if subtotal > 0 else 0 # Step: Apply final amount paid based on that ratio final_cost = ratio * final_amount_paid table_data.append({ "Person": person, "Items Consumed": "\n".join(data["items"]), # Multi-line string for "nested" look "Raw Share ($)": round(data["raw_sum"], 2), "Ratio (%)": f"{round(ratio * 100, 1)}%", "Final Split ($)": round(final_cost, 2) }) return table_data