feat(invoices): per-line-item KDV rates with mixed-rate support#4
Open
AltanEsmer wants to merge 1 commit into
Open
feat(invoices): per-line-item KDV rates with mixed-rate support#4AltanEsmer wants to merge 1 commit into
AltanEsmer wants to merge 1 commit into
Conversation
Invoices can now hold multiple products each with its own KDV rate
(e.g. one line at %10 and another at %16 in the same invoice). Invoice-level
subtotal/vat_amount/total are kept as cached aggregates and always
recomputed server-side from line_items; vat_rate is the shared rate when
all lines agree, or null when mixed ("Karışık").
- database.js: new _computeInvoiceTotals helper, idempotent migration that
synthesizes a single line for legacy records, validation and mutators
always normalize line_items and recompute aggregates, _computeTryEquivalent
now emits per-line TRY equivalents
- InvoiceForm.js + new InvoiceFormLineItems.jsx: editable line-items table
with chip-based per-line KDV selector; manual total override kept only
for single-line invoices to preserve the sum-of-lines invariant
- InvoiceFormMoneyZone.jsx: trimmed to currency selector, manual total
toggle, total display, and FX reveal
- InvoiceTable.jsx: "Karışık" tag + tooltip in KDV column, expandable rows
showing the per-line breakdown with TRY equivalents
- InvoiceList.js Excel export builds a flat lineItems array for a second
"Kalemler" sheet; KDV Oranı column tolerates the "Karışık" string
- main.js export-to-excel handler optionally writes the "Kalemler" sheet
and writes mixed-rate KDV cells as text instead of percent
- docs/DATA-MODEL.md updated with line_items schema and mixed-rate example
Legacy invoices auto-migrate on first load to a single line carrying the
existing rate; aggregate fields preserved so Dashboard / reports keep
working unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
line_items[]to the Invoice schema so a single invoice can carry products with different KDV rates (e.g. %10 and %16 on the same invoice — a Turkish tax requirement).subtotal/vat_amount/totalbecome cached aggregates, always recomputed server-side fromline_items. Invoice-levelvat_rateis the single shared rate ornullwhen mixed ("Karışık").Karışıktag with a tooltip listing the distinct rates, and rows expand to reveal the per-line breakdown (with TRY equivalents for foreign-currency invoices).Kalemlersheet with one row per line item; the mainFaturalarsheet writesKarışıkin the KDV Oranı column for mixed-rate invoices.loadData()synthesizes a single line from the existing flat fields for every legacy invoice on first load.Files touched
database.js— new_computeInvoiceTotalshelper, line-items migration, payload normalization inaddInvoice/updateInvoice, per-line TRY equivalents in_computeTryEquivalent, dashboard aggregation uses the cachedvat_amount, updated sample seed.src/components/InvoiceFormLineItems.jsx(new) — editable line-items table with per-line chip-based KDV selector.src/components/InvoiceFormMoneyZone.jsx— trimmed to currency + manual-total switch + total display + FX reveal.src/pages/InvoiceForm.js— driveslineItemsstate, disables manual total for multi-line invoices.src/components/InvoiceTable.jsx—Karışıktag in the KDV column, expandable rows showing line items.src/pages/InvoiceList.js— builds the second-sheetlineItemspayload; main sheet tolerates theKarışıksentinel.main.js—export-to-excelhandler optionally writes theKalemlersheet and writes non-numeric KDV cells as text.src/index.css— styles for the line-items table and summary strip.docs/DATA-MODEL.md— documents the newline_itemsfield and adds a mixed-rate invoice example.Test plan
npm run dev— launch app, verify legacy invoices auto-migrated (no console errors, expanded row shows a single auto-generated line)Karışıktag with tooltip; expanded row shows both lines; aggregates correctFaturalarsheet showsKarışıkin KDV Oranı for mixed rows;Kalemlersheet lists one row per line with line totals🤖 Generated with Claude Code