Sales module

The order gets written once

Sales orders, customer records, payments and the link to your online store. The order is born validated and drives fulfilment from there, with nothing retyped from one program to another.

Talk to us

In short

  1. Once
    The order is not retyped

    Confirming an order creates its fulfilment in the same transaction. Confirming it twice returns the first one.

  2. Offline
    The rep takes orders with no signal

    Catalogue and price lists live on the phone. The server writes the price, the warehouse confirms availability.

  3. VAT no.
    Checked as you type it

    VAT number with its check character, tax code, certified email and recipient code: mistakes surface on save.

  4. PrestaShop
    The store is genuinely connected

    Orders come in on their own, stock and prices go out, states and refunds come back. No evening file export.

For most sellers the pain is the step before the warehouse: the price only one person knows, the same company entered twice, the phone order copied by hand, the deposit on a separate sheet, the store still selling what has already left. Sales covers orders, customers, payments and channel. And it keeps them attached to the movement ledger, not beside it.

Sales validates, the warehouse fulfils

You confirm an order once and the warehouse fulfils it: no line retyped, no goods promised twice.

  • 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
How it works, in detail

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.

  1. The orderSALESCustomer resolved, a price that comes from a declared source, tax on every line.
  2. The confirmationSALESThe fulfilment order is created in the same transaction: either both exist, or neither does.
  3. The reservationWAREHOUSEAllocation reserves the goods and picks the locations: from there available-to-promise drops for everyone.
  4. Pick and packPACK-2The warehouse works the fulfilment order, line by line.
  5. 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.
From the order to the shipment, and the line between two tradesConfirming the same order twice returns the first one, not a second one to ship: the same rule that lets the handheld resend a scan without doubling it. The status travels back to the sales order: allocated, picked, shipped.

A price has a source, and the source stays on record

Faced with an off-list price, you can tell at once whether it is an agreed discount or a typo.

  • 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
How it works, in detail

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.

An order line taken by a sales rep, with no price typed by hand

  1. 01Price set by handempty: move down
  2. 02Price coming from the storethe order did not come from the store
  3. 03Customer price listanswers: the line takes this price
  4. 04Item base pricenot needed
Four sources, and the first one that answers decidesThe line records which step its price came from: faced with an off-list price, you can tell a concession from a typo.

Tax sits on the line, with the cases Italy imposes

Your invoice and VAT register state the same figure, line by line.

  • 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
How it works, in detail

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.

One order, three lines, and the tax on each of them
LineRateNetTax
Item SKU-4471 · 12 units22%240.0052.80
Carriage · a line with no item behind it22%9.902.18
Exempt service · with its own Natura code0% · Natura80.000.00
Document totalmixed329.9054.98
A zero rate with no Natura code will not save: an electronic invoice like that would be rejected. And totals are recomputed from the lines, never summed from the groups.

The customer record is the one an invoice needs

You fix the VAT number and recipient code while the customer is on the phone, not when the invoice bounces.

  • 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
How it works, in detail

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. 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. You also get a list, in black and white, of what had moved onto the other one and stays there, beginning with where new orders will arrive. 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.

Customer record · the checks made on save
  • 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

Your reps take orders even with no signal, and each one sees only their own customers.

  • 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
How it works, in detail

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. A user who holds the rep role but is not linked to any rep record does not get an empty list (which would read 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.

Payments: the payment status is not typed in

You always know what has really been paid, because the status comes from the payments, not a dropdown.

  • 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
How it works, in detail

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.

Order 2026-1187 · the payments, and the status they produce
  • 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

Your PrestaShop store publishes real stock, and an order with an unknown item is never lost.

  • 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
How it works, in detail

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.

  1. The storePRESTASHOPThe module calls the moment the order is placed, and the call is signed.
  2. Inbound queueWITH ITS OWN KEYEvery event carries its own key: a resend does not create a second order.
  3. The warehouseLEDGERThe order is in, its lines matched to variants and the customer recognised.
  4. Outbound queueWITH ITS RETRIESStock, prices, order confirmations, payments and refunds go back out.
  5. 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.
Two queues between the store and the warehouseThose two queues are the only way the store and the warehouse talk to each other. The scheduled sweep runs anyway, as a safety net for whatever the store failed to send.

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, with the right price list, the right customer and tax on every line, and you want payment, customer record and online store attached to that order rather than 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, including a standalone invoice typed with no order behind it. Sales puts an already validated order in front of the invoice; it is not what makes issuing one possible.

Does the warehouse stay the authority on stock, or can sales override it?

It stays the authority: 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, or 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. Administrators, on the other hand, 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: 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