ZuloOne
English
Sign in
Menu

04 · Inventory — items, stores, and stock balances

Updated

Solution layer. Depends on Organization for sites. The model stores arbitrary items and store logistics by the MIQS model Store → Zone → Cell. It owns the Qty EDT and the Store, Cell, Item, Customer, and CustomerOutlet analytics.

← General specification

Purpose#

Inventory covers items (raw materials, semi-finished goods, finished goods, and merchandise), units of measure and item packs, counterparties (Supplier/Customer plus contacts and outlets), pricing (PriceType), stores (Store) → zones (StoreZone) → cells (StoreCell) with cell types and roles, the Stock register with balances by cell, and optional store discipline for receiving → storage → picking. Store discipline is off by default. The model also provides dictionaries and attributes, such as customer type and item tax category, that Sales and Purchasing use to build the tax context.

The process description is in Store and stock. This page does not repeat it. It lists exact object names, field names, and links.

What is created#

Kind Name Purpose
Model Inventory Module model on the Solution layer
NumberSequence 21 sequences; see Number sequences Numbering
EDT Qty (scalar) + 12 Ref EDTs; see EDT Types
Dictionary ItemGroup, Item, Brand, ItemUnit, PriceType, Supplier, Customer, CustomerContact, CustomerOutlet, Store, StoreZone, StoreCellType, StoreCell, InventorySettings (singleton) Items, pricing, counterparties, stores, zones, cells, and settings
TablePart PutAwayTaskLines, PickTaskLines, StockAdjustmentLines, StockTransferLines, StockCountLines, GoodsIssueLines WMS document lines
Document PutAwayTask, PickTask, StockAdjustment, StockTransfer, StockCount, GoodsIssue Movements, stock count, and issue
Register Stock Balances by cell
Analytic Store, Cell, Item, Customer, CustomerOutlet Register sections
Service IStoreCellService Cell resolution and store discipline
Script tx (PutAwayTaskTx/PickTaskTx/StockAdjustmentTx/StockTransferTx/StockCountTx/GoodsIssueTx), commands (ConfirmPutAway/ConfirmPick/PostStockAdjustment/PostStockTransfer/PostStockCount/PostGoodsIssue), dictionary and document events Postings, transitions, and validation
Menu menu.json Module menu
Reused from Common and the platform kernel UnitOfMeasure, UnitClass (Common), Division (Organization), Money (Accounting) Do not create them here

Total: 1 model, 21 number sequences, 13 EDTs (1 scalar + 12 Ref), 14 dictionaries (one singleton settings dictionary), 6 table parts, 6 documents, 1 register, 5 analytics, 1 service, scripts, and menu entries.

Sales extends PickTask on top of Inventory. See PickTask for reservations.

model.json#

Solution(2) layer. Dependency: Organization. Money comes from Accounting, so the model also declares a dependency on Accounting.

Number sequences#

ItemSeq, ItemGroupSeq, BrandSeq, ItemUnitSeq, PriceTypeSeq, SupplierSeq, CustomerSeq, CustomerContactSeq, CustomerOutletSeq, StoreSeq, StoreZoneSeq, StoreCellTypeSeq, StoreCellSeq, InventorySettingsSeq, PutAwayTaskSeq, PickTaskSeq, StockAdjustmentSeq, StockTransferSeq, StockCountSeq, GoodsIssueSeq.

The sequence files still contain UnitConversionSeq, but the model no longer has a UnitConversion object. Units were rebuilt on UnitClass and RatioToBase. See Store and stock. The sequence is an unused tail.

EDT#

The model owns the scalar Qty EDT: Decimal(18,4). It also owns 12 reference EDTs: RefItemGroup, RefItem, RefBrand, RefPriceType, RefSupplier, RefCustomer, RefCustomerContact, RefCustomerOutlet, RefStore, RefStoreZone, RefStoreCellType, and RefStoreCell.

RefUnitOfMeasure is not part of Inventory. Units of measure and their EDTs belong to Common. Inventory only references them through Item.UnitOfMeasure.

Dictionaries#

ItemGroup#

Code String(16), required, unique · Name String(64), required. The description is a free text hint such as RawMaterial/SemiFinished/FinishedGood/Merchandise. It is not a closed list. Groups are records, not enum values.

Item#

Fields: see Item in Objects below.

Field Business note
UnitOfMeasure Base unit for the item.
Barcode Indexed. Used by the form scan widget.
DefaultPurchasePrice Fallback when the supplier or customer has no PriceType.
DefaultSalePrice Sale fallback price.
TaxProductCategory Product/category key for TaxMapping with SourceType=Product/Category.

Referenced by Purchasing, Production, and Sales lines; the Item analytic; Stock, Cost, and Revenue; and ItemUnit. In the UI, SKU is ID or Barcode; there is no separate SKU column.

Brand#

Name String(256), required. A flat dictionary without hierarchy. Referenced by optional field Item.Brand.

ItemUnit#

An item pack stores the factor from a specific item and unit to the item base unit. The factor belongs to the item + unit pair, not to the unit itself: one item may have 12 pieces per box, another item may have 6. Fields: see ItemUnit in Objects below.

Field Business note
Unit Pack unit, for example BOX.
QtyInBaseUnit Number of Item.UnitOfMeasure base units in one pack.

ItemUnit is cached and logged. It is used by the ItemQuantityConverter implementation of IQuantityConverter on every quantity line. See Store and stock.

PriceType#

A price type applies to a transaction side. It is assigned by PriceType on Customer or Supplier and participates in price selection. Fields: see PriceType in Objects below.

Field Business note
Direction Sale prices are never selected for supplier orders, and purchase prices are never selected for sales.
Kind Base stores manually entered history through LT_PriceTypeHistory on the item card. Calculated derives from BasePriceType with MarkupPercent.
BasePriceType Required for Kind=Calculated; must be empty for Kind=Base. The handler checks it.
MarkupPercent May be negative for a discount. Must be 0 for Kind=Base.
IsDisabled Disabled price types are excluded from selection. Empty means active. The field is named from the disabled case so the optional Boolean default does not disable every type.

Supplier#

Fields: see Supplier in Objects below.

Field Business note
TaxRegistrationNumber VAT number for the tax context.
PriceType Purchase price type. Empty means item defaults are used.

Referenced by Store.InventoryAgent and Purchasing.

Customer#

Fields: see Customer in Objects below.

Field Business note
TaxRegistrationNumber Buyer VAT number. In KSA, this chooses clearance or reporting instead of CustomerType.
CustomerType B2B/B2C commercial classification. It does not choose the KSA clearance/reporting branch.
PriceType Sale price type. Empty means item defaults are used.

CRM extends Customer with loyalty fields. The record is referenced by the Customer analytic, CustomerContact, CustomerOutlet, and Sales.

CustomerContact#

A customer contact person. It is not a shipping address; shipping addresses are CustomerOutlet records. Fields: see CustomerContact in Objects below.

Customer is indexed for contact lookup by customer.

CustomerOutlet#

Ship-to point of a customer: address and contact. Commercial terms live on SalesContract in Sales, not here. Fields: see CustomerOutlet in Objects below.

Customer is indexed for ship-to lookup by customer. CustomerOutlet is logged and is referenced by the CustomerOutlet analytic and by Sales.

Store#

Store (MIQS Store). Fields: see Store in Objects below.

Field Business note
Division Site or office that owns the store.
InventoryAgent Materially responsible counterparty or depot agent.
IsSimple Marks a simple store without zones and cells.
IsSalesPoint Marks a point of sale used by Sales.

OnAfterSaveAsync: if store discipline is already enabled (InventorySettings.EnforceWarehouseTasks), a new store immediately gets its yard. See IStoreCellService. Referenced by StoreZone and the Store analytic.

StoreZone#

Store zone. It is cached and logged. Fields: see StoreZone in Objects below.

Field Business note
Store Owner store.
IsBarcodeTracking Enables barcode tracking in the zone.

Referenced by StoreCell.

StoreCellType#

Cell type. It is cached. Fields: see StoreCellType in Objects below.

Field Business note
Purpose Role of the type: Receiving, Storage, Picking, or Unspecified. The closed list replaces the legacy string-name check for Receiving; a typo in the type name no longer disables address discipline silently.

A cell type with Purpose that does not match the required role is not allowed when discipline is enabled. Cells of that type fail the single IsCellAllowedForAsync guard. Referenced by StoreCell.Type.

StoreCell#

Store cell. It is logged. The address is zone → line → rack → shelf → cell. Fields: see StoreCell in Objects below.

Field Business note
StoreZone The store is derived through StoreZone.Store.
Type Cell role is read through Type.Purpose.
IsPickable Hidden in the UI (isVisible:false). Code does not read it, because picking is determined by Type.Purpose = Picking.
MaxQty Reference capacity value. Automatic validation does not use it.

Referenced by the Cell analytic, Stock, and all WMS documents.

InventorySettings (singleton)#

One record, cannot be deleted, and opens directly for editing. Fields: see InventorySettings in Objects below.

Field Business note
DefaultReceivingLocation Requires an already open cell. Configure it after the store.
EnforceWarehouseTasks Empty means false: cells are free, and receipts/issues can use any cell directly without put-away or pick tasks. The field is intentionally named from the requirement, because the optional Boolean is generated as non-nullable and the working default must be off.
FulfillmentScheme Only matters when EnforceWarehouseTasks is enabled. Details and a numeric example are in Store and stock.

Enabling EnforceWarehouseTasks on existing data is safe and idempotent. OnAfterSaveAsync calls PrepareAllYardsAsync(). The service sets Purpose by role name and creates missing receiving, storage, and picking cells for each store. Repeating the call does not create duplicates.

Master data setup order#

Inventory objects have hard dependencies, where a field must point to an existing record, and soft dependencies, where you may leave a field empty and fill it later. If you skip a hard dependency, the next object is not saved. If you skip a soft dependency, the record is saved but some functions do not work until the field is filled.

  1. ItemGroup records are item groups. They need no other records. You cannot create an Item without one, because ItemGroup is required.
  2. Brand records are optional. Item.Brand is optional, so you can add brands later without changing existing items.
  3. Item is the item master. It requires ItemGroup and references UnitOfMeasure from Common. If the base units do not exist in Common, create them there first.
  4. ItemUnit records are optional packs for a specific item. They require Item. Missing packs, for example box = 12 pcs, simply are not available for that item and do not cause errors.
  5. PriceType is optional, but you need it before you want prices separate from Item.DefaultSalePrice and Item.DefaultPurchasePrice. Create Kind=Base price types first, then Kind=Calculated price types that need an existing BasePriceType.
  6. Supplier / Customer plus CustomerContact and CustomerOutlet are independent of stores, but must exist before the first documents with a counterparty, such as GoodsIssue.Customer or Store.InventoryAgent. PriceType on the card is a soft dependency and can be filled later.
  7. Store → StoreZone → StoreCellType → StoreCell is a hard chain. A zone requires an existing store; a cell requires an existing zone and type. For an IsSimple store without detailed addressing, one zone and one cell per store are enough.
  8. InventorySettings is configured last. DefaultReceivingLocation points to an existing StoreCell. EnforceWarehouseTasks can be enabled any time after that. PrepareAllYardsAsync fills missing role cells and sets Purpose on existing types by name. Enabling the flag after data already exists is safe.

What to decide before setup#

  • Simple store or zones/cells? Store.IsSimple is a decision for the whole store. You can change it later, but cell data for the earlier simple period does not appear retroactively.
  • Do you need address discipline from day one, or later? Retroactive enablement is safe; see step 8. You can start with discipline off and enable it when the storekeeper process is ready.
  • Name standard cell types by role. Use Receiving, Storage, or Picking. PrepareAllYardsAsync matches Purpose by name case-insensitively and independent of the register. Arbitrary type names require manual Purpose setup.

Analytics#

Store (RefStore), Cell (RefStoreCell), Item (RefItem), Customer (RefCustomer), and CustomerOutlet (RefCustomerOutlet) are used by Stock, Cost, Revenue, and LoyaltyPoints. Stock itself does not consume analytics; see below. They are needed by other registers of this model and by other models.

Registers#

Stock#

Balances in cells. The section is defined by two dimensions (dimensions), not by analytics:

{
  "kind": "Register",
  "object": {
    "registerEngineType": "Standard",
    "totalDriverMetaId": "<GUID Inventory-TotalDriver>",
    "isDoubleEntry": false, "allowNegativeBalance": true, "useBalanceTable": true,
    "metaId": "<GUID Reg.Stock>", "name": "Stock",
    "modelId": "<GUID Model.Inventory>"
  },
  "dimensions": [
    { "fieldName": "Cell", "edtMetaId": "<GUID EDT.RefStoreCell>", "isOperational": true },
    { "fieldName": "Item", "edtMetaId": "<GUID EDT.RefItem>", "isOperational": true }
  ],
  "resources": [ { "fieldName": "Qty", "edtMetaId": "<GUID EDT.Qty>", "isOperational": true } ]
}
  • The section is the cell. Store and zone are derived from StoreCell.StoreZone.Store.
  • allowNegativeBalance: true means the CAM engine does not reject an issue over balance. Document event handlers apply balance checks where needed; the check is not a register property.
  • The register has its own totalDriverMetaId. The balance is calculated by the standard accumulation register engine.

Example. At a random moment, the register stores one line for each cell/item pair:

Cell Item Qty
Storage-A1 Milk 1L 150
Picking-01 (Store-1) Milk 1L 26
Picking-01 (Store-2) Milk 1L 10

The numbers come from the end-to-end document example below: this is the final state after all six operations on one milk batch.

Documents (WMS)#

The example below follows one item, Milk 1L, through all six documents. The storekeeper receives 200 pcs; part is damaged, and part is shipped to the customer. Each document example continues the previous one.

None of the six documents uses transactionPairs.Add. All of them post to Stock with transactions.Add(new RegisterMovementSpec("Stock")…):

  • Two consecutive calls with the same BaseQuantity: one minus from a cell and one plus to another cell. Used by PutAwayTask, PickTask, and StockTransfer.
  • One signed call: GoodsIssue uses a minus only. StockAdjustment uses the signed line quantity. StockCount uses the signed calculated difference.

A document line may carry its own cell (line.FromCell, line.ToCell, or line.Cell, depending on the document). If it is empty, the line uses the header cell.

PutAwayTask#

Receiving → storage. Header FromCell → StoreCell is required and means the receiving cell. Table part Lines: Item, Quantity/BaseQuantity, ToCell. Subtypes: Draft (initial, editable) → Confirmed (read-only). The confirmed document is frozen. One tx script runs on Confirmed. Command: ConfirmPutAway.

OnBeforePostAsync requires Subtype == "Confirmed" and checks two things:

  • Physical stock always: for each line, the balance on FromCell from ITotalsManager.GetBalanceAsync must cover the requested quantity.
  • Policy only when EnforceWarehouseTasks is enabled: FromCell must have Purpose=Receiving, and each line.ToCell must have Purpose=Storage, checked through IStoreCellService.IsCellAllowedForAsync.

Example. The supplier brought 200 Milk 1L units into the receiving cell. The storekeeper puts the whole lot into permanent storage:

Cell Role Balance before Movement Balance after
Receiving-01 Receiving 200 −200 0
Storage-A1 Storage 0 +200 200

PickTask#

Storage → picking. Header FromCell → StoreCell is required and means the storage cell. Subtypes: Draft (editable) → Confirmed (read-only). Explicit transitions exist in both directions: Draft→Confirmed and Confirmed→Draft, so confirmation can be cancelled. Command: ConfirmPick.

OnBeforePostAsync checks physical stock on FromCell always. When EnforceWarehouseTasks is enabled, it also checks policy: FromCell must have Purpose=Storage, and each line.ToCell must have Purpose=Picking.

There are three tx scripts, not one script per subtype:

  • Draft → PickTaskDraftReserveTx in the Sales extension PickTask.Sales with [ExtensionOf]. A draft pick does not move Stock; it writes +qty to ReservedStock on FromCell (storage) so a second order does not see the same cell as free.
  • Confirmed, executionOrder 1 → PickTaskTx in Inventory. It moves Stock: minus FromCell, plus line.ToCell.
  • Confirmed, executionOrder 2 → PickTaskFollowReserveTx in Sales. If the task serves a sales order (ISalesFulfillmentService.PickServesSalesOrderAsync), it moves the reserve to the new cell (line.ToCell). Manual picking without an order creates no reserve.

The black reserve on FromCell is removed by the platform automatically when the document exits the Draft subtype. No script clears it manually. Reserve (ReservedStock) and balance are read separately by ICellFreeStock as physical balance minus someone else's reserve. The Reserved stock by item and cell layout is described in Store and stock.

Example. 50 items are picked from the storage cell for a customer order:

Cell Role Balance before Movement Balance after
Storage-A1 Storage 200 −50 150
Picking-01 (Store-1) Picking 0 +50 50

If this task serves a sales order, the reserve on Storage-A1 (+50, created by draft PickTask) is removed and transferred to Picking-01. This operation does not change the Stock balance; it is a separate Sales register operation.

StockAdjustment#

Write-off or surplus acceptance. Header Cell → StoreCell is required. Reason is optional String(128). Table part Lines: Item, Quantity. Subtypes: Draft → Posted, and both are editable. Unlike Pick, Put-away, and Goods Issue, the posted document remains editable. One tx script runs on Posted. Command: PostStockAdjustment.

OnBeforePostAsync checks balance sufficiency only for negative lines, which write stock off. Positive lines, which add surplus, are always allowed.

Example. In the picking cell, the storekeeper found damage of 3 pcs and one extra unit during recount. Two separate documents would be excessive, so one StockAdjustment has two lines:

Line Reason Qty (signed) Balance before Balance after
1 Breakage −3 50 47
2 Extra unit found +1 47 48

StockTransfer#

Free movement between cells. Header FromCell and ToCell are both required; they are the defaults for the lines. Table part Lines: Item, Quantity, and optional FromCell / ToCell — a filled line cell overrides the header for that line, so one transfer can gather from several cells or spread into several. Subtypes: Draft → Posted, and both are editable. One tx script runs on Posted. Command: PostStockTransfer.

OnBeforePostAsync checks only physical stock on the source cell (line.FromCell or the header). There is no Purpose validation, unlike Pick and Put-away. Free movement is not part of target store discipline. Skipping the balance check here is more dangerous than in a normal issue: the movement is net zero, the cost driver does not see it, and an unchecked transfer can create a phantom balance without a cost layer at the destination.

Example. Part of the batch is moved to a second store, for example for an opened outlet. This is free movement without roles and without a reservation:

Cell Balance before Movement Balance after
Picking-01 (Store-1) 48 −10 38
Picking-01 (Store-2) 0 +10 10

StockCount#

Cell inventory count. Header Cell → StoreCell is required. CountDate is required DateTime, not an EDT. Table part Lines: required Item, required CountedQty → Qty. Subtypes: Draft → Posted, and both are editable. One tx script runs on Posted. Command: PostStockCount.

This is not a guard; it is a delta calculation. OnBeforePostAsync calculates, for each line, delta = counted − onHand from Stock[Cell,Item] balance, uses BaseQuantity with fallback to CountedQty, and writes the result to TP_StockCountLines.QtyDelta directly through IDataService.UpdateAsync. It bypasses the normal save because draft line writes may not reach the database before the tx script runs. The tx script (StockCountTx) reads the already calculated QtyDelta and posts one signed Stock movement per line. delta = 0 creates no movement.

OnBeforeSaveAsync sets header.DocumentDate = CountDate before posting, so movements use DocumentDate and not CountDate directly. You can enter Item with a scanner by Barcode; see the form scan widget.

Example. Planned count of the Picking-01 (Store-1) cell: the storekeeper counts the physical stock and enters the actual quantity for each item. The document calculates the difference and posts only that difference:

Item System balance (on hand) Counted (CountedQty) Delta (QtyDelta) Movement on Stock
Milk 1L 38 36 −2 −2 (shortage write-off)
Kefir 1L 15 14 −1 −1 (shortage)
Yogurt 200g 5 5 0 no movement

Milk and kefir have shortages, perhaps because someone took stock without a document or because of a previous error. Yogurt matches. The line is saved, but Stock is unchanged. After posting on Picking-01 (Store-1), Milk 1L = 36.

GoodsIssue#

Issue. Header Customer → Customer is optional. Header FromCell → StoreCell is required and means the picking cell. Table part Lines: Item, Quantity. Subtypes: Draft (editable) → Posted (read-only). One tx script runs on Posted. Command: PostGoodsIssue.

OnBeforePostAsync rejects lines with qty <= 0, aggregates demand by (Cell, Item) through BaseQuantity with fallback to Quantity, and checks balance through ITotalsManager.GetBalanceAsync("Stock", …). The line cell is line.FromCell or the header cell.

Example. 10 pcs of milk are shipped directly from the picking cell to customer Camel LLC. Issue has no counter-movement, unlike the previous documents. It only subtracts stock:

Cell Balance before Movement Balance after
Picking-01 (Store-1) 36 −10 26

The final balance is 26 in the first store, plus 10 in the second store from the StockTransfer example. Those are the balances shown in the Stock register snapshot above.

Services#

IStoreCellService#

The model's only service resolves cells and owns the entire store discipline policy. The real contract in Inventory/Services/StoreCellService/StoreCellService.cs is broader than "choose the default cell":

  • GetDefaultReceivingCellAsync/GetDefaultPickingCellAsync/GetDefaultOutputCellAsync(store), SuggestPutAwayCellAsync(store, item), SuggestStorageCellAsync(...), GetStoreAsync(cell), GetCellsOfStoreAsync(store, purpose?): resolve cells for postings in Purchasing, Production, and Sales. The store is derived through StoreCell.StoreZone.Store.
  • IsStoreDisciplineOnAsync() reads InventorySettings.EnforceStoreTasks.
  • GetCellPurposeAsync(cell) / GetCellByPurposeAsync(store, purpose) read the cell role through StoreCell.Type.Purpose.
  • IsCellAllowedForAsync(cell, purpose): when discipline is off, it always returns true for backward compatibility. When discipline is on, it verifies that the cell Purpose matches the requested role. This is the only policy point; it is called from PutAwayTask and PickTask events and is not duplicated in each document.
  • EnsureYardAsync(store) idempotently creates a start yard for a store: a main zone plus one Receiving, one Storage, and one Picking cell if they do not exist yet.
  • PrepareAllYardsAsync() is a retroactive backfill. It sets Purpose on existing StoreCellType records by name, matching Receiving/Acceptance, Storage/Storage, and Picking/Selection case-insensitively, then calls EnsureYardAsync for each store. InventorySettingsEventHandler.OnAfterSaveAsync calls it automatically when EnforceStoreTasks is enabled.
  • GetLegalEntityAsync(cell) bridges from cell to legal entity for taxes and GL: StoreCell → StoreZone → Store → Division → LegalEntity.

Physical balance checks, meaning "is there enough stock", are not in this service and not in an availability service. Each document's OnBeforePostAsync performs the needed check separately through ITotalsManager.GetBalanceAsync("Stock", …).

Business logic and invariants#

Storage hierarchy. Store → StoreZone by Store → StoreCell by StoreZone. Cell address is line / rack / shelf / cell plus type, and the role is read through Type.Purpose. An IsSimple store can operate without detailed addressing.

Balance is in the cell, not in the store. Store and zone are derived through StoreCell.StoreZone.Store. Stock has no separate store analytic. The register allows negative balance at the engine level (allowNegativeBalance:true). Balance checks over available quantity are application checks in document OnBeforePostAsync, and they differ by document: GoodsIssue checks all demand, StockAdjustment checks only write-offs, StockTransfer checks only the source cell, and StockCount is a delta calculation, not a guard.

Address discipline is optional and off by default. InventorySettings.EnforceStoreTasks = false means cells are free: receipts and issues may use any cell directly, and pick/put-away tasks are not required. When the flag is on, receipts go only to Purpose=Receiving, issues go only from Purpose=Picking, and PutAwayTask and PickTask are required between them. Switching on existing data is safe; see InventorySettings. The store does not need to be prepared in advance.

Items are not teleportable. Any movement between cells is a pair of operations: one minus and one plus. The documents implement this with two consecutive register calls, not with platform pair posting.

Cell resolution and cell-role policy are centralized. Postings in Purchasing, Production, and Sales get cells and check roles through IStoreCellService. Do not hardcode IDs or compare type names as strings.

Stock count posts the difference. StockCount does not rewrite the balance. It moves Stock by fact − system for a cell/item pair. The audit trail and cost stay consistent.

Reservations are not in Inventory. The ReservedStock register and ISalesFulfillmentService belong to Sales. Sales extends PickTask with additional tx scripts; see PickTask. Without the Sales model, PickTask still physically moves Stock, but there is no cell reservation between draft and confirmation.

Inventory → Dictionaries (15 entries, including singleton InventorySettings) · Documents (PutAwayTask, PickTask, StockAdjustment, StockTransfer, StockCount, GoodsIssue) · Registers (Stock) · Settings (InventorySettings).

  • Outgoing: Organization (Division), Accounting (Money), and Common (UnitOfMeasure, UnitClass, Address).
  • Incoming: Purchasing, Production, and Sales use Stock, IStoreCellService, counterparty dictionaries, and item dictionaries. Costing reads cost by Store/Item and integrates StockCount with the cost driver. CRM extends Customer. Sales extends PickTask with two reservation tx scripts (PickTask.Sales).

Objects#

Generated from workspace metadata by node tools/gen-reference.mjs; edit the metadata, not this block.

Dictionaries#

Brand — Brands

Field Caption Type Required
ID Code String(50) Yes
Name Name String(256) Yes

Customer — Customers

Field Caption Type Required
Address Address → Address No
CreditLimit Credit limit Money No
CustomerType Customer type code String(8) No
Email Email String(128) No
FullName Full name String(250) No
ID ID String(50) Yes
IsDisabled Disabled Boolean No
Kind Customer type → CustomerType No
Name Name String(160) Yes
Notes Notes String(2000) No
PaymentTerm Payment term → PaymentTerm No
Phone Phone String(32) No
PriceType Price type → PriceType No
TaxRegistrationNumber Tax reg. number String(64) No

CustomerContact — Customer contacts

Field Caption Type Required
Customer Customer → Customer Yes
Email Email String(128) No
ID Code String(50) Yes
IsPrimary Primary contact Boolean No
Name Name String(256) Yes
Phone Phone String(64) No

CustomerOutlet — Customer outlets

Ship-to of a customer: address and contact. Commercial terms live on SalesContract.

Field Caption Type Required
Address Address → Address No
Contact Contact → CustomerContact No
Customer Customer → Customer Yes
ID ID String(50) Yes
IsDisabled Disabled Boolean No
Lat Latitude Decimal(10,7) No
Lng Longitude Decimal(10,7) No
Name Name String(160) Yes
Phone Phone String(32) No
WorkingHours Working hours String(200) No

CustomerType — Customer types

B2B, B2C, Retail… — what the customer card's «Customer type» points at. The code is what other models compare (loyalty campaigns, the invoice's buyer.type); it is copied onto the customer's hidden CustomerType column.

Field Caption Type Required
Code Code String(8) Yes
ID Code String(50) Yes
Name Name String(128) Yes

InventorySettings — Inventory settings

Field Caption Type Required
DefaultPurchasePriceType Default purchase price type → PriceType No
DefaultReceivingLocation Default receiving location → StoreCell No
DefaultSalePriceType Default sale price type → PriceType No
DefaultUnit Default unit of measure → UnitOfMeasure No
EnforceUnitConversion Enforce unit conversion Boolean No
EnforceWarehouseTasks Enforce warehouse tasks Boolean No
FulfillmentScheme Shipment scheme WarehouseFulfillmentSchemeEdt No
ID ID String(50) Yes

Item — Items

Any item: raw material, semi-finished, finished good, merchandise

Field Caption Type Required
Article Article String(64) No
Barcode Barcode String(64) No
BaseName Base name String(200) No
Brand Brand → Brand No
CharacteristicTemplate Characteristic template → CharacteristicTemplate No
DefaultPurchasePrice Default purchase price Money No
DefaultSalePrice Default sale price Money No
Description Description String(500) No
ID ID String(50) Yes
Image Image Image No
IsDisabled Discontinued Boolean No
IsRawMaterial Raw material Boolean No
IsSellable Sellable Boolean No
ItemGroup Item group → ItemGroup Yes
Name Name String(160) Yes
TaxCode VAT rate → TaxCode No
TaxProductCategory Tax product category String(32) No
UnitOfMeasure Unit → UnitOfMeasure Yes
WeightGross Gross weight, kg Decimal(15,3) No
WeightNet Net weight, kg Decimal(15,3) No

ItemCategory — Item categories

Catalogue tree like a web shop: Paints → Interior. A category's characteristic template is inherited by its subcategories.

Field Caption Type Required
ID Code String(50) Yes
MemberCharacteristicTemplate Template for its items → CharacteristicTemplate No
Name Name String(150) Yes
ParentId Parent → ItemCategory No

ItemGroup — Item groups

RawMaterial / SemiFinished / FinishedGood / Merchandise

Field Caption Type Required
Code Code String(16) Yes
ID ID String(50) Yes
MemberCharacteristicTemplate Template for its items → CharacteristicTemplate No
Name Name String(64) Yes
ParentId Parent → ItemGroup No

ItemUnit — Item units

Field Caption Type Required
ID Code String(50) Yes
Item Item → Item Yes
QtyInBaseUnit Quantity in base unit Decimal(18,6) Yes
Unit Unit → UnitOfMeasure Yes

PriceListItem — Item prices

Field Caption Type Required
EffectiveFrom Effective from DateTime No
EffectiveTo Effective to DateTime No
ID Code String(50) Yes
Item Item → Item Yes
Price Price Money Yes
PriceType Price type → PriceType Yes
Unit Unit → UnitOfMeasure Yes

PriceType — Price types

Field Caption Type Required
BasePriceType Base price type → PriceType No
Direction Direction PriceDirectionEdt Yes
ID ID String(50) Yes
IsDisabled Disabled Boolean No
Kind Kind PriceTypeKindEdt Yes
MarkupPercent Markup % Percent No
Name Name String(160) Yes
RoundingStep Rounding step Decimal(10,4) No
RoundUp Round up Boolean No

Store — Stores

Store / warehouse (MIQS Store). Zones and cells hang off it.

Field Caption Type Required
Division Division → Division Yes
ID Code String(50) Yes
InventoryAgent Inventory agent → Supplier No
IsSalesPoint Sales point Boolean No
IsSimple Simple store Boolean Yes
Name Name String(128) Yes

StoreCell — Store cells

Bin within a store zone (MIQS StoreCell); addressed by line/rack/shelf/cell. Stock is held per cell; store is derived via StoreZone.Store.

Field Caption Type Required
CellNumber Cell Integer Yes
ID Code String(50) Yes
IsPickable Pickable Boolean No
LineNumber Line Integer Yes
MaxQty Capacity (max qty) Qty No
Name Name String(64) Yes
RackNumber Rack Integer Yes
ShelfNumber Shelf Integer Yes
StoreZone Zone → StoreZone Yes
Type Cell type → StoreCellType Yes

StoreCellType — Store cell types

Receiving / Storage / Picking (MIQS StoreCellType)

Field Caption Type Required
Code Code String(16) Yes
ID Code String(50) Yes
Name Name String(64) Yes
Purpose Purpose StoreCellPurposeEdt No

StoreZone — Store zones

Zone within a store (MIQS StoreZone); groups cells. Store is the owner.

Field Caption Type Required
ID Code String(50) Yes
IsBarcodeTracking Barcode tracking Boolean Yes
Name Name String(128) Yes
Store Store → Store Yes

Supplier — Suppliers

Field Caption Type Required
Email Email String(128) No
FullName Full name String(250) No
ID ID String(50) Yes
IsDisabled Disabled Boolean No
Name Name String(160) Yes
Notes Notes String(2000) No
Phone Phone String(32) No
PriceType Price type → PriceType No
TaxRegistrationNumber Tax reg. number String(64) No

Documents#

GoodsIssue — Goods issue

Header fields:

Field Caption Type Required
Customer Customer → Customer No
FromCell From cell → StoreCell Yes
ID Number String(50) Yes

Subtypes:

Subtype Caption
Draft Draft
Posted Posted

Commands:

Command Caption Target subtype
PostGoodsIssue Post goods issue —

PickTask — Pick task

Header fields:

Field Caption Type Required
FromCell From cell (storage) → StoreCell Yes
ID Number String(50) Yes

Subtypes:

Subtype Caption
Draft Draft
Confirmed Confirmed

Commands:

Command Caption Target subtype
ConfirmPick Confirm pick —

PutAwayTask — Put-away task

Header fields:

Field Caption Type Required
FromCell From cell (receiving) → StoreCell Yes
ID Number String(50) Yes

Subtypes:

Subtype Caption
Draft Draft
Confirmed Confirmed

Commands:

Command Caption Target subtype
ConfirmPutAway Confirm put-away —

StockAdjustment — Stock adjustment

Header fields:

Field Caption Type Required
Cell Cell → StoreCell Yes
ID Number String(50) Yes
Reason Reason String(128) No

Subtypes:

Subtype Caption
Draft Draft
Posted Posted

Commands:

Command Caption Target subtype
PostStockAdjustment Post adjustment —

StockCount — Stock count

Header fields:

Field Caption Type Required
Cell Cell → StoreCell Yes
CountDate Count date DateTime Yes
ID Number String(50) Yes

Subtypes:

Subtype Caption
Draft Draft
Posted Posted

Commands:

Command Caption Target subtype
PostStockCount Post stock count —

StockTransfer — Stock transfer

Header fields:

Field Caption Type Required
FromCell From location → StoreCell Yes
ID Number String(50) Yes
Notes Notes String(2000) No
ToCell To location → StoreCell Yes

Subtypes:

Subtype Caption
Draft Draft
Posted Posted

Commands:

Command Caption Target subtype
PostStockTransfer Post transfer —

Registers#

Stock — Stock

On-hand quantity by location and item (single-entry accumulation register, MIQS-style). Receipts add +qty, issues/sales post -qty directly from the cell; transfers move between two cells. Balance = actual on-hand — no External counterparty bucket.

Dimensions:

Dimension Caption Type Required
Cell Cell → StoreCell —
Item Item → Item —

Resources:

Resource Caption Type Required
Qty Qty Qty —

Table parts#

GoodsIssueLines — Lines

Used by: GoodsIssue.

Field Caption Type Required
BaseQuantity Qty in base unit Qty No
FromCell From cell → StoreCell No
Item Item → Item Yes
Quantity Quantity Qty Yes
Unit Unit → UnitOfMeasure No

PickTaskLines — Lines

Used by: PickTask.

Field Caption Type Required
BaseQuantity Qty in base unit Qty No
Item Item → Item Yes
Quantity Quantity Qty Yes
ToCell To cell (picking) → StoreCell Yes
Unit Unit → UnitOfMeasure No

PutAwayTaskLines — Lines

Used by: PutAwayTask.

Field Caption Type Required
BaseQuantity Qty in base unit Qty No
Item Item → Item Yes
Quantity Quantity Qty Yes
ToCell To cell (storage) → StoreCell Yes
Unit Unit → UnitOfMeasure No

StockAdjustmentLines — Lines

Used by: StockAdjustment.

Field Caption Type Required
Amount Amount Money No
BaseQuantity Qty in base unit Qty No
Cell Cell → StoreCell No
Item Item → Item Yes
PackQty Packages Qty No
PackUnit Package unit → UnitOfMeasure No
Quantity Quantity Qty Yes
Unit Unit → UnitOfMeasure No
UnitPrice Unit price Money No

StockCountLines — Lines

Used by: StockCount.

Field Caption Type Required
BaseQuantity Qty in base unit Qty No
Cell Cell → StoreCell No
CountedQty Counted qty Qty Yes
Item Item → Item Yes
QtyDelta Qty delta Qty No
Unit Unit → UnitOfMeasure No

StockTransferLines — Lines

Used by: StockTransfer.

Field Caption Type Required
Amount Amount Money No
BaseQuantity Qty in base unit Qty No
FromCell From cell → StoreCell No
Item Item → Item Yes
PackQty Packages Qty No
PackUnit Package unit → UnitOfMeasure No
Quantity Quantity Qty Yes
ToCell To cell → StoreCell No
Unit Unit → UnitOfMeasure No
UnitPrice Unit price Money No
Was this page helpful?