Skip to main content

Orden de Compra API

The Orden de Compra (Purchase Order) API manages the complete lifecycle of purchase orders in the POS system, including creation, detail management, approval, and cancellation workflows. Purchase orders track materials ordered from suppliers and integrate with inventory management upon approval.

Endpoints Overview

MethodEndpointAuthenticationDescription
POST/api/pos/ordencompraRequiredCreate new purchase order
GET/api/pos/ordencompraRequiredGet all purchase orders with pagination
GET/api/pos/ordencompra/searchRequiredSearch orders by supplier
GET/api/pos/ordencompra/:idRequiredGet purchase order with details
POST/api/pos/ordencompra/:id/detalleRequiredAdd/update order line item
DELETE/api/pos/ordencompra/:id/detalle/:mpRequiredRemove order line item
POST/api/pos/ordencompra/:id/aprobarRequiredApprove purchase order
POST/api/pos/ordencompra/:id/anularRequiredCancel purchase order

Purchase Order States

Purchase orders can be in one of three states:
StateCodeDescription
PendingPENOrder is being prepared, details can be modified
ApprovedAPROrder is approved and stock has been updated
CancelledANUOrder has been cancelled
Once a purchase order is approved (APR), its details cannot be modified. The approval process triggers inventory updates and kardex entries.

POST /api/pos/ordencompra

Create a new purchase order. This endpoint calls the stored procedure sp_crear_orden_compra which initializes the order in pending state.

Request

prv_codigo
string
required
Supplier code. Must reference a valid and active supplier (e.g., PRV000123).

Response

oc_codigo
string
Auto-generated purchase order code
cabecera
object
Complete purchase order header information

Example Request

curl -X POST http://localhost:3000/api/pos/ordencompra \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "prv_codigo": "PRV000123"
  }'

Response Examples

{
  "oc_codigo": "OC00000123",
  "cabecera": {
    "oc_codigo": "OC00000123",
    "prv_codigo": "PRV000123",
    "oc_fecha": "2024-03-04T00:00:00.000Z",
    "oc_subtotal": 0.00,
    "oc_iva": 0.00,
    "oc_total": 0.00,
    "oc_fecha_aprobacion": null,
    "oc_fecha_eliminacion": null,
    "oc_estado": "PEN"
  }
}
New purchase orders are created with zero totals. Add line items using the detalle endpoints to populate the order.
{
  "message": "prv_codigo es requerido"
}
{
  "message": "insert or update on table \"ordencompra\" violates foreign key constraint"
}
This error occurs when the provided supplier code doesn’t exist or the supplier is inactive.

GET /api/pos/ordencompra

Retrieve a paginated list of purchase orders. Supports filtering by state and searching by supplier name or RUC.

Query Parameters

page
integer
default:"1"
Page number for pagination
estado
string
Filter by order state: PEN (Pending), APR (Approved), or ANU (Cancelled)
q
string
Search term to filter by supplier name or RUC (case-insensitive)

Response

page
integer
Current page number
limit
integer
Records per page (from PAGINATION_LIMIT env variable, default 20)
count
integer
Total count of orders matching the filters
data
array
Array of purchase order objects

Example Request

# Get pending orders, page 1
curl -X GET "http://localhost:3000/api/pos/ordencompra?page=1&estado=PEN" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Search by supplier
curl -X GET "http://localhost:3000/api/pos/ordencompra?q=garcia&page=1" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

{
  "page": 1,
  "limit": 20,
  "count": 15,
  "data": [
    {
      "oc_codigo": "OC00000123",
      "prv_codigo": "PRV000123",
      "oc_fecha": "2024-03-04T00:00:00.000Z",
      "oc_subtotal": 1500.00,
      "oc_iva": 180.00,
      "oc_total": 1680.00,
      "oc_estado": "PEN"
    },
    {
      "oc_codigo": "OC00000122",
      "prv_codigo": "PRV000456",
      "oc_fecha": "2024-03-03T00:00:00.000Z",
      "oc_subtotal": 2300.00,
      "oc_iva": 276.00,
      "oc_total": 2576.00,
      "oc_estado": "PEN"
    }
  ]
}
{
  "message": "No se encontraron órdenes de compra"
}

GET /api/pos/ordencompra/search

Search purchase orders by supplier code with pagination. Alternative to the main GET endpoint when you know the exact supplier code.

Query Parameters

prv
string
required
Supplier code to filter by (e.g., PRV000123)
page
integer
default:"1"
Page number for pagination

Example Request

curl -X GET "http://localhost:3000/api/pos/ordencompra/search?prv=PRV000123&page=1" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

{
  "page": 1,
  "limit": 20,
  "count": 45,
  "data": [
    {
      "oc_codigo": "OC00000123",
      "prv_codigo": "PRV000123",
      "oc_fecha": "2024-03-04T00:00:00.000Z",
      "oc_subtotal": 1500.00,
      "oc_iva": 180.00,
      "oc_total": 1680.00,
      "oc_estado": "PEN"
    }
  ]
}
{
  "message": "El parámetro prv es requerido"
}

GET /api/pos/ordencompra/:id

Retrieve a complete purchase order including header information and all line item details.

Path Parameters

id
string
required
Purchase order code (e.g., OC00000123)

Response

cabecera
object
Purchase order header information (see POST response for structure)
detalles
array
Array of order line items

Example Request

curl -X GET http://localhost:3000/api/pos/ordencompra/OC00000123 \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

{
  "cabecera": {
    "oc_codigo": "OC00000123",
    "prv_codigo": "PRV000123",
    "oc_fecha": "2024-03-04T00:00:00.000Z",
    "oc_subtotal": 1500.00,
    "oc_iva": 180.00,
    "oc_total": 1680.00,
    "oc_fecha_aprobacion": null,
    "oc_fecha_eliminacion": null,
    "oc_estado": "PEN"
  },
  "detalles": [
    {
      "oc_codigo": "OC00000123",
      "mp_codigo": "MP00001",
      "mp_descripcion": "Harina de Trigo Premium 50kg",
      "pxoc_cantidad": 10.00,
      "pxoc_subtotal": 750.00,
      "pxoc_estado": "PEN"
    },
    {
      "oc_codigo": "OC00000123",
      "mp_codigo": "MP00002",
      "mp_descripcion": "Azúcar Blanca 50kg",
      "pxoc_cantidad": 15.00,
      "pxoc_subtotal": 750.00,
      "pxoc_estado": "PEN"
    }
  ]
}
{
  "message": "No se encontró la orden de compra"
}

POST /api/pos/ordencompra/:id/detalle

Add or update a line item in a purchase order. Uses UPSERT logic: if the material already exists in the order, the quantity is updated; otherwise, a new line is added.
This operation can only be performed on orders in PEN (pending) state. Database triggers will prevent modifications to approved or cancelled orders.

Path Parameters

id
string
required
Purchase order code (e.g., OC00000123)

Request

mp_codigo
string
required
Raw material code. Must reference a valid material in the materia_prima table.
pxoc_cantidad
number
required
Quantity to order. Must be a positive number.

Response

cabecera
object
Updated purchase order header (totals recalculated)
detalle_actualizado
object
The added/updated line item
detalles
array
Complete list of all order line items

Example Request

curl -X POST http://localhost:3000/api/pos/ordencompra/OC00000123/detalle \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "mp_codigo": "MP00001",
    "pxoc_cantidad": 10
  }'

Response Examples

{
  "cabecera": {
    "oc_codigo": "OC00000123",
    "prv_codigo": "PRV000123",
    "oc_fecha": "2024-03-04T00:00:00.000Z",
    "oc_subtotal": 750.00,
    "oc_iva": 90.00,
    "oc_total": 840.00,
    "oc_fecha_aprobacion": null,
    "oc_fecha_eliminacion": null,
    "oc_estado": "PEN"
  },
  "detalle_actualizado": {
    "oc_codigo": "OC00000123",
    "mp_codigo": "MP00001",
    "pxoc_cantidad": 10.00,
    "pxoc_subtotal": 750.00,
    "pxoc_estado": "PEN"
  },
  "detalles": [
    {
      "oc_codigo": "OC00000123",
      "mp_codigo": "MP00001",
      "mp_descripcion": "Harina de Trigo Premium 50kg",
      "pxoc_cantidad": 10.00,
      "pxoc_subtotal": 750.00,
      "pxoc_estado": "PEN"
    }
  ]
}
Totals are automatically recalculated by database triggers when line items are added or updated.
{
  "message": "mp_codigo y pxoc_cantidad son requeridos"
}
{
  "message": "No se puede modificar el detalle de una orden que no está en estado PENDIENTE"
}
This error is raised by database triggers when attempting to modify an order that is not in pending state.

DELETE /api/pos/ordencompra/:id/detalle/:mp

Remove a line item from a purchase order. Can only be performed on pending orders.

Path Parameters

id
string
required
Purchase order code (e.g., OC00000123)
mp
string
required
Raw material code to remove (e.g., MP00001)

Response

message
string
Success message
cabecera
object
Updated purchase order header
detalles
array
Remaining line items after deletion

Example Request

curl -X DELETE http://localhost:3000/api/pos/ordencompra/OC00000123/detalle/MP00001 \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

{
  "message": "Detalle eliminado",
  "cabecera": {
    "oc_codigo": "OC00000123",
    "prv_codigo": "PRV000123",
    "oc_fecha": "2024-03-04T00:00:00.000Z",
    "oc_subtotal": 750.00,
    "oc_iva": 90.00,
    "oc_total": 840.00,
    "oc_fecha_aprobacion": null,
    "oc_fecha_eliminacion": null,
    "oc_estado": "PEN"
  },
  "detalles": [
    {
      "oc_codigo": "OC00000123",
      "mp_codigo": "MP00002",
      "mp_descripcion": "Azúcar Blanca 50kg",
      "pxoc_cantidad": 15.00,
      "pxoc_subtotal": 750.00,
      "pxoc_estado": "PEN"
    }
  ]
}
{
  "message": "Detalle no encontrado"
}

POST /api/pos/ordencompra/:id/aprobar

Approve a purchase order, changing its state from PEN to APR. This action:
  1. Updates the order state to APR
  2. Sets the approval date (oc_fecha_aprobacion)
  3. Triggers inventory synchronization
  4. Creates kardex entries for materials
  5. Updates stock levels
This action is irreversible. Once approved, the order cannot be modified or deleted. Only cancellation is possible.

Path Parameters

id
string
required
Purchase order code to approve

Response

message
string
Success message: “Orden aprobada”
cabecera
object
Updated purchase order header with approval date
detalles
array
Order line items with updated state

Example Request

curl -X POST http://localhost:3000/api/pos/ordencompra/OC00000123/aprobar \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

{
  "message": "Orden aprobada",
  "cabecera": {
    "oc_codigo": "OC00000123",
    "prv_codigo": "PRV000123",
    "oc_fecha": "2024-03-04T00:00:00.000Z",
    "oc_subtotal": 1500.00,
    "oc_iva": 180.00,
    "oc_total": 1680.00,
    "oc_fecha_aprobacion": "2024-03-04T15:30:00.000Z",
    "oc_fecha_eliminacion": null,
    "oc_estado": "APR"
  },
  "detalles": [
    {
      "oc_codigo": "OC00000123",
      "mp_codigo": "MP00001",
      "mp_descripcion": "Harina de Trigo Premium 50kg",
      "pxoc_cantidad": 10.00,
      "pxoc_subtotal": 750.00,
      "pxoc_estado": "APR"
    },
    {
      "oc_codigo": "OC00000123",
      "mp_codigo": "MP00002",
      "mp_descripcion": "Azúcar Blanca 50kg",
      "pxoc_cantidad": 15.00,
      "pxoc_subtotal": 750.00,
      "pxoc_estado": "APR"
    }
  ]
}
The approval timestamp is automatically set by the database when the order is approved.
{
  "message": "Orden de compra no encontrada"
}

POST /api/pos/ordencompra/:id/anular

Cancel a purchase order, changing its state to ANU. Sets the cancellation date (oc_fecha_eliminacion).
Cancelled orders remain in the database for audit purposes but cannot be reactivated or modified.

Path Parameters

id
string
required
Purchase order code to cancel

Response

message
string
Success message: “Orden anulada”
cabecera
object
Updated purchase order header with cancellation date
detalles
array
Order line items with updated state

Example Request

curl -X POST http://localhost:3000/api/pos/ordencompra/OC00000123/anular \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response Examples

{
  "message": "Orden anulada",
  "cabecera": {
    "oc_codigo": "OC00000123",
    "prv_codigo": "PRV000123",
    "oc_fecha": "2024-03-04T00:00:00.000Z",
    "oc_subtotal": 1500.00,
    "oc_iva": 180.00,
    "oc_total": 1680.00,
    "oc_fecha_aprobacion": null,
    "oc_fecha_eliminacion": "2024-03-04T16:45:00.000Z",
    "oc_estado": "ANU"
  },
  "detalles": [
    {
      "oc_codigo": "OC00000123",
      "mp_codigo": "MP00001",
      "mp_descripcion": "Harina de Trigo Premium 50kg",
      "pxoc_cantidad": 10.00,
      "pxoc_subtotal": 750.00,
      "pxoc_estado": "ANU"
    }
  ]
}
{
  "message": "Orden de compra no encontrada"
}

Error Codes

Status CodeDescription
200Request successful
201Purchase order created successfully
400Bad request - missing required parameters
404Purchase order not found
500Internal server error or database constraint violation

Purchase Order Workflow

The typical workflow for a purchase order is:
1

Create Order

Create a new purchase order with a supplier code. Order is created in PEN state with zero totals.
2

Add Line Items

Add materials and quantities using the detalle endpoint. Totals are automatically calculated.
3

Review Totals

Fetch the complete order to review the calculated subtotals, taxes, and total amount.
4

Approve Order

Approve the order to trigger inventory updates. This changes state to APR and is irreversible.
5

Cancel (if needed)

Cancel orders that are no longer needed. Can only cancel pending orders before approval.

Database Triggers and Business Logic

Automatic Calculations:
  • Line item subtotals are calculated automatically based on material price × quantity
  • Order subtotal is the sum of all line item subtotals
  • IVA (tax) is calculated as 12% of the subtotal
  • Order total = subtotal + IVA
All calculations are performed by database triggers when line items are added, updated, or removed.
State Constraints:
  • Details can only be modified when order is in PEN state
  • Approved orders (APR) cannot be modified or deleted
  • Cancelled orders (ANU) cannot be reactivated
  • Database triggers enforce these constraints and will raise exceptions if violated

Implementation Notes

The Orden de Compra API uses the stored procedure sp_crear_orden_compra for order creation, which ensures proper initialization and sequencing. The approval process integrates with the inventory management system through database triggers that:
  1. Synchronize the order state across header and detail records
  2. Create kardex entries for inventory tracking
  3. Update stock levels for each material
  4. Set timestamps for audit trailing

Build docs developers (and LLMs) love