A Hong Kong-based specialist wine business engaged Linescripts to build a custom operating platform on Odoo covering the public-facing storefront, back-office inventory and finance, and the wine-trade-specific workflows that off-the-shelf retail systems don't handle cleanly. The client requested that their name not appear in published case studies; the engagement is described here in the generic terms of the work.
The operating reality of a specialist wine business is heterogeneous in ways generic retail does not anticipate. Stock is cost-individual — two bottles of the same SKU bought in different lots can carry different landed costs, different bond statuses, different provenance, and different sale prices. Units of measure shift between case, bottle, half-bottle, and large-format across the same inventory line. Tastings and sampling consume valued stock that has to be tracked. Imports, customs, and bonded handling each leave traces in the cost basis. Age verification is a legal requirement on the website. And the staff that runs day-to-day operations needs granular, role-scoped access to the system, not generic ERP-wide permissions.
The Challenges
- Cost basis varies per lot, not per SKU. Generic FIFO costing assumes that any unit of a SKU is interchangeable. In wine that assumption breaks: two bottles of the same wine bought in different deliveries, different vintages, or different supplier deals carry different real costs. The system has to track and report cost at the lot / serial level, not at the product level.
- Multi-unit-of-measure stock that has to reconcile. The same wine moves in and out as cases when buying, as bottles when selling, and sometimes as half-bottles or large formats. Stock counts, valuation, and reporting all have to know that 12 bottles = 1 case (for one SKU) but 6 bottles = 1 case (for another), and the conversions have to hold across stock moves, sales, and purchase orders.
- Tastings and sampling are not "shrinkage." Beverage sampling consumes inventory legitimately — for trade tastings, customer education, and sales-led pours. The system has to record sampling against the right cost basis, deduct from inventory, and post the valuation correctly so finance sees an honest picture of stock vs sampling consumption.
- Public website that respects alcohol regulation. Selling wine online in Hong Kong requires age verification gating at the entry point. The site also has to behave honestly about availability — out-of-stock products should not be browsable as if they were available.
- Bulk operations that fit how a wine merchant actually works. Wine merchants think in lists — incoming PO lines from a supplier come in bulk, a tasting flight is a list of wines, a customer order is a list of bottles across many SKUs. Operating the system requires bulk import / bulk creation flows for products, purchase orders, and sale orders — not one-record-at-a-time Odoo screens.
- Role-scoped access for a small specialist team. Different functions inside the business — buying, retail, accounting, fulfilment, tasting events — need the views and actions that fit their role, not the full ERP surface. Generic Odoo permissions don't get granular enough.
How Linescripts Built the Solution
Actual costing at the lot / serial level
A custom actual-costing engine replaces FIFO for inventory lines that need lot-individual costs. Each lot carries its own cost basis derived from the actual landed cost of the specific delivery it came in on. Reports, valuation, and margin all read from the lot-level cost rather than from a SKU-level average — finance sees the real margin per bottle, not an averaged abstraction.
Multi-UOM lot management with bulk creation
Lots are easy to create across different units of measure — cases, bottles, half-bottles, large formats — and the conversions hold consistently across stock, purchase, and sale flows. Operators creating new stock don't fight the UOM model on every receipt.
Custom product, PO, and SO models with import wizards
Product customisations and product-creator wizards let the team onboard wines with the attributes wine inventory actually needs (vintage, region, style, format, supplier, bond status). Purchase order and sale order modules carry custom enhancements plus import wizards so bulk inbound and outbound work — a supplier PO with 200 lines, a customer order with mixed bottles across many SKUs — happens as a single import instead of 200 manual entries.
Beverage sampling as a first-class workflow
A dedicated sampling module tracks tastings and trade samples against the right stock and the right valuation. Sampling deducts from inventory and posts to the correct cost / expense account. Finance reads honest sampling cost rather than aggregated "shrinkage."
Custom stock picking with industry-fit reports
Stock picking customisations plus custom report templates produce the picking lists, delivery notes, and inventory reports the wine business actually uses — not the generic stock printouts Odoo ships with.
Public website: age verification + honest stock visibility
Website age verification gates entry to the site to comply with the alcohol-sales legal requirement. A website inventory module ties the public storefront's product display to actual back-office stock, and a third-party module hides out-of-stock products from the public catalog so the public experience matches what is actually orderable.
Accounting customisations + journal sequence configuration
Accounting customisations align Odoo's posting rules to how the wine business reports — journal sequencing, period handling, and reconciliation patterns specific to the operation. Finance closes the books reading from the live data rather than reconciling against parallel records.
Advance access manager with role-scoped permissions
An advanced access-management layer provides granular role-based permissions, field-level security, model-level restrictions, and record-level filters. Different functions inside the business (buying, retail, accounting, fulfilment, sampling) see the views and actions that fit their role — not the full surface.
Custom discount engine
A discount module customises promotional logic for the wine retail motion — case discounts, mixed-six promotions, trade pricing tiers, and other patterns that generic retail discounts do not cleanly handle.
What Changed
- Finance reads real margin, not averaged margin. Lot-level actual costing replaces FIFO assumptions; the cost of any bottle on the books is the cost of that specific bottle, not an average across deliveries.
- Bulk operations work as bulk operations. Importing a 200-line supplier PO or a mixed-SKU customer order takes one upload, not 200 manual entries.
- Sampling stops being shrinkage. Trade tastings and samples track honestly against inventory and valuation, posting to the right finance accounts.
- The public site behaves honestly. Age verification at the gate, out-of-stock products hidden, live inventory tied to back-office stock — the public catalog matches what's actually orderable.
- The team sees only what fits their role. Role-scoped access stops every operator from seeing every screen; the system reads less cluttered and is easier to train new staff on.
- One platform for the storefront, back office, and finance. No separate e-commerce-to-ERP reconciliation pipeline; the storefront, stock, sampling, purchase, sales, and finance all read from one source.
Closing
Specialist wine retail is one of those operations where generic retail tooling almost works and then breaks at the seams that matter most — cost basis, units of measure, sampling, regulatory gating. The platform Linescripts built handles those seams as first-class workflows rather than as exceptions to the generic flow. Lot-individual costing, multi-UOM lot management, sampling tracked against stock and valuation, age verification on the storefront, role-scoped access for a small specialist team — the system reads like wine-business software, not like a configured generic retail ERP.