backbone-inventory 0.17.2

Inventory: stock ledger of record (SLE) + moving-average valuation; emits COGS/asset AccountingPost (Delivery/Receipt -> GL)
Documentation
# =============================================================================
# Domain: Inventory
# Entity: DeliveryNote (+ DeliveryNoteItem)
# Description: Outbound delivery. On submit → SLE outgoing (qty -, consuming the
# current moving-average valuation) → Bin updated → emits AccountingPost
# (Dr COGS · Cr Inventory) for the consumed value. customer_id / source SO / item
# are logical FKs; cogs/inventory accounts are logical FKs to accounting.Account.
# =============================================================================

models:
  - name: DeliveryNote
    collection: delivery_notes
    description: "Outbound delivery; emits a COGS (Dr COGS · Cr Inventory) post on submit"

    fields:
      id:
        type: uuid
        attributes: ["@id", "@default(uuid)"]
        description: "Unique delivery identifier"

      delivery_number:
        type: string
        attributes: ["@required", "@max(40)"]
        description: "Human reference (the post's voucher_no)"


      branch_id:
        type: uuid?
        attributes: ["@exclude_from_foreign_key_check"]
        description: "Branch # logical FK to organization.Branch.id"

      customer_id:
        type: uuid
        attributes: ["@required", "@exclude_from_foreign_key_check"]
        description: "Customer # logical FK to party.Party.id"

      source_so_id:
        type: uuid?
        attributes: ["@exclude_from_foreign_key_check"]
        description: "Source sales order # logical FK to selling.SalesOrder.id"

      warehouse_id:
        type: uuid
        attributes: ["@required", "@foreign_key(Warehouse.id)"]
        description: "Source warehouse"

      posting_date:
        type: date
        attributes: ["@required"]
        description: "Delivery / posting date"

      total_cogs:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)", "@non_negative"]
        description: "Σ consumed value across lines (computed at post from valuation) — the COGS debit"

      # ---- GL account refs (logical FKs to accounting.Account) ----
      cogs_account_id:
        type: uuid
        attributes: ["@required", "@exclude_from_foreign_key_check"]
        description: "COGS (expense) account to debit # logical FK to accounting.Account.id"

      inventory_account_id:
        type: uuid
        attributes: ["@required", "@exclude_from_foreign_key_check"]
        description: "Inventory (asset) account to credit # logical FK to accounting.Account.id"

      transfer_id:
        type: uuid?
        attributes: ["@foreign_key(Transfer.id)"]
        description: "The delivery transfer this voucher minted (SC-1 convergence): submitting the delivery mints a Transfer (outgoing) grouping its StockMoves; the move pipeline's _action_done writes the SLE rows and GL legs through the proven AccountingPost seam. NULL = not yet minted (draft)"

      status:
        type: DocStatus
        attributes: ["@default(draft)"]
        lifecycle:
          shape: hand_set
        description: "Document lifecycle (hand_set, ADR-0016): draft -> submitted -> cancelled, driven by the voucher submit/cancel pipeline — the minted transfer's state is a projection (T1) and never feeds back into this field"

      posting_state:
        type: GlPostingState
        attributes: ["@default(pending)"]
        description: "GL reconciliation state"

      journal_id:
        type: uuid?
        attributes: ["@exclude_from_foreign_key_check"]
        description: "Resulting journal # logical FK to accounting.Journal.id"

      accounting_post_id:
        type: uuid?
        attributes: ["@exclude_from_foreign_key_check"]
        description: "The AccountingPost record # logical FK to accounting.AccountingPost.id"

      posted_at:
        type: datetime?
        description: "When the GL post was confirmed"

      notes:
        type: string?
        attributes: ["@max(1000)"]
        description: "Free-text notes"

      metadata:
        type: Metadata
        attributes: ["@audit_metadata"]
        description: "Audit metadata"

    relations:
      items:
        type: DeliveryNoteItem[]
        attributes: ["@one_to_many"]
        description: "Delivered lines"
        inverse: delivery

    indexes:
      - type: unique
        fields: [delivery_number]
        where: "deleted_at IS NULL"
      - type: index
        fields: [posting_state]
      - type: index
        fields: [transfer_id]
        description: "Minted-transfer lookup (voucher -> picking projection)"

  - name: DeliveryNoteItem
    collection: delivery_note_items
    # engine-owned table: written only by the move engine / its parent
    # document verbs; the generic CRUD surface is reads.
    read_only: true
    description: "One delivered line (qty; COGS computed at post from current valuation)"

    fields:
      id:
        type: uuid
        attributes: ["@id", "@default(uuid)"]
        description: "Unique line id"

      delivery_id:
        type: uuid
        attributes: ["@required", "@foreign_key(DeliveryNote.id)"]
        description: "Owning delivery note"


      item_id:
        type: uuid
        attributes: ["@required", "@exclude_from_foreign_key_check"]
        description: "Catalog item # logical FK to catalog.Item.id"

      quantity:
        type: decimal
        attributes: ["@required", "@precision(18,4)", "@non_negative"]
        description: "Delivered quantity"

      valuation_rate:
        type: decimal
        attributes: ["@default(0)", "@precision(18,6)", "@non_negative"]
        description: "Moving-average rate consumed (snapshot at post)"

      cogs_amount:
        type: decimal
        attributes: ["@default(0)", "@precision(18,2)", "@non_negative"]
        description: "quantity * valuation_rate at post (2dp)"

      metadata:
        type: Metadata
        attributes: ["@audit_metadata"]
        description: "Audit metadata"

    relations:
      delivery:
        type: DeliveryNote
        attributes: ["@one", "@foreign_key(delivery_id)"]
        description: "Owning delivery note"
        inverse: items

    indexes:
      - type: index
        fields: [delivery_id]