Files
hotel-hacienda/docs/API.md
Consultoria AS 411d517ba4 docs: documentación extensiva del proyecto
- README.md con guía completa de instalación y arquitectura
- docs/BACKEND.md — guía detallada del API
- docs/FRONTEND.md — guía del SPA React
- docs/DATABASE.md — funciones SQL y patrones de datos
- docs/API.md — referencia completa de endpoints REST
- docs/DEPLOYMENT.md — guía de despliegue en producción
- docs/TROUBLESHOOTING.md — solución de problemas comunes
- CHANGELOG.md — historial de cambios
- CONTRIBUTING.md — guía de contribución
2026-06-09 16:26:09 -07:00

12 KiB

🔌 Referencia Completa de la API REST

Base URL: https://<dominio>/api


Índice

  1. Convenciones
  2. Autenticación
  3. Empleados
  4. Contratos
  5. Productos
  6. Gastos
  7. Aprobaciones y Pagos
  8. Pagos Mensuales
  9. Configuraciones
  10. Emails
  11. Ingresos (Little Hotelier)
  12. Compras
  13. Tipo de Cambio
  14. Hotel P&L
  15. Restaurant P&L
  16. Ingresos Horux

Convenciones

  • Formato: JSON en request body y response.
  • Paginación: ?page=N&limit=M (default limit: 500 para empleados, 10 para productos).
  • Errores: Status 500 con { message: "Error descripción" }.
  • CORS: Origen controlado por URL_CORS en el backend.

Autenticación

⚠️ Nota: No hay JWT. El login devuelve un rol numérico que el frontend guarda en localStorage.

POST /api/auth/login

// Request
{
  "name_mail_user": "usuario_o_email",
  "user_pass": "contraseña"
}

// Response 200
{
  "rol": 1,
  "user_id": 5,
  "user_name": "Admin",
  "message": "Usuario autenticado correctamente"
}

Status codes de la función SQL:

  • status: 1 = Autenticado
  • status: 2 = Credenciales incorrectas

POST /api/auth/createuser

// Request
{
  "name_user": "Nuevo Usuario",
  "id_rol": 2,
  "email": "user@email.com",
  "user_pass": "password123"
}

// Response
{
  "message": "Se agrego el usuario correctamente",
  "status": 1
}

POST /api/auth/recoverpass

Genera una contraseña aleatoria y la envía por correo.

// Request
{ "user_mail": "user@email.com" }

// Response
{
  "message": "Correo enviado con nueva contraseña.",
  "status": 1
}

Empleados

Base: /api/employees

GET /api/employees/

Lista paginada de empleados.

Query params: ?page=1&limit=500

// Response
{
  "page": 1,
  "limit": 500,
  "total": 45,
  "totalPages": 1,
  "data": [
    {
      "employee_rfc": "RFC123456",
      "name_employee": "Juan Pérez",
      "nss_employe": "12345678901",
      "position_employee": "Recepcionista",
      "area_employee": "Front Desk",
      "phone_employee": "5551234567",
      "end_contract": "2025-12-31",
      "daily_pay": 500.00,
      "uniforms": 2,
      "status": "Activo",
      "birthday": "1990-05-15",
      "curp": "CURP123456HDF"
    }
  ]
}

GET /api/employees/activeEmployees

{ "message": "Total de empleados activos", "data": 42 }

GET /api/employees/getattendance

{ "message": "attendance", "data": [...] }

GET /api/employees/gradeofstudy

Catálogo de grados de estudio.

GET /api/employees/relationship

Catálogo de parentescos.

POST /api/employees/employee

Obtiene un empleado por RFC.

// Request
{ "rfcEmployee": "RFC123456" }

POST /api/employees/newemployee

// Request
{
  "name_emp": "Juan Pérez",
  "rfc_emp": "RFC123456",
  "nss_emp": "12345678901",
  "addres_emp": "Calle 123",
  "phone_emp": "5551234567",
  "email_emp": "juan@email.com",
  "birthday_emp": "1990-05-15",
  "curp_emp": "CURP123456HDF",
  "study_emp": 1,
  "emergency_name": "María Pérez",
  "emergency_tel": "5559876543",
  "relationship_id": 1
}

POST /api/employees/updateemployee

Misma firma que newemployee. Actualiza por RFC.


Contratos

Base: /api/contracts

GET /api/contracts/

GET /api/contracts/getinfocontract/:id

GET /api/contracts/neartoend

GET /api/contracts/positions

GET /api/contracts/areas

GET /api/contracts/bosses

GET /api/contracts/reportempcontract

GET /api/contracts/disabledcontract

POST /api/contracts/newcontract

PUT /api/contracts/updatecontract/:id


Productos

Base: /api/products

GET /api/products/

Paginado (default limit: 10).

GET /api/products/productcategory

GET /api/products/producttype

GET /api/products/suppliers

GET /api/products/gdiscardproducts

GET /api/products/reportinventory

GET /api/products/stockadjusment

GET /api/products/gethousekeeper

GET /api/products/getproducts

GET /api/products/getconsumptionstockreport

POST /api/products/newsupplier

{
  "new_name_supp": "Proveedor SA",
  "new_rfc_supp": "RFC123456",
  "new_mail_supp": "prov@email.com",
  "new_phone_supp": "5551234567"
}

POST /api/products/newproduct

{
  "new_name_product": "Toallas",
  "new_sku_product": "TOW-001",
  "product_type": [{"id": 1, "name": "Textil"}],
  "new_category": 1,
  "suppliers_id": 1,
  "unit": 1,
  "new_stock": 100,
  "newprice_product": 150.00,
  "new_tax": 1,
  "currency": 1,
  "image_product": "url_o_base64"
}

Nota: product_type se serializa a JSONB.

POST /api/products/stockadjusmentset

{
  "stockproductadjusment": [
    { "id_product": 1, "new_stock": 50 },
    { "id_product": 2, "new_stock": 30 }
  ]
}

POST /api/products/newconsumptionstock

{
  "product_id": 1,
  "quantity_consumption": 5,
  "date_consumption": "2025-01-15",
  "rfc_emp": "RFC123456"
}

POST /api/products/disableSupplier

{ "supplier_id": 1 }

PUT /api/products/update_product/:id

PUT /api/products/discardproduct/:id

{
  "quantity": 5,
  "reasons": "Dañado"
}

PUT /api/products/product/:id

PUT /api/products/updatesupplier/:id

⚠️ Bug conocido: Falta / inicial en la ruta del backend.


Gastos

Base: /api/expenses

GET /api/expenses/pendingapproval

GET /api/expenses/approvedexpenses

GET /api/expenses/rejectedexpenses

GET /api/expenses/mainsupplier

PUT /api/expenses/getexpense/:id

⚠️ Nota: Es PUT pero debería ser GET. No requiere body.

GET /api/expenses/getinfo

Devuelve catálogos combinados (suppliers, categories, areas, users, currencies, uniforms, taxes).

GET /api/expenses/reportexpenses

POST /api/expenses/countpending

{ "option": 1 }  // 1 = aprobaciones, 2 = mensuales

GET /api/expenses/reportpayments

GET /api/expenses/monthlypayments

POST /api/expenses/newexpense

{
  "new_description": "Compra de amenities",
  "suppliers_id": 1,
  "new_request_date": "2025-01-01",
  "new_payment_deadline": "2025-01-31",
  "request_by": 1,
  "area": 1,
  "expense_cat": 1,
  "currency_id": 1,
  "products": [
    { "id_product": 1, "quantity": 10 },
    { "id_product": 2, "quantity": 5 }
  ],
  "new_iva": 16.00,
  "new_ieps": 0.00,
  "new_subtotal": 1000.00,
  "new_total": 1160.00,
  "needtoapprove": true
}

POST /api/expenses/totalapproved

{ "option": 1 }  // 1 = aprobado, 2 = rechazado

PUT /api/expenses/updateexpense/:id

Misma estructura que newexpense, con campos prefijados con up_.

GET /api/expenses/gettaxes


Aprobaciones y Pagos

Base: /api/status

PUT /api/status/approveupdate/:id

{
  "status": 2,
  "approved_by": 1
}

Status:

  • 2 = Aprobado
  • 3 = Rechazado

PUT /api/status/paymentupdate/:id

{ "status": 2 }

GET /api/status/penapppayments

GET /api/status/countdelaypay

GET /api/status/totalspent


Pagos Mensuales

Base: /api/payment

POST /api/payment/newexpmonthly

{
  "descriptionex": "Renta",
  "recurrence_id": 1,
  "payment_type": 1,
  "currency_id": 1,
  "suppliers_id": 1,
  "area": 1,
  "expense_category": 1,
  "day_expense": 15,
  "tax_id": 1,
  "new_subtotal": 5000.00
}

GET /api/payment/refreshmonthly

PUT /api/payment/paymentstatusmonthly/:id

{
  "status_payment": 2,
  "tax_id": 1,
  "subtotal": 5000.00
}

Si subtotal es null, solo actualiza el estado sin recalcular total.

PUT /api/payment/updateexpmonthly/:id

GET /api/payment/onemothlyexpense/:id

PUT /api/payment/needtorefresh/:id

{ "notrefresh": true }

Configuraciones

Base: /api/settings

POST /api/settings/newroom

POST /api/settings/newproperty

GET /api/settings/reportrooms

GET /api/settings/reportproperties

GET /api/settings/approveby

GET /api/settings/requestby

GET /api/settings/categoryexpense

GET /api/settings/currency

GET /api/settings/units

GET /api/settings/recurrence


Emails

Base: /api/emails

⚠️ Nota: Todos estos endpoints tienen validación de frecuencia (1 ejecución por mes) mediante la función validateendpoint().

POST /api/emails/nearexpiring

POST /api/emails/paymentdelay

POST /api/emails/expensesneartodeadline

POST /api/emails/expensesspecial

POST /api/emails/birthdays

POST /api/emails/contractexpired

POST /api/emails/expiredcontractsmonth


Ingresos (Little Hotelier)

Base: /api/incomes

Nota: La mayoría de estos endpoints reciben filtros de fecha en el body.

POST /api/incomes/getincomes

POST /api/incomes/totalincomes

POST /api/incomes/channelscards

POST /api/incomes/loadincomes

Carga masiva desde CSV/XLSX previamente colocado en src/resources/littleHotelier/.

POST /api/incomes/loadproductsales

POST /api/incomes/loadchequesdetalle

POST /api/incomes/reportincomes

POST /api/incomes/countticket

POST /api/incomes/efectivo

POST /api/incomes/otros

POST /api/incomes/propinas

POST /api/incomes/tarjeta

POST /api/incomes/vales

POST /api/incomes/sumatotal

POST /api/incomes/ticketpromedio

GET /api/incomes/getproductsales

GET /api/incomes/getdetallecheque


Compras

Base: /api/purchases

GET /api/purchases/getpurchases

Devuelve líneas de compra pendientes de recepción.

// Response
{
  "message": "Se obtuvieron todos los Purchases details",
  "data": [
    {
      "id_purchase_dt": 1,
      "id_expense": 5,
      "id_product": 2,
      "product_name": "Toallas",
      "quantity": 10,
      "delivered": 0,
      "id_tax": 1,
      "total": 1500.00
    }
  ]
}

PUT /api/purchases/entry/:id

Registra la recepción física de una compra.

// Request
{ "checking": 10 }

// Response
{
  "message": "Se obtuvo el Purchases details",
  "newentry": 1
}

Tipo de Cambio

Base: /api/exchange

POST /api/exchange/consultexchange

Consulta tipo de cambio actual desde API de Banxico.

GET /api/exchange/getexchanges

Devuelve historial de tipos de cambio guardados.


Hotel P&L

Base: /api/hotelpl

POST /api/hotelpl/cogs

POST /api/hotelpl/ebitda

POST /api/hotelpl/employeeshare

POST /api/hotelpl/grossprofit

POST /api/hotelpl/tips

POST /api/hotelpl/totalrevenue

POST /api/hotelpl/weightedCategoriesCost


Restaurant P&L

Base: /api/restaurantpl

POST /api/restaurantpl/cogs

POST /api/restaurantpl/ebitda

POST /api/restaurantpl/grossprofit

POST /api/restaurantpl/totalrevenue

POST /api/restaurantpl/weightedCategoriesCost


Ingresos Horux

Base: /api/incomeshrx

GET /api/incomeshrx/accountincome

GET /api/incomeshrx/categoryincome

GET /api/incomeshrx/invoiceIncome

GET /api/incomeshrx/totalIncome

GET /api/incomeshrx/incomehorux

GET /api/incomeshrx/oneincomehorux/:id

GET /api/incomeshrx/stripedata/

Obtiene transfers de Stripe y las inserta en PostgreSQL.

POST /api/incomeshrx/stripedatademo/

Crea un transfer de demo en Stripe.

POST /api/incomeshrx/insertinvoice

Descarga facturas de API externa (año actual) y las inserta.

POST /api/incomeshrx/newincome

{
  "account_id": 1,
  "amount": 5000.00,
  "new_date": "2025-01-15",
  "newinvoice": "FAC-001",
  "area_id": 1,
  "categories": [{"id": 1, "amount": 5000}]
}

PUT /api/incomeshrx/updateincome/:id

Misma estructura que newincome.


Fin de la referencia API. Para ver la lógica interna de cada endpoint, revisa los controllers en backend/hotel_hacienda/src/controllers/.