Business Actions
No todo lo que el ERP hace es CRUD. Hay operaciones que cambian el estado de una entidad de manera no-trivial: autorizar una compra, cancelar una venta, timbrar un CFDI, recalcular saldos. Para eso existe el mecanismo de Business Actions.
Forma del endpoint
POST /api/v1/{modelo}/actions/{accion} # batch (n registros)
POST /api/v1/{modelo}/{id}/actions/{accion} # single (1 registro)Ambos retornan el envelope estándar { data, meta, errors }.
Modos de ejecución
Cada acción declara cómo se ejecuta. Hay tres modos:
grid_action
La acción opera sobre una lista de IDs (típico de la grid del ERP: seleccionas varias filas y aplicas la acción). El body lleva un array.
curl -X POST http://localhost/api/v1/Compra/actions/autorizar_compra \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ids": [12345, 12346, 12347]}'La respuesta es por registro:
{
"data": {
"results": [
{ "id": 12345, "ok": true },
{ "id": 12346, "ok": true },
{ "id": 12347, "ok": false, "errors": [{ "code": "INVALID_STATE", "message": "Compra ya autorizada" }] }
]
},
"meta": { "model": "Compra", "action": "autorizar_compra", "total": 3, "succeeded": 2, "failed": 1 },
"errors": null
}url_action
La acción opera sobre un registro identificado por path param. Útil cuando el flujo de la UI es "estoy en el detalle de X y oprimo el botón".
curl -X POST http://localhost/api/v1/Compra/12345/actions/cancelar_compra \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"motivo": "Duplicado"}'native
La acción es autocontenida: no opera sobre un registro existente sino que el body define todos sus inputs (ej. un wizard de generación de un asiento contable). Más raro pero existe.
Acciones habilitadas hoy
| Modelo | Acción | Modo |
|---|---|---|
| Compra | autorizar_compra | grid_action |
| Compra | cancelar_compra | grid_action |
| Compra | cambiar_iniciada | grid_action |
La hoja de ruta incluye acciones para Venta (timbrar_venta,
cancelar_venta), Asociado (alta_de_empleado) y muchas más.
Manejo de errores en batch
En grid_action, una acción puede tener éxitos parciales: parte de
los IDs procesados ok y parte con error. El status HTTP siempre es
200 si al menos uno se procesó. Esto facilita el flujo de la UI:
mostrar la grid con un check verde por fila exitosa y una x roja por
fila fallida.
Para detectar fallos totales, revisa meta.succeeded === 0.
const r = await fetch(`/api/v1/Compra/actions/autorizar_compra`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
body: JSON.stringify({ ids: selectedIds }),
});
const json = await r.json();
const failures = json.data.results.filter((x) => !x.ok);
if (failures.length) {
console.warn('Fallaron:', failures);
}¿Cuándo es Business Action y cuándo CRUD?
| Operación | Mecanismo |
|---|---|
Cambiar el nombre de una Moneda | PUT /Moneda/{id} |
Cambiar el estado de una Compra a "autorizada" | POST /Compra/{id}/actions/autorizar_compra |
Como regla general: si solo cambia un campo plano, es CRUD. Si dispara efectos secundarios (genera pólizas, manda email, registra auditoría, valida flujo de aprobación), es una Business Action.