Skip to content

Saldo Inicial

Saldo Inicial

Prefijo: /api/saldo-inicial
Requiere Auth:
Permiso requerido: saldo_inicial, *

Módulo para registrar el saldo inicial de efectivo por terminal al iniciar la jornada.

GET /api/saldo-inicial/

Descripción: Lista los saldos iniciales registrados
Requiere Auth:
Permiso requerido: saldo_inicial, leer

Respuesta exitosa: 200 OK

Response:

[
{
"id": 1,
"terminal_id": "TERM-001",
"fecha": "2025-01-15",
"usuario": "Juan Pérez",
"monto": 500000,
"jornada_id": 19,
"tenant_id": "uuid-tenant",
"created_at": "2025-01-15T06:00:00"
}
]

cURL:

Terminal window
curl http://localhost/api/saldo-inicial/ -H "Authorization: Bearer <token>"

Python:

import httpx
resp = httpx.get("http://localhost/api/saldo-inicial/", headers={"Authorization": f"Bearer :token"})
saldos = resp.json()

JavaScript:

const resp = await fetch('http://localhost/api/saldo-inicial/', {
headers: {'Authorization': `Bearer $:token`}
});
const saldos = await resp.json();

GET /api/saldo-inicial/existe

Descripción: Verifica si ya existe un saldo inicial para una terminal/fecha. La consulta es global por terminal_id + fecha (no depende del tenant actual), alineada con el UniqueConstraint(terminal_id, fecha) global: devuelve true aunque el registro haya sido creado bajo otro tenant.
Requiere Auth:
Permiso requerido: saldo_inicial, leer

Parámetros query:

ParámetroTipoObligatorioDescripción
terminal_idstringIdentificador de terminal
fechadateFecha a verificar

Respuesta exitosa: 200 OK

Response:

{
"existe": true
}

cURL:

Terminal window
curl "http://localhost/api/saldo-inicial/existe?terminal_id=TERM-001&fecha=2025-01-15" -H "Authorization: Bearer <token>"

POST /api/saldo-inicial/

Descripción: Crea un nuevo saldo inicial. Idempotente: si ya existe un saldo con la misma terminal_id + fecha, retorna el registro existente re-amarrado a la jornada (en vez de violar el UniqueConstraint(terminal_id, fecha) y devolver 500). Al crear o re-amarrar, sincroniza la base de la jornada: actualiza jornada_caja.base_inicial de la jornada activa del usuario (o la indicada en jornada_id) y caja.base de la última caja del tenant, de modo que el cierre cuadre contra la base correcta.
Requiere Auth:
Permiso requerido: saldo_inicial, crear

Request:

{
"terminal_id": "TERM-001",
"fecha": "2025-01-15",
"usuario": "Juan Pérez",
"monto": 500000,
"jornada_id": 19
}
  • jornada_id (opcional): ID de la jornada a la que se amarra el saldo. Si no se envía, se resuelve automáticamente la jornada ABIERTA más reciente del usuario.

Respuesta exitosa: 201 Created (creado) / 200 OK (ya existía, retorna el registro actualizado con su id, monto y jornada_id)

cURL:

Terminal window
curl -X POST http://localhost/api/saldo-inicial/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{"terminal_id":"TERM-001","fecha":"2025-01-15","usuario":"Juan Pérez","monto":500000,"jornada_id":19}'

Python:

import httpx
resp = httpx.post("http://localhost/api/saldo-inicial/",
json={"terminal_id": "TERM-001", "fecha": "2025-01-15", "usuario": "Juan Pérez", "monto": 500000, "jornada_id": 19},
headers={"Authorization": f"Bearer :token"})
saldo = resp.json()

JavaScript:

const resp = await fetch('http://localhost/api/saldo-inicial/', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'Authorization': `Bearer $:token`},
body: JSON.stringify({terminal_id: 'TERM-001', fecha: '2025-01-15', usuario: 'Juan Pérez', monto: 500000, jornada_id: 19})
});

GET /api/saldo-inicial/:saldo_id

Descripción: Obtiene el detalle de un saldo inicial por ID. Incluye terminal, fecha, usuario, monto, jornada asociada y timestamp de creación. Para verificar registro, auditoría o pre-cargar edición.
Requiere Auth:
Permiso requerido: saldo_inicial, leer

Parámetros path:

ParámetroTipoObligatorioDescripción
saldo_idintID del saldo inicial

Comportamiento / Casos de uso:

  • Verificar monto registrado vs arqueo físico
  • Confirmar a qué jornada está amarrado el saldo
  • Auditoría: quién y cuándo registró la base

Respuesta exitosa: 200 OK

Response:

{
"id": 1,
"terminal_id": "TERM-001",
"fecha": "2025-01-15",
"usuario": "Juan Pérez",
"monto": 500000,
"jornada_id": 19,
"tenant_id": "uuid-tenant",
"created_at": "2025-01-15T06:00:00"
}

Errores:

CódigoCausaSolución
404No encontradoVerificar saldo_id
403Sin permiso saldo_inicial, leerSolicitar a admin

cURL:

Terminal window
curl http://localhost/api/saldo-inicial/1 -H "Authorization: Bearer <token>"

Python:

import httpx
resp = httpx.get("http://localhost/api/saldo-inicial/1", headers={"Authorization": f"Bearer :token"})
saldo = resp.json()

JavaScript:

const resp = await fetch('http://localhost/api/saldo-inicial/1', {
headers: {'Authorization': `Bearer $:token`}
});
const saldo = await resp.json();

PUT /api/saldo-inicial/:saldo_id

Descripción: Actualiza campos de un saldo inicial (partial update). Importante: al cambiar monto o jornada_id, sincroniza automáticamente jornada_caja.base_inicial de la jornada vinculada y caja.base del último cierre del tenant, para que el cuadre de cierre sea correcto.
Requiere Auth:
Permiso requerido: saldo_inicial, actualizar

Parámetros path:

ParámetroTipoObligatorioDescripción
saldo_idintID del saldo inicial

Request (campos opcionales, solo los enviados):

{
"usuario": "Juan Pérez",
"monto": 550000,
"jornada_id": 20
}

Campos actualizables:

CampoTipoDescripción
usuariostringCajero responsable
montointNuevo monto base (sincroniza jornada.caja.base_inicial y caja.base)
jornada_idintRe-asignar a otra jornada (debe ser del mismo usuario y fecha)

Comportamiento / Casos de uso:

  • Corrección de monto: cajero digitó mal la base inicial
  • Re-asignación: saldo se creó en jornada equivocada
  • Sincronización automática: al cambiar monto → actualiza jornada.base_inicial y caja.base del tenant

Respuesta exitosa: 200 OK — retorna SaldoInicialResponse actualizado

Response:

{
"id": 1,
"terminal_id": "TERM-001",
"fecha": "2025-01-15",
"usuario": "Juan Pérez",
"monto": 550000,
"jornada_id": 20,
"tenant_id": "uuid-tenant",
"created_at": "2025-01-15T06:00:00"
}

Errores:

CódigoCausaSolución
404No encontradoVerificar saldo_id
400Jornada_id no pertenece al usuario/fechaValidar jornada
403Sin permiso saldo_inicial, actualizarSolo admin
409Conflicto unique (terminal_id + fecha)No se puede duplicar

cURL:

Terminal window
curl -X PUT http://localhost/api/saldo-inicial/1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{"monto":550000}'

Python:

import httpx
resp = httpx.put("http://localhost/api/saldo-inicial/1",
json={"monto": 550000},
headers={"Authorization": f"Bearer :token"})
saldo = resp.json()

JavaScript:

const resp = await fetch('http://localhost/api/saldo-inicial/1', {
method: 'PUT',
headers: {'Content-Type': 'application/json', 'Authorization': `Bearer $:token`},
body: JSON.stringify({monto: 550000})
});
const saldo = await resp.json();

DELETE /api/saldo-inicial/:saldo_id

Descripción: Elimina (hard delete) un saldo inicial. Solo para errores de registro (duplicado por bug, monto cero, prueba). NO usar para anular saldo real — eso des-sincroniza jornada.base_inicial y caja.base, rompiendo el cuadre de cierre. Para corregir: editar monto (PUT) o crear nuevo saldo en jornada correcta.
Requiere Auth:
Permiso requerido: saldo_inicial, eliminar

Parámetros path:

ParámetroTipoObligatorioDescripción
saldo_idintID del saldo inicial

Comportamiento / Casos de uso:

  • Saldo duplicado por doble envío (idempotencia falló)
  • Registro de prueba en desarrollo
  • Error de sistema (monto = 0)
  • ADVERTENCIA: No hace rollback de sincronización — jornada.base_inicial y caja.base quedan con valor viejo.

Respuesta exitosa: 204 No Content

Errores:

CódigoCausaSolución
404No encontradoVerificar saldo_id
403Sin permiso saldo_inicial, eliminarSolo superadmin
409Tiene dependencias (jornada/caja sincronizadas)No eliminar, usar PUT para corregir

cURL:

Terminal window
curl -X DELETE http://localhost/api/saldo-inicial/1 -H "Authorization: Bearer <token>"

Python:

import httpx
resp = httpx.delete("http://localhost/api/saldo-inicial/1", headers={"Authorization": f"Bearer :token"})
assert resp.status_code == 204

JavaScript:

const resp = await fetch('http://localhost/api/saldo-inicial/1', {
method: 'DELETE',
headers: {'Authorization': `Bearer $:token`}
});
// 204 = éxito