Skip to content

Purchase Bills (فواتير المشتريات)

Purchase Bills record supplier invoices and create accounting journal entries. They integrate with Purchase Orders for billing tracking and with Inventory for direct-mode stock receipts.

Entity Attributes

FieldTypeDescription
idintegerPrimary key
bill_numberstringAuto-generated (BILL-YYYY-NNNNN)
datedateBill date
due_datedatePayment due date
supplier_idintegerFK to business_partners
supplier_namestringDenormalized supplier name
supplier_invoice_numberstringSupplier's own invoice reference
supplier_invoice_datedateDate on supplier's invoice
purchase_order_idintegerOptional linked PO
currency_idintegerFK to currencies
exchange_ratedecimalCurrency exchange rate
cost_center_idintegerFK to cost_centers
statusenumBill lifecycle status
payment_statusstringpending / partial / paid
discount_typestringHeader discount: percentage or fixed
discount_valuedecimalDiscount value
discount_amountdecimalCalculated discount amount
subtotaldecimalSum of line totals
tax_amountdecimalSum of line taxes
totaldecimalsubtotal - discount + tax
amount_paiddecimalTotal payments applied
balance_duedecimaltotal - amount_paid
journal_entry_idintegerFK to journal_entries (after posting)

Bill Item Attributes

FieldTypeDescription
product_idintegerFK to products
product_variant_idintegerOptional variant
unit_idintegerFK to units
warehouse_idintegerTarget warehouse (for stock)
quantitydecimalQuantity billed
unit_costdecimalCost per unit
discount_typestringLine discount: percentage or fixed
discount_valuedecimalDiscount value
discount_amountdecimalCalculated discount
tax_rate_idintegerFK to tax_rates
tax_ratedecimalTax percentage
tax_amountdecimalCalculated tax
line_totaldecimal(qty * unit_cost) - discount

Status Workflow

API Endpoints

MethodEndpointPermissionDescription
GET/api/purchases/billspurchases.bills.viewList bills with filters
POST/api/purchases/billspurchases.bills.createCreate new bill
GET/api/purchases/bills/{id}purchases.bills.viewShow bill details
PUT/api/purchases/bills/{id}purchases.bills.updateUpdate draft bill
DELETE/api/purchases/bills/{id}purchases.bills.deleteDelete draft bill
POST/api/purchases/bills/{id}/submit-approvalpurchases.bills.approveSubmit for approval
POST/api/purchases/bills/{id}/approvepurchases.bills.approveApprove bill
POST/api/purchases/bills/{id}/rejectpurchases.bills.approveReject back to draft
POST/api/purchases/bills/{id}/postpurchases.bills.postPost (creates JE + stock)
POST/api/purchases/bills/{id}/cancelpurchases.bills.cancelCancel bill
POST/api/purchases/orders/{id}/create-billpurchases.bills.createCreate bill from PO

Query Parameters (List)

ParamTypeDescription
statusstringFilter by status
payment_statusstringFilter by payment status
supplier_idintegerFilter by supplier
purchase_order_idintegerFilter by linked PO
branch_idintegerFilter by branch
date_fromdateStart date range
date_todateEnd date range
due_date_fromdateDue date range start
due_date_todateDue date range end
supplier_invoice_numberstringSearch supplier reference
searchstringSearch bill_number, supplier ref, supplier name

Journal Entry Structure

When a bill is posted, the following journal entry is created:

AccountDebitCreditCondition
Inventory Accountline_totalProducts with track_inventory = true
Expense Accountline_totalServices / non-inventory products
Input Tax Accounttax_amountIf tax > 0
Purchase Discount Accountdiscount_amountIf header discount > 0
Accounts PayabletotalAlways

GL accounts are configured in Purchases Settings:

  • purchases.inventory_account_id
  • purchases.expense_account_id
  • purchases.payable_account_id
  • purchases.tax_receivable_account_id
  • purchases.discount_account_id

Direct Mode Stock

When purchases.grn_mode = 'direct', posting a bill also creates inventory receipts:

  1. Items are grouped by warehouse_id
  2. One InventoryReceipt is created per warehouse
  3. Each receipt is auto-approved via ApproveReceipt action
  4. Only products with track_inventory = true and a warehouse_id are included

PO Billing Integration

  • Creating a bill from a PO copies items with remainingBillQuantity()
  • Posting updates each PO item's billed_quantity
  • PO's bill_status is recalculated (not_billed / partial / billed)
  • Cancellation reverses billed quantities

Business Rules

  • Only Draft bills can be edited or deleted
  • Only Approved bills can be posted
  • Bills with payments (amount_paid > 0) cannot be cancelled
  • Cancellation reverses: JE, stock (if direct mode), PO billed quantities
  • Posting requires at least one item and configured GL accounts
  • payment_status is auto-managed: pending → partial → paid

Moon ERP API Documentation