3 ms·
There are a lot of things that can change, not only the price. The name of the product can change. What was "Medium crispy crusted pepperoni pizza" yesterday, m
by andix 3y ago
There are a lot of things that can change, not only the price. The name of the product can change. What was "Medium crispy crusted pepperoni pizza" yesterday, may be called "Extra large pepperoni pizza" today. If you re-print the invoice, it should look the same as on the first print. Otherwise you may get some issues with the authorities (manipulating your copy of the invoices).
There may also be a lot of related tables for finding the price (in the system I worked it was about 10 joins to get from the article to the price). It can be done in an immutable way, but it is possible that the way of calculating prices may change after an update. There may even have been a bug in the first place (like incorrect rounding, issuing rebates that shouldn't have been issued, incomplete sync of the prices table from the main server to the cash register, ...). Once you fix it all the previously issued invoices would show a different price. Which means you "lost" your copy of the invoice. Authorities don't like that. Credit card companies don't like it, if the customer disputes the charge and you show them an invoice with a different amount. Your bookkeeper doesn't like it, if a lot of payments don't match the invoices exactly, ...
Edit: Example for rounding: Two people split a pizza for 19,99$. Version 1.0 creates two invoices with 10,00$ each. Version 2.0 creates one invoice with 9,99$ and a second one with 10,00$. Then the authorities pass a law that rounding prices must always floor them. So Version 3.0 creates two invoices for 9,99$.
- hot_gril 3y agoRight, other things can change, and you record those changes as immutable rows in a table too. You don't forget that the "super pizza" used to be called "uber pizza," so you can print the same exact receipt again, but you know they're the same product.
- andix 3y agoSure, you can do that. But if you do some changes in your data model or logic you need to be extremely careful that all existing invoices still show exactly the same data. You probably need to use immutable price calculation logic for that too. Keep the old logic after an update and only use the new logic for new invoices. Because over the years there will be braking changes in your price calculation logic. A lot of effort for not so much added value. The systems I worked on put the calculated price of every item on every invoice into the database. So it can’t “drift“ over time. Off course they still keep the reference to the article too. It’s also much easier/faster to calculate sums and statistics one one table column instead of doing many joins every time you need the price.
- hot_gril 3y agoMaybe I'm not thinking of a complicated enough case, but I don't see why there'd be so many breaking changes. Say you add a new table for some special kind of promo, that doesn't affect the old receipts. At least this wasn't an issue in the last few e-commerce sites I dealt with. In any case, I would stay far away from having to preserve multiple versions of logic. It's also fine to denormalize a bit by copying the final price somewhere for performance, convenience, or sanity checking, but that's the kind of thing you bolt on after. If you're managing account balances, you actually need this for concurrency control alone.
- andix 3y agoI think you can't compare e-commerce to POS. Another example: A customer can stay a few hours inside a restaurant. Their tab stays open during that time, items are added at different times, and in the end the tab is closed and the invoice created. Prices of the items could change during that time (somebody noticed a wrong price during the shift and fixed it). There could be a happy hour with lower prices. Let's say Version 1.0 uses the prices that were valid when the invoice was finalized. Version 2.0 implements a happy hour feature, and now prices need to be calculated based on the time the item was added to the invoice. Without the right backwards compatible logic that may change the previous invoices. Or let's say you have two branches with one POS system. It's a small business, so they don't have a redundant internet connection, and a system that can work offline. One branch goes offline for a day, they receive the price updates a day late. They may know about that, but off course they don't close for the day, they just keep operating with the old prices. Their system will sync back the created invoices once connectivity is established again. The manager notices it and calls the branch to update the price for the caviar, because it recently tripled and that's a really important change. So they change the price of that item now in the disconnected database, at a different time than in the main database. On the next day the branch reconnects again and you need to sync that. Sounds like fun, doesn't it? :D It's much easier to just copy the new invoices to the main database as they are and replace the price list with the version from the main database. Let's imagine an airline, with a lot of cash registers on the plane for food and drinks. Some of them don't connect for maybe a week on a regular basis. There are perfectly immutable solutions for all those cases for sure. But they may become really complex really quick.