8 min read
The 'Multi' Concepts in POS Systems

I used to think building a POS was simple. One product, one price, one stock count. Done. Then I jumped into real projects and realized: the retail world is way more complicated than that.

My client said: “Hey, we sell bottled water by the piece, by the pack, and by the case. How do we handle that?” I answered casually: “Just create three separate products.” He shook his head. “But it’s the same inventory. If we sell one pack, the individual bottle count needs to decrease too.”

Oh. Turns out I needed to learn something called Multi-Unit.

And that was just the beginning. After that came Multi-Variant, Multi-Warehouse, Multi-Barcode, and all sorts of “Multi” concepts. Let me share my journey dealing with these.

Multi-Unit: One Product, Multiple Packages

The Problem I Faced

Client had bottled water. Sold in three packages:

  • Individual (bottle): Rp 5.000
  • Pack (6 bottles): Rp 25.000
  • Case (48 bottles): Rp 180.000

Cashiers needed to sell in any package. But inventory was one thing: counted in individual bottles.

My challenge: How do I build a system that can sell various packages while keeping inventory accurate?

How I Solved It

I created a product_units table storing conversions:

CREATE TABLE product_units (
    id INT PRIMARY KEY,
    product_id INT,
    unit_name VARCHAR(50), -- Individual, Pack, Case
    conversion_value INT,   -- Convert to smallest unit
    price DECIMAL(15,2)
);

-- Data for Bottled Water:
-- Individual: conversion = 1 (base)
-- Pack: conversion = 6 (1 pack = 6 bottles)
-- Case: conversion = 48 (1 case = 48 bottles)

How it works:

  • Stock stored in smallest unit (bottles)
  • Cashier sells 2 packs? System deducts 12 bottles (2 × 6)
  • Cashier sells 1 case? System deducts 48 bottles

Result: Stock always accurate, cashiers free to sell in any package.

What I Learned

Multi-Unit is super useful for products sold in various packages. But there are important points:

  • Always have a base unit (smallest unit for storing inventory)
  • Price per package can differ (buying a case is cheaper per bottle)
  • Each package can have its own barcode

Multi-Variant: The Clothing Store Story

New Problem Emerged

My second client ran a clothing store. One t-shirt model had multiple choices:

  • Sizes: S, M, L, XL
  • Colors: Red, Blue, Black, White

“How do we handle inventory? Red size M and Blue size L have different stock counts, right?”

Ah, this is different from Multi-Unit!

Multi-Unit vs Multi-Variant

I was confused at first. What’s the difference?

Multi-UnitMulti-Variant
Exact same productProduct with different attributes
Combined inventorySeparate inventory per combination
Example: bottle, pack, caseExample: colors, sizes, flavors

Multi-Unit Example:

Bottled Water (stock: 480 bottles)
├─ Sell individual: stock -1
├─ Sell pack: stock -6
└─ Sell case: stock -48

Multi-Variant Example:

Plain T-Shirt
├─ Red S (stock: 20)
├─ Red M (stock: 35)
├─ Blue L (stock: 15)
└─ Black XL (stock: 10)

Sell Red S: only Red S stock decreases

How I Solved It

I built a hierarchical variant system:

-- Attributes table (Color, Size)
CREATE TABLE variant_attributes (
    id INT PRIMARY KEY,
    name VARCHAR(50) -- Color, Size
);

-- Values table (Red, Blue, or S, M, L)
CREATE TABLE variant_values (
    id INT PRIMARY KEY,
    attribute_id INT,
    value VARCHAR(100) -- Red, Blue, or S, M, L
);

-- Product combinations table
CREATE TABLE product_variants (
    id INT PRIMARY KEY,
    parent_product_id INT,
    sku VARCHAR(50),      -- TS-RED-M (T-Shirt Red M)
    variant_name VARCHAR(255),
    price DECIMAL(15,2),
    stock INT            -- Separate inventory!
);

Each color-size combination becomes a separate product with its own inventory.

What I Learned

Mistake I made: combining Multi-Unit and Multi-Variant in one table. Disaster. Inventory went haywire.

Lesson: Keep Multi-Unit and Multi-Variant separate. They’re different concepts.

Multi-Warehouse: The Branch Store Drama

Problem I Didn’t Anticipate

Third client: “We have 5 branches. Inventory needs to be separate per branch.”

I thought just add a warehouse_id column to the stock table. But turns out…

It was more complex:

  1. Customer calls branch A asking about stock. Sold out. But branch B has it.
  2. Branch A wants to borrow stock from branch B (inter-branch transfer)
  3. Manager wants to see inventory reports across all branches

How I Solved It

I created inventory tables per warehouse:

CREATE TABLE warehouses (
    id INT PRIMARY KEY,
    code VARCHAR(20),
    name VARCHAR(100),    -- Main Warehouse, Branch A, Branch B
    type ENUM('warehouse', 'store')
);

CREATE TABLE product_stock (
    id INT PRIMARY KEY,
    product_id INT,
    warehouse_id INT,
    quantity INT,
    min_stock INT,        -- Minimum threshold for alerts
    UNIQUE (product_id, warehouse_id)
);

Features I added:

  • Check stock availability at other branches
  • Inter-branch stock transfers with documentation
  • Inventory reports per location
  • Alerts when stock at specific branches runs low

What I Learned

Multi-Warehouse dramatically increases complexity. But it’s essential for businesses with multiple locations.

My tip: Set one warehouse as the “Main Warehouse” to simplify management.

Multi-Barcode: Surprise from Imported Products

The Unexpected Story

One day a cashier complained: “This product has two barcodes. One from the foreign manufacturer, one from the local distributor. But the system only accepts one barcode.”

Oops. Didn’t think about this.

Why Multi-Barcode is Needed?

Turns out there are many cases:

  • Imported products have international barcode + local barcode
  • Repackaged products get new barcodes
  • Different packages have different barcodes (individual vs pack)

How I Solved It

CREATE TABLE product_barcodes (
    id INT PRIMARY KEY,
    product_id INT,
    product_unit_id INT,  -- If barcode is specific to a package
    barcode VARCHAR(100) UNIQUE,
    is_primary BOOLEAN    -- Main barcode
);

Now one product can have multiple barcodes. Cashier scans any barcode, system still knows which product it is.

What I Learned

Don’t underestimate barcodes. In practice, one product can have 2-3 different barcodes.

Multi-Supplier: Learning from Mistakes

My Mistake

Initially, I only stored one supplier per product. Then the client said: “We buy sugar from three suppliers. Prices are different. How do we compare?”

I had to restructure the database. What a pain.

Should’ve Done This from the Start

CREATE TABLE product_suppliers (
    id INT PRIMARY KEY,
    product_id INT,
    supplier_id INT,
    supplier_sku VARCHAR(100),    -- Product code at supplier
    purchase_price DECIMAL(15,2),
    min_order_qty INT,
    lead_time_days INT,           -- Delivery wait time
    is_preferred BOOLEAN          -- Primary supplier
);

Benefits:

  • Compare prices across suppliers
  • Backup supplier if primary is out of stock
  • Track supplier performance (fastest delivery, cheapest price)

What I Learned

Don’t wait for requests. Think ahead: could this product be purchased from multiple suppliers?

Multi-Payment: Customer Wants to Split Payment

What Happened at the Store

Customer: “Can I pay half cash, half debit card?”

Cashier: “Hey developer, the system can’t do that…”

Me: ”…” (thinking: oops, forgot to build this feature)

How I Fixed It

CREATE TABLE transaction_payments (
    id INT PRIMARY KEY,
    transaction_id INT,
    payment_method_id INT,  -- Cash, Card, QR, etc
    amount DECIMAL(15,2),
    reference_no VARCHAR(100) -- Reference number for card/transfer
);

Now one transaction can use multiple payment methods:

Total Purchase: Rp 5.000.000
├─ Cash:        Rp 3.000.000
├─ Debit Card:  Rp 1.500.000
└─ QR Payment:  Rp 500.000

What I Learned

Split payment is more common than I thought. Many customers want to pay part cash, part cashless.

Implementation Priority: What to Build First?

From my experience, here’s the order:

Must-Have (Definitely Need)

  1. Multi-Unit - almost every business needs this
  2. Multi-Variant - especially for fashion, shoes, electronics
  3. Multi-Warehouse - if you have more than one location
  4. Multi-Barcode - makes scanning easier

Should-Have (Really Useful)

  1. Multi-Supplier - for price comparison
  2. Multi-Payment - customers love flexibility
  3. Multi-Tax - depends on business regulations

Nice-to-Have (Extra Features)

  1. Multi-Bundle (Product Packages)
  2. Multi-Category (Multiple Categories)
  3. Multi-Currency - only for international business

Mistakes I’ve Made

So you don’t repeat my mistakes:

  1. Combining Multi-Unit and Multi-Variant in one table (huge mistake).
  2. Not separating inventory by location from the start.
  3. Forgetting to validate negative stock.
  4. Not logging stock changes history.

My Conclusions

Building a POS with various “Multi” concepts taught me a lot:

  1. Don’t assume it’s simple - what looks easy can be complex.
  2. Listen to users - they know the real problems.
  3. Separate concepts clearly - Multi-Unit ≠ Multi-Variant.
  4. Think about scalability - plan for growth early.
  5. Log everything - essential for debugging.

If you’re building a POS system, I hope my stories help. Don’t be afraid to make mistakes, but learn from others’ experiences so you don’t fall too much.

Happy coding!