""" AR roll-forward (movement) and ledger, built from the journal decomposition + payouts. Closing AR = Opening AR + Net Revenue − Payouts received (payouts are stored negative, so Closing = Opening + NetRev + received_payouts) Net Revenue is the sum of the non-transfer journal lines. Gross Revenue is the Sales line (product sales + shipping + gift-wrap). This ties to both the Journal Entry and the settlement-based receivable. """ from __future__ import annotations def compute_movement(journal: dict, received_payouts: float, all_payouts: float, opening: float, settlement_closing: float | None = None, currency: str = "USD") -> dict: periods = journal.get("periods", []) lines = journal.get("lines", []) n = len(periods) net_rev_per = [0.0] * n gross_per = [0.0] * n revenue_lines = [] for ln in lines: if ln["key"] == "Transfer": continue for i in range(n): net_rev_per[i] += ln["values"][i] if ln["key"] == "Sales": for i in range(n): gross_per[i] += ln["values"][i] revenue_lines.append(ln) net_revenue = round(sum(net_rev_per), 2) gross_revenue = round(sum(gross_per), 2) closing = round(opening + net_revenue + received_payouts, 2) # Ledger (debits raise AR, credits reduce it) ledger = [{"period": "Opening", "description": "Previous month closing balance", "debit": None, "credit": None, "balance": round(opening, 2)}] bal = opening for i, p in enumerate(periods): bal += net_rev_per[i] ledger.append({"period": p["label"], "description": "Net revenue (accrued)", "debit": round(net_rev_per[i], 2), "credit": None, "balance": round(bal, 2)}) bal += received_payouts ledger.append({"period": "Settlement", "description": "Amazon payout received", "debit": None, "credit": round(-received_payouts, 2), "balance": round(bal, 2)}) ledger.append({"period": "Closing", "description": "Month-end receivable", "debit": None, "credit": None, "balance": round(bal, 2)}) diff_vs_settlement = (round(closing - settlement_closing, 2) if settlement_closing is not None else None) return { "currency": currency, "opening": round(opening, 2), "gross_revenue": gross_revenue, "net_revenue": net_revenue, "net_revenue_per_period": [round(x, 2) for x in net_rev_per], "total_receivable": round(opening + net_revenue, 2), "received_payouts": round(received_payouts, 2), "all_payouts": round(all_payouts, 2), "in_transit_payouts": round(all_payouts - received_payouts, 2), "closing": closing, "settlement_closing": settlement_closing, "difference_vs_settlement": diff_vs_settlement, "period_labels": [p["label"] for p in periods], "revenue_lines": revenue_lines, # per-period + total revenue/fee breakdown "ledger": ledger, }