Data model for physical sales(POS)

Hi all! I was wondering if somebody else implemented a POS system in Moqui. More specifically I’m wondering if there is some data model available already for POS sales, something like a POSLine or similar.

Because when we talk about physical in store sales, the Invoice or OrderHeader don’t really apply so well since most of the time we don’t have any information about the customer, like the name or contact mechanisms.

Did somebody else implemented a POS system with Moqui, and if yes, did you do it with the standard data model in the udm, or did you customized and added new entities?

1 Like

This isn’t a full explanation of the model, but there has been pos stuff done with Moqui before.

Off the top of my head there is a terminalId on OrderHeader

        <field name="terminalId" type="text-short"><description>ID for the terminal, such as a POS system, where the order was recorded</description></field>

Yea, I just realized a bit after posting that we don’t actually need a separate POSLine, because a POS sale is basically an Order, so we can customize the OrderHeader and OrderLine for the POS specific case. I didn’t yet tested this approach, but probably I will use the following settings:

  • Register a simple in-store Sale as an Order with no customer(or placeholder customer like _NA_)
  • If shipment or Invoice is needed, then register the customer and shipment/billing as usual
  • The payment is the specific part. So I guess I should create some new payment methods for in-store cash, in-store credit card or cash on delivery and either add a terminalId to the payment or link the terminal to the terminalId from the OrderHeader(as it already has this field, as you mentioned above). I just hope I can receive a payment for an Order, instead of just for invoices…
  • Then at the end of the day I need the total cash per terminal, which I can get from the payments, since they are linked to the terminalId
  • Or instead of using a terminalId I could use the FinancialAccount??, as a terminal is similar to a BankAccount(as in it stores money, but inside the store, not inside the bank)… not sure about this one…

Note
As I was writting this I thought a bit more about where the terminalId should be stored, and I think it should be on the Payment, not OrderHeader, as the terminal is just the place where you store cash, and you receive cash through payments, not orders.
I’m thinking about my case, where we have 2 stores in the same city(one terminal per store), and we could register an order in any of the 2 stores, and then receive the payment(or multiple partial payments) for the order in any of the 2 stores(aka terminals), so I know how much cash we have in each terminal at a given time.

1 Like

To receive a payment for an order, you just set it to a sales order instead of a purchase order. That’s done by making the vendor of the OrderPart the internal organization.

I’d probably use a FinancialAccount associated to the terminalId, because then I wouldn’t have to write custom summary and transaction reports based on a custom data structure.

Because typically a POS System is a way to place a n order and a payment is downstream of that, I would consider that if you want to associate the terminalId with the payment, the payment is already associated with the OrderPart which is associated with the OrderHeader. So you could create a view entity for grabbing a OrderPartWithPayment based on a terminalId in the OrderHeader.

1 Like

Okay, I came back to this. So, the data model seems to miss some crucial fields for in store sales. Let’s forget about the terminalId for a moment. What I need to know for in store sales are 2 things: the products sold and the cash received.

For products sold everything seems ok. The order registers the products and the product store/facility where the inventory should be updated.

But for cash there are 2 problems. First, there is no facility id or store id on the payment, so for cash payments I don’t know in which store we received the payment. Note that the order might be created and shipped from store 1, but the payment received in store 2.

The second problem is that for in store sales we very rarely create invoices, and the payment application can only be applied to invoices, not orders. So for orders we have no way of knowing which are paid and which are unpaid.

IMO, you always need an invoice in exchange for a payment. Cash register tickets are a type of invoice, just smaller. :wink: The issue with the facility ID or store ID sounds good if we fix it, though.

Yea, I agree. Even in my country in accounting terms the cash register ticket is called a simplified invoice, because it’s both an invoice and a receipt(proof of payment). So I guess for cash payments I will just create an Invoice with a new invoiceTypeEnumId of type Simplified for example, and a payment of type cash connected to it.

Now for the store problem I think there are 3 solutions:

  1. Add a store or facility ID to the payment. Honestly I don’t think this is a good fix. First because you already have the to and fromPartyId, and you can just create a party for each store or facility and you know that those payments are made throught that store. Secondly, connecting the payment only to the store still leaves the problem of having only the total cash per store. There are cases, for example supermarkets, that have multiple cash drawers in each store and they might want to have the totals per each drawer, not only per store, so they can reconcile the physical cash with the cash in the ERP.
  2. Use overrideGlAccountId and create subaccounts for each cash drawer or store. This leaves the ability to map the accounts however you want. However I still don’t like this solution, because it’s tied to the accounting module, and I might not need the accounting module otherwise. For example in our country, the majority of companies outsource accounting posting to another specialized company.
  3. Use financial accounts for each cash drawer and connect it to payments. I like this solution the best so far, because it’s not dependent on the accounting module. And I guess a bank account is very similar to a cash drawer, so most of the implemented functionality in the financial account should work out of the box. And I can also make transfers from one financial account to another financial account, aka move money from the cash drawer to a bank account an vice versa. Or just use money directly from the financial account, without a payment, to decrease the cash in the drawer.
1 Like