Purchase Order

Create purchase order

Creates a new purchase order to track purchase commitments before invoices are received. This endpoint handles three types of purchase orders with comprehensive validation and automatic folio generation.

Purchase Order Types

1. Against Invoice

Single invoice purchase order with exactly one item at 100%.

Use case: Simple purchases with a single invoice expected.

Example: Purchasing office equipment for $10,000 CLP.

2. By Milestone

Multiple named deliverables with individual percentages.

Use case: Projects with defined stages and separate invoicing for each stage.

Example: Software project with Design (30%), Development (50%), Testing (20%).

3. By Percentage

Multiple payment stages with percentages (no names required).

Use case: Service contracts with payment schedule.

Example: Consulting service with 30% advance, 50% mid-project, 20% final payment.

Prerequisites

Before creating a purchase order, you need:

  1. Business Partner: The vendor/supplier for this purchase

    • Must be pre-registered and approved
    • Find partners: GET /v1/erp/payouts/business_partners
  2. Company: The company making the purchase

    • User must be a member with appropriate role
    • Required roles: admin, owner, or member

Validation Rules

General Rules (All Types)

  • amount_cents: Integer, >= 0, in the minor unit of currency — not always a hundredth. CLP → whole pesos (10000 is $10.000). USD → cents (99000 is US$990). UF/CLF → ten-thousandths of a UF (400000 is 40 UF). See Amounts and currency.
  • description: Required field for purchase reference
  • currency: Must be exactly one of CLP, UF, CLF, USD — case-sensitive, so clp or uf is rejected. UF is normalized to its ISO code CLF on save, which is what reads back.
  • items: Must have at least one item
  • percentages: Item percentages must sum to exactly 100%
  • custom columns: every custom column the company marked as required_on_purchase_orders must have a value, sent in custom_column_values or coming from the column's default_value. Otherwise 422 with errors: ["<label> es obligatoria para solicitar una orden de compra"] and nothing is created. Once created, a required value cannot be emptied (PATCH /v1/custom_column_values answers 422); orders created before the column was required stay editable.

Type-Specific Rules

AgainstInvoice:

  • Must have exactly 1 item
  • Item percentage must be 100%
  • Item name is optional (not required)

ByMilestone:

  • Must have at least 1 item
  • Each item must have a name
  • Item percentages must sum to 100%

ByPercentage:

  • Must have at least 2 items
  • Item names are optional (not required)
  • Item percentages must sum to 100%

Automatic Features

Folio Generation

System automatically generates a folio: a per-company sequential integer (1, 2, 3, ...), unique within the company. It is not a formatted string.

Item Amount Calculation

System automatically calculates item amounts based on percentages:

  • Formula: item.amount_cents = (total_amount_cents × percentage / 100).round
  • Automatically recalculated when total amount changes

Creator Tracking

System automatically assigns current authenticated user as creator (user_id).

Workflow

  1. Purchase order is created with status draft
  2. Admin/creator assigns reviewers to items (if approval required)
  3. Reviewers approve or reject items independently
  4. When fiscal invoice arrives, it's linked to approved items
  5. Linked items can be paid via bank transactions
  6. When all items are paid, purchase order is considered complete

Important Notes

  • Regular users can only create purchase orders for companies they are members of
  • All amounts are integers in the minor unit of the order's currency: whole pesos for CLP, cents for USD, ten-thousandths for UF/CLF. See Amounts and currency
  • Item amounts are automatically calculated from percentages
  • With tax_treatment (taxable / exempt) the order is entered by its net_amount_cents and amount_cents is calculated as the gross total (net + 19 % IVA when taxable), which is what the order is matched against on the invoice
  • Full audit trail is maintained for all changes
post/v1/erp/payouts/purchase_orders

Request

  • Base URL
    https://api.cardda.com
  • URL
    https://api.cardda.com/v1/erp/payouts/purchase_orders
  • Auth
    HTTP bearer

Parameters

#/paths/~1v1~1erp~1payouts~1rules/get/parameters/0 (unresolved $ref)

Request body

Example request

{
  "purchase_order": {
    "type": "Erp::Payouts::PurchaseOrders::AgainstInvoice",
    "business_partner_id": "8e668a4e-8485-4248-86cc-a7a2201cf8c3",
    "description": "Office equipment - 5 laptops",
    "amount_cents": 10000000,
    "tax_treatment": "taxable",
    "net_amount_cents": 8403361,
    "currency": "CLP",
    "items_attributes": [
      {
        "number": 1,
        "name": "Design and Requirements Analysis",
        "percentage": 100
      }
    ],
    "custom_column_values": [
      {
        "custom_column_id": "c0ffee00-1111-2222-3333-444455556666",
        "value": "ti"
      }
    ]
  }
}

Response

Purchase order created successfully

idstring uuid required

Unique identifier for the purchase order

company_idstring uuid required

ID of the company that owns this purchase order

business_partner_idstring uuid required

ID of the vendor/supplier for this purchase order

user_idstring required

ID of the user who created this purchase order

foliointeger required

Unique sequential folio number (auto-incremented per company)

descriptionstring required

Description of the purchase

amount_centsinteger required

Total amount as an integer in the minor unit of currency: whole pesos for CLP, cents for USD, ten-thousandths for UF/CLF. See Amounts and currency.

tax_treatment'taxable' | 'exempt' | 'null' nullable

Whether the order is subject to IVA (taxable) or exempt (exempt). null for orders created without it ("IVA not declared"), whose amount_cents is the amount that was sent. When present, amount_cents is derived from net_amount_cents.

net_amount_centsinteger nullable

Net amount (before IVA). null when tax_treatment is null.

tax_amount_centsinteger nullable

IVA of the order (amount_cents - net_amount_cents): 0 for an exempt order, null when tax_treatment is null.

currency'CLP' | 'CLF' | 'USD' required

Currency of the purchase order as stored. UF submitted on write reads back as its ISO 4217 code CLF, so responses and filters use CLF.

type'Erp::Payouts::PurchaseOrders::AgainstInvoice' | 'Erp::Payouts::PurchaseOrders::ByMilestone' | 'Erp::Payouts::PurchaseOrders::ByPercentage' required

Purchase order type (STI discriminator)

review_status'draft' | 'pending' | 'approved' | 'declined' required

Lifecycle/approval state of the purchase order:

  • draft: initial draft, not yet submitted for review
  • pending: submitted, awaiting reviewer decisions
  • approved: all assigned reviewers approved
  • declined: at least one reviewer rejected
created_atstring date-time required

Timestamp when the purchase order was created

updated_atstring date-time required

Timestamp when the purchase order was last updated

available_balance_centsinteger

Amount still available for linking to invoices (amount_cents - linked_amount_cents), in the same minor unit as amount_cents.

linked_amount_centsinteger

Total amount already linked to invoices

itemsSchema[] (unresolved $ref)

List of purchase order items

Changes

No recorded changes to this operation across all 1 revision of this API.