Contents
On this page
Finalize Stock Movement - Plugixa Inventory
POST /plugixa-inventory/v1/stock-movements/{id}/finalize
Finalize a draft stock movement: its lines are written to the stock ledger and on hand changes.
The user needs the plugixa_inventory_edit capability (administrators have every inventory capability). With Pro Roles and permissions enforcing, their role must also allow editing this stock movement. Finalizing also needs the plugixa_inventory_manage capability, which any user holding an inventory capability has.
This writes the ledger. Finalizing is the only way stock changes. It is all or nothing, and it cannot be undone: to correct a finalized document, finalize an opposite one.
Each line becomes one ledger row in the document’s warehouse: check_in and add_stock add, check_out and remove_stock take away. The document becomes finalized, gets its reference if it had none, and records line_count, total_quantity and total_cost. Each line gets the id of its ledger row and its final cost.
Request
POST https://your-site.example/wp-json/plugixa-inventory/v1/stock-movements/57/finalize
Path parameters
| Name | Type | Description |
|---|---|---|
id |
integer |
The stock movement’s id |
Responses
200 OK. data is the finalized stock movement with its lines.
{
"success": true,
"data": {
"id": 57,
"reference": "SM-2026-0057",
"movement_type": "add_stock",
"warehouse_id": 1,
"recipient_id": null,
"recipient": "",
"movement_date": "2026-11-12 10:30:00",
"status": "finalized",
"finalized_at": "2026-11-12 10:15:00",
"finalized_by": 1,
"batch_id": "3f6c1a52-8d0e-4b7a-9c61-2f4e8a9b7d10",
"line_count": 1,
"total_quantity": 120.0,
"total_cost": 504.0,
"details": "",
"attachments": null,
"assigned_user_id": null,
"created_by": 1,
"modified_by": 1,
"created_at": "2026-11-12 09:30:00",
"modified_at": "2026-11-12 10:15:00",
"deleted_at": null,
"lines": [
{
"id": 210,
"movement_id": 57,
"item_id": 42,
"unit_id": null,
"quantity": 120.0,
"weight": 0.0,
"weight_unit": "",
"weight_base": 0.0,
"cost_per_unit": 4.2,
"total_cost": 504.0,
"transaction_id": 981,
"notes": "Delivery note 4471",
"position": 1,
"created_by": "1",
"modified_by": "1",
"created_at": "2026-11-12 09:30:00",
"modified_at": "2026-11-12 09:30:00",
"deleted_at": null,
"item_name": "Printer paper A4",
"item_sku": "PAP-A4",
"item_type": "consumable",
"unit_code": null
}
]
}
}
| Field | Type | Meaning |
|---|---|---|
data.status |
string |
finalized |
data.reference |
string |
Your reference, or SM-YYYY-NNNN |
data.batch_id |
string |
The id shared by every ledger row this wrote. Filter List Transactions with batch |
data.total_quantity |
number |
Sum of the quantities moved |
data.total_cost |
number |
Sum of the line costs |
data.finalized_at |
string |
UTC datetime |
data.lines[].transaction_id |
integer |
The ledger row this line wrote |
This answer does not carry the warehouse names. Read the document again with Get Stock Movement for those.
Errors
| Status | Code | When |
|---|---|---|
404 |
plugixa_inventory_not_found |
No document with that id, or it is in the trash. |
409 |
plugixa_inventory_invalid_transition |
The document is already finalized. data.status_now is its status. |
422 |
plugixa_inventory_document_empty |
The document has no lines. |
422 |
plugixa_inventory_unknown_warehouse |
The warehouse no longer exists. |
422 |
plugixa_inventory_recipient_required |
A check_out has no live recipient. |
422 |
plugixa_inventory_invalid_lines |
A line points at an item that no longer exists. data.lines lists them. |
422 |
plugixa_inventory_item_type_mismatch |
A line’s item type is not allowed for this movement type. data.lines lists them with the item name and type. |
409 |
plugixa_inventory_insufficient_stock |
A decrease needs more than the warehouse holds. data.lines lists every short item with item_id, warehouse_id, available and requested. |
409 |
plugixa_inventory_stock_changed |
There was enough stock when checked, and not any more when written. Nothing was applied: try again. |
409 |
plugixa_inventory_too_many_layers / plugixa_inventory_costing_unavailable |
The costing method cannot cost a removal. Nothing was applied. |
503 |
plugixa_inventory_stock_busy |
Another stock operation is running. Try again in a moment. |
500 |
plugixa_inventory_stock_write_failed |
The stock change could not be written. Nothing was applied. |
409 |
plugixa_inventory_conflict |
You sent modified_at and the record has changed since. data.expected and data.current carry both values. |
Plus the errors every endpoint can return.
Examples
curl -s -X POST "https://your-site.example/wp-json/plugixa-inventory/v1/stock-movements/57/finalize" \
-u "admin:$WP_APP_PASSWORD"
<?php
$ch = curl_init('https://your-site.example/wp-json/plugixa-inventory/v1/stock-movements/57/finalize');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => 'admin:' . getenv('WP_APP_PASSWORD'),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const auth = 'Basic ' + btoa(`admin:${process.env.WP_APP_PASSWORD}`);
const response = await fetch('https://your-site.example/wp-json/plugixa-inventory/v1/stock-movements/57/finalize', {
method: 'POST',
headers: { 'Authorization': auth },
});
const { data } = await response.json();
Quick Links
Share