You are browsing as a guest. Sign up (or log in) to start making projects!

4h 59m 46s logged

Hey guys, back on this project. Last time I said the next round was going to be document lines, my quote was “the only part of this CRM that doesn’t fit the dynamic JSON engine”. That’s what this round was, plus the report engine on top of it.

Document Lines: One single table for all four documents: quote, sales order, delivery note, invoice. The line is exactly the samein all of them, the only thing that changes is the document holding it, and a document here is just a Record like any other, so there’s no type constraint on the line at all.
A line can be a product line, a free text line (no amounts, just something to say in the middle of the document) or a subtotal.
Two things get copied at save time: the description and the vat percentage.

The math is its own class, DocumentLineCalculator, and it’s the one piece of this project I wanted testable completely on its own, because it’s the only place where a wrong rounding produces a wrong tax document.
The order is fixed:

  1. gross = quantity × unit price
  2. discount = a percentage of the gross, or a flat amount
  3. net = gross - discount, rounded to 2 decimals here
  4. vat = net × rate, rounded
  5. line total = net + vat

Rounding happens after the discount and after the vat, never on the unit price: round the unit price and the error gets multiplied by the quantity. Rounding mode is HALF_UP, which is the commercial rounding used here, not HALF_EVEN. And a flat discount bigger than the line itself gets clamped instead of producing a negative amount, since that’s a typo 100% of the time.

Lines are always saved all together. The endpoint is a PUT that replaces the whole set. It deletes and rewrites instead of diffing row by row, because a document has a few dozen lines at most and the diff would cost more code than it’s worth. The reason for this rule is the totals: they depend on every line, so a partial save would leave the header and the lines disagreeing, even if only for a moment.

The totals (subtotal, vatTotal, total) get written back into the document’s own JSON, plus the header level discount and shipping cost. They live there so they can be list columns you filter and sort on, which is the whole point of having them.

Now I’m working on the dashboard graphs, widget and this kind of things.I hope you like the project.

I’m sorry if I don’t have any screenshot of the working website, it’s because I focused only on the backend, the frontend of this part still needs to be written.

0
15

Comments 0

No comments yet. Be the first!