spliit icon indicating copy to clipboard operation
spliit copied to clipboard

[Feature request] CSV export: switch to per‑expense saldo format and remove reimbursement column

Open Uli-Z opened this issue 1 month ago • 0 comments

Background

Discussion status and references:

  • PR #456 introduces “Paid By” + sorting; reviewers requested the format change in a separate PR.
  • Issue #455 asks for CSV↔JSON parity (incl. “Paid By” and ordering).
  • Issue #471 shows the payer can appear negative in participant columns, which is not useful for “personal cost” or for balancing.
  • Issue #342 discusses that the current “signed shares” columns lose information and are awkward in spreadsheets; a per‑expense saldo is more practical.

Problem statement:

  • Participant columns encode “signed shares,” which are neither clear personal costs nor per‑expense balances; this makes the export unintuitive compared to the JSON data model.
  • Reimbursements appear as expenses, distorting totals and requiring a special flag.

Proposed direction:

  • Switch participant columns to per‑expense saldo (payer advances; others owe). Model reimbursements as internal transfers by using Cost=0.

Why now:

  • This follows Jessica’s PR (#456) that fixed sorting and added "Paid By". To keep scope clean, this PR focuses on the CSV format revamp as a dedicated, reviewable change.

Summary

This PR switches the CSV export to a per‑expense saldo format that aligns better with user expectations and spreadsheet workflows. Participant columns carry the net effect (saldo) of each expense. Reimbursements use Cost=0, which removes the need for a dedicated reimbursement flag.

Changes

  • Columns
    • Keep: Date, Description, Category, Currency, Cost, Original cost, Original currency, Conversion rate, Split mode, Paid By.
    • Remove: Is Reimbursement (redundant once reimbursements use Cost=0).
    • Participant columns: per‑expense saldos (payer positive advance; others negative owed amounts).
  • Behaviour
    • Reimbursements: exported as internal transfers with Cost=0; participant saldos reflect direction/amount.
    • Incomes: negative Cost values; participant saldos remain consistent.
    • Sorting: consistent with JSON export (by expenseDate, then createdAt).
  • Implementation
    • CSV route updated to compute participant saldos; paid amounts and conversion values normalized to plain numbers before formatting.

CSV Format (Descriptive)

  • Fixed columns: Date, Description, Category, Currency, Cost, Original cost, Original currency, Conversion rate, Split mode, Paid By.
  • Participant columns: per‑expense saldo per participant.
  • Semantics:
    • Payer: saldo = totalAmount - ownShareAmount (advance for others).
    • Others: saldo = - ownShareAmount (owed to the payer).
  • Special cases:
    • Reimbursements → Cost = 0 (internal transfer; not group spending).
    • Incomes → negative Cost (distribution to participants).

Testing

  • Manual: export CSVs for classical expenses, altruist payments, self‑payments, incomes, and reimbursements; verify that “who owes whom” is directly readable and that reimbursements use Cost=0.
  • Script‑assisted: run the CSV→sentences helper (attached) to cross‑check narrative output and totals.

Rationale

  • Practical and close to intent: participant columns show the real‑world effect per expense (advance vs. owed), matching users’ mental model and spreadsheet usage.
  • Trade‑off: the exact split method (shares/percentages) is not serialized; amounts are. In practice, amounts are what downstream tools operate on.
  • Clarity: Is Reimbursement becomes unnecessary with Cost=0; totals remain correct and the transfer direction is visible in participant columns.

Why remove the Is Reimbursement column?

  • Reimbursements are internal transfers, not spending. Using Cost=0 keeps group totals correct without an extra flag.
  • The participant columns already encode direction and amount; the boolean adds no additional value.

Evidence

  • Exercised against a comprehensive set of scenarios (classical expenses, altruist payments, self‑payments, incomes, reimbursements) using a CSV→sentences helper and curated test CSVs (attached via PR comment).

Files for testing

testcases.csv convert-csv-to-sentences.py

Uli-Z avatar Nov 17 '25 20:11 Uli-Z