# Fortexa ERP — Documentacion API de Integracion
## Asientos de Diario (Journal Entries) para Sincronizacion de Nomina

**Version:** 1.0  
**Base URL:** `https://fortexaerp.com`  
**Formato:** JSON  
**Autenticacion:** Bearer Token (JWT)

---

## 1. Autenticacion

### Obtener Token de Acceso

```
POST /api/auth/login
Content-Type: application/json
```

**Request Body:**
```json
{
  "email": "usuario@empresa.com",
  "password": "su_contraseña"
}
```

**Response (200):**
```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "user": {
    "id": "uuid",
    "email": "usuario@empresa.com",
    "full_name": "Nombre del Usuario"
  }
}
```

### Uso del Token
Incluir en todas las solicitudes posteriores:
```
Authorization: Bearer {access_token}
```

---

## 2. Obtener Empresas del Usuario

```
GET /api/companies
Authorization: Bearer {token}
```

**Response (200):**
```json
[
  {
    "id": "abcdda61-0663-46d5-87ff-8fd3d96390bf",
    "name": "Mi Empresa SRL",
    "rnc": "123456789"
  }
]
```

> El `company_id` es necesario para todas las operaciones de Journal Entries.

---

## 3. Plan de Cuentas

### Listar Cuentas Contables

```
GET /api/chart-of-accounts/{company_id}/accounts
Authorization: Bearer {token}
```

**Response (200):**
```json
{
  "accounts": [
    {
      "id": "2eaaf0ab-d401-4bc5-b6c3-6edb709cf84d",
      "code": "50152",
      "name": "Sueldos y Salarios",
      "type": "EXPENSE",
      "is_active": true
    },
    {
      "id": "864ee2e6-ebae-4998-bbaa-8b77424d05b3",
      "code": "25006",
      "name": "ISR Retenido Nomina",
      "type": "LIABILITY",
      "is_active": true
    }
  ]
}
```

> Use el `id` y `code` de cada cuenta para construir las lineas del asiento de diario.

---

## 4. Asientos de Diario (Journal Entries)

### 4.1 Crear Asiento de Diario

```
POST /api/journal/{company_id}/entries
Authorization: Bearer {token}
Content-Type: application/json
```

**Request Body:**

| Campo           | Tipo     | Requerido | Descripcion                                                      |
|-----------------|----------|-----------|------------------------------------------------------------------|
| `entry_date`    | string   | Si        | Fecha del asiento (YYYY-MM-DD)                                   |
| `description`   | string   | Si        | Descripcion del asiento                                          |
| `reference`     | string   | No        | Referencia unica (ej: NOM-2026-03). Se auto-genera si no se envia|
| `entry_type`    | string   | Si        | Tipo de asiento (ver tabla abajo)                                |
| `lines`         | array    | Si        | Lineas del asiento (minimo 2)                                    |
| `currency`      | string   | No        | Moneda (default: "DOP")                                          |
| `exchange_rate`  | number   | No        | Tasa de cambio (default: 1.0)                                    |
| `notes`         | string   | No        | Notas adicionales                                                |
| `is_adjustment` | boolean  | No        | Si es un asiento de ajuste (default: false)                      |

**Estructura de cada linea (`lines`):**

| Campo             | Tipo   | Requerido | Descripcion                              |
|-------------------|--------|-----------|------------------------------------------|
| `account_id`      | string | Si        | UUID de la cuenta contable               |
| `account_name`    | string | Si        | Nombre de la cuenta                      |
| `account_type`    | string | No        | Tipo (EXPENSE, LIABILITY, ASSET, etc.)   |
| `debit`           | number | Si        | Monto debito (0 si es credito)           |
| `credit`          | number | Si        | Monto credito (0 si es debito)           |
| `description`     | string | No        | Descripcion de la linea                  |
| `contact_name`    | string | No        | Nombre del contacto asociado             |
| `cost_center_id`  | string | No        | UUID del centro de costo                 |
| `cost_center_name`| string | No        | Nombre del centro de costo               |

> **REGLA:** La suma de todos los debitos DEBE ser igual a la suma de todos los creditos.

**Tipos de Asiento Relevantes para Nomina:**

| Codigo            | Nombre              | Uso                                     |
|-------------------|----------------------|------------------------------------------|
| `PAYROLL`         | Nomina               | Asiento de provision de nomina           |
| `PAYROLL_PAYMENT` | Pago de Nomina       | Asiento del pago efectivo de la nomina   |
| `MANUAL`          | Entrada Manual       | Para ajustes manuales                    |

---

### Ejemplo: Asiento de Nomina (PAYROLL)

```json
{
  "entry_date": "2026-03-31",
  "description": "Nomina Marzo 2026 - 15 empleados",
  "reference": "NOM-2026-03",
  "entry_type": "PAYROLL",
  "currency": "DOP",
  "lines": [
    {
      "account_id": "uuid-sueldos-salarios",
      "account_name": "Sueldos y Salarios",
      "account_type": "EXPENSE",
      "debit": 650000.00,
      "credit": 0,
      "description": "Gasto de sueldos brutos"
    },
    {
      "account_id": "uuid-tss-patronal-gasto",
      "account_name": "TSS Patronal",
      "account_type": "EXPENSE",
      "debit": 99385.00,
      "credit": 0,
      "description": "Aporte patronal TSS (SFS+AFP+SRL)"
    },
    {
      "account_id": "uuid-isr-retenido",
      "account_name": "ISR Retenido Nomina",
      "account_type": "LIABILITY",
      "debit": 0,
      "credit": 79024.05,
      "description": "Retencion ISR empleados"
    },
    {
      "account_id": "uuid-tss-empleado",
      "account_name": "TSS por Pagar Empleado",
      "account_type": "LIABILITY",
      "debit": 0,
      "credit": 38415.00,
      "description": "Retencion TSS empleados (SFS+AFP)"
    },
    {
      "account_id": "uuid-tss-patronal-pagar",
      "account_name": "TSS por Pagar Patronal",
      "account_type": "LIABILITY",
      "debit": 0,
      "credit": 99385.00,
      "description": "TSS patronal por pagar"
    },
    {
      "account_id": "uuid-sueldos-pagar",
      "account_name": "Sueldos por Pagar",
      "account_type": "LIABILITY",
      "debit": 0,
      "credit": 532560.95,
      "description": "Neto a pagar a empleados"
    }
  ]
}
```

**Response (200):**
```json
{
  "success": true,
  "message": "Entrada de diario creada",
  "entry": {
    "id": "5ac9cbe9-b786-40e9-89da-563653b497f2",
    "company_id": "abcdda61-...",
    "entry_date": "2026-03-31",
    "description": "Nomina Marzo 2026 - 15 empleados",
    "reference": "NOM-2026-03",
    "entry_type": "PAYROLL",
    "entry_type_name": "Nomina",
    "lines": [...],
    "total_debit": 749385.00,
    "total_credit": 749385.00,
    "status": "posted",
    "created_at": "2026-03-31T12:00:00.000000+00:00"
  }
}
```

---

### Ejemplo: Pago de Nomina (PAYROLL_PAYMENT)

Cuando se realiza la transferencia bancaria para pagar los sueldos:

```json
{
  "entry_date": "2026-04-01",
  "description": "Pago de Nomina Marzo 2026",
  "reference": "PAG-NOM-2026-03",
  "entry_type": "PAYROLL_PAYMENT",
  "currency": "DOP",
  "lines": [
    {
      "account_id": "uuid-sueldos-pagar",
      "account_name": "Sueldos por Pagar",
      "account_type": "LIABILITY",
      "debit": 532560.95,
      "credit": 0,
      "description": "Liquidacion de sueldos por pagar"
    },
    {
      "account_id": "uuid-banco-principal",
      "account_name": "Banco BHD - Cuenta Operativa",
      "account_type": "ASSET",
      "debit": 0,
      "credit": 532560.95,
      "description": "Transferencia bancaria nomina"
    }
  ]
}
```

---

### 4.2 Listar Asientos de Diario

```
GET /api/journal/{company_id}/entries
Authorization: Bearer {token}
```

**Query Parameters:**

| Parametro    | Tipo   | Descripcion                                      |
|--------------|--------|--------------------------------------------------|
| `entry_type` | string | Filtrar por tipo (PAYROLL, PAYROLL_PAYMENT, etc.) |
| `from_date`  | string | Fecha inicio (YYYY-MM-DD)                        |
| `to_date`    | string | Fecha fin (YYYY-MM-DD)                           |
| `search`     | string | Buscar en descripcion o referencia               |
| `page`       | int    | Pagina (default: 1)                              |
| `page_size`  | int    | Resultados por pagina (default: 50)               |

**Ejemplo — Obtener solo asientos de nomina:**
```
GET /api/journal/{company_id}/entries?entry_type=PAYROLL&from_date=2026-01-01&to_date=2026-12-31
```

**Response (200):**
```json
{
  "entries": [
    {
      "id": "uuid",
      "entry_date": "2026-03-31",
      "description": "Nomina Marzo 2026",
      "reference": "NOM-2026-03",
      "entry_type": "PAYROLL",
      "entry_type_name": "Nomina",
      "total_debit": 749385.00,
      "total_credit": 749385.00,
      "status": "posted",
      "lines": [...]
    }
  ],
  "total": 3,
  "page": 1,
  "page_size": 50
}
```

---

### 4.3 Obtener un Asiento Especifico

```
GET /api/journal/{company_id}/entries/{entry_id}
Authorization: Bearer {token}
```

---

### 4.4 Actualizar un Asiento

> Solo asientos de tipo `MANUAL` pueden ser editados.

```
PUT /api/journal/{company_id}/entries/{entry_id}
Authorization: Bearer {token}
Content-Type: application/json
```

**Request Body:** (solo campos a modificar)
```json
{
  "entry_date": "2026-04-01",
  "description": "Nomina corregida",
  "lines": [...]
}
```

---

### 4.5 Eliminar un Asiento

> Solo asientos de tipo `MANUAL` pueden ser eliminados.

```
DELETE /api/journal/{company_id}/entries/{entry_id}
Authorization: Bearer {token}
```

---

## 5. Errores Comunes

| Codigo | Mensaje                                          | Causa                                      |
|--------|--------------------------------------------------|--------------------------------------------|
| 400    | "La entrada no esta balanceada"                  | Total debitos ≠ Total creditos             |
| 400    | "Una entrada debe tener al menos 2 lineas"       | Menos de 2 lineas en el asiento            |
| 400    | "Fecha en periodo cerrado"                       | Se intenta crear en un periodo contable cerrado |
| 401    | "Token de autenticacion requerido"               | Falta el header Authorization              |
| 401    | "Invalid token"                                  | Token expirado o invalido                  |
| 404    | "Company not found"                              | company_id invalido o sin acceso           |

---

## 6. Flujo Recomendado para Sincronizacion de Nomina

```
1. POST /api/auth/login                          → Obtener token
2. GET  /api/companies                            → Obtener company_id
3. GET  /api/chart-of-accounts/{company_id}/accounts → Obtener account_ids
4. POST /api/journal/{company_id}/entries         → Crear JE de Nomina (PAYROLL)
5. POST /api/journal/{company_id}/entries         → Crear JE de Pago (PAYROLL_PAYMENT)
6. GET  /api/journal/{company_id}/entries?entry_type=PAYROLL → Verificar
```

---

## 7. Cuentas Contables Tipicas de Nomina (RD)

| Codigo | Cuenta                   | Naturaleza | Debito/Credito en JE |
|--------|--------------------------|------------|----------------------|
| 50152  | Sueldos y Salarios       | Gasto      | Debito               |
| 60109  | TSS Patronal (Gasto)     | Gasto      | Debito               |
| 25006  | ISR Retenido Nomina      | Pasivo     | Credito              |
| 25010  | TSS por Pagar Empleado   | Pasivo     | Credito              |
| 25011  | TSS por Pagar Patronal   | Pasivo     | Credito              |
| 20201  | Sueldos por Pagar        | Pasivo     | Credito              |
| 11001  | Banco (cuenta operativa) | Activo     | Credito (al pagar)   |

---

## 8. Documentacion Interactiva (Swagger)

Acceda a la documentacion interactiva completa de todos los endpoints:

- **Swagger UI:** `https://fortexaerp.com/docs`
- **ReDoc:** `https://fortexaerp.com/redoc`

---

## 9. Notas Importantes

- Todos los montos son en la moneda especificada (`currency`). Default: DOP.
- Los asientos creados via API quedan con `status: "posted"` inmediatamente.
- Los `account_id` son UUIDs unicos por empresa. Siempre consulte el plan de cuentas primero.
- El `reference` debe ser unico por empresa para evitar duplicados.
- Los asientos automaticos (PAYROLL, SALES_INVOICE, etc.) no pueden ser editados ni eliminados via API. Solo `MANUAL`.

---

*Generado automaticamente — Fortexa ERP v2026.04*
