Sales module
The order gets written once
Sales orders, customer records, payments and the link to your online store. This is the module that puts a commercial front end onto the warehouse: the order is born validated — right customer, a price that came from somewhere, tax on every line — and from there fulfilment takes over. Nobody retypes anything from one program into another.
Confirming a sales order creates its fulfilment order in the same transaction. Confirming it twice returns the first one, not a second thing to ship.
Catalogue and price lists are downloaded to the phone, which works out the price to quote from its own copy. The server is what writes it, being the only one that knows whether the list has changed: if a line comes out different from the one promised, the rep is shown it by name. Availability is confirmed by the warehouse the moment the signal returns, so nobody promises goods that have already gone.
Italian VAT number with its check character, tax code, certified email address and the seven-character e-invoicing recipient code: the mistake surfaces on save, not the day the invoice bounces.
Orders come in on their own, stock and prices go out, states and refunds come back. It is not a file somebody exports in the evening.
For most companies that sell, the painful part is not the warehouse: it is the step before. The agreed price that lives in one person’s head, the same company entered twice under two different VAT numbers, the order taken by phone and copied out by hand, the deposit noted on a separate sheet, the online store still selling what has just left the building. The Sales module covers those four trades — orders, customers, payments, channel — and keeps them attached to the movement ledger rather than beside it.
Sales validates, the warehouse fulfils
This is the boundary everything else is built on: Sales never writes to the movement ledger and never touches stock. Once the order is commercially sound — customer resolved, prices applied, every line carrying its tax rate — confirmation creates the fulfilment order in the same transaction: either both exist or neither does. From there the warehouse is in charge, allocating, picking, packing, shipping and issuing the delivery note (the transport document Italian law requires with the goods); status flows back onto the commercial order. Sales asks for availability rather than computing it: there is exactly one authority on “how much can I promise”, and it is the one holding the goods.
- Confirmation creates the fulfilment order in the same transaction as the sales order
- Sales never writes to the movement ledger and never corrects stock
- Available-to-promise comes from the warehouse: stock minus active reservations
- An order already confirmed, confirmed again, returns the first one
- Status flows back: allocated, picked, shipped, with the document that proves it
- Cancelling is a declared, recorded act, not a row that disappears
- The orderSALESCustomer resolved, a price that comes from a declared source, tax on every line.
- The confirmationSALESThe fulfilment order is created in the same transaction: either both exist, or neither does.
- The reservationWAREHOUSEAllocation reserves the goods and picks the locations: from there available-to-promise drops for everyone.
- Pick and packPACK-2The warehouse works the fulfilment order, line by line.
- The shipmentDISPATCHThe delivery note comes out of the movement, and the status goes back to the order.
What never crosses that line
- The ledgerSales never writes a stock movement: there is no route for it to do so.
- The stock figureThey do not correct it. They ask for it and get a number: stock minus active reservations.
- The last unitWhen two orders compete for it, the second one finds out before promising it to a customer.
A price has a source, and the source stays on record
There is one door to the selling price, and a declared order of precedence. A price typed in by hand always wins, even below cost, because that is a decision by whoever sells and not a figure to be corrected. Next comes the price that arrived from the store: it is the number the customer has already seen and agreed to, and recomputing it would make it diverge from what was actually paid. Then the customer’s price list, in two steps — the item’s own entry at the right quantity break, and the list’s general discount where no entry exists. Underneath everything sits the item’s base price. Every line records which of those sources produced its price: without that, faced with an off-list price, you cannot tell a commercial concession from a typing mistake.
- Four sources in a declared order: manual, channel, customer price list, base price
- The right break applies: with thresholds of 1 / 6 / 24, twelve units pay the price of six
- The list’s general discount also covers items added to the catalogue tomorrow
- A price list whose validity window has expired genuinely stops applying
- Order-level discounts, promotions and coupons, with the totals recomputed
- A whole list can be repriced in one go instead of entry by entry
- The price typed by handIt beats everything else, even below cost: it is a decision by the person selling, not a figure to be corrected.
- The price the store sentIt is the number the customer has already seen and accepted. Recomputing it would make it drift from what they paid.
- The customer’s price listThe item’s own entry at the right break; where there is no entry, the list’s general discount.
- The item’s base priceUnderneath everything else, for when nothing else has anything to say.
Tax sits on the line, with the cases Italy imposes
Rate, taxable amount and tax sit on every order line, not only at the foot of the document: it is the only way for the invoice, the VAT register and the books to state the same figure. The Italian cases are wired in where they belong rather than left to whoever is filling the form. A zero rate without an exemption code will not save, because an electronic invoice like that gets rejected by the tax authority’s exchange system; the one legitimate zero without an exemption code is the margin scheme, where tax is computed on the margin rather than on the full amount. Sellers of goods carrying Italian consumption duty find it applied as a factor on the line, not added on to the total. And a line need not have an item behind it — a service, carriage, a piece of work — while still carrying its own rate like any other.
- Rate, taxable amount and tax computed and kept line by line
- A zero rate without an exemption code is refused on save
- Margin scheme: nominal zero rate, tax computed on the margin
- Consumption duty applied as a factor of the line, for those who deal in such goods
- Lines with no item behind them, carrying their own rate and taxable amount
- Totals are recomputed from the lines, never summed up from groupings
| Line | Rate | Net | Tax |
|---|---|---|---|
| Item SKU-4471 · 12 units | 22% | 240.00 | 52.80 |
| Carriage · a line with no item behind it | 22% | 9.90 | 2.18 |
| Exempt service · with its own Natura code | 0% · Natura | 80.00 | 0.00 |
| Document total | — | 329.90 | 54.98 |
The customer record is the one an invoice needs
This is the operational record: the one that downstream has to hold up an electronic invoice. VAT number, tax code, certified email address and e-invoicing recipient code are checked on save — the VAT number against its check character, the recipient code for shape and length — so the mistake shows up while you still have the customer on the phone rather than three weeks later. Billing and shipping addresses are different things and stay apart, each with its own default. Duplicate records are found by VAT number, which nothing forces to be unique, and are merged only after you have seen what merging would do. And if you merged the wrong record there is a way out: the pointer is removed, the record goes back to being itself and can be edited again — with a list, in black and white, of what had moved onto the other one and stays there, beginning with where new orders will arrive. And a new customer — arriving from the store, or signed up by a rep on the spot — can go through a queue: whoever approves them also decides how they may pay, and if nobody decides, payment in advance applies.
- VAT number, tax code, certified email and recipient code validated on save
- Billing and shipping addresses kept apart, each with its default
- Duplicates found by VAT number, with a preview of what merging would entail
- The pointer comes off and the record goes back to itself, listing what stays on the other
- Notes and tags on the record, with who wrote them and when; deleted ones stay on record
- Approving a customer and granting payment terms are deliberately the same act
- VAT NUMBERIT01234567897, with the right check characterpasses
- CERTIFIED MAILordini@pec.esempio.itpasses
- RECIPIENT CODEABC123X, seven characters as the format wantspasses
- DUPLICATESame VAT number as a record already on fileto be merged
The error surfaces while you still have the customer on the phone, not three weeks later, when the invoice bounces back.
Field reps see their own customers, and nobody else’s
A sales rep is a real role, not an administrator with less patience. Their scope is enforced in a single place, above every sub-route of the order, so whoever adds the next feature inherits it without having to remember: a colleague’s order answers “not found”, which is the only answer that does not even confirm the thing exists. And a user who holds the rep role but is not linked to any rep record does not get an empty list — which reads as “there are no orders” — but a refusal that says what is missing. Taking an order and deciding the price you sell at are two different permissions: the rep composes the order but cannot mint themselves a coupon. Commission accrues on the same taxable base the tax is computed on, and is settled when the time comes.
- The rep’s scope is enforced in one place, above every order sub-route
- A rep user with no linked record reads why they see nothing, instead of seeing zero
- Taking an order and setting price lists, promotions and coupons are separate permissions
- Commission accrues on the same taxable base as the tax, following its own rules
- Accrued commission gets settled, with a record of when that happened
- An order-taking catalogue with filters and, per customer, what they took last time
Payments: the payment status is not typed in
A payment is recorded against the order, and the payment status is recomputed from it in the same transaction: it is not a dropdown somebody moves. A deposit and a balance turn into “partly paid” and then “paid” on their own, and nobody can declare an order paid with no payment underneath. An announced payment — the one the channel promises but has not confirmed yet — stays pending until it comes true, or fails carrying its reason with it. Refunds can be partial, and they lower what is owed as well: an order refunded for a line that never shipped must not show that money as still outstanding. Resending the same request does not create a second payment: it returns the one already recorded.
- Payment status is always derived from the payments, never picked by hand
- Unpaid, partly paid, paid, refunded: four computed states
- An announced payment stays pending, then confirms or fails with its reason
- Partial refunds that lower what is owed, not only what was taken in
- Resending the same request returns the payment already recorded
- Configurable payment methods: transfer, card, cash, PayPal, bank collection, direct debit
- PAYMENTDeposit on confirmation, by card+ 305.00
- PAYMENTBalance on delivery, by bank transfer+ 305.00
- STATUSPaidcomputed, not chosen
No dropdown to move: the status is recomputed from the payments in the same transaction, and an order with no payments under it is one nobody can declare paid.
The online store, and what happens when the two disagree
The channel connected today is PrestaShop, and it is not a nightly file import: orders arrive both because the store announces them with a signed call and because a periodic run goes and fetches them. What goes out is real availability — stock minus active reservations, the same figure the warehouse operator sees — along with prices, categories and images. Order states are not guessed: they are read from the store by name, and you choose which of them mean “ready to fulfil”. A line with an item you do not know does not cost you the order: it goes into quarantine, you map the item and send it through again. And the queues that talk to the store have a memory: they retry with a growing wait and know how to give up on a permanent error, instead of knocking at a bricked-up door for days.
- Orders arrive both by signed call from the store and by periodic run
- Published stock is available-to-promise, never a parallel counter
- Prices, categories and images pushed from the system to the store
- Order states read from the store by name, and chosen by you
- A line with an unknown item: order quarantined, then mapped and replayed
- Queues with growing waits, surrender on permanent errors and a panel to get out
- The storePRESTASHOPThe module calls the moment the order is placed, and the call is signed.
- Inbound queueWITH ITS OWN KEYEvery event carries its own key: a resend does not create a second order.
- The warehouseLEDGERThe order is in, its lines matched to variants and the customer recognised.
- Outbound queueWITH ITS RETRIESStock, prices, order confirmations, payments and refunds go back out.
- The storefrontPRESTASHOPIt lines up on the next sweep, not at the end of the day.
No outside system touches the warehouse — and when something does not add up
- Unknown lineThe line fails, not the order: that one waits in quarantine and the other lines go through.
- Store unreachableIt retries with growing waits, and past the threshold it is set aside and says so.
- Deleted productA permanent error, recognised as such: it stops at once instead of retrying for days.
Frequently asked questions
I already have a program for invoicing. Do I still need Sales?
It depends where the order is born. If it reaches you already made and you only ship it, the warehouse on its own is enough: it receives, allocates, picks, ships and issues the delivery note. Sales is what you want when the order gets composed here — right price list, right customer, tax on every line — and when you want the payment, the customer record and the online store attached to that order rather than sitting beside it in a second place you keep aligned by hand.
Do I have to buy this module in order to issue invoices?
No. Invoices, VAT registers, statutory inventory and delivery notes are compliance, and compliance is never sold separately: they stay active in every configuration. There is even a standalone invoice, typed with no order behind it, for those who work that way. Sales is what puts an already validated order in front of the invoice — not what makes issuing one possible.
Does the warehouse stay the authority on stock, or can sales override it?
It stays the authority, and not out of politeness: Sales has no route by which to write to the movement ledger. It asks how much is available to promise — stock minus active reservations — and receives a number. If two orders compete for the last unit, the second finds out before promising anything to the customer, because the reservation is already taken by the first.
What happens if the store sends an order containing an item I do not know?
The order is neither lost nor half imported: it goes into quarantine with a precise list of the lines that could not be matched to an item. You map those lines once — the mapping stays for future orders — and send the order through again, and it lands exactly as it would have landed straight away. Nobody retypes anything, and nobody has to notice by reading a technical log.
Can a rep see a colleague’s customers and orders?
No. The scope is enforced on the server, above every order route, and a colleague’s order answers “not found” like any number that does not exist: refusing access while confirming the order is there would already be telling you something. It works the other way round too: administrators see everything, and see which rep each order belongs to.
Which online stores can be connected?
PrestaShop today, with a module installed on the store that does the parts its standard calls cannot: freezing the taxes at the moment the order is placed, switching a customer account on, probing the price the customer actually sees. The spine underneath — an inbound queue with its idempotency key, an outbound queue with its retries, quarantine for lines that do not match an item — is not written for PrestaShop: it is the point where a channel plugs in, and the warehouse on the other side does not change by a line. If your channel is a different one, tell us: that is where it attaches.
Bring us a real order
The quickest way to tell whether Sales is for you is to take an order from yesterday — with its agreed discount, its odd line and its deposit — and see what shape it takes in here.
Talk to us