Ventas
Ventas
Prefijo: /api/ventas
Requiere Auth: Sí
Módulo principal de ventas del POS. Incluye CRUD completo, agregaciones por fecha/medio de pago, gestión de detalles DIAN y pendientes de facturación electrónica.
Nota: Las ventas utilizan soft delete — al eliminar una venta se marca como eliminada sin borrarse físicamente.
CRUD Ventas
GET /api/ventas
Descripción: Lista todas las ventas con paginación y filtro por fechas
Requiere Auth: Sí
Permiso requerido: ventas, leer
Parámetros query:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
skip | int | ❌ | Número de registros a saltar (default 0) |
limit | int | ❌ | Máximo de registros a retornar (default 100) |
fecha_desde | date | ❌ | Filtro fecha inicial (YYYY-MM-DD) |
fecha_hasta | date | ❌ | Filtro fecha final (YYYY-MM-DD) |
Respuesta exitosa: 200 OK
Response:
[ { "id": 1, "tenant_id": "uuid-tenant", "id_cliente": 1, "vendedor": "Juan Pérez", "montoRecibido": 12000, "total": 10000, "descuento": 0, "vueltos": 2000, "totalf": "10000", "medioPago": "Efectivo", "tipoPago": "CONTADO", "fecha": "2025-01-15", "hora": "14:30:00", "tipo_pago": "CONTADO", "iva_venta": 1900, "valor_iva": 1900, "precio_iva": 11900, "fecha_hora": "2025-01-15T14:30:00", "cliente_nombre": "Cliente Ejemplo", "detalles": [ { "id": 1, "cod_pro": "PROD001", "nombre": "Café Latte", "cantidad": 2, "precio": 3500, "id_venta": 1, "cufe": "", "NumeroFact": "", "tipo_impuesto": "IVA", "valor_base": 7000, "valor_impuesto": 1330, "codigo_impuesto": "01" } ], "pagos": [ { "id": 1, "id_venta": 1, "medio_pago": "Efectivo", "monto": 12000, "fecha": "2025-01-15" } ] }]cURL:
curl "http://localhost/api/ventas?skip=0&limit=10&fecha_desde=2025-01-01" -H "Authorization: Bearer <token>"Python:
import httpxresp = httpx.get("http://localhost/api/ventas", params={"skip": 0, "limit": 10}, headers={"Authorization": f"Bearer {token}"})ventas = resp.json()JavaScript:
const resp = await fetch('http://localhost/api/ventas?skip=0&limit=10', { headers: {'Authorization': `Bearer ${token}`}});const ventas = await resp.json();GET /api/ventas/{venta_id}
Descripción: Obtiene una venta por ID
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
Errores: 404 (no encontrada)
cURL:
curl http://localhost/api/ventas/1 -H "Authorization: Bearer <token>"POST /api/ventas
Descripción: Crea una nueva venta con detalles y pagos
Requiere Auth: Sí
Permiso requerido: ventas, crear
Parámetros body:
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id_cliente | int | ✅ | ID del cliente |
vendedor | string | ✅ | Nombre del vendedor |
montoRecibido | float | ✅ | Monto recibido del cliente |
total | float | ✅ | Total de la venta |
descuento | float | ❌ | Descuento aplicado |
medioPago | string | ✅ | Efectivo, Transferencia, Credito |
tipoPago | string | ✅ | CONTADO o CREDITO |
detalles | array | ✅ | Líneas de la venta |
pagos | array | ✅ | Pagos asociados |
idempotency_key | string | ❌ | UUID para evitar duplicados |
Respuesta exitosa: 201 Created
Request:
{ "id_cliente": 1, "vendedor": "Juan Pérez", "montoRecibido": 12000, "total": 10000, "descuento": 0, "vueltos": 2000, "totalf": "10000", "medioPago": "Efectivo", "tipoPago": "CONTADO", "fecha": "2025-01-15", "hora": "14:30:00", "tipo_pago": "CONTADO", "detalles": [ { "cod_pro": "PROD001", "nombre": "Café Latte", "cantidad": 2, "cliente_id": "1", "precio": 3500, "medioPago": "Efectivo", "id_producto": 1, "tipo_impuesto": "IVA", "valor_base": 7000, "valor_impuesto": 1330, "codigo_impuesto": "01" } ], "pagos": [ { "id_venta": 0, "medio_pago": "Efectivo", "monto": 12000 } ], "idempotency_key": "uuid-unico-para-evitar-duplicados"}cURL:
curl -X POST http://localhost/api/ventas \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '{"id_cliente":1,"vendedor":"Juan Pérez","montoRecibido":12000,"total":10000,"medioPago":"Efectivo","tipoPago":"CONTADO","detalles":[{"cod_pro":"PROD001","nombre":"Café Latte","cantidad":2,"precio":3500,"id_producto":1,"tipo_impuesto":"IVA","valor_base":7000,"valor_impuesto":1330,"codigo_impuesto":"01"}],"pagos":[{"medio_pago":"Efectivo","monto":12000}]}'Python:
import httpxresp = httpx.post("http://localhost/api/ventas", json={"id_cliente": 1, "vendedor": "Juan Pérez", "montoRecibido": 12000, "total": 10000, "medioPago": "Efectivo", "tipoPago": "CONTADO", "detalles": [{"cod_pro": "PROD001", "nombre": "Café Latte", "cantidad": 2, "precio": 3500, "id_producto": 1, "tipo_impuesto": "IVA", "valor_base": 7000, "valor_impuesto": 1330, "codigo_impuesto": "01"}], "pagos": [{"medio_pago": "Efectivo", "monto": 12000}]}, headers={"Authorization": f"Bearer {token}"})venta = resp.json()JavaScript:
const resp = await fetch('http://localhost/api/ventas', { method: 'POST', headers: {'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`}, body: JSON.stringify({id_cliente: 1, vendedor: 'Juan Pérez', montoRecibido: 12000, total: 10000, medioPago: 'Efectivo', tipoPago: 'CONTADO', detalles: [{cod_pro: 'PROD001', nombre: 'Café Latte', cantidad: 2, precio: 3500, id_producto: 1, tipo_impuesto: 'IVA', valor_base: 7000, valor_impuesto: 1330, codigo_impuesto: '01'}], pagos: [{medio_pago: 'Efectivo', monto: 12000}]})});const venta = await resp.json();PUT /api/ventas/{venta_id}
Descripción: Actualiza una venta existente
Requiere Auth: Sí
Permiso requerido: ventas, actualizar
Respuesta exitosa: 200 OK
Errores: 404 (no encontrada)
cURL:
curl -X PUT http://localhost/api/ventas/1 \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '{"total":11000,"montoRecibido":15000}'DELETE /api/ventas/{venta_id}
Descripción: Elimina (soft delete) una venta
Requiere Auth: Sí
Permiso requerido: ventas, eliminar
Respuesta exitosa: 204 No Content
Errores: 404 (no encontrada)
cURL:
curl -X DELETE http://localhost/api/ventas/1 -H "Authorization: Bearer <token>"GET /api/ventas/cliente/{cliente_id}
Descripción: Obtiene todas las ventas de un cliente
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
cURL:
curl http://localhost/api/ventas/cliente/1 -H "Authorization: Bearer <token>"GET /api/ventas/tipo-pago/{tipo_pago}
Descripción: Obtiene ventas por tipo de pago (CONTADO, CREDITO)
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
cURL:
curl http://localhost/api/ventas/tipo-pago/CONTADO -H "Authorization: Bearer <token>"Agregaciones
GET /api/ventas/total-por-medio-pago
Descripción: Obtiene el total de ventas agrupado por medio de pago en una fecha
Requiere Auth: Sí
Permiso requerido: ventas, leer
Parámetros query:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
medio_pago | string | ✅ | Efectivo, Transferencia, Credito, VARIOS |
fecha | date | ❌ | Fecha (default: hoy) |
Respuesta exitosa: 200 OK
Response:
{ "total": 500000}cURL:
curl "http://localhost/api/ventas/total-por-medio-pago?medio_pago=Efectivo&fecha=2025-01-15" -H "Authorization: Bearer <token>"GET /api/ventas/total-vueltos-dia
Descripción: Obtiene el total de vueltos del día
Requiere Auth: Sí
Permiso requerido: ventas, leer
Parámetros query:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
fecha | date | ❌ | Fecha (default: hoy) |
Respuesta exitosa: 200 OK
Response:
{ "total": 15000}cURL:
curl "http://localhost/api/ventas/total-vueltos-dia?fecha=2025-01-15" -H "Authorization: Bearer <token>"GET /api/ventas/total-transacciones-dia
Descripción: Obtiene el número total de transacciones del día
Requiere Auth: Sí
Permiso requerido: ventas, leer
Parámetros query:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
fecha | date | ❌ | Fecha (default: hoy) |
Respuesta exitosa: 200 OK
Response:
{ "total": 45}cURL:
curl "http://localhost/api/ventas/total-transacciones-dia?fecha=2025-01-15" -H "Authorization: Bearer <token>"GET /api/ventas/total-rango
Descripción: Obtiene el total de ventas en un rango de fechas
Requiere Auth: Sí
Permiso requerido: ventas, leer
Parámetros query:
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
fecha_inicio | date | ✅ | Fecha inicial |
fecha_fin | date | ✅ | Fecha final |
Respuesta exitosa: 200 OK
Response:
{ "total": 2500000.0}cURL:
curl "http://localhost/api/ventas/total-rango?fecha_inicio=2025-01-01&fecha_fin=2025-01-31" -H "Authorization: Bearer <token>"Detalles y Pagos
GET /api/ventas/{venta_id}/detalles
Descripción: Obtiene los detalles (líneas) de una venta
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
cURL:
curl http://localhost/api/ventas/1/detalles -H "Authorization: Bearer <token>"PATCH /api/ventas/{venta_id}/detalles
Descripción: Actualiza campos DIAN de los detalles de una venta (CUFE, NumeroFact, etc.)
Requiere Auth: Sí
Permiso requerido: ventas, actualizar
Request:
[ { "id": 1, "cufe": "a1b2c3d4e5f6...", "NumeroFact": "FAC-001", "estadoFact": 1, "fechaCreacion": "2025-01-15T14:30:00", "fechaValidacion": "2025-01-15T14:35:00" }]Respuesta exitosa: 200 OK
{ "ok": true}cURL:
curl -X PATCH http://localhost/api/ventas/1/detalles \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '[{"id":1,"cufe":"a1b2c3d4e5f6...","NumeroFact":"FAC-001","estadoFact":1}]'GET /api/ventas/{venta_id}/pagos
Descripción: Obtiene los pagos asociados a una venta
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
cURL:
curl http://localhost/api/ventas/1/pagos -H "Authorization: Bearer <token>"GET /api/ventas/{venta_id}/pendiente
Descripción: Verifica si una venta tiene detalles pendientes DIAN
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
Response:
{ "pendiente": true}cURL:
curl http://localhost/api/ventas/1/pendiente -H "Authorization: Bearer <token>"PATCH /api/ventas/{venta_id}/abono
Descripción: Actualiza el monto recibido (abono) de una venta
Requiere Auth: Sí
Permiso requerido: ventas, actualizar
Request:
{ "montoRecibido": 5000}Respuesta exitosa: 200 OK
{ "ok": true}cURL:
curl -X PATCH http://localhost/api/ventas/1/abono \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '{"montoRecibido":5000}'Pendientes DIAN
GET /api/ventas/pendientes-dian/
Descripción: Lista ventas pendientes de facturación electrónica DIAN
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
cURL:
curl http://localhost/api/ventas/pendientes-dian/ -H "Authorization: Bearer <token>"GET /api/ventas/pendientes-dian/{pendiente_id}
Descripción: Obtiene un pendiente DIAN por ID
Requiere Auth: Sí
Permiso requerido: ventas, leer
Respuesta exitosa: 200 OK
Errores: 404 (no encontrado)
cURL:
curl http://localhost/api/ventas/pendientes-dian/1 -H "Authorization: Bearer <token>"POST /api/ventas/pendientes-dian/
Descripción: Crea un nuevo registro pendiente DIAN
Requiere Auth: Sí
Permiso requerido: ventas, crear
Respuesta exitosa: 201 Created
cURL:
curl -X POST http://localhost/api/ventas/pendientes-dian/ \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '{"id_venta":1,"cufe":"...","NumeroFact":"FAC-001"}'PUT /api/ventas/pendientes-dian/{pendiente_id}
Descripción: Actualiza un pendiente DIAN
Requiere Auth: Sí
Permiso requerido: ventas, actualizar
Respuesta exitosa: 200 OK
Errores: 404 (no encontrado)
cURL:
curl -X PUT http://localhost/api/ventas/pendientes-dian/1 \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token>" \ -d '{"cufe":"nuevo-cufe"}'DELETE /api/ventas/pendientes-dian/{pendiente_id}
Descripción: Elimina un pendiente DIAN
Requiere Auth: Sí
Permiso requerido: ventas, eliminar
Respuesta exitosa: 204 No Content
Errores: 404 (no encontrado)
cURL:
curl -X DELETE http://localhost/api/ventas/pendientes-dian/1 -H "Authorization: Bearer <token>"