# 🔌 Referencia Completa de la API REST

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

---

## Índice
1. [Convenciones](#convenciones)
2. [Autenticación](#autenticación)
3. [Empleados](#empleados)
4. [Contratos](#contratos)
5. [Productos](#productos)
6. [Gastos](#gastos)
7. [Aprobaciones y Pagos](#aprobaciones-y-pagos)
8. [Pagos Mensuales](#pagos-mensuales)
9. [Configuraciones](#configuraciones)
10. [Emails](#emails)
11. [Ingresos (Little Hotelier)](#ingresos-little-hotelier)
12. [Compras](#compras)
13. [Tipo de Cambio](#tipo-de-cambio)
14. [Hotel P&L](#hotel-pl)
15. [Restaurant P&L](#restaurant-pl)
16. [Ingresos Horux](#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`

```json
// 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`

```json
// 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.

```json
// 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`

```json
// 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`

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

### GET `/api/employees/getattendance`

```json
{ "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.

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

### POST `/api/employees/newemployee`

```json
// 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`

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

### POST `/api/products/newproduct`

```json
{
  "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`

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

### POST `/api/products/newconsumptionstock`

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

### POST `/api/products/disableSupplier`

```json
{ "supplier_id": 1 }
```

### PUT `/api/products/update_product/:id`

### PUT `/api/products/discardproduct/:id`

```json
{
  "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`

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

### GET `/api/expenses/reportpayments`

### GET `/api/expenses/monthlypayments`

### POST `/api/expenses/newexpense`

```json
{
  "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`

```json
{ "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`

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

**Status:**
- `2` = Aprobado
- `3` = Rechazado

### PUT `/api/status/paymentupdate/:id`

```json
{ "status": 2 }
```

### GET `/api/status/penapppayments`

### GET `/api/status/countdelaypay`

### GET `/api/status/totalspent`

---

## Pagos Mensuales

Base: `/api/payment`

### POST `/api/payment/newexpmonthly`

```json
{
  "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`

```json
{
  "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`

```json
{ "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.

```json
// 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.

```json
// 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`

```json
{
  "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/`.
