openapi: 3.1.0
info:
  title: Aleluya V1
  description: |-
    ## Introducción

    **Esta página te ayudará a comenzar a usar rápidamente la API de Aleluya.**

    La API de [Aleluya](https://aleluya.com/) es un servicio que te permite acceder a tu cuenta para mantener tu información actualizada, tener acceso a tus datos y conectar aplicaciones externas

    Algunas acciones que puedes hacer en nuestra API son:

    - Sincronizar información de tu nómina con otras aplicaciones externas que utilices.
    - Agregar novedades de nómina.
    - Crear automáticamente personas en la aplicación a partir de pedidos de tu página web.
    - Sincronizar la información de la empresa con Aleluya.
    - Envío de correos.

    Actualmente, en la API puedes:

    | **Recurso** | **Endpoint** | **Descripción** |
    | --- | --- | --- |
    | **Registro** | `/registries` | Permite registrar/crear una empresa en Nominapp. |
    | **Empresa** | `/companies` |  |
    | **Area** | `/{company_id}/area` | Permite consultar, editar, crear y eliminar las areas de la empresa. |
    | **Cargos** | `/{company_id}/positions` | Permite consultar, editar, crear y eliminar los cargos de la empresa. |
    | **Sedes** | `/{company_id}/locations` | Permite consultar, editar, crear y eliminar las sedes de la empresa. |
    | **Débito automático** | `/{company_id}/automatic_debit_information` | Permite editar la información de débito automático de la empresa. |
    | **Periodos** | `/{company_id}/periods` | Permite listar y consultar la información de los periodos de la empresa. |
    | **Personas** | `/{company_id}/workers` | Permite listar, consultar, crear, eliminar y editar la información de las personas de empresa. |
    | **Contratos** | `/{company_id}/workers/{worker_id}/contracts` | Permite listar, consultar, crear, eliminar y editar la información de los contratos. |
    | **Salarios** | `/{company_id}/contracts/{contract_id}/wages` | Permite listar, consultar, crear, eliminar y editar la información de los salarios. |
    | **Nómina** | `/{company_id}/payrolls` | Permite consultar o modificar una nómina. |
    | **Otros ingresos y deducciones** | `/{company_id}/payrolls/{payroll_id}/items` | Permite listar, consultar, crear, eliminar y editar los ingresos adicionales o deducciones de una nómina. |
    | **Horas extras y recargos** | `/{company_id}/payrolls/{payroll_id}/overtime_items` | Permite listar, consultar, crear, eliminar y editar las horas extras o recargos de una nómina. |
    | **Vacaciones disfrutadas, incapacidades y licencias** | `/{company_id}/payrolls/{payroll_id}/novelties` | Permite listar, consultar, crear, eliminar y editar las vacaciones, incapacidades o licencias de una nómina. |
    | **Vacaciones compensadas** | `/{company_id}/payrolls/{payroll_id}/compensated_days` | Permite consultar, crear, eliminar y editar las vacaciones compensadas de una nómina. |
    | **Liquidación contrato** | `/{company_id}/contracts/{contract_id}/termination` | Permite consultar, crear, eliminar y editar la liquidación definitiva de un contrato laboral. |
    | **Conceptos de nómina** | `{company_id}/payroll_concepts` | Permite consultar, crear, editar y eliminar los conceptos de nómina de la empresa. |
    | **Instituciones** | `/institutions` | Permite listar, consultar, crear, eliminar y editar los ingresos adicionales o deducciones de una nómina. |
    | **Departamentos** | `/departments` | Permite listar y consultar los diferentes departamentos del país. |

    > ⚠ Tener en cuenta:
    Toda la comunicación con la API debe hacerse utilizando `https://`

    Nuestra API está basada en principios REST; puedes hacer llamados con los que métodos HTTP `(GET, POST, PUT y DELETE)` que son utilizados para acceder a los recursos. El sistema procesa la petición y retorna un código de respuesta en formato `JSON`, es decir, todas las respuestas se envían en formato `JSON`.

    ## Códigos de respuesta

    La API puede retornar alguno de los siguientes códigos HTTP:

    | Código | Descripción |
    | --- | --- |
    | `200` | Todo funcionó correctamente. |
    | `201` | El recurso se creó exitosamente. |
    | `202` | El request fue aceptado. |
    | `400` | El request está mal formado. La información para crear el recurso no existe o es inválida. |
    | `401` | Error en autenticación. La autenticación falló o no se encontró la información para autenticar el request. |
    | `402` | Pago requerido para realizar esta acción, se acabó el periodo de prueba y no se ha realizado el pago. |
    | `403` | El usuario no tiene permisos para realizar la acción. |
    | `404` | No se encontró en la aplicación el recurso que se está buscando. |
    | `422` | No se puede procesar la petición. Ocurre cuando en el request enviado hay un error o la información enviada no es correcta |
    | `429` | Muchos requests. Ocurre cuando el usuario supera el número de request permitidos por minuto (150 requests por minuto por IP o por usuario). |
    | `500` | Ocurrió un error en la aplicación |

    > ⓘ Recuerda que los _requests_ que realices pueden modificar la información de tu cuenta.

    ---

    ## Autenticación

    En la API de **Aleluya** existen 2 tipos de autenticación:

    1. Basic auth
    2. Bearer token

    ## Basic Auth

    > ⓘ Este tipo autenticación se usa para crear la sesión del usuario, para los endpoints de `Registro` y de `Aliados`.

    En el header Authorization se debe enviar el correo y el token del usuario separado por dos puntos (`:`), todo en base64.

    Por ejemplo, si el correo del usuario es `user@example.com` y el token es `api_token123` el header Authorization debe quedar así:

    `Authorization: Basic token`

    Donde `token` es base64 `('user@example.com:api_token123')`.

    ## Bearer Token

    > ⓘ Todos los endpoints menos crear sesión y los de `Registro` usan esta autenticación.

    La API de **Aleluya** utiliza `Bearer Token Authentication` como método de autenticación. Todos los request que se realicen deben incluirlo en el `header Authorization`.

    ### Obtener el token de acceso

    El `JWT Token` para autenticarse en la API**Aleluya** se obtiene al momento de crear sesión con el correo y la contraseña o la API token del usuario. Este tiene una duración de 30 minutos.

    ### Errores en autenticación

    Si la API encuentra algún inconveniente con la autenticación, retorna un status `401` y un mensaje con el error encontrado, por ejemplo:

    ``` json
    {
        "error": [
            {
                "message": "Credenciales inválidas.",
                "code": "0001",
                "object": "user",
                "index": 0
            }
        ]
    }

     ```

    ---

    ## Errores de autenticación o permisos

    Respuesta a errores de autenticación o permisos

    La mayoría de los endpoints del API **Aleluya** requieren autenticación y que el usuario tenga cierto rol, de lo contrario se tendrán errores de autenticación (`401`) o permisos (`403`).

    Además, los endpoints diferentes a consultas que modifiquen información o generen archivos también pueden presentar errores porque el pago es requerido (`402`), por lo que si se acabó el periodo de prueba o la suscripción se presentará esa respuesta.

    Los ejemplos de respuesta para estos 3 errores son:

    ``` json
    {
      "message":"Credenciales inválidas"
    }

     ```

    ``` json
    {
      "message": "Para poder utilizar esta funcionalidad, pasate al plan Full Juguetes"
    }

     ```

    ``` json
    {
      "message": "No tienes permiso para esta acción"
    }

     ```

    Existen diferentes tipos de mensaje para el error de pago requerido(402), este depende de la funcionalidad a la que se quiere acceder, es decir, si la funcionalidad es premium más recursos humanos, el mensaje será el siguiente:

    ``` json
    {
      "message": "Para poder utilizar esta funcionalidad, pasate al plan Full Juguetes"
    }

     ```

    De lo contrario, si la funcionalidad es solamente premium, es decir, para el plan básico, el mensaje de error de pago requerido depende del `freemium_status` de la compañía:

    ``` json
    {
      "message": "Esta es una funcionalidad premium y el periodo de prueba premium ha finalizado"
    }
    {
      "message": "Esta es una funcionalidad premium y tu suscripción esta vencida"
    }
    {
      "message": "Esta es una funcionalidad premium y tu suscripción esta cancelada"
    }

     ```

    También existen otros mensajes para pago requerido que corresponden al estado de la suscripción de la compañía y cuando se excede número máximo de personas que se pueden ingresar:

    ``` json
    {
      "message": "El periodo de prueba ha finalizado"
    }
    {
      "message": "Suscripción vencida"
    }
    {
      "message": "Suscripción cancelada"
    }
    {
      "message": "Tu Anualidad es máximo para 80 personas. Si deseas ingresar más personas, por favor comunicate con nuestro equipo de soporte para ayudarte"
    }
    {
      "message": "Tu plan es máximo para 80 personas. Si deseas ingresar más personas, por favor comunicate con nuestro equipo de soporte para ayudarte."
    }

     ```

    ---

    ## Filtros

    En algunas páginas se puede enviar un parámetro search o category que permite filtrar la respuesta.

    > ⓘ Estos endpoints por defecto devuelven 20 registros por página.

    En estos endpoints se agrega una llave filters que trae la siguiente información:

    | Campo | Tipo | Comentarios |
    | --- | --- | --- |
    | **total_records** | _integer_ | Total de registros encontrados según los registros aplicados |
    | **page** | _integer_ | El número de la página |
    | **per_page** | _integer_ | La cantidad máxima que se va mostrar por página |
    | **search** | _string_ | Valor del filtro search |

    ---

    ## Limite de requests

    Actualmente, se pueden realizar 150 request por minuto por IP.

    Si este límite es sobrepasado, la aplicación retorna un código `429 ("Too Many request")`. Si el usuario llega al límite, debe esperar que se termine el período (1 minuto) para realizar nuevamente llamadas a la API.

    ---

    ## Mensajes de errores

    La API puede retornar alguno de estos mensajes de errores cuando se presenta un error en el request enviado por el cliente.

    Los status son:

    | **HTTP Status code** | **HTTP Message** | **Descripción** |
    | --- | --- | --- |
    | `401` | `unauthorized` | Error en autenticación. La autenticación falla o no se encontró la información para autenticar el `request`. |
    | `402` | `payment_required` | Pago requerido para realizar esta acción, se acabó el periodo de prueba y no se ha realizado el pago. |
    | `403` | `forbidden` | El usuario no tiene permisos para realizar la acción. |
    | `404` | `not_found` | No se encontró en la aplicación el recurso que se está buscando. |
    | `422` | `unprocessable_entity` | No se puede procesar la petición. Ocurre cuando en el `request` enviado hay un error o la información enviada no es correcta. |

    Cuando se presenta un error 4XX, Aleluya devuelve el mensaje de error donde para cada uno de los errores se incluye:

    1. Mensaje
    2. Código específico del error (diferente al status http)
    3. Objeto donde se presentó el error.
    4. Index, posición donde ocurre el error. Por defecto es 0, puede ser diferente para endpoints donde se puede crear, editar o eliminar de forma masiva y el index indicará en cuál de todos los elementos enviados ocurrió el error

    > ⓘ Cada código HTTP tiene sus códigos, por lo que el código 0001 se puede repetir en el `401`, `402`, etc., sin que sea el mismo error o el mismo mensaje.

    ### Ejemplos de respuestas

    ``` json
    {
      "error": [
        {
          "message": "Credenciales inválidas.",
          "code": "0001",
          "object": "user",
          "index": 0
        }
      ]
    }

     ```
  version: 1.0.0
  contact: {}
servers:
  - url: https://nominapp-api.herokuapp.com
    description: Producción
  - url: https://nominapp-api-stage.herokuapp.com
    description: Entorno de pruebas
security:
  - bearerAuth: []
  - BasicAuth: []
tags:
  - name: Autenticación
    description: Inicio de sesión en la API
  - name: Generar token de sesión
    description: Inicio de sesión y obtención de tokens de sesión
  - name: Información de la empresa
    description: Las empresas (companies) son la base de Aleluya, ya que tienen la configuración sobre la cual se hacen los cálculos de nómina.
  - name: Registro e onboarding
    description: Registro de nuevas empresas
  - name: Áreas
    description: Gestión de áreas de la empresa
  - name: Cargos
    description: Gestión de cargos de la empresa
  - name: Sedes
    description: Gestión de sedes y ubicaciones de la empresa
  - name: Centros de costos
    description: Gestión de centros de costos
  - name: Distribución de centros de costos
    description: Gestión de la distribución de centros de costos por contrato
  - name: Centros de trabajo
    description: Gestión de centros de trabajo
  - name: Documentos de la empresa
    description: Gestión de documentos corporativos
  - name: Dashboard y métricas
    description: Dashboard y métricas de la empresa
  - name: Personas
    description: Crear, consultar, actualizar y eliminar personas
  - name: Importación masiva
    description: Importación masiva de trabajadores
  - name: Perfil de la persona
    description: Información y opciones del perfil de la persona autenticada
  - name: Nómina de la persona
    description: Conceptos y detalles de nómina accesibles desde el perfil de la persona
  - name: Colillas de la persona
    description: Colillas de pago accesibles desde el perfil de la persona
  - name: Préstamos de la persona
    description: Préstamos accesibles desde el perfil de la persona
  - name: Conceptos recurrentes de la persona
    description: Conceptos recurrentes accesibles desde el perfil de la persona
  - name: Solicitudes de novedad de la persona
    description: Solicitudes de novedad accesibles desde el perfil de la persona
  - name: Historial de pagos de la persona
    description: Historial de pagos accesible desde el perfil de la persona
  - name: Carpetas de la persona
    description: Carpetas y documentos accesibles desde el perfil de la persona
  - name: Certificados de la persona
    description: Certificados laborales y de ingresos accesibles desde el perfil de la persona
  - name: Documentos de personas
    description: Gestión de carpetas y documentos de trabajadores
  - name: Onboarding de personas
    description: Proceso de onboarding de nuevos trabajadores
  - name: Consulta de antecedentes
    description: Consulta de antecedentes de trabajadores
  - name: Contratos
    description: Gestión de contratos laborales
  - name: Detalles del contrato
    description: Detalles y configuraciones de contratos
  - name: Historial de cargos
    description: Historial de cambios de cargo en contratos
  - name: Salarios
    description: Gestión de salarios y actualización masiva
  - name: Terminación de contratos
    description: Liquidación y terminación de contratos
  - name: Firma electrónica
    description: Firma electrónica de documentos
  - name: Periodos de nómina
    description: Gestión de periodos de nómina
  - name: Nóminas
    description: Creación y gestión de nóminas
  - name: Conceptos de nómina
    description: Configuración de conceptos de nómina
  - name: Ítems de nómina
    description: Otros ingresos y deducciones en nómina
  - name: Horas extras y recargos
    description: Gestión de horas extras y recargos
  - name: Análisis de horas extras y recargos
    description: Análisis estadísticos de horas extras y recargos por periodo
  - name: Novedades
    description: Vacaciones, incapacidades y licencias
  - name: Solicitudes de novedades
    description: Solicitudes de novedades por trabajadores
  - name: Vacaciones compensadas
    description: Gestión de vacaciones compensadas
  - name: Auxilio de conectividad
    description: Configuración de auxilio de conectividad
  - name: Conceptos recurrentes
    description: Conceptos recurrentes por trabajador
  - name: Configuración de horas trabajadas
    description: Configuración de horas trabajadas
  - name: Configuración de nómina electrónica
    description: Configuración de nómina electrónica
  - name: Periodos de nómina electrónica
    description: Periodos de nómina electrónica
  - name: Emisión de nómina electrónica
    description: Emisión de nómina electrónica
  - name: Colillas electrónicas
    description: Gestión de colillas electrónicas
  - name: Archivos XML y gobierno
    description: Archivos XML y datos para el gobierno
  - name: Anulación de nómina electrónica
    description: Anulación de documentos electrónicos
  - name: Resúmenes de nómina electrónica
    description: Resúmenes y reportes de nómina electrónica
  - name: Historial por persona NE
    description: Historial de emisiones por trabajador
  - name: Periodos de prestaciones
    description: Periodos de liquidación de prestaciones
  - name: Prestaciones por periodo
    description: Prestaciones sociales por periodo
  - name: Prestaciones por contrato
    description: Prestaciones sociales por contrato
  - name: Archivos de prestaciones
    description: Archivos de prestaciones sociales
  - name: Sucursales
    description: Gestión de sucursales de seguridad social
  - name: Planilla PILA
    description: Planilla de seguridad social (PILA)
  - name: Integración con operador
    description: Integración con Aportes en Línea
  - name: Decreto 376
    description: Operadores especiales (Decreto 376)
  - name: Suscripción
    description: Gestión de suscripciones
  - name: Planes
    description: Planes disponibles
  - name: Pagos
    description: Métodos de pago (PSE, tarjeta, débito automático)
  - name: Facturación
    description: Información y envío de facturas
  - name: Desprendibles de pago
    description: Generación y envío de colillas de pago
  - name: Certificados laborales
    description: Generación de certificados laborales
  - name: Certificados de ingresos
    description: Certificados de ingresos y retenciones
  - name: Archivos de retefuente
    description: Archivos de retención en la fuente
  - name: Configuración de retención en la fuente
    description: Configuración de retención en la fuente
  - name: Configuración contable
    description: Códigos contables y configuración
  - name: Configuración para instituciones
    description: Códigos contables para instituciones
  - name: Archivos y documentos contables
    description: Archivos y documentos contables
  - name: Integración con Alegra
    description: Integración con sistema contable Alegra
  - name: Integraciones generales
    description: Integraciones con otros sistemas
  - name: Resúmenes de nómina
    description: Resúmenes y consolidados de nómina
  - name: Archivos bancarios
    description: Archivos bancarios para pagos
  - name: Historial de novedades
    description: Historial de novedades por periodo y trabajador
  - name: Historial de vacaciones
    description: Historial de vacaciones
  - name: Historial de pagos
    description: Historial de pagos por trabajador
  - name: Información exógena
    description: Información exógena
  - name: Datasets de reportes
    description: Datasets para reportes
  - name: Usuarios
    description: CRUD de usuarios
  - name: Información de usuario
    description: Información de usuarios
  - name: Sesión y seguridad
    description: Gestión de sesiones y seguridad
  - name: Tokens de acceso
    description: Gestión del token de API y llaves secretas de acceso del usuario
  - name: Invitaciones
    description: Invitaciones a usuarios
  - name: Credenciales de empresa
    description: Credenciales de empresa
  - name: Préstamos
    description: Gestión de préstamos a empleados
  - name: Configuración de empresa
    description: Parámetros de liquidación, deducciones y reglas de nómina
  - name: Cuentas bancarias
    description: Cuentas bancarias de la empresa
  - name: Notificaciones
    description: Configuración de notificaciones
  - name: Pulso Chat
    description: Chat con asistente de inteligencia artificial
  - name: Datos geográficos
    description: Departamentos y ciudades
  - name: Instituciones
    description: EPS, AFP, ARL, Cajas de compensación
  - name: Actividades económicas
    description: Códigos CIIU y clasificación de riesgo ARL
  - name: Sectores económicos
    description: Sectores económicos
paths:
  /users:
    patch:
      operationId: updateUserRegistration
      tags:
        - Usuarios
      summary: Actualizar datos del usuario autenticado
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el nombre, el correo y/o la contraseña del usuario autenticado. Si cambia el correo o la contraseña,
        se regeneran los tokens de sesión y la respuesta incluye un nuevo token de API y su fecha de expiración.

        **¿Cuándo usar este endpoint?**

        * Permitir que el usuario modifique su perfil desde una integración o cliente de API.
        * Rotar credenciales tras un cambio de correo o contraseña (nuevo token en la respuesta).

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede actualizar su propio perfil.
        * **Contraseña actual:** Si se envía `email`, `password` o `password_confirmation`, debe incluirse `current_password` con la contraseña vigente. Solo el cambio de `name` puede hacerse sin `current_password`.
        * **Nueva contraseña:** Los campos `password` y `password_confirmation` deben enviarse codificados en **Base64**. La contraseña debe tener mínimo 8 caracteres e incluir letras mayúsculas, minúsculas, números y símbolos.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user:
                  description: Campos a actualizar; solo se modifican los atributos enviados.
                  type: object
                  properties:
                    name:
                      description: Nombre completo del usuario.
                      type: string
                      example: María González
                    email:
                      description: Nuevo correo electrónico. Debe ser único en el sistema.
                      type: string
                      format: email
                      example: usuario@ejemplo.com
                    current_password:
                      description: Contraseña actual en texto plano. Obligatoria si se envía correo nuevo o cambio de contraseña (no aplica si solo se actualiza `name`).
                      type: string
                      example: ContraseñaSegura1!
                    password:
                      description: Nueva contraseña codificada en Base64. El valor decodificado debe tener entre 8 y 128 caracteres e incluir al menos una letra mayúscula, una minúscula, un número y un símbolo especial.
                      type: string
                      example: TnVldmFDbGF2ZTEyMyE=
                    password_confirmation:
                      description: Confirmación de la nueva contraseña codificada en Base64. Debe coincidir con `password`.
                      type: string
                      example: TnVldmFDbGF2ZTEyMyE=
              required:
                - user
            examples:
              Solo nombre:
                value:
                  user:
                    name: María González
              Cambio de correo y contraseña:
                value:
                  user:
                    name: María González
                    email: nuevo@ejemplo.com
                    current_password: ContraseñaSegura1!
                    password: bmV3cGFzczEyZDNBQEA=
                    password_confirmation: bmV3cGFzczEyZDNBQEA=
      responses:
        '202':
          description: Datos actualizados correctamente. Incluye nuevo token de autenticación y su expiración cuando aplica.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Contenedor con datos del usuario y tokens emitidos tras la actualización.
                    type: object
                    properties:
                      user:
                        description: Correo y nombre actualizados del usuario.
                        type: object
                        properties:
                          email:
                            description: Correo electrónico actual del usuario.
                            type: string
                            example: usuario@ejemplo.com
                          name:
                            description: Nombre actual del usuario.
                            type: string
                            example: María González
                      token:
                        description: Token de autenticación para enviar en el header `Authorization` de las peticiones siguientes (valor emitido por el servidor).
                        type: string
                        example: eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiODMyODdiZmEtZTg1Yi01YWE2LTk3Y2ItYTA3YjllYWFmNDE4In0.signature
                      expires:
                        description: Marca de tiempo Unix (segundos) en que expira el token de autenticación.
                        type: integer
                        example: 1738156800
              example:
                data:
                  user:
                    email: usuario@ejemplo.com
                    name: María González
                  token: eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiODMyODdiZmEtZTg1Yi01YWE2LTk3Y2ItYTA3YjllYWFmNDE4In0.signature
                  expires: 1738156800
        '401':
          $ref: '#/components/responses/401'
        '422':
          description: Contraseña actual incorrecta / Email duplicado / Contraseña demasiado corta / Requisitos de contraseña
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contraseña actual incorrecta:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Contraseña actual es inválido.
                        object: current_password
                Email ya en uso:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Email ya está en uso.
                        object: email
                Contraseña demasiado corta:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Contraseña es demasiado corto (8 caracteres mínimo).
                        object: password
                Contraseña no cumple requisitos:
                  value:
                    error:
                      - code: '1605'
                        index: 0
                        message: Elige una contraseña más segura. Combina letras mayúsculas, minúsculas, números y símbolos.
                        object: user
  /users/password:
    post:
      operationId: createPasswordReset
      tags:
        - Sesión y seguridad
      summary: Solicitar restablecimiento de contraseña
      description: |
        **¿Qué hace este endpoint?**

        Envía un correo al usuario con las instrucciones para restablecer su contraseña.

        **¿Cuándo usar este endpoint?**

        * Iniciar el flujo de recuperación de contraseña cuando el usuario no recuerda su clave.

        **Consideraciones importantes**

        * **Correo:** Debe corresponder a un usuario registrado en el sistema.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - user
              properties:
                user:
                  description: Datos del usuario que solicita el restablecimiento.
                  type: object
                  required:
                    - email
                  properties:
                    email:
                      description: Correo electrónico del usuario.
                      type: string
                      format: email
                      example: usuario@ejemplo.com
            example:
              user:
                email: usuario@ejemplo.com
      responses:
        '200':
          description: Solicitud procesada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del envío del correo.
                        type: string
                        example: Si tu usuario existe en Aleluya, en pocos minutos un email será enviado. Por favor, revisa tu correo.
              example:
                data:
                  message: Si tu usuario existe en Aleluya, en pocos minutos un email será enviado. Por favor, revisa tu correo.
        '422':
          description: Correo no enviado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0002'
                    index: 0
                    message: email no puede estar en blanco.
                    object: email
    put:
      operationId: updatePasswordReset
      tags:
        - Sesión y seguridad
      summary: Restablecer contraseña
      description: |
        **¿Qué hace este endpoint?**

        Restablece la contraseña del usuario usando el token recibido por correo.

        **¿Cuándo usar este endpoint?**

        * Completar el flujo de recuperación de contraseña después de recibir el correo con el token.

        **Consideraciones importantes**

        * **Token:** El token de restablecimiento se obtiene del enlace enviado al correo del usuario. Expira tras un tiempo definido.
        * **Contraseña:** Los campos `password` y `password_confirmation` deben enviarse codificados en **Base64**. El valor decodificado debe tener entre 8 y 128 caracteres e incluir al menos una letra mayúscula, una minúscula, un número y un símbolo especial.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - user
              properties:
                user:
                  description: Datos necesarios para restablecer la contraseña.
                  type: object
                  required:
                    - reset_password_token
                    - password
                    - password_confirmation
                  properties:
                    reset_password_token:
                      description: Token de restablecimiento recibido por correo.
                      type: string
                      example: xYz123AbC456dEf789
                    password:
                      description: Nueva contraseña codificada en Base64.
                      type: string
                      example: cGFzczEyM0Ah
                    password_confirmation:
                      description: Confirmación de la nueva contraseña codificada en Base64. Debe coincidir con `password`.
                      type: string
                      example: cGFzczEyM0Ah
            example:
              user:
                reset_password_token: xYz123AbC456dEf789
                password: cGFzczEyM0Ah
                password_confirmation: cGFzczEyM0Ah
      responses:
        '200':
          description: Contraseña restablecida correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del restablecimiento de contraseña.
                        type: string
                        example: Contraseña actualizada
              example:
                data:
                  message: Contraseña actualizada
        '422':
          description: Token inválido o expirado / Contraseña no coincide
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Token inválido o expirado:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Token de restablecimiento de contraseña no es válido
                        object: reset_password_token
                Contraseña no coincide:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Confirmación de contraseña no coincide con Contraseña
                        object: password_confirmation
  /users/sign_out:
    delete:
      operationId: destroySession
      tags:
        - Sesión y seguridad
      summary: Cerrar sesión
      description: |
        **¿Qué hace este endpoint?**

        Cierra la sesión del usuario autenticado eliminando la cookie de autenticación del servidor.

        **¿Cuándo usar este endpoint?**

        * Cerrar sesión de forma explícita al finalizar el uso de la aplicación.

        **Consideraciones importantes**

        * **Autenticación:** Requiere que el usuario esté autenticado mediante cookie de sesión. Si no hay sesión activa, responde `401`.
      responses:
        '200':
          description: Sesión cerrada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del cierre de sesión.
                        type: string
                        example: Token eliminado
              example:
                data:
                  message: Token eliminado
        '401':
          $ref: '#/components/responses/401'
  /users/unlock:
    get:
      operationId: showUserUnlock
      tags:
        - Sesión y seguridad
      summary: Desbloquear cuenta con token
      description: |
        **¿Qué hace este endpoint?**

        Completa el desbloqueo de la cuenta cuando el usuario estuvo bloqueado por intentos fallidos de inicio de sesión,
        usando el token enviado por correo (enlace de desbloqueo).

        **¿Cuándo usar este endpoint?**

        * Consumir el enlace o token del correo de “desbloquear cuenta” para volver a permitir el inicio de sesión.

        **Consideraciones importantes**

        * **Token:** El `unlock_token` actúa como credencial de un solo uso enviado al correo del usuario.
        * **Token:** Debe coincidir con el token vigente generado por el sistema; si es inválido o expiró, la API responde error de validación.
      parameters:
        - in: query
          name: unlock_token
          required: true
          description: Token recibido en el correo de instrucciones para desbloquear la cuenta (cadena opaca generada por el sistema).
          schema:
            type: string
            example: fCKoRpzjMx5NMNFqcfo6
      responses:
        '200':
          description: Cuenta desbloqueada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Contenedor del mensaje de confirmación.
                    type: object
                    properties:
                      message:
                        description: Mensaje confirmando que la cuenta quedó desbloqueada y puede iniciar sesión.
                        type: string
                        example: Tu cuenta ha sido desbloqueada. Ya puedes iniciar sesión.
              example:
                data:
                  message: Tu cuenta ha sido desbloqueada. Ya puedes iniciar sesión.
        '422':
          description: Token de desbloqueo inválido, ausente o con errores de validación
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0101'
                    index: 0
                    message: Token para desbloquear usuario es inválido.
                    object: unlock_token
    post:
      operationId: createUserUnlock
      tags:
        - Sesión y seguridad
      summary: Reenviar correo de desbloqueo
      description: |
        **¿Qué hace este endpoint?**

        Solicita el reenvío del correo con instrucciones (y enlace) para desbloquear la cuenta cuando está bloqueada
        por intentos fallidos.

        **¿Cuándo usar este endpoint?**

        * Cuando el usuario no recibió o perdió el correo original de desbloqueo y debe solicitar uno nuevo.

        **Consideraciones importantes**

        * **Correo:** Debe corresponder a un usuario registrado en el sistema.
        * **Correo:** Debe enviarse el objeto `user` con `email`; si el correo va vacío, la API responde error de validación.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user:
                  description: Debe incluir el correo del usuario que solicita el reenvío.
                  type: object
                  properties:
                    email:
                      description: Correo electrónico asociado a la cuenta en Aleluya.
                      type: string
                      format: email
                      example: usuario@ejemplo.com
                  required:
                    - email
              required:
                - user
            example:
              user:
                email: usuario@ejemplo.com
      responses:
        '200':
          description: Solicitud procesada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Contenedor del mensaje informativo para el usuario.
                    type: object
                    properties:
                      message:
                        description: Mensaje estándar indicando que, si el usuario existe, recibirá un correo en breve.
                        type: string
                        example: Si tu usuario existe en Aleluya, en pocos minutos un email será enviado. Por favor, revisa tu correo.
              example:
                data:
                  message: Si tu usuario existe en Aleluya, en pocos minutos un email será enviado. Por favor, revisa tu correo.
        '422':
          description: Correo vacío / Petición mal formada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Email vacío:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Email no puede estar en blanco.
                        object: email
                Cuerpo inválido:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
  /v1/activity_codes:
    get:
      operationId: indexActivityCodes
      tags:
        - Actividades económicas
      summary: Listar actividades económicas
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de actividades económicas (códigos CIIU) disponibles,
        filtrado según el decreto aplicable a la fecha indicada.

        **¿Cuándo usar este endpoint?**

        * Obtener el catálogo de actividades económicas para asignar el código CIIU a una empresa o centro de trabajo.
        * Buscar un código CIIU específico por código o descripción antes de asignarlo a la empresa.
        * Obtener el tipo de riesgo asociado a cada actividad para calcular el aporte a ARL.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * La fecha enviada en `filter` determina qué decreto aplica: antes del 2022-12-01 retorna el Decreto 1607; a partir de esa fecha retorna el Decreto 768. Si no se envía o el formato es inválido, aplica Decreto 768 por defecto.
      parameters:
        - in: query
          name: filter
          required: false
          description: 'Fecha de referencia para determinar qué decreto aplica: antes del 2022-12-01 retorna códigos del Decreto 1607; a partir de esa fecha retorna códigos del Decreto 768. Si no se envía o el formato es inválido, retorna Decreto 768 por defecto.'
          schema:
            type: string
            format: date
            example: '2024-01-01'
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca actividades económicas por código CIIU o descripción. La búsqueda es parcial y no distingue mayúsculas ni minúsculas.
          schema:
            type: string
            example: comercio
      responses:
        '200':
          description: Actividades económicas retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado paginado de actividades económicas ordenadas por código CIIU.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la actividad económica en la base de datos.
                          type: string
                          example: bca4c459-1a30-56c0-9c0c-055567614101
                        category:
                          description: 'Decreto bajo el cual se clasifica la actividad económica. Valores posibles: decree1607 (Decreto 1607), decree768 (Decreto 768), default_category (sin decreto asociado).'
                          type: string
                          enum:
                            - decree1607
                            - decree768
                            - default_category
                          example: decree768
                        risk_type:
                          description: Nombre codificado del tipo de riesgo ARL asociado a la actividad económica.
                          type: string
                          example: risk_1
                        ciiu_code:
                          description: Código CIIU de la actividad económica.
                          type: string
                          example: '0123'
                        description:
                          description: Descripción de la actividad económica.
                          type: string
                          example: Cultivo de cereales (excepto arroz), legumbres y semillas oleaginosas
                      required:
                        - id
                        - category
                        - risk_type
                        - ciiu_code
                        - description
                  filters:
                    description: Información de paginación y filtros aplicados a la consulta.
                    type: object
                    properties:
                      total_records:
                        description: Número total de actividades económicas que coinciden con los filtros aplicados, sin paginar.
                        type: integer
                        example: 350
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de registros retornados por página.
                        type: integer
                        example: 25
                      search:
                        description: Término de búsqueda aplicado. Cadena vacía si no se envió búsqueda.
                        type: string
                        example: ''
                    required:
                      - total_records
                      - page
                      - per_page
                      - search
                required:
                  - data
                  - filters
              example:
                data:
                  - id: bca4c459-1a30-56c0-9c0c-055567614101
                    category: decree768
                    risk_type: risk_1
                    ciiu_code: '0123'
                    description: Cultivo de cereales (excepto arroz), legumbres y semillas oleaginosas
                  - id: d3e4f5a6-b7c8-9d0e-1f2a-3b4c5d6e7f8a
                    category: decree768
                    risk_type: risk_2
                    ciiu_code: '0210'
                    description: Silvicultura y otras actividades forestales
                filters:
                  total_records: 350
                  page: 1
                  per_page: 25
                  search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
  /v1/companies:
    get:
      operationId: indexCompanies
      tags:
        - Información de la empresa
      summary: Listar empresas
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de empresas asociadas al usuario autenticado, con información básica de cada empresa y el rol del usuario en ella.

        **¿Cuándo usar este endpoint?**

        * Obtener la lista de empresas a las que tiene acceso el usuario para permitirle seleccionar con cuál operar.
        * Filtrar por estado para consultar únicamente empresas activas o inactivas.
        * Localizar una empresa específica mediante búsqueda por nombre o NIT.

        **Consideraciones importantes**

        * **Accesos:** Cualquier usuario autenticado puede consultar sus propias empresas; no requiere rol específico.
      parameters:
        - in: query
          name: filter
          required: false
          description: 'Filtra las empresas por estado. Valores posibles: `active` (activas), `inactive` (inactivas).'
          schema:
            type: string
            enum:
              - active
              - inactive
            example: active
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca empresas por razón social o número de identificación. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Empresa ABC
      responses:
        '200':
          description: Empresas registradas / Sin empresas registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo de empresas a las que tiene acceso el usuario. Cada objeto incluye identificadores, estado, tipo de documento y el rol del usuario en esa empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la empresa en la base de datos.
                          type: string
                          example: ba5a8865-29dc-4c24-aedc-7b45bf525882
                        active:
                          description: Indica si la empresa está activa.
                          type: boolean
                          example: true
                        document_type:
                          $ref: '#/components/schemas/CompanyDocumentType'
                        id_number:
                          description: Número de documento de identificación de la empresa.
                          type: string
                          example: '900123456'
                        name:
                          description: Nombre o razón social de la empresa.
                          type: string
                          example: Empresa de prueba S.A.S.
                        role:
                          $ref: '#/components/schemas/UserAccessRole'
                        worker_id:
                          description: Identificador único (ID) de la persona asociada al usuario en esta empresa. Puede ser null si el usuario no tiene contrato.
                          type:
                            - string
                            - 'null'
                          example: 072eec42-fef9-4234-98c3-4ed1208a3838
                        worker_with_benefits:
                          description: Indica si la empresa tiene habilitado el acceso a créditos para sus personas.
                          type: boolean
                          example: true
                  filters:
                    description: Parámetros de paginación y filtrado aplicados a la consulta.
                    type: object
                    properties:
                      filter:
                        description: Filtro de estado aplicado. Retorna el valor enviado (`active` o `inactive`) o `All` si no se aplicó ningún filtro.
                        type: string
                        example: All
                      page:
                        description: Página actual de la paginación.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de resultados por página.
                        type: integer
                        example: 50
                      search:
                        description: Término de búsqueda aplicado. Cadena vacía si no se aplicó ningún filtro de búsqueda.
                        type: string
                        example: ''
                      total_records:
                        description: Total de empresas que coinciden con los filtros aplicados.
                        type: integer
                        example: 1
              examples:
                Empresas registradas:
                  value:
                    data:
                      - id: ba5a8865-29dc-4c24-aedc-7b45bf525882
                        active: true
                        document_type: ni
                        id_number: '900123456'
                        name: Empresa de prueba S.A.S.
                        role: accountant
                        worker_id: 072eec42-fef9-4234-98c3-4ed1208a3838
                        worker_with_benefits: true
                    filters:
                      filter: All
                      page: 1
                      per_page: 50
                      search: ''
                      total_records: 1
                Sin empresas registradas:
                  value:
                    data: []
                    filters:
                      filter: All
                      page: 1
                      per_page: 50
                      search: ''
                      total_records: 0
        '401':
          $ref: '#/components/responses/401'
    post:
      operationId: createCompany
      tags:
        - Información de la empresa
      summary: Crear empresa
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva empresa y la asocia al usuario autenticado con el rol indicado (administrador o contador).

        **¿Cuándo usar este endpoint?**

        * Crear la empresa antes de registrar personas, contratos o nóminas — es el primer recurso que debe existir en el flujo de integración.
        * Registrar una empresa adicional para un usuario que administra múltiples empresas desde la misma cuenta.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe indicar rol administrador (admin) o contador (accountant) en el parámetro `role`; si no se envía, se asigna admin por defecto.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  description: Nombre o razón social de la empresa.
                  type: string
                  example: Aleluya S.A.S.
                id_number:
                  description: Número de identificación tributaria (NIT) de la empresa.
                  type: string
                  example: '900213123'
                email:
                  description: Correo electrónico principal de la empresa.
                  type: string
                  example: hq@aleluya.com
                user_area:
                  description: Área funcional del usuario dentro de la empresa.
                  type: string
                  example: accounting
                economic_sector_id:
                  description: Identificador único (ID) del sector económico al que pertenece la empresa.
                  type: string
                  example: f0b48bad-11d7-4c5d-8bf8-015049dc3d4d
                workers_number:
                  $ref: '#/components/schemas/WorkersNumberRange'
                role:
                  description: 'Rol del usuario en la empresa recién creada. Si no se envía, se asigna admin por defecto. Valores posibles: admin (administrador), accountant (contador).'
                  type: string
                  enum:
                    - admin
                    - accountant
                  example: admin
                user_area_other_info:
                  description: Descripción adicional cuando el área del usuario no corresponde a las opciones predefinidas.
                  type: string
                  example: Gestión administrativa
                main_goal:
                  description: 'Objetivo principal de uso de Aleluya. Valores posibles: payroll (nómina), electronic_payroll (nómina electrónica), financial_wellness (bienestar financiero), other (otro).'
                  type: string
                  enum:
                    - payroll
                    - electronic_payroll
                    - financial_wellness
                    - other
                  example: payroll
                main_goal_other_info:
                  description: Descripción adicional cuando el objetivo principal no corresponde a las opciones predefinidas.
                  type: string
                  example: Gestión integral de nómina
              required:
                - name
                - email
      responses:
        '201':
          description: Empresa creada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la empresa recién creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 072eec42-fef9-4234-98c3-4ed1208a3838
                      name:
                        description: Nombre o razón social de la empresa.
                        type: string
                        example: Aleluya S.A.S.
                      id_number:
                        description: Número de identificación tributaria (NIT) de la empresa.
                        type:
                          - string
                          - 'null'
                        example: '900213123'
                      email:
                        description: Correo electrónico principal de la empresa.
                        type: string
                        example: hq@aleluya.com
              example:
                data:
                  id: 072eec42-fef9-4234-98c3-4ed1208a3838
                  name: Aleluya S.A.S.
                  id_number: '900213123'
                  email: hq@aleluya.com
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '422':
          description: Rol no válido / Nombre en blanco / Nombre demasiado corto / Nombre demasiado largo / Correo electrónico en blanco / Correo electrónico con formato inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Rol no válido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Rol no es valido.
                        object: user
                Nombre en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Nombre demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre es demasiado corto (3 caracteres mínimo).
                        object: name
                Nombre demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Nombre es demasiado largo (110 caracteres máximo).
                        object: name
                Correo electrónico en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Correo electrónico no puede estar en blanco.
                        object: email
                Correo electrónico con formato inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Correo electrónico es inválido.
                        object: email
  /v1/companies/{id}:
    get:
      operationId: showCompany
      tags:
        - Información de la empresa
      summary: Obtener empresa
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información completa de una empresa. Si se envía el parámetro `only_files=true`, retorna únicamente las URLs de los documentos asociados a la empresa.

        **¿Cuándo usar este endpoint?**

        * Obtener toda la información de la empresa para mostrarla o editarla.
        * Consultar las URLs de los archivos subidos (certificado bancario, documento de identificación, representante legal, RUT) usando `only_files=true`.
        * Conocer el paso de onboarding actual de la empresa para determinar qué información falta completar.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - name: only_files
          in: query
          description: Si es `true`, retorna únicamente las URLs de los documentos de la empresa.
          required: false
          schema:
            type: boolean
        - name: interactive_tour_finished
          in: query
          description: Si es `true`, marca que el usuario completó el tour interactivo de configuración de la empresa.
          required: false
          schema:
            type: boolean
      responses:
        '200':
          description: Datos de la empresa / Solo archivos
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: |
                      Datos retornados según el parámetro `only_files`.

                      - Sin `only_files=true`: retorna la información completa de la empresa.
                      - Con `only_files=true`: retorna únicamente las URLs de los documentos (`files`).
                    oneOf:
                      - description: Información completa de la empresa.
                        type: object
                        required:
                          - id
                          - name
                          - document_type
                          - id_number
                          - verification_digit
                          - email
                          - payroll_frequency
                          - payment_method
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la empresa en la base de datos.
                            type: string
                            example: 1c16224f-fe8b-3669-bac4-e134424d3bad
                          name:
                            description: Nombre o razón social de la empresa.
                            type: string
                            example: Waystar Royco S.A.S.
                          document_type:
                            $ref: '#/components/schemas/CompanyDocumentType'
                          id_number:
                            description: Número de identificación tributaria (NIT) de la empresa.
                            type: string
                            example: '900123456'
                          verification_digit:
                            description: Dígito de verificación del NIT de la empresa.
                            type: integer
                            example: 5
                          email:
                            description: Correo electrónico principal de la empresa.
                            type: string
                            example: contacto@empresa.com
                          government_email:
                            description: Correo electrónico registrado ante la DIAN para comunicaciones oficiales.
                            type: string
                            example: dian@empresa.com
                          phone:
                            description: Número de teléfono de contacto de la empresa.
                            type: string
                            example: '6015551234'
                          address:
                            description: Dirección de la sede principal de la empresa.
                            type: string
                            example: Calle 72 No. 10-07
                          payroll_frequency:
                            $ref: '#/components/schemas/PayrollFrequency'
                          payment_method:
                            $ref: '#/components/schemas/PaymentMethod'
                          constitution_date:
                            description: Fecha de constitución legal de la empresa en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2015-03-20'
                          law_1429:
                            description: Indica si la empresa aplica beneficios de la Ley 1429 (empresas jóvenes).
                            type: boolean
                            example: false
                          law_1607:
                            description: Indica si la empresa aplica exoneración de aportes según la Ley 1607.
                            type: boolean
                            example: false
                          law_590:
                            description: Indica si la empresa aplica beneficios de la Ley 590 (micro y pequeña empresa).
                            type: boolean
                            example: false
                          decree_558:
                            description: Indica si la empresa acogió el Decreto 558 de reducción de aportes a pensión.
                            type: boolean
                            example: false
                          decree_376:
                            description: Indica si la empresa acogió el Decreto 376 de diferimiento de aportes.
                            type: boolean
                            example: false
                          from_partner_company:
                            description: Indica si la empresa fue creada a través de un aliado (partner).
                            type: boolean
                            example: false
                          electronic_payroll_authorized:
                            description: Indica si la empresa está habilitada para emitir nómina electrónica ante la DIAN.
                            type: boolean
                            example: false
                          created_at:
                            description: Fecha y hora de creación de la empresa como timestamp Unix en segundos.
                            type: string
                            example: '1551398400'
                          economic_sector:
                            description: Sector económico al que pertenece la empresa.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) del sector económico en la base de datos.
                                type: string
                                example: f0b48bad-11d7-4c5d-8bf8-015049dc3d4d
                              name:
                                description: Nombre del sector económico.
                                type: string
                                example: Servicios
                          department:
                            description: Departamento donde se ubica la empresa.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) del departamento en la base de datos.
                                type: string
                                example: a7106ca0-b758-570a-8c24-b043a7ef08fb
                              name:
                                description: Nombre del departamento.
                                type: string
                                example: Cundinamarca
                          city:
                            description: Ciudad donde se ubica la empresa.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) de la ciudad en la base de datos.
                                type: string
                                example: 2d16c1b8-1768-5504-993e-d2306280586b
                              name:
                                description: Nombre de la ciudad.
                                type: string
                                example: Bogotá, D.C.
                          onboarding:
                            description: Información del proceso de onboarding de la empresa.
                            type: object
                            properties:
                              workers_number:
                                $ref: '#/components/schemas/WorkersNumberRange'
                              user_area:
                                description: Área funcional del usuario indicada durante el onboarding.
                                type: string
                                example: accounting
                              onboarding_step:
                                description: Paso actual del proceso de onboarding de la empresa.
                                type: string
                                example: finished
                          onboarding_first_steps:
                            description: Estado de los primeros pasos del onboarding de la empresa.
                            type: object
                            properties:
                              first_worker:
                                description: Indica si ya se registró la primera persona en la empresa.
                                type: boolean
                                example: true
                              first_payroll:
                                description: Indica si ya se generó la primera nómina.
                                type: boolean
                                example: false
                              first_user:
                                description: Indica si ya se invitó al primer usuario adicional.
                                type: boolean
                                example: true
                              company_data_configured:
                                description: Indica si los datos básicos de la empresa están completos.
                                type: boolean
                                example: true
                              finished_all_steps:
                                description: Indica si se completaron todos los primeros pasos del onboarding.
                                type: boolean
                                example: false
                      - description: URLs de los documentos de la empresa. Retornado cuando se usa `only_files=true`.
                        type: object
                        required:
                          - files
                        properties:
                          files:
                            description: URLs de los documentos de la empresa almacenados en S3.
                            type: object
                            properties:
                              bank_certificate_document:
                                description: URL del certificado bancario. Puede ser null si no se ha subido.
                                type:
                                  - string
                                  - 'null'
                                example: https://storage.example.com/bank_certificate.pdf
                              identification_document:
                                description: URL del documento de identificación. Puede ser null si no se ha subido.
                                type:
                                  - string
                                  - 'null'
                                example: https://storage.example.com/identification.pdf
                              legal_representative_document:
                                description: URL del documento del representante legal. Puede ser null si no se ha subido.
                                type:
                                  - string
                                  - 'null'
                                example: https://storage.example.com/legal_rep.pdf
                              tax_document:
                                description: URL del RUT. Puede ser null si no se ha subido.
                                type:
                                  - string
                                  - 'null'
                                example: https://storage.example.com/rut.pdf
              examples:
                Datos de la empresa:
                  value:
                    data:
                      id: 1c16224f-fe8b-3669-bac4-e134424d3bad
                      name: Waystar Royco S.A.S.
                      document_type: ni
                      id_number: '900123456'
                      verification_digit: 5
                      email: contacto@empresa.com
                      government_email: dian@empresa.com
                      phone: '6015551234'
                      address: Calle 72 No. 10-07
                      payroll_frequency: monthly
                      payment_method: wire_transfer
                      constitution_date: '2015-03-20'
                      law_1429: false
                      law_1607: false
                      law_590: false
                      decree_558: false
                      decree_376: false
                      from_partner_company: false
                      electronic_payroll_authorized: false
                      created_at: '1551398400'
                      economic_sector:
                        id: f0b48bad-11d7-4c5d-8bf8-015049dc3d4d
                        name: Servicios
                      department:
                        id: a7106ca0-b758-570a-8c24-b043a7ef08fb
                        name: Cundinamarca
                      city:
                        id: 2d16c1b8-1768-5504-993e-d2306280586b
                        name: Bogotá, D.C.
                Solo archivos:
                  value:
                    data:
                      files:
                        bank_certificate_document: https://storage.example.com/bank_certificate.pdf
                        identification_document: https://storage.example.com/identification.pdf
                        legal_representative_document: https://storage.example.com/legal_rep.pdf
                        tax_document: https://storage.example.com/rut.pdf
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateCompany
      tags:
        - Información de la empresa
      summary: Actualizar empresa
      description: |
        **¿Qué hace este endpoint?**

        Actualiza la información de una empresa existente. Solo se deben enviar los campos que se desean modificar. También gestiona el flujo de onboarding cuando la empresa aún no ha completado su registro inicial.

        **¿Cuándo usar este endpoint?**

        * Modificar nombre, dirección, correo, teléfono u otros datos de la empresa.
        * Actualizar la periodicidad de liquidación (mensual o quincenal) cuando el periodo activo no tiene personas liquidadas.
        * Enviar los pasos del proceso de registro inicial de la empresa usando el campo `onboarding_step`.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{id}` con rol administrador (admin) o contador (accountant).
        * **Cambio de frecuencia de nómina:** No es posible cambiar la frecuencia si el periodo actual ya tiene personas liquidadas.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                company:
                  type: object
                  description: Objeto con los campos de la empresa a actualizar. Solo se deben enviar los campos a modificar.
                  properties:
                    address:
                      description: Dirección de la sede principal de la empresa.
                      type: string
                      example: Calle 72 No. 10-07
                    city_id:
                      description: Identificador único (ID) de la ciudad donde se ubica la empresa.
                      type: string
                      example: 072eec42-fef9-4234-98c3-4ed1208a3838
                    constitution_date:
                      description: Fecha de constitución legal de la empresa en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2015-03-20'
                    document_type:
                      $ref: '#/components/schemas/CompanyDocumentType'
                    economic_sector_id:
                      description: Identificador único (ID) del sector económico al que pertenece la empresa.
                      type: string
                      example: f0b48bad-11d7-4c5d-8bf8-015049dc3d4d
                    email:
                      description: Correo electrónico principal de la empresa.
                      type: string
                      example: contacto@empresa.com
                    government_email:
                      description: Correo electrónico registrado ante la DIAN para comunicaciones oficiales.
                      type: string
                      example: dian@empresa.com
                    id_number:
                      description: Número de identificación tributaria (NIT) de la empresa.
                      type: string
                      example: '900123456'
                    name:
                      description: Nombre o razón social de la empresa.
                      type: string
                      example: Waystar Royco S.A.S.
                    payment_method:
                      $ref: '#/components/schemas/PaymentMethod'
                    payroll_frequency:
                      $ref: '#/components/schemas/PayrollFrequency'
                    phone:
                      description: Número de teléfono de contacto de la empresa.
                      type: string
                      example: '6015551234'
                    onboarding_step:
                      description: 'Paso del proceso de onboarding a completar. Valores posibles: user_area (área del usuario), company_data (datos de la empresa), invite_admin (invitar administrador), finished (finalizado).'
                      type: string
                      enum:
                        - user_area
                        - company_data
                        - invite_admin
                        - finished
                      example: finished
                    user_area:
                      description: Área funcional del usuario dentro de la empresa, usada durante el onboarding.
                      type: string
                      example: accounting
                    user_area_other_info:
                      description: Descripción adicional del área cuando no corresponde a las opciones predefinidas del onboarding.
                      type: string
                      example: Gestión administrativa
                    workers_number:
                      $ref: '#/components/schemas/WorkersNumberRange'
              required:
                - company
      responses:
        '202':
          description: Empresa actualizada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la empresa.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 1c16224f-fe8b-3669-bac4-e134424d3bad
                      name:
                        description: Nombre o razón social de la empresa.
                        type: string
                        example: Waystar Royco S.A.S.
                      document_type:
                        $ref: '#/components/schemas/CompanyDocumentType'
                      id_number:
                        description: Número de identificación tributaria (NIT) de la empresa.
                        type: string
                        example: '900123456'
                      verification_digit:
                        description: Dígito de verificación del NIT de la empresa.
                        type: integer
                        example: 5
                      email:
                        description: Correo electrónico principal de la empresa.
                        type: string
                        example: contacto@empresa.com
                      government_email:
                        description: Correo electrónico registrado ante la DIAN para comunicaciones oficiales.
                        type: string
                        example: dian@empresa.com
                      phone:
                        description: Número de teléfono de contacto de la empresa.
                        type: string
                        example: '6015551234'
                      address:
                        description: Dirección de la sede principal de la empresa.
                        type: string
                        example: Calle 72 No. 10-07
                      payroll_frequency:
                        $ref: '#/components/schemas/PayrollFrequency'
                      payment_method:
                        $ref: '#/components/schemas/PaymentMethod'
                      constitution_date:
                        description: Fecha de constitución legal de la empresa en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2015-03-20'
                      law_1429:
                        description: Indica si la empresa aplica beneficios de la Ley 1429 (empresas jóvenes).
                        type: boolean
                        example: false
                      law_1607:
                        description: Indica si la empresa aplica exoneración de aportes según la Ley 1607.
                        type: boolean
                        example: false
                      law_590:
                        description: Indica si la empresa aplica beneficios de la Ley 590 (micro y pequeña empresa).
                        type: boolean
                        example: false
                      decree_558:
                        description: Indica si la empresa acogió el Decreto 558 de reducción de aportes a pensión.
                        type: boolean
                        example: false
                      decree_376:
                        description: Indica si la empresa acogió el Decreto 376 de diferimiento de aportes.
                        type: boolean
                        example: false
                      from_partner_company:
                        description: Indica si la empresa fue creada a través de un aliado (partner).
                        type: boolean
                        example: false
                      electronic_payroll_authorized:
                        description: Indica si la empresa está habilitada para emitir nómina electrónica ante la DIAN.
                        type: boolean
                        example: false
                      created_at:
                        description: Fecha y hora de creación de la empresa como timestamp Unix en segundos.
                        type: string
                        example: '1551398400'
                      economic_sector:
                        description: Sector económico al que pertenece la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del sector económico en la base de datos.
                            type: string
                            example: f0b48bad-11d7-4c5d-8bf8-015049dc3d4d
                          name:
                            description: Nombre del sector económico.
                            type: string
                            example: Servicios
                      department:
                        description: Departamento donde se ubica la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del departamento en la base de datos.
                            type: string
                            example: a7106ca0-b758-570a-8c24-b043a7ef08fb
                          name:
                            description: Nombre del departamento.
                            type: string
                            example: Cundinamarca
                      city:
                        description: Ciudad donde se ubica la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) de la ciudad en la base de datos.
                            type: string
                            example: 2d16c1b8-1768-5504-993e-d2306280586b
                          name:
                            description: Nombre de la ciudad.
                            type: string
                            example: Bogotá, D.C.
              example:
                data:
                  id: 1c16224f-fe8b-3669-bac4-e134424d3bad
                  name: Waystar Royco S.A.S.
                  document_type: ni
                  id_number: '900123456'
                  verification_digit: 5
                  email: contacto@empresa.com
                  government_email: dian@empresa.com
                  phone: '6015551234'
                  address: Calle 72 No. 10-07
                  payroll_frequency: monthly
                  payment_method: wire_transfer
                  constitution_date: '2015-03-20'
                  law_1429: false
                  law_1607: false
                  law_590: false
                  decree_558: false
                  decree_376: false
                  from_partner_company: false
                  electronic_payroll_authorized: false
                  created_at: '1551398400'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Cambio de frecuencia de nómina / Nombre de rol inválido / Nombre en blanco / Nombre demasiado corto / Nombre demasiado largo / Correo electrónico con formato inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Cambio de frecuencia de nómina:
                  value:
                    error:
                      - message: No es posible cambiar la frecuencia de pago a quincenal porque el periodo actual tiene personas liquidadas
                        code: '1403'
                        object: payroll_frequency
                        index: 0
                Nombre de rol inválido:
                  value:
                    error:
                      - message: 'Detalle otro rol de usuario solo puede contener números, letras, signos de puntuación y los siguientes caracteres #$%'
                        code: '117'
                        object: user_role_other_info
                        index: 0
                Nombre en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Nombre demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre es demasiado corto (3 caracteres mínimo).
                        object: name
                Nombre demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Nombre es demasiado largo (110 caracteres máximo).
                        object: name
                Correo electrónico con formato inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Correo electrónico es inválido.
                        object: email
    parameters:
      - name: id
        in: path
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        required: true
        schema:
          type: string
          example: 1c16224f-fe8b-3669-bac4-e134424d3bad
  /v1/departments:
    get:
      operationId: indexDepartments
      tags:
        - Datos geográficos
      summary: Listar departamentos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de todos los departamentos de Colombia ordenados alfabéticamente.

        **¿Cuándo usar este endpoint?**

        * Obtener el catálogo de departamentos de Colombia para validar o mapear ubicaciones geográficas.
        * Obtener los IDs de departamento para luego consultar sus ciudades con el endpoint de detalle.

        **Consideraciones importantes**

        * **Accesos:** Requiere autenticación. No está restringido a un rol específico de empresa.
      responses:
        '200':
          description: Departamentos retornados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de departamentos de Colombia ordenados alfabéticamente.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al departamento en la base de datos.
                          type: string
                          example: 2713b019-f917-4e65-815f-fccd8dffe6e3
                        name:
                          description: Nombre del departamento.
                          type: string
                          example: Cundinamarca
                      required:
                        - id
                        - name
                required:
                  - data
              example:
                data:
                  - id: 2713b019-f917-4e65-815f-fccd8dffe6e3
                    name: Antioquia
                  - id: 50c7a870-4fc4-50ac-8b40-3d9359fbe355
                    name: Cundinamarca
        '401':
          $ref: '#/components/responses/401'
  /v1/departments/{id}:
    get:
      operationId: showDepartment
      tags:
        - Datos geográficos
      summary: Obtener departamento con ciudades
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información de un departamento junto con el listado de sus ciudades ordenadas por código.

        **¿Cuándo usar este endpoint?**

        * Obtener el listado de ciudades de un departamento para validar o mapear ubicaciones geográficas a nivel municipal.

        **Consideraciones importantes**

        * **Accesos:** Requiere autenticación. No está restringido a un rol específico de empresa.
      responses:
        '200':
          description: Departamento retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información del departamento con su listado de ciudades.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al departamento en la base de datos.
                        type: string
                        example: 50c7a870-4fc4-50ac-8b40-3d9359fbe355
                      name:
                        description: Nombre del departamento.
                        type: string
                        example: Cundinamarca
                      cities:
                        description: Listado de ciudades del departamento ordenadas por código.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la ciudad en la base de datos.
                              type: string
                              example: 2d16c1b8-1768-5504-993e-d2306280586b
                            name:
                              description: Nombre de la ciudad.
                              type: string
                              example: Bogotá, D.C.
                          required:
                            - id
                            - name
                    required:
                      - id
                      - name
                      - cities
                required:
                  - data
              example:
                data:
                  id: 50c7a870-4fc4-50ac-8b40-3d9359fbe355
                  name: Cundinamarca
                  cities:
                    - id: 2d16c1b8-1768-5504-993e-d2306280586b
                      name: Bogotá, D.C.
                    - id: 3a4b5c6d-7e8f-9012-abcd-ef1234567890
                      name: Soacha
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al departamento en la base de datos.
        schema:
          type: string
          example: 50c7a870-4fc4-50ac-8b40-3d9359fbe355
  /v1/economic_sectors:
    get:
      operationId: indexEconomicSectors
      tags:
        - Sectores económicos
      summary: Listar sectores económicos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de sectores económicos disponibles en la plataforma.

        **¿Cuándo usar este endpoint?**

        * Poblar un selector de sector económico al registrar o actualizar la información de una empresa.
        * Obtener el `coded_name` o `id` de un sector para enviarlo en otros endpoints.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Listado de sectores económicos retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de sectores económicos disponibles.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al sector económico en la base de datos.
                          type: string
                          example: 43ef3a93-c158-5947-be9d-e7cfbcf747cb
                        coded_name:
                          description: Nombre clave del sector económico usado como identificador semántico.
                          type: string
                          example: agroindustry_and_environment
                        name:
                          description: Nombre legible del sector económico.
                          type: string
                          example: Agroindustria y Medio Ambiente
              example:
                data:
                  - id: 43ef3a93-c158-5947-be9d-e7cfbcf747cb
                    coded_name: agroindustry_and_environment
                    name: Agroindustria y Medio Ambiente
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
  /v1/institutions:
    get:
      operationId: indexInstitutions
      tags:
        - Instituciones
      summary: Listar instituciones
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de instituciones filtrado por categoría. Incluye bancos, EPS, ARLs,
        fondos de pensiones, cajas de compensación, operadores de seguridad social y otros.

        **¿Cuándo usar este endpoint?**

        * Obtener el catálogo de instituciones de una categoría para validar o mapear entidades en la configuración de empresa o contrato.
        * Obtener las cajas de compensación disponibles para un departamento específico.
        * Listar los bancos compatibles con un proveedor de pagos específico.
        * Filtrar solo las instituciones que requieren credenciales para afiliación electrónica.

        **Consideraciones importantes**

        * **Accesos:** Requiere autenticación. No está restringido a un rol específico de empresa.
        * El parámetro `category` es obligatorio. Si no se envía o es inválido, retorna 422.
        * `department_id` solo aplica cuando `category` es `compensation_fund`. Filtra las cajas de compensación del departamento indicado.
        * `provider` solo aplica cuando `category` es `bank`. El único valor válido es `druo`. Si se envía con otra categoría o con un valor inválido, retorna 422.
        * `company_credentials` en `true` retorna solo las instituciones que requieren contraseña para operar.
      parameters:
        - name: category
          in: query
          required: true
          description: |
            Categoría de la institución a listar:

            * `bank` - Bancos
            * `ss_operator` - Operadores de seguridad social
            * `risk_provider` - ARLs
            * `health_provider` - EPS
            * `pension_provider` - Fondos de pensiones
            * `compensation_fund` - Cajas de compensación
            * `severance_provider` - Fondos de cesantías
            * `parafiscal_provider` - Entidades parafiscales
            * `accounting_provider` - Software contable
          schema:
            type: string
            enum:
              - bank
              - ss_operator
              - risk_provider
              - health_provider
              - pension_provider
              - compensation_fund
              - severance_provider
              - parafiscal_provider
              - accounting_provider
            example: health_provider
        - name: company_credentials
          in: query
          required: false
          description: Si es `true`, retorna solo las instituciones que requieren credenciales para afiliación electrónica.
          schema:
            type: boolean
            example: true
        - name: department_id
          in: query
          required: false
          description: Identificador único (ID) del departamento. Solo aplica cuando `category` es `compensation_fund`. Filtra las cajas de compensación del departamento indicado.
          schema:
            type: string
            example: 50c7a870-4fc4-50ac-8b40-3d9359fbe355
        - name: provider
          in: query
          required: false
          description: Proveedor de pago para filtrar bancos. Solo aplica cuando `category` es `bank`. El único valor válido actualmente es `druo`.
          schema:
            type: string
            example: druo
      responses:
        '200':
          description: Instituciones retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de instituciones ordenadas alfabéticamente.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la institución en la base de datos.
                          type: string
                          example: aff3d9f3-aad7-597a-b545-1dadc463c4d5
                        name:
                          description: Nombre de la institución. Para EPS incluye el código de seguridad social separado por guion.
                          type: string
                          example: Sura - 025
                        id_number:
                          description: Número de identificación tributaria (NIT) de la institución.
                          type: string
                          example: '892400320'
                      required:
                        - id
                        - name
                        - id_number
                required:
                  - data
              example:
                data:
                  - id: aff3d9f3-aad7-597a-b545-1dadc463c4d5
                    name: Sura - 025
                    id_number: '892400320'
                  - id: b1c2d3e4-f5a6-7b8c-9d0e-1f2a3b4c5d6e
                    name: Nueva EPS - 047
                    id_number: '900156264'
        '401':
          $ref: '#/components/responses/401'
        '422':
          description: Categoría inválida / Filtro de proveedor inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Categoría inválida:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
                Filtro de proveedor inválido:
                  value:
                    error:
                      - code: '0121'
                        index: 0
                        message: El filtro de proveedor es inválido.
                        object: institution
  /v1/pulso/chat:
    post:
      operationId: createPulsoChat
      tags:
        - Pulso Chat
      summary: Iniciar o continuar una conversación de chat
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva conversación (si no se envía `conversation_id`) o recupera una existente.
        Retorna el `conversation_id` necesario para suscribirse al canal ActionCable y enviar mensajes.

        Los mensajes del usuario se envían directamente por WebSocket a través del canal `PulsoChatChannel`
        mediante la acción `receive_message`. La respuesta de la IA se transmite token a token por el
        canal ActionCable `pulso_chat_<conversation_id>`.

        **¿Cuándo usar este endpoint?**

        * Iniciar una nueva conversación sin `conversation_id`.
        * Recuperar el `conversation_id` de una conversación existente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `company_id` con rol administrador (admin) o contador (accountant).
        * **Flujo de mensajes:** Una vez obtenido el `conversation_id`, conéctate al WebSocket `/cable` y suscríbete al canal `PulsoChatChannel` con ese ID. Envía mensajes con la acción `receive_message`. La respuesta de la IA llega por el stream `pulso_chat_<conversation_id>`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                company_id:
                  description: Identificador único (ID) asignado a la empresa en la base de datos.
                  type: string
                  example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                conversation_id:
                  description: |
                    Identificador único (ID) de la conversación existente. Omitir para iniciar una nueva conversación.
                  type:
                    - string
                    - 'null'
                  example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
              required:
                - company_id
            example:
              company_id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      responses:
        '202':
          description: Conversación creada o recuperada
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la conversación.
                    type: object
                    properties:
                      conversation_id:
                        description: Identificador único (ID) de la conversación. Usar para suscribirse al canal ActionCable `pulso_chat_<conversation_id>` y enviar mensajes por WebSocket.
                        type: string
                        example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
              example:
                data:
                  conversation_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Solicitud inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
  /v1/registries:
    get:
      operationId: showRegistry
      tags:
        - Registro e onboarding
      summary: Validar registro
      description: |
        **¿Qué hace este endpoint?**

        Verifica si una empresa o un usuario ya existen en Aleluya, a partir del email o el número de identificación (NIT) enviados como parámetros de consulta.

        **¿Cuándo usar este endpoint?**

        * Confirmar que el email no está en uso antes de registrar una nueva empresa, para evitar errores 422 por duplicidad.
        * Verificar que el NIT de la empresa aún no está registrado antes de iniciar el proceso de alta.

        **Consideraciones importantes**

        * **Accesos:** Requiere autenticación HTTP Basic con las credenciales de aliado (usuario y api_token) proporcionadas por Aleluya. Se envían codificadas en Base64 en el header `Authorization: Basic <credenciales>`.
        * **Parámetros opcionales:** Se puede enviar uno o ambos parámetros (`email`, `id_number`). Si cualquiera ya existe en Aleluya, la respuesta será 422.
      parameters:
        - name: email
          in: query
          description: Email a validar.
          schema:
            type: string
            example: delilah@predovic.example
        - name: id_number
          in: query
          description: Número de identificación de la empresa a validar.
          schema:
            type: string
            example: '900123010'
      responses:
        '200':
          description: Acción realizada
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de que los datos enviados están disponibles para registro.
                        type: string
                        example: Se puede crear un registro con estos datos.
              example:
                data:
                  message: Se puede crear un registro con estos datos.
        '401':
          $ref: '#/components/responses/401'
        '422':
          description: Email o NIT ya registrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0103'
                    index: 0
                    message: No se puede crear un registro con esta información.
                    object: registry
    post:
      operationId: createRegistry
      tags:
        - Registro e onboarding
      summary: Crear registro
      description: |
        **¿Qué hace este endpoint?**

        Crea un nuevo registro en Aleluya: genera un usuario y una empresa a partir de los datos enviados. Es el primer paso para usar la plataforma.

        **¿Cuándo usar este endpoint?**

        * Registrar una nueva empresa y su usuario administrador antes de usar cualquier otro endpoint de la API.
        * Crear el primer recurso del flujo de integración cuando la empresa aún no existe en el sistema — es el único endpoint que no requiere una empresa previa.

        **Consideraciones importantes**

        * **Accesos:** Requiere autenticación HTTP Basic con las credenciales de aliado (usuario y api_token) proporcionadas por Aleluya. Se envían codificadas en Base64 en el header `Authorization: Basic <credenciales>`.
        * **Términos y condiciones:** El campo `terms_accepted` debe ser `true`; de lo contrario, la petición será rechazada.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                registry:
                  description: Datos para crear el registro
                  type: object
                  properties:
                    company_id_number:
                      description: Número de identificación de la empresa. De 7 a 13 caracteres.
                      type: string
                      example: '558101008'
                    company_name:
                      description: Nombre de la empresa. Longitud de 3 a 50 caracteres.
                      type: string
                      example: Company & Test SAS
                    email:
                      description: Email del usuario. Debe tener formato válido de email.
                      type: string
                      example: christie_stroman@hegmann-lesch.example
                    gclid:
                      description: Google Click Identifier.
                      type: string
                      example: marketing_test
                    name:
                      description: Nombre del usuario. Longitud de 3 a 50 caracteres.
                      type: string
                      example: User Test
                    page_url:
                      description: URL de la página.
                      type: string
                      example: /url_test
                    password:
                      description: Contraseña (longitud mínima de 8 caracteres).
                      type: string
                      example: p@ssw0rd123
                    payroll_frequency:
                      $ref: '#/components/schemas/PayrollFrequency'
                    phone:
                      description: Número de celular (longitud de 7 a 20 caracteres, solo números).
                      type: string
                      example: '3001234567'
                    source:
                      description: 'Fuente de origen del registro. Valores posibles: landing (página principal), accountants_landing (landing de contadores), alternative_landing (landing alternativa), demo (registro de prueba), calculadora_laboral (calculadora laboral), retefuente (calculadora de retefuente).'
                      type: string
                      enum:
                        - landing
                        - accountants_landing
                        - alternative_landing
                        - demo
                        - calculadora_laboral
                        - retefuente
                      example: accountants_landing
                    terms_accepted:
                      description: Debe ser `true` para poder crear una cuenta en Aleluya.
                      type: boolean
                      example: true
                    utm_adgroup:
                      description: Parámetro UTM de grupo de anuncios.
                      type: string
                      example: AdGroup1
                    utm_adposition:
                      description: Parámetro UTM de posición de anuncio.
                      type: string
                      example: 1t2
                    utm_campaign:
                      description: Parámetro UTM de campaña.
                      type: string
                      example: Campaign1
                    utm_content:
                      description: Parámetro UTM de contenido.
                      type: string
                      example: Content1
                    utm_device:
                      description: Parámetro UTM de dispositivo.
                      type: string
                      example: mobile
                    utm_devicemodel:
                      description: Parámetro UTM del modelo de dispositivo.
                      type: string
                      example: iPhone
                    utm_keyword:
                      description: Parámetro UTM de palabra clave.
                      type: string
                      example: keyword1
                    utm_matchtype:
                      description: Parámetro UTM de tipo de concordancia.
                      type: string
                      example: broad
                    utm_medium:
                      description: Parámetro UTM de medio.
                      type: string
                      example: cpc
                    utm_source:
                      description: Parámetro UTM de fuente.
                      type: string
                      example: google
                    workers_number:
                      description: 'Rango de número de personas que tiene la empresa. Valores posibles: 1-19 (1 a 19 personas), 20-49 (20 a 49), 50-99 (50 a 99), 100-149 (100 a 149), 150-200 (150 a 200), over_200 (más de 200).'
                      type: string
                      enum:
                        - 1-19
                        - 20-49
                        - 50-99
                        - 100-149
                        - 150-200
                        - over_200
                      example: 1-19
      responses:
        '201':
          description: Registro creado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del usuario y la empresa creados.
                    type: object
                    properties:
                      user:
                        description: Información del usuario creado.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al usuario en la base de datos.
                            type: string
                            example: aabfc5ab-cd5e-4136-8b28-9d4a0ca97d86
                          email:
                            description: Correo electrónico del usuario creado.
                            type: string
                            example: jim_schaefer@aufderhar.example
                      company:
                        description: Información de la empresa creada.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la empresa en la base de datos.
                            type: string
                            example: 3bf7642d-cf94-4945-a8cd-36d6b71bc2dd
                          name:
                            description: Nombre o razón social de la empresa.
                            type: string
                            example: Company & Test SAS
                          id_number:
                            description: Número de identificación tributaria (NIT) de la empresa. Puede ser null si no fue enviado en la solicitud.
                            type:
                              - string
                              - 'null'
                            example: '960643436'
              example:
                data:
                  user:
                    id: aabfc5ab-cd5e-4136-8b28-9d4a0ca97d86
                    email: jim_schaefer@aufderhar.example
                  company:
                    id: 3bf7642d-cf94-4945-a8cd-36d6b71bc2dd
                    name: Company & Test SAS
                    id_number: '960643436'
        '401':
          $ref: '#/components/responses/401'
        '422':
          description: Términos no aceptados / Campo obligatorio en blanco / Valor inválido / Dato ya en uso
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Términos no aceptados:
                  value:
                    error:
                      - code: '0105'
                        index: 0
                        message: Debes aceptar los Términos y Condiciones.
                        object: terms_accepted
                Campo obligatorio en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Email inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Email es inválido.
                        object: email
                Email ya en uso:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Email ya está en uso.
                        object: email
                Datos inválidos:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
  /v1/sessions:
    post:
      operationId: createSession
      tags:
        - Generar token de sesión
      summary: Iniciar sesión
      description: |
        **¿Qué hace este endpoint?**

        Autentica al usuario y devuelve la información del usuario y su empresa. Las credenciales se
        envían en el header `Authorization: Basic <base64(email:credencial)>`, donde `credencial` puede
        ser la **contraseña** del usuario o su **API token**.

        Soporta dos modos de respuesta según si se incluye `auth_type: bearer` en el cuerpo:

        **Modo 1 — Sesión con cookie (por defecto)**

        El servidor establece una cookie de sesión que se usa automáticamente en peticiones posteriores.

        **Modo 2 — Sesión con Bearer token**

        Incluir `auth_type: bearer` en el cuerpo. La respuesta devuelve un `api_access_token` con
        expiración de 8 horas para usar en el header `Authorization: Bearer <token>` en peticiones
        posteriores. Útil para integraciones que no pueden manejar cookies.

        <div style="padding: 12px 16px; border-radius: 8px; background-color: var(--callout-tip-bg); border: 1px solid var(--callout-tip-border); border-left: 3px solid var(--callout-tip-color);">
        <p style="margin: 0 0 6px 0; font-weight: 700; color: var(--callout-tip-color);">💡 Recomendado para integraciones y para probar esta API</p>
        <p style="margin: 0; color: var(--callout-tip-body-color);">Usa el Modo 2 (Bearer token): copia el <code>api_access_token</code> de la respuesta y envíalo en el header <code>Authorization: Bearer &lt;token&gt;</code> para autenticar las siguientes peticiones.</p>
        </div>

        **¿Cuándo usar este endpoint?**

        * Iniciar una sesión de usuario con correo y contraseña y recibir una cookie de sesión.
        * Obtener un Bearer token (`api_access_token`) para integraciones o clientes que no pueden usar cookies.

        **Consideraciones importantes**

        * **OTP:** Si el usuario tiene autenticación de dos factores habilitada, la respuesta es `202`
          con `otp_auth: true`. En ese caso, reenviar la petición incluyendo el parámetro `otp_code`.
        * **Autenticación con Google:** Los usuarios que previamente vincularon su cuenta con Google
          pueden autenticarse enviando `google_session` en el cuerpo en lugar de credenciales en el
          header. Esta opción no está disponible para nuevas vinculaciones.
        * **Cuenta bloqueada:** Tras múltiples intentos fallidos la cuenta se bloquea temporalmente;
          la respuesta es `401` con instrucciones para desbloquearla por correo.
        * **Usuario inactivo:** Si el usuario está inactivo en la empresa, la respuesta es `401`.
      parameters:
        - in: query
          name: otp_code
          required: false
          description: 'Código de autenticación de dos factores (OTP). Se debe incluir cuando el intento de inicio de sesión devolvió `202` con `otp_auth: true`, lo que indica que el usuario tiene autenticación de dos factores habilitada.'
          schema:
            type: string
            example: '123456'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                auth_type:
                  description: Indica el tipo de autenticación. Enviar `bearer` para obtener un `api_access_token` en la respuesta en lugar de usar cookie de sesión.
                  type: string
                  enum:
                    - bearer
                  example: bearer
                google_session:
                  description: Datos de autenticación de Google. Obligatorio cuando se autentica con Google OAuth.
                  type: object
                  required:
                    - google_id
                    - id_token
                  properties:
                    google_id:
                      description: Identificador de la cuenta de Google del usuario.
                      type: string
                      example: '108234567890123456789'
                    id_token:
                      description: Token de identidad emitido por Google.
                      type: string
                      example: eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOTczZWUifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIn0.signature
            examples:
              Sesión con Bearer token:
                value:
                  auth_type: bearer
              Autenticación con Google:
                value:
                  google_session:
                    google_id: '108234567890123456789'
                    id_token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOTczZWUifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIn0.signature
      responses:
        '201':
          description: |
            La estructura de la respuesta depende del modo de autenticación:

            * **Sesión con cookie:** incluye `expires` con la marca de expiración de la cookie.
            * **Sesión con Bearer token:** incluye `api_access_token` y `api_access_token_expires_at`. No incluye `expires`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la sesión y del usuario autenticado.
                    oneOf:
                      - type: object
                        description: Sesión con cookie
                        required:
                          - created_at
                          - is_new_user
                          - expires
                          - user
                        properties:
                          user:
                            $ref: '#/components/schemas/UserInformation'
                          created_at:
                            description: Marca de tiempo Unix en milisegundos del momento en que se creó la sesión.
                            type: integer
                            example: 1712803200000
                          is_new_user:
                            description: Indica si es la primera vez que el usuario inicia sesión.
                            type: boolean
                            example: false
                          expires:
                            description: Marca de tiempo Unix en segundos de expiración de la cookie de sesión.
                            type: integer
                            example: 1712889600
                      - type: object
                        description: Sesión con Bearer token
                        required:
                          - created_at
                          - is_new_user
                          - api_access_token
                          - api_access_token_expires_at
                          - user
                        properties:
                          user:
                            $ref: '#/components/schemas/UserInformation'
                          created_at:
                            description: Marca de tiempo Unix en milisegundos del momento en que se creó la sesión.
                            type: integer
                            example: 1712803200000
                          is_new_user:
                            description: Indica si es la primera vez que el usuario inicia sesión.
                            type: boolean
                            example: false
                          api_access_token:
                            description: Bearer token para autenticar peticiones subsiguientes.
                            type: string
                            example: eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiODMyODdiZmEtZTg1Yi01YWE2LTk3Y2ItYTA3YjllYWFmNDE4In0.signature
                          api_access_token_expires_at:
                            description: Fecha y hora de expiración del `api_access_token`.
                            type: string
                            format: date-time
                            example: '2024-04-11T08:00:00Z'
              examples:
                Sesión con cookie:
                  value:
                    data:
                      user:
                        active: true
                        area: hr
                        company_access: premium_full
                        company_created_at: '1456385484'
                        company_id: 3b7d03f0-e067-3d72-84f4-e410ac36ef57
                        company_name: Empresa Demo S.A.S.
                        distributor: null
                        email: usuario@ejemplo.com
                        id: 3117a7ea-8471-40ed-ac8e-3db728f32c5a
                        is_new_invited_admin_user: false
                        multicompany: false
                        name: María
                        picture: null
                        phone: '3001234567'
                        premium: true
                        role: admin
                        worker_id: cc2690e7-7cca-4cf9-94bb-305d0433459a
                        worker_with_benefits: true
                        workers_handle_novelties: true
                        workers_income_certificate_access: true
                        workers_labor_certificate_access: true
                        workers_payslips_access: true
                      created_at: 1712803200000
                      is_new_user: false
                      expires: 1712889600
                Sesión con Bearer token:
                  value:
                    data:
                      user:
                        active: true
                        area: hr
                        company_access: premium_full
                        company_created_at: '1456385484'
                        company_id: 3b7d03f0-e067-3d72-84f4-e410ac36ef57
                        company_name: Empresa Demo S.A.S.
                        distributor: null
                        email: usuario@ejemplo.com
                        id: 3117a7ea-8471-40ed-ac8e-3db728f32c5a
                        is_new_invited_admin_user: false
                        multicompany: false
                        name: María
                        picture: null
                        phone: '3001234567'
                        premium: true
                        role: admin
                        worker_id: cc2690e7-7cca-4cf9-94bb-305d0433459a
                        worker_with_benefits: true
                        workers_handle_novelties: true
                        workers_income_certificate_access: true
                        workers_labor_certificate_access: true
                        workers_payslips_access: true
                      created_at: 1712803200000
                      is_new_user: false
                      api_access_token: eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiODMyODdiZmEtZTg1Yi01YWE2LTk3Y2ItYTA3YjllYWFmNDE4In0.signature
                      api_access_token_expires_at: '2024-04-11T08:00:00Z'
        '202':
          description: Se requiere autenticación de dos factores
          content:
            application/json:
              schema:
                type: object
                properties:
                  email:
                    description: Correo electrónico del usuario que debe completar el segundo factor.
                    type: string
                    example: usuario@ejemplo.com
                  otp_auth:
                    description: Indica que se debe enviar el código OTP para completar el inicio de sesión.
                    type: boolean
                    example: true
              example:
                email: usuario@ejemplo.com
                otp_auth: true
        '401':
          description: Credenciales inválidas / Usuario inactivo / Cuenta bloqueada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Credenciales inválidas:
                  value:
                    error:
                      - code: '0001'
                        index: 0
                        message: Credenciales inválidas.
                        object: user
                Usuario inactivo:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: El usuario está inactivo. Contacta al administrador de la cuenta para activar este usuario.
                        object: user
                Cuenta bloqueada:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Su cuenta ha sido bloqueada temporalmente debido a múltiples intentos fallidos de inicio de sesión. Si su cuenta existe en Aleluya, en pocos minutos recibirá un correo electrónico con las instrucciones para desbloquearla.
                        object: user
    patch:
      operationId: updateSession
      tags:
        - Sesión y seguridad
      summary: Renovar sesión
      description: |
        **¿Qué hace este endpoint?**

        Renueva la cookie de sesión del usuario autenticado usando el refresh token almacenado en cookie
        y devuelve la nueva marca de expiración.

        **¿Cuándo usar este endpoint?**

        * Extender la sesión activa antes de que expire sin que el usuario tenga que volver a autenticarse.

        **Consideraciones importantes**

        * **Accesos:** Requiere que el usuario esté autenticado con cookie de sesión activa.
        * **Expiración:** Si la sesión superó el tiempo máximo permitido o el refresh token no coincide,
          la cookie se elimina y la respuesta es `401`.
      responses:
        '202':
          description: Sesión renovada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la sesión renovada.
                    type: object
                    properties:
                      created_at:
                        description: Marca de tiempo Unix en milisegundos del momento de renovación.
                        type: integer
                        example: 1712803200000
                      expires:
                        description: Marca de tiempo Unix en segundos de la nueva expiración de la cookie de sesión.
                        type: integer
                        example: 1712889600
              example:
                data:
                  created_at: 1712803200000
                  expires: 1712889600
        '401':
          $ref: '#/components/responses/401'
    delete:
      operationId: destroySessionCookie
      tags:
        - Sesión y seguridad
      summary: Cerrar sesión
      description: |
        **¿Qué hace este endpoint?**

        Cierra la sesión del usuario autenticado eliminando la cookie de autenticación del servidor.

        **¿Cuándo usar este endpoint?**

        * Cerrar sesión de forma explícita al finalizar el uso de la aplicación.

        **Consideraciones importantes**

        * **Accesos:** Requiere que el usuario esté autenticado con cookie de sesión activa.
      responses:
        '200':
          description: Sesión cerrada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del cierre de sesión.
                        type: string
                        example: Token eliminado
              example:
                data:
                  message: Token eliminado
        '401':
          $ref: '#/components/responses/401'
  /v1/user_informations:
    get:
      operationId: indexUserInformations
      tags:
        - Información de usuario
      summary: Listar partners o distribuidores del usuario
      description: |
        **¿Qué hace este endpoint?**

        Devuelve un listado de partners (aliados) o de distribuidores asociados al usuario autenticado, según el
        parámetro `option`. Cada elemento incluye identificador y nombre.

        **¿Cuándo usar este endpoint?**

        * Mostrar con qué partners o distribuidores está relacionado el usuario en contextos de marca blanca o red de aliados.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a una empresa con rol administrador (admin) o contador (accountant).
      parameters:
        - in: query
          name: option
          required: false
          description: |
            Tipo de listado. Si se envía el valor `distributors`, se listan distribuidores; en cualquier otro valor
            o si se omite el parámetro, se listan partners (aliados).
          schema:
            type: string
            example: distributors
      responses:
        '200':
          description: Listado obtenido correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Colección de partners o distribuidores según `option`.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) del partner o distribuidor en la base de datos.
                          type: string
                          example: af2b1701-39cc-45e9-ab64-9afb15e93667
                        name:
                          description: Nombre del partner o distribuidor.
                          type: string
                          example: Partner Demo SAS
              example:
                data:
                  - id: af2b1701-39cc-45e9-ab64-9afb15e93667
                    name: Partner Demo SAS
                  - id: b18e871d-ef72-5b46-ab11-662f4870fd91
                    name: Distribuidor Demo SAS
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
  /v1/user_informations/{id}:
    get:
      operationId: showUserInformation
      tags:
        - Información de usuario
      summary: Obtener información de usuario y empresa
      description: |
        **¿Qué hace este endpoint?**

        Retorna los datos del usuario indicado junto con la información de su empresa asociada: rol, plan, permisos
        de configuración y datos de contacto.

        **¿Cuándo usar este endpoint?**

        * Consultar el perfil completo de un usuario junto con los permisos y configuración de su empresa.
        * Verificar el rol y los accesos de un usuario específico dentro de una empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario autenticado solo puede consultar su propia información. El `{id}` debe corresponder al usuario autenticado.
        * **Empresa:** Si el usuario no tiene empresa asociada, varios campos de la respuesta pueden ser `null`.
      responses:
        '200':
          description: Información obtenida correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de usuario y contexto de empresa para la UI o integraciones.
                    type: object
                    properties:
                      active:
                        description: Indica si el usuario está activo en la empresa actual. Puede ser null si no hay empresa en contexto.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      area:
                        description: Área funcional del usuario en la empresa.
                        type:
                          - string
                          - 'null'
                        example: hr
                      company_access:
                        oneOf:
                          - $ref: '#/components/schemas/CompanyAccess'
                          - type: 'null'
                        description: Nivel de acceso de la empresa según su suscripción activa. Es `null` si el usuario no tiene empresa asociada.
                      company_created_at:
                        description: Fecha de creación de la empresa como cadena numérica con marca de tiempo Unix en segundos (UTC).
                        type:
                          - string
                          - 'null'
                        example: '1456385484'
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: 3b7d03f0-e067-3d72-84f4-e410ac36ef57
                      company_name:
                        description: Razón social o nombre comercial de la empresa.
                        type:
                          - string
                          - 'null'
                        example: Empresa Demo S.A.S.
                      distributor:
                        description: Identificador del distribuidor asociado a la empresa. Es `null` si no tiene distribuidor.
                        type:
                          - string
                          - 'null'
                        example: distribuidor_demo
                      email:
                        description: Correo electrónico del usuario.
                        type: string
                        example: usuario@ejemplo.com
                      id:
                        description: Identificador único (ID) del usuario en la base de datos.
                        type: string
                        example: 3117a7ea-8471-40ed-ac8e-3db728f32c5a
                      is_new_invited_admin_user:
                        description: Indica si el usuario fue creado después de la fecha de corte definida para “nuevo admin invitado”.
                        type: boolean
                        example: false
                      multicompany:
                        description: Indica si el usuario no tiene una única empresa asociada en este contexto (varias empresas o sin empresa fija).
                        type: boolean
                        example: false
                      name:
                        description: Nombre o nombre corto mostrable del usuario.
                        type: string
                        example: María
                      phone:
                        description: Teléfono celular del usuario. Puede ser null si no está registrado.
                        type:
                          - string
                          - 'null'
                        example: '3001234567'
                      picture:
                        description: URL o referencia para la foto de perfil del usuario. Puede ser null si no hay imagen.
                        type:
                          - string
                          - 'null'
                        example: https://ejemplo.com/storage/foto.jpg
                      premium:
                        description: Indica si la empresa tiene plan premium o suscripción premium activa.
                        type: boolean
                        example: true
                      role:
                        $ref: '#/components/schemas/UserAccessRole'
                      worker_id:
                        description: Identificador único (ID) de la persona (worker) en la empresa, si existe vínculo. Puede ser null.
                        type:
                          - string
                          - 'null'
                        example: cc2690e7-7cca-4cf9-94bb-305d0433459a
                      worker_with_benefits:
                        description: Indica si la empresa tiene módulo o personas con beneficios configurados.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      workers_handle_novelties:
                        description: Indica si en la configuración de empresa las personas pueden autogestionar novedades.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      workers_income_certificate_access:
                        description: Indica si aplica acceso a certificados de ingresos según configuración de empresa.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      workers_labor_certificate_access:
                        description: Indica si aplica acceso a certificados laborales según configuración de empresa.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      workers_payslips_access:
                        description: Indica si aplica acceso a colillas según configuración de empresa.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      sign_up:
                        description: Indica si es la primera vez que el usuario inicia sesión. Solo está presente cuando la empresa tiene un distribuidor asociado.
                        type: boolean
                        example: false
              example:
                data:
                  active: true
                  area: hr
                  company_access: premium_full
                  company_created_at: '1456385484'
                  company_id: 3b7d03f0-e067-3d72-84f4-e410ac36ef57
                  company_name: Empresa Demo S.A.S.
                  distributor: Distribuidor_demo
                  email: usuario@ejemplo.com
                  id: 3117a7ea-8471-40ed-ac8e-3db728f32c5a
                  is_new_invited_admin_user: false
                  multicompany: false
                  name: María
                  phone: '3001234567'
                  picture: https://ejemplo.com/storage/foto.jpg
                  premium: true
                  role: admin
                  worker_id: cc2690e7-7cca-4cf9-94bb-305d0433459a
                  worker_with_benefits: true
                  workers_handle_novelties: true
                  workers_income_certificate_access: true
                  workers_labor_certificate_access: true
                  workers_payslips_access: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: id
        description: Identificador único (ID) del usuario cuya información se consulta.
        schema:
          type: string
          example: 731843e9-0fc9-5e81-ae36-41e72e9dcc43
  /v1/users/secret_keys:
    get:
      operationId: indexUserSecretKeys
      tags:
        - Tokens de acceso
      summary: Listar llaves secretas
      description: |
        **¿Qué hace este endpoint?**

        Retorna la lista de llaves secretas de API activas del usuario autenticado. Estas llaves se usan
        para autenticar integraciones contra el servidor MCP de Aleluya.

        La respuesta nunca incluye el token en texto plano. Solo se retorna una vista previa
        enmascarada (`token_preview`) con los últimos 4 caracteres del valor original.

        **¿Cuándo usar este endpoint?**

        * Mostrar al usuario las llaves que tiene activas para identificar qué integraciones están conectadas.
        * Verificar si existe una llave con un nombre específico antes de crear una nueva.
        * Consultar la fecha del último uso (`last_used_at`) de cada llave para detectar integraciones inactivas.

        **Consideraciones importantes**

        * **Accesos:** Cualquier usuario autenticado puede listar sus propias llaves. La respuesta solo incluye llaves del usuario autenticado.
        * **Llaves revocadas:** El listado excluye las llaves que ya fueron revocadas. Una vez revocada, una llave no puede consultarse ni restaurarse.
      responses:
        '200':
          description: Listado obtenido correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo con las llaves secretas activas del usuario autenticado.
                    type: array
                    items:
                      type: object
                      description: Llave secreta de API del usuario para autenticación en el servidor MCP de Aleluya. Nunca incluye el token en texto plano.
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la llave secreta en la base de datos.
                          type: string
                          example: 5f8d7a22-1c4b-47a3-9b6e-8c3f2a1d4e5b
                        name:
                          description: Nombre descriptivo de la llave que ayuda al usuario a identificar dónde está usando la llave (por ejemplo, el equipo o integración asociada).
                          type: string
                          minLength: 3
                          maxLength: 100
                          example: Claude Code Laptop
                        token_preview:
                          description: Vista previa enmascarada del token con formato `sk-aleluya-...XXXX`, donde `XXXX` son los últimos 4 caracteres del valor original. Permite que el usuario identifique la llave sin exponer su valor completo.
                          type: string
                          example: sk-aleluya-...x9k2
                        last_used_at:
                          description: Fecha y hora del último uso registrado de la llave al autenticar contra el servidor MCP, en formato ISO 8601. Es `null` mientras la llave no haya sido utilizada.
                          type:
                            - string
                            - 'null'
                          format: date-time
                          example: '2026-04-22T14:30:00.000-05:00'
                        revoked_at:
                          description: Fecha y hora en que la llave fue revocada, en formato ISO 8601. Siempre es `null` en las respuestas de este endpoint, ya que el listado y las operaciones de modificación solo retornan llaves activas.
                          type:
                            - string
                            - 'null'
                          format: date-time
                          example: null
                        created_at:
                          description: Fecha y hora de creación de la llave, en formato ISO 8601.
                          type: string
                          format: date-time
                          example: '2026-04-20T09:15:00.000-05:00'
              example:
                data:
                  - id: 5f8d7a22-1c4b-47a3-9b6e-8c3f2a1d4e5b
                    name: Claude Code Laptop
                    token_preview: sk-aleluya-...x9k2
                    last_used_at: '2026-04-22T14:30:00.000-05:00'
                    revoked_at: null
                    created_at: '2026-04-20T09:15:00.000-05:00'
                  - id: 7a1e8c99-3d2b-41f6-89a5-2c4d1b8a7f3e
                    name: GPT Desktop
                    token_preview: sk-aleluya-...m4p7
                    last_used_at: null
                    revoked_at: null
                    created_at: '2026-04-21T11:00:00.000-05:00'
        '401':
          $ref: '#/components/responses/401'
    post:
      operationId: createUserSecretKey
      tags:
        - Tokens de acceso
      summary: Crear llave secreta
      description: |
        **¿Qué hace este endpoint?**

        Genera una nueva llave secreta de API para el usuario autenticado. La respuesta incluye el token
        en texto plano (`token`) **por única vez** — una vez entregada la respuesta, el sistema conserva
        solamente un hash y no es posible recuperarla.

        El valor se usa para autenticar integraciones con el servidor MCP de Aleluya enviándolo en el header
        `Authorization: Bearer sk-aleluya-...`.

        **¿Cuándo usar este endpoint?**

        * Configurar una nueva integración con Claude Code, Claude.ai, GPT u otro cliente MCP.
        * Rotar una llave existente creando una nueva y revocando la anterior.

        **Consideraciones importantes**

        * **Accesos:** Cualquier usuario autenticado puede crear llaves para su propia cuenta.
        * **Límite de llaves activas:** El usuario puede tener como máximo 10 llaves activas al mismo tiempo. Si ya alcanzó el límite, debe revocar una llave existente antes de crear una nueva.
        * **Nombre único:** El `name` debe ser único entre las llaves activas del usuario. Se permite reutilizar el nombre de una llave previamente revocada.
        * **Almacenamiento seguro:** El valor de `token` solo se retorna en esta respuesta. Debe guardarse en un gestor de credenciales o variable de entorno segura. Si se pierde, la llave no puede recuperarse y debe generarse una nueva.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                secret_key:
                  description: Datos de la llave secreta a crear.
                  type: object
                  properties:
                    name:
                      description: Nombre descriptivo para identificar la llave (por ejemplo, el equipo o integración asociada). Se aplican reglas de seguridad sobre los caracteres permitidos.
                      type: string
                      minLength: 3
                      maxLength: 100
                      example: Claude Code Laptop
                  required:
                    - name
              required:
                - secret_key
      responses:
        '201':
          description: Llave creada correctamente. El campo `token` se retorna únicamente en esta respuesta.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    description: |
                      Llave secreta recién creada con el token en texto plano incluido.

                      El campo `token` solo se retorna **una vez**, en la respuesta de creación. Después de este punto el sistema conserva únicamente un hash y no es posible recuperarlo; si se pierde, debe generarse una nueva llave.
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la llave secreta en la base de datos.
                        type: string
                        example: 5f8d7a22-1c4b-47a3-9b6e-8c3f2a1d4e5b
                      name:
                        description: Nombre descriptivo de la llave que ayuda al usuario a identificar dónde está usando la llave (por ejemplo, el equipo o integración asociada).
                        type: string
                        minLength: 3
                        maxLength: 100
                        example: Claude Code Laptop
                      token:
                        description: Valor completo de la llave en texto plano con formato `sk-aleluya-<valor>`. Solo se retorna en esta respuesta — no se almacena en claro y no puede recuperarse después. Debe guardarse en un lugar seguro y usarse para autenticar contra el servidor MCP de Aleluya.
                        type: string
                        example: sk-aleluya-AbCdEfGhIjKlMnOpQrStUvWxYz01x9k2
                      token_preview:
                        description: Vista previa enmascarada del token con formato `sk-aleluya-...XXXX`, donde `XXXX` son los últimos 4 caracteres del valor original.
                        type: string
                        example: sk-aleluya-...x9k2
                      last_used_at:
                        description: Fecha y hora del último uso de la llave. En la respuesta de creación siempre es `null`.
                        type:
                          - string
                          - 'null'
                        format: date-time
                        example: null
                      revoked_at:
                        description: Fecha y hora de revocación de la llave. En la respuesta de creación siempre es `null`.
                        type:
                          - string
                          - 'null'
                        format: date-time
                        example: null
                      created_at:
                        description: Fecha y hora de creación de la llave, en formato ISO 8601.
                        type: string
                        format: date-time
                        example: '2026-04-23T09:15:00.000-05:00'
              example:
                data:
                  id: 5f8d7a22-1c4b-47a3-9b6e-8c3f2a1d4e5b
                  name: Claude Code Laptop
                  token: sk-aleluya-AbCdEfGhIjKlMnOpQrStUvWxYz01x9k2
                  token_preview: sk-aleluya-...x9k2
                  last_used_at: null
                  revoked_at: null
                  created_at: '2026-04-23T09:15:00.000-05:00'
        '401':
          $ref: '#/components/responses/401'
        '422':
          description: Nombre vacío / Nombre demasiado corto / Nombre duplicado / Caracteres inválidos / Límite de llaves activas alcanzado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nombre vacío:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar vacío.
                        object: name
                Nombre demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre es demasiado corto (3 caracteres mínimo).
                        object: name
                Nombre duplicado:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Nombre ya está en uso.
                        object: name
                Caracteres inválidos:
                  value:
                    error:
                      - code: '0118'
                        index: 0
                        message: 'Nombre contiene uno o más de los siguientes caracteres inválidos: ''<>$\''.'
                        object: name
                Límite de llaves activas:
                  value:
                    error:
                      - code: '7501'
                        index: 0
                        message: Máximo 10 llaves activas por usuario.
                        object: user_secret_key
  /v1/users/secret_keys/{id}:
    patch:
      operationId: updateUserSecretKey
      tags:
        - Tokens de acceso
      summary: Renombrar llave secreta
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el nombre descriptivo de una llave secreta activa del usuario autenticado.
        Solo el campo `name` puede modificarse; el token y su hash permanecen sin cambios.

        **¿Cuándo usar este endpoint?**

        * Renombrar una llave para reflejar mejor la integración a la que pertenece.
        * Corregir un nombre ingresado por error al crear la llave.

        **Consideraciones importantes**

        * **Accesos:** El usuario autenticado solo puede renombrar sus propias llaves.
        * **Llaves revocadas:** Si la llave ya fue revocada, el endpoint responde con 404. Las llaves revocadas no pueden modificarse.
        * **Nombre único:** El nuevo `name` debe ser único entre las llaves activas del usuario.
        * **Token inalterado:** El valor del token, su hash y los campos `token_preview`, `last_used_at`, `revoked_at` y `created_at` no cambian con esta operación.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                secret_key:
                  description: Campos a actualizar. Solo se admite `name`; cualquier otro campo enviado se ignora.
                  type: object
                  properties:
                    name:
                      description: Nuevo nombre descriptivo para la llave.
                      type: string
                      minLength: 3
                      maxLength: 100
                      example: Claude laptop
                  required:
                    - name
              required:
                - secret_key
      responses:
        '200':
          description: Llave renombrada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    description: Llave secreta de API del usuario para autenticación en el servidor MCP de Aleluya. Nunca incluye el token en texto plano.
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la llave secreta en la base de datos.
                        type: string
                        example: 5f8d7a22-1c4b-47a3-9b6e-8c3f2a1d4e5b
                      name:
                        description: Nombre descriptivo de la llave que ayuda al usuario a identificar dónde está usando la llave (por ejemplo, el equipo o integración asociada).
                        type: string
                        minLength: 3
                        maxLength: 100
                        example: Claude laptop
                      token_preview:
                        description: Vista previa enmascarada del token con formato `sk-aleluya-...XXXX`, donde `XXXX` son los últimos 4 caracteres del valor original. Permite que el usuario identifique la llave sin exponer su valor completo.
                        type: string
                        example: sk-aleluya-...x9k2
                      last_used_at:
                        description: Fecha y hora del último uso registrado de la llave al autenticar contra el servidor MCP, en formato ISO 8601. Es `null` mientras la llave no haya sido utilizada.
                        type:
                          - string
                          - 'null'
                        format: date-time
                        example: '2026-04-22T14:30:00.000-05:00'
                      revoked_at:
                        description: Fecha y hora en que la llave fue revocada, en formato ISO 8601. Siempre es `null` en las respuestas de este endpoint, ya que el listado y las operaciones de modificación solo retornan llaves activas.
                        type:
                          - string
                          - 'null'
                        format: date-time
                        example: null
                      created_at:
                        description: Fecha y hora de creación de la llave, en formato ISO 8601.
                        type: string
                        format: date-time
                        example: '2026-04-20T09:15:00.000-05:00'
              example:
                data:
                  id: 5f8d7a22-1c4b-47a3-9b6e-8c3f2a1d4e5b
                  name: Claude laptop
                  token_preview: sk-aleluya-...x9k2
                  last_used_at: '2026-04-22T14:30:00.000-05:00'
                  revoked_at: null
                  created_at: '2026-04-20T09:15:00.000-05:00'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre demasiado corto / Nombre duplicado / Caracteres inválidos
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nombre demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre es demasiado corto (3 caracteres mínimo).
                        object: name
                Nombre duplicado:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Nombre ya está en uso.
                        object: name
                Caracteres inválidos:
                  value:
                    error:
                      - code: '0118'
                        index: 0
                        message: 'Nombre contiene uno o más de los siguientes caracteres inválidos: ''<>$\''.'
                        object: name
    delete:
      operationId: destroyUserSecretKey
      tags:
        - Tokens de acceso
      summary: Revocar llave secreta
      description: |
        **¿Qué hace este endpoint?**

        Revoca una llave secreta activa del usuario autenticado. La revocación es irreversible: la llave
        deja de ser válida inmediatamente y deja de aparecer en el listado del endpoint `GET /v1/users/secret_keys`.

        El registro se conserva en la base de datos con la marca `revoked_at` establecida, pero no puede restaurarse.

        **¿Cuándo usar este endpoint?**

        * Desconectar una integración que ya no se usa.
        * Rotar credenciales tras un posible compromiso: primero crear una nueva llave, luego revocar la anterior.

        **Consideraciones importantes**

        * **Accesos:** El usuario autenticado solo puede revocar sus propias llaves.
        * **Llaves revocadas:** Si la llave ya fue revocada anteriormente, el endpoint responde con 404.
        * **Irreversible:** Una vez revocada la llave no puede reactivarse; si se necesita recuperar acceso, debe crearse una llave nueva.
      responses:
        '200':
          description: Llave revocada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la revocación.
                        type: string
                        example: La llave secreta ha sido revocada.
              example:
                data:
                  message: La llave secreta ha sido revocada.
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la llave secreta en la base de datos.
        schema:
          type: string
          example: 5f8d7a22-1c4b-47a3-9b6e-8c3f2a1d4e5b
  /v1/users/token:
    get:
      operationId: showUserToken
      tags:
        - Tokens de acceso
      summary: Obtener vista previa del token de API
      description: |
        **¿Qué hace este endpoint?**

        Devuelve una vista enmascarada del `api_token` del usuario autenticado (primer carácter, asteriscos y últimos
        cuatro caracteres), sin exponer el valor completo.

        **¿Cuándo usar este endpoint?**

        * Consultar si el usuario ya tiene un token de API generado antes de solicitar uno nuevo.
        * Identificar el token activo mediante su vista enmascarada sin exponer el valor completo.

        **Consideraciones importantes**

        * **Accesos:** Cualquier usuario autenticado puede consultar su propio token.
      responses:
        '200':
          description: Vista previa obtenida correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Contenedor con la vista enmascarada del token.
                    type: object
                    properties:
                      token_preview:
                        description: Primer carácter del token, diez asteriscos y los últimos cuatro caracteres del `api_token`.
                        type: string
                        example: f**********2g76
              example:
                data:
                  token_preview: f**********2g76
        '401':
          $ref: '#/components/responses/401'
    patch:
      operationId: updateUserToken
      tags:
        - Tokens de acceso
      summary: Regenerar token de API
      description: |
        **¿Qué hace este endpoint?**

        Genera un nuevo `api_token` para el usuario autenticado y lo persiste. La respuesta incluye el token completo
        en claro para que el cliente lo actualice (debe almacenarse de forma segura).

        **¿Cuándo usar este endpoint?**

        * Rotar el token de API tras un posible compromiso o según política de seguridad.
        * Obtener un token nuevo cuando el anterior deja de ser válido para integraciones.

        **Consideraciones importantes**

        * **Accesos:** Cualquier usuario autenticado puede regenerar su propio token.
        * **Seguridad:** El valor de `token` en la respuesta es secreto; almacénalo de forma segura.
      responses:
        '202':
          description: Token regenerado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Contenedor con el nuevo token de API en texto plano.
                    type: object
                    properties:
                      token:
                        description: Nuevo valor del token de API del usuario (hexadecimal). Reemplaza al token anterior para las siguientes peticiones autenticadas con token.
                        type: string
                        example: a1b2c3d4e5f678901234567890abcdef12345678
              example:
                data:
                  token: a1b2c3d4e5f678901234567890abcdef12345678
        '401':
          $ref: '#/components/responses/401'
  /v1/workers_profile/workers/{id}:
    get:
      operationId: showWorkerProfileWorker
      tags:
        - Perfil de la persona
      summary: Obtener perfil de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información completa del perfil de la persona autenticada: datos personales, contrato activo, salario, detalle de contrato, historial de cargo, proveedores de seguridad social y configuraciones de acceso de la empresa.

        **¿Cuándo usar este endpoint?**

        * Cargar el perfil completo de la persona al iniciar sesión como trabajador.
        * Consultar los datos del contrato activo, salario y cargo de la persona autenticada.
        * Verificar qué funcionalidades tiene habilitadas la empresa para sus personas (colillas, certificados, novedades).

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede acceder a su propio perfil.
      responses:
        '200':
          description: Perfil de la persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información completa del perfil de la persona autenticada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
                      active:
                        description: Indica si la persona está activa en la empresa.
                        type: boolean
                        example: true
                      name:
                        description: Nombre de la persona.
                        type: string
                        example: María
                      last_name:
                        description: Apellido de la persona.
                        type: string
                        example: González Pérez
                      picture:
                        description: URL de la foto de perfil de la persona. Retorna null si no tiene foto.
                        type:
                          - string
                          - 'null'
                        example: https://storage.aleluya.com/pictures/worker.jpg
                      payroll_id:
                        description: Identificador único (ID) asignado a la nómina actual de la persona en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: df840cb9-8c31-5293-a476-e726e2e9d759
                      document_type:
                        description: Tipo de documento de identidad de la persona.
                        $ref: '#/components/schemas/WorkerDocumentType'
                      id_number:
                        description: Número de documento de identidad de la persona.
                        type: string
                        example: '1234567890'
                      email:
                        description: Correo electrónico de la persona.
                        type:
                          - string
                          - 'null'
                        example: maria.gonzalez@empresa.com
                      active_user:
                        description: Indica si el usuario de acceso de la persona está activo.
                        type: boolean
                        example: true
                      phone:
                        description: Número de celular de la persona.
                        type:
                          - string
                          - 'null'
                        example: '3001234567'
                      address:
                        description: Dirección de residencia de la persona.
                        type:
                          - string
                          - 'null'
                        example: Calle 123
                      city_address:
                        description: Ciudad de residencia de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la ciudad en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 18ebcabd-87bc-5be0-a0d4-0c5275075f36
                          name:
                            description: Nombre de la ciudad de residencia.
                            type:
                              - string
                              - 'null'
                            example: Medellín
                      department_address:
                        description: Departamento de residencia de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al departamento en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 50c7a870-4fc4-50ac-8b40-3d9359fbe355
                          name:
                            description: Nombre del departamento de residencia.
                            type:
                              - string
                              - 'null'
                            example: Antioquia
                      birthday:
                        description: Fecha de nacimiento de la persona en formato YYYY-MM-DD.
                        type:
                          - string
                          - 'null'
                        example: '1990-04-04'
                      payment_method:
                        description: Método de pago configurado para la persona.
                        $ref: '#/components/schemas/PaymentMethod'
                      pension_reform_2381_transition_regime:
                        description: Indica si la persona hace parte del régimen de transición de la reforma pensional (Ley 2381 de 2024).
                        type: boolean
                        example: false
                      bank:
                        description: Banco asociado a la cuenta bancaria de la persona para el pago de nómina.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al banco en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: d899c4d2-a700-5a87-9fcf-4405e473b9ac
                          name:
                            description: Nombre del banco.
                            type:
                              - string
                              - 'null'
                            example: Banco AV Villas
                      account_number:
                        description: Número de cuenta bancaria de la persona para el pago de nómina.
                        type:
                          - string
                          - 'null'
                        example: '123456789'
                      account_type:
                        description: Tipo de cuenta bancaria de la persona.
                        $ref: '#/components/schemas/AccountType'
                      accumulated_holidays:
                        description: Días de vacaciones acumulados de la persona, expresado como número decimal en formato string.
                        type: string
                        example: '1.25'
                      rest_days:
                        description: Días de descanso de la persona. Los valores corresponden al día de la semana (0 = domingo, 6 = sábado).
                        type: array
                        items:
                          type: string
                          example: '6'
                      terminatable:
                        description: Indica si el contrato activo de la persona puede ser terminado. Retorna null si no tiene contrato activo.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      deleteable:
                        description: Indica si la persona puede ser eliminada de la empresa.
                        type: boolean
                        example: false
                      demo_flag:
                        description: Indica si la persona es un registro de demostración.
                        type: boolean
                        example: false
                      multiple_contracts:
                        description: Indica si la persona tiene más de un contrato registrado.
                        type: boolean
                        example: false
                      finish_registration:
                        description: Indica si la persona completó su registro de datos personales.
                        type: boolean
                        example: true
                      finish_onboarding:
                        description: Indica si la persona completó su proceso de onboarding.
                        type: boolean
                        example: false
                      finish_onboarding_at:
                        description: Fecha en que la persona completó el onboarding en formato YYYY-MM-DD. Retorna null si no ha completado el onboarding.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-15'
                      retention_configuration:
                        description: Indica si la persona tiene una configuración de retención en la fuente activa.
                        type: boolean
                        example: false
                      payroll_retention:
                        description: Indica si la persona tiene retención activa en la nómina.
                        type: boolean
                        example: false
                      city:
                        description: Nombre de la ciudad de trabajo de la persona según su historial de cargo activo.
                        type:
                          - string
                          - 'null'
                        example: Medellín
                      department:
                        description: Nombre del departamento de trabajo de la persona según su historial de cargo activo.
                        type:
                          - string
                          - 'null'
                        example: Antioquia
                      contract_id:
                        description: Identificador único (ID) asignado al contrato activo de la persona en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                      contract_category:
                        description: Categoría del contrato activo de la persona. Null si no tiene contrato activo.
                        oneOf:
                          - $ref: '#/components/schemas/ContractCategory'
                          - type: 'null'
                      initial_day:
                        description: Fecha de inicio del contrato activo en formato YYYY-MM-DD.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del contrato activo en formato YYYY-MM-DD. Retorna null si el contrato es indefinido.
                        type:
                          - string
                          - 'null'
                        example: '2025-12-31'
                      apply_art102_cst:
                        description: Indica si el contrato aplica el artículo 102 del Código Sustantivo del Trabajo.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      term:
                        description: Modalidad del término del contrato (indefinite, fixed_term, obra_labor, etc.).
                        type:
                          - string
                          - 'null'
                        example: indefinite
                      terminated:
                        description: Indica si el contrato está terminado.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      termination:
                        description: Información de la terminación del contrato. Los campos son null si el contrato no tiene terminación registrada.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la terminación en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 014cfe31-92e7-49b7-ac48-ec79b30f58b9
                          date:
                            description: Fecha de terminación del contrato en formato YYYY-MM-DD.
                            type:
                              - string
                              - 'null'
                            example: '2024-06-30'
                          deleteable:
                            description: Indica si la terminación puede ser eliminada.
                            type:
                              - boolean
                              - 'null'
                            example: true
                      wage_id:
                        description: Identificador único (ID) asignado al salario activo en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: 43541d40-259f-52e3-9f78-31f966b0e828
                      wage_category:
                        description: Modalidad del salario activo de la persona.
                        $ref: '#/components/schemas/SalaryCategory'
                      base_salary:
                        description: Valor del salario básico mensual de la persona en pesos colombianos.
                        type: integer
                        example: 1300000
                      remote_work:
                        description: Indica si la persona trabaja de forma remota.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      transport_subsidy:
                        description: Indica si la persona tiene derecho al auxilio de transporte.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      contract_detail:
                        description: Detalle del contrato activo de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 4c13de80-f42f-5620-bd42-9ca3798512f9
                          contributor_subtype:
                            description: 'Subtipo de cotizante de la persona para seguridad social. Valores posibles: no_subtype (sin subtipo), pensioner (pensionado), age_exempt_contributor (cotizante exonerado por edad), qualified_for_pension (con requisitos para pensión), compensated_contributor (cotizante compensado).'
                            type:
                              - string
                              - 'null'
                            enum:
                              - no_subtype
                              - pensioner
                              - age_exempt_contributor
                              - qualified_for_pension
                              - compensated_contributor
                            example: no_subtype
                          initial_day:
                            description: Fecha de inicio del detalle del contrato en formato YYYY-MM-DD.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del detalle del contrato en formato YYYY-MM-DD. Retorna null si no tiene fecha de fin.
                            type:
                              - string
                              - 'null'
                            example: null
                          contract_id:
                            description: Identificador único (ID) asignado al contrato en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                          deleteable:
                            description: Indica si el detalle del contrato puede ser eliminado.
                            type:
                              - boolean
                              - 'null'
                            example: true
                      contract_position_history:
                        description: Historial de cargo activo de la persona, que incluye área, sede y cargo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 7f9a3c1d-2e4b-5f6a-8c9d-0e1f2a3b4c5d
                          initial_day:
                            description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del historial de cargo en formato YYYY-MM-DD. Retorna null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: null
                          contract_id:
                            description: Identificador único (ID) asignado al contrato en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                          area:
                            description: Área de trabajo de la persona según el historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al área en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 096848e6-448b-58b8-a3fe-7704a3d9337b
                              name:
                                description: Nombre del área.
                                type:
                                  - string
                                  - 'null'
                                example: Administrativa
                          location:
                            description: Sede de trabajo de la persona según el historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sede en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                              name:
                                description: Nombre de la sede.
                                type:
                                  - string
                                  - 'null'
                                example: Sede Principal
                          position:
                            description: Cargo de la persona según el historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al cargo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                              name:
                                description: Nombre del cargo.
                                type:
                                  - string
                                  - 'null'
                                example: Analista de nómina
                          deleteable:
                            description: Indica si el historial de cargo puede ser eliminado.
                            type:
                              - boolean
                              - 'null'
                            example: false
                      work_center:
                        description: Centro de trabajo asociado al detalle del contrato activo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                          name:
                            description: Nombre del centro de trabajo con su nivel de riesgo.
                            type:
                              - string
                              - 'null'
                            example: Sede Principal - Riesgo 1 - Mínimo
                          risk_type:
                            description: Nombre legible del tipo de riesgo ARL del centro de trabajo.
                            type:
                              - string
                              - 'null'
                            example: Riesgo 1 - Mínimo
                      risk_type:
                        description: |
                          Código del tipo de riesgo ARL del centro de trabajo.

                          Valores posibles:
                          * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
                          * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
                          * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
                          * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
                          * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)

                          `null` si no tiene centro de trabajo asignado.
                        type:
                          - string
                          - 'null'
                        enum:
                          - risk_1
                          - risk_2
                          - risk_3
                          - risk_4
                          - risk_5
                        example: risk_1
                      high_risk_pension:
                        description: Indica si la persona cotiza pensión de alto riesgo.
                        type: boolean
                        example: false
                      health_provider:
                        description: EPS (entidad promotora de salud) de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la EPS en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name:
                            description: Nombre de la EPS.
                            type:
                              - string
                              - 'null'
                            example: Sura EPS
                      pension_provider:
                        description: Fondo de pensiones de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name:
                            description: Nombre del fondo de pensiones.
                            type:
                              - string
                              - 'null'
                            example: Porvenir
                      severance_provider:
                        description: Fondo de cesantías de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 16881701-ff67-5895-913b-dfdf4ab03797
                          name:
                            description: Nombre del fondo de cesantías.
                            type:
                              - string
                              - 'null'
                            example: Protección
                      area:
                        description: Área de trabajo actual de la persona según su información adicional.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al área en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 096848e6-448b-58b8-a3fe-7704a3d9337b
                          name:
                            description: Nombre del área.
                            type:
                              - string
                              - 'null'
                            example: Administrativa
                      compensation_fund:
                        description: Caja de compensación familiar de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la caja de compensación en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 18f32bf8-a308-55b2-bf8d-347855c7cde2
                          name:
                            description: Nombre de la caja de compensación.
                            type:
                              - string
                              - 'null'
                            example: Comfama
                      cost_center:
                        description: Centro de costos al que pertenece la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de costos en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                          name:
                            description: Nombre del centro de costos.
                            type:
                              - string
                              - 'null'
                            example: Operaciones
                      location:
                        description: Sede de trabajo actual de la persona según su información adicional.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sede en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                          name:
                            description: Nombre de la sede.
                            type:
                              - string
                              - 'null'
                            example: Sede Principal
                      position:
                        description: Cargo actual de la persona según su información adicional.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al cargo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                          name:
                            description: Nombre del cargo.
                            type:
                              - string
                              - 'null'
                            example: Analista de nómina
                      social_security_branch:
                        description: Sucursal de seguridad social asociada a la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sucursal en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name:
                            description: Nombre de la sucursal de seguridad social.
                            type:
                              - string
                              - 'null'
                            example: Sucursal Medellín
                      recurrent_concepts_incomes_total:
                        description: Suma total en pesos colombianos de los conceptos recurrentes de ingresos activos de la persona.
                        type: integer
                        example: 850000
                      recurrent_concepts_deductions_total:
                        description: Suma total en pesos colombianos de los conceptos recurrentes de deducciones activas más los préstamos activos de la persona.
                        type: integer
                        example: 230000
                      company_access:
                        $ref: '#/components/schemas/CompanyAccess'
                      worker_with_benefits:
                        description: Indica si la empresa tiene habilitado el módulo de beneficios para empleados activos.
                        type: boolean
                        example: false
                      workers_handle_novelties:
                        description: Indica si la empresa permite a sus personas solicitar tiempo fuera directamente.
                        type: boolean
                        example: true
                      workers_income_certificate_access:
                        description: Indica si la empresa tiene habilitado el acceso a certificados de ingresos para sus personas.
                        type: boolean
                        example: true
                      workers_labor_certificate_access:
                        description: Indica si la empresa permite a sus personas solicitar certificados laborales.
                        type: boolean
                        example: false
                      workers_payslips_access:
                        description: Indica si la empresa permite a sus personas descargar colillas de pago.
                        type: boolean
                        example: true
              example:
                data:
                  id: 6626a96f-32b2-5890-bc03-af9d8b2854f7
                  active: true
                  name: María
                  last_name: González Pérez
                  picture: https://storage.aleluya.com/pictures/worker.jpg
                  payroll_id: df840cb9-8c31-5293-a476-e726e2e9d759
                  document_type: cc
                  id_number: '1234567890'
                  email: maria.gonzalez@empresa.com
                  active_user: true
                  phone: '3001234567'
                  address: Calle 123
                  city_address:
                    id: 18ebcabd-87bc-5be0-a0d4-0c5275075f36
                    name: Medellín
                  department_address:
                    id: 50c7a870-4fc4-50ac-8b40-3d9359fbe355
                    name: Antioquia
                  birthday: '1990-04-04'
                  payment_method: wire_transfer
                  pension_reform_2381_transition_regime: false
                  bank:
                    id: d899c4d2-a700-5a87-9fcf-4405e473b9ac
                    name: Banco AV Villas
                  account_number: '123456789'
                  account_type: savings_account
                  accumulated_holidays: '1.25'
                  rest_days:
                    - '6'
                    - '0'
                  terminatable: true
                  deleteable: false
                  demo_flag: false
                  multiple_contracts: false
                  finish_registration: true
                  finish_onboarding: false
                  finish_onboarding_at: null
                  retention_configuration: false
                  payroll_retention: false
                  city: Medellín
                  department: Antioquia
                  contract_id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                  contract_category: employee
                  initial_day: '2024-01-01'
                  end_day: null
                  apply_art102_cst: false
                  term: indefinite
                  terminated: false
                  termination:
                    id: null
                    date: null
                    deleteable: null
                  wage_id: 43541d40-259f-52e3-9f78-31f966b0e828
                  wage_category: monthly
                  base_salary: 1300000
                  remote_work: false
                  transport_subsidy: true
                  contract_detail:
                    id: 4c13de80-f42f-5620-bd42-9ca3798512f9
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                    deleteable: true
                  contract_position_history:
                    id: 7f9a3c1d-2e4b-5f6a-8c9d-0e1f2a3b4c5d
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                    area:
                      id: 096848e6-448b-58b8-a3fe-7704a3d9337b
                      name: Administrativa
                    location:
                      id: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                      name: Sede Principal
                    position:
                      id: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                      name: Analista de nómina
                    deleteable: false
                  work_center:
                    id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                    name: Sede Principal - Riesgo 1 - Mínimo
                    risk_type: Riesgo 1 - Mínimo
                  risk_type: risk_1
                  high_risk_pension: false
                  health_provider:
                    id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    name: Sura EPS
                  pension_provider:
                    id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    name: Porvenir
                  severance_provider:
                    id: 16881701-ff67-5895-913b-dfdf4ab03797
                    name: Protección
                  area:
                    id: 096848e6-448b-58b8-a3fe-7704a3d9337b
                    name: Administrativa
                  compensation_fund:
                    id: 18f32bf8-a308-55b2-bf8d-347855c7cde2
                    name: Comfama
                  cost_center:
                    id: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                    name: Operaciones
                  location:
                    id: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                    name: Sede Principal
                  position:
                    id: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                    name: Analista de nómina
                  social_security_branch:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Sucursal Medellín
                  recurrent_concepts_incomes_total: 850000
                  recurrent_concepts_deductions_total: 230000
                  company_access: free
                  worker_with_benefits: false
                  workers_handle_novelties: true
                  workers_income_certificate_access: true
                  workers_labor_certificate_access: false
                  workers_payslips_access: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    patch:
      operationId: updateWorkerProfileWorker
      tags:
        - Perfil de la persona
      summary: Actualizar perfil de la persona
      description: |
        **¿Qué hace este endpoint?**

        Permite a la persona autenticada actualizar su dirección, número de celular y foto de perfil.

        **¿Cuándo usar este endpoint?**

        * Actualizar la dirección de residencia de la persona desde su perfil.
        * Cambiar el número de celular registrado.
        * Subir o reemplazar la foto de perfil.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede actualizar su propio perfil.
        * **Teléfono:** Debe ser un número celular colombiano que comience por 3, seguido de 9 dígitos.
        * **Foto:** Solo se aceptan imágenes en formato PNG o JPG.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                worker:
                  description: Datos del perfil a actualizar.
                  type: object
                  properties:
                    address:
                      description: Dirección de residencia de la persona.
                      type: string
                      example: Calle 123
                    phone:
                      description: Número de celular de la persona. Debe comenzar por 3 y tener 10 dígitos en total.
                      type: string
                      example: '3001234567'
                    picture:
                      description: Información de la foto de perfil de la persona.
                      type: object
                      properties:
                        image:
                          description: Imagen en formato base64 (PNG o JPG).
                          type: string
                          format: base64
                          example: data:image/png;base64,iVBORw0KGgo...
                        name:
                          description: Nombre del archivo de imagen.
                          type: string
                          example: foto_perfil.png
              required:
                - worker
      responses:
        '202':
          description: Perfil actualizado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información actualizada del perfil de la persona.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
                      active:
                        description: Indica si la persona está activa en la empresa.
                        type: boolean
                        example: true
                      name:
                        description: Nombre de la persona.
                        type: string
                        example: María
                      last_name:
                        description: Apellido de la persona.
                        type: string
                        example: González Pérez
                      picture:
                        description: URL de la foto de perfil actualizada. Retorna null si no tiene foto.
                        type:
                          - string
                          - 'null'
                        example: https://storage.aleluya.com/pictures/worker.jpg
                      phone:
                        description: Número de celular actualizado de la persona.
                        type:
                          - string
                          - 'null'
                        example: '3001234567'
                      address:
                        description: Dirección de residencia actualizada de la persona.
                        type:
                          - string
                          - 'null'
                        example: Calle 123
              example:
                data:
                  id: 6626a96f-32b2-5890-bc03-af9d8b2854f7
                  active: true
                  name: María
                  last_name: González Pérez
                  picture: https://storage.aleluya.com/pictures/worker.jpg
                  phone: '3001234567'
                  address: Calle 123
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '422':
          description: Formato de teléfono inválido / Formato de foto inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Formato de teléfono inválido:
                  value:
                    error:
                      - code: '0308'
                        index: 0
                        message: Debes ingresar un número celular válido.
                        object: phone
                Formato de foto inválido:
                  value:
                    error:
                      - code: '0307'
                        index: 0
                        message: La foto debe ser una imagen en formato png o jpg.
                        object: worker
    parameters:
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
  /v1/workers_profile/workers/{worker_id}/folders:
    get:
      operationId: indexWorkerProfileFolders
      tags:
        - Carpetas de la persona
      summary: Listar carpetas de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de carpetas de documentos que la persona autenticada tiene acceso a ver desde su perfil. Solo se incluyen carpetas con `worker_access: true`.

        **¿Cuándo usar este endpoint?**

        * Consultar las carpetas disponibles para la persona antes de acceder a los documentos de cada una.
        * Buscar una carpeta específica por nombre para navegar a su contenido.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propias carpetas.
        * **Visibilidad restringida:** Solo se muestran las carpetas que el administrador ha habilitado para que la persona las vea. Las carpetas con acceso deshabilitado solo son visibles en el perfil de administrador.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca carpetas de documentos por nombre. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Contratos
      responses:
        '200':
          description: Carpetas de la persona / Sin carpetas registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de carpetas de documentos visibles para la persona.
                    type: array
                    items:
                      description: Carpeta de documentos de la persona.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la carpeta en la base de datos.
                          type: string
                          example: d292de70-a803-5e2d-a87f-3ad1128f38fc
                        name:
                          description: Nombre de la carpeta.
                          type: string
                          example: Contratos laborales
                        total_files:
                          description: Número de archivos almacenados en la carpeta.
                          type: integer
                          example: 3
                        created_at:
                          description: Fecha de creación de la carpeta en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-07-03'
                        deleteable:
                          description: Indica si la carpeta puede eliminarse. Es false cuando contiene archivos adjuntos.
                          type: boolean
                          example: false
                  filters:
                    description: Metadatos de paginación y búsqueda aplicados al listado.
                    type: object
                    properties:
                      total_records:
                        description: Total de carpetas que coinciden con el criterio de búsqueda.
                        type: integer
                        example: 2
                      page:
                        description: Página actual de resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de carpetas por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se filtró por nombre.
                        type: string
              examples:
                Carpetas de la persona:
                  value:
                    data:
                      - id: d292de70-a803-5e2d-a87f-3ad1128f38fc
                        name: Contratos laborales
                        total_files: 3
                        created_at: '2024-07-03'
                        deleteable: false
                      - id: b4000992-0c47-54e2-a5d2-26b3ad8bd635
                        name: Seguridad social
                        total_files: 0
                        created_at: '2024-07-03'
                        deleteable: true
                    filters:
                      total_records: 2
                      page: 1
                      per_page: 20
                      search: ''
                Sin carpetas registradas:
                  value:
                    data: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0518c9d8-655b-4952-ac52-fb5800632a58
  /v1/workers_profile/workers/{worker_id}/folders/{id}:
    get:
      operationId: showWorkerProfileFolder
      tags:
        - Carpetas de la persona
      summary: Obtener documentos de una carpeta
      description: |
        **¿Qué hace este endpoint?**

        Retorna el nombre de una carpeta y el listado paginado de documentos que contiene, visibles para la persona autenticada.

        **¿Cuándo usar este endpoint?**

        * Listar los archivos disponibles dentro de una carpeta antes de descargar un documento específico.
        * Buscar un documento dentro de la carpeta por nombre.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar las carpetas de su propio perfil.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca documentos dentro de la carpeta por nombre. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Contrato enero
      responses:
        '200':
          description: Carpeta con documentos / Carpeta vacía
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la carpeta y sus documentos.
                    type: object
                    properties:
                      folder:
                        description: Información de la carpeta solicitada.
                        type: object
                        properties:
                          name:
                            description: Nombre de la carpeta.
                            type: string
                            example: Contratos laborales
                          files:
                            description: Listado de documentos almacenados en la carpeta.
                            type: array
                            items:
                              description: Documento almacenado en la carpeta.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al documento en la base de datos.
                                  type: string
                                  example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                                name:
                                  description: Nombre del archivo del documento.
                                  type: string
                                  example: Contrato_enero_2024.pdf
                                url_file:
                                  description: URL de descarga del documento.
                                  type: string
                                  example: https://storage.aleluya.com/documents/Contrato_enero_2024.pdf
                                created_at:
                                  description: Fecha en que se subió el documento en formato YYYY-MM-DD.
                                  type: string
                                  format: date
                                  example: '2024-01-15'
                  filters:
                    description: Metadatos de paginación y búsqueda aplicados al listado de documentos.
                    type: object
                    properties:
                      total_records:
                        description: Total de documentos que coinciden con el criterio de búsqueda.
                        type: integer
                        example: 3
                      page:
                        description: Página actual de resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de documentos por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se filtró por nombre.
                        type: string
              examples:
                Carpeta con documentos:
                  value:
                    data:
                      folder:
                        name: Contratos laborales
                        files:
                          - id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                            name: Contrato_enero_2024.pdf
                            url_file: https://storage.aleluya.com/documents/Contrato_enero_2024.pdf
                            created_at: '2024-01-15'
                          - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            name: Adicion_salario_julio_2024.pdf
                            url_file: https://storage.aleluya.com/documents/Adicion_salario_julio_2024.pdf
                            created_at: '2024-07-01'
                    filters:
                      total_records: 2
                      page: 1
                      per_page: 20
                      search: ''
                Carpeta vacía:
                  value:
                    data:
                      folder:
                        name: Seguridad social
                        files: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0518c9d8-655b-4952-ac52-fb5800632a58
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la carpeta en la base de datos.
        schema:
          type: string
          example: d292de70-a803-5e2d-a87f-3ad1128f38fc
  /v1/workers_profile/workers/{worker_id}/income_certificate:
    get:
      operationId: showWorkerProfileIncomeCertificate
      tags:
        - Certificados de la persona
      summary: Generar certificado de ingresos y retenciones
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna la URL de descarga del certificado de ingresos y retenciones de la persona autenticada para el año indicado.

        **¿Cuándo usar este endpoint?**

        * Descargar el certificado de ingresos y retenciones para presentarlo ante entidades financieras o para declaración de renta.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede generar su propio certificado de ingresos y retenciones.
        * **Configuración requerida:** La empresa debe tener habilitada la opción de acceso al certificado de ingresos para las personas. Si no está habilitada, el endpoint retorna 403.
        * **Años disponibles:** Solo se pueden generar certificados para los años 2022, 2023, 2024 y 2025.
      parameters:
        - in: query
          name: certificate_year
          required: true
          description: 'Año fiscal para el que se genera el certificado de ingresos y retenciones. Valores válidos: 2022, 2023, 2024, 2025.'
          schema:
            type: integer
            example: 2024
      responses:
        '200':
          description: Certificado generado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del certificado de ingresos y retenciones en formato PDF.
                    type: string
                    example: https://storage.aleluya.com/income_certificate/certificado_2024.pdf
              example:
                file: https://storage.aleluya.com/income_certificate/certificado_2024.pdf
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '422':
          description: Año inválido / Sin información para generar el certificado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Año inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Año es inválido.
                        object: certificate_year
                Sin información para generar el certificado:
                  value:
                    error:
                      - code: '0601'
                        index: 0
                        message: No hay información para generar el archivo.
                        object: file
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: bd1eda77-7d9e-55b5-8a1e-0ffdfb8e2db6
  /v1/workers_profile/workers/{worker_id}/labor_certificate:
    get:
      operationId: showWorkerProfileLaborCertificate
      tags:
        - Certificados de la persona
      summary: Generar certificado laboral
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna la URL de descarga del certificado laboral de la persona autenticada. El certificado puede incluir diferentes modalidades de salario según el parámetro `salary_type`.

        **¿Cuándo usar este endpoint?**

        * Descargar el certificado laboral para presentarlo ante entidades bancarias, arrendadores u otras entidades que requieran constancia de vínculo laboral.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede generar su propio certificado laboral.
        * **Configuración requerida:** La empresa debe tener habilitada la opción de acceso al certificado laboral para las personas. Si no está habilitada, el endpoint retorna 403.
        * **Firma requerida:** La empresa debe tener configurada una firma para certificados laborales. Si no está configurada, el endpoint retorna 422.
        * **Salario omitido:** Si no se envía `salary_type`, el certificado se genera sin información salarial.
      parameters:
        - in: query
          name: salary_type
          required: false
          description: 'Modalidad de salario a incluir en el certificado. Valores posibles: base_salary (salario base), average_salary (salario promedio), average_non_salary_income (salario promedio más promedio de ingresos no salariales), no_salary (sin salario). Si no se envía, se genera el certificado sin salario.'
          schema:
            type: string
            enum:
              - base_salary
              - average_salary
              - average_non_salary_income
              - no_salary
            example: base_salary
      responses:
        '200':
          description: Certificado laboral generado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del certificado laboral en formato PDF.
                    type: string
                    example: https://storage.aleluya.com/labor_certificate/certificado_laboral.pdf
              example:
                file: https://storage.aleluya.com/labor_certificate/certificado_laboral.pdf
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Empresa sin firma configurada para certificados laborales
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '4701'
                    index: 0
                    message: La empresa no tiene configurada una firma para certificados laborales. Un administrador debe agregar esta configuración.
                    object: company_configuration
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: bd1eda77-7d9e-55b5-8a1e-0ffdfb8e2db6
  /v1/workers_profile/workers/{worker_id}/loans:
    get:
      operationId: indexWorkerProfileLoans
      tags:
        - Préstamos de la persona
      summary: Listar préstamos de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de préstamos de la persona autenticada, accesible desde su perfil.

        **¿Cuándo usar este endpoint?**

        * Obtener los préstamos activos e inactivos de la persona para conocer sus descuentos pendientes en nómina.
        * Verificar el saldo, la cuota mensual y las cuotas restantes de cada préstamo.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede ver sus propios préstamos.
      responses:
        '200':
          description: Préstamos registrados / Sin préstamos registrados
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de préstamos de la persona.
                    type: array
                    items:
                      description: Préstamo registrado para la persona.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al préstamo en la base de datos.
                          type: string
                          example: eff368b7-9bff-5531-9c7c-8ec0baf6194c
                        name:
                          description: Nombre descriptivo del préstamo.
                          type: string
                          example: Préstamo educación
                        value:
                          description: Valor total del préstamo en pesos colombianos.
                          type: integer
                          example: 1000000
                        balance:
                          description: Saldo pendiente del préstamo en pesos colombianos.
                          type: integer
                          example: 950000
                        paid_value:
                          description: Valor total pagado hasta la fecha en pesos colombianos.
                          type: integer
                          example: 50000
                        monthly_fee:
                          description: Valor de la cuota mensual descontada en nómina en pesos colombianos.
                          type: integer
                          example: 100000
                        pending_months:
                          description: Número de cuotas mensuales pendientes para saldar el préstamo.
                          type: integer
                          example: 10
                        active:
                          description: Indica si el préstamo está activo y se sigue descontando en nómina.
                          type: boolean
                          example: true
                        period_apply:
                          $ref: '#/components/schemas/ApplicationPeriod'
                        payroll_concept_id:
                          description: Identificador único (ID) del concepto de nómina asociado al descuento del préstamo.
                          type: string
                          example: eff368b7-9bff-5531-9c7c-8ec0baf6194c
                        deleteable:
                          description: Indica si el préstamo puede eliminarse.
                          type: boolean
                          example: false
                        date:
                          description: Fecha de creación del préstamo en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-07-03'
              examples:
                Préstamos registrados:
                  value:
                    data:
                      - id: eff368b7-9bff-5531-9c7c-8ec0baf6194c
                        name: Préstamo educación
                        value: 1000000
                        balance: 950000
                        paid_value: 50000
                        monthly_fee: 100000
                        pending_months: 10
                        active: true
                        period_apply: all_periods
                        payroll_concept_id: eff368b7-9bff-5531-9c7c-8ec0baf6194c
                        deleteable: false
                        date: '2024-07-03'
                Sin préstamos registrados:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/workers_profile/workers/{worker_id}/novelty_requests:
    get:
      operationId: indexWorkerProfileNoveltyRequests
      tags:
        - Solicitudes de novedad de la persona
      summary: Listar solicitudes de novedad
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de solicitudes de novedad de la persona autenticada. Solo retorna resultados cuando se aplica un término de búsqueda por nombre de concepto.

        **¿Cuándo usar este endpoint?**

        * Consultar el historial de solicitudes de novedad enviadas por la persona (vacaciones, incapacidades, etc.).
        * Filtrar solicitudes por estado para hacer seguimiento de las pendientes o aprobadas.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propias solicitudes de novedad.
        * **Configuración requerida:** La empresa debe tener habilitada la opción de que las personas gestionen sus propias novedades. Si no está habilitada, el endpoint retorna 403.
        * **Búsqueda obligatoria:** Sin el parámetro `search`, el endpoint retorna un listado vacío.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca solicitudes de novedad por nombre del concepto de nómina. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Incapacidad
        - in: query
          name: filter
          required: false
          description: 'Filtra solicitudes por estado. Valores posibles: pending (pendiente), approved (aprobada), rejected (rechazada).'
          schema:
            type: string
            enum:
              - pending
              - approved
              - rejected
            example: pending
      responses:
        '200':
          description: Solicitudes de novedad encontradas / Sin resultados
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del listado de solicitudes de novedad.
                    type: object
                    properties:
                      novelty_requests:
                        description: Listado de solicitudes de novedad de la persona.
                        type: array
                        items:
                          description: Solicitud de novedad registrada por la persona.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                              type: string
                              example: 1453199e-dbd7-5ab5-ac75-5e4f3ac44340
                            worker_id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            worker_name:
                              description: Nombre completo de la persona que realizó la solicitud.
                              type: string
                              example: María González Pérez
                            contract_category:
                              $ref: '#/components/schemas/ContractCategory'
                            initial_day:
                              description: Fecha de inicio de la novedad en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-15'
                            end_day:
                              description: Fecha de fin de la novedad en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-20'
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina asociado a la solicitud en la base de datos.
                              type: string
                              example: eb5bb336-448d-5078-ac26-4bc7a858382b
                            payroll_concept_name:
                              description: Nombre del concepto de nómina asociado a la solicitud (por ejemplo, Incapacidad general, Vacaciones disfrutadas).
                              type: string
                              example: Incapacidad general
                            comment:
                              description: Comentario adicional ingresado por la persona al crear la solicitud. Puede ser null si no se ingresó comentario.
                              type:
                                - string
                                - 'null'
                              example: Adjunto certificado médico
                            days:
                              description: Número de días de la novedad calculados entre la fecha de inicio y fin.
                              type: integer
                              example: 6
                            status:
                              $ref: '#/components/schemas/NoveltyRequestStatus'
                            evidence:
                              description: URL del archivo adjunto como soporte de la solicitud. Puede ser null si no se adjuntó evidencia.
                              type:
                                - string
                                - 'null'
                              example: https://storage.aleluya.com/novelty_requests/certificado.pdf
                  filters:
                    description: Metadatos de paginación y filtros aplicados al listado.
                    type: object
                    properties:
                      total_records:
                        description: Total de solicitudes que coinciden con el criterio de búsqueda.
                        type: integer
                        example: 2
                      page:
                        description: Página actual de resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de solicitudes por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se filtró.
                        type: string
                      filter:
                        description: Filtro de estado aplicado. Retorna null si no se filtró por estado.
                        type:
                          - string
                          - 'null'
                        example: pending
              examples:
                Solicitudes encontradas:
                  value:
                    data:
                      novelty_requests:
                        - id: 1453199e-dbd7-5ab5-ac75-5e4f3ac44340
                          worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name: María González Pérez
                          contract_category: employee
                          initial_day: '2024-01-15'
                          end_day: '2024-01-20'
                          payroll_concept_id: eb5bb336-448d-5078-ac26-4bc7a858382b
                          payroll_concept_name: Incapacidad general
                          comment: Adjunto certificado médico
                          days: 6
                          status: pending
                          evidence: null
                        - id: 61672985-5fd9-5fae-b253-8b5ae4477306
                          worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name: María González Pérez
                          contract_category: employee
                          initial_day: '2024-02-01'
                          end_day: '2024-02-10'
                          payroll_concept_id: d2af4701-fde6-5aae-a5e4-42fa12b8c661
                          payroll_concept_name: Vacaciones disfrutadas
                          comment: null
                          days: 10
                          status: approved
                          evidence: https://storage.aleluya.com/novelty_requests/certificado.pdf
                    filters:
                      total_records: 2
                      page: 1
                      per_page: 20
                      search: Incapacidad
                      filter: null
                Sin resultados:
                  value:
                    data:
                      novelty_requests: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: xyz
                      filter: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    post:
      operationId: createWorkerProfileNoveltyRequest
      tags:
        - Solicitudes de novedad de la persona
      summary: Crear solicitud de novedad
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva solicitud de novedad para la persona autenticada (incapacidad, vacaciones, permiso, etc.). La solicitud queda en estado `pending` hasta que un administrador la apruebe o rechace.

        **¿Cuándo usar este endpoint?**

        * Registrar una solicitud de ausencia o novedad para que el administrador la revise antes de aplicarla en nómina.
        * Adjuntar soporte documental (certificado médico, etc.) al crear la solicitud.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede crear solicitudes de novedad para sí misma.
        * **Configuración requerida:** La empresa debe tener habilitada la opción de que las personas gestionen sus propias novedades.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                payroll_concept_id:
                  description: Identificador único (ID) del concepto de nómina que representa el tipo de novedad a solicitar.
                  type: string
                  example: eb5bb336-448d-5078-ac26-4bc7a858382b
                initial_day:
                  description: Fecha de inicio de la novedad en formato YYYY-MM-DD.
                  type: string
                  format: date
                  example: '2024-01-15'
                end_day:
                  description: Fecha de fin de la novedad en formato YYYY-MM-DD.
                  type: string
                  format: date
                  example: '2024-01-20'
                comment:
                  description: Comentario o justificación adicional para la solicitud.
                  type: string
                  example: Adjunto certificado médico del especialista
                evidence:
                  description: Archivo PDF o imagen como soporte de la solicitud (certificado médico, etc.).
                  type: string
                  format: binary
              required:
                - payroll_concept_id
                - initial_day
                - end_day
      responses:
        '200':
          description: Solicitud de novedad creada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la solicitud de novedad creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                        type: string
                        example: ecd219a6-c1cc-486c-b635-0c7179b20187
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name:
                        description: Nombre completo de la persona que realizó la solicitud.
                        type: string
                        example: María González Pérez
                      contract_category:
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio de la novedad en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-15'
                      end_day:
                        description: Fecha de fin de la novedad en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-20'
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina asociado en la base de datos.
                        type: string
                        example: eb5bb336-448d-5078-ac26-4bc7a858382b
                      payroll_concept_name:
                        description: Nombre del concepto de nómina asociado a la solicitud.
                        type: string
                        example: Incapacidad general
                      comment:
                        description: Comentario ingresado por la persona. Puede ser null si no se ingresó.
                        type:
                          - string
                          - 'null'
                        example: Adjunto certificado médico del especialista
                      days:
                        description: Número de días de la novedad calculados entre la fecha de inicio y fin.
                        type: integer
                        example: 6
                      status:
                        description: Estado inicial de la solicitud al momento de crearla. Siempre retorna `pending`.
                        type: string
                        example: pending
                      evidence:
                        description: URL del archivo adjunto como soporte de la solicitud. Puede ser null si no se adjuntó evidencia.
                        type:
                          - string
                          - 'null'
                        example: null
              example:
                data:
                  id: ecd219a6-c1cc-486c-b635-0c7179b20187
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  worker_name: María González Pérez
                  contract_category: employee
                  initial_day: '2024-01-15'
                  end_day: '2024-01-20'
                  payroll_concept_id: eb5bb336-448d-5078-ac26-4bc7a858382b
                  payroll_concept_name: Incapacidad general
                  comment: Adjunto certificado médico del especialista
                  days: 6
                  status: pending
                  evidence: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '422':
          description: Fechas inválidas / Validación fallida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Fechas inválidas:
                  value:
                    error:
                      - code: '6201'
                        index: 0
                        message: El formato del initial_day es inválido.
                        object: novelty_request
                Validación fallida:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Día inicial no puede estar en blanco.
                        object: initial_day
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/workers_profile/workers/{worker_id}/novelty_requests/{id}:
    get:
      operationId: showWorkerProfileNoveltyRequest
      tags:
        - Solicitudes de novedad de la persona
      summary: Obtener solicitud de novedad
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de una solicitud de novedad específica de la persona autenticada.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado actual de una solicitud específica (pendiente, aprobada, rechazada).
        * Obtener los datos completos de una solicitud antes de editarla o eliminarla.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propias solicitudes de novedad.
      responses:
        '200':
          description: Detalle de la solicitud de novedad
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la solicitud de novedad.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                        type: string
                        example: 61672985-5fd9-5fae-b253-8b5ae4477306
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name:
                        description: Nombre completo de la persona que realizó la solicitud.
                        type: string
                        example: María González Pérez
                      contract_category:
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio de la novedad en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-15'
                      end_day:
                        description: Fecha de fin de la novedad en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-20'
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina asociado a la solicitud en la base de datos.
                        type: string
                        example: d2af4701-fde6-5aae-a5e4-42fa12b8c661
                      payroll_concept_name:
                        description: Nombre del concepto de nómina asociado a la solicitud.
                        type: string
                        example: Vacaciones disfrutadas
                      comment:
                        description: Comentario ingresado por la persona al crear la solicitud. Puede ser null si no se ingresó comentario.
                        type:
                          - string
                          - 'null'
                        example: Adjunto certificado médico
                      days:
                        description: Número de días de la novedad calculados entre la fecha de inicio y fin.
                        type: integer
                        example: 6
                      status:
                        $ref: '#/components/schemas/NoveltyRequestStatus'
                      evidence:
                        description: URL del archivo adjunto como soporte de la solicitud. Puede ser null si no se adjuntó evidencia.
                        type:
                          - string
                          - 'null'
                        example: https://storage.aleluya.com/novelty_requests/certificado.pdf
              example:
                data:
                  id: 61672985-5fd9-5fae-b253-8b5ae4477306
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  worker_name: María González Pérez
                  contract_category: employee
                  initial_day: '2024-01-15'
                  end_day: '2024-01-20'
                  payroll_concept_id: d2af4701-fde6-5aae-a5e4-42fa12b8c661
                  payroll_concept_name: Vacaciones disfrutadas
                  comment: null
                  days: 6
                  status: pending
                  evidence: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateWorkerProfileNoveltyRequest
      tags:
        - Solicitudes de novedad de la persona
      summary: Actualizar solicitud de novedad
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los datos de una solicitud de novedad de la persona autenticada. Solo pueden modificarse solicitudes que estén en estado `pending`.

        **¿Cuándo usar este endpoint?**

        * Corregir las fechas o el comentario de una solicitud antes de que sea revisada por el administrador.
        * Reemplazar o eliminar el archivo de soporte adjunto a la solicitud.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede modificar sus propias solicitudes de novedad.
        * **Solo solicitudes pendientes:** No se pueden modificar solicitudes en estado `approved`. El campo `status` del GET indica si la solicitud es editable.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                initial_day:
                  description: Nueva fecha de inicio de la novedad en formato YYYY-MM-DD.
                  type: string
                  format: date
                  example: '2024-01-15'
                end_day:
                  description: Nueva fecha de fin de la novedad en formato YYYY-MM-DD.
                  type: string
                  format: date
                  example: '2024-01-20'
                comment:
                  description: Nuevo comentario o justificación de la solicitud.
                  type: string
                  example: Adjunto nuevo certificado médico
                evidence:
                  description: Nuevo archivo PDF o imagen como soporte. Si se envía una cadena de texto vacía, elimina el archivo existente.
                  type: string
                  format: binary
      responses:
        '200':
          description: Solicitud de novedad actualizada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la solicitud de novedad.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                        type: string
                        example: 61672985-5fd9-5fae-b253-8b5ae4477306
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name:
                        description: Nombre completo de la persona que realizó la solicitud.
                        type: string
                        example: María González Pérez
                      contract_category:
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio actualizada en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-15'
                      end_day:
                        description: Fecha de fin actualizada en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-20'
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina asociado en la base de datos.
                        type: string
                        example: d2af4701-fde6-5aae-a5e4-42fa12b8c661
                      payroll_concept_name:
                        description: Nombre del concepto de nómina asociado a la solicitud.
                        type: string
                        example: Vacaciones disfrutadas
                      comment:
                        description: Comentario actualizado de la solicitud. Puede ser null si no se ingresó comentario.
                        type:
                          - string
                          - 'null'
                        example: Adjunto nuevo certificado médico
                      days:
                        description: Número de días de la novedad calculados entre la fecha de inicio y fin.
                        type: integer
                        example: 6
                      status:
                        description: 'Estado actual de la solicitud tras la actualización. Valores posibles: pending (pendiente), approved (aprobada), rejected (rechazada).'
                        type: string
                        enum:
                          - pending
                          - approved
                          - rejected
                        example: pending
                      evidence:
                        description: URL del archivo adjunto actualizado. Puede ser null si no hay archivo adjunto.
                        type:
                          - string
                          - 'null'
                        example: https://storage.aleluya.com/novelty_requests/certificado.pdf
              example:
                data:
                  id: 61672985-5fd9-5fae-b253-8b5ae4477306
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  worker_name: María González Pérez
                  contract_category: employee
                  initial_day: '2024-01-15'
                  end_day: '2024-01-20'
                  payroll_concept_id: d2af4701-fde6-5aae-a5e4-42fa12b8c661
                  payroll_concept_name: Vacaciones disfrutadas
                  comment: Adjunto nuevo certificado médico
                  days: 6
                  status: pending
                  evidence: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Solicitud aprobada no modificable / Fechas fuera del contrato actual
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Solicitud aprobada no modificable:
                  value:
                    error:
                      - code: '6204'
                        index: 0
                        message: No se pueden modificar los atributos de una solicitud aprobada.
                        object: novelty_request
                Fechas fuera del contrato actual:
                  value:
                    error:
                      - code: '0710'
                        index: 0
                        message: Solo puedes editar solicitudes del contrato actual.
                        object: contract
    delete:
      operationId: destroyWorkerProfileNoveltyRequest
      tags:
        - Solicitudes de novedad de la persona
      summary: Eliminar solicitud de novedad
      description: |
        **¿Qué hace este endpoint?**

        Elimina una solicitud de novedad de la persona autenticada.

        **¿Cuándo usar este endpoint?**

        * Cancelar una solicitud de novedad enviada por error antes de que sea revisada.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede eliminar sus propias solicitudes de novedad.
        * **Novedad ya aplicada:** Si la solicitud tiene una novedad asociada que ya fue procesada en nómina, no puede eliminarse.
      responses:
        '200':
          description: Solicitud de novedad eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La solicitud de tiempo fuera ha sido eliminada.
              example:
                data:
                  message: La solicitud de tiempo fuera ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Novedad asociada no eliminable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '6203'
                    index: 0
                    message: No se puede eliminar la novedad asociada a esta solicitud.
                    object: novelty_request
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
        schema:
          type: string
          example: 61672985-5fd9-5fae-b253-8b5ae4477306
  /v1/workers_profile/workers/{worker_id}/payments_history:
    get:
      operationId: showWorkerProfilePaymentsHistory
      tags:
        - Historial de pagos de la persona
      summary: Obtener historial de pagos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial de pagos de nómina de la persona autenticada. Puede devolver los datos en formato JSON paginado o generar un archivo XLSX descargable de forma síncrona o asíncrona.

        **¿Cuándo usar este endpoint?**

        * Consultar los pagos de nómina recibidos por la persona, con montos de salario, otros ingresos y deducciones por periodo.
        * Generar un archivo Excel con el historial completo para descarga directa o procesamiento posterior.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar su propio historial de pagos.
        * **Periodo actual excluido:** El periodo de nómina en curso no se incluye en el historial.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: file_format
          required: false
          description: Formato del archivo a generar. Si se envía `xlsx`, retorna una URL de descarga en lugar del listado JSON.
          schema:
            type: string
            enum:
              - xlsx
            example: xlsx
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: Historial en JSON / Archivo XLSX listo / Archivo en proceso
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Contenido principal de la respuesta. Es un arreglo de pagos en respuesta JSON, o un objeto con `message` cuando el archivo XLSX se genera de forma asíncrona.
                    oneOf:
                      - description: Listado de pagos de nómina de la persona. Presente solo en respuesta JSON (sin `file_format`).
                        type: array
                        items:
                          description: Resumen de pago de un periodo de nómina.
                          type: object
                          properties:
                            payroll_id:
                              description: Identificador único (ID) asignado a la nómina en la base de datos.
                              type: string
                              example: 60fc2262-b847-5ee9-aefb-9b1b2d61059c
                            initial_day:
                              description: Fecha de inicio del periodo de nómina en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de nómina en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-31'
                            salary:
                              description: Valor del salario base liquidado en el periodo en pesos colombianos.
                              type: integer
                              example: 1850000
                            other_income:
                              description: Suma de otros ingresos adicionales (bonificaciones, auxilios, horas extras, etc.) en pesos colombianos.
                              type: integer
                              example: 282000
                            deductions_retentions:
                              description: Suma de deducciones y retenciones aplicadas en el periodo (salud, pensión, retención en la fuente, etc.) en pesos colombianos.
                              type: integer
                              example: 20000
                            worker_payment:
                              description: Valor neto pagado a la persona en el periodo en pesos colombianos (salario + otros ingresos - deducciones).
                              type: integer
                              example: 2112000
                            payslip_options:
                              description: Opciones de colilla disponibles para este periodo. Puede ser un arreglo vacío si no hay colillas generadas.
                              type: array
                              items:
                                description: Opción de tipo de colilla disponible para el periodo.
                                type: object
                                properties:
                                  label:
                                    description: Nombre legible del tipo de colilla.
                                    type: string
                                    example: Nómina
                                  value:
                                    description: Valor en código del tipo de colilla, usado para solicitar la descarga.
                                    type: string
                                    example: payroll
                      - description: Confirmación de encolamiento del archivo XLSX. Presente cuando se envía `async=true`.
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación cuando el archivo se genera de forma asíncrona.
                            type: string
                            example: Procesando
                  filters:
                    description: Metadatos de paginación del historial. Presente solo en respuesta JSON.
                    type: object
                    properties:
                      total_records:
                        description: Total de periodos de nómina en el historial.
                        type: integer
                        example: 12
                      page:
                        description: Página actual de resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de periodos por página.
                        type: integer
                        example: 20
                  file:
                    description: URL de descarga del archivo XLSX generado. Presente solo cuando se solicita `file_format=xlsx` sin `async`.
                    type: string
                    example: https://storage.aleluya.com/payments_history/historial_de_pagos.xlsx
              examples:
                Historial en JSON:
                  value:
                    data:
                      - payroll_id: 60fc2262-b847-5ee9-aefb-9b1b2d61059c
                        initial_day: '2024-01-01'
                        end_day: '2024-01-31'
                        salary: 1850000
                        other_income: 282000
                        deductions_retentions: 20000
                        worker_payment: 2112000
                        payslip_options:
                          - label: Nómina
                            value: payroll
                          - label: Liquidación
                            value: termination
                      - payroll_id: 1da02c05-fe40-5d6e-8972-1be0ca9795f9
                        initial_day: '2023-12-01'
                        end_day: '2023-12-31'
                        salary: 1850000
                        other_income: 0
                        deductions_retentions: 0
                        worker_payment: 1850000
                        payslip_options: []
                    filters:
                      total_records: 12
                      page: 1
                      per_page: 20
                Archivo XLSX listo:
                  value:
                    file: https://storage.aleluya.com/payments_history/historial_de_pagos.xlsx
                Archivo en proceso:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
  /v1/workers_profile/workers/{worker_id}/payslips/{id}:
    get:
      operationId: showWorkerProfilePayslip
      tags:
        - Colillas de la persona
      summary: Obtener colilla de la persona
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna la colilla de pago de una nómina de la persona autenticada.
        Soporta modo síncrono (retorna la URL inmediatamente) y asíncrono (encola
        la generación y notifica el resultado vía Firebase).

        **¿Cuándo usar este endpoint?**

        * Descargar la colilla de una nómina específica de la persona autenticada.
        * Consultar la colilla al cierre de un periodo para validar el pago neto liquidado.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propias colillas.
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: false
          name: payslip_type
          schema:
            $ref: '#/components/schemas/PayslipType'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga de la colilla generada.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. La colilla se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/payrolls/{payroll_id}/payslips`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga de la colilla generada.
                        type: string
                        example: https://storage.aleluya.com/payslips/colilla_enero_2024.pdf
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que la colilla está siendo procesada en segundo plano.
                            type: string
                            example: Procesando
              examples:
                Colilla síncrona:
                  value:
                    file: https://storage.aleluya.com/payslips/colilla_enero_2024.pdf
                Colilla asíncrona:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de colilla inválido / Error al generar el archivo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Tipo de colilla inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Tipo de colilla es inválido.
                        object: payslip_type
                Error al generar el archivo:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: No es posible generar el archivo.
                        object: file
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: df840cb9-8c31-5293-a476-e726e2e9d759
  /v1/workers_profile/workers/{worker_id}/recurrent_concepts:
    get:
      operationId: indexWorkerProfileRecurrentConcepts
      tags:
        - Conceptos recurrentes de la persona
      summary: Listar conceptos recurrentes de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de conceptos recurrentes (ingresos, deducciones y deudas) configurados
        para la persona autenticada.

        **¿Cuándo usar este endpoint?**

        * Conocer los auxilios o bonificaciones recurrentes que se suman al salario en cada periodo.
        * Verificar qué deducciones se están descontando automáticamente en la nómina de la persona.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propios conceptos recurrentes.
      parameters:
        - in: query
          name: type
          description: Filtrar por categoría del concepto recurrente.
          required: false
          schema:
            $ref: '#/components/schemas/RecurrentConceptCategory'
        - in: query
          name: filter
          description: 'Filtrar por estado del concepto. Valores posibles: active (activos), inactive (inactivos).'
          required: false
          schema:
            type: string
            enum:
              - active
              - inactive
            example: active
        - in: query
          name: search
          description: Busca conceptos recurrentes por nombre. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          required: false
          schema:
            type: string
            example: auxilio
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
      responses:
        '200':
          description: Conceptos configurados / Sin conceptos configurados
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de conceptos recurrentes de la persona.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al concepto recurrente en la base de datos.
                          type: string
                          example: 2bbf2ded-e9ad-4081-a7cd-a1e7b210fc80
                        active:
                          description: Indica si el concepto recurrente está activo y se aplica en la nómina.
                          type: boolean
                          example: true
                        monthly_value:
                          description: Valor mensual del concepto en pesos colombianos.
                          type: integer
                          example: 500000
                        concept_type:
                          description: 'Tipo de cálculo del concepto. Valores posibles: fixed (valor fijo), proportional (proporcional a días trabajados).'
                          type: string
                          example: proportional
                        payroll_concept_id:
                          description: Identificador único (ID) del concepto de nómina asociado en la base de datos.
                          type: string
                          example: 8f3e0645-f854-4f45-b212-eb5b6f1f441d
                        period_apply:
                          $ref: '#/components/schemas/ApplicationPeriod'
                        name:
                          description: Nombre del concepto de nómina asociado.
                          type: string
                          example: Auxilio de alimentación
                        category:
                          description: |
                            Categoría del concepto recurrente.

                            Valores posibles:

                            * `salary_income` — Ingreso salarial
                            * `non_salary_income` — Ingreso no salarial
                            * `occasional_non_salary_income` — Ingreso no salarial ocasional
                            * `deductions` — Deducción
                          type: string
                          enum:
                            - non_salary_income
                            - salary_income
                            - deductions
                            - occasional_non_salary_income
                          example: non_salary_income
                  filters:
                    description: Información de paginación y filtros aplicados al listado.
                    type: object
                    properties:
                      filter:
                        description: Filtro de estado aplicado al listado.
                        type: string
                        example: All
                      page:
                        description: Página actual del listado.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de conceptos por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna una cadena vacía si no se filtró por nombre.
                        type: string
                      total_records:
                        description: Número total de conceptos que coinciden con los filtros.
                        type: integer
                        example: 4
              examples:
                Conceptos configurados:
                  value:
                    data:
                      - id: 2bbf2ded-e9ad-4081-a7cd-a1e7b210fc80
                        active: true
                        monthly_value: 500000
                        concept_type: fixed
                        payroll_concept_id: 8f3e0645-f854-4f45-b212-eb5b6f1f441d
                        period_apply: all_periods
                        name: Auxilio de alimentación
                        category: non_salary_income
                    filters:
                      filter: All
                      page: 1
                      per_page: 20
                      search: ''
                      total_records: 1
                Sin conceptos configurados:
                  value:
                    data: []
                    filters:
                      filter: All
                      page: 1
                      per_page: 20
                      search: ''
                      total_records: 0
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/workers_profile/workers/{worker_id}/view_details/{id}:
    get:
      operationId: showWorkerProfileViewDetails
      tags:
        - Nómina de la persona
      summary: Obtener detalle de nómina de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle completo de una nómina para la persona autenticada, organizado en tres secciones: encabezado (datos del periodo, empresa y persona), detalle de colilla (ingresos, deducciones y días trabajados) y seguridad social y parafiscales.

        **¿Cuándo usar este endpoint?**

        * Mostrar el desglose completo de una nómina específica desde el perfil de la persona.
        * Obtener los valores de salario base, novedades, retenciones y aportes de seguridad social de una nómina.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propias nóminas.
        * **Tipo de contrato:** Solo aplica para contratos de tipo empleado, aprendiz o independiente. Los contratos de tipo contratista retornan 422.
      responses:
        '200':
          description: Detalle de la nómina de la persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle completo de la nómina organizado en secciones.
                    type: object
                    properties:
                      header:
                        description: Información de encabezado de la nómina con datos del periodo, empresa y persona.
                        type: object
                        properties:
                          company:
                            description: Datos de identificación de la empresa.
                            type: object
                            properties:
                              name:
                                description: Nombre o razón social de la empresa.
                                type: string
                                example: Empresa de Prueba S.A.S.
                              document_type:
                                $ref: '#/components/schemas/CompanyDocumentType'
                              id_number:
                                description: Número de documento de la empresa.
                                type: string
                                example: '900123001'
                          worker:
                            description: Datos de identificación de la persona.
                            type: object
                            properties:
                              name:
                                description: Nombre completo de la persona.
                                type: string
                                example: Juan Pérez
                              document_type:
                                $ref: '#/components/schemas/WorkerDocumentType'
                              id_number:
                                description: Número de documento de la persona.
                                type: string
                                example: '1234567890'
                              contract_category:
                                description: Categoría del contrato de la persona en texto legible (ej. Empleado, Aprendiz).
                                type: string
                                example: Empleado
                          period:
                            description: Información del periodo de la nómina.
                            type: object
                            properties:
                              period_payment:
                                description: Rango de fechas del periodo de pago.
                                type: object
                                properties:
                                  initial_day:
                                    description: Fecha de inicio del periodo en formato YYYY-MM-DD.
                                    type: string
                                    format: date
                                    example: '2024-01-01'
                                  end_day:
                                    description: Fecha de fin del periodo en formato YYYY-MM-DD.
                                    type: string
                                    format: date
                                    example: '2024-01-31'
                              worked_days:
                                description: Número de días trabajados en el periodo.
                                type: integer
                                example: 30
                          payroll_options:
                            description: Indicadores de qué secciones tiene disponibles esta nómina para mostrar.
                            type: object
                            properties:
                              payslip_detail:
                                description: Indica si la nómina tiene detalle de colilla disponible.
                                type: boolean
                                example: true
                              social_security_and_parafiscals:
                                description: Indica si la nómina tiene información de seguridad social y parafiscales disponible.
                                type: boolean
                                example: true
                              social_benefits_provisions:
                                description: Indica si la nómina tiene provisiones de prestaciones sociales disponibles.
                                type: boolean
                                example: false
                              payroll_retention:
                                description: Indica si la nómina tiene retención en la fuente disponible.
                                type: boolean
                                example: false
                              termination:
                                description: Indica si la nómina corresponde a una liquidación de contrato.
                                type: boolean
                                example: false
                              social_benefits:
                                description: Indica si la nómina tiene prestaciones sociales disponibles.
                                type: boolean
                                example: false
                      payslip_detail:
                        description: Detalle de la colilla de pago con ingresos, días trabajados, salario base, novedades y deducciones.
                        type: object
                        properties:
                          payment_summary:
                            description: Resumen de pagos totales de la nómina.
                            type: object
                            properties:
                              data:
                                description: Líneas del resumen de pago con nombre y valor.
                                type: array
                                items:
                                  description: Línea del resumen de pago.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta de la línea del resumen.
                                      type: string
                                      example: Total neto a pagar
                                    value:
                                      description: Valor en pesos colombianos de la línea del resumen.
                                      type: integer
                                      example: 1300000
                                example:
                                  - name: Total neto a pagar
                                    value: 1300000
                              comments:
                                description: Comentarios adicionales del resumen de pago. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          worked_days:
                            description: Detalle de días trabajados en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de días trabajados.
                                type: array
                                items:
                                  description: Línea del detalle de días.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta de la línea de días.
                                      type: string
                                      example: Días del período
                                    value:
                                      description: Valor numérico de la línea de días.
                                      type: integer
                                      example: 30
                                example:
                                  - name: Días del período
                                    value: 30
                              comments:
                                description: Comentarios adicionales de días trabajados. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          base_salary:
                            description: Detalle del salario base de la persona en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de salario base.
                                type: array
                                items:
                                  description: Línea del detalle de salario base.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta de la línea de salario.
                                      type: string
                                      example: Salario
                                    monthly_value:
                                      description: Valor mensual del concepto en pesos colombianos.
                                      type: integer
                                      example: 1300000
                                    worked_days:
                                      description: Días trabajados aplicados al cálculo del salario.
                                      type: integer
                                      example: 30
                                    value:
                                      description: Valor calculado para el periodo en pesos colombianos.
                                      type: integer
                                      example: 1300000
                                example:
                                  - name: Salario
                                    monthly_value: 1300000
                                    worked_days: 30
                                    value: 1300000
                              comments:
                                description: Comentarios con fórmulas o aclaraciones sobre el cálculo del salario base.
                                type: array
                                items:
                                  description: Texto de comentario o fórmula de cálculo.
                                  type: string
                                  example: Fórmula = Valor mensual * Días trabajados / 30 Días
                                example:
                                  - Fórmula = Valor mensual * Días trabajados / 30 Días
                          overtime:
                            description: Detalle de horas extras y recargos en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de horas extras. Retorna arreglo vacío si no hay horas extras.
                                type: array
                                items:
                                  description: Línea del detalle de horas extras.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de hora extra o recargo.
                                      type: string
                                      example: Hora extra diurna
                                    value:
                                      description: Valor calculado en pesos colombianos.
                                      type: integer
                                      example: 15000
                                example: []
                              comments:
                                description: Comentarios adicionales de horas extras. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          holidays:
                            description: Detalle de vacaciones liquidadas en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de vacaciones. Retorna arreglo vacío si no hay vacaciones.
                                type: array
                                items:
                                  description: Línea del detalle de vacaciones.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de vacación.
                                      type: string
                                      example: Vacaciones disfrutadas
                                    value:
                                      description: Valor calculado en pesos colombianos.
                                      type: integer
                                      example: 650000
                                example: []
                              comments:
                                description: Comentarios adicionales de vacaciones. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          incapacities:
                            description: Detalle de incapacidades en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de incapacidades. Retorna arreglo vacío si no hay incapacidades.
                                type: array
                                items:
                                  description: Línea del detalle de incapacidad.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de incapacidad.
                                      type: string
                                      example: Incapacidad laboral
                                    value:
                                      description: Valor calculado en pesos colombianos.
                                      type: integer
                                      example: 45000
                                example: []
                              comments:
                                description: Comentarios adicionales de incapacidades. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          licenses:
                            description: Detalle de licencias en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de licencias. Retorna arreglo vacío si no hay licencias.
                                type: array
                                items:
                                  description: Línea del detalle de licencia.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de licencia.
                                      type: string
                                      example: Licencia de maternidad
                                    value:
                                      description: Valor calculado en pesos colombianos.
                                      type: integer
                                      example: 1300000
                                example: []
                              comments:
                                description: Comentarios adicionales de licencias. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          additional_incomes:
                            description: Detalle de ingresos adicionales (bonificaciones, comisiones, etc.) en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de ingresos adicionales. Retorna arreglo vacío si no hay ingresos adicionales.
                                type: array
                                items:
                                  description: Línea del detalle de ingreso adicional.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de ingreso adicional.
                                      type: string
                                      example: Bonificación
                                    value:
                                      description: Valor calculado en pesos colombianos.
                                      type: integer
                                      example: 200000
                                example: []
                              comments:
                                description: Comentarios adicionales de ingresos adicionales. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          retentions:
                            description: Detalle de retenciones en la fuente aplicadas en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de retenciones. Retorna arreglo vacío si no hay retenciones.
                                type: array
                                items:
                                  description: Línea del detalle de retención.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de retención.
                                      type: string
                                      example: Retención en la fuente
                                    value:
                                      description: Valor descontado en pesos colombianos.
                                      type: integer
                                      example: 50000
                                example: []
                              comments:
                                description: Comentarios adicionales de retenciones. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          social_security_retentions:
                            description: Detalle de descuentos de seguridad social a cargo del empleado en el periodo.
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de descuentos de seguridad social del empleado. Retorna arreglo vacío si no hay descuentos.
                                type: array
                                items:
                                  description: Línea del detalle de descuento de seguridad social.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de descuento de seguridad social.
                                      type: string
                                      example: Salud empleado
                                    value:
                                      description: Valor descontado en pesos colombianos.
                                      type: integer
                                      example: 52000
                                example: []
                              comments:
                                description: Comentarios adicionales de seguridad social del empleado. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          deductions:
                            description: Detalle de otras deducciones aplicadas en el periodo (préstamos, embargos, etc.).
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de otras deducciones. Retorna arreglo vacío si no hay deducciones.
                                type: array
                                items:
                                  description: Línea del detalle de deducción.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de deducción.
                                      type: string
                                      example: Préstamo empresa
                                    value:
                                      description: Valor descontado en pesos colombianos.
                                      type: integer
                                      example: 100000
                                example: []
                              comments:
                                description: Comentarios adicionales de deducciones. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                      social_security_and_parafiscals:
                        description: Detalle de aportes de seguridad social y parafiscales a cargo de la empresa.
                        type: object
                        properties:
                          social_security_company:
                            description: Aportes de seguridad social a cargo de la empresa (salud y pensión empresa).
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de seguridad social empresa. Retorna arreglo vacío si no aplica.
                                type: array
                                items:
                                  description: Línea del detalle de seguridad social empresa.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de aporte.
                                      type: string
                                      example: Salud empresa
                                    value:
                                      description: Valor del aporte en pesos colombianos.
                                      type: integer
                                      example: 104000
                                example: []
                              comments:
                                description: Comentarios adicionales de seguridad social empresa. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          parafiscals_company:
                            description: Aportes parafiscales a cargo de la empresa (SENA, ICBF, caja de compensación).
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle de parafiscales empresa. Retorna arreglo vacío si no aplica.
                                type: array
                                items:
                                  description: Línea del detalle de parafiscal.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta del tipo de parafiscal.
                                      type: string
                                      example: Caja de compensación
                                    value:
                                      description: Valor del aporte en pesos colombianos.
                                      type: integer
                                      example: 52000
                                example: []
                              comments:
                                description: Comentarios adicionales de parafiscales. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          ibc_health:
                            description: Base de cotización para salud (IBC salud).
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle del IBC salud. Retorna arreglo vacío si no aplica.
                                type: array
                                items:
                                  description: Línea del detalle del IBC salud.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta de la línea del IBC salud.
                                      type: string
                                      example: IBC salud
                                    value:
                                      description: Valor del IBC en pesos colombianos.
                                      type: integer
                                      example: 1300000
                                example: []
                              comments:
                                description: Comentarios adicionales del IBC salud. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          ibc_pension:
                            description: Base de cotización para pensión (IBC pensión).
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle del IBC pensión. Retorna arreglo vacío si no aplica.
                                type: array
                                items:
                                  description: Línea del detalle del IBC pensión.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta de la línea del IBC pensión.
                                      type: string
                                      example: IBC pensión
                                    value:
                                      description: Valor del IBC en pesos colombianos.
                                      type: integer
                                      example: 1300000
                                example: []
                              comments:
                                description: Comentarios adicionales del IBC pensión. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          ibc_risks:
                            description: Base de cotización para riesgos laborales (IBC ARL).
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle del IBC riesgos. Retorna arreglo vacío si no aplica.
                                type: array
                                items:
                                  description: Línea del detalle del IBC riesgos.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta de la línea del IBC riesgos.
                                      type: string
                                      example: IBC ARL
                                    value:
                                      description: Valor del IBC en pesos colombianos.
                                      type: integer
                                      example: 1300000
                                example: []
                              comments:
                                description: Comentarios adicionales del IBC riesgos. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
                          ibc_parafiscals:
                            description: Base de cotización para parafiscales (IBC parafiscales).
                            type: object
                            properties:
                              data:
                                description: Líneas del detalle del IBC parafiscales. Retorna arreglo vacío si no aplica.
                                type: array
                                items:
                                  description: Línea del detalle del IBC parafiscales.
                                  type: object
                                  properties:
                                    name:
                                      description: Etiqueta de la línea del IBC parafiscales.
                                      type: string
                                      example: IBC parafiscales
                                    value:
                                      description: Valor del IBC en pesos colombianos.
                                      type: integer
                                      example: 1300000
                                example: []
                              comments:
                                description: Comentarios adicionales del IBC parafiscales. Retorna arreglo vacío si no hay comentarios.
                                type: array
                                items:
                                  description: Texto de comentario.
                                  type: string
                                  example: Sin observaciones
                                example: []
              example:
                data:
                  header:
                    company:
                      name: Empresa de Prueba S.A.S.
                      document_type: ni
                      id_number: '900123001'
                    worker:
                      name: Juan Pérez
                      document_type: cc
                      id_number: '1234567890'
                      contract_category: Empleado
                    period:
                      period_payment:
                        initial_day: '2024-01-01'
                        end_day: '2024-01-31'
                      worked_days: 30
                    payroll_options:
                      payslip_detail: true
                      social_security_and_parafiscals: true
                      social_benefits_provisions: false
                      payroll_retention: false
                      termination: false
                      social_benefits: false
                  payslip_detail:
                    payment_summary:
                      data:
                        - name: Total neto a pagar
                          value: 1196000
                      comments: []
                    worked_days:
                      data:
                        - name: Días del período
                          value: 30
                      comments: []
                    base_salary:
                      data:
                        - name: Salario
                          monthly_value: 1300000
                          worked_days: 30
                          value: 1300000
                      comments:
                        - Fórmula = Valor mensual * Días trabajados / 30 Días
                    overtime:
                      data: []
                      comments: []
                    holidays:
                      data: []
                      comments: []
                    incapacities:
                      data: []
                      comments: []
                    licenses:
                      data: []
                      comments: []
                    additional_incomes:
                      data: []
                      comments: []
                    retentions:
                      data: []
                      comments: []
                    social_security_retentions:
                      data:
                        - name: Salud empleado
                          value: 52000
                      comments: []
                    deductions:
                      data: []
                      comments: []
                  social_security_and_parafiscals:
                    social_security_company:
                      data:
                        - name: Salud empresa
                          value: 104000
                      comments: []
                    parafiscals_company:
                      data:
                        - name: Caja de compensación
                          value: 52000
                      comments: []
                    ibc_health:
                      data:
                        - name: IBC salud
                          value: 1300000
                      comments: []
                    ibc_pension:
                      data:
                        - name: IBC pensión
                          value: 1300000
                      comments: []
                    ibc_risks:
                      data:
                        - name: IBC ARL
                          value: 1300000
                      comments: []
                    ibc_parafiscals:
                      data:
                        - name: IBC parafiscales
                          value: 1300000
                      comments: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de contrato no soportado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0101'
                    index: 0
                    message: Contrato es inválido.
                    object: contract
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 00ca6e8d-91dd-5a15-96db-82e77b087706
  /v1/workers_profile/workers/{worker_id}/worker_options:
    get:
      operationId: showWorkerProfileOptions
      tags:
        - Perfil de la persona
      summary: Obtener opciones del perfil
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones de navegación disponibles para la persona autenticada según su contrato activo: qué certificados puede solicitar, qué secciones de historial puede consultar, qué opciones de colillas tiene disponibles y si puede editar su terminación.

        **¿Cuándo usar este endpoint?**

        * Determinar qué secciones del perfil mostrarle a la persona según las configuraciones de su contrato y empresa.
        * Verificar si la persona tiene acceso a certificados laborales, historial de vacaciones, préstamos u otras secciones opcionales.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propias opciones de perfil.
        * **Sin contrato activo:** Si la persona no tiene contrato activo, el endpoint retorna un objeto vacío (sin las claves de opciones).
      responses:
        '200':
          description: Opciones del perfil de la persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones de navegación disponibles para la persona autenticada.
                    type: object
                    properties:
                      certificate_options:
                        description: Lista de tipos de certificados que la persona puede solicitar. Siempre incluye `income_certificate`. Incluye `labor_certificate` si el contrato es laboral o si aplica la reforma laboral Ley 2466.
                        type: array
                        items:
                          type: string
                          enum:
                            - income_certificate
                            - labor_certificate
                      history_options:
                        description: |
                          Lista de secciones de historial disponibles para la persona.

                          Valores posibles:

                          * `contracts` — Contratos
                          * `contract_details` — Detalles del contrato
                          * `novelties` — Novedades
                          * `payments` — Pagos
                          * `social_benefits` — Prestaciones sociales (solo si aplica al contrato activo)
                          * `loans` — Préstamos (solo si aplica al contrato activo)
                          * `contract_position_histories` — Historial de cargos
                          * `cost_center_configurations` — Centros de costo
                          * `with_retention` — Retención en la fuente (solo si aplica al contrato activo)
                          * `wages` — Salarios
                          * `holidays` — Vacaciones (solo si aplica al contrato activo)
                        type: array
                        items:
                          type: string
                          enum:
                            - contracts
                            - contract_details
                            - novelties
                            - payments
                            - social_benefits
                            - loans
                            - contract_position_histories
                            - cost_center_configurations
                            - with_retention
                            - wages
                            - holidays
                      payslips_options:
                        description: Lista de opciones de colillas de pago disponibles para la persona.
                        type: array
                        items:
                          type: string
                          enum:
                            - last_payslip
                            - payroll_history
                      editable_termination:
                        description: Indica si la terminación del contrato activo puede ser editada por la persona. Retorna false si el contrato no tiene terminación registrada.
                        type: boolean
                        example: false
                      contracts_with_retention:
                        description: Lista de contratos tipo empleado que tienen retenciones en la fuente registradas, con los años disponibles para descarga. Retorna un arreglo vacío si no hay contratos con retención.
                        type: array
                        items:
                          description: Información de un contrato con retención en la fuente.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al contrato en la base de datos.
                              type: string
                              example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                            initial_day:
                              description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-01'
                            years:
                              description: Lista de años con retención en la fuente disponibles para descarga.
                              type: array
                              items:
                                type: integer
                                example: 2024
                        example:
                          - id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                            initial_day: '2024-01-01'
                            years:
                              - 2023
                              - 2024
              example:
                data:
                  certificate_options:
                    - income_certificate
                  history_options:
                    - contracts
                    - contract_details
                    - novelties
                    - payments
                    - contract_position_histories
                    - cost_center_configurations
                    - wages
                  payslips_options:
                    - last_payslip
                    - payroll_history
                  editable_termination: false
                  contracts_with_retention: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
  /v1/workers_profile/workers/{worker_id}/payroll_concepts:
    get:
      operationId: indexWorkerProfilePayrollConcepts
      tags:
        - Nómina de la persona
      summary: Listar conceptos de nómina de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna los conceptos de nómina disponibles para la persona autenticada agrupados en tres categorías: vacaciones, incapacidades y licencias. Los conceptos varían según el tipo de contrato y la fecha de la novedad (aplica reforma laboral Ley 2466 de 2025 para aprendices).

        **¿Cuándo usar este endpoint?**

        * Obtener las opciones disponibles antes de registrar una solicitud de novedad desde el perfil de la persona.
        * Filtrar los conceptos según la categoría de contrato de la persona para mostrar solo los que aplican.

        **Consideraciones importantes**

        * **Accesos:** La persona autenticada solo puede consultar sus propios conceptos de nómina.
      parameters:
        - $ref: '#/components/parameters/contractCategoryPayrollConceptsParam'
        - $ref: '#/components/parameters/noveltyInitialDayParam'
      responses:
        '200':
          description: Conceptos de nómina disponibles para la persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Conceptos de nómina agrupados por categoría.
                    type: object
                    properties:
                      holidays:
                        description: Conceptos de vacaciones disponibles para el contrato activo de la persona.
                        type: array
                        items:
                          description: Concepto de vacaciones.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: 550e8400-e29b-41d4-a716-446655440000
                            name:
                              description: Nombre legible del concepto de nómina.
                              type: string
                              example: Vacaciones disfrutadas
                            coded_name:
                              description: Nombre en código del concepto de nómina usado para identificarlo en el sistema.
                              type: string
                              example: enjoyed_days
                            value:
                              description: Valor por defecto de días asociados al concepto.
                              type: integer
                              example: 1
                            owner_type:
                              description: Tipo de propietario del concepto. Indica si es un concepto de la empresa o global del sistema.
                              type:
                                - string
                                - 'null'
                              example: Company
                            deleteable:
                              description: Indica si el concepto puede ser eliminado por la empresa.
                              type: boolean
                              example: false
                        example:
                          - id: 550e8400-e29b-41d4-a716-446655440000
                            name: Vacaciones disfrutadas
                            coded_name: enjoyed_days
                            value: 1
                            owner_type: null
                            deleteable: false
                      incapacities:
                        description: Conceptos de incapacidades disponibles para el contrato activo de la persona.
                        type: array
                        items:
                          description: Concepto de incapacidad.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: 550e8400-e29b-41d4-a716-446655440002
                            name:
                              description: Nombre legible del concepto de nómina.
                              type: string
                              example: Incapacidad laboral
                            coded_name:
                              description: Nombre en código del concepto de nómina usado para identificarlo en el sistema.
                              type: string
                              example: labor_incapacity
                            value:
                              description: Valor por defecto de días asociados al concepto.
                              type: integer
                              example: 1
                            owner_type:
                              description: Tipo de propietario del concepto. Indica si es un concepto de la empresa o global del sistema.
                              type:
                                - string
                                - 'null'
                              example: null
                            deleteable:
                              description: Indica si el concepto puede ser eliminado por la empresa.
                              type: boolean
                              example: false
                        example:
                          - id: 550e8400-e29b-41d4-a716-446655440002
                            name: Incapacidad laboral
                            coded_name: labor_incapacity
                            value: 1
                            owner_type: null
                            deleteable: false
                      licenses:
                        description: Conceptos de licencias disponibles para el contrato activo de la persona.
                        type: array
                        items:
                          description: Concepto de licencia.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: 550e8400-e29b-41d4-a716-446655440004
                            name:
                              description: Nombre legible del concepto de nómina.
                              type: string
                              example: Licencia de maternidad
                            coded_name:
                              description: Nombre en código del concepto de nómina usado para identificarlo en el sistema.
                              type: string
                              example: maternity_leave
                            value:
                              description: Valor por defecto de días asociados al concepto.
                              type: integer
                              example: 1
                            owner_type:
                              description: Tipo de propietario del concepto. Indica si es un concepto de la empresa o global del sistema.
                              type:
                                - string
                                - 'null'
                              example: null
                            deleteable:
                              description: Indica si el concepto puede ser eliminado por la empresa.
                              type: boolean
                              example: false
                        example:
                          - id: 550e8400-e29b-41d4-a716-446655440004
                            name: Licencia de maternidad
                            coded_name: maternity_leave
                            value: 1
                            owner_type: null
                            deleteable: false
              example:
                data:
                  holidays:
                    - id: 550e8400-e29b-41d4-a716-446655440000
                      name: Vacaciones disfrutadas
                      coded_name: enjoyed_days
                      value: 1
                      owner_type: null
                      deleteable: false
                  incapacities:
                    - id: 550e8400-e29b-41d4-a716-446655440002
                      name: Incapacidad laboral
                      coded_name: labor_incapacity
                      value: 1
                      owner_type: null
                      deleteable: false
                  licenses:
                    - id: 550e8400-e29b-41d4-a716-446655440004
                      name: Licencia de maternidad
                      coded_name: maternity_leave
                      value: 1
                      owner_type: null
                      deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
    parameters:
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
  /v1/{company_id}/accounting/code:
    patch:
      operationId: updateAccountingCode
      tags:
        - Configuración contable
      summary: Actualizar código contable
      description: |
        **¿Qué hace este endpoint?**

        Crea o actualiza el código contable y la contrapartida de un concepto de nómina para la empresa.
        Si el concepto no tiene código contable guardado, lo crea; si ya existe, lo actualiza.

        **¿Cuándo usar este endpoint?**

        * Configurar el código contable de un concepto de nómina por primera vez.
        * Actualizar el código o la contrapartida de un concepto ya configurado.
        * Renombrar un concepto de nómina editable de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Conceptos válidos:** Solo se pueden configurar conceptos que pertenezcan a las categorías contables habilitadas. El endpoint retorna error `0102` si el concepto no aplica.
        * **Nombre editable:** El campo `payroll_concept_name` solo actualiza el nombre si el concepto es editable por la empresa.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                payroll_concept_id:
                  description: Identificador único (ID) del concepto de nómina al que se asignará el código contable.
                  type: string
                  example: e66a79f8-d0b6-5439-99ef-ac5364323a6c
                accounting_code:
                  description: Código contable a asignar al concepto de nómina.
                  type: string
                  example: '0572'
                counterpart_code:
                  description: Código de contrapartida contable. Si se omite, conserva el valor anterior.
                  type: string
                  example: '237010'
                payroll_concept_name:
                  description: Nuevo nombre para el concepto de nómina. Solo aplica si el concepto es editable por la empresa.
                  type: string
                  example: Bonificación extralegal mensual
              required:
                - payroll_concept_id
      responses:
        '202':
          description: Código contable actualizado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información actualizada del código contable del concepto de nómina.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al código contable en la base de datos.
                        type: string
                        example: fd2d72ae-9227-4f27-997d-50893969be83
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                        type: string
                        example: e66a79f8-d0b6-5439-99ef-ac5364323a6c
                      payroll_concept_name:
                        description: Nombre del concepto de nómina.
                        type: string
                        example: Bonificación extralegal mensual
                      accounting_code:
                        description: Código contable asignado al concepto de nómina.
                        type: string
                        example: '0572'
                      counterpart_code:
                        description: Código de contrapartida contable. Null si no está configurado.
                        type:
                          - string
                          - 'null'
                        example: '237010'
                      editable:
                        description: Indica si el nombre del concepto de nómina puede ser editado por la empresa.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si el código contable puede ser eliminado.
                        type: boolean
                        example: false
              example:
                data:
                  id: fd2d72ae-9227-4f27-997d-50893969be83
                  payroll_concept_id: e66a79f8-d0b6-5439-99ef-ac5364323a6c
                  payroll_concept_name: Bonificación extralegal mensual
                  accounting_code: '0572'
                  counterpart_code: '237010'
                  editable: true
                  deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Concepto de nómina no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0001'
                    index: 0
                    message: Concepto de nómina no existe
                    object: payroll_concept
        '422':
          description: Concepto de nómina inválido para configuración contable / Código demasiado largo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Concepto de nómina inválido para configuración contable:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
                Código demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Código contable es demasiado largo (30 caracteres máximo).
                        object: accounting_code
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/accounting/codes:
    get:
      operationId: indexAccountingCodes
      tags:
        - Configuración contable
      summary: Listar códigos contables
      description: |
        **¿Qué hace este endpoint?**

        Retorna los conceptos de nómina de la empresa junto con su código contable y código de contrapartida.
        Incluye tanto conceptos legales como personalizados de la empresa.

        **¿Cuándo usar este endpoint?**

        * Consultar los códigos contables asignados a los conceptos de nómina antes de generar archivos contables.
        * Obtener conceptos agrupados por categoría para construir una vista de configuración contable.
        * Verificar qué conceptos tienen código contable o contrapartida pendiente de configurar.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Categoría por defecto:** Si no se envía `category` ni `categories`, retorna los conceptos de la categoría `legal`.
        * **Formato según parámetro:** Con `category` (singular), `data` es un arreglo de objetos. Con `categories` (plural), `data` es un objeto donde cada llave es el nombre de la categoría y su valor es un arreglo de conceptos.
      parameters:
        - in: query
          required: false
          name: category
          description: Filtra los conceptos por una única categoría contable. Si no se envía, retorna `legal` por defecto. Incompatible con `categories`.
          schema:
            $ref: '#/components/schemas/AccountingCategory'
        - in: query
          required: false
          name: categories
          description: Filtra los conceptos por múltiples categorías contables. Cuando se usa este parámetro, `data` es un objeto agrupado por categoría en lugar de un arreglo plano.
          schema:
            type: array
            items:
              $ref: '#/components/schemas/AccountingCategory'
            example:
              - salary_income
              - deductions
      responses:
        '200':
          description: Códigos contables por categoría única / Códigos contables agrupados por categorías
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: |
                      Conceptos de nómina con sus códigos contables. La estructura varía según el parámetro usado:

                      - Sin parámetro o con `category`: arreglo plano de conceptos de la categoría indicada (por defecto `legal`).
                      - Con `categories`: objeto donde cada llave es el nombre de la categoría y su valor es un arreglo de conceptos.
                    oneOf:
                      - type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al código contable en la base de datos. Null si el concepto aún no tiene código contable guardado.
                              type:
                                - string
                                - 'null'
                              example: fd2d72ae-9227-4f27-997d-50893969be83
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: 014612d3-a01f-5acf-8d72-b1e694f916e9
                            payroll_concept_name:
                              description: Nombre del concepto de nómina.
                              type: string
                              example: Auxilio de conectividad
                            accounting_code:
                              description: Código contable asignado al concepto de nómina. Null si el concepto no tiene código configurado.
                              type:
                                - string
                                - 'null'
                              example: '0527'
                            counterpart_code:
                              description: Código de contrapartida contable. Null si no está configurado.
                              type:
                                - string
                                - 'null'
                              example: '2505'
                            editable:
                              description: Indica si el nombre del concepto de nómina puede ser editado por la empresa.
                              type: boolean
                              example: true
                            deleteable:
                              description: Indica si el código contable puede ser eliminado.
                              type: boolean
                              example: false
                      - type: object
                        additionalProperties:
                          description: Arreglo de conceptos de nómina pertenecientes a la categoría indicada por la llave.
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al código contable en la base de datos. Null si el concepto aún no tiene código contable guardado.
                                type:
                                  - string
                                  - 'null'
                                example: fd2d72ae-9227-4f27-997d-50893969be83
                              payroll_concept_id:
                                description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                type: string
                                example: 014612d3-a01f-5acf-8d72-b1e694f916e9
                              payroll_concept_name:
                                description: Nombre del concepto de nómina.
                                type: string
                                example: Bonificación extralegal
                              accounting_code:
                                description: Código contable asignado al concepto de nómina. Null si el concepto no tiene código configurado.
                                type:
                                  - string
                                  - 'null'
                                example: '0527'
                              counterpart_code:
                                description: Código de contrapartida contable. Null si no está configurado.
                                type:
                                  - string
                                  - 'null'
                                example: '2505'
                              editable:
                                description: Indica si el nombre del concepto de nómina puede ser editado por la empresa.
                                type: boolean
                                example: true
                              deleteable:
                                description: Indica si el código contable puede ser eliminado.
                                type: boolean
                                example: false
              examples:
                Códigos contables por categoría única:
                  value:
                    data:
                      - id: null
                        payroll_concept_id: 014612d3-a01f-5acf-8d72-b1e694f916e9
                        payroll_concept_name: Auxilio de conectividad
                        accounting_code: '0527'
                        counterpart_code: null
                        editable: false
                        deleteable: false
                      - id: fd2d72ae-9227-4f27-997d-50893969be83
                        payroll_concept_id: d3e832c0-8a34-5fb4-9f2c-319f93e7ff51
                        payroll_concept_name: Salario
                        accounting_code: '0506'
                        counterpart_code: '2505'
                        editable: false
                        deleteable: false
                Códigos contables agrupados por categorías:
                  value:
                    data:
                      salary_income:
                        - id: null
                          payroll_concept_id: 014612d3-a01f-5acf-8d72-b1e694f916e9
                          payroll_concept_name: Bonificación extralegal
                          accounting_code: '0527'
                          counterpart_code: null
                          editable: true
                          deleteable: false
                      deductions:
                        - id: fd2d72ae-9227-4f27-997d-50893969be83
                          payroll_concept_id: d3e832c0-8a34-5fb4-9f2c-319f93e7ff51
                          payroll_concept_name: Deducción voluntaria
                          accounting_code: '2370'
                          counterpart_code: '1110'
                          editable: true
                          deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/accounting/documents:
    get:
      operationId: indexAccountingDocuments
      tags:
        - Archivos y documentos contables
      summary: Listar documentos contables
      description: |
        **¿Qué hace este endpoint?**

        Retorna los documentos contables configurados en la integración activa de la empresa:
        nómina, prestaciones sociales, seguridad social, pago de nómina y pago de seguridad social.
        Cada documento incluye su código y número consecutivo configurados para el proveedor indicado.

        **¿Cuándo usar este endpoint?**

        * Consultar qué documentos contables ya tienen código configurado antes de generar archivos.
        * Verificar el número consecutivo asignado a cada tipo de documento en la integración.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Integración requerida:** La empresa debe tener una integración contable activa con el proveedor indicado. Si no existe o no está activa, retorna error `1216`.
        * **Documentos no configurados:** Si un documento aún no tiene código asignado, los campos `id`, `code` y `consecutive_number` retornan `null`.
      parameters:
        - in: query
          name: provider
          required: true
          description: 'Proveedor de la integración contable activa de la empresa. Valores posibles: alegra (Alegra), siigo (Siigo), pya (PYA).'
          schema:
            type: string
            enum:
              - alegra
              - siigo
              - pya
            example: siigo
      responses:
        '200':
          description: Documentos contables listados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo con los cinco tipos de documentos contables de la integración.
                    type: array
                    items:
                      description: Datos de un documento contable y su configuración en el proveedor.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al documento contable en la base de datos. Null si aún no ha sido configurado.
                          type:
                            - string
                            - 'null'
                          example: 20ec380c-94e9-410a-9106-2d6e6fe46044
                        integration_id:
                          description: Identificador único (ID) asignado a la integración contable en la base de datos.
                          type: string
                          example: e0cdb81d-dc47-4692-9ea1-fd7e477969a8
                        document_type:
                          $ref: '#/components/schemas/AccountingDocumentType'
                        name:
                          description: Nombre descriptivo del tipo de documento contable en español.
                          type: string
                          example: Nómina (provisión)
                        code:
                          description: Código del documento en el sistema contable del proveedor. Null si aún no ha sido configurado.
                          type:
                            - integer
                            - 'null'
                          example: 5
                        consecutive_number:
                          description: Número consecutivo del documento en el sistema contable. Null si aún no ha sido configurado.
                          type:
                            - integer
                            - 'null'
                          example: 1000
              example:
                data:
                  - id: null
                    integration_id: e0cdb81d-dc47-4692-9ea1-fd7e477969a8
                    document_type: payroll
                    name: Nómina (provisión)
                    code: null
                    consecutive_number: null
                  - id: 20ec380c-94e9-410a-9106-2d6e6fe46044
                    integration_id: e0cdb81d-dc47-4692-9ea1-fd7e477969a8
                    document_type: social_benefits
                    name: Prestaciones sociales (provisión)
                    code: 5
                    consecutive_number: 1000
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin integración contable activa / Sin acceso a la integración
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Sin integración contable activa:
                  value:
                    error:
                      - code: '1216'
                        index: 0
                        message: La empresa no tiene activa ninguna integración contable.
                        object: integration
                Sin acceso a la integración:
                  value:
                    error:
                      - code: '1218'
                        index: 0
                        message: No tienes acceso a esta integración.
                        object: integration
    put:
      operationId: updateAccountingDocument
      tags:
        - Archivos y documentos contables
      summary: Crear o actualizar documento contable
      description: |
        **¿Qué hace este endpoint?**

        Crea o actualiza el código y número consecutivo de un documento contable en la integración
        activa de la empresa. Si el documento no existe, lo crea; si ya existe, lo actualiza.

        **¿Cuándo usar este endpoint?**

        * Configurar por primera vez el código de un tipo de documento antes de generar archivos contables.
        * Actualizar el número consecutivo de un documento tras un ajuste en el sistema contable.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Integración requerida:** La empresa debe tener una integración contable activa con el proveedor indicado. Si no existe o no está activa, retorna error `1216`.
        * **Rango de código:** El campo `code` debe ser un entero entre 1 y 999.
        * **Rango de consecutivo:** El campo `consecutive_number` debe ser un entero entre 1 y 99.999.999.999.
      parameters:
        - in: query
          name: provider
          required: true
          description: 'Proveedor de la integración contable activa de la empresa. Valores posibles: alegra (Alegra), siigo (Siigo), pya (PYA).'
          schema:
            type: string
            enum:
              - alegra
              - siigo
              - pya
            example: siigo
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                document_type:
                  $ref: '#/components/schemas/AccountingDocumentType'
                code:
                  description: Código del documento en el sistema contable del proveedor. Debe ser un entero entre 1 y 999.
                  type: integer
                  example: 5
                consecutive_number:
                  description: Número consecutivo del documento. Debe ser un entero entre 1 y 99.999.999.999.
                  type: integer
                  example: 1000
              required:
                - document_type
                - code
            example:
              document_type: payroll
              code: 5
              consecutive_number: 1000
      responses:
        '202':
          description: Documento contable creado o actualizado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados del documento contable.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al documento contable en la base de datos.
                        type: string
                        example: 20ec380c-94e9-410a-9106-2d6e6fe46044
                      integration_id:
                        description: Identificador único (ID) asignado a la integración contable en la base de datos.
                        type: string
                        example: e0cdb81d-dc47-4692-9ea1-fd7e477969a8
                      document_type:
                        $ref: '#/components/schemas/AccountingDocumentType'
                      name:
                        description: Nombre descriptivo del tipo de documento contable en español.
                        type: string
                        example: Nómina (provisión)
                      code:
                        description: Código del documento en el sistema contable del proveedor.
                        type: integer
                        example: 5
                      consecutive_number:
                        description: Número consecutivo del documento. Null si no fue configurado.
                        type:
                          - integer
                          - 'null'
                        example: 1000
              example:
                data:
                  id: 20ec380c-94e9-410a-9106-2d6e6fe46044
                  integration_id: e0cdb81d-dc47-4692-9ea1-fd7e477969a8
                  document_type: payroll
                  name: Nómina (provisión)
                  code: 5
                  consecutive_number: 1000
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin integración contable activa / Sin acceso a la integración / Código fuera de rango
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Sin integración contable activa:
                  value:
                    error:
                      - code: '1216'
                        index: 0
                        message: La empresa no tiene activa ninguna integración contable.
                        object: integration
                Sin acceso a la integración:
                  value:
                    error:
                      - code: '1218'
                        index: 0
                        message: No tienes acceso a esta integración.
                        object: integration
                Código fuera de rango:
                  value:
                    error:
                      - code: '0303'
                        index: 0
                        message: Código del documento debe ser menor o igual a 999.
                        object: code
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/accounting/institution_code:
    patch:
      operationId: updateAccountingInstitutionCode
      tags:
        - Configuración para instituciones
      summary: Actualizar código contable de institución
      description: |
        **¿Qué hace este endpoint?**

        Crea o actualiza el código contable de una institución (EPS, fondo de pensiones, ARL o caja de
        compensación) para la empresa. Si la institución no tiene código contable guardado, lo crea;
        si ya existe, lo actualiza.

        **¿Cuándo usar este endpoint?**

        * Asignar por primera vez el código contable a una EPS o fondo de pensiones vinculado a la empresa.
        * Corregir o actualizar el código contable de una institución ya configurada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Instituciones válidas:** Solo se pueden configurar instituciones de las categorías `health_provider`, `pension_provider`, `risk_provider` o `compensation_fund`. El endpoint retorna error `0102` si la institución no pertenece a estas categorías.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                institution_id:
                  description: Identificador único (ID) de la institución a la que se asignará el código contable.
                  type: string
                  example: c0358bc8-42af-5574-871e-cf4ae3a12110
                accounting_code:
                  description: Código contable a asignar a la institución.
                  type: string
                  example: '237010'
              required:
                - institution_id
                - accounting_code
      responses:
        '202':
          description: Código contable de institución actualizado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información actualizada del código contable de la institución.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al código contable de la institución en la base de datos.
                        type: string
                        example: dcd33dcc-26f0-4bc3-b60e-23ec862843c9
                      institution_id:
                        description: Identificador único (ID) asignado a la institución en la base de datos.
                        type: string
                        example: c0358bc8-42af-5574-871e-cf4ae3a12110
                      institution_name:
                        description: Nombre de la institución.
                        type: string
                        example: Porvenir
                      id_number:
                        description: Número de identificación tributaria (NIT) de la institución.
                        type: string
                        example: '890903790'
                      accounting_code:
                        description: Código contable asignado a la institución para la empresa.
                        type: string
                        example: '237010'
              example:
                data:
                  id: dcd33dcc-26f0-4bc3-b60e-23ec862843c9
                  institution_id: c0358bc8-42af-5574-871e-cf4ae3a12110
                  institution_name: Porvenir
                  id_number: '890903790'
                  accounting_code: '237010'
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Institución no encontrada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0001'
                    index: 0
                    message: Institución no existe
                    object: institution
        '422':
          description: Institución inválida para configuración contable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/accounting/institution_codes:
    get:
      operationId: indexAccountingInstitutionCodes
      tags:
        - Configuración para instituciones
      summary: Listar códigos contables de instituciones
      description: |
        **¿Qué hace este endpoint?**

        Retorna las instituciones vinculadas a los contratos de la empresa (EPS, fondos de pensiones, ARL
        y cajas de compensación) junto con su código contable asignado.

        **¿Cuándo usar este endpoint?**

        * Consultar los códigos contables de las EPS antes de generar archivos contables de seguridad social.
        * Obtener los fondos de pensiones con su código contable para la conciliación contable de nómina.
        * Revisar los códigos de ARL y cajas de compensación asignados a las instituciones de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Categoría por defecto:** Si no se envía `category`, retorna las instituciones de tipo `health_provider` (EPS) por defecto.
        * **Instituciones incluidas:** Solo se retornan las instituciones actualmente vinculadas a los contratos vigentes de la empresa, no el catálogo completo de instituciones.
      parameters:
        - in: query
          required: false
          name: category
          description: 'Filtra las instituciones por categoría. Si no se envía, retorna las EPS por defecto. Valores posibles: health_provider (EPS), pension_provider (fondo de pensiones), arl_compensation_fund (ARL y cajas de compensación).'
          schema:
            type: string
            enum:
              - health_provider
              - pension_provider
              - arl_compensation_fund
            example: pension_provider
      responses:
        '200':
          description: Instituciones con códigos / Sin instituciones vinculadas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo de instituciones con su código contable asignado. Retorna un arreglo vacío si la empresa no tiene contratos vigentes con instituciones de la categoría solicitada.
                    type: array
                    items:
                      description: Datos de una institución con su código contable asignado.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al código contable de la institución en la base de datos. Null si la institución aún no tiene código contable guardado.
                          type:
                            - string
                            - 'null'
                          example: dcd33dcc-26f0-4bc3-b60e-23ec862843c9
                        institution_id:
                          description: Identificador único (ID) asignado a la institución en la base de datos.
                          type: string
                          example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                        institution_name:
                          description: Nombre de la institución.
                          type: string
                          example: Sura EPS
                        id_number:
                          description: Número de identificación tributaria (NIT) de la institución.
                          type: string
                          example: '800088702'
                        accounting_code:
                          description: Código contable asignado a la institución para la empresa. Null si no está configurado.
                          type:
                            - string
                            - 'null'
                          example: '237005'
              examples:
                Instituciones con códigos:
                  value:
                    data:
                      - id: null
                        institution_id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                        institution_name: Sura EPS
                        id_number: '800088702'
                        accounting_code: '237005'
                      - id: dcd33dcc-26f0-4bc3-b60e-23ec862843c9
                        institution_id: c0358bc8-42af-5574-871e-cf4ae3a12110
                        institution_name: Compensar EPS
                        id_number: '860007336'
                        accounting_code: '237010'
                Sin instituciones vinculadas:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/alegra_accounting:
    get:
      operationId: showAlegraAccounting
      tags:
        - Integración con Alegra
      summary: Obtener códigos contables de Alegra
      description: |
        **¿Qué hace este endpoint?**

        Retorna los conceptos de nómina de la empresa con sus códigos contables configurados
        en la integración con Alegra, junto con las opciones de cuentas disponibles en Alegra
        para asignar como código y contrapartida.

        **¿Cuándo usar este endpoint?**

        * Cargar la pantalla de configuración de códigos contables de Alegra para una categoría específica.
        * Obtener las cuentas disponibles en Alegra para mostrarlas como opciones al usuario al asignar un código.
        * Consultar los códigos ya configurados por categoría antes de actualizarlos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Integración activa requerida:** La empresa debe tener activa la integración con Alegra. Si no existe, retorna 404. Si existe pero las credenciales son inválidas o hay un error de conexión, retorna error `1202`, `1203` o `1204`.
        * **Categoría por defecto:** Si no se envía `category`, retorna los conceptos de la categoría `legal` por defecto.
        * **Categoría `payment_method`:** Para esta categoría, `alegra_options.codes` retorna los métodos de pago bancarios configurados en Alegra y `counterpart_codes` retorna `null`.
      parameters:
        - in: query
          required: false
          name: category
          schema:
            $ref: '#/components/schemas/AccountingCategory'
          description: Si no se envía, retorna la categoría `legal` por defecto.
      responses:
        '200':
          description: Códigos contables de Alegra obtenidos correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Lista de conceptos de nómina de la categoría solicitada con sus códigos contables configurados en Alegra.
                    type: array
                    items:
                      description: Concepto de nómina con su código contable asignado en la integración con Alegra.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al código de integración en la base de datos. Null si el concepto aún no tiene código configurado.
                          type:
                            - string
                            - 'null'
                          example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                        integration_id:
                          description: Identificador único (ID) asignado a la integración con Alegra en la base de datos.
                          type: string
                          example: f2af04af-082c-58d3-9eb8-c388139b9c43
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: 014612d3-a01f-5acf-8d72-b1e694f916e9
                        payroll_concept_name:
                          description: Nombre del concepto de nómina.
                          type: string
                          example: Auxilio de conectividad
                        integration_code:
                          description: Cuenta contable de Alegra asignada como código principal para este concepto.
                          type: object
                          properties:
                            id:
                              description: Identificador de la cuenta en Alegra.
                              type:
                                - string
                                - 'null'
                              example: '5081'
                            name:
                              description: Nombre de la cuenta en Alegra.
                              type:
                                - string
                                - 'null'
                              example: Gastos administrativos
                        counterpart_code:
                          description: Cuenta contable de Alegra asignada como contrapartida para este concepto. Null si la categoría no maneja contrapartida.
                          type:
                            - object
                            - 'null'
                          properties:
                            id:
                              description: Identificador de la cuenta de contrapartida en Alegra.
                              type:
                                - string
                                - 'null'
                              example: '5047'
                            name:
                              description: Nombre de la cuenta de contrapartida en Alegra.
                              type:
                                - string
                                - 'null'
                              example: Cuentas por pagar - proveedores
                  alegra_options:
                    description: Cuentas disponibles en Alegra para asignar como código y contrapartida a los conceptos de la categoría solicitada.
                    type: object
                    properties:
                      codes:
                        description: Lista de cuentas contables disponibles en Alegra para asignar como código principal.
                        type: array
                        items:
                          description: Cuenta contable disponible en Alegra.
                          type: object
                          properties:
                            id:
                              description: Identificador de la cuenta en Alegra.
                              type: string
                              example: '5081'
                            name:
                              description: Nombre de la cuenta en Alegra.
                              type: string
                              example: Gastos administrativos
                      counterpart_codes:
                        description: Lista de cuentas contables disponibles en Alegra para asignar como contrapartida. Null si la categoría no maneja contrapartida.
                        type:
                          - array
                          - 'null'
                        items:
                          description: Cuenta contable disponible en Alegra como contrapartida.
                          type: object
                          properties:
                            id:
                              description: Identificador de la cuenta en Alegra.
                              type: string
                              example: '5047'
                            name:
                              description: Nombre de la cuenta en Alegra.
                              type: string
                              example: Cuentas por pagar - proveedores
                      category:
                        description: Categoría de conceptos consultada.
                        type: string
                        example: legal
              example:
                data:
                  - id: null
                    integration_id: f2af04af-082c-58d3-9eb8-c388139b9c43
                    payroll_concept_id: 014612d3-a01f-5acf-8d72-b1e694f916e9
                    payroll_concept_name: Auxilio de conectividad
                    integration_code:
                      id: '5081'
                      name: Gastos administrativos
                    counterpart_code:
                      id: '5047'
                      name: Cuentas por pagar - proveedores
                  - id: null
                    integration_id: f2af04af-082c-58d3-9eb8-c388139b9c43
                    payroll_concept_id: a1a917d5-ca8a-50a9-82e9-2a6b2b3d6f9f
                    payroll_concept_name: Salario
                    integration_code:
                      id: null
                      name: null
                    counterpart_code:
                      id: null
                      name: null
                alegra_options:
                  codes:
                    - id: '5081'
                      name: Gastos administrativos
                    - id: '5007'
                      name: Nómina
                    - id: '5008'
                      name: Prestaciones sociales
                  counterpart_codes:
                    - id: '5047'
                      name: Cuentas por pagar - proveedores
                    - id: '5048'
                      name: Obligaciones financieras y préstamos a terceros
                  category: legal
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Credenciales inválidas en Alegra / Pago requerido en Alegra / Acción no permitida en Alegra / Categoría inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Credenciales inválidas en Alegra:
                  value:
                    error:
                      - code: '1202'
                        index: 0
                        message: Las credenciales son incorrectas para la integración.
                        object: integration
                Pago requerido en Alegra:
                  value:
                    error:
                      - code: '1203'
                        index: 0
                        message: Pago requerido para ejecutar la integración.
                        object: integration
                Acción no permitida en Alegra:
                  value:
                    error:
                      - code: '1204'
                        index: 0
                        message: Acción no permitida para el usuario en la integración.
                        object: integration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/areas:
    get:
      operationId: indexAreas
      tags:
        - Áreas
      summary: Listar áreas
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de áreas registradas para la empresa, ordenadas alfabéticamente.

        **¿Cuándo usar este endpoint?**

        * Consultar las áreas disponibles para asignar a una persona al crear o modificar su contrato.
        * Verificar qué áreas pueden eliminarse antes de reorganizar la estructura de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Áreas registradas / Sin áreas registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de áreas de la empresa, ordenadas alfabéticamente.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al área en la base de datos.
                          type: string
                          example: 096848e6-448b-58b8-a3fe-7704a3d9337b
                        name:
                          description: Nombre del área.
                          type: string
                          example: Administración
                        deleteable:
                          description: Indica si el área puede eliminarse. Es `false` cuando tiene personas asociadas en su historial de cargo.
                          type: boolean
                          example: false
              examples:
                Áreas registradas:
                  value:
                    data:
                      - id: 096848e6-448b-58b8-a3fe-7704a3d9337b
                        name: Administración
                        deleteable: false
                      - id: 53772730-00c6-5292-aa7b-715d1e62962d
                        name: Operaciones
                        deleteable: true
                      - id: 37ccc70f-e460-4693-9211-850140ef2221
                        name: Tecnología
                        deleteable: true
                Sin áreas registradas:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateAreas
      tags:
        - Áreas
      summary: Gestionar áreas
      description: |
        **¿Qué hace este endpoint?**

        Gestiona de forma masiva las áreas de la empresa en una sola operación. La acción se determina
        automáticamente según los campos enviados en cada objeto:

        * **Crear:** Sin `id` — crea una nueva área con el `name` indicado.
        * **Actualizar:** Con `id` y `name` — actualiza el nombre del área existente.
        * **Eliminar:** Con `id` sin `name` — elimina el área si no tiene personas asociadas.

        **¿Cuándo usar este endpoint?**

        * Configurar las áreas de la empresa antes de registrar personas.
        * Renombrar o eliminar áreas tras cambios en la estructura organizacional.
        * Crear, actualizar y eliminar varias áreas en una sola llamada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Eliminación:** Solo se puede eliminar un área si no tiene personas asociadas en su historial de cargo. El campo `deleteable` del GET indica si el área es eliminable antes de intentarlo.
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
      requestBody:
        required: true
        description: Crear área / Actualizar área / Eliminar área / Operación combinada
        content:
          application/json:
            schema:
              type: object
              properties:
                areas:
                  description: Arreglo de operaciones a ejecutar sobre las áreas de la empresa.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) del área en la base de datos. Omitir para crear un área nueva.
                        type: string
                        example: 096848e6-448b-58b8-a3fe-7704a3d9337b
                      name:
                        description: Nombre del área. Omitir para eliminar el área.
                        type: string
                        example: Administración
              required:
                - areas
            examples:
              Crear área:
                value:
                  areas:
                    - name: Auditoría
              Actualizar área:
                value:
                  areas:
                    - id: 096848e6-448b-58b8-a3fe-7704a3d9337b
                      name: Nuevo nombre
              Eliminar área:
                value:
                  areas:
                    - id: 096848e6-448b-58b8-a3fe-7704a3d9337b
              Operación combinada:
                value:
                  areas:
                    - name: Auditoría
                    - id: 096848e6-448b-58b8-a3fe-7704a3d9337b
                      name: Administración General
                    - id: 53772730-00c6-5292-aa7b-715d1e62962d
      responses:
        '202':
          description: Operación ejecutada exitosamente. Retorna las áreas creadas y actualizadas (las eliminadas no se incluyen).
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de áreas creadas o actualizadas en la operación.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al área en la base de datos.
                          type: string
                          example: 096848e6-448b-58b8-a3fe-7704a3d9337b
                        name:
                          description: Nombre del área.
                          type: string
                          example: Administración
                        deleteable:
                          description: Indica si el área puede eliminarse.
                          type: boolean
                          example: true
              example:
                data:
                  - id: 096848e6-448b-58b8-a3fe-7704a3d9337b
                    name: Administración
                    deleteable: false
                  - id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                    name: Auditoría
                    deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Datos inválidos / Área con personas asociadas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Datos inválidos:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
                Área con personas asociadas:
                  value:
                    error:
                      - code: '0504'
                        index: 1
                        message: Área no se puede eliminar porque tiene personas asociadas.
                        object: area
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/billing_information:
    get:
      operationId: showBillingInformation
      tags:
        - Facturación
      summary: Obtener información de facturación
      description: |
        **¿Qué hace este endpoint?**

        Retorna los datos de facturación registrados para la empresa, usados para la emisión de facturas de suscripción.

        **¿Cuándo usar este endpoint?**

        * Consultar los datos actuales de facturación antes de mostrar el formulario de edición.
        * Verificar el nombre, documento y correo asociados a las facturas de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Información de facturación retornada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de facturación de la empresa.
                    type: object
                    properties:
                      address:
                        description: Dirección de facturación de la empresa.
                        type:
                          - string
                          - 'null'
                        example: Calle 8
                      name:
                        description: Nombre o razón social de la empresa para la factura.
                        type:
                          - string
                          - 'null'
                        example: Empresa Ejemplo S.A.S.
                      email:
                        description: Correo electrónico al que Aleluya envía las facturas y comunicaciones.
                        type:
                          - string
                          - 'null'
                        example: facturacion@empresa.com
                      document_type:
                        description: Tipo de documento de identificación de la empresa.
                        $ref: '#/components/schemas/CompanyDocumentType'
                      id_number:
                        description: Número de identificación de la empresa.
                        type:
                          - string
                          - 'null'
                        example: '900123456'
                      phone:
                        description: Teléfono de contacto de la empresa.
                        type:
                          - string
                          - 'null'
                        example: '3128345212'
                      verification_digit:
                        description: Dígito de verificación del NIT de la empresa. Null si no aplica para el tipo de documento.
                        type:
                          - integer
                          - 'null'
                        example: 1
                      logo:
                        description: URL del logo de la empresa. Null si no tiene logo configurado.
                        type:
                          - string
                          - 'null'
                        example: https://storage.example.com/logos/empresa.png
                    required:
                      - address
                      - name
                      - email
                      - document_type
                      - id_number
                      - phone
                      - verification_digit
                      - logo
                required:
                  - data
              example:
                data:
                  address: Calle 8
                  name: Empresa Ejemplo S.A.S.
                  email: facturacion@empresa.com
                  document_type: ni
                  id_number: '900123456'
                  phone: '3128345212'
                  verification_digit: 1
                  logo: https://storage.example.com/logos/empresa.png
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateBillingInformation
      tags:
        - Facturación
      summary: Actualizar información de facturación
      description: |
        **¿Qué hace este endpoint?**

        Actualiza parcialmente los datos de facturación de la empresa. Solo se modifican los campos enviados; los demás se conservan sin cambios.

        **¿Cuándo usar este endpoint?**

        * Actualizar el correo, nombre o dirección que aparece en las facturas de suscripción.
        * Cambiar el documento de identificación registrado para la facturación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Campos opcionales:** Todos los campos son opcionales. Solo se actualizan los campos incluidos en el request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                billing_information:
                  description: Campos de facturación a actualizar. Todos son opcionales.
                  type: object
                  properties:
                    address:
                      description: Dirección de facturación de la empresa.
                      type: string
                      example: Calle 8
                    name:
                      description: Nombre o razón social de la empresa para la factura.
                      type: string
                      example: Empresa Ejemplo S.A.S.
                    email:
                      description: Correo electrónico al que Aleluya envía las facturas y comunicaciones.
                      type: string
                      example: facturacion@empresa.com
                    document_type:
                      description: Tipo de documento de identificación de la empresa.
                      $ref: '#/components/schemas/CompanyDocumentType'
                    id_number:
                      description: Número de identificación de la empresa.
                      type: string
                      example: '900123456'
                    phone:
                      description: Teléfono de contacto de la empresa.
                      type: string
                      example: '3128345212'
              required:
                - billing_information
            example:
              billing_information:
                name: Empresa Ejemplo S.A.S.
                email: facturacion@empresa.com
      responses:
        '202':
          description: Información de facturación actualizada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de facturación actualizados de la empresa.
                    type: object
                    properties:
                      address:
                        description: Dirección de facturación de la empresa.
                        type:
                          - string
                          - 'null'
                        example: Calle 8
                      name:
                        description: Nombre o razón social de la empresa para la factura.
                        type:
                          - string
                          - 'null'
                        example: Empresa Ejemplo S.A.S.
                      email:
                        description: Correo electrónico al que Aleluya envía las facturas y comunicaciones.
                        type:
                          - string
                          - 'null'
                        example: facturacion@empresa.com
                      document_type:
                        description: Tipo de documento de identificación de la empresa.
                        $ref: '#/components/schemas/CompanyDocumentType'
                      id_number:
                        description: Número de identificación de la empresa.
                        type:
                          - string
                          - 'null'
                        example: '900123456'
                      phone:
                        description: Teléfono de contacto de la empresa.
                        type:
                          - string
                          - 'null'
                        example: '3128345212'
                      verification_digit:
                        description: Dígito de verificación del NIT de la empresa. Null si no aplica para el tipo de documento.
                        type:
                          - integer
                          - 'null'
                        example: 1
                      logo:
                        description: URL del logo de la empresa. Null si no tiene logo configurado.
                        type:
                          - string
                          - 'null'
                        example: https://storage.example.com/logos/empresa.png
                    required:
                      - address
                      - name
                      - email
                      - document_type
                      - id_number
                      - phone
                      - verification_digit
                      - logo
                required:
                  - data
              example:
                data:
                  address: Calle 8
                  name: Empresa Ejemplo S.A.S.
                  email: facturacion@empresa.com
                  document_type: ni
                  id_number: '900123456'
                  phone: '3128345212'
                  verification_digit: 1
                  logo: https://storage.example.com/logos/empresa.png
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: e0864fc1-c35b-4c98-8448-aed379d07c04
  /v1/{company_id}/company_bank_accounts:
    get:
      operationId: indexCompanyBankAccounts
      tags:
        - Cuentas bancarias
      summary: Listar cuentas bancarias
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de cuentas bancarias registradas para una empresa, ordenadas
        alfabéticamente por nombre del banco.

        **¿Cuándo usar este endpoint?**

        * Obtener las cuentas registradas de la empresa para saber con qué bancos puede realizar el pago de nómina.
        * Confirmar qué bancos tiene registrados la empresa antes de registrar una nueva cuenta.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Enmascaramiento del número de cuenta:** Por defecto el número de cuenta se muestra enmascarado (ej. `****6789`). Para obtener el número completo, enviar `unmask=true`.
      parameters:
        - in: query
          name: unmask
          required: false
          description: Indica si se debe mostrar el número de cuenta completo. Por defecto es `false` y el número aparece enmascarado (ej. `****6789`).
          schema:
            type: boolean
            example: false
      responses:
        '200':
          description: Cuentas registradas / Sin cuentas registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de cuentas bancarias registradas para la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la cuenta bancaria en la base de datos.
                          type: string
                          example: 8d90bcec-ae95-48b4-b35d-e38a752b8ddb
                        bank:
                          description: Información del banco al que pertenece la cuenta.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) del banco en la base de datos.
                              type: string
                              example: 03faad35-36e4-5603-898c-8fcb97ff4bc7
                            coded_name:
                              description: Código interno del banco utilizado para identificar el formato de archivo bancario compatible.
                              type: string
                              example: bancolombia
                            name:
                              description: Nombre comercial del banco.
                              type: string
                              example: Bancolombia
                            file_formats:
                              description: Formatos de archivo bancario disponibles para este banco. Solo algunos bancos soportan múltiples formatos (ej. Bancolombia con PAB y SAP). Para la mayoría de bancos este arreglo estará vacío.
                              type: array
                              items:
                                type: object
                                properties:
                                  label:
                                    description: Nombre legible del formato de archivo bancario.
                                    type: string
                                    example: PAB
                                  value:
                                    description: Valor del formato que se envía al generar el archivo bancario.
                                    type: string
                                    example: PAB
                            supported_file:
                              description: Indica si el banco soporta generación de archivo bancario para el pago de nómina. Si es `false`, el pago debe gestionarse de forma manual.
                              type: boolean
                              example: true
                        account_number:
                          description: Número de la cuenta bancaria. Por defecto aparece enmascarado mostrando solo los últimos 4 dígitos (ej. `****6789`). Se muestra completo si se envía `unmask=true`.
                          type: string
                          example: '****6789'
                        account_type:
                          $ref: '#/components/schemas/AccountType'
              examples:
                Cuentas registradas:
                  value:
                    data:
                      - id: 8d90bcec-ae95-48b4-b35d-e38a752b8ddb
                        bank:
                          id: 03faad35-36e4-5603-898c-8fcb97ff4bc7
                          coded_name: bancolombia
                          name: Bancolombia
                          file_formats:
                            - label: PAB
                              value: PAB
                          supported_file: true
                        account_number: '****6789'
                        account_type: savings_account
                Sin cuentas registradas:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createCompanyBankAccount
      tags:
        - Cuentas bancarias
      summary: Crear cuenta bancaria
      description: |
        **¿Qué hace este endpoint?**

        Registra una nueva cuenta bancaria para la empresa, vinculándola a un banco existente.

        **¿Cuándo usar este endpoint?**

        * Registrar la cuenta destino antes de generar el primer archivo bancario de pago de nómina.
        * Cuando la empresa quiere realizar el pago de nómina a través de un banco adicional.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Límite de cuentas:** Una empresa puede tener máximo 10 cuentas bancarias registradas.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                bank_id:
                  description: Identificador único (ID) del banco al que pertenece la cuenta. Se puede obtener del listado de instituciones.
                  type: string
                  example: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                account_number:
                  description: Número de la cuenta bancaria. Debe ser numérico y tener mínimo 7 dígitos.
                  type: string
                  example: '1234567890'
                account_type:
                  $ref: '#/components/schemas/AccountType'
              required:
                - bank_id
                - account_number
                - account_type
      responses:
        '201':
          description: Cuenta bancaria creada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la cuenta bancaria recién creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la cuenta bancaria en la base de datos.
                        type: string
                        example: b69ff2e9-6d48-4e03-a920-5c9831d864ea
                      account_number:
                        description: Número de la cuenta bancaria registrada.
                        type: string
                        example: '1234567890'
                      account_type:
                        $ref: '#/components/schemas/AccountType'
                      bank:
                        description: Información del banco asociado a la cuenta.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del banco en la base de datos.
                            type: string
                            example: 03faad35-36e4-5603-898c-8fcb97ff4bc7
                          name:
                            description: Nombre comercial del banco.
                            type: string
                            example: Bancolombia
                          coded_name:
                            description: Código interno del banco utilizado para identificar el formato de archivo bancario compatible.
                            type: string
                            example: bancolombia
                          supported_file:
                            description: Indica si el banco soporta generación de archivo bancario para el pago de nómina.
                            type: boolean
                            example: true
              example:
                data:
                  id: b69ff2e9-6d48-4e03-a920-5c9831d864ea
                  account_number: '1234567890'
                  account_type: savings_account
                  bank:
                    id: 03faad35-36e4-5603-898c-8fcb97ff4bc7
                    name: Bancolombia
                    coded_name: bancolombia
                    supported_file: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Número de cuenta en blanco / Número de cuenta demasiado corto / Número de cuenta demasiado largo / Número de cuenta no numérico / Número de cuenta duplicado / Tipo de cuenta en blanco / Límite de cuentas alcanzado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Número de cuenta en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Número de cuenta no puede estar en blanco.
                        object: account_number
                Número de cuenta demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Número de cuenta es demasiado corto (7 caracteres mínimo).
                        object: account_number
                Número de cuenta demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Número de cuenta es demasiado largo (21 caracteres máximo).
                        object: account_number
                Número de cuenta no numérico:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Número de cuenta es inválido. Este debe ser un número.
                        object: account_number
                Número de cuenta duplicado:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Número de cuenta ya está en uso.
                        object: account_number
                Tipo de cuenta en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Tipo de cuenta no puede estar en blanco.
                        object: account_type
                Límite de cuentas alcanzado:
                  value:
                    error:
                      - code: '7001'
                        index: 0
                        message: Llegaste al límite de cuentas bancarias permitidas.
                        object: company_bank_account
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/company_bank_accounts/{id}:
    put:
      operationId: updateCompanyBankAccount
      tags:
        - Cuentas bancarias
      summary: Actualizar cuenta bancaria
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el banco, número o tipo de una cuenta bancaria existente de la empresa.

        **¿Cuándo usar este endpoint?**

        * Ajustar el número de cuenta o el tipo (ahorros/corriente) registrado incorrectamente.
        * Actualizar la cuenta cuando la empresa migra a un banco diferente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                bank_id:
                  description: Identificador único (ID) del banco al que pertenece la cuenta.
                  type: string
                  example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                account_number:
                  description: Número de la cuenta bancaria. Debe ser numérico y tener mínimo 7 dígitos.
                  type: string
                  example: '2587461230'
                account_type:
                  $ref: '#/components/schemas/AccountType'
      responses:
        '200':
          description: Cuenta bancaria actualizada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la cuenta bancaria.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la cuenta bancaria en la base de datos.
                        type: string
                        example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                      account_number:
                        description: Número de la cuenta bancaria actualizado.
                        type: string
                        example: '2587461230'
                      account_type:
                        $ref: '#/components/schemas/AccountType'
                      bank:
                        description: Información del banco asociado a la cuenta.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del banco en la base de datos.
                            type: string
                            example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                          name:
                            description: Nombre comercial del banco.
                            type: string
                            example: Bancolombia
                          coded_name:
                            description: Código interno del banco utilizado para identificar el formato de archivo bancario compatible.
                            type: string
                            example: bancolombia
                          supported_file:
                            description: Indica si el banco soporta generación de archivo bancario para el pago de nómina. Si es `false`, el pago debe gestionarse de forma manual.
                            type: boolean
                            example: true
              example:
                data:
                  id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                  account_number: '2587461230'
                  account_type: savings_account
                  bank:
                    id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                    name: Bancolombia
                    coded_name: bancolombia
                    supported_file: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Número de cuenta en blanco / Número de cuenta demasiado corto / Número de cuenta demasiado largo / Número de cuenta no numérico / Número de cuenta duplicado / Tipo de cuenta en blanco
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Número de cuenta en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Número de cuenta no puede estar en blanco.
                        object: account_number
                Número de cuenta demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Número de cuenta es demasiado corto (7 caracteres mínimo).
                        object: account_number
                Número de cuenta demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Número de cuenta es demasiado largo (21 caracteres máximo).
                        object: account_number
                Número de cuenta no numérico:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Número de cuenta es inválido. Este debe ser un número.
                        object: account_number
                Número de cuenta duplicado:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Número de cuenta ya está en uso.
                        object: account_number
                Tipo de cuenta en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Tipo de cuenta no puede estar en blanco.
                        object: account_type
    delete:
      operationId: destroyCompanyBankAccount
      tags:
        - Cuentas bancarias
      summary: Eliminar cuenta bancaria
      description: |
        **¿Qué hace este endpoint?**

        Elimina una cuenta bancaria registrada de la empresa.

        **¿Cuándo usar este endpoint?**

        * Dar de baja una cuenta cuando la empresa cierra o deja de usar una cuenta bancaria para el pago de nómina.
        * Eliminar una cuenta duplicada o registrada por error antes de generar archivos bancarios.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Restricción de eliminación:** No se puede eliminar la cuenta si es la única registrada y la empresa tiene configurado el pago por transferencia bancaria.
      responses:
        '200':
          description: Cuenta bancaria eliminada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: Cuenta bancaria eliminada correctamente
              example:
                data:
                  message: Cuenta bancaria eliminada correctamente
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Única cuenta con transferencia bancaria activa / Cuenta principal no eliminable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Única cuenta con transferencia bancaria activa:
                  value:
                    error:
                      - code: '7002'
                        index: 0
                        message: Debes tener al menos una cuenta bancaria para poder realizar el pago por transferencia.
                        object: company_bank_account
                Cuenta principal no eliminable:
                  value:
                    error:
                      - code: '7003'
                        index: 0
                        message: No se puede eliminar la cuenta bancaria principal de la empresa.
                        object: company_bank_account
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la cuenta bancaria en la base de datos.
        schema:
          type: string
          example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
  /v1/{company_id}/company_configuration_options:
    get:
      operationId: showCompanyConfigurationOptions
      tags:
        - Configuración de empresa
      summary: Obtener opciones de configuración
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones válidas para cada campo de configuración de la empresa, con etiquetas legibles (`label`) y valores técnicos (`value`) listos para usarse en el endpoint de actualización de configuración.

        **¿Cuándo usar este endpoint?**

        * Obtener los pares `label`/`value` válidos para cada campo antes de enviar una actualización de configuración.
        * Validar qué valores acepta cada campo de configuración sin depender de documentación externa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Opciones de configuración retornadas correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones válidas para cada campo de configuración de la empresa.
                    type: object
                    properties:
                      accrued_income_with_non_salary:
                        type: array
                        description: Opciones para incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí, incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí, incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                            value: true
                          - label: No, no incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                            value: false
                      apply_art102_cst:
                        type: array
                        description: Opciones para aplicar el Artículo 102 del CST (pago de 360 días).
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí, habilitar opción donde un año escolar equivale a un año calendario.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí, habilitar opción donde un año escolar equivale a un año calendario.
                            value: true
                          - label: No, no habilitar opción.
                            value: false
                      deduct_not_worked_concepts_from_service_bonus:
                        type: array
                        description: Opciones de novedades no remuneradas que se descuentan de la prima de servicios.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Se descuenta licencia no remunerada, suspensión y ausencia injustificada.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Se descuenta licencia no remunerada, suspensión y ausencia injustificada.
                            value: true
                          - label: Solo se descuenta ausencia injustificada.
                            value: false
                      edit_periods:
                        type: array
                        description: Opciones para la activación de edición de periodos históricos.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Activa
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Activa
                            value: true
                          - label: Inactiva
                            value: false
                      general_incapacity_payment:
                        type: array
                        description: Opciones para la forma de cálculo de la incapacidad general.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Al 66,67% del día 1 al 90.
                            value:
                              type: string
                              description: Valor técnico de la opción.
                              example: legal
                        example:
                          - label: Al 66,67% del día 1 al 90.
                            value: legal
                          - label: Al 100% en los primeros 2 días y del día 3 al 90 al 66,67%.
                            value: 2_days
                          - label: Al 100% del día 1 al 90.
                            value: full_salary
                      integrated_counterpart_code:
                        type: array
                        description: Opciones para las contrapartidas de subsidio de transporte, otros ingresos, horas extras y recargos.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Consolidados con la contrapartida de salario
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Consolidados con la contrapartida de salario
                            value: true
                          - label: Separados, cada cuenta con su contrapartida
                            value: false
                      part_time_paid_rest:
                        type: array
                        description: Opciones para la inclusión del descanso obligatorio remunerado en las nóminas de personas con contrato tiempo parcial.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí, incluir descanso obligatorio remunerado en la nómina.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí, incluir descanso obligatorio remunerado en la nómina.
                            value: true
                          - label: No, no incluir descanso obligatorio remunerado en la nómina.
                            value: false
                      pay_february_extra_days_if_hired_in_month:
                        type: array
                        description: Opciones para la forma de pago de febrero cuando una persona es contratada durante ese mes.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Pagar febrero como si tuviera 30 días.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Pagar febrero como si tuviera 30 días.
                            value: true
                          - label: Pagar los días reales (28 o 29) de febrero.
                            value: false
                      pay_holidays_31:
                        type: array
                        description: Opciones para el pago del día 31 del mes durante las vacaciones.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí pagar el 31.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí pagar el 31.
                            value: true
                          - label: No pagar el 31.
                            value: false
                      proportional_deductions:
                        type: array
                        description: Opciones para la forma de pago de las deducciones (no retenciones).
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Proporcionales en cada pago.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Proporcionales en cada pago.
                            value: true
                          - label: Al final del periodo.
                            value: false
                      signature_in_labor_certificate:
                        type: array
                        description: Opciones para la visibilidad de la firma en los certificados laborales.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí, incluir firma en certificados laborales.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí, incluir firma en certificados laborales.
                            value: true
                          - label: No, no incluir firma en certificados laborales.
                            value: false
                      signature_in_payslip:
                        type: array
                        description: Opciones para la visibilidad de la firma en las colillas de pago.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí, incluir firma en colillas de pago.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí, incluir firma en colillas de pago.
                            value: true
                          - label: No, no incluir firma en colillas de pago.
                            value: false
                      social_security_accounting:
                        type: array
                        description: Opciones para la causación de los aportes a la seguridad social.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Con el número de identificación de la persona.
                            value:
                              type: string
                              description: Valor técnico de la opción.
                              example: worker
                        example:
                          - label: Con el número de identificación de la persona.
                            value: worker
                          - label: Con el NIT de las instituciones.
                            value: institution
                          - label: Con el NIT de las instituciones y agregado por centro de costos.
                            value: cost_center
                      social_security_file_type:
                        type: array
                        description: Opciones para el tipo de archivo de seguridad social.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Único
                            value:
                              type: string
                              description: Valor técnico de la opción.
                              example: unique
                        example:
                          - label: Único
                            value: unique
                          - label: Por sucursal
                            value: branch
                      transport_subsidy_base:
                        type: array
                        description: Opciones para la afectación de los ingresos salariales al subsidio de transporte.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Salario + ingresos salariales + novedades del periodo.
                            value:
                              type: string
                              description: Valor técnico de la opción.
                              example: salary_income
                        example:
                          - label: Salario + ingresos salariales + novedades del periodo.
                            value: salary_income
                          - label: Salario + novedades de días del periodo.
                            value: salary_and_novelties
                          - label: Salario + ingresos salariales del periodo.
                            value: salary_income_without_novelties
                          - label: Solo salario básico.
                            value: only_salary
                      transport_subsidy_per_period:
                        type: array
                        description: Opciones para la frecuencia de pago del subsidio de transporte.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Quincenal.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Quincenal.
                            value: true
                          - label: Mensual.
                            value: false
                      uvt_configuration:
                        type: array
                        description: Opciones para la configuración de los UVTs para la retención en la fuente.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Fijar tope de UVT's mes a mes
                            value:
                              type: string
                              description: Valor técnico de la opción.
                              example: monthly_uvt
                        example:
                          - label: Fijar tope de UVT's mes a mes
                            value: monthly_uvt
                          - label: Validación de UVTs anual
                            value: yearly_uvt
                      withholding_tax_per_period:
                        type: array
                        description: Opciones para la frecuencia de aplicación de la retención en la fuente.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Quincenal.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Quincenal.
                            value: true
                          - label: Mensual.
                            value: false
                      worker_pension_unpaid_license:
                        type: array
                        description: Opciones para el método de pago de la pensión durante licencias no remuneradas.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí. Pagar pensión completa en licencias no remuneradas, tanto el porcentaje de la empresa como del empleado.
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí. Pagar pensión completa en licencias no remuneradas, tanto el porcentaje de la empresa como del empleado.
                            value: true
                          - label: No. Pagar solamente la parte de pensión correspondiente a la empresa en licencias no remuneradas.
                            value: false
                      workers_benefits:
                        type: array
                        description: Opciones para habilitar el módulo de beneficios para personas.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí
                            value: true
                          - label: 'No'
                            value: false
                      workers_handle_novelties:
                        type: array
                        description: Opciones para la autogestión de novedades por parte de las personas.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí
                            value: true
                          - label: 'No'
                            value: false
                      workers_income_certificate_access:
                        type: array
                        description: Opciones para permitir a las personas descargar su certificado de ingresos y retenciones.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí
                            value: true
                          - label: 'No'
                            value: false
                      workers_labor_certificate_access:
                        type: array
                        description: Opciones para permitir a las personas descargar su certificado laboral.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí
                            value: true
                          - label: 'No'
                            value: false
                      workers_payslips_access:
                        type: array
                        description: Opciones para permitir a las personas descargar sus colillas de pago.
                        items:
                          type: object
                          properties:
                            label:
                              type: string
                              description: Etiqueta legible de la opción.
                              example: Sí
                            value:
                              type: boolean
                              description: Valor técnico de la opción.
                              example: true
                        example:
                          - label: Sí
                            value: true
                          - label: 'No'
                            value: false
              example:
                data:
                  accrued_income_with_non_salary:
                    - label: Sí, incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                      value: true
                    - label: No, no incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                      value: false
                  general_incapacity_payment:
                    - label: Al 66,67% del día 1 al 90.
                      value: legal
                    - label: Al 100% en los primeros 2 días y del día 3 al 90 al 66,67%.
                      value: 2_days
                    - label: Al 100% del día 1 al 90.
                      value: full_salary
                  social_security_file_type:
                    - label: Único
                      value: unique
                    - label: Por sucursal
                      value: branch
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 0001ce28-d7ca-4103-85a0-582dffdc43f9
  /v1/{company_id}/company_configurations:
    get:
      operationId: showCompanyConfiguration
      tags:
        - Configuración de empresa
      summary: Obtener configuración de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Retorna la configuración actual de la empresa, incluyendo las opciones de liquidación, seguridad social, retención en la fuente, subsidio de transporte y firma para documentos.

        **¿Cuándo usar este endpoint?**

        * Consultar la configuración vigente antes de editar algún parámetro.
        * Verificar qué opciones de nómina tiene habilitadas la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Configuración retornada correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Configuración actual de la empresa.
                    type: object
                    properties:
                      accrued_income_with_non_salary:
                        type: boolean
                        description: Configuración para incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                        example: false
                      apply_art102_cst:
                        type: boolean
                        description: Configuración para aplicar el Artículo 102 del CST (pago de 360 días).
                        example: false
                      deduct_not_worked_concepts_from_service_bonus:
                        type: boolean
                        description: Configuración de las novedades no remuneradas que se descuentan de la prima de servicios.
                        example: false
                      edit_periods:
                        type: boolean
                        description: Configuración de la activación de edición de periodos históricos.
                        example: false
                      general_incapacity_payment:
                        type: string
                        description: Configuración de la forma de cálculo para la incapacidad general.
                        example: 2_days
                      has_labor_certificate_signature:
                        type: boolean
                        description: Indica si la empresa tiene configurada la información de la firma para los documentos.
                        example: false
                      integrated_counterpart_code:
                        type: boolean
                        description: Configuración de las contrapartidas de subsidio de transporte, otros ingresos, horas extras y recargos.
                        example: false
                      labor_certificate_signature:
                        type: object
                        description: Información de la firma para el certificado laboral y colillas de pago.
                        properties:
                          signee_name:
                            type: string
                            description: Nombre de la persona asociada a la firma.
                            example: Juan Pérez
                          signee_email:
                            type: string
                            description: Correo electrónico de la persona asociada a la firma.
                            example: juan.perez@empresa.com
                          signee_phone:
                            type: string
                            description: Teléfono de la persona asociada a la firma.
                            example: '3001234567'
                          signee_position:
                            type: string
                            description: Cargo de la persona asociada a la firma.
                            example: Gerente General
                          signee_id_number:
                            type: string
                            description: Número de identificación de la persona asociada a la firma.
                            example: '1000000000'
                          signee_document_type:
                            type: string
                            description: Tipo de documento de identidad de la persona asociada a la firma.
                            example: CC
                          signature_image:
                            type: string
                            description: URL de la imagen de la firma.
                            example: https://storage.example.com/firma.png
                      part_time_paid_rest:
                        type: boolean
                        description: Configuración para incluir el descanso obligatorio remunerado en las nóminas de las personas con contrato tiempo parcial.
                        example: true
                      pay_february_extra_days_if_hired_in_month:
                        type: boolean
                        description: Configuración de la forma de pago de febrero si una persona es contratada durante este mes.
                        example: true
                      pay_holidays_31:
                        type: boolean
                        description: Configuración del pago correspondiente al día 31 del mes durante las vacaciones.
                        example: false
                      proportional_deductions:
                        type: boolean
                        description: Configuración de la forma de pago de las deducciones (no retenciones).
                        example: false
                      signature_in_labor_certificate:
                        type: boolean
                        description: Configuración de la visibilidad de la firma en los certificados laborales.
                        example: true
                      signature_in_payslip:
                        type: boolean
                        description: Configuración de la visibilidad de la firma en las colillas de pago.
                        example: false
                      social_security_accounting:
                        type: string
                        description: Configuración de la causación de los aportes a la seguridad social.
                        example: worker
                      social_security_file_type:
                        type: string
                        description: Configuración del tipo de archivo de seguridad social.
                        enum:
                          - unique
                          - branch
                        example: branch
                      transport_subsidy_base:
                        type: string
                        description: Configuración de la afectación de los ingresos salariales al subsidio de transporte.
                        enum:
                          - salary_income
                          - salary_and_novelties
                          - salary_income_without_novelties
                          - only_salary
                        example: salary_income_without_novelties
                      transport_subsidy_per_period:
                        type: boolean
                        description: Configuración de la frecuencia de pago del subsidio de transporte.
                        example: true
                      uvt_configuration:
                        type: string
                        description: Configuración de los UVTs para la retención en la fuente.
                        example: monthly_uvt
                      with_credits:
                        type: boolean
                        description: Indica si el módulo de crédito para personas está habilitado en la empresa.
                        example: true
                      withholding_tax_per_period:
                        type: boolean
                        description: Configuración de la frecuencia en que se aplica la retención en la fuente.
                        example: true
                      worker_pension_unpaid_license:
                        type: boolean
                        description: Configuración del método de pago de la pensión durante licencias no remuneradas.
                        example: true
                      workers_benefits:
                        type: boolean
                        description: Indica si el módulo de beneficios para personas está habilitado en la empresa.
                        example: false
                      workers_handle_novelties:
                        type: boolean
                        description: Configuración de la autogestión de novedades para las personas.
                        example: true
                      workers_income_certificate_access:
                        type: boolean
                        description: Configuración del acceso de las personas para descargar su certificado de ingresos y retenciones.
                        example: true
                      workers_labor_certificate_access:
                        type: boolean
                        description: Configuración del acceso de las personas para descargar su certificado laboral.
                        example: true
                      workers_payslips_access:
                        type: boolean
                        description: Configuración del acceso de las personas para descargar sus colillas de pago.
                        example: true
              example:
                data:
                  accrued_income_with_non_salary: false
                  apply_art102_cst: false
                  deduct_not_worked_concepts_from_service_bonus: false
                  edit_periods: false
                  general_incapacity_payment: 2_days
                  has_labor_certificate_signature: true
                  integrated_counterpart_code: false
                  labor_certificate_signature:
                    signee_name: Juan Pérez
                    signee_email: juan.perez@empresa.com
                    signee_phone: '3001234567'
                    signee_position: Gerente General
                    signee_id_number: '1000000000'
                    signee_document_type: CC
                    signature_image: https://storage.example.com/firma.png
                  part_time_paid_rest: true
                  pay_february_extra_days_if_hired_in_month: true
                  pay_holidays_31: false
                  proportional_deductions: false
                  signature_in_labor_certificate: true
                  signature_in_payslip: false
                  social_security_accounting: worker
                  social_security_file_type: branch
                  transport_subsidy_base: salary_income_without_novelties
                  transport_subsidy_per_period: true
                  uvt_configuration: monthly_uvt
                  with_credits: true
                  withholding_tax_per_period: true
                  worker_pension_unpaid_license: true
                  workers_benefits: false
                  workers_handle_novelties: true
                  workers_income_certificate_access: true
                  workers_labor_certificate_access: true
                  workers_payslips_access: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateCompanyConfiguration
      tags:
        - Configuración de empresa
      summary: Actualizar configuración de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Actualiza uno o varios parámetros de configuración de la empresa. Solo se deben enviar los campos que se desean modificar.

        Cuando se envía `signature_image`, la respuesta retorna únicamente los campos `has_labor_certificate_signature` y `labor_certificate_signature`. En cualquier otro caso, retorna la configuración completa.

        **¿Cuándo usar este endpoint?**

        * Cambiar la forma de cálculo de incapacidades, deducciones o subsidio de transporte.
        * Activar o desactivar la firma en certificados laborales y colillas de pago.
        * Actualizar la imagen o datos de la persona firmante.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * Para consultar los valores válidos de cada campo, usar el endpoint de opciones de configuración.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                accrued_income_with_non_salary:
                  type: boolean
                  description: Configuración para incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                  example: false
                apply_art102_cst:
                  type: boolean
                  description: Configuración para aplicar el Artículo 102 del CST (pago de 360 días).
                  example: false
                deduct_not_worked_concepts_from_service_bonus:
                  type: boolean
                  description: Configuración de las novedades no remuneradas que se descuentan de la prima de servicios.
                  example: false
                edit_periods:
                  type: boolean
                  description: Configuración de la activación de edición de periodos históricos.
                  example: false
                general_incapacity_payment:
                  type: string
                  description: Configuración de la forma de cálculo para la incapacidad general.
                  example: legal
                integrated_counterpart_code:
                  type: boolean
                  description: Configuración de las contrapartidas de subsidio de transporte, otros ingresos, horas extras y recargos.
                  example: true
                part_time_paid_rest:
                  type: boolean
                  description: Configuración para incluir el descanso obligatorio remunerado en las nóminas de las personas con contrato tiempo parcial.
                  example: false
                pay_february_extra_days_if_hired_in_month:
                  type: boolean
                  description: Configuración de la forma de pago de febrero si una persona es contratada durante este mes.
                  example: false
                pay_holidays_31:
                  type: boolean
                  description: Configuración del pago correspondiente al día 31 del mes durante las vacaciones.
                  example: true
                proportional_deductions:
                  type: boolean
                  description: Configuración de la forma de pago de las deducciones (no retenciones).
                  example: false
                signature_image:
                  type: string
                  format: binary
                  description: Imagen de la firma en formato PNG o JPEG. Al enviarse, la respuesta retorna únicamente los campos de firma.
                  example: firma.png
                signee_document_type:
                  type: string
                  description: Tipo de documento de identidad de la persona firmante.
                  example: CC
                signee_email:
                  type: string
                  description: Correo electrónico de la persona firmante.
                  example: juan.perez@empresa.com
                signee_id_number:
                  type: string
                  description: Número de identificación de la persona firmante.
                  example: '1000000000'
                signee_name:
                  type: string
                  description: Nombre completo de la persona firmante.
                  example: Juan Pérez
                signee_phone:
                  type: string
                  description: Teléfono de la persona firmante.
                  example: '3001234567'
                signee_position:
                  type: string
                  description: Cargo de la persona firmante.
                  example: Gerente General
                signature_in_labor_certificate:
                  type: boolean
                  description: Visibilidad de la firma en los certificados laborales.
                  example: true
                signature_in_payslip:
                  type: boolean
                  description: Visibilidad de la firma en las colillas de pago.
                  example: false
                social_security_accounting:
                  type: string
                  description: Configuración de la causación de los aportes a la seguridad social.
                  example: institution
                social_security_file_type:
                  type: string
                  description: Configuración del tipo de archivo de seguridad social.
                  enum:
                    - unique
                    - branch
                  example: unique
                transport_subsidy_base:
                  type: string
                  description: Configuración de la afectación de los ingresos salariales al subsidio de transporte.
                  enum:
                    - salary_income
                    - salary_and_novelties
                    - salary_income_without_novelties
                    - only_salary
                  example: salary_income_without_novelties
                transport_subsidy_per_period:
                  type: boolean
                  description: Configuración de la frecuencia de pago del subsidio de transporte.
                  example: false
                uvt_configuration:
                  type: string
                  description: Configuración de los UVTs para la retención en la fuente.
                  example: yearly_uvt
                withholding_tax_per_period:
                  type: boolean
                  description: Configuración de la frecuencia en que se aplica la retención en la fuente.
                  example: true
                worker_pension_unpaid_license:
                  type: boolean
                  description: Configuración del método de pago de la pensión durante licencias no remuneradas.
                  example: false
                workers_handle_novelties:
                  type: boolean
                  description: Configuración de la autogestión de novedades para las personas.
                  example: true
                workers_income_certificate_access:
                  type: boolean
                  description: Configuración del acceso de las personas para descargar su certificado de ingresos y retenciones.
                  example: true
                workers_labor_certificate_access:
                  type: boolean
                  description: Configuración del acceso de las personas para descargar su certificado laboral.
                  example: true
                workers_payslips_access:
                  type: boolean
                  description: Configuración del acceso de las personas para descargar sus colillas de pago.
                  example: true
      responses:
        '202':
          description: Configuración actualizada correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Configuración actual de la empresa.
                    type: object
                    properties:
                      accrued_income_with_non_salary:
                        type: boolean
                        description: Configuración para incluir ingresos no salariales en el devengado para el cálculo del límite de la Ley 1607.
                        example: false
                      apply_art102_cst:
                        type: boolean
                        description: Configuración para aplicar el Artículo 102 del CST (pago de 360 días).
                        example: false
                      deduct_not_worked_concepts_from_service_bonus:
                        type: boolean
                        description: Configuración de las novedades no remuneradas que se descuentan de la prima de servicios.
                        example: false
                      edit_periods:
                        type: boolean
                        description: Configuración de la activación de edición de periodos históricos.
                        example: false
                      general_incapacity_payment:
                        type: string
                        description: Configuración de la forma de cálculo para la incapacidad general.
                        example: 2_days
                      has_labor_certificate_signature:
                        type: boolean
                        description: Indica si la empresa tiene configurada la información de la firma para los documentos.
                        example: false
                      integrated_counterpart_code:
                        type: boolean
                        description: Configuración de las contrapartidas de subsidio de transporte, otros ingresos, horas extras y recargos.
                        example: false
                      labor_certificate_signature:
                        type: object
                        description: Información de la firma para el certificado laboral y colillas de pago.
                        properties:
                          signee_name:
                            type: string
                            description: Nombre de la persona asociada a la firma.
                            example: Juan Pérez
                          signee_email:
                            type: string
                            description: Correo electrónico de la persona asociada a la firma.
                            example: juan.perez@empresa.com
                          signee_phone:
                            type: string
                            description: Teléfono de la persona asociada a la firma.
                            example: '3001234567'
                          signee_position:
                            type: string
                            description: Cargo de la persona asociada a la firma.
                            example: Gerente General
                          signee_id_number:
                            type: string
                            description: Número de identificación de la persona asociada a la firma.
                            example: '1000000000'
                          signee_document_type:
                            type: string
                            description: Tipo de documento de identidad de la persona asociada a la firma.
                            example: CC
                          signature_image:
                            type: string
                            description: URL de la imagen de la firma.
                            example: https://storage.example.com/firma.png
                      part_time_paid_rest:
                        type: boolean
                        description: Configuración para incluir el descanso obligatorio remunerado en las nóminas de las personas con contrato tiempo parcial.
                        example: true
                      pay_february_extra_days_if_hired_in_month:
                        type: boolean
                        description: Configuración de la forma de pago de febrero si una persona es contratada durante este mes.
                        example: true
                      pay_holidays_31:
                        type: boolean
                        description: Configuración del pago correspondiente al día 31 del mes durante las vacaciones.
                        example: false
                      proportional_deductions:
                        type: boolean
                        description: Configuración de la forma de pago de las deducciones (no retenciones).
                        example: false
                      signature_in_labor_certificate:
                        type: boolean
                        description: Configuración de la visibilidad de la firma en los certificados laborales.
                        example: true
                      signature_in_payslip:
                        type: boolean
                        description: Configuración de la visibilidad de la firma en las colillas de pago.
                        example: false
                      social_security_accounting:
                        type: string
                        description: Configuración de la causación de los aportes a la seguridad social.
                        example: worker
                      social_security_file_type:
                        type: string
                        description: Configuración del tipo de archivo de seguridad social.
                        enum:
                          - unique
                          - branch
                        example: branch
                      transport_subsidy_base:
                        type: string
                        description: Configuración de la afectación de los ingresos salariales al subsidio de transporte.
                        enum:
                          - salary_income
                          - salary_and_novelties
                          - salary_income_without_novelties
                          - only_salary
                        example: salary_income_without_novelties
                      transport_subsidy_per_period:
                        type: boolean
                        description: Configuración de la frecuencia de pago del subsidio de transporte.
                        example: true
                      uvt_configuration:
                        type: string
                        description: Configuración de los UVTs para la retención en la fuente.
                        example: monthly_uvt
                      with_credits:
                        type: boolean
                        description: Indica si el módulo de crédito para personas está habilitado en la empresa.
                        example: true
                      withholding_tax_per_period:
                        type: boolean
                        description: Configuración de la frecuencia en que se aplica la retención en la fuente.
                        example: true
                      worker_pension_unpaid_license:
                        type: boolean
                        description: Configuración del método de pago de la pensión durante licencias no remuneradas.
                        example: true
                      workers_benefits:
                        type: boolean
                        description: Indica si el módulo de beneficios para personas está habilitado en la empresa.
                        example: false
                      workers_handle_novelties:
                        type: boolean
                        description: Configuración de la autogestión de novedades para las personas.
                        example: true
                      workers_income_certificate_access:
                        type: boolean
                        description: Configuración del acceso de las personas para descargar su certificado de ingresos y retenciones.
                        example: true
                      workers_labor_certificate_access:
                        type: boolean
                        description: Configuración del acceso de las personas para descargar su certificado laboral.
                        example: true
                      workers_payslips_access:
                        type: boolean
                        description: Configuración del acceso de las personas para descargar sus colillas de pago.
                        example: true
              example:
                data:
                  accrued_income_with_non_salary: false
                  apply_art102_cst: false
                  deduct_not_worked_concepts_from_service_bonus: false
                  edit_periods: false
                  general_incapacity_payment: 2_days
                  has_labor_certificate_signature: true
                  integrated_counterpart_code: false
                  labor_certificate_signature:
                    signee_name: Juan Pérez
                    signee_email: juan.perez@empresa.com
                    signee_phone: '3001234567'
                    signee_position: Gerente General
                    signee_id_number: '1000000000'
                    signee_document_type: CC
                    signature_image: https://storage.example.com/firma.png
                  part_time_paid_rest: true
                  pay_february_extra_days_if_hired_in_month: true
                  pay_holidays_31: false
                  proportional_deductions: false
                  signature_in_labor_certificate: true
                  signature_in_payslip: false
                  social_security_accounting: worker
                  social_security_file_type: branch
                  transport_subsidy_base: salary_income_without_novelties
                  transport_subsidy_per_period: true
                  uvt_configuration: monthly_uvt
                  with_credits: true
                  withholding_tax_per_period: true
                  worker_pension_unpaid_license: true
                  workers_benefits: false
                  workers_handle_novelties: true
                  workers_income_certificate_access: true
                  workers_labor_certificate_access: true
                  workers_payslips_access: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Imagen de firma inválida / Campo del firmante en blanco / Campo del firmante demasiado corto / Campo del firmante demasiado largo / Tipo de documento inválido / Correo electrónico inválido / Número de documento fuera de rango / Caracteres inválidos en campo de firma
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Imagen de firma inválida:
                  value:
                    error:
                      - code: '0313'
                        index: 0
                        message: Imagen de la firma para certificados laborales es un archivo corrupto.
                        object: signature_image_file
                Campo del firmante en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre del firmante no puede estar en blanco.
                        object: signee_name
                Campo del firmante demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre del firmante es demasiado corto (4 caracteres mínimo).
                        object: signee_name
                Campo del firmante demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Nombre del firmante es demasiado largo (60 caracteres máximo).
                        object: signee_name
                Tipo de documento inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Tipo de documento del firmante es inválido.
                        object: signee_document_type
                Correo electrónico inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Correo electrónico del firmante es inválido.
                        object: signee_email
                Número de documento fuera de rango:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Número de documento del firmante es demasiado corto (6 caracteres mínimo).
                        object: signee_id_number
                Caracteres inválidos en campo de firma:
                  value:
                    error:
                      - code: '0118'
                        index: 0
                        message: 'Nombre del firmante contiene uno o más de los siguientes caracteres inválidos: ''<>$\''.'
                        object: signee_name
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 4853fe09-fb85-4015-9dca-c8fd0245223f
  /v1/{company_id}/company_credentials:
    get:
      operationId: indexCompanyCredentials
      tags:
        - Credenciales de empresa
      summary: Listar credenciales de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de credenciales de seguridad social registradas para la empresa, con el usuario y contraseña de acceso a cada operador.

        **¿Cuándo usar este endpoint?**

        * Consultar qué credenciales de operadores tiene configuradas la empresa antes de generar la planilla PILA.
        * Filtrar por categoría de institución para verificar credenciales específicas (EPS, ARL, etc.).

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * Si no se envía el parámetro `categories`, se retornan todas las credenciales de la empresa sin filtro.
        * Las categorías válidas son: `compensation_fund`, `health_provider`, `pension_provider`, `risk_provider`, `severance_provider`.
      parameters:
        - name: categories
          in: query
          required: false
          description: |
            Filtro por categoría de institución. Se pueden enviar múltiples valores como arreglo.
            Categorías válidas: `compensation_fund`, `health_provider`, `pension_provider`, `risk_provider`, `severance_provider`.
          schema:
            type: array
            items:
              type: string
            example:
              - risk_provider
              - health_provider
      responses:
        '200':
          description: Credenciales registradas / Sin credenciales registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de credenciales de seguridad social de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: Identificador único (ID) asignado a la credencial en la base de datos.
                          example: 2a9240b3-a0b9-5147-b009-e929d9cd3433
                        institution_id:
                          type: string
                          description: Identificador único (ID) asignado a la institución en la base de datos.
                          example: c0358bc8-42af-5574-871e-cf4ae3a12110
                        institution_name:
                          type: string
                          description: Nombre de la institución asociada a la credencial.
                          example: Positiva Compañía de Seguros
                        institution_category:
                          type: string
                          description: Categoría de la institución asociada a la credencial.
                          example: risk_provider
                        username:
                          type: string
                          description: Nombre de usuario de acceso al portal del operador.
                          example: empresa_positiva
                        password:
                          type: string
                          description: Contraseña de acceso al portal del operador.
                          example: Cl4v3Segura!
              examples:
                Credenciales registradas:
                  value:
                    data:
                      - id: 2a9240b3-a0b9-5147-b009-e929d9cd3433
                        institution_id: c0358bc8-42af-5574-871e-cf4ae3a12110
                        institution_name: Positiva Compañía de Seguros
                        institution_category: risk_provider
                        username: empresa_positiva
                        password: Cl4v3Segura!
                      - id: e7ba5d99-03d5-5b9c-90fc-3d4b12afa331
                        institution_id: 18f32bf8-a308-55b2-bf8d-347855c7cde2
                        institution_name: Compensar EPS
                        institution_category: health_provider
                        username: empresa_compensar
                        password: OtroPass2024
                Sin credenciales registradas:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateCompanyCredentials
      tags:
        - Credenciales de empresa
      summary: Gestionar credenciales de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Crea, actualiza o elimina credenciales de la empresa en una sola operación. La acción se determina según los campos enviados en cada objeto del arreglo `company_credentials`:

        * **Crear:** Sin `id` — crea una nueva credencial con `username`, `password` e `institution_id`.
        * **Actualizar:** Con `id` y uno o más de `username`, `password`, `institution_id` — actualiza los campos enviados.
        * **Eliminar:** Con `id` únicamente, sin otros campos — elimina la credencial.

        Todas las operaciones se ejecutan en una transacción atómica.

        **¿Cuándo usar este endpoint?**

        * Registrar las credenciales de acceso a operadores de seguridad social antes de generar la planilla PILA.
        * Actualizar usuario o contraseña cuando cambian las credenciales en el portal del operador.
        * Eliminar credenciales de instituciones que ya no aplican a la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * Solo se puede registrar una credencial por institución (combinación única de `institution_id` + `company_id`).
        * La `institution_id` debe corresponder a una institución válida de las categorías: `risk_provider`, `health_provider`, `pension_provider`, `compensation_fund` o `severance_provider`.
      requestBody:
        required: true
        description: Crear credencial / Actualizar credencial / Eliminar credencial / Operación combinada
        content:
          application/json:
            schema:
              type: object
              properties:
                company_credentials:
                  type: array
                  description: Arreglo de credenciales a crear, actualizar o eliminar.
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Identificador único (ID) asignado a la credencial en la base de datos. Requerido para actualizar o eliminar.
                        example: 2a9240b3-a0b9-5147-b009-e929d9cd3433
                      institution_id:
                        type: string
                        description: Identificador único (ID) asignado a la institución en la base de datos. Requerido al crear.
                        example: c0358bc8-42af-5574-871e-cf4ae3a12110
                      username:
                        type: string
                        description: Nombre de usuario de la credencial.
                        example: empresa_positiva
                      password:
                        type: string
                        description: Contraseña de la credencial.
                        example: Cl4v3Segura!
              required:
                - company_credentials
            examples:
              Crear credencial:
                value:
                  company_credentials:
                    - institution_id: c0358bc8-42af-5574-871e-cf4ae3a12110
                      username: empresa_positiva
                      password: Cl4v3Segura!
              Actualizar credencial:
                value:
                  company_credentials:
                    - id: e7ba5d99-03d5-5b9c-90fc-3d4b12afa331
                      username: empresa_compensar_nuevo
                      password: NuevoPass2024!
              Eliminar credencial:
                value:
                  company_credentials:
                    - id: 9f1a2b3c-1234-5678-abcd-ef0123456789
              Operación combinada:
                value:
                  company_credentials:
                    - institution_id: c0358bc8-42af-5574-871e-cf4ae3a12110
                      username: empresa_positiva
                      password: Cl4v3Segura!
                    - id: e7ba5d99-03d5-5b9c-90fc-3d4b12afa331
                      username: empresa_compensar_nuevo
                    - id: 9f1a2b3c-1234-5678-abcd-ef0123456789
      responses:
        '202':
          description: Credenciales procesadas correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de credenciales de seguridad social de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: Identificador único (ID) asignado a la credencial en la base de datos.
                          example: 2a9240b3-a0b9-5147-b009-e929d9cd3433
                        institution_id:
                          type: string
                          description: Identificador único (ID) asignado a la institución en la base de datos.
                          example: c0358bc8-42af-5574-871e-cf4ae3a12110
                        institution_name:
                          type: string
                          description: Nombre de la institución asociada a la credencial.
                          example: Positiva Compañía de Seguros
                        institution_category:
                          type: string
                          description: Categoría de la institución asociada a la credencial.
                          example: risk_provider
                        username:
                          type: string
                          description: Nombre de usuario de acceso al portal del operador.
                          example: empresa_positiva
                        password:
                          type: string
                          description: Contraseña de acceso al portal del operador.
                          example: Cl4v3Segura!
              example:
                data:
                  - id: 2a9240b3-a0b9-5147-b009-e929d9cd3433
                    institution_id: c0358bc8-42af-5574-871e-cf4ae3a12110
                    institution_name: Positiva Compañía de Seguros
                    institution_category: risk_provider
                    username: empresa_positiva
                    password: Cl4v3Segura!
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Parámetros vacíos / Usuario o contraseña en blanco / Institución duplicada / Categoría de institución inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Parámetros vacíos:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
                Usuario en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Usuario no puede estar en blanco.
                        object: username
                Contraseña en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Contraseña no puede estar en blanco.
                        object: password
                Institución duplicada:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Institución ya está en uso.
                        object: institution_id
                Categoría de institución inválida:
                  value:
                    error:
                      - code: '3201'
                        index: 0
                        message: La categoría de la institución es inválida.
                        object: company_credential
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 7acbf6f9-35a8-4d6f-b442-73887e88a540
  /v1/{company_id}/company_dashboard:
    get:
      operationId: showCompanyDashboard
      tags:
        - Dashboard y métricas
      summary: Obtener dashboard de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información del dashboard de la empresa: métricas del equipo, costos de nómina, próximos pagos, pendientes y variaciones. Cada sección se genera solo si el parámetro `metrics` la incluye; si no se envía `metrics`, se retornan todas las secciones.

        **¿Cuándo usar este endpoint?**

        * Cargar el dashboard principal de la empresa con todas las métricas disponibles.
        * Solicitar solo las secciones necesarias enviando `metrics` con los nombres separados por coma para optimizar el tiempo de respuesta.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * Las secciones disponibles para `metrics` son: `costs_in_percentages`, `greet_message`, `next_payments`, `payroll_costs`, `pendings`, `period_information`, `variations`, `workers_information`.
      parameters:
        - name: metrics
          in: query
          required: false
          description: Lista de secciones del dashboard a retornar, separadas por coma. Si no se envía, se retornan todas.
          schema:
            type: string
            example: greet_message,pendings,workers_information
      responses:
        '200':
          description: Dashboard retornado correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Secciones del dashboard de la empresa. Solo se incluyen las secciones solicitadas mediante el parámetro `metrics`.
                    type: object
                    properties:
                      costs_in_percentages:
                        type: object
                        description: Distribución porcentual de los costos de nómina del periodo actual por categoría, sede y área.
                        properties:
                          initial_day:
                            type: string
                            format: date
                            description: Fecha de inicio del periodo de referencia.
                            example: '2024-01-01'
                          end_day:
                            type: string
                            format: date
                            description: Fecha de fin del periodo de referencia.
                            example: '2024-01-31'
                          staff:
                            type: array
                            description: Distribución porcentual por categoría de costo (salarios, seguridad social, extras, otros).
                            items:
                              type: object
                              properties:
                                name:
                                  type: string
                                  description: Nombre de la categoría de costo.
                                  example: Salarios
                                percentage:
                                  type:
                                    - string
                                    - 'null'
                                  description: Porcentaje del costo sobre el total. Nulo si no hay datos.
                                  example: '65.5'
                            example:
                              - name: Salarios
                                percentage: '65.5'
                              - name: Seguridad Social
                                percentage: '20.0'
                              - name: Extras y Recargos
                                percentage: '8.5'
                              - name: Otros pagos
                                percentage: '6.0'
                          cost_centers:
                            type: array
                            description: Distribución porcentual de costos por centro de costos.
                            items:
                              type: object
                              properties:
                                name:
                                  type: string
                                  description: Nombre del centro de costos.
                                  example: Sede Principal
                                percentage:
                                  type: number
                                  description: Porcentaje del costo sobre el total.
                                  example: 100
                            example:
                              - name: Sede Principal
                                percentage: 100
                          locations:
                            type: array
                            description: Distribución porcentual de costos por sede.
                            items:
                              type: object
                              properties:
                                name:
                                  type: string
                                  description: Nombre de la sede.
                                  example: Sede Norte
                                percentage:
                                  type: number
                                  description: Porcentaje del costo sobre el total.
                                  example: 63
                            example:
                              - name: Sede Norte
                                percentage: 63
                              - name: Sede Sur
                                percentage: 37
                          areas:
                            type: array
                            description: Distribución porcentual de costos por área.
                            items:
                              type: object
                              properties:
                                name:
                                  type: string
                                  description: Nombre del área.
                                  example: Tecnología
                                percentage:
                                  type: number
                                  description: Porcentaje del costo sobre el total.
                                  example: 50
                            example:
                              - name: Tecnología
                                percentage: 50
                              - name: Administración
                                percentage: 50
                      greet_message:
                        type: string
                        description: Mensaje de saludo personalizado para el usuario autenticado.
                        example: ¡Buenos días, Juan!
                      next_payments:
                        type: object
                        description: Resumen de los próximos pagos pendientes de la empresa.
                        properties:
                          payroll_payments:
                            type: integer
                            description: Monto total de la próxima nómina a pagar en pesos colombianos.
                            example: 3500000
                          social_security:
                            type: object
                            description: Información del próximo pago de seguridad social.
                            properties:
                              company_id_number:
                                type: boolean
                                description: Indica si la liquidación de seguridad social está configurada con NIT de la empresa.
                                example: false
                              limit_date:
                                type: string
                                format: date
                                description: Fecha límite para el pago de seguridad social.
                                example: '2024-06-21'
                              payment:
                                type: integer
                                description: Monto del próximo pago de seguridad social en pesos colombianos.
                                example: 850000
                              period_id:
                                type: string
                                description: Identificador único (ID) asignado al periodo en la base de datos.
                                example: 27aa440b-19dc-5ca4-9843-25e94d80eb08
                              status:
                                type: boolean
                                description: Indica si el pago de seguridad social del periodo ya fue realizado.
                                example: false
                          social_benefits:
                            type: object
                            description: Información de la próxima liquidación de prestaciones sociales.
                            properties:
                              category:
                                type: string
                                description: Categoría de la prestación social próxima a liquidar.
                                example: severance_interests
                              payment:
                                type: integer
                                description: Monto estimado de la próxima prestación social en pesos colombianos.
                                example: 120000
                              limit_date:
                                type: string
                                format: date
                                description: Fecha límite para liquidar la prestación social.
                                example: '2024-01-31'
                              show:
                                type: boolean
                                description: Indica si la sección de prestaciones sociales debe mostrarse en el dashboard.
                                example: true
                              status:
                                type: boolean
                                description: Indica si la prestación social del periodo ya fue liquidada.
                                example: false
                      payroll_costs:
                        type: array
                        description: Histórico mensual de costos de nómina de los últimos 6 meses.
                        items:
                          type: object
                          properties:
                            date:
                              type: string
                              format: date
                              description: Fecha de inicio del mes en formato YYYY-MM-DD.
                              example: '2024-01-01'
                            value:
                              type: integer
                              description: Costo total de nómina del mes en pesos colombianos.
                              example: 3500000
                        example:
                          - date: '2024-01-01'
                            value: 3500000
                          - date: '2023-12-01'
                            value: 3200000
                          - date: '2023-11-01'
                            value: 3400000
                      pendings:
                        type: object
                        description: Tareas pendientes de configuración y operación de la empresa.
                        properties:
                          accountant_added:
                            type: boolean
                            description: Indica si la empresa ya tiene un contador configurado.
                            example: true
                          activated:
                            type: boolean
                            description: Indica si la empresa está activa en la plataforma.
                            example: true
                          social_security_integration:
                            type: boolean
                            description: Indica si la integración con el operador de seguridad social está configurada.
                            example: false
                          electronic_payroll_authorized:
                            type: boolean
                            description: Indica si la empresa está autorizada para emitir nómina electrónica ante la DIAN.
                            example: false
                          next_payroll:
                            type: object
                            description: Información del siguiente periodo de nómina a liquidar.
                            properties:
                              payroll_paid:
                                type: boolean
                                description: Indica si la nómina del próximo periodo ya fue pagada.
                                example: false
                              initial_day:
                                type: string
                                format: date
                                description: Fecha de inicio del próximo periodo de nómina.
                                example: '2024-02-01'
                              end_day:
                                type: string
                                format: date
                                description: Fecha de fin del próximo periodo de nómina.
                                example: '2024-02-29'
                          wages_update:
                            type: boolean
                            description: Indica si hay personas con salario pendiente de actualizar al nuevo salario mínimo.
                            example: false
                          social_benefits_provision:
                            type: object
                            description: Información de la próxima provisión de prestaciones sociales a liquidar.
                            properties:
                              date:
                                type: string
                                description: Etiqueta legible del mes de la provisión.
                                example: Dic. 2024
                              category:
                                type: string
                                description: Categoría de la prestación social a provisionar.
                                example: service_bonus
                              social_benefits_period_id:
                                type: string
                                description: Identificador único (ID) asignado al periodo de prestaciones en la base de datos.
                                example: f0e37428-7c17-5424-88db-01f91c4a7cbd
                              period_id:
                                type: string
                                description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
                                example: ccb54dc0-42d3-5a19-8ff9-d0d41ec80d4d
                          novelty_request:
                            type: object
                            description: Estado de las solicitudes de novedad pendientes de aprobación.
                            properties:
                              pending_request:
                                type: boolean
                                description: Indica si hay solicitudes de novedad pendientes de aprobación.
                                example: false
                              upcoming_request_date:
                                type:
                                  - string
                                  - 'null'
                                description: Fecha de la próxima novedad programada. Nulo si no hay ninguna.
                                example: '2024-02-15'
                      period_information:
                        type: object
                        description: Información básica del periodo de nómina vigente.
                        properties:
                          id:
                            type: string
                            description: Identificador único (ID) asignado al periodo en la base de datos.
                            example: ccb54dc0-42d3-5a19-8ff9-d0d41ec80d4d
                          initial_day:
                            type: string
                            format: date
                            description: Fecha de inicio del periodo vigente.
                            example: '2024-01-01'
                          end_day:
                            type: string
                            format: date
                            description: Fecha de fin del periodo vigente.
                            example: '2024-01-31'
                      variations:
                        type: object
                        description: Variaciones de costos de nómina entre los dos últimos meses cerrados.
                        properties:
                          first_month:
                            type:
                              - string
                              - 'null'
                            description: Nombre del primer mes de comparación. Nulo si no hay datos suficientes.
                            example: Diciembre 2023
                          second_month:
                            type:
                              - string
                              - 'null'
                            description: Nombre del segundo mes de comparación. Nulo si no hay datos suficientes.
                            example: Enero 2024
                          concepts:
                            type: array
                            description: Lista de conceptos con variación de costos entre los dos meses.
                            items:
                              type: object
                            example: []
                      workers_information:
                        type: object
                        description: Información del equipo de personas de la empresa.
                        properties:
                          anniversaries:
                            type: array
                            description: Personas que cumplen aniversario laboral en el mes actual.
                            items:
                              type: object
                            example: []
                          birthdays:
                            type: array
                            description: Personas que cumplen años en el mes actual.
                            items:
                              type: object
                            example: []
                          contracts_to_expire:
                            type: array
                            description: Contratos próximos a vencer en los siguientes 30 días.
                            items:
                              type: object
                            example: []
                          provisions:
                            type: object
                            description: Resumen de provisiones de prestaciones sociales del periodo actual.
                            properties:
                              limit_date:
                                type: string
                                format: date
                                description: Fecha límite del periodo de provisiones.
                                example: '2024-01-31'
                              service_bonus:
                                type: integer
                                description: Monto provisionado para prima de servicios en pesos colombianos.
                                example: 450000
                              severance:
                                type: integer
                                description: Monto provisionado para cesantías en pesos colombianos.
                                example: 290000
                              severance_interests:
                                type: integer
                                description: Monto provisionado para intereses sobre cesantías en pesos colombianos.
                                example: 34800
                          team_count:
                            type: object
                            description: Conteo de personas en la empresa.
                            properties:
                              active_workers:
                                type: integer
                                description: Número de personas con contrato activo en la empresa.
                                example: 12
                              onboarding_workers:
                                type: integer
                                description: Número de personas en proceso de onboarding.
                                example: 2
                          workers_off_duty:
                            type: object
                            description: Personas que no están laborando actualmente.
                            properties:
                              on_leave:
                                type: integer
                                description: Número de personas en licencia no remunerada.
                                example: 1
                              on_sick_leave:
                                type: integer
                                description: Número de personas en incapacidad.
                                example: 0
                              on_vacation:
                                type: integer
                                description: Número de personas en vacaciones.
                                example: 2
              example:
                data:
                  greet_message: ¡Buenos días, Juan!
                  period_information:
                    id: ccb54dc0-42d3-5a19-8ff9-d0d41ec80d4d
                    initial_day: '2024-01-01'
                    end_day: '2024-01-31'
                  pendings:
                    accountant_added: true
                    activated: true
                    social_security_integration: false
                    electronic_payroll_authorized: false
                    wages_update: false
                    next_payroll:
                      payroll_paid: false
                      initial_day: '2024-02-01'
                      end_day: '2024-02-29'
                    social_benefits_provision:
                      date: Dic. 2024
                      category: service_bonus
                      social_benefits_period_id: f0e37428-7c17-5424-88db-01f91c4a7cbd
                      period_id: ccb54dc0-42d3-5a19-8ff9-d0d41ec80d4d
                    novelty_request:
                      pending_request: false
                      upcoming_request_date: '2024-02-15'
                  workers_information:
                    team_count:
                      active_workers: 12
                      onboarding_workers: 2
                    workers_off_duty:
                      on_leave: 1
                      on_sick_leave: 0
                      on_vacation: 2
                    provisions:
                      limit_date: '2024-01-31'
                      service_bonus: 450000
                      severance: 290000
                      severance_interests: 34800
                    anniversaries: []
                    birthdays: []
                    contracts_to_expire: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 8a72e835-91d8-42c1-add4-d6a803d9d2db
  /v1/{company_id}/company_files:
    patch:
      operationId: updateCompanyFiles
      tags:
        - Documentos de la empresa
      summary: Actualizar archivos de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Actualiza uno o más archivos asociados a la empresa: certificado bancario, documento de identificación, documento del representante legal, logo y documento tributario.

        **¿Cuándo usar este endpoint?**

        * Subir o reemplazar el logo de la empresa.
        * Actualizar los documentos legales de la empresa (identificación, representante legal, RUT).
        * Cargar o actualizar el certificado bancario para habilitación de pagos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Formato de documentos:** Los archivos `bank_certificate_document`, `identification_document`, `legal_representative_document` y `tax_document` deben ser PDF.
        * **Formato del logo:** El campo `logo` debe ser una imagen en formato PNG o JPG.
        * **Tamaño máximo:** Cada archivo no debe superar 1 MB.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                bank_certificate_document:
                  type: string
                  format: binary
                  description: Certificado bancario de la empresa. Debe ser un archivo PDF con peso máximo de 1 MB.
                identification_document:
                  type: string
                  format: binary
                  description: Documento de identificación de la empresa. Debe ser un archivo PDF con peso máximo de 1 MB.
                legal_representative_document:
                  type: string
                  format: binary
                  description: Documento del representante legal de la empresa. Debe ser un archivo PDF con peso máximo de 1 MB.
                logo:
                  type: string
                  format: binary
                  description: Logotipo de la empresa. Debe ser una imagen en formato PNG o JPG con peso máximo de 1 MB.
                tax_document:
                  type: string
                  format: binary
                  description: Documento tributario (RUT) de la empresa. Debe ser un archivo PDF con peso máximo de 1 MB.
      responses:
        '202':
          description: Archivos actualizados correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la empresa.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 1c16224f-fe8b-3669-bac4-e134424d3bad
                      name:
                        description: Nombre de la empresa.
                        type: string
                        example: La casita de Lolita SAS
                      document_type:
                        $ref: '#/components/schemas/CompanyDocumentType'
                      economic_sector:
                        description: Sector económico al que pertenece la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del sector económico en la base de datos.
                            type: string
                            example: f8a84396-1e85-4235-a46a-faefe7ec3aa5
                          name:
                            description: Nombre del sector económico.
                            type: string
                            example: Turismo y Entretenimiento
                      id_number:
                        description: Número de identificación tributaria de la empresa (NIT).
                        type: string
                        example: '900000005'
                      ignore_id_number_length:
                        description: Indica si se ignoran las validaciones de longitud del número de identificación.
                        type: boolean
                        example: false
                      verification_digit:
                        description: Dígito de verificación del NIT.
                        type: integer
                        example: 1
                      email:
                        description: Correo electrónico principal de la empresa.
                        type: string
                        example: prueba@nominapp.com
                      government_email:
                        description: Correo electrónico registrado ante entidades gubernamentales.
                        type: string
                        example: prueba@nominapp.com
                      phone:
                        description: Teléfono de contacto de la empresa.
                        type: string
                        example: '3001234567'
                      address:
                        description: Dirección física de la empresa.
                        type: string
                        example: Calle 39
                      account_type:
                        $ref: '#/components/schemas/AccountType'
                      account_number:
                        description: Número de cuenta bancaria principal de la empresa.
                        type: string
                        example: '54546465006'
                      payroll_frequency:
                        $ref: '#/components/schemas/PayrollFrequency'
                      payment_method:
                        $ref: '#/components/schemas/PaymentMethod'
                      constitution_date:
                        description: Fecha de constitución legal de la empresa.
                        type: string
                        format: date
                        example: '2017-09-25'
                      law_1429:
                        description: Indica si la empresa está acogida a los beneficios de la Ley 1429.
                        type: boolean
                        example: false
                      law_1607:
                        description: Indica si la empresa está acogida a los beneficios de la Ley 1607.
                        type: boolean
                        example: false
                      law_590:
                        description: Indica si la empresa está acogida a los beneficios de la Ley 590.
                        type: boolean
                        example: false
                      decree_558:
                        description: Indica si la empresa aplica el Decreto 558 de reducción de aportes a pensión.
                        type: boolean
                        example: false
                      decree_376:
                        description: Indica si la empresa aplica el Decreto 376 de apoyo a la nómina.
                        type: boolean
                        example: false
                      from_partner_company:
                        description: Indica si la empresa está asociada a un partner.
                        type: boolean
                        example: false
                      electronic_period_id:
                        description: Identificador único (ID) del periodo de nómina electrónica activo de la empresa.
                        type: string
                        example: b89c5611-0b9e-30be-98c0-b2dc103d3d66
                      electronic_payroll_authorized:
                        description: Indica si la empresa está autorizada para emitir nómina electrónica ante la DIAN.
                        type: boolean
                        example: false
                      created_at:
                        description: Fecha en que fue creada la empresa en el sistema.
                        type: string
                        format: date
                        example: '2019-03-01'
                      novelties_value:
                        description: Valor máximo de novedades que pueden ser reclamadas por la empresa.
                        type: integer
                        example: 690001
                      accounting_provider:
                        description: Información del proveedor contable integrado con la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del proveedor contable en la base de datos.
                            type: string
                            example: f4e6bd51-159c-d6bc-vc43-f08307c3e379
                          name:
                            description: Nombre del proveedor contable.
                            type: string
                            example: Siigo
                      bank:
                        description: Información del banco principal de la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del banco en la base de datos.
                            type: string
                            example: f8a84396-1e85-4235-a46a-faefe7ec3aa5
                          name:
                            description: Nombre del banco.
                            type: string
                            example: Bancolombia
                      risk_provider:
                        description: Información del proveedor de riesgos laborales de la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del proveedor de riesgos en la base de datos.
                            type: string
                            example: f8a84396-1e85-4235-a46a-faefe7ec3aa5
                          name:
                            description: Nombre del proveedor de riesgos.
                            type: string
                            example: Positiva
                      ss_operator:
                        description: Información del operador de seguridad social de la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del operador de seguridad social en la base de datos.
                            type: string
                            example: f8a84396-1e85-4235-a46a-faefe7ec3aa5
                          name:
                            description: Nombre del operador de seguridad social.
                            type: string
                            example: Enlace Operativo
                      department:
                        description: Departamento donde se ubica la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del departamento en la base de datos.
                            type: string
                            example: 2713b019-f917-4e65-815f-fccd8dffe6es
                          name:
                            description: Nombre del departamento.
                            type: string
                            example: Cundinamarca
                      city:
                        description: Ciudad donde se ubica la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) de la ciudad en la base de datos.
                            type: string
                            example: 2d16c1b8-1768-5504-993e-d2306280586b
                          name:
                            description: Nombre de la ciudad.
                            type: string
                            example: Bogotá, D.C.
                      logo:
                        description: URL temporal de acceso al logo de la empresa almacenado en S3.
                        type: string
                        example: https://s3.amazonaws.com/empresa-logo.png
                      onboarding:
                        description: Información del proceso de incorporación (onboarding) de la empresa.
                        type: object
                        properties:
                          workers_number:
                            $ref: '#/components/schemas/WorkersNumberRange'
                          user_area:
                            description: Área del usuario que realizó el registro.
                            type: string
                            example: accountant
                          user_area_other_info:
                            description: Información adicional del área del usuario.
                            type: string
                            example: Recursos Humanos
                          user_name:
                            description: Nombre del usuario que realizó el registro.
                            type: string
                            example: Lina María
                          payroll_frequency:
                            $ref: '#/components/schemas/PayrollFrequency'
                          onboarding_step:
                            description: 'Paso actual del proceso de incorporación. Valores posibles: user_area (área del usuario), company_data (datos de la empresa), invite_admin (invitar administrador), finished (finalizado).'
                            type: string
                            enum:
                              - user_area
                              - company_data
                              - invite_admin
                              - finished
                            example: finished
                      onboarding_first_steps:
                        description: Estado de los primeros pasos del proceso de incorporación.
                        type: object
                        properties:
                          first_worker:
                            description: Indica si se ha registrado al menos una persona en la empresa.
                            type: boolean
                            example: true
                          first_payroll:
                            description: Indica si se ha generado al menos una nómina en la empresa.
                            type: boolean
                            example: true
                          first_user:
                            description: Indica si se ha creado al menos un usuario administrador o contador.
                            type: boolean
                            example: true
                          company_data_configured:
                            description: Indica si los datos básicos de la empresa han sido configurados.
                            type: boolean
                            example: true
                          finished_all_steps:
                            description: Indica si todos los pasos del onboarding han sido completados.
                            type: boolean
                            example: false
                      files:
                        description: URLs de acceso a los archivos de la empresa almacenados en S3.
                        type: object
                        properties:
                          identification_document:
                            description: URL temporal de acceso al documento de identificación de la empresa.
                            type: string
                            example: https://s3.amazonaws.com/identification_document.pdf
                          tax_document:
                            description: URL temporal de acceso al documento tributario (RUT) de la empresa.
                            type: string
                            example: https://s3.amazonaws.com/tax_document.pdf
              example:
                data:
                  id: 1c16224f-fe8b-3669-bac4-e134424d3bad
                  name: La casita de Lolita SAS
                  document_type: ni
                  id_number: '900000005'
                  verification_digit: 1
                  email: prueba@nominapp.com
                  payroll_frequency: monthly
                  payment_method: wire_transfer
                  constitution_date: '2017-09-25'
                  law_1429: false
                  law_1607: false
                  law_590: false
                  decree_558: false
                  decree_376: false
                  electronic_payroll_authorized: false
                  logo: https://s3.amazonaws.com/empresa-logo.png
                  files:
                    identification_document: https://s3.amazonaws.com/identification_document.pdf
                    tax_document: https://s3.amazonaws.com/tax_document.pdf
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Documento inválido (debe ser PDF) / Logo inválido (debe ser PNG o JPG) / Archivo demasiado grande
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Documento inválido (debe ser PDF):
                  value:
                    error:
                      - code: '0309'
                        index: 0
                        message: legal_representative_document debe ser un PDF.
                        object: legal_representative_document
                Logo inválido (debe ser PNG o JPG):
                  value:
                    error:
                      - code: '0307'
                        index: 0
                        message: logo debe ser una imagen en formato png o jpg.
                        object: logo
                Archivo demasiado grande:
                  value:
                    error:
                      - code: '0306'
                        index: 0
                        message: identification_document es muy grande. Su peso máximo debe ser 1 MB.
                        object: identification_document
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 072eec42-fef9-4234-98c3-4ed1208a3838
  /v1/{company_id}/consolidated_payroll_summary_file:
    get:
      operationId: showConsolidatedPayrollSummaryFile
      tags:
        - Resúmenes de nómina
      summary: Obtener archivo de resumen consolidado
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo de resumen consolidado de nómina de la empresa para un rango de fechas,
        incluyendo los totales de todas las nóminas de los periodos comprendidos en ese rango.

        **¿Cuándo usar este endpoint?**

        * Obtener el resumen de nómina de varios periodos en un único archivo consolidado.
        * Generar el archivo para auditorías o reportes internos que abarcan múltiples periodos.
        * Descargar el consolidado histórico de nómina dentro de un rango de fechas específico.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Fechas requeridas:** Los parámetros `initial_day` y `end_day` son obligatorios. Si alguno está ausente o tiene formato inválido, retorna 422. La fecha final debe ser mayor o igual a la inicial.
        * **Modo asíncrono:** Con `async: true` el archivo se publica en Firebase en la ruta `companies/{company_id}/payroll_summary`.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: true
          name: initial_day
          description: Fecha inicial del rango de periodos a incluir en el resumen consolidado, en formato `YYYY-MM-DD`.
          schema:
            type: string
            format: date
            example: '2024-01-01'
        - in: query
          required: true
          name: end_day
          description: Fecha final del rango de periodos a incluir en el resumen consolidado, en formato `YYYY-MM-DD`. Debe ser mayor o igual a `initial_day`.
          schema:
            type: string
            format: date
            example: '2024-12-31'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga.
            - **Asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta síncrona
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo de resumen consolidado de nómina generado.
                        type: string
                        example: https://storage.aleluya.com/consolidated_payroll_summary.xlsx
                  - type: object
                    description: Respuesta asíncrona
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de encolamiento del archivo.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/consolidated_payroll_summary.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Formato de fecha inicial inválido / Formato de fecha final inválido / Fecha inicial mayor a la final
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Formato de fecha inicial inválido:
                  value:
                    error:
                      - code: '0409'
                        index: 0
                        message: El formato de la fecha inicial es inválido.
                        object: initial_day
                Formato de fecha final inválido:
                  value:
                    error:
                      - code: '0410'
                        index: 0
                        message: El formato de la fecha final es inválido.
                        object: end_day
                Fecha inicial mayor a la final:
                  value:
                    error:
                      - code: '0401'
                        index: 0
                        message: La fecha final debe ser mayor o igual a la fecha inicial.
                        object: end_day
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/contract_details/{id}:
    get:
      operationId: showContractDetail
      tags:
        - Detalles del contrato
      summary: Obtener detalle de contrato
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de un registro de contrato específico, incluyendo el subtipo de cotizante,
        el centro de trabajo asignado y el tipo de riesgo ARL vigente en ese periodo.

        **¿Cuándo usar este endpoint?**

        * Consultar la configuración de seguridad social de un periodo específico del contrato.
        * Verificar si el detalle puede ser eliminado antes de realizar la operación.
        * Obtener el centro de trabajo y tipo de riesgo asignado en un detalle histórico.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Detalle de contrato encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información del detalle del contrato.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                        type: string
                        example: 4853f212-17fa-5631-884f-bed5587f7976
                      contributor_subtype:
                        description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social en este periodo.
                        type: string
                        example: no_subtype
                      initial_day:
                        description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin de vigencia del detalle del contrato en formato YYYY-MM-DD. Null si es el detalle vigente.
                        type:
                          - string
                          - 'null'
                        example: '2024-06-30'
                      contract_id:
                        description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo en este periodo.
                        type: boolean
                        example: false
                      work_center:
                        description: Centro de trabajo asignado en este detalle del contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                          name:
                            description: Nombre del centro de trabajo. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: Oficina central
                          risk_type_coded_name:
                            description: Código del tipo de riesgo ARL vigente en la fecha del detalle. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: risk_1
                      deleteable:
                        description: Indica si el detalle del contrato puede ser eliminado.
                        type: boolean
                        example: false
              example:
                data:
                  id: 4853f212-17fa-5631-884f-bed5587f7976
                  contributor_subtype: no_subtype
                  initial_day: '2024-01-01'
                  end_day: '2024-06-30'
                  contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  high_risk_pension: false
                  work_center:
                    id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                    name: Oficina central
                    risk_type_coded_name: risk_1
                  deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Empresa no encontrada / Detalle de contrato no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Empresa no encontrada:
                  value:
                    error:
                      - code: '0001'
                        index: 0
                        message: company no existe
                        object: company
                Detalle de contrato no encontrado:
                  value:
                    error:
                      - code: '0001'
                        index: 0
                        message: contract_detail no existe
                        object: contract_detail
    patch:
      operationId: updateContractDetail
      tags:
        - Detalles del contrato
      summary: Actualizar detalle de contrato
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el detalle vigente de un contrato: subtipo de cotizante, centro de trabajo,
        pensión de alto riesgo y fechas de vigencia.

        **¿Cuándo usar este endpoint?**

        * Cambiar el subtipo de cotizante de una persona ante un cambio en su situación de seguridad social.
        * Actualizar el centro de trabajo asignado al contrato cuando la persona cambia de ubicación.
        * Modificar las fechas de vigencia del detalle actual para ajustar el periodo de aplicación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Solo detalle actual:** Solo se puede editar el detalle del contrato más reciente. Los detalles históricos no son editables.
        * **Pensión de alto riesgo:** Aplica para actividades clasificadas como alto riesgo según el Decreto 2090. La normativa colombiana (Resolución 6072 de 2024) exige que el contrato tenga Colpensiones como administradora de pensiones; si no, la API devuelve el error `4009`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contract_detail:
                  description: Objeto con los campos del detalle del contrato a actualizar.
                  type: object
                  properties:
                    contributor_subtype:
                      description: Subtipo de cotizante para la liquidación de seguridad social.
                      type: string
                      example: no_subtype
                    initial_day:
                      description: Fecha de inicio de vigencia del detalle en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-01-01'
                    end_day:
                      description: Fecha de fin de vigencia del detalle en formato YYYY-MM-DD. Null si no tiene fecha de fin.
                      type:
                        - string
                        - 'null'
                      example: '2024-06-30'
                    high_risk_pension:
                      description: Indica si aplica pensión de alto riesgo. Requiere Colpensiones como fondo de pensiones.
                      type: boolean
                      example: false
                    work_center_id:
                      description: Identificador único (ID) asignado al centro de trabajo en la base de datos. Null para desasignar.
                      type:
                        - string
                        - 'null'
                      example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
              required:
                - contract_detail
      responses:
        '202':
          description: Detalle de contrato actualizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información actualizada del detalle del contrato.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                        type: string
                        example: 4853f212-17fa-5631-884f-bed5587f7976
                      contributor_subtype:
                        description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social en este periodo.
                        type: string
                        example: no_subtype
                      initial_day:
                        description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin de vigencia del detalle del contrato en formato YYYY-MM-DD. Null si es el detalle vigente.
                        type:
                          - string
                          - 'null'
                        example: '2024-06-30'
                      contract_id:
                        description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo en este periodo.
                        type: boolean
                        example: false
                      work_center:
                        description: Centro de trabajo asignado en este detalle del contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                          name:
                            description: Nombre del centro de trabajo. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: Oficina central
                          risk_type_coded_name:
                            description: Código del tipo de riesgo ARL vigente en la fecha del detalle. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: risk_1
                      deleteable:
                        description: Indica si el detalle del contrato puede ser eliminado.
                        type: boolean
                        example: false
              example:
                data:
                  id: 4853f212-17fa-5631-884f-bed5587f7976
                  contributor_subtype: no_subtype
                  initial_day: '2024-01-01'
                  end_day: '2024-06-30'
                  contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  high_risk_pension: false
                  work_center:
                    id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                    name: Oficina central
                    risk_type_coded_name: risk_1
                  deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Solo detalle actual editable / Fecha inicial inválida / Pensión de alto riesgo inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Solo detalle actual editable:
                  value:
                    error:
                      - code: '4005'
                        index: 0
                        message: Solo puedes editar el detalle del contrato actual.
                        object: contract_detail
                Fecha inicial inválida:
                  value:
                    error:
                      - code: '4003'
                        index: 0
                        message: Fecha inicial del detalle del contrato debe ser mayor a la del detalle actual.
                        object: contract_detail
                Pensión de alto riesgo inválida:
                  value:
                    error:
                      - code: '4009'
                        index: 0
                        message: La pensión de alto riesgo requiere Colpensiones como administradora de pensiones (Resolución 6072 de 2024).
                        object: contract_detail
    delete:
      operationId: destroyContractDetail
      tags:
        - Detalles del contrato
      summary: Eliminar detalle de contrato
      description: |
        **¿Qué hace este endpoint?**

        Elimina un detalle de contrato y recalcula las nóminas afectadas por el cambio.

        **¿Cuándo usar este endpoint?**

        * Corregir un detalle de contrato creado por error antes de que genere nóminas.
        * Revertir un cambio de subtipo de cotizante o centro de trabajo en el contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Eliminable:** El campo `deleteable` del GET indica si el detalle puede ser eliminado. Solo se pueden eliminar detalles que no tienen nóminas procesadas en su rango de fechas.
      responses:
        '200':
          description: Detalle de contrato eliminado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: El detalle del contrato ha sido eliminado.
              example:
                data:
                  message: El detalle del contrato ha sido eliminado.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 36c964e8-a517-41c0-bc11-a27c1b3f70f9
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
        schema:
          type: string
          example: 4853f212-17fa-5631-884f-bed5587f7976
  /v1/{company_id}/contract_position_histories/{id}:
    get:
      operationId: showContractPositionHistory
      tags:
        - Historial de cargos
      summary: Obtener historial de cargo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de un registro específico del historial de cargos de un contrato.

        **¿Cuándo usar este endpoint?**

        * Consultar el cargo, área y sede asignados a una persona en un periodo específico de su contrato.
        * Verificar el campo `deleteable` antes de intentar eliminar un registro.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Registro de historial de cargo encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle del registro de historial de cargo solicitado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al registro en la base de datos.
                        type: string
                        example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                      initial_day:
                        description: Fecha de inicio del registro en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del registro en formato YYYY-MM-DD. Null si es el registro vigente.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      contract_id:
                        description: Identificador único (ID) asignado al contrato al que pertenece este registro en la base de datos.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      area:
                        description: Área de la empresa asignada a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al área en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name:
                            description: Nombre del área.
                            type: string
                            example: Administración
                      location:
                        description: Sede de la empresa asignada a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sede en la base de datos.
                            type: string
                            example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                          name:
                            description: Nombre de la sede.
                            type: string
                            example: Bogotá
                      position:
                        description: Cargo asignado a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al cargo en la base de datos.
                            type: string
                            example: c3d4e5f6-a7b8-9012-cdef-012345678901
                          name:
                            description: Nombre del cargo.
                            type: string
                            example: Analista de Nómina
                      deleteable:
                        description: Indica si el registro puede ser eliminado. El primer registro del contrato no es eliminable.
                        type: boolean
                        example: false
              example:
                data:
                  id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                  initial_day: '2024-01-01'
                  end_day: '2024-12-31'
                  contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  area:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Administración
                  location:
                    id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                    name: Bogotá
                  position:
                    id: c3d4e5f6-a7b8-9012-cdef-012345678901
                    name: Analista de Nómina
                  deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateContractPositionHistory
      tags:
        - Historial de cargos
      summary: Actualizar historial de cargo
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el cargo, área, sede o fechas del registro actual del historial de un contrato.

        **¿Cuándo usar este endpoint?**

        * Corregir el cargo, área o sede asignados incorrectamente al momento del traslado.
        * Ajustar la fecha de inicio del registro vigente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Solo registro actual:** Únicamente se puede editar el historial de cargo vigente del contrato.
        * **Contrato liquidado:** No es posible editar el historial de cargo de un contrato ya liquidado.
        * **Cambio de sede:** Solo se puede modificar la sede si la nueva fecha inicial corresponde a la fecha de inicio del contrato o al primer día de un mes.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contract_position_history:
                  description: Objeto con los campos del historial de cargo a actualizar.
                  type: object
                  properties:
                    area_id:
                      description: Identificador único (ID) asignado al área de la empresa en la base de datos.
                      type: string
                      example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    location_id:
                      description: Identificador único (ID) asignado a la sede de la empresa en la base de datos.
                      type: string
                      example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                    position_id:
                      description: Identificador único (ID) asignado al cargo en la base de datos.
                      type: string
                      example: c3d4e5f6-a7b8-9012-cdef-012345678901
                    initial_day:
                      description: Fecha de inicio del registro en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-01-01'
                    end_day:
                      description: Fecha de fin del registro en formato YYYY-MM-DD. Null si es el registro vigente.
                      type:
                        - string
                        - 'null'
                      example: '2024-12-31'
              required:
                - contract_position_history
      responses:
        '202':
          description: Historial de cargo actualizado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con los datos actualizados del registro de historial de cargo.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al registro en la base de datos.
                        type: string
                        example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                      initial_day:
                        description: Fecha de inicio del registro en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del registro en formato YYYY-MM-DD. Null si es el registro vigente.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      contract_id:
                        description: Identificador único (ID) asignado al contrato al que pertenece este registro en la base de datos.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      area:
                        description: Área de la empresa asignada a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al área en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name:
                            description: Nombre del área.
                            type: string
                            example: Administración
                      location:
                        description: Sede de la empresa asignada a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sede en la base de datos.
                            type: string
                            example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                          name:
                            description: Nombre de la sede.
                            type: string
                            example: Bogotá
                      position:
                        description: Cargo asignado a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al cargo en la base de datos.
                            type: string
                            example: c3d4e5f6-a7b8-9012-cdef-012345678901
                          name:
                            description: Nombre del cargo.
                            type: string
                            example: Analista de Nómina
                      deleteable:
                        description: Indica si el registro puede ser eliminado.
                        type: boolean
                        example: false
              example:
                data:
                  id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                  initial_day: '2024-01-01'
                  end_day: '2024-12-31'
                  contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  area:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Administración
                  location:
                    id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                    name: Bogotá
                  position:
                    id: c3d4e5f6-a7b8-9012-cdef-012345678901
                    name: Analista de Nómina
                  deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato liquidado / Solo registro actual / Cambio de sede inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato liquidado:
                  value:
                    error:
                      - code: '3105'
                        index: 0
                        message: El contrato ya ha sido liquidado, por lo cual no puedes editarlo.
                        object: contract
                Solo registro actual editable:
                  value:
                    error:
                      - code: '4013'
                        index: 0
                        message: Solo puedes editar el historial de cargo del contrato actual.
                        object: contract_position_history
                Cambio de sede inválido:
                  value:
                    error:
                      - code: '4015'
                        index: 0
                        message: Solo puedes modificar la sede para que aplique desde la fecha inicial del contrato o desde el primer día del mes. Esto se debe a validaciones de seguridad social.
                        object: contract_position_history
    delete:
      operationId: destroyContractPositionHistory
      tags:
        - Historial de cargos
      summary: Eliminar historial de cargo
      description: |
        **¿Qué hace este endpoint?**

        Elimina un registro del historial de cargos de un contrato. Al eliminarse, el registro anterior
        recupera su fecha de fin automáticamente.

        **¿Cuándo usar este endpoint?**

        * Eliminar un traslado registrado por error en el historial del contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Restricción de eliminación:** Solo pueden eliminarse registros con `deleteable: true`. El primer registro del contrato nunca puede ser eliminado.
      responses:
        '200':
          description: Historial de cargo eliminado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: El historial de cargo del contrato ha sido eliminado.
              example:
                data:
                  message: El historial de cargo del contrato ha sido eliminado.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Registro no eliminable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Registro no eliminable:
                  value:
                    error:
                      - code: '0501'
                        index: 0
                        message: ContractPositionHistory no se puede eliminar.
                        object: contract_position_history
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al registro de historial de cargo en la base de datos.
        schema:
          type: string
          example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
  /v1/{company_id}/contracts/{contract_id}/contract_details:
    get:
      operationId: indexContractDetails
      tags:
        - Detalles del contrato
      summary: Listar detalles de contrato
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial completo de detalles del contrato, ordenados del más reciente al más antiguo.
        Cada detalle registra el subtipo de cotizante, el centro de trabajo y el tipo de riesgo ARL
        vigentes en un periodo específico del contrato.

        **¿Cuándo usar este endpoint?**

        * Consultar todos los cambios de subtipo de cotizante o centro de trabajo que ha tenido un contrato.
        * Verificar cuál de los detalles es el actual antes de crear uno nuevo.
        * Determinar si un detalle histórico puede ser eliminado mediante el campo `deleteable`.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Detalles del contrato listados
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo con el historial de detalles del contrato, ordenado del más reciente al más antiguo.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                          type: string
                          example: 4853f212-17fa-5631-884f-bed5587f7976
                        contributor_subtype:
                          description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social en este periodo.
                          type: string
                          example: no_subtype
                        initial_day:
                          description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-01-01'
                        end_day:
                          description: Fecha de fin de vigencia del detalle del contrato en formato YYYY-MM-DD. Null si es el detalle vigente.
                          type:
                            - string
                            - 'null'
                          example: '2024-06-30'
                        contract_id:
                          description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                          type: string
                          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                        high_risk_pension:
                          description: Indica si el contrato aplica pensión de alto riesgo en este periodo.
                          type: boolean
                          example: false
                        work_center:
                          description: Centro de trabajo asignado en este detalle del contrato.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al centro de trabajo en la base de datos. Null si no tiene centro asignado.
                              type:
                                - string
                                - 'null'
                              example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                            name:
                              description: Nombre del centro de trabajo. Null si no tiene centro asignado.
                              type:
                                - string
                                - 'null'
                              example: Oficina central
                            risk_type_coded_name:
                              description: Código del tipo de riesgo ARL vigente en la fecha del detalle. Null si no tiene centro asignado.
                              type:
                                - string
                                - 'null'
                              example: risk_1
                        deleteable:
                          description: Indica si el detalle del contrato puede ser eliminado.
                          type: boolean
                          example: false
              example:
                data:
                  - id: 4853f212-17fa-5631-884f-bed5587f7976
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                    high_risk_pension: false
                    work_center:
                      id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                      name: Oficina central
                      risk_type_coded_name: risk_1
                    deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createContractDetail
      tags:
        - Detalles del contrato
      summary: Crear detalle de contrato
      description: |
        **¿Qué hace este endpoint?**

        Crea un nuevo detalle para el contrato especificado, registrando un cambio en el subtipo de
        cotizante, centro de trabajo o tipo de riesgo ARL. Recalcula automáticamente las nóminas
        afectadas en el rango de fechas del nuevo detalle.

        **¿Cuándo usar este endpoint?**

        * Registrar un cambio de subtipo de cotizante cuando la situación de seguridad social de la persona varía.
        * Actualizar el centro de trabajo y el tipo de riesgo ARL cuando la persona cambia de ubicación.
        * Crear un detalle histórico para cubrir un periodo pasado del contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Sin duplicados:** El nuevo detalle debe diferir del detalle actual en al menos el subtipo de cotizante o el centro de trabajo.
        * **Pensión de alto riesgo:** Aplica para actividades clasificadas como alto riesgo según el Decreto 2090. La normativa colombiana (Resolución 6072 de 2024) exige que el contrato tenga Colpensiones como administradora de pensiones; si no, la API devuelve el error `4009`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contract_detail:
                  description: Objeto con los datos del nuevo detalle del contrato.
                  type: object
                  properties:
                    contributor_subtype:
                      description: Subtipo de cotizante para la liquidación de seguridad social.
                      type: string
                      example: no_subtype
                    initial_day:
                      description: Fecha de inicio de vigencia del nuevo detalle en formato YYYY-MM-DD. Debe ser mayor a la fecha de inicio del detalle actual.
                      type: string
                      format: date
                      example: '2024-07-01'
                    end_day:
                      description: Fecha de fin de vigencia del nuevo detalle en formato YYYY-MM-DD. Null si no tiene fecha de fin.
                      type:
                        - string
                        - 'null'
                      example: null
                    high_risk_pension:
                      description: Indica si aplica pensión de alto riesgo. Requiere Colpensiones como fondo de pensiones del contrato.
                      type: boolean
                      example: false
                    work_center_id:
                      description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                  required:
                    - contributor_subtype
                    - initial_day
              required:
                - contract_detail
      responses:
        '201':
          description: Detalle de contrato creado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información del detalle del contrato recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                        type: string
                        example: 866d943a-b001-4106-ade9-feed1cab9251
                      contributor_subtype:
                        description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social en este periodo.
                        type: string
                        example: no_subtype
                      initial_day:
                        description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-07-01'
                      end_day:
                        description: Fecha de fin de vigencia del detalle del contrato en formato YYYY-MM-DD. Null si es el detalle vigente.
                        type:
                          - string
                          - 'null'
                        example: null
                      contract_id:
                        description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo en este periodo.
                        type: boolean
                        example: false
                      work_center:
                        description: Centro de trabajo asignado en este detalle del contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                          name:
                            description: Nombre del centro de trabajo. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: Oficina central
                          risk_type_coded_name:
                            description: Código del tipo de riesgo ARL vigente en la fecha del detalle. Null si no tiene centro asignado.
                            type:
                              - string
                              - 'null'
                            example: risk_1
                      deleteable:
                        description: Indica si el detalle del contrato puede ser eliminado.
                        type: boolean
                        example: true
              example:
                data:
                  id: 866d943a-b001-4106-ade9-feed1cab9251
                  contributor_subtype: no_subtype
                  initial_day: '2024-07-01'
                  end_day: null
                  contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  high_risk_pension: false
                  work_center:
                    id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                    name: Oficina central
                    risk_type_coded_name: risk_1
                  deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Detalle duplicado / Subtipo inválido para categoría / Pensión de alto riesgo inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Detalle duplicado:
                  value:
                    error:
                      - code: '4007'
                        index: 0
                        message: El nuevo detalle del contrato debe ser diferente al actual.
                        object: contract_detail
                Subtipo inválido para categoría:
                  value:
                    error:
                      - code: '4001'
                        index: 0
                        message: El subtipo de cotizante no aplica para la categoría del contrato.
                        object: contract_detail
                Pensión de alto riesgo inválida:
                  value:
                    error:
                      - code: '4009'
                        index: 0
                        message: La pensión de alto riesgo requiere Colpensiones como administradora de pensiones (Resolución 6072 de 2024).
                        object: contract_detail
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
  /v1/{company_id}/contracts/{contract_id}/contract_position_histories:
    get:
      operationId: indexContractPositionHistories
      tags:
        - Historial de cargos
      summary: Listar historial de cargos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial completo de cargos, áreas y sedes asociados a un contrato,
        ordenado del más reciente al más antiguo.

        **¿Cuándo usar este endpoint?**

        * Consultar todos los cambios de cargo, área o sede que ha tenido una persona durante su contrato.
        * Verificar cuál es el registro vigente antes de crear uno nuevo.
        * Determinar si un registro histórico puede ser eliminado mediante el campo `deleteable`.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Historial de cargos del contrato
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo con el historial de cargos del contrato, ordenado del más reciente al más antiguo.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al registro de historial de cargo en la base de datos.
                          type: string
                          example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                        initial_day:
                          description: Fecha de inicio del registro en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-01-01'
                        end_day:
                          description: Fecha de fin del registro en formato YYYY-MM-DD. Null si es el registro vigente.
                          type:
                            - string
                            - 'null'
                          example: '2024-06-30'
                        contract_id:
                          description: Identificador único (ID) asignado al contrato al que pertenece este registro en la base de datos.
                          type: string
                          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                        area:
                          description: Área de la empresa asignada a la persona en este periodo.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al área en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            name:
                              description: Nombre del área.
                              type: string
                              example: Administración
                        location:
                          description: Sede de la empresa asignada a la persona en este periodo.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la sede en la base de datos.
                              type: string
                              example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                            name:
                              description: Nombre de la sede.
                              type: string
                              example: Bogotá
                        position:
                          description: Cargo asignado a la persona en este periodo.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al cargo en la base de datos.
                              type: string
                              example: c3d4e5f6-a7b8-9012-cdef-012345678901
                            name:
                              description: Nombre del cargo.
                              type: string
                              example: Analista de Nómina
                        deleteable:
                          description: Indica si el registro puede ser eliminado. El primer registro del contrato no es eliminable.
                          type: boolean
                          example: true
              example:
                data:
                  - id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                    initial_day: '2024-01-01'
                    end_day: '2024-06-30'
                    contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                    area:
                      id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      name: Administración
                    location:
                      id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      name: Bogotá
                    position:
                      id: c3d4e5f6-a7b8-9012-cdef-012345678901
                      name: Analista de Nómina
                    deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createContractPositionHistory
      tags:
        - Historial de cargos
      summary: Crear historial de cargo
      description: |
        **¿Qué hace este endpoint?**

        Registra un nuevo cambio de cargo, área o sede en el historial del contrato.
        El registro anterior queda con fecha de fin automáticamente.

        **¿Cuándo usar este endpoint?**

        * Registrar un traslado cuando una persona cambia de área o sede dentro de la empresa.
        * Registrar un ascenso o cambio de cargo sin liquidar el contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Contrato liquidado:** No es posible crear un nuevo historial de cargo en un contrato ya liquidado.
        * **Fecha inicial:** Debe ser mayor a la fecha inicial del historial de cargo actual.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contract_position_history:
                  description: Objeto con los datos del nuevo registro de historial de cargo.
                  type: object
                  properties:
                    area_id:
                      description: Identificador único (ID) asignado al área de la empresa en la base de datos.
                      type: string
                      example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    location_id:
                      description: Identificador único (ID) asignado a la sede de la empresa en la base de datos.
                      type: string
                      example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                    position_id:
                      description: Identificador único (ID) asignado al cargo en la base de datos.
                      type: string
                      example: c3d4e5f6-a7b8-9012-cdef-012345678901
                    initial_day:
                      description: Fecha de inicio del nuevo registro en formato YYYY-MM-DD. Debe ser mayor a la fecha inicial del historial actual.
                      type: string
                      format: date
                      example: '2024-07-01'
                    end_day:
                      description: Fecha de fin del registro en formato YYYY-MM-DD. Null si es el registro vigente.
                      type:
                        - string
                        - 'null'
                      example: '2024-06-30'
                  required:
                    - area_id
                    - location_id
                    - position_id
                    - initial_day
              required:
                - contract_position_history
      responses:
        '201':
          description: Historial de cargo creado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información del registro de historial de cargo recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al registro en la base de datos.
                        type: string
                        example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                      initial_day:
                        description: Fecha de inicio del registro en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-07-01'
                      end_day:
                        description: Fecha de fin del registro en formato YYYY-MM-DD. Null si es el registro vigente.
                        type:
                          - string
                          - 'null'
                        example: '2024-06-30'
                      contract_id:
                        description: Identificador único (ID) asignado al contrato al que pertenece este registro en la base de datos.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      area:
                        description: Área de la empresa asignada a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al área en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name:
                            description: Nombre del área.
                            type: string
                            example: Operaciones
                      location:
                        description: Sede de la empresa asignada a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sede en la base de datos.
                            type: string
                            example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                          name:
                            description: Nombre de la sede.
                            type: string
                            example: Medellín
                      position:
                        description: Cargo asignado a la persona en este periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al cargo en la base de datos.
                            type: string
                            example: c3d4e5f6-a7b8-9012-cdef-012345678901
                          name:
                            description: Nombre del cargo.
                            type: string
                            example: Coordinador de Nómina
                      deleteable:
                        description: Indica si el registro puede ser eliminado.
                        type: boolean
                        example: true
              example:
                data:
                  id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                  initial_day: '2024-07-01'
                  end_day: '2024-12-31'
                  contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  area:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Operaciones
                  location:
                    id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                    name: Medellín
                  position:
                    id: c3d4e5f6-a7b8-9012-cdef-012345678901
                    name: Coordinador de Nómina
                  deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato liquidado / Historial duplicado / Fecha inicial inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato liquidado:
                  value:
                    error:
                      - code: '3105'
                        index: 0
                        message: El contrato ya ha sido liquidado, por lo cual no puedes editarlo.
                        object: contract
                Historial duplicado:
                  value:
                    error:
                      - code: '4016'
                        index: 0
                        message: El nuevo historial de puesto de trabajo debe ser diferente al actual.
                        object: contract_position_history
                Fecha inicial inválida:
                  value:
                    error:
                      - code: '4011'
                        index: 0
                        message: La fecha inicial del historial de cargo del contrato debe ser mayor a la del historial actual.
                        object: contract_position_history
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
  /v1/{company_id}/contracts/{contract_id}/contract_social_benefits:
    get:
      operationId: indexContractSocialBenefits
      tags:
        - Prestaciones por contrato
      summary: Listar prestaciones del contrato
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de prestaciones sociales (prima de servicios, cesantías e
        intereses de cesantías) liquidadas para un contrato, con el saldo pendiente,
        el valor base y la fecha límite de pago de cada una.

        **¿Cuándo usar este endpoint?**

        * Consultar el historial completo de prestaciones liquidadas para un contrato
          antes de registrar pagos adicionales.
        * Verificar el saldo pendiente de cada prestación para determinar qué pagos
          quedan por realizar.
        * Filtrar por categoría para ver solo las primas de servicios o solo las cesantías.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Tipo de contrato:** Solo los contratos laborales y pensionados tienen derecho
          al pago de prestaciones. Si el contrato no aplica, se retorna un error 422.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: category
          required: false
          description: 'Filtra las prestaciones por categoría. Valores posibles: `service_bonus` (prima de servicios), `severance_interests` (intereses de cesantías), `severance` (cesantías).'
          schema:
            type: string
            enum:
              - service_bonus
              - severance_interests
              - severance
            example: service_bonus
      responses:
        '200':
          description: Listado de prestaciones del contrato obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Lista de prestaciones sociales liquidadas para el contrato.
                    type: array
                    items:
                      description: Datos de una prestación social liquidada.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la prestación social en la base de datos.
                          type: string
                          example: c7c6d896-5f98-549b-8f63-10b1ae027e43
                        balance:
                          description: Saldo pendiente de pago de la prestación, en pesos colombianos.
                          type: number
                          example: 1500000
                        base_value:
                          description: Valor base del salario usado para calcular la prestación, en pesos colombianos.
                          type: number
                          example: 3000000
                        days:
                          description: Número de días trabajados usados en el cálculo de la prestación.
                          type: integer
                          example: 180
                        label:
                          description: Nombre legible del periodo de prestaciones (ej. "Prima de Servicios 2024-1").
                          type: string
                          example: Prima de Servicios 2024-2
                        payment_limit_day:
                          description: Fecha límite legal para el pago de esta prestación.
                          type: string
                          format: date
                          example: '2024-12-20'
                        value:
                          description: Valor total liquidado de la prestación, en pesos colombianos.
                          type: integer
                          example: 1500000
                  filters:
                    description: Información de paginación y totales del listado.
                    type: object
                    properties:
                      page:
                        description: Número de página actual de los resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de registros por página.
                        type: integer
                        example: 20
                      category:
                        description: Filtro de categoría aplicado. Solo presente si se envió el parámetro `category`.
                        type: string
                        example: service_bonus
                      total_records:
                        description: Número total de prestaciones del contrato (sin paginación).
                        type: integer
                        example: 3
              examples:
                Con prestaciones:
                  value:
                    data:
                      - id: c7c6d896-5f98-549b-8f63-10b1ae027e43
                        balance: 1500000
                        base_value: 3000000
                        days: 180
                        label: Prima de Servicios 2024-2
                        payment_limit_day: '2024-12-20'
                        value: 1500000
                      - id: 0924cb18-41cc-531c-9364-065b735d9feb
                        balance: 100000
                        base_value: 200000
                        days: 180
                        label: Intereses a las Cesantías 2024
                        payment_limit_day: '2025-01-31'
                        value: 100000
                    filters:
                      page: 1
                      per_page: 20
                      total_records: 2
                Sin prestaciones:
                  value:
                    data: []
                    filters:
                      page: 1
                      per_page: 20
                      total_records: 0
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato sin derecho a prestaciones sociales
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0707'
                    index: 0
                    message: Este tipo de contrato no otorga derecho al pago de prestaciones sociales.
                    object: contract
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 985e3843-3248-43fc-855d-a78b01d74773
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
  /v1/{company_id}/contracts/{contract_id}/contract_social_benefits/{contract_social_benefit_id}/social_benefit_items:
    get:
      operationId: indexSocialBenefitItems
      tags:
        - Prestaciones por contrato
      summary: Listar ítems de prestación
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de pagos realizados para una prestación social de un contrato,
        incluyendo los pagos regulares por periodo de nómina y cualquier pago realizado
        en la liquidación del contrato.

        **¿Cuándo usar este endpoint?**

        * Consultar el historial de pagos de una prestación específica para verificar
          en qué periodos se realizaron abonos.
        * Identificar si parte de la prestación fue pagada en la liquidación del contrato
          (ítem con `id: "termination"`).

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago por liquidación:** Si parte de la prestación fue pagada al liquidar el
          contrato, aparece un ítem con `id: "termination"` en lugar de un UUID.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
      responses:
        '200':
          description: Detalle de pagos de la prestación obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información del periodo de prestaciones y sus pagos realizados.
                    type: object
                    properties:
                      label:
                        description: Nombre legible del periodo de prestaciones (ej. "Prima de Servicios 2024-2").
                        type: string
                        example: Prima de Servicios 2024-2
                      payments:
                        description: Lista de pagos realizados para esta prestación social.
                        type: array
                        items:
                          description: Datos de un pago individual de la prestación.
                          type: object
                          properties:
                            id:
                              description: Identificador del pago. Es el UUID del ítem de nómina cuando el pago se realizó en un periodo regular, o la cadena `"termination"` cuando fue pagado en la liquidación del contrato.
                              type: string
                              example: e63f873a-ba00-5ab2-976b-7ef76392c20a
                            date:
                              description: Fecha en que se realizó el pago de la prestación.
                              type: string
                              format: date
                              example: '2024-06-30'
                            value:
                              description: Valor pagado en este ítem, en pesos colombianos.
                              type: integer
                              example: 750000
                  filters:
                    description: Información de paginación y totales del listado.
                    type: object
                    properties:
                      page:
                        description: Número de página actual de los resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de registros por página.
                        type: integer
                        example: 20
                      total_records:
                        description: Número total de pagos de la prestación (sin paginación).
                        type: integer
                        example: 2
              examples:
                Con pagos:
                  value:
                    data:
                      label: Prima de Servicios 2024-2
                      payments:
                        - id: e63f873a-ba00-5ab2-976b-7ef76392c20a
                          date: '2024-06-30'
                          value: 750000
                        - id: termination
                          date: '2024-07-15'
                          value: 50000
                    filters:
                      page: 1
                      per_page: 20
                      total_records: 2
                Sin pagos:
                  value:
                    data:
                      label: Prima de Servicios 2024-2
                      payments: []
                    filters:
                      page: 1
                      per_page: 20
                      total_records: 0
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 7a886e31-c717-49ab-9448-da1a7c5c9e35
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
      - in: path
        required: true
        name: contract_social_benefit_id
        description: Identificador único (ID) asignado a la prestación social del contrato en la base de datos.
        schema:
          type: string
          example: c7c6d896-5f98-549b-8f63-10b1ae027e43
  /v1/{company_id}/contracts/{contract_id}/cost_center_configurations:
    get:
      operationId: indexCostCenterConfigurations
      tags:
        - Distribución de centros de costos
      summary: Listar configuraciones de centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de configuraciones de centros de costos de un contrato, ordenadas por fecha inicial de forma descendente.

        **¿Cuándo usar este endpoint?**

        * Consultar todas las configuraciones de centros de costos asociadas a un contrato.
        * Verificar la distribución histórica de centros de costos antes de crear una nueva configuración.
        * Determinar si una configuración es editable o eliminable antes de intentar modificarla.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Listado de configuraciones / Sin configuraciones
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo de configuraciones de centros de costos del contrato, ordenadas por fecha inicial descendente.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
                          type: string
                          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                        initial_day:
                          description: Fecha de inicio de vigencia de la configuración en formato ISO 8601.
                          type: string
                          format: date
                          example: '2022-01-01'
                        end_day:
                          description: Fecha de fin de vigencia de la configuración. Es null si es la configuración más reciente y no hay una posterior.
                          type:
                            - string
                            - 'null'
                          format: date
                          example: '2021-12-31'
                        editable:
                          description: Indica si la configuración puede ser modificada. Es true si el periodo de nómina es editable o si es la configuración actual y el contrato no ha sido terminado.
                          type: boolean
                          example: true
                        deleteable:
                          description: Indica si la configuración puede ser eliminada. Es true si existe más de una configuración activa para el contrato y la configuración es editable.
                          type: boolean
                          example: false
                        items:
                          description: Listado de ítems de distribución de la configuración, ordenados por nombre del centro de costos.
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al ítem de configuración en la base de datos.
                                type: string
                                example: a2b3c4d5-e6f7-8901-bcde-f23456789012
                              cost_center_id:
                                description: Identificador único (ID) del centro de costos asignado a este ítem.
                                type: string
                                example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                              cost_center_name:
                                description: Nombre del centro de costos.
                                type: string
                                example: Administración
                              cost_center_accounting_code:
                                description: Código contable del centro de costos.
                                type: string
                                example: '10001'
                              percentage:
                                description: Porcentaje de distribución asignado a este centro de costos.
                                type: number
                                example: 100
              examples:
                Configuraciones registradas:
                  value:
                    data:
                      - id: b2c3d4e5-6f78-90ab-cdef-1234567890ab
                        initial_day: '2022-01-01'
                        end_day: null
                        editable: true
                        deleteable: true
                        items:
                          - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                            cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                            cost_center_name: Administración
                            cost_center_accounting_code: '10001'
                            percentage: 60
                          - id: c3d4e5f6-a7b8-9012-cdef-345678901234
                            cost_center_id: f6a7b8c9-d0e1-2345-bcde-f67890123456
                            cost_center_name: Operaciones
                            cost_center_accounting_code: '10002'
                            percentage: 40
                      - id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                        initial_day: '2021-01-01'
                        end_day: '2021-12-31'
                        editable: false
                        deleteable: false
                        items:
                          - id: d4e5f6a7-b8c9-0123-defa-456789012345
                            cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                            cost_center_name: Administración
                            cost_center_accounting_code: '10001'
                            percentage: 100
                Sin configuraciones:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createCostCenterConfiguration
      tags:
        - Distribución de centros de costos
      summary: Crear configuración de centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva configuración de centros de costos para un contrato, definiendo cómo se distribuye el porcentaje entre los centros de costos asociados al contrato.

        **¿Cuándo usar este endpoint?**

        * Asignar por primera vez la distribución de centros de costos a un contrato recién creado.
        * Registrar un cambio en la distribución a partir de una nueva fecha de inicio.
        * Configurar múltiples centros de costos con porcentajes de distribución distintos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Primera configuración:** Si es la primera configuración del contrato, la fecha de inicio se establece automáticamente a la fecha de inicio del contrato, ignorando el valor enviado.
        * **Porcentajes:** La suma de los porcentajes de todos los ítems debe ser exactamente 100%. Se permiten hasta dos decimales por porcentaje.
        * **Suscripción:** Requiere que la empresa tenga un plan de suscripción activo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - cost_center_configuration
              properties:
                cost_center_configuration:
                  type: object
                  properties:
                    initial_day:
                      description: Fecha de inicio de vigencia de la nueva configuración en formato ISO 8601. Para la primera configuración del contrato se usa la fecha de inicio del contrato.
                      type: string
                      format: date
                      example: '2022-01-01'
                    items:
                      description: Arreglo de ítems que definen la distribución entre centros de costos.
                      type: array
                      items:
                        type: object
                        properties:
                          cost_center_id:
                            description: Identificador único (ID) del centro de costos al que se asigna el porcentaje.
                            type: string
                            example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                          percentage:
                            description: Porcentaje de distribución asignado a este centro de costos. Debe ser mayor a 0 y hasta 100, con máximo 2 decimales.
                            type: number
                            example: 100
                        required:
                          - cost_center_id
                          - percentage
                  required:
                    - items
      responses:
        '201':
          description: Configuración creada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle de la configuración creada, incluyendo los ítems de distribución.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
                        type: string
                        example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                      initial_day:
                        description: Fecha de inicio de vigencia de la configuración.
                        type: string
                        format: date
                        example: '2022-01-01'
                      end_day:
                        description: Fecha de fin de vigencia de la configuración. Es null si no hay una configuración posterior.
                        type:
                          - string
                          - 'null'
                        format: date
                        example: null
                      editable:
                        description: Indica si la configuración puede ser modificada.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si la configuración puede ser eliminada.
                        type: boolean
                        example: false
                      items:
                        description: Listado de ítems de distribución de la configuración, ordenados por nombre del centro de costos.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem de configuración en la base de datos.
                              type: string
                              example: a2b3c4d5-e6f7-8901-bcde-f23456789012
                            cost_center_id:
                              description: Identificador único (ID) del centro de costos asignado a este ítem.
                              type: string
                              example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                            cost_center_name:
                              description: Nombre del centro de costos.
                              type: string
                              example: Administración
                            cost_center_accounting_code:
                              description: Código contable del centro de costos.
                              type: string
                              example: '10001'
                            percentage:
                              description: Porcentaje de distribución asignado a este centro de costos.
                              type: number
                              example: 100
              example:
                data:
                  id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                  initial_day: '2022-01-01'
                  end_day: null
                  editable: true
                  deleteable: false
                  items:
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                      cost_center_name: Administración
                      cost_center_accounting_code: '10001'
                      percentage: 100
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Porcentajes no suman 100% / Fecha inicial duplicada / Fecha final inválida / Orden de configuración inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Porcentajes no suman 100%:
                  value:
                    error:
                      - code: '4902'
                        index: 0
                        message: Los porcentajes deben sumar exactamente 100%.
                        object: cost_center_configuration_item
                Fecha inicial duplicada:
                  value:
                    error:
                      - code: '4907'
                        index: 0
                        message: Ya existe una configuración con esta fecha inicial.
                        object: cost_center_configuration
                Fecha final inválida:
                  value:
                    error:
                      - code: '4908'
                        index: 0
                        message: La fecha final calculada es menor a la fecha inicial de la configuración.
                        object: cost_center_configuration
                Orden de configuración inválido:
                  value:
                    error:
                      - code: '4909'
                        index: 0
                        message: Solo puedes agregar configuraciones con fecha posterior a la configuración actual.
                        object: cost_center_configuration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-6f78-90ab-cdef-1234567890ab
  /v1/{company_id}/contracts/{contract_id}/cost_center_configurations/{id}:
    get:
      operationId: showCostCenterConfiguration
      tags:
        - Distribución de centros de costos
      summary: Obtener configuración de centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de una configuración de centros de costos de un contrato, incluyendo los ítems de distribución con sus porcentajes.

        **¿Cuándo usar este endpoint?**

        * Consultar los centros de costos y porcentajes asignados en una configuración específica.
        * Verificar si una configuración es editable o eliminable antes de intentar modificarla.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Detalle de la configuración de centros de costos
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle de la configuración de centros de costos, incluyendo los ítems de distribución.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
                        type: string
                        example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                      initial_day:
                        description: Fecha de inicio de vigencia de la configuración.
                        type: string
                        format: date
                        example: '2021-01-01'
                      end_day:
                        description: Fecha de fin de vigencia de la configuración. Es null si no hay una configuración posterior.
                        type:
                          - string
                          - 'null'
                        format: date
                        example: '2021-12-31'
                      editable:
                        description: Indica si la configuración puede ser modificada.
                        type: boolean
                        example: false
                      deleteable:
                        description: Indica si la configuración puede ser eliminada.
                        type: boolean
                        example: false
                      items:
                        description: Listado de ítems de distribución, ordenados por nombre del centro de costos.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem de configuración en la base de datos.
                              type: string
                              example: a2b3c4d5-e6f7-8901-bcde-f23456789012
                            cost_center_id:
                              description: Identificador único (ID) del centro de costos asignado a este ítem.
                              type: string
                              example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                            cost_center_name:
                              description: Nombre del centro de costos.
                              type: string
                              example: Administración
                            cost_center_accounting_code:
                              description: Código contable del centro de costos.
                              type: string
                              example: '10001'
                            percentage:
                              description: Porcentaje de distribución asignado a este centro de costos.
                              type: number
                              example: 100
              example:
                data:
                  id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                  initial_day: '2021-01-01'
                  end_day: '2021-12-31'
                  editable: false
                  deleteable: false
                  items:
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                      cost_center_name: Administración
                      cost_center_accounting_code: '10001'
                      percentage: 100
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateCostCenterConfiguration
      tags:
        - Distribución de centros de costos
      summary: Actualizar configuración de centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Actualiza la fecha de inicio de vigencia de una configuración de centros de costos. La fecha de fin de la configuración inmediatamente anterior se recalcula automáticamente para acomodar el cambio.

        **¿Cuándo usar este endpoint?**

        * Corregir la fecha de inicio de una configuración existente.
        * Ajustar los periodos de vigencia de los centros de costos de un contrato.
        * Mover la fecha de inicio a un rango que actualmente cubre la configuración anterior.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Editabilidad:** Solo se puede actualizar si el campo `editable` de la configuración es true.
        * **Primera configuración:** Si es la única configuración del contrato, la fecha de inicio se ajusta automáticamente a la fecha de inicio del contrato.
        * **Configuración anterior:** Si la nueva fecha de inicio cae dentro del rango de la configuración inmediatamente anterior, ésta ajusta automáticamente su fecha de fin. Sin embargo, si la nueva fecha quedaría entre dos configuraciones existentes distintas a la anterior inmediata, se retorna error 4911.
        * **Suscripción:** Requiere que la empresa tenga un plan de suscripción activo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - cost_center_configuration
              properties:
                cost_center_configuration:
                  type: object
                  properties:
                    initial_day:
                      description: Nueva fecha de inicio de vigencia de la configuración en formato ISO 8601.
                      type: string
                      format: date
                      example: '2022-06-01'
      responses:
        '200':
          description: Configuración actualizada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle de la configuración actualizada, incluyendo los ítems de distribución.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
                        type: string
                        example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                      initial_day:
                        description: Fecha de inicio de vigencia actualizada de la configuración.
                        type: string
                        format: date
                        example: '2022-06-01'
                      end_day:
                        description: Fecha de fin de vigencia de la configuración. Es null si no hay una configuración posterior.
                        type:
                          - string
                          - 'null'
                        format: date
                        example: null
                      editable:
                        description: Indica si la configuración puede ser modificada.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si la configuración puede ser eliminada.
                        type: boolean
                        example: true
                      items:
                        description: Listado de ítems de distribución de la configuración.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem de configuración en la base de datos.
                              type: string
                              example: a2b3c4d5-e6f7-8901-bcde-f23456789012
                            cost_center_id:
                              description: Identificador único (ID) del centro de costos asignado a este ítem.
                              type: string
                              example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                            cost_center_name:
                              description: Nombre del centro de costos.
                              type: string
                              example: Administración
                            cost_center_accounting_code:
                              description: Código contable del centro de costos.
                              type: string
                              example: '10001'
                            percentage:
                              description: Porcentaje de distribución asignado a este centro de costos.
                              type: number
                              example: 100
              example:
                data:
                  id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                  initial_day: '2022-06-01'
                  end_day: null
                  editable: true
                  deleteable: true
                  items:
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                      cost_center_name: Administración
                      cost_center_accounting_code: '10001'
                      percentage: 100
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Configuración no editable / Fecha anterior al contrato / Fechas duplicadas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Configuración no editable:
                  value:
                    error:
                      - code: '4901'
                        index: 0
                        message: Configuración de centro de costos no es editable.
                        object: cost_center_configuration
                Fecha anterior al contrato:
                  value:
                    error:
                      - code: '4912'
                        index: 0
                        message: La fecha inicial no puede ser anterior al inicio del contrato.
                        object: cost_center_configuration
                Fechas duplicadas:
                  value:
                    error:
                      - code: '4911'
                        index: 0
                        message: Ya existe una configuración activa para esta fecha.
                        object: cost_center_configuration
    delete:
      operationId: destroyCostCenterConfiguration
      tags:
        - Distribución de centros de costos
      summary: Eliminar configuración de centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Elimina una configuración de centros de costos de un contrato. Solo es posible si el campo `deleteable` es true.

        **¿Cuándo usar este endpoint?**

        * Revertir una configuración creada por error cuando existen al menos dos configuraciones activas en el contrato.
        * Eliminar la configuración más reciente para ajustar los centros de costos del contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Eliminabilidad:** Solo se puede eliminar si el campo `deleteable` de la configuración es true. Se puede verificar antes con el endpoint de listar o consultar.
        * **Suscripción:** Requiere que la empresa tenga un plan de suscripción activo.
      responses:
        '200':
          description: Configuración eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La configuración de centros de costos ha sido eliminada.
              example:
                data:
                  message: La configuración de centros de costos ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Configuración no eliminable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0501'
                    index: 0
                    message: Configuración de centro de costos no se puede eliminar.
                    object: cost_center_configuration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-6f78-90ab-cdef-1234567890ab
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
        schema:
          type: string
          example: c3d4e5f6-7890-abcd-ef12-345678901234
  /v1/{company_id}/contracts/{contract_id}/cost_center_configurations/{id}/editor:
    patch:
      operationId: updateCostCenterConfigurationEditor
      tags:
        - Distribución de centros de costos
      summary: Editar configuración de centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Actualiza de forma parcial una configuración de centros de costos existente. Permite
        modificar la fecha inicial (`initial_day`), gestionar los ítems de distribución
        (`items`), o ambos en una sola operación. Al menos uno de los dos campos debe enviarse.

        La acción sobre cada ítem se determina automáticamente según los campos enviados:

        * **Crear ítem:** Sin `id` — crea un nuevo ítem con el centro de costos y porcentaje indicados.
        * **Actualizar ítem:** Con `id` y `percentage` — actualiza el porcentaje del ítem existente.
          Puede incluir `cost_center_id` para reasignar el centro de costos.
        * **Eliminar ítem:** Con `id` y `_destroy: true` — elimina el ítem de la configuración.

        **¿Cuándo usar este endpoint?**

        * Corregir la fecha inicial de una configuración sin tener que eliminarla y crearla de nuevo.
        * Redistribuir los porcentajes entre los centros de costos de una configuración existente.
        * Agregar, actualizar o eliminar ítems de distribución en una sola llamada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con
          rol administrador (admin) o contador (accountant).
        * **Editabilidad:** Solo se puede modificar una configuración si el campo `editable` es true.
          Se puede verificar antes con el endpoint de consulta.
        * **Suma de porcentajes:** Los ítems resultantes tras aplicar los cambios deben sumar
          exactamente 100%.
        * **Suscripción:** Requiere que la empresa tenga un plan de suscripción activo.
      requestBody:
        required: true
        description: Solo fecha / Solo ítems (crear) / Solo ítems (actualizar) / Solo ítems (eliminar) / Fecha e ítems
        content:
          application/json:
            schema:
              type: object
              properties:
                cost_center_configuration:
                  description: Datos de la configuración de centros de costos a actualizar.
                  type: object
                  properties:
                    initial_day:
                      description: Nueva fecha inicial de la configuración en formato ISO 8601 (YYYY-MM-DD). Opcional si se envían ítems.
                      type: string
                      format: date
                      example: '2024-06-01'
                    items:
                      description: Lista de operaciones sobre los ítems de distribución de la configuración. Opcional si se envía la fecha inicial.
                      type: array
                      items:
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al ítem en la base de datos. Omitir para crear un ítem nuevo.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          cost_center_id:
                            description: Identificador único (ID) asignado al centro de costos en la base de datos.
                            type: string
                            example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                          percentage:
                            description: Porcentaje de distribución asignado al centro de costos. Debe ser mayor a 0 y hasta 100.
                            type: number
                            example: 60
                          _destroy:
                            description: Si es true, elimina el ítem de la configuración.
                            type: boolean
                            example: true
              required:
                - cost_center_configuration
            examples:
              Solo fecha:
                value:
                  cost_center_configuration:
                    initial_day: '2024-06-01'
              Solo ítems (crear):
                value:
                  cost_center_configuration:
                    items:
                      - cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                        percentage: 100
              Solo ítems (actualizar):
                value:
                  cost_center_configuration:
                    items:
                      - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        percentage: 60
                      - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        percentage: 40
              Solo ítems (eliminar):
                value:
                  cost_center_configuration:
                    items:
                      - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        _destroy: true
              Fecha e ítems:
                value:
                  cost_center_configuration:
                    initial_day: '2024-06-01'
                    items:
                      - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        percentage: 70
                      - cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                        percentage: 30
      responses:
        '200':
          description: Configuración actualizada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle actualizado de la configuración de centros de costos.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración en la base de datos.
                        type: string
                        example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                      initial_day:
                        description: Fecha inicial de vigencia de la configuración.
                        type: string
                        format: date
                        example: '2024-06-01'
                      end_day:
                        description: Fecha final de vigencia de la configuración. Es null si es la configuración más reciente del contrato.
                        type:
                          - string
                          - 'null'
                        format: date
                        example: '2024-12-31'
                      editable:
                        description: Indica si la configuración puede ser modificada.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si la configuración puede ser eliminada. Solo es posible si el contrato tiene más de una configuración y la configuración es editable.
                        type: boolean
                        example: false
                      items:
                        description: Lista de ítems de distribución por centro de costos.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            cost_center_id:
                              description: Identificador único (ID) asignado al centro de costos en la base de datos.
                              type: string
                              example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                            cost_center_name:
                              description: Nombre del centro de costos asignado.
                              type: string
                              example: Administración
                            cost_center_accounting_code:
                              description: Código contable del centro de costos.
                              type: string
                              example: '10001'
                            percentage:
                              description: Porcentaje de distribución asignado al centro de costos.
                              type: number
                              example: 100
              example:
                data:
                  id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                  initial_day: '2024-06-01'
                  end_day: null
                  editable: true
                  deleteable: false
                  items:
                    - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                      cost_center_name: Administración
                      cost_center_accounting_code: '10001'
                      percentage: 100
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Configuración no editable / Fecha anterior al contrato / Fechas duplicadas / ID de ítem inválido / Centro de costos ya asignado / Faltan campos en ítem nuevo / Falta porcentaje en ítem / Suma de porcentajes inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Configuración no editable:
                  value:
                    error:
                      - code: '4901'
                        index: 0
                        message: Configuración de centro de costos no es editable.
                        object: cost_center_configuration
                Fecha anterior al contrato:
                  value:
                    error:
                      - code: '4912'
                        index: 0
                        message: La fecha inicial no puede ser anterior al inicio del contrato.
                        object: cost_center_configuration
                Fechas duplicadas:
                  value:
                    error:
                      - code: '4911'
                        index: 0
                        message: Ya existe una configuración activa para esta fecha.
                        object: cost_center_configuration
                ID de ítem inválido:
                  value:
                    error:
                      - code: '4903'
                        index: 0
                        message: Uno o más ítems enviados no pertenecen a esta configuración.
                        object: cost_center_configuration_item
                Centro de costos ya asignado:
                  value:
                    error:
                      - code: '4906'
                        index: 0
                        message: El centro de costos ya está asignado en esta configuración.
                        object: cost_center_configuration_item
                Faltan campos en ítem nuevo:
                  value:
                    error:
                      - code: '4905'
                        index: 0
                        message: Cada ítem nuevo debe incluir el centro de costos y el porcentaje.
                        object: cost_center_configuration_item
                Falta porcentaje en ítem:
                  value:
                    error:
                      - code: '4904'
                        index: 0
                        message: Cada ítem a actualizar debe incluir el porcentaje.
                        object: cost_center_configuration_item
                Suma de porcentajes inválida:
                  value:
                    error:
                      - code: '4902'
                        index: 0
                        message: Los porcentajes deben sumar exactamente 100%.
                        object: cost_center_configuration_item
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-f6a7-8901-bcde-f12345678901
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/contracts/{contract_id}/cost_center_configurations/{cost_center_configuration_id}/items:
    patch:
      operationId: updateCostCenterConfigurationItems
      tags:
        - Distribución de centros de costos
      summary: Actualizar ítems de configuración
      description: |
        **¿Qué hace este endpoint?**

        Gestiona los ítems de distribución de una configuración de centros de costos en una sola operación. La acción sobre cada ítem se determina por los campos enviados:

        * **Actualizar:** Con `id` y `percentage` — actualiza el porcentaje del ítem existente. Se puede incluir `cost_center_id` para cambiar el centro de costos.
        * **Crear:** Sin `id`, con `cost_center_id` y `percentage` — agrega un nuevo ítem de distribución.
        * **Eliminar:** Con `id` y `_destroy: true` — elimina el ítem de la configuración.

        Los ítems no incluidos en la solicitud permanecen sin cambios. La suma de todos los porcentajes resultantes debe ser exactamente 100%.

        **¿Cuándo usar este endpoint?**

        * Reasignar los porcentajes de distribución entre centros de costos sin modificar la fecha de vigencia.
        * Agregar un nuevo centro de costos a la distribución de un contrato.
        * Eliminar un centro de costos de la configuración y redistribuir su porcentaje.
        * Realizar múltiples cambios en los ítems de distribución en una sola llamada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Editabilidad:** Solo se pueden modificar ítems si la configuración tiene `editable: true`.
        * **Porcentajes finales:** La suma de todos los porcentajes —incluyendo los ítems no modificados— debe ser exactamente 100%.
        * **Suscripción:** Requiere que la empresa tenga un plan de suscripción activo.
      requestBody:
        required: true
        description: Actualizar ítem / Crear ítem / Eliminar ítem / Operación combinada
        content:
          application/json:
            schema:
              type: object
              properties:
                items:
                  description: Arreglo de operaciones a ejecutar sobre los ítems de distribución.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) del ítem existente. Omitir para crear un ítem nuevo.
                        type: string
                        example: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      cost_center_id:
                        description: Identificador único (ID) del centro de costos. Requerido al crear un ítem nuevo. Opcional al actualizar para cambiar el centro de costos asignado.
                        type: string
                        example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                      percentage:
                        description: Porcentaje de distribución asignado a este centro de costos. Debe ser mayor a 0 y hasta 100, con máximo 2 decimales.
                        type: number
                        example: 70
                      _destroy:
                        description: Si es true, elimina el ítem existente indicado por `id`. Solo aplica cuando se envía `id`.
                        type: boolean
                        example: true
              required:
                - items
            examples:
              Actualizar ítem:
                value:
                  items:
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      percentage: 60
                    - id: b3c4d5e6-f789-0123-cdef-456789012345
                      percentage: 40
              Crear ítem:
                value:
                  items:
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      percentage: 70
                    - cost_center_id: f6a7b8c9-d012-3456-ef12-567890123456
                      percentage: 30
              Eliminar ítem:
                value:
                  items:
                    - id: b3c4d5e6-f789-0123-cdef-456789012345
                      _destroy: true
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      percentage: 100
              Operación combinada:
                value:
                  items:
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      percentage: 60
                    - id: b3c4d5e6-f789-0123-cdef-456789012345
                      _destroy: true
                    - cost_center_id: f6a7b8c9-d012-3456-ef12-567890123456
                      percentage: 40
      responses:
        '200':
          description: Ítems actualizados exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle de la configuración actualizada, incluyendo el estado final de todos los ítems de distribución.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
                        type: string
                        example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                      initial_day:
                        description: Fecha de inicio de vigencia de la configuración.
                        type: string
                        format: date
                        example: '2022-01-01'
                      end_day:
                        description: Fecha de fin de vigencia de la configuración. Es null si no hay una configuración posterior.
                        type:
                          - string
                          - 'null'
                        format: date
                        example: null
                      editable:
                        description: Indica si la configuración puede ser modificada.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si la configuración puede ser eliminada.
                        type: boolean
                        example: true
                      items:
                        description: Estado final de todos los ítems de distribución de la configuración, ordenados por nombre del centro de costos.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem de configuración en la base de datos.
                              type: string
                              example: a2b3c4d5-e6f7-8901-bcde-f23456789012
                            cost_center_id:
                              description: Identificador único (ID) del centro de costos asignado a este ítem.
                              type: string
                              example: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                            cost_center_name:
                              description: Nombre del centro de costos.
                              type: string
                              example: Administración
                            cost_center_accounting_code:
                              description: Código contable del centro de costos.
                              type: string
                              example: '10001'
                            percentage:
                              description: Porcentaje de distribución asignado a este centro de costos.
                              type: number
                              example: 60
              example:
                data:
                  id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                  initial_day: '2022-01-01'
                  end_day: null
                  editable: true
                  deleteable: true
                  items:
                    - id: a2b3c4d5-e6f7-8901-bcde-f23456789012
                      cost_center_id: e5f6a7b8-c9d0-1234-abcd-ef5678901234
                      cost_center_name: Administración
                      cost_center_accounting_code: '10001'
                      percentage: 60
                    - id: f6a7b8c9-d012-3456-ef12-567890123456
                      cost_center_id: c9d0e1f2-3456-7890-abcd-ef1234567890
                      cost_center_name: Operaciones
                      cost_center_accounting_code: '20001'
                      percentage: 40
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Configuración no editable / Porcentajes no suman 100% / ID de ítem inválido / Ítem sin porcentaje / Ítem nuevo sin centro de costos / Centro de costos duplicado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Configuración no editable:
                  value:
                    error:
                      - code: '4901'
                        index: 0
                        message: Configuración de centro de costos no es editable.
                        object: cost_center_configuration
                Porcentajes no suman 100%:
                  value:
                    error:
                      - code: '4902'
                        index: 0
                        message: Los porcentajes deben sumar exactamente 100%.
                        object: cost_center_configuration_item
                ID de ítem inválido:
                  value:
                    error:
                      - code: '4903'
                        index: 0
                        message: Uno o más ítems enviados no pertenecen a esta configuración.
                        object: cost_center_configuration_item
                Ítem sin porcentaje:
                  value:
                    error:
                      - code: '4904'
                        index: 0
                        message: Cada ítem a actualizar debe incluir el porcentaje.
                        object: cost_center_configuration_item
                Ítem nuevo sin centro de costos:
                  value:
                    error:
                      - code: '4905'
                        index: 0
                        message: Cada ítem nuevo debe incluir el centro de costos y el porcentaje.
                        object: cost_center_configuration_item
                Centro de costos duplicado:
                  value:
                    error:
                      - code: '4906'
                        index: 0
                        message: El centro de costos ya está asignado en esta configuración.
                        object: cost_center_configuration_item
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-6f78-90ab-cdef-1234567890ab
      - in: path
        required: true
        name: cost_center_configuration_id
        description: Identificador único (ID) asignado a la configuración de centros de costos en la base de datos.
        schema:
          type: string
          example: c3d4e5f6-7890-abcd-ef12-345678901234
  /v1/{company_id}/contracts/{contract_id}/salary_payments_file:
    get:
      operationId: showSalaryPaymentsFile
      tags:
        - Archivos de prestaciones
      summary: Obtener archivo de pagos salariales
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo Excel con el historial de pagos salariales de un contrato.

        **¿Cuándo usar este endpoint?**

        * Descargar el reporte de pagos salariales de un contrato para revisión o archivo.
        * Generar el archivo en segundo plano cuando el volumen de datos es grande
          y se prefiere no bloquear la respuesta.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Tipo de contrato:** Solo aplica para contratos laborales. Si el contrato no es
          de tipo laboral, se retorna un error 422.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/contracts/{contract_id}/salary_payments_file` para recibir
          la URL del archivo cuando esté listo.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          name: date
          required: false
          description: Fecha de corte para filtrar los pagos incluidos en el archivo, en formato YYYY-MM-DD.
          schema:
            type: string
            format: date
            example: '2024-12-31'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo generado.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/contracts/{contract_id}/salary_payments_file`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel de pagos salariales generado.
                        type: string
                        example: https://storage.aleluya.com/documents/contrato-pagos-salariales.xlsx
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que la generación del archivo fue encolada.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/documents/contrato-pagos-salariales.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato no laboral
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '3101'
                    index: 0
                    message: El contrato actual no corresponde a un contrato laboral (empleado o pensionado), por lo que no se puede liquidar.
                    object: contract
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
  /v1/{company_id}/contracts/{contract_id}/termination:
    get:
      operationId: showTermination
      tags:
        - Terminación de contratos
      summary: Obtener liquidación
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle completo de la liquidación existente de un contrato, incluyendo
        todas las bases de cálculo, valores de prestaciones sociales y montos de pago.

        **¿Cuándo usar este endpoint?**

        * Consultar los datos calculados de una liquidación antes de procesarla o imprimirla.
        * Verificar los valores de cesantías, primas, intereses y vacaciones pendientes.
        * Determinar el rango de fechas permitido (`min_date`, `max_date`) para la liquidación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Liquidación encontrada
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con todos los datos calculados de la liquidación del contrato.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la liquidación en la base de datos.
                        type: string
                        example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                      contract_id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                      payroll_id:
                        description: Identificador único (ID) asignado a la nómina de liquidación en la base de datos.
                        type: string
                        example: df840cb9-8c31-5293-a476-e726e2e9d759
                      cause:
                        description: Causa de terminación del contrato.
                        type: string
                        example: Sin justa causa
                      possible_trial_period:
                        description: Indica si el contrato tiene la posibilidad de estar en periodo de prueba al momento de la liquidación.
                        type: boolean
                        example: false
                      trial_period:
                        description: Indica si la terminación ocurre durante el periodo de prueba.
                        type: boolean
                        example: false
                      with_just_cause:
                        description: Indica si la terminación es con justa causa.
                        type: boolean
                        example: false
                      hire_date:
                        description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2019-01-01'
                      date:
                        description: Fecha de terminación del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-15'
                      min_date:
                        description: Fecha mínima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-01'
                      max_date:
                        description: Fecha máxima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-31'
                      worked_days:
                        description: Total de días trabajados durante la vigencia del contrato.
                        type: integer
                        example: 1065
                      holidays:
                        description: Días de vacaciones pendientes a liquidar.
                        type: number
                        example: 10.5
                      accumulated_holidays:
                        description: Días de vacaciones acumulados y pendientes de pago.
                        type: number
                        example: 1.25
                      holidays_value:
                        description: Valor a pagar por vacaciones pendientes en pesos colombianos (COP).
                        type: integer
                        example: 433334
                      termination_base:
                        description: Base salarial usada para el cálculo de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      holidays_base:
                        description: Base salarial usada para el cálculo de vacaciones en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      service_bonus_base:
                        description: Base salarial usada para el cálculo de prima de servicios en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      severance_base:
                        description: Base salarial usada para el cálculo de cesantías en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      previous_service_bonus_base:
                        description: Base salarial para prima del semestre anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      previous_severance_base:
                        description: Base salarial para cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_days:
                        description: Días del semestre actual para el cálculo de prima de servicios.
                        type: integer
                        example: 165
                      previous_service_bonus_days:
                        description: Días del semestre anterior para el cálculo de prima de servicios.
                        type: integer
                        example: 0
                      severance_days:
                        description: Días del periodo actual para el cálculo de cesantías.
                        type: integer
                        example: 345
                      previous_severance_days:
                        description: Días del periodo anterior para el cálculo de cesantías.
                        type: integer
                        example: 0
                      severance_interests_days:
                        description: Días del periodo actual para el cálculo de intereses de cesantías.
                        type: integer
                        example: 345
                      previous_severance_interests_days:
                        description: Días del periodo anterior para el cálculo de intereses de cesantías.
                        type: integer
                        example: 0
                      pay_rest_days:
                        description: Indica si se pagan días de descanso pendientes.
                        type: boolean
                        example: false
                      show_pay_service_bonus:
                        description: Indica si la opción de pagar prima de servicios es visible.
                        type: boolean
                        example: false
                      pay_service_bonus:
                        description: Indica si se paga la prima de servicios del semestre actual.
                        type: boolean
                        example: true
                      pay_previous_service_bonus:
                        description: Indica si se paga la prima del semestre anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance:
                        description: Indica si la opción de pagar cesantías anteriores es visible.
                        type: boolean
                        example: false
                      pay_previous_severance:
                        description: Indica si se pagan las cesantías del periodo anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance_interests:
                        description: Indica si la opción de pagar intereses de cesantías anteriores es visible.
                        type: boolean
                        example: false
                      pay_previous_severance_interests:
                        description: Indica si se pagan los intereses de cesantías del periodo anterior.
                        type: boolean
                        example: false
                      non_salary_income:
                        description: Ingresos no salariales incluidos en la base de cálculo en pesos colombianos (COP).
                        type: integer
                        example: 0
                      occasional_non_salary_income:
                        description: Ingresos no salariales ocasionales en pesos colombianos (COP).
                        type: integer
                        example: 0
                      loans:
                        description: Monto de préstamos descontados en pesos colombianos (COP).
                        type: integer
                        example: 0
                      deductions:
                        description: Deducciones adicionales aplicadas en pesos colombianos (COP).
                        type: integer
                        example: 0
                      anticipated_social_benefits_value:
                        description: Valor de prestaciones anticipadas ya pagadas en pesos colombianos (COP).
                        type: integer
                        example: 0
                      payroll_credit_value:
                        description: Crédito de nómina descontado en pesos colombianos (COP).
                        type: integer
                        example: 0
                      show_decree376:
                        description: Indica si aplica el pago del Decreto 376.
                        type: boolean
                        example: false
                      pay_decree376:
                        description: Indica si se está pagando el Decreto 376.
                        type: boolean
                        example: false
                      decree376:
                        description: Valor del Decreto 376 a pagar en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_retention:
                        description: Retención sobre la indemnización en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_retention:
                        description: Retención sobre la prima de servicios en pesos colombianos (COP).
                        type: integer
                        example: 0
                      notes:
                        description: Notas u observaciones adicionales de la liquidación.
                        type:
                          - string
                          - 'null'
                        example: null
                      service_bonus:
                        description: Valor de prima de servicios del semestre actual en pesos colombianos (COP).
                        type: integer
                        example: 640306
                      total_paid_service_bonus:
                        description: Valor neto a pagar de prima (descontando anticipos) en pesos colombianos (COP).
                        type: integer
                        example: 640306
                      previous_service_bonus:
                        description: Valor de prima del semestre anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance:
                        description: Valor de cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 1338822
                      previous_severance:
                        description: Valor de cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance_interests:
                        description: Valor de intereses sobre cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 153965
                      previous_severance_interests:
                        description: Valor de intereses de cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_fund:
                        description: Aporte del empleador a la caja de compensación familiar en pesos colombianos (COP).
                        type: integer
                        example: 17333
                      sena:
                        description: Aporte del empleador al SENA en pesos colombianos (COP).
                        type: integer
                        example: 0
                      icbf:
                        description: Aporte del empleador al ICBF en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation:
                        description: Valor de indemnización por despido sin justa causa en pesos colombianos (COP).
                        type: integer
                        example: 0
                      withholding_tax:
                        description: Valor de retención en la fuente sobre los pagos de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      worker_payment:
                        description: Total neto a pagar al trabajador en pesos colombianos (COP).
                        type: integer
                        example: 2566427
                      company_cost:
                        description: Costo total para la empresa en aportes parafiscales en pesos colombianos (COP).
                        type: integer
                        example: 17333
                      bank_file:
                        description: Indica si la liquidación puede incluirse en un archivo de pago bancario.
                        type: boolean
                        example: true
              example:
                data:
                  id: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                  contract_id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                  payroll_id: df840cb9-8c31-5293-a476-e726e2e9d759
                  cause: Sin justa causa
                  possible_trial_period: false
                  trial_period: false
                  with_just_cause: false
                  hire_date: '2019-01-01'
                  date: '2024-12-15'
                  min_date: '2024-12-01'
                  max_date: '2024-12-31'
                  worked_days: 1065
                  holidays: 10.5
                  accumulated_holidays: 1.25
                  holidays_value: 433334
                  termination_base: 3500000
                  holidays_base: 3500000
                  service_bonus_base: 3500000
                  severance_base: 3500000
                  previous_service_bonus_base: 0
                  previous_severance_base: 0
                  service_bonus_days: 165
                  previous_service_bonus_days: 0
                  severance_days: 345
                  previous_severance_days: 0
                  severance_interests_days: 345
                  previous_severance_interests_days: 0
                  pay_rest_days: false
                  show_pay_service_bonus: false
                  pay_service_bonus: true
                  pay_previous_service_bonus: false
                  show_pay_previous_severance: false
                  pay_previous_severance: false
                  show_pay_previous_severance_interests: false
                  pay_previous_severance_interests: false
                  non_salary_income: 0
                  occasional_non_salary_income: 0
                  loans: 0
                  deductions: 0
                  anticipated_social_benefits_value: 0
                  payroll_credit_value: 0
                  show_decree376: false
                  pay_decree376: false
                  decree376: 0
                  compensation_retention: 0
                  service_bonus_retention: 0
                  notes: null
                  service_bonus: 640306
                  total_paid_service_bonus: 640306
                  previous_service_bonus: 0
                  severance: 1338822
                  previous_severance: 0
                  severance_interests: 153965
                  previous_severance_interests: 0
                  compensation_fund: 17333
                  sena: 0
                  icbf: 0
                  compensation: 0
                  withholding_tax: 0
                  worker_payment: 2566427
                  company_cost: 17333
                  bank_file: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createTermination
      tags:
        - Terminación de contratos
      summary: Crear liquidación
      description: |
        **¿Qué hace este endpoint?**

        Crea la liquidación del contrato laboral de una persona. Calcula automáticamente
        prestaciones sociales (cesantías, primas, intereses), vacaciones pendientes, parafiscales
        y el valor total a pagar al trabajador.

        **¿Cuándo usar este endpoint?**

        * Liquidar a una persona cuando termina su relación laboral.
        * Registrar la causa de terminación y la fecha de liquidación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Tipo de contrato:** Solo aplica a contratos laborales (empleado o pensionado).
        * **Registro completo:** La persona debe tener toda su información laboral completa (EPS, pensión, sede y tipo de riesgo).
        * **Sin liquidación previa:** El contrato no debe tener una liquidación activa.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                termination:
                  description: Objeto con los datos para crear la liquidación.
                  type: object
                  properties:
                    cause:
                      description: Causa de terminación del contrato según la legislación laboral colombiana.
                      type: string
                      example: Sin justa causa
                    date:
                      description: Fecha de terminación del contrato en formato YYYY-MM-DD. Debe estar dentro del rango `min_date`–`max_date`.
                      type: string
                      format: date
                      example: '2024-12-15'
                    trial_period:
                      description: Indica si la terminación ocurre durante el periodo de prueba.
                      type: boolean
                      example: false
                    with_just_cause:
                      description: Indica si la terminación es con justa causa.
                      type: boolean
                      example: false
                    holidays:
                      description: Días de vacaciones pendientes a liquidar. Si se omite, el sistema los calcula automáticamente.
                      type: number
                      example: 10.5
                    termination_base:
                      description: Base salarial personalizada para el cálculo de la liquidación en pesos colombianos (COP). Si se omite, se usa el salario vigente.
                      type: integer
                      example: 3500000
                    holidays_base:
                      description: Base salarial personalizada para el cálculo de vacaciones en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    service_bonus_base:
                      description: Base salarial personalizada para el cálculo de prima en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    severance_base:
                      description: Base salarial personalizada para el cálculo de cesantías en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    previous_service_bonus_base:
                      description: Base salarial para el cálculo de prima del semestre anterior en pesos colombianos (COP).
                      type: integer
                      example: 0
                    previous_severance_base:
                      description: Base salarial para el cálculo de cesantías del periodo anterior en pesos colombianos (COP).
                      type: integer
                      example: 0
                    pay_rest_days:
                      description: Indica si se deben pagar los días de descanso pendientes.
                      type: boolean
                      example: false
                    pay_service_bonus:
                      description: Indica si se debe pagar la prima del semestre actual.
                      type: boolean
                      example: true
                    pay_previous_service_bonus:
                      description: Indica si se debe pagar la prima del semestre anterior.
                      type: boolean
                      example: false
                    pay_previous_severance:
                      description: Indica si se deben pagar las cesantías del periodo anterior.
                      type: boolean
                      example: false
                    pay_previous_severance_interests:
                      description: Indica si se deben pagar los intereses de cesantías del periodo anterior.
                      type: boolean
                      example: false
                    pay_decree376:
                      description: Indica si aplica el pago correspondiente al Decreto 376 (diferencia de salario para trabajadores con salario inferior al mínimo).
                      type: boolean
                      example: false
                    loans:
                      description: Monto de préstamos pendientes a descontar de la liquidación en pesos colombianos (COP).
                      type: integer
                      example: 0
                    non_salary_income:
                      description: Ingresos no salariales a incluir en la base de cálculo en pesos colombianos (COP).
                      type: integer
                      example: 0
                    occasional_non_salary_income:
                      description: Ingresos no salariales ocasionales a incluir en la base de cálculo en pesos colombianos (COP).
                      type: integer
                      example: 0
                    deductions:
                      description: Deducciones adicionales a aplicar sobre la liquidación en pesos colombianos (COP).
                      type: integer
                      example: 0
                    payroll_credit:
                      description: Crédito de nómina a descontar de la liquidación en pesos colombianos (COP).
                      type: integer
                      example: 0
                    compensation_retention:
                      description: Retención sobre la indemnización por despido sin justa causa en pesos colombianos (COP).
                      type: integer
                      example: 0
                    service_bonus_retention:
                      description: Retención sobre la prima de servicios en pesos colombianos (COP).
                      type: integer
                      example: 0
                    notes:
                      description: Notas u observaciones adicionales sobre la liquidación.
                      type: string
                      example: Acuerdo de terminación mutua firmado.
                  required:
                    - cause
                    - date
              required:
                - termination
      responses:
        '201':
          description: Liquidación creada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con los datos completos de la liquidación recién creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la liquidación en la base de datos.
                        type: string
                        example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                      contract_id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                      payroll_id:
                        description: Identificador único (ID) asignado a la nómina de liquidación en la base de datos.
                        type: string
                        example: df840cb9-8c31-5293-a476-e726e2e9d759
                      cause:
                        description: Causa de terminación del contrato.
                        type: string
                        example: Sin justa causa
                      possible_trial_period:
                        description: Indica si el contrato tiene la posibilidad de estar en periodo de prueba al momento de la liquidación.
                        type: boolean
                        example: false
                      trial_period:
                        description: Indica si la terminación ocurre durante el periodo de prueba.
                        type: boolean
                        example: false
                      with_just_cause:
                        description: Indica si la terminación es con justa causa.
                        type: boolean
                        example: false
                      hire_date:
                        description: Fecha de inicio del contrato (fecha de contratación) en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2019-01-01'
                      date:
                        description: Fecha de terminación del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-15'
                      min_date:
                        description: Fecha mínima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-01'
                      max_date:
                        description: Fecha máxima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-31'
                      worked_days:
                        description: Total de días trabajados durante la vigencia del contrato.
                        type: integer
                        example: 1065
                      holidays:
                        description: Días de vacaciones pendientes a liquidar.
                        type: number
                        example: 10.5
                      accumulated_holidays:
                        description: Días de vacaciones acumulados y pendientes de pago al momento de la liquidación.
                        type: number
                        example: 1.25
                      holidays_value:
                        description: Valor en pesos colombianos (COP) a pagar por vacaciones pendientes.
                        type: integer
                        example: 433334
                      termination_base:
                        description: Base salarial usada para el cálculo de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      holidays_base:
                        description: Base salarial usada para el cálculo de vacaciones en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      service_bonus_base:
                        description: Base salarial usada para el cálculo de prima de servicios en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      severance_base:
                        description: Base salarial usada para el cálculo de cesantías en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      previous_service_bonus_base:
                        description: Base salarial usada para el cálculo de prima del semestre anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      previous_severance_base:
                        description: Base salarial usada para el cálculo de cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_days:
                        description: Días del semestre actual utilizados para calcular la prima de servicios.
                        type: integer
                        example: 165
                      previous_service_bonus_days:
                        description: Días del semestre anterior utilizados para calcular la prima de servicios.
                        type: integer
                        example: 0
                      severance_days:
                        description: Días del periodo actual utilizados para calcular las cesantías.
                        type: integer
                        example: 345
                      previous_severance_days:
                        description: Días del periodo anterior utilizados para calcular las cesantías.
                        type: integer
                        example: 0
                      severance_interests_days:
                        description: Días del periodo actual utilizados para calcular los intereses de cesantías.
                        type: integer
                        example: 345
                      previous_severance_interests_days:
                        description: Días del periodo anterior utilizados para calcular los intereses de cesantías.
                        type: integer
                        example: 0
                      pay_rest_days:
                        description: Indica si se pagan los días de descanso pendientes en la liquidación.
                        type: boolean
                        example: false
                      show_pay_service_bonus:
                        description: Indica si la opción de pagar prima de servicios es visible según las condiciones del contrato.
                        type: boolean
                        example: false
                      pay_service_bonus:
                        description: Indica si se paga la prima de servicios del semestre actual.
                        type: boolean
                        example: true
                      pay_previous_service_bonus:
                        description: Indica si se paga la prima de servicios del semestre anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance:
                        description: Indica si la opción de pagar cesantías del periodo anterior es visible según las condiciones del contrato.
                        type: boolean
                        example: false
                      pay_previous_severance:
                        description: Indica si se pagan las cesantías del periodo anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance_interests:
                        description: Indica si la opción de pagar intereses de cesantías del periodo anterior es visible según las condiciones del contrato.
                        type: boolean
                        example: false
                      pay_previous_severance_interests:
                        description: Indica si se pagan los intereses de cesantías del periodo anterior.
                        type: boolean
                        example: false
                      non_salary_income:
                        description: Ingresos no salariales incluidos en la base de cálculo de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      occasional_non_salary_income:
                        description: Ingresos no salariales ocasionales incluidos en la base de cálculo en pesos colombianos (COP).
                        type: integer
                        example: 0
                      loans:
                        description: Monto de préstamos descontados de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      deductions:
                        description: Deducciones adicionales aplicadas sobre la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      anticipated_social_benefits_value:
                        description: Valor de prestaciones sociales anticipadas ya pagadas y descontadas de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      payroll_credit_value:
                        description: Crédito de nómina descontado de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      show_decree376:
                        description: Indica si aplica el pago del Decreto 376 (diferencia de salario mínimo).
                        type: boolean
                        example: false
                      pay_decree376:
                        description: Indica si se está pagando el Decreto 376 en esta liquidación.
                        type: boolean
                        example: false
                      decree376:
                        description: Valor del Decreto 376 a pagar en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_retention:
                        description: Retención aplicada sobre la indemnización por despido sin justa causa en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_retention:
                        description: Retención aplicada sobre la prima de servicios en pesos colombianos (COP).
                        type: integer
                        example: 0
                      notes:
                        description: Notas u observaciones adicionales registradas para la liquidación.
                        type:
                          - string
                          - 'null'
                        example: null
                      service_bonus:
                        description: Valor total calculado de prima de servicios del semestre actual en pesos colombianos (COP).
                        type: integer
                        example: 640306
                      total_paid_service_bonus:
                        description: Valor neto a pagar de prima de servicios (descontando anticipos) en pesos colombianos (COP).
                        type: integer
                        example: 640306
                      previous_service_bonus:
                        description: Valor de prima de servicios del semestre anterior a pagar en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance:
                        description: Valor total calculado de cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 1338822
                      previous_severance:
                        description: Valor de cesantías del periodo anterior a pagar en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance_interests:
                        description: Valor de intereses sobre cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 153965
                      previous_severance_interests:
                        description: Valor de intereses sobre cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_fund:
                        description: Aporte del empleador a la caja de compensación familiar en pesos colombianos (COP).
                        type: integer
                        example: 17333
                      sena:
                        description: Aporte del empleador al SENA en pesos colombianos (COP).
                        type: integer
                        example: 0
                      icbf:
                        description: Aporte del empleador al ICBF en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation:
                        description: Valor de indemnización por terminación sin justa causa en pesos colombianos (COP).
                        type: integer
                        example: 0
                      withholding_tax:
                        description: Valor de retención en la fuente aplicada sobre los pagos de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      worker_payment:
                        description: Total neto a pagar al trabajador en pesos colombianos (COP), incluyendo todos los conceptos de la liquidación menos las deducciones.
                        type: integer
                        example: 2566427
                      company_cost:
                        description: Costo total para la empresa correspondiente a los aportes parafiscales de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 17333
                      bank_file:
                        description: Indica si la liquidación puede incluirse en un archivo de pago bancario.
                        type: boolean
                        example: true
              example:
                data:
                  id: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                  contract_id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                  payroll_id: df840cb9-8c31-5293-a476-e726e2e9d759
                  cause: Sin justa causa
                  possible_trial_period: false
                  trial_period: false
                  with_just_cause: false
                  hire_date: '2019-01-01'
                  date: '2024-12-15'
                  min_date: '2024-12-01'
                  max_date: '2024-12-31'
                  worked_days: 1065
                  holidays: 10.5
                  accumulated_holidays: 1.25
                  holidays_value: 433334
                  termination_base: 3500000
                  holidays_base: 3500000
                  service_bonus_base: 3500000
                  severance_base: 3500000
                  previous_service_bonus_base: 0
                  previous_severance_base: 0
                  service_bonus_days: 165
                  previous_service_bonus_days: 0
                  severance_days: 345
                  previous_severance_days: 0
                  severance_interests_days: 345
                  previous_severance_interests_days: 0
                  pay_rest_days: false
                  show_pay_service_bonus: false
                  pay_service_bonus: true
                  pay_previous_service_bonus: false
                  show_pay_previous_severance: false
                  pay_previous_severance: false
                  show_pay_previous_severance_interests: false
                  pay_previous_severance_interests: false
                  non_salary_income: 0
                  occasional_non_salary_income: 0
                  loans: 0
                  deductions: 0
                  anticipated_social_benefits_value: 0
                  payroll_credit_value: 0
                  show_decree376: false
                  pay_decree376: false
                  decree376: 0
                  compensation_retention: 0
                  service_bonus_retention: 0
                  notes: null
                  service_bonus: 640306
                  total_paid_service_bonus: 640306
                  previous_service_bonus: 0
                  severance: 1338822
                  previous_severance: 0
                  severance_interests: 153965
                  previous_severance_interests: 0
                  compensation_fund: 17333
                  sena: 0
                  icbf: 0
                  compensation: 0
                  withholding_tax: 0
                  worker_payment: 2566427
                  company_cost: 17333
                  bank_file: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato no liquidable / Liquidación duplicada / Sin información laboral completa / Contrato sin tiempo trabajado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato no liquidable:
                  value:
                    error:
                      - code: '3101'
                        index: 0
                        message: El contrato actual no corresponde a un contrato laboral (empleado o pensionado), por lo que no se puede liquidar.
                        object: contract
                Liquidación duplicada:
                  value:
                    error:
                      - code: '3102'
                        index: 0
                        message: El contrato ya ha sido liquidado. No puedes crear una nueva liquidación.
                        object: contract
                Sin información laboral completa:
                  value:
                    error:
                      - code: '3109'
                        index: 0
                        message: Para liquidar a esta persona, primero debe completar toda la información laboral del empleado (EPS, fondo de pensiones, sede y tipo de riesgo).
                        object: termination
                Contrato sin tiempo trabajado:
                  value:
                    error:
                      - code: '3108'
                        index: 0
                        message: Para poder liquidar a esta persona, debe tener al menos un día trabajado o con novedades en el mes.
                        object: termination
    patch:
      operationId: updateTermination
      tags:
        - Terminación de contratos
      summary: Actualizar liquidación
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los datos de una liquidación existente, recalculando automáticamente los valores
        de prestaciones sociales con los nuevos parámetros indicados.

        **¿Cuándo usar este endpoint?**

        * Corregir la fecha de terminación o la causa de liquidación.
        * Ajustar las bases salariales o los días de vacaciones antes de confirmar el pago.
        * Modificar las opciones de pago (prima anterior, cesantías anteriores, decreto 376).

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Ingreso no salarial:** No puede superar el 40% del ingreso mensual.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                termination:
                  description: Objeto con los campos de la liquidación a actualizar.
                  type: object
                  properties:
                    cause:
                      description: Causa de terminación del contrato según la legislación laboral colombiana.
                      type: string
                      example: Con justa causa
                    date:
                      description: Fecha de terminación del contrato en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-11-30'
                    trial_period:
                      description: Indica si la terminación ocurre durante el periodo de prueba.
                      type: boolean
                      example: false
                    with_just_cause:
                      description: Indica si la terminación es con justa causa.
                      type: boolean
                      example: true
                    holidays:
                      description: Días de vacaciones pendientes a liquidar.
                      type: number
                      example: 12.5
                    termination_base:
                      description: Base salarial personalizada para el cálculo en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    holidays_base:
                      description: Base salarial para el cálculo de vacaciones en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    service_bonus_base:
                      description: Base salarial para el cálculo de prima de servicios en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    severance_base:
                      description: Base salarial para el cálculo de cesantías en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    previous_service_bonus_base:
                      description: Base salarial para el cálculo de prima del semestre anterior en pesos colombianos (COP).
                      type: integer
                      example: 0
                    previous_severance_base:
                      description: Base salarial para el cálculo de cesantías del periodo anterior en pesos colombianos (COP).
                      type: integer
                      example: 0
                    pay_rest_days:
                      description: Indica si se deben pagar los días de descanso pendientes.
                      type: boolean
                      example: false
                    pay_service_bonus:
                      description: Indica si se debe pagar la prima del semestre actual.
                      type: boolean
                      example: true
                    pay_previous_service_bonus:
                      description: Indica si se debe pagar la prima del semestre anterior.
                      type: boolean
                      example: false
                    pay_previous_severance:
                      description: Indica si se deben pagar las cesantías del periodo anterior.
                      type: boolean
                      example: false
                    pay_previous_severance_interests:
                      description: Indica si se deben pagar los intereses de cesantías del periodo anterior.
                      type: boolean
                      example: false
                    pay_decree376:
                      description: Indica si aplica el pago del Decreto 376.
                      type: boolean
                      example: false
                    loans:
                      description: Monto de préstamos pendientes a descontar en pesos colombianos (COP).
                      type: integer
                      example: 0
                    non_salary_income:
                      description: Ingresos no salariales a incluir en la base de cálculo en pesos colombianos (COP).
                      type: integer
                      example: 0
                    occasional_non_salary_income:
                      description: Ingresos no salariales ocasionales en pesos colombianos (COP).
                      type: integer
                      example: 0
                    deductions:
                      description: Deducciones adicionales en pesos colombianos (COP).
                      type: integer
                      example: 0
                    payroll_credit:
                      description: Crédito de nómina a descontar en pesos colombianos (COP).
                      type: integer
                      example: 0
                    compensation_retention:
                      description: Retención sobre la indemnización en pesos colombianos (COP).
                      type: integer
                      example: 0
                    service_bonus_retention:
                      description: Retención sobre la prima de servicios en pesos colombianos (COP).
                      type: integer
                      example: 0
                    notes:
                      description: Notas u observaciones adicionales sobre la liquidación.
                      type: string
                      example: Acuerdo de terminación mutua firmado.
              required:
                - termination
      responses:
        '202':
          description: Liquidación actualizada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con los datos actualizados de la liquidación.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la liquidación en la base de datos.
                        type: string
                        example: 264fdf6e-a161-56a9-a26e-e0893743e5cc
                      contract_id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                      payroll_id:
                        description: Identificador único (ID) asignado a la nómina de liquidación en la base de datos.
                        type: string
                        example: e939c90f-ab57-55da-9931-ffdd16e17f88
                      cause:
                        description: Causa de terminación del contrato.
                        type: string
                        example: Con justa causa
                      possible_trial_period:
                        description: Indica si el contrato tiene la posibilidad de estar en periodo de prueba al momento de la liquidación.
                        type: boolean
                        example: false
                      trial_period:
                        description: Indica si la terminación ocurre durante el periodo de prueba.
                        type: boolean
                        example: false
                      with_just_cause:
                        description: Indica si la terminación es con justa causa.
                        type: boolean
                        example: true
                      hire_date:
                        description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2019-01-01'
                      date:
                        description: Fecha de terminación del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-11-30'
                      min_date:
                        description: Fecha mínima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-11-01'
                      max_date:
                        description: Fecha máxima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-11-30'
                      worked_days:
                        description: Total de días trabajados durante la vigencia del contrato.
                        type: integer
                        example: 391
                      holidays:
                        description: Días de vacaciones pendientes a liquidar.
                        type: number
                        example: 12.5
                      accumulated_holidays:
                        description: Días de vacaciones acumulados y pendientes de pago.
                        type: number
                        example: 15
                      holidays_value:
                        description: Valor a pagar por vacaciones pendientes en pesos colombianos (COP).
                        type: integer
                        example: 1254167
                      termination_base:
                        description: Base salarial usada para el cálculo en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      holidays_base:
                        description: Base salarial usada para el cálculo de vacaciones en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      service_bonus_base:
                        description: Base salarial usada para el cálculo de prima en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      severance_base:
                        description: Base salarial usada para el cálculo de cesantías en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      previous_service_bonus_base:
                        description: Base salarial para prima del semestre anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      previous_severance_base:
                        description: Base salarial para cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_days:
                        description: Días del semestre actual para el cálculo de prima de servicios.
                        type: integer
                        example: 121
                      previous_service_bonus_days:
                        description: Días del semestre anterior para el cálculo de prima de servicios.
                        type: integer
                        example: 0
                      severance_days:
                        description: Días del periodo actual para el cálculo de cesantías.
                        type: integer
                        example: 301
                      previous_severance_days:
                        description: Días del periodo anterior para el cálculo de cesantías.
                        type: integer
                        example: 0
                      severance_interests_days:
                        description: Días del periodo actual para el cálculo de intereses de cesantías.
                        type: integer
                        example: 301
                      previous_severance_interests_days:
                        description: Días del periodo anterior para el cálculo de intereses de cesantías.
                        type: integer
                        example: 0
                      pay_rest_days:
                        description: Indica si se pagan días de descanso pendientes.
                        type: boolean
                        example: false
                      show_pay_service_bonus:
                        description: Indica si la opción de pagar prima de servicios es visible.
                        type: boolean
                        example: false
                      pay_service_bonus:
                        description: Indica si se paga la prima de servicios del semestre actual.
                        type: boolean
                        example: true
                      pay_previous_service_bonus:
                        description: Indica si se paga la prima del semestre anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance:
                        description: Indica si la opción de pagar cesantías anteriores es visible.
                        type: boolean
                        example: false
                      pay_previous_severance:
                        description: Indica si se pagan las cesantías del periodo anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance_interests:
                        description: Indica si la opción de pagar intereses de cesantías anteriores es visible.
                        type: boolean
                        example: false
                      pay_previous_severance_interests:
                        description: Indica si se pagan los intereses de cesantías del periodo anterior.
                        type: boolean
                        example: false
                      non_salary_income:
                        description: Ingresos no salariales incluidos en la base de cálculo en pesos colombianos (COP).
                        type: integer
                        example: 0
                      occasional_non_salary_income:
                        description: Ingresos no salariales ocasionales en pesos colombianos (COP).
                        type: integer
                        example: 0
                      loans:
                        description: Monto de préstamos descontados en pesos colombianos (COP).
                        type: integer
                        example: 0
                      deductions:
                        description: Deducciones adicionales aplicadas en pesos colombianos (COP).
                        type: integer
                        example: 0
                      anticipated_social_benefits_value:
                        description: Valor de prestaciones anticipadas ya pagadas en pesos colombianos (COP).
                        type: integer
                        example: 0
                      payroll_credit_value:
                        description: Crédito de nómina descontado en pesos colombianos (COP).
                        type: integer
                        example: 0
                      show_decree376:
                        description: Indica si aplica el pago del Decreto 376.
                        type: boolean
                        example: false
                      pay_decree376:
                        description: Indica si se está pagando el Decreto 376.
                        type: boolean
                        example: false
                      decree376:
                        description: Valor del Decreto 376 en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_retention:
                        description: Retención sobre la indemnización en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_retention:
                        description: Retención sobre la prima de servicios en pesos colombianos (COP).
                        type: integer
                        example: 0
                      notes:
                        description: Notas u observaciones adicionales de la liquidación.
                        type:
                          - string
                          - 'null'
                        example: null
                      service_bonus:
                        description: Valor de prima de servicios del semestre actual en pesos colombianos (COP).
                        type: integer
                        example: 1008333
                      total_paid_service_bonus:
                        description: Valor neto a pagar de prima (descontando anticipos) en pesos colombianos (COP).
                        type: integer
                        example: 258333
                      previous_service_bonus:
                        description: Valor de prima del semestre anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance:
                        description: Valor de cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 2508333
                      previous_severance:
                        description: Valor de cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance_interests:
                        description: Valor de intereses sobre cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 251670
                      previous_severance_interests:
                        description: Valor de intereses de cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_fund:
                        description: Aporte del empleador a la caja de compensación familiar en pesos colombianos (COP).
                        type: integer
                        example: 50167
                      sena:
                        description: Aporte del empleador al SENA en pesos colombianos (COP).
                        type: integer
                        example: 0
                      icbf:
                        description: Aporte del empleador al ICBF en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation:
                        description: Valor de indemnización por despido sin justa causa en pesos colombianos (COP).
                        type: integer
                        example: 0
                      withholding_tax:
                        description: Valor de retención en la fuente sobre los pagos de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 0
                      worker_payment:
                        description: Total neto a pagar al trabajador en pesos colombianos (COP).
                        type: integer
                        example: 4172503
                      company_cost:
                        description: Costo total para la empresa en aportes parafiscales de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 70167
                      bank_file:
                        description: Indica si la liquidación puede incluirse en un archivo de pago bancario.
                        type: boolean
                        example: true
              example:
                data:
                  id: 264fdf6e-a161-56a9-a26e-e0893743e5cc
                  contract_id: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                  payroll_id: e939c90f-ab57-55da-9931-ffdd16e17f88
                  cause: Con justa causa
                  possible_trial_period: false
                  trial_period: false
                  with_just_cause: true
                  hire_date: '2019-01-01'
                  date: '2024-11-30'
                  min_date: '2024-11-01'
                  max_date: '2024-11-30'
                  worked_days: 391
                  holidays: 12.5
                  accumulated_holidays: 15
                  holidays_value: 1254167
                  termination_base: 3500000
                  holidays_base: 3500000
                  service_bonus_base: 3500000
                  severance_base: 3500000
                  previous_service_bonus_base: 0
                  previous_severance_base: 0
                  service_bonus_days: 121
                  previous_service_bonus_days: 0
                  severance_days: 301
                  previous_severance_days: 0
                  severance_interests_days: 301
                  previous_severance_interests_days: 0
                  pay_rest_days: false
                  show_pay_service_bonus: false
                  pay_service_bonus: true
                  pay_previous_service_bonus: false
                  show_pay_previous_severance: false
                  pay_previous_severance: false
                  show_pay_previous_severance_interests: false
                  pay_previous_severance_interests: false
                  non_salary_income: 0
                  occasional_non_salary_income: 0
                  loans: 0
                  deductions: 0
                  anticipated_social_benefits_value: 0
                  payroll_credit_value: 0
                  show_decree376: false
                  pay_decree376: false
                  decree376: 0
                  compensation_retention: 0
                  service_bonus_retention: 0
                  notes: null
                  service_bonus: 1008333
                  total_paid_service_bonus: 258333
                  previous_service_bonus: 0
                  severance: 2508333
                  previous_severance: 0
                  severance_interests: 251670
                  previous_severance_interests: 0
                  compensation_fund: 50167
                  sena: 0
                  icbf: 0
                  compensation: 0
                  withholding_tax: 0
                  worker_payment: 4172503
                  company_cost: 70167
                  bank_file: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Ingreso no salarial excede el límite / Aprendiz no liquidable antes de julio 2025
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Ingreso no salarial excede el límite:
                  value:
                    error:
                      - code: '3112'
                        index: 0
                        message: El ingreso no salarial no puede ser mayor al 40% del ingreso mensual.
                        object: termination
                Aprendiz no liquidable antes de julio 2025:
                  value:
                    error:
                      - code: '3111'
                        index: 0
                        message: Los aprendices solo pueden ser liquidados a partir del 25 de junio de 2025.
                        object: termination
    delete:
      operationId: destroyTermination
      tags:
        - Terminación de contratos
      summary: Eliminar liquidación
      description: |
        **¿Qué hace este endpoint?**

        Elimina la liquidación de un contrato, revirtiendo el estado del contrato a activo
        y recalculando las nóminas y prestaciones sociales afectadas.

        **¿Cuándo usar este endpoint?**

        * Anular una liquidación creada por error antes de que sea definitiva.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Contrato actual:** Solo puede eliminarse la liquidación del contrato más reciente de la persona. Si la persona tiene contratos posteriores, primero deben eliminarse esos contratos.
      responses:
        '200':
          description: Liquidación eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La liquidación ha sido eliminada.
              example:
                data:
                  message: La liquidación ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato posterior activo impide eliminar la liquidación
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '3106'
                    index: 0
                    message: Para eliminar la liquidación, primero debes eliminar el contrato actual.
                    object: termination
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: b5ee90e9-921c-55c5-8dda-728eea651b2d
  /v1/{company_id}/contracts/{contract_id}/termination_preview:
    post:
      operationId: createTerminationPreview
      tags:
        - Terminación de contratos
      summary: Crear previsualización de liquidación
      description: |
        **¿Qué hace este endpoint?**

        Calcula una vista previa de la liquidación del contrato sin persistir los datos.
        Permite al usuario verificar todos los valores calculados (prestaciones, vacaciones,
        deducciones, pago al trabajador) antes de crear la liquidación definitiva.

        **¿Cuándo usar este endpoint?**

        * Mostrar al usuario los cálculos estimados de su liquidación antes de confirmarla.
        * Generar un archivo PDF previsualización del comprobante de liquidación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Tipo de contrato:** Solo aplica a contratos laborales (empleado o pensionado).
        * **Sin persistencia:** Esta acción NO crea ni modifica ninguna liquidación en la base de datos.
        * **Si ya existe una liquidación:** Los cálculos se basan en los valores actuales de la liquidación existente, sobreescribiendo con los parámetros enviados.
        * **Formato de respuesta:** Sin `file_format`, retorna `data` con los cálculos. Con `file_format=pdf`, retorna `file` con la URL temporal del PDF generado.
      parameters:
        - in: query
          name: file_format
          required: false
          description: |
            Formato del resultado. Si se envía `pdf`, la respuesta contiene la URL del PDF
            generado en lugar de los datos JSON de la liquidación.
          schema:
            type: string
            enum:
              - pdf
            example: pdf
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                termination:
                  description: Parámetros de la liquidación a previsualizar. Si se omite, se usan los valores predeterminados calculados para el contrato.
                  type: object
                  properties:
                    cause:
                      description: Causa de terminación del contrato según la legislación laboral colombiana.
                      type: string
                      example: Sin justa causa
                    date:
                      description: Fecha de terminación del contrato en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-12-15'
                    trial_period:
                      description: Indica si la terminación ocurre durante el periodo de prueba.
                      type: boolean
                      example: false
                    with_just_cause:
                      description: Indica si la terminación es con justa causa.
                      type: boolean
                      example: false
                    holidays:
                      description: Días de vacaciones pendientes a liquidar.
                      type: number
                      example: 10.5
                    termination_base:
                      description: Base salarial personalizada para el cálculo en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    holidays_base:
                      description: Base salarial para el cálculo de vacaciones en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    service_bonus_base:
                      description: Base salarial para el cálculo de prima de servicios en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    severance_base:
                      description: Base salarial para el cálculo de cesantías en pesos colombianos (COP).
                      type: integer
                      example: 3500000
                    previous_service_bonus_base:
                      description: Base salarial para prima del semestre anterior en pesos colombianos (COP).
                      type: integer
                      example: 0
                    previous_severance_base:
                      description: Base salarial para cesantías del periodo anterior en pesos colombianos (COP).
                      type: integer
                      example: 0
                    pay_rest_days:
                      description: Indica si se deben pagar los días de descanso pendientes.
                      type: boolean
                      example: false
                    pay_service_bonus:
                      description: Indica si se debe pagar la prima del semestre actual.
                      type: boolean
                      example: true
                    pay_previous_service_bonus:
                      description: Indica si se debe pagar la prima del semestre anterior.
                      type: boolean
                      example: false
                    pay_previous_severance:
                      description: Indica si se deben pagar las cesantías del periodo anterior.
                      type: boolean
                      example: false
                    pay_previous_severance_interests:
                      description: Indica si se deben pagar los intereses de cesantías del periodo anterior.
                      type: boolean
                      example: false
                    pay_decree376:
                      description: Indica si aplica el pago del Decreto 376.
                      type: boolean
                      example: false
                    loans:
                      description: Monto de préstamos pendientes a descontar en pesos colombianos (COP).
                      type: integer
                      example: 0
                    non_salary_income:
                      description: Ingresos no salariales a incluir en la base de cálculo en pesos colombianos (COP).
                      type: integer
                      example: 0
                    occasional_non_salary_income:
                      description: Ingresos no salariales ocasionales en pesos colombianos (COP).
                      type: integer
                      example: 0
                    deductions:
                      description: Deducciones adicionales en pesos colombianos (COP).
                      type: integer
                      example: 0
                    payroll_credit:
                      description: Crédito de nómina a descontar en pesos colombianos (COP).
                      type: integer
                      example: 0
                    compensation_retention:
                      description: Retención sobre la indemnización en pesos colombianos (COP).
                      type: integer
                      example: 0
                    service_bonus_retention:
                      description: Retención sobre la prima de servicios en pesos colombianos (COP).
                      type: integer
                      example: 0
                    notes:
                      description: Notas u observaciones adicionales de la liquidación.
                      type: string
                      example: Previsualización para revisión del empleado.
      responses:
        '200':
          description: Previsualización calculada / Previsualización en PDF
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Cálculos de la liquidación. Presente únicamente cuando `file_format` NO es `pdf`.
                    type:
                      - object
                      - 'null'
                    properties:
                      id:
                        description: Identificador único (ID) de la liquidación existente. Nulo si la liquidación aún no ha sido creada.
                        type:
                          - string
                          - 'null'
                        example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                      contract_id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                      payroll_id:
                        description: Identificador único (ID) de la nómina de liquidación. Nulo si aún no ha sido creada.
                        type:
                          - string
                          - 'null'
                        example: df840cb9-8c31-5293-a476-e726e2e9d759
                      cause:
                        description: Causa de terminación del contrato.
                        type: string
                        example: Sin justa causa
                      possible_trial_period:
                        description: Indica si el contrato tiene la posibilidad de estar en periodo de prueba.
                        type: boolean
                        example: false
                      trial_period:
                        description: Indica si la terminación ocurre durante el periodo de prueba.
                        type: boolean
                        example: false
                      with_just_cause:
                        description: Indica si la terminación es con justa causa.
                        type: boolean
                        example: false
                      hire_date:
                        description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2019-01-01'
                      date:
                        description: Fecha de terminación del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-15'
                      min_date:
                        description: Fecha mínima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-01'
                      max_date:
                        description: Fecha máxima permitida para la liquidación en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-12-31'
                      worked_days:
                        description: Total de días trabajados durante la vigencia del contrato.
                        type: integer
                        example: 345
                      holidays:
                        description: Días de vacaciones pendientes a liquidar.
                        type: number
                        example: 10.5
                      accumulated_holidays:
                        description: Días de vacaciones acumulados y pendientes de pago.
                        type: number
                        example: 15
                      holidays_value:
                        description: Valor a pagar por vacaciones pendientes en pesos colombianos (COP).
                        type: integer
                        example: 276039
                      termination_base:
                        description: Base salarial usada para el cálculo de la liquidación en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      holidays_base:
                        description: Base salarial usada para el cálculo de vacaciones en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      service_bonus_base:
                        description: Base salarial usada para el cálculo de prima de servicios en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      severance_base:
                        description: Base salarial usada para el cálculo de cesantías en pesos colombianos (COP).
                        type: integer
                        example: 3500000
                      previous_service_bonus_base:
                        description: Base salarial para prima del semestre anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      previous_severance_base:
                        description: Base salarial para cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_days:
                        description: Días del semestre actual para el cálculo de prima de servicios.
                        type: integer
                        example: 165
                      previous_service_bonus_days:
                        description: Días del semestre anterior para el cálculo de prima de servicios.
                        type: integer
                        example: 0
                      severance_days:
                        description: Días del periodo actual para el cálculo de cesantías.
                        type: integer
                        example: 345
                      previous_severance_days:
                        description: Días del periodo anterior para el cálculo de cesantías.
                        type: integer
                        example: 0
                      severance_interests_days:
                        description: Días del periodo actual para el cálculo de intereses de cesantías.
                        type: integer
                        example: 345
                      previous_severance_interests_days:
                        description: Días del periodo anterior para el cálculo de intereses de cesantías.
                        type: integer
                        example: 0
                      pay_rest_days:
                        description: Indica si se pagan días de descanso pendientes.
                        type: boolean
                        example: false
                      show_pay_service_bonus:
                        description: Indica si la opción de pagar prima de servicios es visible.
                        type: boolean
                        example: false
                      pay_service_bonus:
                        description: Indica si se paga la prima de servicios del semestre actual.
                        type: boolean
                        example: true
                      pay_previous_service_bonus:
                        description: Indica si se paga la prima del semestre anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance:
                        description: Indica si la opción de pagar cesantías anteriores es visible.
                        type: boolean
                        example: false
                      pay_previous_severance:
                        description: Indica si se pagan las cesantías del periodo anterior.
                        type: boolean
                        example: false
                      show_pay_previous_severance_interests:
                        description: Indica si la opción de pagar intereses de cesantías anteriores es visible.
                        type: boolean
                        example: false
                      pay_previous_severance_interests:
                        description: Indica si se pagan los intereses de cesantías del periodo anterior.
                        type: boolean
                        example: false
                      non_salary_income:
                        description: Ingresos no salariales incluidos en la base de cálculo en pesos colombianos (COP).
                        type: integer
                        example: 0
                      occasional_non_salary_income:
                        description: Ingresos no salariales ocasionales en pesos colombianos (COP).
                        type: integer
                        example: 0
                      loans:
                        description: Monto de préstamos descontados en pesos colombianos (COP).
                        type: integer
                        example: 0
                      deductions:
                        description: Deducciones adicionales aplicadas en pesos colombianos (COP).
                        type: integer
                        example: 0
                      anticipated_social_benefits_value:
                        description: Valor de prestaciones anticipadas ya pagadas en pesos colombianos (COP).
                        type: integer
                        example: 0
                      payroll_credit_value:
                        description: Crédito de nómina descontado en pesos colombianos (COP).
                        type: integer
                        example: 0
                      show_decree376:
                        description: Indica si aplica el pago del Decreto 376.
                        type: boolean
                        example: false
                      pay_decree376:
                        description: Indica si se está pagando el Decreto 376.
                        type: boolean
                        example: false
                      decree376:
                        description: Valor del Decreto 376 a pagar en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_retention:
                        description: Retención sobre la indemnización en pesos colombianos (COP).
                        type: integer
                        example: 0
                      service_bonus_retention:
                        description: Retención sobre la prima de servicios en pesos colombianos (COP).
                        type: integer
                        example: 0
                      notes:
                        description: Notas u observaciones adicionales de la liquidación.
                        type:
                          - string
                          - 'null'
                        example: Revisar cálculo de vacaciones antes de confirmar.
                      service_bonus:
                        description: Valor de prima de servicios del semestre actual en pesos colombianos (COP).
                        type: integer
                        example: 424026
                      total_paid_service_bonus:
                        description: Valor neto a pagar de prima (descontando anticipos) en pesos colombianos (COP).
                        type: integer
                        example: 424026
                      previous_service_bonus:
                        description: Valor de prima del semestre anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance:
                        description: Valor de cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 886600
                      previous_severance:
                        description: Valor de cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      severance_interests:
                        description: Valor de intereses sobre cesantías del periodo actual en pesos colombianos (COP).
                        type: integer
                        example: 101959
                      previous_severance_interests:
                        description: Valor de intereses de cesantías del periodo anterior en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation_fund:
                        description: Aporte del empleador a la caja de compensación familiar en pesos colombianos (COP).
                        type: integer
                        example: 11042
                      sena:
                        description: Aporte del empleador al SENA en pesos colombianos (COP).
                        type: integer
                        example: 0
                      icbf:
                        description: Aporte del empleador al ICBF en pesos colombianos (COP).
                        type: integer
                        example: 0
                      compensation:
                        description: Valor de indemnización por despido sin justa causa en pesos colombianos (COP).
                        type: integer
                        example: 0
                      withholding_tax:
                        description: Valor de retención en la fuente sobre los pagos en pesos colombianos (COP).
                        type: integer
                        example: 0
                      worker_payment:
                        description: Total neto a pagar al trabajador en pesos colombianos (COP).
                        type: integer
                        example: 1688624
                      company_cost:
                        description: Costo total para la empresa en aportes parafiscales en pesos colombianos (COP).
                        type: integer
                        example: 31042
                      bank_file:
                        description: Indica si la liquidación puede incluirse en un archivo de pago bancario.
                        type: boolean
                        example: false
                  file:
                    description: URL temporal del PDF de la liquidación generado. Presente únicamente cuando `file_format=pdf`.
                    type:
                      - string
                      - 'null'
                    example: https://storage.aleluya.com/termination-preview-b5ee90e9.pdf
              examples:
                Previsualización calculada:
                  value:
                    data:
                      id: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                      contract_id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                      payroll_id: df840cb9-8c31-5293-a476-e726e2e9d759
                      cause: Sin justa causa
                      possible_trial_period: false
                      trial_period: false
                      with_just_cause: false
                      hire_date: '2019-01-01'
                      date: '2024-12-15'
                      min_date: '2024-12-01'
                      max_date: '2024-12-31'
                      worked_days: 345
                      holidays: 10.5
                      accumulated_holidays: 15
                      holidays_value: 276039
                      termination_base: 3500000
                      holidays_base: 3500000
                      service_bonus_base: 3500000
                      severance_base: 3500000
                      previous_service_bonus_base: 0
                      previous_severance_base: 0
                      service_bonus_days: 165
                      previous_service_bonus_days: 0
                      severance_days: 345
                      previous_severance_days: 0
                      severance_interests_days: 345
                      previous_severance_interests_days: 0
                      pay_rest_days: false
                      show_pay_service_bonus: false
                      pay_service_bonus: true
                      pay_previous_service_bonus: false
                      show_pay_previous_severance: false
                      pay_previous_severance: false
                      show_pay_previous_severance_interests: false
                      pay_previous_severance_interests: false
                      non_salary_income: 0
                      occasional_non_salary_income: 0
                      loans: 0
                      deductions: 0
                      anticipated_social_benefits_value: 0
                      payroll_credit_value: 0
                      show_decree376: false
                      pay_decree376: false
                      decree376: 0
                      compensation_retention: 0
                      service_bonus_retention: 0
                      notes: null
                      service_bonus: 424026
                      total_paid_service_bonus: 424026
                      previous_service_bonus: 0
                      severance: 886600
                      previous_severance: 0
                      severance_interests: 101959
                      previous_severance_interests: 0
                      compensation_fund: 11042
                      sena: 0
                      icbf: 0
                      compensation: 0
                      withholding_tax: 0
                      worker_payment: 1688624
                      company_cost: 31042
                      bank_file: false
                    file: null
                Previsualización en PDF:
                  value:
                    file: https://storage.aleluya.com/termination-preview-b5ee90e9.pdf
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato no liquidable / Aprendiz no liquidable antes de julio 2025 / Ingreso no salarial excede el límite
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato no liquidable:
                  value:
                    error:
                      - code: '3101'
                        index: 0
                        message: El contrato actual no corresponde a un contrato laboral (empleado o pensionado), por lo que no se puede liquidar.
                        object: contract
                Aprendiz no liquidable antes de julio 2025:
                  value:
                    error:
                      - code: '3111'
                        index: 0
                        message: Los aprendices solo pueden ser liquidados a partir del 25 de junio de 2025.
                        object: termination
                Ingreso no salarial excede el límite:
                  value:
                    error:
                      - code: '3112'
                        index: 0
                        message: El ingreso no salarial no puede ser mayor al 40% del ingreso mensual.
                        object: termination
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: b5ee90e9-921c-55c5-8dda-728eea651b2d
  /v1/{company_id}/contracts/{contract_id}/view_termination_details:
    get:
      operationId: showViewTerminationDetails
      tags:
        - Terminación de contratos
      summary: Obtener detalle de cálculo de liquidación
      description: |
        **¿Qué hace este endpoint?**

        Retorna el desglose detallado de los cálculos de una liquidación para un contrato,
        organizados en hasta cuatro categorías: salario base, vacaciones, cesantías y prima
        de servicios. Cada categoría incluye la fórmula aplicada, el histórico de datos
        usados en el cálculo y el resultado final.

        **¿Cuándo usar este endpoint?**

        * Obtener el desglose fórmula a fórmula de cada componente de la liquidación para verificar los valores calculados.
        * Consultar el histórico de períodos que componen la base de cesantías, prima o vacaciones de un contrato.
        * Auditar los cálculos de prestaciones sociales período a período antes o después de crear la liquidación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Tipo de contrato:** No aplica para contratos de tipo contratista.
        * **Fecha de liquidación:** Si no se envía `termination_date`, se usa la fecha predeterminada calculada por el sistema (fecha de la liquidación existente o el fin del periodo actual).
        * **Secciones condicionales:** Siempre retorna `termination_base` y `termination_holidays_base`. Las secciones `termination_severance_base` y `termination_service_bonus_base` solo se incluyen cuando el contrato tiene fechas de cálculo para esos conceptos.
      parameters:
        - in: query
          name: termination_date
          required: false
          description: |
            Fecha de terminación del contrato en formato YYYY-MM-DD para la cual se calcularán
            los detalles. Si se omite, el sistema usa la fecha de liquidación existente o
            la fecha predeterminada del periodo actual.
          schema:
            type: string
            format: date
            example: '2024-12-15'
        - in: query
          name: with_just_cause
          required: false
          description: |
            Indica si la terminación es con justa causa. Afecta el cálculo de la indemnización.
            Acepta `"true"` o `"false"` como cadena de texto.
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
            example: 'false'
      responses:
        '200':
          description: Detalle de cálculo de liquidación obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Contenedor de las secciones de detalle de la liquidación.
                    type: object
                    properties:
                      termination:
                        description: |
                          Desglose de los cálculos de la liquidación organizado en categorías.
                          Siempre incluye `termination_base` y `termination_holidays_base`.
                          Incluye `termination_severance_base` y `termination_service_bonus_base`
                          solo si el contrato tiene datos históricos para esos conceptos.
                        type: object
                        properties:
                          termination_base:
                            description: Cálculo del salario base promedio usado para la liquidación.
                            type: object
                            properties:
                              information:
                                description: Información descriptiva y fórmulas aplicadas en esta categoría.
                                type: object
                                properties:
                                  title:
                                    description: Título de la sección de cálculo.
                                    type: string
                                    example: Salario base
                                  description:
                                    description: Explicación de cómo se calcula el salario base para la liquidación.
                                    type: string
                                    example: Se calcula como el promedio de ingresos salariales del año en el que se terminó el contrato.
                                  formulas:
                                    description: Lista de identificadores de fórmulas aplicadas en el cálculo.
                                    type: array
                                    items:
                                      type: string
                                      example: termination_base
                                    example:
                                      - termination_base
                                  link:
                                    description: URL de ayuda con el detalle de la fórmula de cálculo.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-el-salario-base-en-una-liquidaci%C3%B3n-laboral
                              data:
                                description: |
                                  Histórico de períodos utilizados para calcular el promedio del salario base.
                                  El último elemento del arreglo es el registro de totales (symbol `=`).
                                type: array
                                items:
                                  description: Fila del histórico de cálculo para un período.
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación. `+` para filas sumadas, `=` para el total acumulado.
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha de corte del período. Ausente en la fila de totales.
                                      type: string
                                      format: date
                                      example: '2024-10-31'
                                    worked_days:
                                      description: Días trabajados en este período.
                                      type: integer
                                      example: 15
                                    average_salary:
                                      description: Valor del salario mensual para este período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                    salary_income:
                                      description: Ingresos salariales variables adicionales del período en pesos colombianos (COP).
                                      type: integer
                                      example: 0
                                    total:
                                      description: Valor acumulado del período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                example:
                                  - symbol: +
                                    date: '2024-10-31'
                                    worked_days: 15
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                                  - symbol: +
                                    date: '2024-12-15'
                                    worked_days: 15
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                                  - symbol: '='
                                    worked_days: 30
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                              totals:
                                description: Resumen del cálculo con fórmulas aplicadas y valor total resultante.
                                type: object
                                properties:
                                  formulas:
                                    description: Fórmulas de cálculo con sus componentes (numerador, denominador y resultado).
                                    type: array
                                    items:
                                      description: Fórmula de cálculo de un componente del salario base.
                                      type: object
                                      properties:
                                        label:
                                          description: Nombre del concepto calculado.
                                          type: string
                                          example: Salario base
                                        numerator:
                                          description: Numerador de la fórmula de cálculo con valores y unidades.
                                          type: string
                                          example: $ 3.500.000 * 30 días
                                        denominator:
                                          description: Denominador de la fórmula de cálculo.
                                          type: string
                                          example: 30 días
                                        complement:
                                          description: Complemento adicional de la fórmula. Nulo si no aplica.
                                          type:
                                            - string
                                            - 'null'
                                          example: + $ 200.000
                                        value:
                                          description: Valor calculado del componente en pesos colombianos (COP).
                                          type: integer
                                          example: 3500000
                                    example:
                                      - label: Salario base
                                        numerator: $ 3.500.000 * 30 días
                                        denominator: 30 días
                                        complement: null
                                        value: 3500000
                                  total:
                                    description: Total final de la categoría con su etiqueta y valor.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta del total de la categoría.
                                        type: string
                                        example: Salario base
                                      value:
                                        description: Valor total calculado para la categoría en pesos colombianos (COP).
                                        type: integer
                                        example: 3500000
                          termination_holidays_base:
                            description: Cálculo de las vacaciones pendientes incluidas en la liquidación.
                            type: object
                            properties:
                              information:
                                description: Información descriptiva y fórmulas aplicadas en el cálculo de vacaciones.
                                type: object
                                properties:
                                  title:
                                    description: Título de la sección de vacaciones.
                                    type: string
                                    example: Vacaciones
                                  description:
                                    description: Explicación de cómo se calculan las vacaciones en la liquidación.
                                    type: string
                                    example: Las vacaciones se calculan sobre los días pendientes de disfrute.
                                  formulas:
                                    description: Lista de identificadores de fórmulas aplicadas.
                                    type: array
                                    items:
                                      type: string
                                      example: termination_base
                                    example:
                                      - termination_base
                                      - termination_holidays_base
                                  link:
                                    description: URL de ayuda con el detalle del cálculo de vacaciones.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/vacaciones-en-liquidacion
                              data:
                                description: Histórico de períodos para el cálculo de vacaciones.
                                type: array
                                items:
                                  description: Fila del histórico de cálculo para un período.
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación. `+` para filas sumadas, `=` para el total.
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha de corte del período.
                                      type: string
                                      format: date
                                      example: '2024-10-31'
                                    worked_days:
                                      description: Días trabajados en este período.
                                      type: integer
                                      example: 15
                                    average_salary:
                                      description: Salario mensual del período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                    salary_income:
                                      description: Ingresos salariales variables del período en pesos colombianos (COP).
                                      type: integer
                                      example: 0
                                    total:
                                      description: Total acumulado del período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                example:
                                  - symbol: +
                                    date: '2024-10-31'
                                    worked_days: 15
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                                  - symbol: '='
                                    worked_days: 15
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                              totals:
                                description: Resumen del cálculo de vacaciones con fórmulas y total.
                                type: object
                                properties:
                                  formulas:
                                    description: Fórmulas de cálculo del valor de vacaciones.
                                    type: array
                                    items:
                                      description: Fórmula de cálculo con sus componentes.
                                      type: object
                                      properties:
                                        label:
                                          description: Nombre del concepto calculado.
                                          type: string
                                          example: Vacaciones pendientes
                                        numerator:
                                          description: Numerador de la fórmula.
                                          type: string
                                          example: $ 3.500.000 * 10.5 días
                                        denominator:
                                          description: Denominador de la fórmula.
                                          type: string
                                          example: 30 días
                                        complement:
                                          description: Complemento adicional. Nulo si no aplica.
                                          type:
                                            - string
                                            - 'null'
                                          example: null
                                        value:
                                          description: Valor de las vacaciones en pesos colombianos (COP).
                                          type: integer
                                          example: 433334
                                    example:
                                      - label: Salario base
                                        numerator: $ 3.500.000 * 30 días
                                        denominator: 30 días
                                        complement: null
                                        value: 3500000
                                      - label: Vacaciones pendientes
                                        numerator: $ 3.500.000 * 10.5 días
                                        denominator: 30 días
                                        complement: null
                                        value: 433334
                                  total:
                                    description: Total de vacaciones a pagar.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta del total de vacaciones.
                                        type: string
                                        example: Vacaciones
                                      value:
                                        description: Valor total de vacaciones en pesos colombianos (COP).
                                        type: integer
                                        example: 433334
                          termination_severance_base:
                            description: |
                              Cálculo de las cesantías incluidas en la liquidación.
                              Esta sección solo se incluye cuando el contrato tiene fechas de cesantías calculables.
                            type: object
                            properties:
                              information:
                                description: Información descriptiva y fórmulas del cálculo de cesantías.
                                type: object
                                properties:
                                  title:
                                    description: Título de la sección de cesantías.
                                    type: string
                                    example: Cesantías
                                  description:
                                    description: Explicación del cálculo de cesantías en la liquidación.
                                    type: string
                                    example: Las cesantías se calculan sobre el último salario mensual o el promedio.
                                  formulas:
                                    description: Lista de identificadores de fórmulas aplicadas.
                                    type: array
                                    items:
                                      type: string
                                      example: termination_base
                                    example:
                                      - termination_base
                                      - termination_severance_base
                                  link:
                                    description: URL de ayuda con el detalle del cálculo de cesantías.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/cesantias-en-liquidacion
                              data:
                                description: Histórico de períodos para el cálculo de cesantías.
                                type: array
                                items:
                                  description: Fila del histórico de cálculo para un período de cesantías.
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación. `+` para filas, `=` para el total.
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha de corte del período.
                                      type: string
                                      format: date
                                      example: '2024-10-31'
                                    worked_days:
                                      description: Días trabajados en este período.
                                      type: integer
                                      example: 30
                                    average_salary:
                                      description: Salario mensual del período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                    salary_income:
                                      description: Ingresos salariales variables del período en pesos colombianos (COP).
                                      type: integer
                                      example: 0
                                    total:
                                      description: Total acumulado del período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                example:
                                  - symbol: +
                                    date: '2024-10-31'
                                    worked_days: 30
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                                  - symbol: '='
                                    worked_days: 345
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                              totals:
                                description: Resumen del cálculo de cesantías con fórmulas y total.
                                type: object
                                properties:
                                  formulas:
                                    description: Fórmulas de cálculo del valor de cesantías.
                                    type: array
                                    items:
                                      description: Fórmula de cálculo con sus componentes.
                                      type: object
                                      properties:
                                        label:
                                          description: Nombre del concepto calculado.
                                          type: string
                                          example: Cesantías
                                        numerator:
                                          description: Numerador de la fórmula.
                                          type: string
                                          example: $ 3.500.000 * 345 días
                                        denominator:
                                          description: Denominador de la fórmula.
                                          type: string
                                          example: 360 días
                                        complement:
                                          description: Complemento adicional. Nulo si no aplica.
                                          type:
                                            - string
                                            - 'null'
                                          example: null
                                        value:
                                          description: Valor de las cesantías en pesos colombianos (COP).
                                          type: integer
                                          example: 1338822
                                  total:
                                    description: Total de cesantías a pagar.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta del total de cesantías.
                                        type: string
                                        example: Cesantías
                                      value:
                                        description: Valor total de cesantías en pesos colombianos (COP).
                                        type: integer
                                        example: 1338822
                          termination_service_bonus_base:
                            description: |
                              Cálculo de la prima de servicios incluida en la liquidación.
                              Esta sección solo se incluye cuando el contrato tiene fechas de prima calculables.
                            type: object
                            properties:
                              information:
                                description: Información descriptiva y fórmulas del cálculo de prima de servicios.
                                type: object
                                properties:
                                  title:
                                    description: Título de la sección de prima de servicios.
                                    type: string
                                    example: Prima de servicios
                                  description:
                                    description: Explicación del cálculo de prima de servicios en la liquidación.
                                    type: string
                                    example: La prima se calcula sobre el promedio del semestre en que ocurre la liquidación.
                                  formulas:
                                    description: Lista de identificadores de fórmulas aplicadas.
                                    type: array
                                    items:
                                      type: string
                                      example: termination_base
                                    example:
                                      - termination_base
                                      - termination_service_bonus_base
                                  link:
                                    description: URL de ayuda con el detalle del cálculo de prima.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/prima-de-servicios-en-liquidacion
                              data:
                                description: Histórico de períodos para el cálculo de prima de servicios.
                                type: array
                                items:
                                  description: Fila del histórico de cálculo para un período de prima.
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación. `+` para filas, `=` para el total.
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha de corte del período.
                                      type: string
                                      format: date
                                      example: '2024-11-30'
                                    worked_days:
                                      description: Días trabajados en este período.
                                      type: integer
                                      example: 30
                                    average_salary:
                                      description: Salario mensual del período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                    salary_income:
                                      description: Ingresos salariales variables del período en pesos colombianos (COP).
                                      type: integer
                                      example: 0
                                    total:
                                      description: Total acumulado del período en pesos colombianos (COP).
                                      type: integer
                                      example: 3500000
                                example:
                                  - symbol: +
                                    date: '2024-11-30'
                                    worked_days: 30
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                                  - symbol: '='
                                    worked_days: 165
                                    average_salary: 3500000
                                    salary_income: 0
                                    total: 3500000
                              totals:
                                description: Resumen del cálculo de prima de servicios con fórmulas y total.
                                type: object
                                properties:
                                  formulas:
                                    description: Fórmulas de cálculo del valor de prima de servicios.
                                    type: array
                                    items:
                                      description: Fórmula de cálculo con sus componentes.
                                      type: object
                                      properties:
                                        label:
                                          description: Nombre del concepto calculado.
                                          type: string
                                          example: Prima de servicios
                                        numerator:
                                          description: Numerador de la fórmula.
                                          type: string
                                          example: $ 3.500.000 * 165 días
                                        denominator:
                                          description: Denominador de la fórmula.
                                          type: string
                                          example: 360 días
                                        complement:
                                          description: Complemento adicional. Nulo si no aplica.
                                          type:
                                            - string
                                            - 'null'
                                          example: null
                                        value:
                                          description: Valor de la prima en pesos colombianos (COP).
                                          type: integer
                                          example: 640306
                                  total:
                                    description: Total de prima de servicios a pagar.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta del total de prima de servicios.
                                        type: string
                                        example: Prima de servicios
                                      value:
                                        description: Valor total de prima en pesos colombianos (COP).
                                        type: integer
                                        example: 640306
              example:
                data:
                  termination:
                    termination_base:
                      information:
                        title: Salario base
                        description: Se calcula como el promedio de ingresos salariales del año en el que se terminó el contrato.
                        formulas:
                          - termination_base
                        link: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-el-salario-base-en-una-liquidaci%C3%B3n-laboral
                      data:
                        - symbol: +
                          date: '2024-10-31'
                          worked_days: 15
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                        - symbol: '='
                          worked_days: 15
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                      totals:
                        formulas:
                          - label: Salario base
                            numerator: $ 3.500.000 * 30 días
                            denominator: 30 días
                            complement: null
                            value: 3500000
                        total:
                          label: Salario base
                          value: 3500000
                    termination_holidays_base:
                      information:
                        title: Vacaciones
                        description: Las vacaciones se calculan sobre los días pendientes de disfrute.
                        formulas:
                          - termination_base
                          - termination_holidays_base
                        link: https://ayuda.aleluya.com/portal/es/kb/articles/vacaciones-en-liquidacion
                      data:
                        - symbol: +
                          date: '2024-10-31'
                          worked_days: 15
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                        - symbol: '='
                          worked_days: 15
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                      totals:
                        formulas:
                          - label: Salario base
                            numerator: $ 3.500.000 * 30 días
                            denominator: 30 días
                            complement: null
                            value: 3500000
                          - label: Vacaciones pendientes
                            numerator: $ 3.500.000 * 10.5 días
                            denominator: 30 días
                            complement: null
                            value: 433334
                        total:
                          label: Vacaciones
                          value: 433334
                    termination_severance_base:
                      information:
                        title: Cesantías
                        description: Las cesantías se calculan sobre el último salario mensual o el promedio variable.
                        formulas:
                          - termination_base
                          - termination_severance_base
                        link: https://ayuda.aleluya.com/portal/es/kb/articles/cesantias-en-liquidacion
                      data:
                        - symbol: +
                          date: '2024-12-15'
                          worked_days: 345
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                        - symbol: '='
                          worked_days: 345
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                      totals:
                        formulas:
                          - label: Salario base
                            numerator: $ 3.500.000 * 30 días
                            denominator: 30 días
                            complement: null
                            value: 3500000
                          - label: Cesantías
                            numerator: $ 3.500.000 * 345 días
                            denominator: 360 días
                            complement: null
                            value: 1338822
                        total:
                          label: Cesantías
                          value: 1338822
                    termination_service_bonus_base:
                      information:
                        title: Prima de servicios
                        description: La prima se calcula sobre el promedio del semestre en que ocurre la liquidación.
                        formulas:
                          - termination_base
                          - termination_service_bonus_base
                        link: https://ayuda.aleluya.com/portal/es/kb/articles/prima-de-servicios-en-liquidacion
                      data:
                        - symbol: +
                          date: '2024-11-30'
                          worked_days: 165
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                        - symbol: '='
                          worked_days: 165
                          average_salary: 3500000
                          salary_income: 0
                          total: 3500000
                      totals:
                        formulas:
                          - label: Salario base
                            numerator: $ 3.500.000 * 30 días
                            denominator: 30 días
                            complement: null
                            value: 3500000
                          - label: Prima de servicios
                            numerator: $ 3.500.000 * 165 días
                            denominator: 360 días
                            complement: null
                            value: 640306
                        total:
                          label: Prima de servicios
                          value: 640306
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Formato de fecha inválido / Tipo de contrato no soportado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Formato de fecha inválido:
                  value:
                    error:
                      - code: '0412'
                        index: 0
                        message: El formato de la fecha es inválido.
                        object: date
                Tipo de contrato no soportado:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Contrato es inválido.
                        object: contract
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 0019e210-f36f-4655-aa91-35a3bc6fbba8
  /v1/{company_id}/contracts/{contract_id}/wage:
    get:
      operationId: showCurrentWage
      tags:
        - Salarios
      summary: Obtener salario vigente del contrato
      description: |
        **¿Qué hace este endpoint?**

        Retorna el salario vigente de un contrato laboral. Opcionalmente, si se envía el parámetro `id`,
        retorna un salario específico del contrato independientemente de si es el vigente.

        **¿Cuándo usar este endpoint?**

        * Consultar el salario base actual de una persona antes de registrar un cambio salarial.
        * Verificar si el salario puede ser editado (`editable`) o eliminado (`deleteable`) antes de modificarlo.
        * Obtener los detalles de un salario histórico pasando el `id` del registro.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Sin salario vigente:** Retorna `404` si el contrato no tiene un salario actual registrado.
      parameters:
        - in: query
          required: false
          name: id
          description: Identificador único (ID) de un salario específico en la base de datos. Si se omite, retorna el salario vigente del contrato.
          schema:
            type: string
            example: c9803794-bd6c-5b9c-995d-c7807cfccf44
      responses:
        '200':
          description: Salario del contrato encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información del salario solicitado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al salario en la base de datos.
                        type: string
                        example: c9803794-bd6c-5b9c-995d-c7807cfccf44
                      base_salary:
                        description: Monto del salario base en pesos colombianos (COP).
                        type: integer
                        example: 2500000
                      category:
                        $ref: '#/components/schemas/SalaryCategory'
                      initial_day:
                        description: Fecha de inicio de vigencia del salario en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin de vigencia del salario en formato YYYY-MM-DD. Null si es el salario vigente.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      editable:
                        description: Indica si el salario puede ser editado.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si el salario puede ser eliminado.
                        type: boolean
                        example: false
                      remote_work:
                        description: Indica si la persona trabaja de forma remota (teletrabajo).
                        type: boolean
                        example: false
                      transport_subsidy:
                        description: Indica si la persona tiene derecho al auxilio de transporte.
                        type: boolean
                        example: true
              example:
                data:
                  id: c9803794-bd6c-5b9c-995d-c7807cfccf44
                  base_salary: 2500000
                  category: monthly
                  initial_day: '2024-01-01'
                  end_day: null
                  editable: true
                  deleteable: false
                  remote_work: false
                  transport_subsidy: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Empresa, contrato o salario no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Empresa no encontrada:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: La empresa no existe.
                        object: company
                Contrato no encontrado:
                  value:
                    error:
                      - code: '0301'
                        index: 0
                        message: El contrato no existe.
                        object: contract
                Salario no encontrado:
                  value:
                    error:
                      - code: '0401'
                        index: 0
                        message: El salario no existe.
                        object: wage
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
  /v1/{company_id}/contracts/{contract_id}/wages:
    get:
      operationId: indexWages
      tags:
        - Salarios
      summary: Listar salarios del contrato
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial completo de salarios de un contrato laboral, ordenado del más reciente al más antiguo.

        **¿Cuándo usar este endpoint?**

        * Consultar todos los cambios salariales que ha tenido una persona durante su contrato.
        * Determinar qué salarios pueden editarse o eliminarse mediante los campos `editable` y `deleteable`.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Historial de salarios del contrato
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo con el historial de salarios del contrato, ordenado del más reciente al más antiguo.
                    type: array
                    items:
                      description: Registro de un salario en el historial del contrato.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al salario en la base de datos.
                          type: string
                          example: c9803794-bd6c-5b9c-995d-c7807cfccf44
                        base_salary:
                          description: Monto del salario base en pesos colombianos (COP).
                          type: integer
                          example: 2500000
                        category:
                          $ref: '#/components/schemas/SalaryCategory'
                        initial_day:
                          description: Fecha de inicio de vigencia del salario en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-01-01'
                        end_day:
                          description: Fecha de fin de vigencia del salario en formato YYYY-MM-DD. Null si es el salario vigente.
                          type:
                            - string
                            - 'null'
                          example: '2024-12-31'
                        editable:
                          description: Indica si el salario puede ser editado.
                          type: boolean
                          example: true
                        deleteable:
                          description: Indica si el salario puede ser eliminado.
                          type: boolean
                          example: true
                        remote_work:
                          description: Indica si la persona trabaja de forma remota (teletrabajo).
                          type: boolean
                          example: false
                        transport_subsidy:
                          description: Indica si la persona tiene derecho al auxilio de transporte.
                          type: boolean
                          example: true
              example:
                data:
                  - id: c9803794-bd6c-5b9c-995d-c7807cfccf44
                    base_salary: 2500000
                    category: monthly
                    initial_day: '2024-06-01'
                    end_day: null
                    editable: true
                    deleteable: false
                    remote_work: false
                    transport_subsidy: true
                  - id: 0723e08a-d98e-5909-867b-94fe6cb871dd
                    base_salary: 1300000
                    category: monthly
                    initial_day: '2024-01-01'
                    end_day: '2024-05-31'
                    editable: false
                    deleteable: true
                    remote_work: false
                    transport_subsidy: true
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createWage
      tags:
        - Salarios
      summary: Crear salario
      description: |
        **¿Qué hace este endpoint?**

        Registra un nuevo salario en el historial de un contrato laboral. El salario anterior
        recibe una fecha de fin automáticamente.

        **¿Cuándo usar este endpoint?**

        * Registrar un aumento o cambio de salario sin liquidar el contrato.
        * Cambiar la modalidad salarial de la persona (p. ej. de mensual a integral).

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Contrato liquidado:** No es posible crear un salario en un contrato ya liquidado.
        * **Fecha inicial:** Debe ser mayor a la fecha inicial del salario vigente.
        * **Salario duplicado:** El nuevo salario debe diferir del actual en al menos uno de los campos `base_salary`, `category`, `remote_work` o `transport_subsidy`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                wage:
                  description: Objeto con los datos del nuevo salario.
                  type: object
                  properties:
                    base_salary:
                      description: Monto del salario base en pesos colombianos (COP).
                      type: integer
                      example: 2500000
                    category:
                      $ref: '#/components/schemas/SalaryCategory'
                    initial_day:
                      description: Fecha de inicio de vigencia del salario en formato YYYY-MM-DD. Debe ser mayor a la del salario vigente.
                      type: string
                      format: date
                      example: '2024-06-01'
                    end_day:
                      description: Fecha de fin de vigencia del salario en formato YYYY-MM-DD. Null si es el salario vigente.
                      type:
                        - string
                        - 'null'
                      example: '2024-12-31'
                    remote_work:
                      description: Indica si la persona trabajará de forma remota (teletrabajo).
                      type: boolean
                      example: false
                    transport_subsidy:
                      description: Indica si la persona tiene derecho al auxilio de transporte.
                      type: boolean
                      example: true
                  required:
                    - base_salary
                    - category
                    - initial_day
              required:
                - wage
      responses:
        '201':
          description: Salario creado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información del salario recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al salario en la base de datos.
                        type: string
                        example: 05fb2683-e185-4e6d-a8fd-812ed4a09d48
                      base_salary:
                        description: Monto del salario base en pesos colombianos (COP).
                        type: integer
                        example: 2500000
                      category:
                        $ref: '#/components/schemas/SalaryCategory'
                      initial_day:
                        description: Fecha de inicio de vigencia del salario en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-06-01'
                      end_day:
                        description: Fecha de fin de vigencia del salario en formato YYYY-MM-DD. Null si es el salario vigente.
                        type:
                          - string
                          - 'null'
                        example: null
                      editable:
                        description: Indica si el salario puede ser editado.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si el salario puede ser eliminado.
                        type: boolean
                        example: false
                      remote_work:
                        description: Indica si la persona trabaja de forma remota (teletrabajo).
                        type: boolean
                        example: false
                      transport_subsidy:
                        description: Indica si la persona tiene derecho al auxilio de transporte.
                        type: boolean
                        example: true
              example:
                data:
                  id: 05fb2683-e185-4e6d-a8fd-812ed4a09d48
                  base_salary: 2500000
                  category: monthly
                  initial_day: '2024-06-01'
                  end_day: null
                  editable: true
                  deleteable: false
                  remote_work: false
                  transport_subsidy: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato liquidado / Salario duplicado / Fecha inicial inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato liquidado:
                  value:
                    error:
                      - code: '3105'
                        index: 0
                        message: El contrato ya ha sido liquidado, por lo cual no puedes editarlo.
                        object: contract
                Salario duplicado:
                  value:
                    error:
                      - code: '0808'
                        index: 0
                        message: El nuevo salario debe ser diferente al actual.
                        object: wage
                Fecha inicial inválida:
                  value:
                    error:
                      - code: '0801'
                        index: 0
                        message: La fecha inicial del salario debe ser mayor a la del salario actual.
                        object: initial_day
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
  /v1/{company_id}/contracts/{contract_id}/yearly_retention_file:
    get:
      operationId: showContractYearlyRetentionFile
      tags:
        - Archivos de retefuente
      summary: Generar reporte anual de retención del contrato
      description: |
        **¿Qué hace este endpoint?**

        Genera un archivo con el resumen de retención en la fuente aplicada mes a mes a las nóminas
        de un contrato durante un año específico.

        **¿Cuándo usar este endpoint?**

        * Obtener el reporte anual de retención en la fuente de una persona para soporte de declaración de renta.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Siempre asíncrono:** El archivo se publica en Firebase en la ruta `users/{user_id}/contracts/{contract_id}/contract_retention_yearly_file`.
      parameters:
        - in: query
          required: true
          name: year
          description: Año fiscal para el cual se genera el reporte de retención.
          schema:
            type: integer
            example: 2024
      responses:
        '200':
          description: Generación encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento. El archivo se notifica vía Firebase cuando esté listo.
                        type: string
                        example: Procesando
                required:
                  - data
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 120a6990-830e-4304-9779-f0c7aaad9415
      - in: path
        required: true
        name: contract_id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 006e189a-e75f-4b7e-8638-3cdf60492d6f
  /v1/{company_id}/contracts/{id}:
    get:
      operationId: showContract
      tags:
        - Contratos
      summary: Obtener contrato
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información detallada de un contrato, incluyendo salario vigente, detalle del contrato,
        historial de cargo, proveedores de seguridad social y centro de trabajo.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado actual de un contrato antes de realizar actualizaciones.
        * Verificar las afiliaciones de seguridad social (salud, pensión, cesantías) de una persona.
        * Obtener el cargo, sede y área asignados actualmente a una persona en un contrato específico.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Contrato encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información completa del contrato.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: 8ea29a65-19f5-40d2-854a-869415d4494a
                      category:
                        description: Categoría del contrato laboral.
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                        type: string
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del contrato en formato YYYY-MM-DD. Null si el contrato es indefinido.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      period_end_day:
                        description: Fecha de fin del periodo de nómina actual del contrato en formato YYYY-MM-DD.
                        type: string
                        example: '2024-01-31'
                      apply_art102_cst:
                        description: Indica si el contrato aplica el Artículo 102 del CST (pago de vacaciones sobre 360 días).
                        type: boolean
                        example: false
                      term:
                        description: Tipo de duración del contrato.
                        $ref: '#/components/schemas/ContractTerm'
                      terminated:
                        description: Indica si el contrato ha sido liquidado.
                        type: boolean
                        example: false
                      termination:
                        description: Información de la liquidación del contrato, si existe.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la liquidación en la base de datos. Null si el contrato no ha sido liquidado.
                            type:
                              - string
                              - 'null'
                            example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                          date:
                            description: Fecha de la liquidación en formato YYYY-MM-DD. Null si el contrato no ha sido liquidado.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          deleteable:
                            description: Indica si la liquidación puede ser eliminada. Null si el contrato no ha sido liquidado.
                            type:
                              - boolean
                              - 'null'
                            example: true
                      wage_id:
                        description: Identificador único (ID) asignado al salario vigente del contrato en la base de datos.
                        type: string
                        example: 7887b3b9-9869-4416-8da7-5db9e99ed8e2
                      wage_category:
                        description: Modalidad del salario vigente del contrato.
                        $ref: '#/components/schemas/SalaryCategory'
                      base_salary:
                        description: Valor del salario básico mensual del contrato en pesos colombianos.
                        type: integer
                        example: 1300000
                      remote_work:
                        description: Indica si la persona trabaja en modalidad de teletrabajo o trabajo en casa.
                        type: boolean
                        example: false
                      transport_subsidy:
                        description: Indica si el contrato incluye auxilio de transporte.
                        type: boolean
                        example: true
                      contract_detail:
                        description: Detalle vigente del contrato con información de cotizante y centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                            type: string
                            example: 99763829-ec48-4d60-96c8-cde35e7d86b0
                          contributor_subtype:
                            description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social.
                            $ref: '#/components/schemas/ContributorSubtype'
                          initial_day:
                            description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                            type: string
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin de vigencia del detalle del contrato. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                            type: string
                            example: 8ea29a65-19f5-40d2-854a-869415d4494a
                          deleteable:
                            description: Indica si el detalle del contrato puede ser eliminado.
                            type: boolean
                            example: false
                      contract_position_history:
                        description: Historial de cargo vigente del contrato con área, sede y cargo asignados.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          initial_day:
                            description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                            type: string
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del historial de cargo. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este historial en la base de datos.
                            type: string
                            example: 8ea29a65-19f5-40d2-854a-869415d4494a
                          area:
                            description: Área asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al área en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                              name:
                                description: Nombre del área.
                                type:
                                  - string
                                  - 'null'
                                example: Administración
                          location:
                            description: Sede asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sede en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                              name:
                                description: Nombre de la sede.
                                type:
                                  - string
                                  - 'null'
                                example: Oficina principal
                          position:
                            description: Cargo asignado al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al cargo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                              name:
                                description: Nombre del cargo.
                                type:
                                  - string
                                  - 'null'
                                example: Coordinador de proyectos
                          deleteable:
                            description: Indica si el historial de cargo puede ser eliminado.
                            type: boolean
                            example: false
                      work_center:
                        description: |
                          Centro de trabajo asignado al contrato.

                          - Si el contrato tiene centro de trabajo, retorna el objeto con su información.
                          - Si no tiene centro de trabajo asignado, retorna un objeto vacío `{}`.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                            type: string
                            example: 97a1f505-fbd5-554c-a620-ca0017f9bada
                          name:
                            description: Nombre del centro de trabajo junto con el tipo de riesgo.
                            type: string
                            example: Oficina central - Riesgo 1 - Mínimo
                          risk_type:
                            description: Nombre del tipo de riesgo del centro de trabajo.
                            type:
                              - string
                              - 'null'
                            example: Riesgo 1 - Mínimo
                      risk_type:
                        description: |
                          Código del tipo de riesgo ARL del centro de trabajo.

                          Valores posibles:
                          * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
                          * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
                          * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
                          * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
                          * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)

                          `null` si no tiene centro de trabajo asignado.
                        type:
                          - string
                          - 'null'
                        enum:
                          - risk_1
                          - risk_2
                          - risk_3
                          - risk_4
                          - risk_5
                        example: risk_1
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo.
                        type: boolean
                        example: false
                      health_provider:
                        description: Entidad prestadora de salud (EPS) afiliada al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la EPS en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name:
                            description: Nombre de la EPS.
                            type:
                              - string
                              - 'null'
                            example: Nueva EPS
                      pension_provider:
                        description: Fondo de pensiones afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name:
                            description: Nombre del fondo de pensiones.
                            type:
                              - string
                              - 'null'
                            example: Protección
                      severance_provider:
                        description: Fondo de cesantías afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 16881701-ff67-5895-913b-dfdf4ab03797
                          name:
                            description: Nombre del fondo de cesantías.
                            type:
                              - string
                              - 'null'
                            example: Fondo Nacional del Ahorro
              example:
                data:
                  id: 8ea29a65-19f5-40d2-854a-869415d4494a
                  category: employee
                  initial_day: '2024-01-01'
                  end_day: null
                  period_end_day: '2024-01-31'
                  apply_art102_cst: false
                  term: indefinite
                  terminated: false
                  termination:
                    id: null
                    date: null
                    deleteable: null
                  wage_id: 7887b3b9-9869-4416-8da7-5db9e99ed8e2
                  wage_category: monthly
                  base_salary: 1300000
                  remote_work: false
                  transport_subsidy: true
                  contract_detail:
                    id: 99763829-ec48-4d60-96c8-cde35e7d86b0
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: 8ea29a65-19f5-40d2-854a-869415d4494a
                    deleteable: false
                  contract_position_history:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: 8ea29a65-19f5-40d2-854a-869415d4494a
                    area:
                      id: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                      name: Administración
                    location:
                      id: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                      name: Oficina principal
                    position:
                      id: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                      name: Coordinador de proyectos
                    deleteable: false
                  work_center:
                    id: 97a1f505-fbd5-554c-a620-ca0017f9bada
                    name: Oficina central - Riesgo 1 - Mínimo
                    risk_type: Riesgo 1 - Mínimo
                  risk_type: risk_1
                  high_risk_pension: false
                  health_provider:
                    id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    name: Nueva EPS
                  pension_provider:
                    id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    name: Protección
                  severance_provider:
                    id: 16881701-ff67-5895-913b-dfdf4ab03797
                    name: Fondo Nacional del Ahorro
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Empresa no encontrada / Contrato no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Empresa no encontrada:
                  value:
                    error:
                      - code: '0001'
                        index: 0
                        message: Empresa no existe
                        object: company
                Contrato no encontrado:
                  value:
                    error:
                      - code: '0001'
                        index: 0
                        message: Contrato no existe
                        object: contract
    patch:
      operationId: updateContract
      tags:
        - Contratos
      summary: Actualizar contrato
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los datos de un contrato existente: fechas, categoría, duración, afiliaciones de seguridad
        social, salario, auxilio de transporte, teletrabajo, subtipo de cotizante, centro de trabajo y cargo.

        **¿Cuándo usar este endpoint?**

        * Modificar las fechas de inicio o fin de un contrato fijo para extenderlo o ajustarlo.
        * Cambiar la EPS, fondo de pensiones o fondo de cesantías de una persona.
        * Actualizar el cargo, área o sede asignados a una persona en su contrato actual.
        * Ajustar el salario base o la modalidad salarial del contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Contrato liquidado:** No es posible editar un contrato que ya haya sido liquidado. El campo `terminated` del GET indica si el contrato está en este estado.
        * **Pago activo:** Requiere que la empresa tenga una suscripción activa o en periodo de prueba.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contract:
                  description: Objeto con los campos del contrato a actualizar. Solo se deben enviar los campos que se desean modificar.
                  type: object
                  properties:
                    category:
                      description: Categoría del contrato laboral.
                      $ref: '#/components/schemas/ContractCategory'
                    initial_day:
                      description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                      type: string
                      example: '2024-01-01'
                    end_day:
                      description: Fecha de fin del contrato en formato YYYY-MM-DD. Enviar null para contratos indefinidos.
                      type:
                        - string
                        - 'null'
                      example: '2024-12-31'
                    term:
                      description: Tipo de duración del contrato.
                      $ref: '#/components/schemas/ContractTerm'
                    apply_art102_cst:
                      description: Indica si el contrato aplica el Artículo 102 del CST (pago de vacaciones sobre 360 días).
                      type: boolean
                      example: false
                    health_provider_id:
                      description: Identificador único (ID) asignado a la EPS en la base de datos.
                      type: string
                      example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    pension_provider_id:
                      description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                      type: string
                      example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    severance_provider_id:
                      description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                      type: string
                      example: 16881701-ff67-5895-913b-dfdf4ab03797
                    risk_type:
                      description: Código del tipo de riesgo ARL del centro de trabajo del contrato.
                      $ref: '#/components/schemas/RiskType'
                    base_salary:
                      description: Valor del salario básico mensual del contrato en pesos colombianos.
                      type: integer
                      example: 1300000
                    wage_category:
                      description: Modalidad del salario vigente del contrato.
                      $ref: '#/components/schemas/SalaryCategory'
                    transport_subsidy:
                      description: Indica si el contrato incluye auxilio de transporte.
                      type: boolean
                      example: true
                    remote_work:
                      description: Indica si la persona trabaja en modalidad de teletrabajo o trabajo en casa.
                      type: boolean
                      example: false
                    contributor_subtype:
                      description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social.
                      $ref: '#/components/schemas/ContributorSubtype'
                    high_risk_pension:
                      description: Indica si el contrato aplica pensión de alto riesgo. Requiere Colpensiones como fondo de pensiones.
                      type: boolean
                      example: false
                    work_center_id:
                      description: Identificador único (ID) asignado al centro de trabajo en la base de datos. Alternativa a `risk_type` para asignar el centro de trabajo.
                      type:
                        - string
                        - 'null'
                      example: 97a1f505-fbd5-554c-a620-ca0017f9bada
                    area_id:
                      description: Identificador único (ID) asignado al área en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                    location_id:
                      description: Identificador único (ID) asignado a la sede en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                    position_id:
                      description: Identificador único (ID) asignado al cargo en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: d4e5f6a7-b8c9-0123-4567-89abcdef0123
              required:
                - contract
      responses:
        '202':
          description: Contrato actualizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información actualizada del contrato.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: 8ea29a65-19f5-40d2-854a-869415d4494a
                      category:
                        description: Categoría del contrato laboral.
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                        type: string
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del contrato en formato YYYY-MM-DD. Null si el contrato es indefinido.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      period_end_day:
                        description: Fecha de fin del periodo de nómina actual del contrato en formato YYYY-MM-DD.
                        type: string
                        example: '2024-01-31'
                      apply_art102_cst:
                        description: Indica si el contrato aplica el Artículo 102 del CST (pago de vacaciones sobre 360 días).
                        type: boolean
                        example: false
                      term:
                        description: Tipo de duración del contrato.
                        $ref: '#/components/schemas/ContractTerm'
                      terminated:
                        description: Indica si el contrato ha sido liquidado.
                        type: boolean
                        example: false
                      termination:
                        description: Información de la liquidación del contrato, si existe.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la liquidación en la base de datos. Null si el contrato no ha sido liquidado.
                            type:
                              - string
                              - 'null'
                            example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                          date:
                            description: Fecha de la liquidación en formato YYYY-MM-DD. Null si el contrato no ha sido liquidado.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          deleteable:
                            description: Indica si la liquidación puede ser eliminada. Null si el contrato no ha sido liquidado.
                            type:
                              - boolean
                              - 'null'
                            example: true
                      wage_id:
                        description: Identificador único (ID) asignado al salario vigente del contrato en la base de datos.
                        type: string
                        example: 7887b3b9-9869-4416-8da7-5db9e99ed8e2
                      wage_category:
                        description: Modalidad del salario vigente del contrato.
                        $ref: '#/components/schemas/SalaryCategory'
                      base_salary:
                        description: Valor del salario básico mensual del contrato en pesos colombianos.
                        type: integer
                        example: 1300000
                      remote_work:
                        description: Indica si la persona trabaja en modalidad de teletrabajo o trabajo en casa.
                        type: boolean
                        example: false
                      transport_subsidy:
                        description: Indica si el contrato incluye auxilio de transporte.
                        type: boolean
                        example: true
                      contract_detail:
                        description: Detalle vigente del contrato con información de cotizante y centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                            type: string
                            example: 99763829-ec48-4d60-96c8-cde35e7d86b0
                          contributor_subtype:
                            description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social.
                            $ref: '#/components/schemas/ContributorSubtype'
                          initial_day:
                            description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                            type: string
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin de vigencia del detalle del contrato. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                            type: string
                            example: 8ea29a65-19f5-40d2-854a-869415d4494a
                          deleteable:
                            description: Indica si el detalle del contrato puede ser eliminado.
                            type: boolean
                            example: false
                      contract_position_history:
                        description: Historial de cargo vigente del contrato con área, sede y cargo asignados.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          initial_day:
                            description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                            type: string
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del historial de cargo. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este historial en la base de datos.
                            type: string
                            example: 8ea29a65-19f5-40d2-854a-869415d4494a
                          area:
                            description: Área asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al área en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                              name:
                                description: Nombre del área.
                                type:
                                  - string
                                  - 'null'
                                example: Administración
                          location:
                            description: Sede asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sede en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                              name:
                                description: Nombre de la sede.
                                type:
                                  - string
                                  - 'null'
                                example: Oficina principal
                          position:
                            description: Cargo asignado al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al cargo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                              name:
                                description: Nombre del cargo.
                                type:
                                  - string
                                  - 'null'
                                example: Coordinador de proyectos
                          deleteable:
                            description: Indica si el historial de cargo puede ser eliminado.
                            type: boolean
                            example: false
                      work_center:
                        description: |
                          Centro de trabajo asignado al contrato.

                          - Si el contrato tiene centro de trabajo, retorna el objeto con su información.
                          - Si no tiene centro de trabajo asignado, retorna un objeto vacío `{}`.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                            type: string
                            example: 97a1f505-fbd5-554c-a620-ca0017f9bada
                          name:
                            description: Nombre del centro de trabajo junto con el tipo de riesgo.
                            type: string
                            example: Oficina central - Riesgo 1 - Mínimo
                          risk_type:
                            description: Nombre del tipo de riesgo del centro de trabajo.
                            type:
                              - string
                              - 'null'
                            example: Riesgo 1 - Mínimo
                      risk_type:
                        description: |
                          Código del tipo de riesgo ARL del centro de trabajo.

                          Valores posibles:
                          * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
                          * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
                          * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
                          * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
                          * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)

                          `null` si no tiene centro de trabajo asignado.
                        type:
                          - string
                          - 'null'
                        enum:
                          - risk_1
                          - risk_2
                          - risk_3
                          - risk_4
                          - risk_5
                        example: risk_1
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo.
                        type: boolean
                        example: false
                      health_provider:
                        description: Entidad prestadora de salud (EPS) afiliada al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la EPS en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name:
                            description: Nombre de la EPS.
                            type:
                              - string
                              - 'null'
                            example: Nueva EPS
                      pension_provider:
                        description: Fondo de pensiones afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name:
                            description: Nombre del fondo de pensiones.
                            type:
                              - string
                              - 'null'
                            example: Protección
                      severance_provider:
                        description: Fondo de cesantías afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 16881701-ff67-5895-913b-dfdf4ab03797
                          name:
                            description: Nombre del fondo de cesantías.
                            type:
                              - string
                              - 'null'
                            example: Fondo Nacional del Ahorro
              example:
                data:
                  id: 8ea29a65-19f5-40d2-854a-869415d4494a
                  category: employee
                  initial_day: '2024-01-01'
                  end_day: '2024-12-31'
                  period_end_day: '2024-01-31'
                  apply_art102_cst: false
                  term: fixed
                  terminated: false
                  termination:
                    id: null
                    date: null
                    deleteable: null
                  wage_id: 7887b3b9-9869-4416-8da7-5db9e99ed8e2
                  wage_category: monthly
                  base_salary: 1300000
                  remote_work: false
                  transport_subsidy: true
                  contract_detail:
                    id: 99763829-ec48-4d60-96c8-cde35e7d86b0
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: 8ea29a65-19f5-40d2-854a-869415d4494a
                    deleteable: false
                  contract_position_history:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: 8ea29a65-19f5-40d2-854a-869415d4494a
                    area:
                      id: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                      name: Administración
                    location:
                      id: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                      name: Oficina principal
                    position:
                      id: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                      name: Coordinador de proyectos
                    deleteable: false
                  work_center:
                    id: 97a1f505-fbd5-554c-a620-ca0017f9bada
                    name: Oficina central - Riesgo 1 - Mínimo
                    risk_type: Riesgo 1 - Mínimo
                  risk_type: risk_1
                  high_risk_pension: false
                  health_provider:
                    id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    name: Nueva EPS
                  pension_provider:
                    id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    name: Protección
                  severance_provider:
                    id: 16881701-ff67-5895-913b-dfdf4ab03797
                    name: Fondo Nacional del Ahorro
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato liquidado / Fecha inicial inválida / Pensión de alto riesgo inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato liquidado:
                  value:
                    error:
                      - code: '3105'
                        index: 0
                        message: El contrato ya ha sido liquidado, por lo cual no puedes editarlo.
                        object: contract
                Fecha inicial inválida:
                  value:
                    error:
                      - code: '0702'
                        index: 0
                        message: La fecha inicial no puede ser una fecha superior a la fecha final del periodo actual más 15 días.
                        object: initial_day
                Pensión de alto riesgo inválida:
                  value:
                    error:
                      - code: '4009'
                        index: 0
                        message: La pensión de alto riesgo requiere Colpensiones como administradora de pensiones (Resolución 6072 de 2024).
                        object: contract_detail
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al contrato en la base de datos.
        schema:
          type: string
          example: 8ea29a65-19f5-40d2-854a-869415d4494a
  /v1/{company_id}/cost_centers:
    get:
      operationId: indexCostCenters
      tags:
        - Centros de costos
      summary: Listar centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de centros de costos de la empresa junto con las opciones de integración de Alegra si se solicitan.

        **¿Cuándo usar este endpoint?**

        * Consultar los centros de costos disponibles para asignar a una persona al crear o modificar su contrato.
        * Verificar qué centros de costos pueden eliminarse antes de reorganizar la estructura de la empresa.
        * Obtener las opciones de Alegra disponibles para vincular con los centros de costos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Integración con Alegra:** El parámetro `integration_options=true` activa la consulta a Alegra para obtener centros de costos activos; si no se envía, `alegra_options` retorna vacío.
      parameters:
        - in: query
          name: integration_options
          required: false
          description: Si es `true`, consulta la integración de Alegra para obtener centros de costos activos disponibles como opciones.
          schema:
            type: string
            example: 'true'
      responses:
        '200':
          description: Con opciones de Alegra / Sin opciones de Alegra
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de centros de costos de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al centro de costos en la base de datos.
                          type: string
                          example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                        name:
                          description: Nombre del centro de costos.
                          type: string
                          example: Producción
                        accounting_code:
                          description: Código contable asociado al centro de costos.
                          type: string
                          example: '051'
                        integration_code:
                          description: Código de integración con Alegra vinculado al centro de costos. Puede ser null si no tiene integración configurada.
                          type:
                            - string
                            - 'null'
                          example: '001'
                        code:
                          description: Código interno del centro de costos.
                          type: string
                          example: X123
                        workers_number:
                          description: Número de personas actualmente asignadas a este centro de costos.
                          type: integer
                          example: 4
                        deleteable:
                          description: Indica si el centro de costos puede eliminarse. Es `false` cuando tiene personas asociadas.
                          type: boolean
                          example: false
                  alegra_options:
                    description: Opciones de centros de costos disponibles en Alegra para vincular. Retorna vacío si no se envió `integration_options=true`.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador del centro de costos en Alegra.
                          type: integer
                          example: 1
                        code:
                          description: Código del centro de costos en Alegra.
                          type: string
                          example: '001'
                        name:
                          description: Nombre del centro de costos en Alegra.
                          type: string
                          example: Centro Alegra
              examples:
                Con opciones de Alegra:
                  value:
                    data:
                      - id: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                        name: Producción
                        accounting_code: '051'
                        integration_code: '001'
                        code: X123
                        workers_number: 4
                        deleteable: false
                    alegra_options:
                      - id: 1
                        code: '001'
                        name: Centro Alegra
                Sin opciones de Alegra:
                  value:
                    data:
                      - id: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                        name: Producción
                        accounting_code: '051'
                        integration_code: null
                        code: X123
                        workers_number: 4
                        deleteable: false
                    alegra_options: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createCostCenter
      tags:
        - Centros de costos
      summary: Crear centro de costos
      description: |
        **¿Qué hace este endpoint?**

        Crea un nuevo centro de costos asociado a la empresa.

        **¿Cuándo usar este endpoint?**

        * Agregar un nuevo centro de costos para clasificar y agrupar personas dentro de la empresa.
        * Configurar la estructura de centros de costos antes de registrar personas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Nombre único:** El nombre debe ser único dentro de la empresa y solo puede contener letras, números y los caracteres `-_`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                cost_center:
                  description: Datos del centro de costos a crear.
                  type: object
                  properties:
                    name:
                      type: string
                      description: Nombre del centro de costos. Debe ser único en la empresa.
                      example: Producción
                    accounting_code:
                      type: string
                      description: Código contable asociado al centro de costos.
                      example: '123'
                    code:
                      type: string
                      description: Código interno del centro de costos.
                      example: '01'
                    integration_code:
                      type: string
                      description: Código de integración con Alegra (opcional).
                      example: '001'
                  required:
                    - name
                    - accounting_code
              required:
                - cost_center
      responses:
        '201':
          description: Centro de costos creado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del centro de costos recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al centro de costos en la base de datos.
                        type: string
                        example: 078b9f9e-098c-489f-a457-7d5873a477d1
                      name:
                        description: Nombre del centro de costos.
                        type: string
                        example: Producción
                      accounting_code:
                        description: Código contable asociado al centro de costos.
                        type: string
                        example: '123'
                      code:
                        description: Código interno del centro de costos.
                        type: string
                        example: '01'
                      integration_code:
                        description: Código de integración con Alegra vinculado al centro de costos. Puede ser null si no tiene integración configurada.
                        type:
                          - string
                          - 'null'
                        example: '001'
                      workers_number:
                        description: Número de personas actualmente asignadas a este centro de costos.
                        type: integer
                        example: 0
                      deleteable:
                        description: Indica si el centro de costos puede eliminarse. Es `false` cuando tiene personas asociadas.
                        type: boolean
                        example: true
              example:
                data:
                  id: 078b9f9e-098c-489f-a457-7d5873a477d1
                  name: Producción
                  accounting_code: '123'
                  code: '01'
                  integration_code: null
                  workers_number: 0
                  deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre en blanco / Nombre demasiado largo / Nombre duplicado / Nombre con caracteres inválidos / Código contable en blanco / Código contable demasiado largo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nombre en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Nombre demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Nombre es demasiado largo (50 caracteres máximo).
                        object: name
                Nombre duplicado:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Nombre ya está en uso.
                        object: name
                Nombre con caracteres inválidos:
                  value:
                    error:
                      - code: '0116'
                        index: 0
                        message: 'Nombre solo puede contener números, letras y los siguientes caracteres: ''-_''.'
                        object: name
                Código contable en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Código contable no puede estar en blanco.
                        object: accounting_code
                Código contable demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Código contable es demasiado largo (10 caracteres máximo).
                        object: accounting_code
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 061c135f-92fc-4ee1-acf7-3fd76a4e8a00
  /v1/{company_id}/cost_centers/{id}:
    patch:
      operationId: updateCostCenter
      tags:
        - Centros de costos
      summary: Actualizar centro de costos
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los datos de un centro de costos existente de la empresa.

        **¿Cuándo usar este endpoint?**

        * Corregir el nombre o código contable de un centro de costos registrado incorrectamente.
        * Actualizar el código de integración con Alegra cuando cambia la configuración contable.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                cost_center:
                  description: Campos del centro de costos a actualizar.
                  type: object
                  properties:
                    name:
                      description: Nombre del centro de costos. Debe ser único en la empresa y solo puede contener letras, números y los caracteres `-_`.
                      type: string
                      example: Producción
                    accounting_code:
                      description: Código contable asociado al centro de costos.
                      type: string
                      example: '123'
                    code:
                      description: Código interno del centro de costos.
                      type: string
                      example: '01'
                    integration_code:
                      description: Código de integración con Alegra. Puede ser nulo si no aplica.
                      type:
                        - string
                        - 'null'
                      example: '001'
      responses:
        '202':
          description: Centro de costos actualizado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados del centro de costos.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al centro de costos en la base de datos.
                        type: string
                        example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                      name:
                        description: Nombre del centro de costos.
                        type: string
                        example: Producción
                      accounting_code:
                        description: Código contable asociado al centro de costos.
                        type: string
                        example: '123'
                      code:
                        description: Código interno del centro de costos.
                        type: string
                        example: '01'
                      integration_code:
                        description: Código de integración con Alegra. Nulo si no tiene integración configurada.
                        type:
                          - string
                          - 'null'
                        example: '001'
                      workers_number:
                        description: Número de personas actualmente asignadas a este centro de costos.
                        type: integer
                        example: 4
                      deleteable:
                        description: Indica si el centro de costos puede eliminarse. Es `false` cuando tiene personas asociadas o es el único de la empresa.
                        type: boolean
                        example: false
              example:
                data:
                  id: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                  name: Producción
                  accounting_code: '123'
                  code: '01'
                  integration_code: '001'
                  workers_number: 4
                  deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre inválido / Código contable inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nombre inválido:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Código contable inválido:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Código contable no puede estar en blanco.
                        object: accounting_code
    delete:
      operationId: destroyCostCenter
      tags:
        - Centros de costos
      summary: Eliminar centro de costos
      description: |
        **¿Qué hace este endpoint?**

        Elimina de forma permanente un centro de costos de la empresa.

        **¿Cuándo usar este endpoint?**

        * Remover un centro de costos que ya no está en uso y no tiene personas asociadas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Eliminación:** Solo se puede eliminar si no tiene personas asociadas y no es el único centro de costos de la empresa. El campo `deleteable` del listado indica si es eliminable.
      responses:
        '200':
          description: Centro de costos eliminado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: El centro de costos ha sido eliminado.
              example:
                data:
                  message: El centro de costos ha sido eliminado.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Centro de costos con personas asociadas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0504'
                    index: 0
                    message: Centro de costos no se puede eliminar porque tiene personas asociadas.
                    object: cost_center
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al centro de costos en la base de datos.
        schema:
          type: string
          example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
  /v1/{company_id}/cost_center_configurations_file:
    get:
      operationId: showCostCenterConfigurationsFile
      tags:
        - Centros de costos
      summary: Generar plantilla de centros de costos
      description: Genera un archivo XLSX de plantilla para carga masiva de configuración de centros de costos
      responses:
        '200':
          description: Archivo en proceso de generación
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de procesamiento
                        type: string
                        examples:
                          - Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createCostCenterConfigurationsFile
      tags:
        - Centros de costos
      summary: Importar configuraciones de centros de costos
      description: |
        **¿Qué hace este endpoint?**

        Recibe el archivo Excel de configuración de centros de costos y encola un trabajo en segundo plano para procesarlo. El archivo se adjunta al usuario autenticado y luego se ejecuta la importación masiva de las configuraciones.

        **¿Cuándo usar este endpoint?**

        * Cargar masivamente configuraciones de centros de costos para asignarlas a múltiples personas desde un archivo Excel.
        * Importar el archivo diligenciado a partir de la plantilla generada con el `GET` de este mismo endpoint.
        * Actualizar en bloque la distribución de centros de costos de la empresa sin hacer cambios manuales por persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Formato del archivo:** Solo se aceptan archivos `.xlsx`. Archivos con otro formato serán rechazados.
        * **Pago activo:** La empresa debe tener un plan activo para usar esta funcionalidad.
        * **Procesamiento asíncrono:** El endpoint no retorna el resultado final de la importación en la respuesta HTTP inmediata. Solo confirma que el archivo fue recibido y que el procesamiento fue encolado.
        * **Entrega del resultado:** El resultado del procesamiento se publica de forma asíncrona en Firebase en la ruta `users/:user_id/import_cost_center_configurations`.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  description: Archivo Excel (`.xlsx`) con las configuraciones de centros de costos a importar.
                  type: string
                  format: binary
      responses:
        '200':
          description: Archivo de configuraciones encolado correctamente para su procesamiento
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que el archivo fue recibido y está siendo procesado.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Archivo inválido o firma del archivo corrompida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Archivo inválido:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
                Firma del archivo corrompida:
                  value:
                    error:
                      - code: '0609'
                        index: 0
                        message: Ocurrio un error. Intenta cargar nuevamente el archivo.
                        object: file
    patch:
      operationId: updateCostCenterConfigurationsFile
      tags:
        - Centros de costos
      summary: Reprocesar configuraciones de centros de costos con errores
      description: |
        **¿Qué hace este endpoint?**

        Recibe el resultado de una importación previa de configuraciones de centros de costos que tuvo registros fallidos y encola el reprocesamiento únicamente de las filas con error.

        **¿Cuándo usar este endpoint?**

        * Reintentar el procesamiento de los registros que fallaron tras una importación de centros de costos con errores.
        * Enviar las correcciones una vez revisados y ajustados los datos devueltos por la importación inicial.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** La empresa debe tener un plan activo para usar esta funcionalidad.
        * **Procesamiento asíncrono:** El resultado se publica en Firebase en la ruta `users/:user_id/companies/:company_id/fix_cost_center_configurations`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - updated_configurations_data
              properties:
                updated_configurations_data:
                  description: Objeto con los resultados de la importación anterior, incluyendo conteos de éxito, fallos y las filas con errores.
                  type: object
                  required:
                    - success_workers_ids
                    - file_with_errors
                    - cost_center_configurations
                  properties:
                    success_workers_ids:
                      description: Lista de IDs de los trabajadores procesados correctamente en la importación anterior.
                      type: array
                      items:
                        type: string
                        example: d2bc3e5a-dc49-4160-8d01-6dedbba4c0c0
                    file_with_errors:
                      description: Indica si la importación anterior tuvo registros con error.
                      type: boolean
                      example: true
                    cost_center_configurations:
                      description: Datos de los centros de costos con resultados de éxito y fallo de la importación anterior.
                      type: object
                      required:
                        - success_cases
                        - failure_cases_count
                        - failure_cases
                        - not_found_workers
                      properties:
                        success_cases:
                          description: Número de trabajadores procesados correctamente.
                          type: integer
                          example: 0
                        failure_cases_count:
                          description: Número de filas con error.
                          type: integer
                          example: 2
                        failure_cases:
                          description: Detalle de las filas que fallaron, con columnas dinámicas de centros de costo y datos del trabajador.
                          type: object
                          required:
                            - columns
                            - rows
                          properties:
                            columns:
                              description: Columnas dinámicas correspondientes a los centros de costo de la empresa.
                              type: array
                              items:
                                type: object
                                properties:
                                  key:
                                    description: Identificador interno de la columna (coincide con el nombre del centro de costo).
                                    type: string
                                    example: Centro de Costo Principal
                                  name:
                                    description: Nombre visible de la columna en la interfaz.
                                    type: string
                                    example: Centro de Costo Principal
                                  editor:
                                    description: Indica si la celda es editable por el usuario.
                                    type: boolean
                                    example: true
                            rows:
                              description: Filas con los datos de los trabajadores que fallaron.
                              type: array
                              items:
                                type: object
                                properties:
                                  worker_id:
                                    description: UUID del trabajador.
                                    type: string
                                    example: d2bc3e5a-dc49-4160-8d01-6dedbba4c0c0
                                  worker_id_number:
                                    description: Número de documento del trabajador.
                                    type: string
                                    example: '123456789'
                                  name:
                                    description: Nombre completo del trabajador.
                                    type: string
                                    example: Juan Pérez
                                  error_details:
                                    description: Detalle del error de la fila.
                                    type: object
                                  percentages:
                                    description: Porcentajes asignados a cada centro de costo de la empresa.
                                    type: array
                                    items:
                                      type: object
                                      required:
                                        - name
                                        - value
                                      properties:
                                        name:
                                          description: Nombre del centro de costo.
                                          type: string
                                          example: Centro de Costo Principal
                                        value:
                                          description: Porcentaje asignado a ese centro (0–100).
                                          type: number
                                          example: 100
                        not_found_workers:
                          description: Trabajadores no encontrados en la importación anterior.
                          type: array
                          items:
                            type: object
                            properties:
                              message:
                                type: string
                                example: Trabajador con cédula 123456789 no encontrado.
            example:
              updated_configurations_data:
                success_workers_ids: []
                file_with_errors: true
                cost_center_configurations:
                  success_cases: 0
                  failure_cases_count: 2
                  failure_cases:
                    columns:
                      - key: Centro de Costo Principal
                        name: Centro de Costo Principal
                        editor: true
                    rows:
                      - worker_id: d2bc3e5a-dc49-4160-8d01-6dedbba4c0c0
                        worker_id_number: '123456789'
                        name: Juan Pérez
                        error_details: {}
                        percentages:
                          - name: Centro de Costo Principal
                            value: 100
                  not_found_workers: []
      responses:
        '200':
          description: Corrección de centros de costos encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que el reprocesamiento fue encolado.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Los parámetros enviados en `updated_configurations_data` son inválidos o están ausentes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    parameters:
      - name: company_id
        in: path
        description: Identificador de la empresa
        required: true
        schema:
          type: string
          examples:
            - 006y189a-e75f-2b7e-8638-3cdf60492d6f
  /v1/{company_id}/current_period:
    get:
      operationId: showCurrentPeriod
      tags:
        - Periodos de nómina
      summary: Obtener periodo actual
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información completa del periodo de nómina actual de la empresa, incluyendo
        totales de costos, conteo de contratos y periodos relacionados. Por defecto incluye el
        listado paginado de nóminas; al indicar que no se requieren nóminas (`without_payrolls`),
        omite ese listado y los filtros de paginación.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado y los totales del periodo en curso antes de procesarlo o revisarlo.
        * Obtener el listado de nóminas del periodo con soporte de búsqueda y filtros.
        * Verificar si el periodo actual es editable antes de modificar nóminas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Empresa sin periodo actual:** Si la empresa no tiene un periodo activo, retorna `404`.
      parameters:
        - $ref: '#/components/parameters/withoutPayrollsParam'
        - $ref: '#/components/parameters/contractCategoryParam'
        - $ref: '#/components/parameters/contractStatusParam'
        - $ref: '#/components/parameters/locationParam'
        - in: query
          required: false
          name: search
          description: Busca nóminas por nombre de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `without_payrolls`:

            - **Sin `without_payrolls`** (por defecto): retorna `data` con el listado de nóminas y `filters` con la paginación.
            - **`without_payrolls: true`**: retorna solo `data` con los totales y contadores del periodo, sin nóminas ni paginación.
          content:
            application/json:
              schema:
                oneOf:
                  - description: Respuesta con nóminas y paginación
                    required:
                      - data
                      - filters
                    type: object
                    properties:
                      data:
                        description: Información del periodo actual de la empresa.
                        type: object
                        properties:
                          previous_period_id:
                            description: Identificador único (ID) del periodo anterior al actual en la base de datos. Null si no existe periodo anterior.
                            type:
                              - string
                              - 'null'
                            example: fc4b7f84-060e-450d-bc17-8a963d409ede
                          electronic_payroll_period_id:
                            description: Identificador único (ID) del periodo de nómina electrónica mensual asociado. Null si no aplica.
                            type:
                              - string
                              - 'null'
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          id:
                            description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          initial_day:
                            description: Fecha de inicio del periodo en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del periodo en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-15'
                          length:
                            description: Duración del periodo en días.
                            type: integer
                            example: 15
                          payrolls_paid:
                            description: Indica si las nóminas del periodo han sido marcadas como pagadas.
                            type: boolean
                            example: false
                          payrolls_number:
                            description: Número total de nóminas del periodo.
                            type: integer
                            example: 5
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7500000
                          social_benefits_provision:
                            description: Total de prestaciones sociales provisionadas en el periodo, en pesos colombianos.
                            type: integer
                            example: 850000
                          company_cost:
                            description: Costo total de la empresa en el periodo incluyendo aportes de seguridad social y parafiscales, en pesos colombianos.
                            type: integer
                            example: 9750000
                          social_security_payment:
                            description: Total del aporte de seguridad social del periodo, en pesos colombianos.
                            type: integer
                            example: 1200000
                          editable:
                            description: Indica si el periodo puede ser editado (nóminas modificables).
                            type: boolean
                            example: true
                          contracts_counter:
                            description: Conteo de nóminas del periodo agrupado por categoría de contrato.
                            type: object
                            properties:
                              all:
                                description: Total de nóminas del periodo.
                                type: integer
                                example: 5
                              employee:
                                description: Nóminas de empleados a tiempo completo.
                                type: integer
                                example: 3
                              part_time_contract:
                                description: Nóminas de empleados a tiempo parcial.
                                type: integer
                                example: 1
                              apprentice:
                                description: Nóminas de aprendices.
                                type: integer
                                example: 0
                              student:
                                description: Nóminas de estudiantes.
                                type: integer
                                example: 0
                              contractor:
                                description: Nóminas de contratistas.
                                type: integer
                                example: 1
                          terminated_contracts_counter:
                            description: Número de nóminas del periodo con liquidación de contrato registrada.
                            type: integer
                            example: 0
                          related_periods:
                            description: Periodos del mismo mes (quincenas del mismo periodo mensual). Vacío si el periodo no tiene relacionados.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al periodo en la base de datos.
                                  type: string
                                  example: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                                initial_day:
                                  description: Fecha inicial del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-16'
                                end_day:
                                  description: Fecha final del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-31'
                          payrolls:
                            description: Listado de nóminas del periodo con su detalle.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la nómina en la base de datos.
                                  type: string
                                  example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                                worker_id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                worker_name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: Juan Pérez
                                contract_id:
                                  description: Identificador único (ID) asignado al contrato en la base de datos.
                                  type: string
                                  example: 3c4d5e6f-7a8b-9012-cdef-123456789012
                                contract_category:
                                  $ref: '#/components/schemas/ContractCategory'
                                salary:
                                  description: Salario base de la nómina en pesos colombianos.
                                  type: integer
                                  example: 1500000
                                worker_payment:
                                  description: Pago neto a la persona en pesos colombianos.
                                  type: integer
                                  example: 1600000
                                company_cost:
                                  description: Costo total para la empresa en pesos colombianos.
                                  type: integer
                                  example: 1900000
                                worked_time:
                                  description: Días u horas trabajados en el periodo.
                                  type: number
                                  example: 15
                                locked:
                                  description: Indica si la nómina está bloqueada (liquidada definitivamente).
                                  type: boolean
                                  example: false
                                editable:
                                  description: Indica si la nómina puede ser editada.
                                  type: boolean
                                  example: true
                                contract_terminated:
                                  description: Indica si el contrato asociado a esta nómina tiene una liquidación registrada en el periodo.
                                  type: boolean
                                  example: false
                      filters:
                        description: Información de paginación de las nóminas del periodo.
                        type: object
                        properties:
                          location:
                            description: Identificador de la sede por la que se filtró, o `All` si no se aplicó filtro de sede.
                            type: string
                            example: All
                          total_records:
                            description: Número total de nóminas del periodo que coinciden con los filtros.
                            type: integer
                            example: 5
                          page:
                            description: Número de página actual.
                            type: integer
                            example: 1
                          per_page:
                            description: Número máximo de nóminas retornadas por página.
                            type: integer
                            example: 20
                          search:
                            description: Texto de búsqueda aplicado. Null si no se envió búsqueda.
                            type:
                              - string
                              - 'null'
                            example: Juan Pérez
                  - description: Respuesta con totales del periodo sin nóminas
                    required:
                      - data
                    type: object
                    properties:
                      data:
                        description: Información del periodo actual de la empresa.
                        type: object
                        properties:
                          previous_period_id:
                            description: Identificador único (ID) del periodo anterior al actual en la base de datos. Null si no existe periodo anterior.
                            type:
                              - string
                              - 'null'
                            example: fc4b7f84-060e-450d-bc17-8a963d409ede
                          electronic_payroll_period_id:
                            description: Identificador único (ID) del periodo de nómina electrónica mensual asociado. Null si no aplica.
                            type:
                              - string
                              - 'null'
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          id:
                            description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          initial_day:
                            description: Fecha de inicio del periodo en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del periodo en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-15'
                          length:
                            description: Duración del periodo en días.
                            type: integer
                            example: 15
                          payrolls_paid:
                            description: Indica si las nóminas del periodo han sido marcadas como pagadas.
                            type: boolean
                            example: false
                          payrolls_number:
                            description: Número total de nóminas del periodo.
                            type: integer
                            example: 5
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7500000
                          social_benefits_provision:
                            description: Total de prestaciones sociales provisionadas en el periodo, en pesos colombianos.
                            type: integer
                            example: 850000
                          company_cost:
                            description: Costo total de la empresa en el periodo incluyendo aportes de seguridad social y parafiscales, en pesos colombianos.
                            type: integer
                            example: 9750000
                          social_security_payment:
                            description: Total del aporte de seguridad social del periodo, en pesos colombianos.
                            type: integer
                            example: 1200000
                          editable:
                            description: Indica si el periodo puede ser editado (nóminas modificables).
                            type: boolean
                            example: true
                          contracts_counter:
                            description: Conteo de nóminas del periodo agrupado por categoría de contrato.
                            type: object
                            properties:
                              all:
                                description: Total de nóminas del periodo.
                                type: integer
                                example: 5
                              employee:
                                description: Nóminas de empleados a tiempo completo.
                                type: integer
                                example: 3
                              part_time_contract:
                                description: Nóminas de empleados a tiempo parcial.
                                type: integer
                                example: 1
                              apprentice:
                                description: Nóminas de aprendices.
                                type: integer
                                example: 0
                              student:
                                description: Nóminas de estudiantes.
                                type: integer
                                example: 0
                              contractor:
                                description: Nóminas de contratistas.
                                type: integer
                                example: 1
                          terminated_contracts_counter:
                            description: Número de nóminas del periodo con liquidación de contrato registrada.
                            type: integer
                            example: 0
                          related_periods:
                            description: Periodos del mismo mes (quincenas del mismo periodo mensual). Vacío si el periodo no tiene relacionados.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al periodo en la base de datos.
                                  type: string
                                  example: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                                initial_day:
                                  description: Fecha inicial del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-16'
                                end_day:
                                  description: Fecha final del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-31'
              examples:
                Con nóminas:
                  value:
                    data:
                      previous_period_id: fc4b7f84-060e-450d-bc17-8a963d409ede
                      electronic_payroll_period_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                      initial_day: '2024-01-01'
                      end_day: '2024-01-15'
                      length: 15
                      payrolls_paid: false
                      payrolls_number: 5
                      workers_payment: 7500000
                      social_benefits_provision: 850000
                      company_cost: 9750000
                      social_security_payment: 1200000
                      editable: true
                      contracts_counter:
                        all: 5
                        employee: 3
                        part_time_contract: 1
                        apprentice: 0
                        student: 0
                        contractor: 1
                      terminated_contracts_counter: 0
                      related_periods:
                        - id: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                          initial_day: '2024-01-16'
                          end_day: '2024-01-31'
                      payrolls:
                        - id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name: Juan Pérez
                          contract_id: 3c4d5e6f-7a8b-9012-cdef-123456789012
                          contract_category: employee
                          salary: 1500000
                          worker_payment: 1600000
                          company_cost: 1900000
                          worked_time: 15
                          locked: false
                          editable: true
                          contract_terminated: false
                    filters:
                      location: All
                      total_records: 5
                      page: 1
                      per_page: 20
                      search: Juan Pérez
                Sin nóminas:
                  value:
                    data:
                      previous_period_id: fc4b7f84-060e-450d-bc17-8a963d409ede
                      electronic_payroll_period_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                      initial_day: '2024-01-01'
                      end_day: '2024-01-15'
                      length: 15
                      payrolls_paid: false
                      payrolls_number: 5
                      workers_payment: 7500000
                      social_benefits_provision: 850000
                      company_cost: 9750000
                      social_security_payment: 1200000
                      editable: true
                      contracts_counter:
                        all: 5
                        employee: 3
                        part_time_contract: 1
                        apprentice: 0
                        student: 0
                        contractor: 1
                      terminated_contracts_counter: 0
                      related_periods:
                        - id: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                          initial_day: '2024-01-16'
                          end_day: '2024-01-31'
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateCurrentPeriod
      tags:
        - Periodos de nómina
      summary: Actualizar periodo actual
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el estado de pago de las nóminas del periodo actual. Al marcar el periodo como pagado
        (`payrolls_paid: true`), el sistema registra el pago y descuenta las cuotas pendientes de los
        préstamos activos de cada persona.

        **¿Cuándo usar este endpoint?**

        * Marcar las nóminas del periodo como pagadas una vez realizado el pago a las personas.
        * Revertir el estado de pago si se marcó por error.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Empresa sin periodo actual:** Si la empresa no tiene un periodo activo, retorna `404`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - period
              properties:
                period:
                  description: Datos del periodo a actualizar.
                  type: object
                  required:
                    - payrolls_paid
                  properties:
                    payrolls_paid:
                      description: Indica si las nóminas del periodo han sido pagadas.
                      type: boolean
                      example: true
            example:
              period:
                payrolls_paid: true
      responses:
        '202':
          description: Estado de pago del periodo actualizado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados del periodo.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
                        type: string
                        example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                      payrolls_paid:
                        description: Estado de pago actualizado del periodo.
                        type: boolean
                        example: true
              example:
                data:
                  id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                  payrolls_paid: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/electronic_payroll/cancels/{id}:
    patch:
      operationId: cancelElectronicPayroll
      tags:
        - Anulación de nómina electrónica
      summary: Anular nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Anula o elimina una nómina electrónica ante la DIAN. Puede operar de forma síncrona (retorna el estado actualizado del periodo) o asíncrona (encola la anulación y notifica el resultado vía Firebase).

        **¿Cuándo usar este endpoint?**

        * Anular ante la DIAN una nómina electrónica emitida con errores que no pueden corregirse.
        * Eliminar una nómina electrónica pendiente que no llegó a ser transmitida.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Condición de anulación:** Solo se pueden anular nóminas electrónicas en estado anulable o eliminable. El campo `options.cancelable` del listado de nóminas del periodo indica si la nómina puede ser anulada.
        * **Síncrono vs. asíncrono:** Si `async: true`, encola la anulación y notifica el resultado vía Firebase en `electronic_payroll/cancels/{id}`. Si `async: false` o no se envía, retorna el estado actualizado del periodo directamente.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: Anulación encolada (modo asíncrono)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que la anulación fue encolada. El resultado se notifica vía Firebase.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '202':
          description: Nómina anulada correctamente (modo síncrono)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Estado actualizado del periodo de nómina electrónica tras la anulación.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
                        type: string
                        example: b8b5d397-19a0-5504-90ee-ee0355df88f0
                      active:
                        description: Indica si el periodo está activo para transmitir nóminas electrónicas a la DIAN.
                        type: boolean
                        example: true
                      initial_day:
                        description: Fecha de inicio del periodo de nómina electrónica.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del periodo de nómina electrónica.
                        type: string
                        format: date
                        example: '2024-01-31'
                      options:
                        description: Opciones de transmisión disponibles para el periodo.
                        type: object
                        properties:
                          authorized:
                            description: Indica si la empresa está autorizada por la DIAN para emitir nómina electrónica.
                            type: boolean
                            example: true
                          transmission_authorized:
                            description: Indica si el periodo puede transmitirse a la DIAN en este momento.
                            type: boolean
                            example: false
                          transmission_in_range:
                            description: Indica si la fecha actual está dentro del plazo legal para transmitir el periodo.
                            type: boolean
                            example: false
                      electronic_payrolls_counter:
                        description: Conteo de nóminas electrónicas del periodo agrupadas por estado.
                        type: object
                        properties:
                          total:
                            description: Total de nóminas electrónicas actuales del periodo.
                            type: integer
                            example: 1
                          to_issue:
                            description: Nóminas electrónicas pendientes de emisión.
                            type: integer
                            example: 1
                          issued:
                            description: Nóminas electrónicas emitidas y aceptadas por la DIAN.
                            type: integer
                            example: 0
                          modified:
                            description: Nóminas electrónicas modificadas y aceptadas por la DIAN.
                            type: integer
                            example: 0
                          rejected:
                            description: Nóminas electrónicas rechazadas por la DIAN.
                            type: integer
                            example: 0
                          processing:
                            description: Nóminas electrónicas en proceso de validación por la DIAN.
                            type: integer
                            example: 0
                          pending:
                            description: Nóminas electrónicas pendientes de envío a la DIAN.
                            type: integer
                            example: 1
                          canceled:
                            description: Nóminas electrónicas anuladas ante la DIAN.
                            type: integer
                            example: 0
                          replaced:
                            description: Nóminas electrónicas reemplazadas por una versión más reciente.
                            type: integer
                            example: 0
                      authorization_date:
                        description: Fecha en que la empresa fue autorizada por la DIAN para emitir nómina electrónica.
                        type: string
                        format: date
                        example: '2024-07-03'
                      electronic_payroll_social_benefit:
                        description: Modo de reporte de prestaciones sociales configurado para la nómina electrónica.
                        $ref: '#/components/schemas/ElectronicPayrollSocialBenefits'
                      electronic_payrolls:
                        description: Listado de nóminas electrónicas del periodo tras la anulación.
                        type: array
                        items:
                          description: Nómina electrónica con su estado actualizado.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
                              type: string
                              example: 6f637089-05d0-5996-a1c4-7cb36564368c
                            cune:
                              description: Código Único de Nómina Electrónica asignado por la DIAN. Es null si aún no ha sido aceptada.
                              type:
                                - string
                                - 'null'
                              example: null
                            initial_day:
                              description: Fecha de inicio del periodo de la nómina electrónica.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de la nómina electrónica.
                              type: string
                              format: date
                              example: '2024-01-31'
                            incomes:
                              description: Total de ingresos salariales de la nómina en pesos colombianos.
                              type: integer
                              example: 1850000
                            bonus_incomes:
                              description: Total de ingresos no salariales de la nómina en pesos colombianos.
                              type: integer
                              example: 0
                            deductions:
                              description: Total de deducciones de la nómina en pesos colombianos.
                              type: integer
                              example: 250000
                            payment:
                              description: Valor neto a pagar de la nómina en pesos colombianos.
                              type: integer
                              example: 1600000
                            status:
                              description: Estado actual de la nómina electrónica ante la DIAN.
                              type: string
                              example: pending
                            response_message:
                              description: Mensaje de respuesta recibido de la DIAN. Contiene el error si el estado es rechazado.
                              type: string
                              example: ''
                            error_messages:
                              description: Detalle de errores de validación retornados por la DIAN. Es null si no hay errores.
                              type:
                                - string
                                - 'null'
                              example: null
                            worker:
                              description: Información básica de la persona a quien corresponde la nómina electrónica.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: María González
                                id_number:
                                  description: Número de documento de identificación de la persona.
                                  type: string
                                  example: '1023456789'
                                picture:
                                  description: URL de la foto de perfil de la persona. Es null si no tiene foto cargada.
                                  type:
                                    - string
                                    - 'null'
                                  example: null
                            options:
                              description: Acciones disponibles sobre la nómina electrónica según su estado actual.
                              type: object
                              properties:
                                to_issue:
                                  description: Indica si la nómina puede ser emitida o reenviada a la DIAN.
                                  type: boolean
                                  example: true
                                cancelable:
                                  description: Indica si la nómina puede ser anulada ante la DIAN.
                                  type: boolean
                                  example: false
                                download_files:
                                  description: Indica si los archivos XML de la nómina están disponibles para descarga.
                                  type: boolean
                                  example: false
                                show_errors:
                                  description: Indica si hay errores de gobierno disponibles para mostrar.
                                  type: boolean
                                  example: false
                      related_ep_periods:
                        description: Periodos de nómina electrónica relacionados (del mismo mes en frecuencia mixta o quincenal).
                        type: array
                        items:
                          description: Periodo de nómina electrónica relacionado.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al periodo relacionado en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            initial_day:
                              description: Fecha de inicio del periodo relacionado.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo relacionado.
                              type: string
                              format: date
                              example: '2024-01-15'
                      errors:
                        description: Nóminas electrónicas con errores de gobierno pendientes de corrección.
                        type: array
                        items:
                          description: Detalle de error de gobierno para una nómina electrónica.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) de la nómina electrónica con error.
                              type: string
                              example: 6f637089-05d0-5996-a1c4-7cb36564368c
                            initial_day:
                              description: Fecha de inicio del periodo de la nómina electrónica con error.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de la nómina electrónica con error.
                              type: string
                              format: date
                              example: '2024-01-31'
                            worker:
                              description: Información de la persona asociada a la nómina con error.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: María González
                            message:
                              description: Mensaje de error recibido de la DIAN.
                              type: object
                              properties:
                                error:
                                  description: Descripción del error retornado por la DIAN.
                                  type: string
                                  example: instance.governmentData.Periodo requires property "FechaIngreso"
                                details:
                                  description: Detalle adicional del error de validación. Es null si no hay detalle disponible.
                                  type:
                                    - string
                                    - 'null'
                                  example: null
              example:
                data:
                  id: b8b5d397-19a0-5504-90ee-ee0355df88f0
                  active: true
                  initial_day: '2024-01-01'
                  end_day: '2024-01-31'
                  options:
                    authorized: true
                    transmission_authorized: false
                    transmission_in_range: false
                  electronic_payrolls_counter:
                    total: 1
                    to_issue: 1
                    issued: 0
                    modified: 0
                    rejected: 0
                    processing: 0
                    pending: 1
                    canceled: 0
                    replaced: 0
                  authorization_date: '2024-07-03'
                  electronic_payroll_social_benefit: at_the_time_of_payment
                  electronic_payrolls:
                    - id: 6f637089-05d0-5996-a1c4-7cb36564368c
                      cune: null
                      initial_day: '2024-01-01'
                      end_day: '2024-01-31'
                      incomes: 1850000
                      bonus_incomes: 0
                      deductions: 250000
                      payment: 1600000
                      status: pending
                      response_message: ''
                      error_messages: null
                      worker:
                        id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        name: María González
                        id_number: '1023456789'
                        picture: null
                      options:
                        to_issue: true
                        cancelable: false
                        download_files: false
                        show_errors: false
                  related_ep_periods: []
                  errors: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nómina no anulable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '2704'
                    index: 0
                    message: La nómina electrónica no puede ser anulada o eliminada.
                    object: electronic_payroll
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 4fcd5696-7e51-4743-9780-928d6571d735
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
        schema:
          type: string
          example: a03b18ca-9e5b-53af-a907-ab9babdc02c3
  /v1/{company_id}/electronic_payroll/configuration:
    get:
      operationId: showElectronicPayrollConfiguration
      tags:
        - Configuración de nómina electrónica
      summary: Obtener configuración de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Retorna la configuración de nómina electrónica (DIAN) asociada a la empresa.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado de habilitación ante la DIAN antes de emitir nóminas electrónicas.
        * Verificar los parámetros de reporte de vacaciones y prestaciones sociales configurados.
        * Confirmar si la empresa usa certificado propio o el de Aleluya para la firma electrónica.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Configuración de nómina electrónica
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Configuración de nómina electrónica de la empresa.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de nómina electrónica en la base de datos.
                        type: string
                        example: db80f609-8599-5355-b89d-fd6cfabd4b9f
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 56e06d90-0244-5866-9b2a-af6df5418eee
                      active:
                        description: Indica si la nómina electrónica está activa para la empresa.
                        type: boolean
                        example: true
                      company_certificate:
                        description: Indica si la empresa usa su propio certificado digital para firmar las nóminas electrónicas. Si es false, utiliza el certificado de Aleluya.
                        type: boolean
                        example: false
                      certificate_file_name:
                        description: Nombre del archivo del certificado digital cargado. Es null si no se ha cargado un certificado propio.
                        type:
                          - string
                          - 'null'
                        example: certificado_empresa.pfx
                      canceled_consecutive_number:
                        description: Próximo número consecutivo disponible para nóminas electrónicas anuladas.
                        type: integer
                        example: 29
                      consecutive_number:
                        description: Próximo número consecutivo disponible para nóminas electrónicas.
                        type: integer
                        example: 102
                      government_enabled_status:
                        description: Estado de habilitación de la empresa ante la DIAN para emitir nómina electrónica.
                        $ref: '#/components/schemas/ElectronicPayrollGovernmentStatus'
                      holidays:
                        description: Modo de reporte de vacaciones en la nómina electrónica ante la DIAN.
                        $ref: '#/components/schemas/ElectronicPayrollHolidays'
                      social_benefits:
                        description: Modo de reporte de prestaciones sociales en la nómina electrónica ante la DIAN.
                        $ref: '#/components/schemas/ElectronicPayrollSocialBenefits'
                      test_set_code:
                        description: Código del set de pruebas asignado por la DIAN para el proceso de habilitación. Es null si no se ha iniciado el proceso.
                        type:
                          - string
                          - 'null'
                        example: a70562e0-631e-4ceb-aa65-36887b57dc17
              example:
                data:
                  id: db80f609-8599-5355-b89d-fd6cfabd4b9f
                  company_id: 56e06d90-0244-5866-9b2a-af6df5418eee
                  active: true
                  company_certificate: false
                  certificate_file_name: null
                  canceled_consecutive_number: 29
                  consecutive_number: 102
                  government_enabled_status: unauthorized
                  holidays: holidays_at_the_time_of_payment
                  social_benefits: at_the_time_of_payment
                  test_set_code: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateElectronicPayrollConfiguration
      tags:
        - Configuración de nómina electrónica
      summary: Actualizar configuración de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Actualiza la configuración de nómina electrónica (DIAN) de la empresa. Permite activar la nómina electrónica, configurar el certificado digital, y definir el modo de reporte de vacaciones y prestaciones sociales.

        **¿Cuándo usar este endpoint?**

        * Activar o desactivar la generación de nómina electrónica para la empresa.
        * Cargar o actualizar el certificado digital propio para la firma de documentos DIAN.
        * Configurar cómo se reportan vacaciones y prestaciones sociales ante la DIAN.
        * Actualizar el código de set de pruebas durante el proceso de habilitación DIAN.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Certificado:** Si `company_certificate` es `true`, los campos `certificate_file`, `certificate_file_name` y `certificate_password` son obligatorios.
        * **Contraseña del certificado:** El valor de `certificate_password` debe enviarse codificado en Base64.
        * **Reenvío de set de pruebas:** Si se envía el mismo código existente en `test_set_code`, se reenvía la solicitud de habilitación al proveedor DIAN.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                configuration:
                  description: Parámetros de la configuración de nómina electrónica a actualizar.
                  type: object
                  properties:
                    active:
                      description: Indica si la nómina electrónica está activa para la empresa.
                      type: boolean
                      example: true
                    company_certificate:
                      description: Indica si la empresa usa su propio certificado digital. Si es true, los campos certificate_file, certificate_file_name y certificate_password son obligatorios.
                      type: boolean
                      example: false
                    certificate_file:
                      description: Contenido del certificado digital codificado en Base64. Requerido si company_certificate es true.
                      type: string
                      example: MTIzNDU2Nzg5...
                    certificate_file_name:
                      description: Nombre del archivo del certificado digital (con extensión .pfx). Requerido si company_certificate es true.
                      type: string
                      example: certificado_empresa.pfx
                    certificate_password:
                      description: Contraseña del certificado digital, codificada en Base64. Requerida si company_certificate es true.
                      type: string
                      example: MTIzNDU2Nzg5
                    consecutive_number:
                      description: Número consecutivo para la próxima nómina electrónica. Debe ser mayor al último consecutivo usado.
                      type: integer
                      example: 103
                    canceled_consecutive_number:
                      description: Número consecutivo para la próxima nómina electrónica anulada. Debe ser mayor al último consecutivo de anulación usado.
                      type: integer
                      example: 30
                    holidays:
                      description: Modo de reporte de vacaciones en la nómina electrónica ante la DIAN.
                      $ref: '#/components/schemas/ElectronicPayrollHolidays'
                    social_benefits:
                      description: Modo de reporte de prestaciones sociales en la nómina electrónica ante la DIAN.
                      $ref: '#/components/schemas/ElectronicPayrollSocialBenefits'
                    test_set_code:
                      description: Código del set de pruebas asignado por la DIAN. Si se envía el mismo código ya existente, reenvía la solicitud de habilitación al proveedor.
                      type: string
                      example: a70562e0-631e-4ceb-aa65-36887b57dc17
      responses:
        '202':
          description: Configuración actualizada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Configuración de nómina electrónica actualizada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de nómina electrónica en la base de datos.
                        type: string
                        example: 9fd3a6fa-42a9-5638-8881-350a980ccb16
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: f1c002bb-ab19-5777-8b15-1146af50ee17
                      active:
                        description: Indica si la nómina electrónica está activa para la empresa.
                        type: boolean
                        example: true
                      company_certificate:
                        description: Indica si la empresa usa su propio certificado digital para firmar las nóminas electrónicas.
                        type: boolean
                        example: false
                      certificate_file_name:
                        description: Nombre del archivo del certificado digital cargado. Es null si no se ha cargado un certificado propio.
                        type:
                          - string
                          - 'null'
                        example: certificado_empresa.pfx
                      canceled_consecutive_number:
                        description: Próximo número consecutivo disponible para nóminas electrónicas anuladas.
                        type: integer
                        example: 30
                      consecutive_number:
                        description: Próximo número consecutivo disponible para nóminas electrónicas.
                        type: integer
                        example: 103
                      government_enabled_status:
                        description: Estado de habilitación de la empresa ante la DIAN para emitir nómina electrónica.
                        $ref: '#/components/schemas/ElectronicPayrollGovernmentStatus'
                      holidays:
                        description: Modo de reporte de vacaciones en la nómina electrónica ante la DIAN.
                        $ref: '#/components/schemas/ElectronicPayrollHolidays'
                      social_benefits:
                        description: Modo de reporte de prestaciones sociales en la nómina electrónica ante la DIAN.
                        $ref: '#/components/schemas/ElectronicPayrollSocialBenefits'
                      test_set_code:
                        description: Código del set de pruebas asignado por la DIAN. Es null si no se ha configurado.
                        type:
                          - string
                          - 'null'
                        example: a70562e0-631e-4ceb-aa65-36887b57dc17
              example:
                data:
                  id: 9fd3a6fa-42a9-5638-8881-350a980ccb16
                  company_id: f1c002bb-ab19-5777-8b15-1146af50ee17
                  active: true
                  company_certificate: false
                  certificate_file_name: null
                  canceled_consecutive_number: 30
                  consecutive_number: 103
                  government_enabled_status: unauthorized
                  holidays: holidays_at_the_time_of_payment
                  social_benefits: at_the_time_of_payment
                  test_set_code: null
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Certificado requerido / Consecutivo inválido / Consecutivo de anulación inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Certificado requerido:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Certificado no puede estar en blanco.
                        object: certificate_file
                Consecutivo inválido:
                  value:
                    error:
                      - code: '2702'
                        index: 0
                        message: El consecutivo de nómina electrónica debe ser mayor a los usados anteriormente.
                        object: electronic_payroll_configuration
                Consecutivo de anulación inválido:
                  value:
                    error:
                      - code: '2706'
                        index: 0
                        message: El consecutivo de nómina electrónica cancelada debe ser mayor a uno usado anteriormente.
                        object: electronic_payroll_configuration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: df872419-e898-43e2-ae75-8e72cbf90f13
  /v1/{company_id}/electronic_payroll/configuration_options:
    get:
      operationId: showElectronicPayrollConfigurationOptions
      tags:
        - Configuración de nómina electrónica
      summary: Obtener opciones de configuración de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones disponibles para configurar el reporte de vacaciones y prestaciones sociales en la nómina electrónica ante la DIAN.

        **¿Cuándo usar este endpoint?**

        * Poblar los selectores de configuración antes de actualizar la nómina electrónica.
        * Mostrar al usuario las opciones disponibles con sus etiquetas traducidas al español.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Opciones de configuración de nómina electrónica
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones disponibles para la configuración de nómina electrónica.
                    type: object
                    properties:
                      holidays:
                        description: Opciones disponibles para el modo de reporte de vacaciones ante la DIAN.
                        type: array
                        items:
                          description: Opción de configuración con su etiqueta en español y su valor.
                          type: object
                          properties:
                            label:
                              description: Descripción legible de la opción en español.
                              type: string
                              example: Las vacaciones se incluyen al momento del pago.
                            value:
                              description: Valor del enum que se envía al actualizar la configuración.
                              $ref: '#/components/schemas/ElectronicPayrollHolidays'
                      social_benefits:
                        description: Opciones disponibles para el modo de reporte de prestaciones sociales ante la DIAN.
                        type: array
                        items:
                          description: Opción de configuración con su etiqueta en español y su valor.
                          type: object
                          properties:
                            label:
                              description: Descripción legible de la opción en español.
                              type: string
                              example: Las prestaciones sociales se incluyen al momento del pago.
                            value:
                              description: Valor del enum que se envía al actualizar la configuración.
                              $ref: '#/components/schemas/ElectronicPayrollSocialBenefits'
              example:
                data:
                  holidays:
                    - label: Las vacaciones se incluyen mensualmente de acuerdo al concepto de devengo.
                      value: holidays_provision_per_month
                    - label: Las vacaciones se incluyen al momento del pago.
                      value: holidays_at_the_time_of_payment
                    - label: Las vacaciones se reportan en diciembre si no se han pagado durante el año.
                      value: holidays_payment_in_year
                  social_benefits:
                    - label: Las prestaciones sociales se incluyen mensualmente de acuerdo al concepto de devengo.
                      value: provision_per_month
                    - label: Las prestaciones sociales se incluyen al momento del pago.
                      value: at_the_time_of_payment
                    - label: Las cesantías e intereses se reportan en diciembre si no se han pagado durante el año y la prima al momento del pago.
                      value: payment_in_year
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 08ae55ae-15e0-4782-bc5d-33bbe4a237c6
  /v1/{company_id}/electronic_payroll/government_files/{id}:
    get:
      operationId: showElectronicPayrollGovernmentFile
      tags:
        - Archivos XML y gobierno
      summary: Obtener archivo XML de gobierno
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo XML enviado a la DIAN para una nómina electrónica específica. Puede operar de forma síncrona (retorna la URL directamente) o asíncrona (encola la generación y notifica el resultado vía Firebase).

        **¿Cuándo usar este endpoint?**

        * Descargar el archivo XML de una nómina electrónica emitida para revisión o auditoría.
        * Obtener el archivo XML de una nómina rechazada para identificar errores de estructura.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Síncrono vs. asíncrono:** Si `async: true`, encola la generación y notifica el resultado vía Firebase en `electronic_payrolls/{id}/government_file`. Si `async: false` o no se envía, retorna la URL directamente.
        * **Disponibilidad:** Solo se puede descargar el archivo XML de nóminas electrónicas que hayan sido procesadas por la DIAN (emitidas, modificadas o rechazadas).
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo XML.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo XML enviado a la DIAN.
                        type: string
                        example: https://nominapp-api.s3.amazonaws.com/government_files/nomina_electronica_enero_2024.xml
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación indicando que la generación fue encolada. El resultado se notifica vía Firebase.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://nominapp-api.s3.amazonaws.com/government_files/nomina_electronica_enero_2024.xml
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: ID en proveedor inválido / Sin archivo descargable / Error del proveedor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                ID en proveedor inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Identificación en proveedor es inválido.
                        object: electronic_payroll
                Sin archivo descargable:
                  value:
                    error:
                      - code: '0612'
                        index: 0
                        message: La nómina electrónica no tiene archivo asociado.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: ef0db194-d9a2-4997-b4f7-906e7326667e
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
        schema:
          type: string
          example: a03b18ca-9e5b-53af-a907-ab9babdc02c3
  /v1/{company_id}/electronic_payroll/periods:
    get:
      operationId: indexElectronicPayrollPeriods
      tags:
        - Periodos de nómina electrónica
      summary: Listar periodos de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de periodos de nómina electrónica de la empresa, ordenados de más reciente a más antiguo. Incluye el conteo de nóminas electrónicas por estado para cada periodo.

        **¿Cuándo usar este endpoint?**

        * Consultar todos los periodos de nómina electrónica generados para la empresa.
        * Filtrar periodos por mes y año para navegar el historial.
        * Verificar el estado de transmisión de cada periodo antes de emitir nóminas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: month
          required: false
          description: Filtra los periodos por mes (número del 1 al 12).
          schema:
            type: integer
            minimum: 1
            maximum: 12
            example: 9
        - in: query
          name: year
          required: false
          description: Filtra los periodos por año.
          schema:
            type: integer
            example: 2024
      responses:
        '200':
          description: Listado de periodos de nómina electrónica
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de periodos de nómina electrónica de la empresa.
                    type: array
                    items:
                      description: Periodo de nómina electrónica con su estado y conteo de nóminas.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
                          type: string
                          example: 7a3f1c2d-44b8-5e9f-a012-bc3d4e5f6789
                        active:
                          description: Indica si el periodo está activo para transmitir nóminas electrónicas a la DIAN. Se activa a partir del día 20 del mes.
                          type: boolean
                          example: true
                        initial_day:
                          description: Fecha de inicio del periodo de nómina electrónica.
                          type: string
                          format: date
                          example: '2024-01-01'
                        end_day:
                          description: Fecha de fin del periodo de nómina electrónica.
                          type: string
                          format: date
                          example: '2024-01-31'
                        options:
                          description: Opciones de transmisión disponibles para el periodo.
                          type: object
                          properties:
                            authorized:
                              description: Indica si la empresa está autorizada por la DIAN para emitir nómina electrónica.
                              type: boolean
                              example: true
                            transmission_authorized:
                              description: Indica si el periodo puede transmitirse a la DIAN en este momento (empresa autorizada, periodo activo y con nóminas pendientes).
                              type: boolean
                              example: false
                            transmission_in_range:
                              description: Indica si la fecha actual está dentro del plazo legal para transmitir el periodo (10 días hábiles del mes siguiente).
                              type: boolean
                              example: true
                        electronic_payrolls_counter:
                          description: Conteo de nóminas electrónicas del periodo agrupadas por estado.
                          type: object
                          properties:
                            total:
                              description: Total de nóminas electrónicas actuales del periodo.
                              type: integer
                              example: 10
                            to_issue:
                              description: Nóminas electrónicas pendientes de emisión (total menos las procesadas o emitidas).
                              type: integer
                              example: 4
                            issued:
                              description: Nóminas electrónicas emitidas y aceptadas por la DIAN.
                              type: integer
                              example: 3
                            modified:
                              description: Nóminas electrónicas modificadas y aceptadas por la DIAN.
                              type: integer
                              example: 1
                            rejected:
                              description: Nóminas electrónicas rechazadas por la DIAN.
                              type: integer
                              example: 0
                            processing:
                              description: Nóminas electrónicas en proceso de validación por la DIAN.
                              type: integer
                              example: 2
                            pending:
                              description: Nóminas electrónicas pendientes de envío a la DIAN.
                              type: integer
                              example: 0
                            canceled:
                              description: Nóminas electrónicas anuladas ante la DIAN.
                              type: integer
                              example: 0
                            replaced:
                              description: Nóminas electrónicas reemplazadas por una versión más reciente.
                              type: integer
                              example: 0
                  filters:
                    description: Información de paginación y filtros aplicados a la consulta.
                    type: object
                    properties:
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de registros por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se aplicó búsqueda.
                        type: string
                        example: ''
                      total_records:
                        description: Total de periodos que coinciden con los filtros aplicados.
                        type: integer
                        example: 6
              examples:
                Con periodos:
                  value:
                    data:
                      - id: 7a3f1c2d-44b8-5e9f-a012-bc3d4e5f6789
                        active: true
                        initial_day: '2024-01-01'
                        end_day: '2024-01-31'
                        options:
                          authorized: true
                          transmission_authorized: false
                          transmission_in_range: true
                        electronic_payrolls_counter:
                          total: 10
                          to_issue: 4
                          issued: 3
                          modified: 1
                          rejected: 0
                          processing: 2
                          pending: 0
                          canceled: 0
                          replaced: 0
                    filters:
                      page: 1
                      per_page: 20
                      search: ''
                      total_records: 6
                Sin periodos:
                  value:
                    data: []
                    filters:
                      page: 1
                      per_page: 20
                      search: ''
                      total_records: 0
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createElectronicPayrollPeriod
      tags:
        - Periodos de nómina electrónica
      summary: Crear periodo de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Crea el siguiente periodo de nómina electrónica de la empresa. El sistema determina automáticamente el mes a generar basándose en los periodos ya existentes.

        **¿Cuándo usar este endpoint?**

        * Generar el periodo de nómina electrónica del mes que aún no ha sido creado.
        * Iniciar el proceso mensual de emisión de nóminas electrónicas ante la DIAN.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Requisito de habilitación:** La empresa debe estar autorizada por la DIAN antes de poder crear periodos de nómina electrónica.
        * **Fecha mínima:** No se pueden crear periodos anteriores al 1 de agosto de 2021.
        * **Periodos de nómina requeridos:** La empresa debe tener los periodos de nómina del mes correspondiente antes de crear el periodo electrónico.
      responses:
        '201':
          description: Periodo de nómina electrónica en proceso de creación
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que el periodo está siendo generado en segundo plano.
                        type: string
                        example: La información se agregó a la cola, en unos minutos verás el periodo creado.
              example:
                data:
                  message: La información se agregó a la cola, en unos minutos verás el periodo creado.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Empresa no habilitada / Fecha inválida / Periodos de nómina faltantes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Empresa no habilitada:
                  value:
                    error:
                      - code: '2502'
                        index: 0
                        message: La empresa debe estar habilitada para emitir nómina electrónica antes de crear un periodo.
                        object: special_period
                Fecha inválida:
                  value:
                    error:
                      - code: '2503'
                        index: 0
                        message: Los periodos de nómina electrónica no se pueden crear antes del 1 de agosto del 2021.
                        object: special_period
                Periodos de nómina faltantes:
                  value:
                    error:
                      - code: '2504'
                        index: 0
                        message: La empresa no tiene los periodos de nómina para generar este periodo de nómina electrónica.
                        object: special_period
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 9356ea34-1cef-4520-a082-fec88c629cc2
  /v1/{company_id}/electronic_payroll/periods/{id}:
    get:
      operationId: showElectronicPayrollPeriod
      tags:
        - Periodos de nómina electrónica
      summary: Obtener periodo de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de un periodo de nómina electrónica con el listado de nóminas vigentes, sus estados ante la DIAN y el conteo por estado.

        **¿Cuándo usar este endpoint?**

        * Consultar el detalle de un periodo para ver las nóminas y su estado de transmisión ante la DIAN.
        * Verificar qué nóminas fueron rechazadas por la DIAN y tienen errores de validación pendientes.
        * Filtrar las nóminas del periodo por estado para ver solo las rechazadas o pendientes.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Filtro de estados:** El parámetro `electronic_payroll_statuses` permite filtrar las nóminas por estado. Si no se envía, retorna todas las nóminas vigentes del periodo.
      parameters:
        - in: query
          name: electronic_payroll_statuses
          required: false
          description: |
            Filtra las nóminas electrónicas del periodo por estado ante la DIAN. Se pueden enviar múltiples valores.

            * `pending` — Pendiente de envío a la DIAN.
            * `processing` — En proceso de validación por la DIAN.
            * `issued` — Emitida y aceptada por la DIAN.
            * `modified` — Modificada y aceptada por la DIAN.
            * `rejected` — Rechazada por la DIAN.
            * `canceled` — Anulada ante la DIAN.
            * `replaced` — Reemplazada por una versión más reciente.
          schema:
            type: array
            items:
              type: string
              enum:
                - pending
                - processing
                - issued
                - modified
                - rejected
                - canceled
                - replaced
            example:
              - pending
              - rejected
      responses:
        '200':
          description: Detalle del periodo de nómina electrónica
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle del periodo con sus nóminas, contador de estados y periodos relacionados.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
                        type: string
                        example: b8b5d397-19a0-5504-90ee-ee0355df88f0
                      active:
                        description: Indica si el periodo está activo para transmitir nóminas electrónicas a la DIAN.
                        type: boolean
                        example: true
                      initial_day:
                        description: Fecha de inicio del periodo de nómina electrónica.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del periodo de nómina electrónica.
                        type: string
                        format: date
                        example: '2024-01-31'
                      options:
                        description: Opciones de transmisión disponibles para el periodo.
                        type: object
                        properties:
                          authorized:
                            description: Indica si la empresa está autorizada por la DIAN para emitir nómina electrónica.
                            type: boolean
                            example: true
                          transmission_authorized:
                            description: Indica si el periodo puede transmitirse a la DIAN en este momento.
                            type: boolean
                            example: false
                          transmission_in_range:
                            description: Indica si la fecha actual está dentro del plazo legal para transmitir el periodo.
                            type: boolean
                            example: true
                      electronic_payrolls_counter:
                        description: Conteo de nóminas electrónicas del periodo agrupadas por estado.
                        type: object
                        properties:
                          total:
                            description: Total de nóminas electrónicas vigentes del periodo.
                            type: integer
                            example: 5
                          to_issue:
                            description: Nóminas electrónicas pendientes de emisión.
                            type: integer
                            example: 2
                          issued:
                            description: Nóminas electrónicas emitidas y aceptadas por la DIAN.
                            type: integer
                            example: 2
                          modified:
                            description: Nóminas electrónicas modificadas y aceptadas por la DIAN.
                            type: integer
                            example: 0
                          rejected:
                            description: Nóminas electrónicas rechazadas por la DIAN.
                            type: integer
                            example: 1
                          processing:
                            description: Nóminas electrónicas en proceso de validación por la DIAN.
                            type: integer
                            example: 0
                          pending:
                            description: Nóminas electrónicas pendientes de envío a la DIAN.
                            type: integer
                            example: 1
                          canceled:
                            description: Nóminas electrónicas anuladas ante la DIAN.
                            type: integer
                            example: 0
                          replaced:
                            description: Nóminas electrónicas reemplazadas por una versión más reciente.
                            type: integer
                            example: 0
                      authorization_date:
                        description: Fecha en que la empresa fue autorizada por la DIAN para emitir nómina electrónica.
                        type: string
                        format: date
                        example: '2024-07-03'
                      electronic_payroll_social_benefit:
                        description: Modo de reporte de prestaciones sociales configurado para la nómina electrónica.
                        $ref: '#/components/schemas/ElectronicPayrollSocialBenefits'
                      electronic_payrolls:
                        description: Listado de nóminas electrónicas vigentes del periodo según el filtro de estados aplicado.
                        type: array
                        items:
                          description: Nómina electrónica con su estado y detalle de provisiones.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
                              type: string
                              example: 6f637089-05d0-5996-a1c4-7cb36564368c
                            cune:
                              description: Código Único de Nómina Electrónica asignado por la DIAN. Es null si aún no ha sido aceptada.
                              type:
                                - string
                                - 'null'
                              example: null
                            initial_day:
                              description: Fecha de inicio del periodo de la nómina electrónica.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de la nómina electrónica.
                              type: string
                              format: date
                              example: '2024-01-31'
                            incomes:
                              description: Total de ingresos salariales de la nómina en pesos colombianos.
                              type: integer
                              example: 1850000
                            bonus_incomes:
                              description: Total de ingresos no salariales (conceptos adicionales) en pesos colombianos.
                              type: integer
                              example: 0
                            deductions:
                              description: Total de deducciones de la nómina en pesos colombianos.
                              type: integer
                              example: 250000
                            payment:
                              description: Valor neto a pagar de la nómina en pesos colombianos.
                              type: integer
                              example: 1600000
                            status:
                              description: Estado actual de la nómina electrónica ante la DIAN.
                              type: string
                              example: issued
                            response_message:
                              description: Mensaje de respuesta recibido de la DIAN. Contiene el error si el estado es rechazado.
                              type: string
                              example: ''
                            error_messages:
                              description: Detalle de errores de validación retornados por la DIAN. Es null si no hay errores.
                              type:
                                - string
                                - 'null'
                              example: null
                            provisions:
                              description: Valores de provisiones sociales reportados en el XML de gobierno enviado a la DIAN.
                              type: object
                              properties:
                                enjoyed_days:
                                  description: Valor de vacaciones disfrutadas reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                                service_bonus:
                                  description: Valor de prima de servicios reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                                severance:
                                  description: Valor de cesantías reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                                severance_interests:
                                  description: Valor de intereses de cesantías reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                            worker:
                              description: Información básica de la persona a quien corresponde la nómina electrónica.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: María González
                                id_number:
                                  description: Número de documento de identificación de la persona.
                                  type: string
                                  example: '1023456789'
                                picture:
                                  description: URL de la foto de perfil de la persona. Es null si no tiene foto cargada.
                                  type:
                                    - string
                                    - 'null'
                                  example: null
                            options:
                              description: Acciones disponibles sobre la nómina electrónica según su estado actual.
                              type: object
                              properties:
                                to_issue:
                                  description: Indica si la nómina puede ser emitida o reenviada a la DIAN.
                                  type: boolean
                                  example: true
                                cancelable:
                                  description: Indica si la nómina puede ser anulada ante la DIAN.
                                  type: boolean
                                  example: false
                                download_files:
                                  description: Indica si los archivos XML de la nómina están disponibles para descarga.
                                  type: boolean
                                  example: false
                                show_errors:
                                  description: Indica si hay errores de gobierno disponibles para mostrar.
                                  type: boolean
                                  example: false
                      related_ep_periods:
                        description: Periodos de nómina electrónica relacionados (del mismo mes en frecuencia mixta o quincenal).
                        type: array
                        items:
                          description: Periodo de nómina electrónica relacionado.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al periodo relacionado en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            initial_day:
                              description: Fecha de inicio del periodo relacionado.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo relacionado.
                              type: string
                              format: date
                              example: '2024-01-15'
                      errors:
                        description: Nóminas electrónicas con errores de gobierno pendientes de corrección.
                        type: array
                        items:
                          description: Detalle de error de gobierno para una nómina electrónica.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) de la nómina electrónica con error.
                              type: string
                              example: 6f637089-05d0-5996-a1c4-7cb36564368c
                            initial_day:
                              description: Fecha de inicio del periodo de la nómina electrónica con error.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de la nómina electrónica con error.
                              type: string
                              format: date
                              example: '2024-01-31'
                            worker:
                              description: Información de la persona asociada a la nómina con error.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: María González
                            message:
                              description: Mensaje de error recibido de la DIAN.
                              type: object
                              properties:
                                error:
                                  description: Descripción del error retornado por la DIAN.
                                  type: string
                                  example: instance.governmentData.Periodo requires property "FechaIngreso"
                                details:
                                  description: Detalle adicional del error de validación. Es null si no hay detalle disponible.
                                  type:
                                    - string
                                    - 'null'
                                  example: null
              example:
                data:
                  id: b8b5d397-19a0-5504-90ee-ee0355df88f0
                  active: true
                  initial_day: '2024-01-01'
                  end_day: '2024-01-31'
                  options:
                    authorized: true
                    transmission_authorized: false
                    transmission_in_range: true
                  electronic_payrolls_counter:
                    total: 5
                    to_issue: 2
                    issued: 2
                    modified: 0
                    rejected: 1
                    processing: 0
                    pending: 1
                    canceled: 0
                    replaced: 0
                  authorization_date: '2024-07-03'
                  electronic_payroll_social_benefit: at_the_time_of_payment
                  electronic_payrolls:
                    - id: 6f637089-05d0-5996-a1c4-7cb36564368c
                      cune: null
                      initial_day: '2024-01-01'
                      end_day: '2024-01-31'
                      incomes: 1850000
                      bonus_incomes: 0
                      deductions: 250000
                      payment: 1600000
                      status: pending
                      response_message: ''
                      error_messages: null
                      provisions:
                        enjoyed_days: 0
                        service_bonus: 0
                        severance: 0
                        severance_interests: 0
                      worker:
                        id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        name: María González
                        id_number: '1023456789'
                        picture: null
                      options:
                        to_issue: true
                        cancelable: false
                        download_files: false
                        show_errors: false
                  related_ep_periods: []
                  errors: []
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: f351f609-fe97-4478-81e8-daeda1f38788
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
  /v1/{company_id}/electronic_payroll/periods/{period_id}/payrolls_to_issue:
    patch:
      operationId: updateElectronicPayrollPayrollsToIssue
      tags:
        - Emisión de nómina electrónica
      summary: Emitir nóminas electrónicas
      description: |
        **¿Qué hace este endpoint?**

        Transmite las nóminas electrónicas seleccionadas a la DIAN para su validación y emisión.

        **¿Cuándo usar este endpoint?**

        * Emitir nóminas electrónicas pendientes o rechazadas de un periodo ante la DIAN.
        * Reintentar la emisión de nóminas previamente rechazadas con correcciones aplicadas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Periodo activo:** Solo se pueden emitir nóminas de un periodo activo (a partir del día 20 del mes).
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                electronic_payroll_ids:
                  description: Lista de identificadores de las nóminas electrónicas a emitir. Si se omite o es null, se emiten todas las nóminas pendientes del periodo.
                  type:
                    - array
                    - 'null'
                  items:
                    description: Identificador único (ID) de una nómina electrónica.
                    type: string
                    example: 6f637089-05d0-5996-a1c4-7cb36564368c
                  example:
                    - 6f637089-05d0-5996-a1c4-7cb36564368c
      responses:
        '200':
          description: Transmisión encolada (modo asíncrono)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que la transmisión fue encolada. El resultado se notifica vía Firebase.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '202':
          description: Nóminas emitidas correctamente (modo síncrono)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Estado actualizado del periodo de nómina electrónica tras la transmisión.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
                        type: string
                        example: b8b5d397-19a0-5504-90ee-ee0355df88f0
                      active:
                        description: Indica si el periodo está activo para transmitir nóminas electrónicas a la DIAN.
                        type: boolean
                        example: true
                      initial_day:
                        description: Fecha de inicio del periodo de nómina electrónica.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del periodo de nómina electrónica.
                        type: string
                        format: date
                        example: '2024-01-31'
                      options:
                        description: Opciones de transmisión disponibles para el periodo.
                        type: object
                        properties:
                          authorized:
                            description: Indica si la empresa está autorizada por la DIAN para emitir nómina electrónica.
                            type: boolean
                            example: true
                          transmission_authorized:
                            description: Indica si el periodo puede transmitirse a la DIAN en este momento.
                            type: boolean
                            example: false
                          transmission_in_range:
                            description: Indica si la fecha actual está dentro del plazo legal para transmitir el periodo.
                            type: boolean
                            example: false
                      electronic_payrolls_counter:
                        description: Conteo de nóminas electrónicas del periodo agrupadas por estado.
                        type: object
                        properties:
                          total:
                            description: Total de nóminas electrónicas actuales del periodo.
                            type: integer
                            example: 2
                          to_issue:
                            description: Nóminas electrónicas pendientes de emisión.
                            type: integer
                            example: 1
                          issued:
                            description: Nóminas electrónicas emitidas y aceptadas por la DIAN.
                            type: integer
                            example: 1
                          modified:
                            description: Nóminas electrónicas modificadas y aceptadas por la DIAN.
                            type: integer
                            example: 0
                          rejected:
                            description: Nóminas electrónicas rechazadas por la DIAN.
                            type: integer
                            example: 0
                          processing:
                            description: Nóminas electrónicas en proceso de validación por la DIAN.
                            type: integer
                            example: 0
                          pending:
                            description: Nóminas electrónicas pendientes de envío a la DIAN.
                            type: integer
                            example: 0
                          canceled:
                            description: Nóminas electrónicas anuladas ante la DIAN.
                            type: integer
                            example: 0
                          replaced:
                            description: Nóminas electrónicas reemplazadas por una versión más reciente.
                            type: integer
                            example: 0
                      authorization_date:
                        description: Fecha en que la empresa fue autorizada por la DIAN para emitir nómina electrónica.
                        type: string
                        format: date
                        example: '2024-07-03'
                      electronic_payroll_social_benefit:
                        description: Modo de reporte de prestaciones sociales configurado para la nómina electrónica.
                        $ref: '#/components/schemas/ElectronicPayrollSocialBenefits'
                      electronic_payrolls:
                        description: Listado de nóminas electrónicas procesadas en esta transmisión.
                        type: array
                        items:
                          description: Nómina electrónica con su estado tras la transmisión a la DIAN.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
                              type: string
                              example: 6f637089-05d0-5996-a1c4-7cb36564368c
                            cune:
                              description: Código Único de Nómina Electrónica asignado por la DIAN. Es null si aún no ha sido aceptada.
                              type:
                                - string
                                - 'null'
                              example: null
                            initial_day:
                              description: Fecha de inicio del periodo de la nómina electrónica.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de la nómina electrónica.
                              type: string
                              format: date
                              example: '2024-01-31'
                            incomes:
                              description: Total de ingresos salariales de la nómina en pesos colombianos.
                              type: integer
                              example: 1850000
                            bonus_incomes:
                              description: Total de ingresos no salariales de la nómina en pesos colombianos.
                              type: integer
                              example: 0
                            deductions:
                              description: Total de deducciones de la nómina en pesos colombianos.
                              type: integer
                              example: 250000
                            payment:
                              description: Valor neto a pagar de la nómina en pesos colombianos.
                              type: integer
                              example: 1600000
                            status:
                              description: Estado actual de la nómina electrónica ante la DIAN.
                              type: string
                              example: issued
                            response_message:
                              description: Mensaje de respuesta recibido de la DIAN. Contiene el error si el estado es rechazado.
                              type: string
                              example: ''
                            error_messages:
                              description: Detalle de errores de validación retornados por la DIAN. Es null si no hay errores.
                              type:
                                - string
                                - 'null'
                              example: null
                            worker:
                              description: Información básica de la persona a quien corresponde la nómina electrónica.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: María González
                                id_number:
                                  description: Número de documento de identificación de la persona.
                                  type: string
                                  example: '1023456789'
                                picture:
                                  description: URL de la foto de perfil de la persona. Es null si no tiene foto cargada.
                                  type:
                                    - string
                                    - 'null'
                                  example: null
                            options:
                              description: Acciones disponibles sobre la nómina electrónica según su estado actual.
                              type: object
                              properties:
                                to_issue:
                                  description: Indica si la nómina puede ser emitida o reenviada a la DIAN.
                                  type: boolean
                                  example: false
                                cancelable:
                                  description: Indica si la nómina puede ser anulada ante la DIAN.
                                  type: boolean
                                  example: true
                                download_files:
                                  description: Indica si los archivos XML de la nómina están disponibles para descarga.
                                  type: boolean
                                  example: true
                                show_errors:
                                  description: Indica si hay errores de gobierno disponibles para mostrar.
                                  type: boolean
                                  example: false
                      related_ep_periods:
                        description: Periodos de nómina electrónica relacionados (del mismo mes en frecuencia mixta o quincenal).
                        type: array
                        items:
                          description: Periodo de nómina electrónica relacionado.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al periodo relacionado en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            initial_day:
                              description: Fecha de inicio del periodo relacionado.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo relacionado.
                              type: string
                              format: date
                              example: '2024-01-15'
                      errors:
                        description: Nóminas electrónicas con errores de gobierno pendientes de corrección.
                        type: array
                        items:
                          description: Detalle de error de gobierno para una nómina electrónica.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) de la nómina electrónica con error.
                              type: string
                              example: 6f637089-05d0-5996-a1c4-7cb36564368c
                            initial_day:
                              description: Fecha de inicio del periodo de la nómina electrónica con error.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de la nómina electrónica con error.
                              type: string
                              format: date
                              example: '2024-01-31'
                            worker:
                              description: Información de la persona asociada a la nómina con error.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: María González
                            message:
                              description: Mensaje de error recibido de la DIAN.
                              type: object
                              properties:
                                error:
                                  description: Descripción del error retornado por la DIAN.
                                  type: string
                                  example: instance.governmentData.Periodo requires property "FechaIngreso"
                                details:
                                  description: Detalle adicional del error de validación. Es null si no hay detalle disponible.
                                  type:
                                    - string
                                    - 'null'
                                  example: null
              example:
                data:
                  id: b8b5d397-19a0-5504-90ee-ee0355df88f0
                  active: true
                  initial_day: '2024-01-01'
                  end_day: '2024-01-31'
                  options:
                    authorized: true
                    transmission_authorized: false
                    transmission_in_range: false
                  electronic_payrolls_counter:
                    total: 2
                    to_issue: 1
                    issued: 1
                    modified: 0
                    rejected: 0
                    processing: 0
                    pending: 0
                    canceled: 0
                    replaced: 0
                  authorization_date: '2024-07-03'
                  electronic_payroll_social_benefit: at_the_time_of_payment
                  electronic_payrolls:
                    - id: 6f637089-05d0-5996-a1c4-7cb36564368c
                      cune: null
                      initial_day: '2024-01-01'
                      end_day: '2024-01-31'
                      incomes: 1850000
                      bonus_incomes: 0
                      deductions: 250000
                      payment: 1600000
                      status: issued
                      response_message: ''
                      error_messages: null
                      worker:
                        id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        name: María González
                        id_number: '1023456789'
                        picture: null
                      options:
                        to_issue: false
                        cancelable: true
                        download_files: true
                        show_errors: false
                  related_ep_periods: []
                  errors: []
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo no activo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '2501'
                    index: 0
                    message: Debes esperar hasta el 20 del mes para emitir la nómina electrónica.
                    object: special_period
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 99558269-9202-447e-9d58-9a41d34e0aaa
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
  /v1/{company_id}/electronic_payroll/periods/{period_id}/payslips:
    get:
      operationId: indexElectronicPayrollPayslips
      tags:
        - Colillas electrónicas
      summary: Generar colillas electrónicas del periodo
      description: |
        **¿Qué hace este endpoint?**

        Genera las colillas electrónicas de todas las nóminas emitidas del periodo. Según el formato solicitado, produce un archivo ZIP con colillas individuales o un PDF consolidado.

        **¿Cuándo usar este endpoint?**

        * Obtener todas las colillas electrónicas del periodo en un archivo ZIP con PDFs individuales.
        * Obtener un PDF consolidado con todas las colillas del periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Formato:** Si se envía `type=zip`, genera un archivo ZIP con las colillas individuales en PDF. Si se omite, genera un PDF consolidado.
      parameters:
        - in: query
          name: type
          required: false
          description: Formato del archivo a generar. Si es `zip`, genera un archivo ZIP con las colillas individuales. Si se omite, genera un PDF consolidado con todas las colillas del periodo.
          schema:
            type: string
            example: zip
      responses:
        '200':
          description: Generación de colillas encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que la generación de colillas está en proceso.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: d2bc3e5a-dc49-4160-8d01-6dedbba4c0c0
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
  /v1/{company_id}/electronic_payroll/periods/{period_id}/payslips/{id}:
    get:
      operationId: showElectronicPayrollPayslip
      tags:
        - Colillas electrónicas
      summary: Obtener colilla electrónica
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna la URL de descarga de la colilla electrónica en PDF para una nómina electrónica específica.

        **¿Cuándo usar este endpoint?**

        * Obtener el PDF de la colilla electrónica de una persona para un periodo determinado.
        * Permitir que el administrador descargue colillas individuales de nóminas emitidas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      responses:
        '200':
          description: URL de la colilla electrónica en PDF
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del archivo PDF con la colilla electrónica de la persona.
                    type: string
                    example: https://storage.example.com/payslips/colilla_enero_2024.pdf
              example:
                file: https://storage.example.com/payslips/colilla_enero_2024.pdf
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
        schema:
          type: string
          example: e8d0d6a2-8620-4347-a7fe-56cc1802dab5
  /v1/{company_id}/electronic_payroll/periods/{period_id}/period_payrolls_summary:
    get:
      operationId: showElectronicPayrollPeriodPayrollsSummary
      tags:
        - Resúmenes de nómina electrónica
      summary: Obtener resumen de nóminas del periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de nóminas electrónicas del periodo con el resumen de devengados, deducciones y pago neto de cada persona, junto con el detalle de cada concepto por fila.

        **¿Cuándo usar este endpoint?**

        * Mostrar la tabla resumen de nóminas electrónicas de un periodo con totales por persona.
        * Buscar nóminas de personas específicas dentro del periodo para revisión contable.
        * Paginar el listado de nóminas para cargar resultados progresivamente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Solo nóminas vigentes:** El listado incluye únicamente las nóminas electrónicas marcadas como actuales (`current: true`) del periodo.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Texto para filtrar nóminas por nombre de la persona.
          schema:
            type: string
            example: María González
      responses:
        '200':
          description: Resumen de nóminas del periodo
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado paginado de nóminas electrónicas con resumen de devengados, deducciones y pago por persona.
                    type: array
                    items:
                      description: Resumen de nómina electrónica de una persona en el periodo.
                      type: object
                      properties:
                        electronic_payroll_id:
                          description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
                          type: string
                          example: 6f637089-05d0-5996-a1c4-7cb36564368c
                        worker_id:
                          description: Identificador único (ID) asignado a la persona en la base de datos.
                          type: string
                          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        worker_name:
                          description: Nombre completo de la persona a quien corresponde la nómina electrónica.
                          type: string
                          example: María González
                        income:
                          description: Total de ingresos salariales de la nómina con su etiqueta de presentación.
                          type: object
                          properties:
                            label:
                              description: Etiqueta de presentación del total de devengados.
                              type: string
                              example: Devengados
                            value:
                              description: Valor total de devengados en pesos colombianos. Es null si no hay datos.
                              type:
                                - integer
                                - 'null'
                              example: 1850000
                        deductions:
                          description: Total de deducciones de la nómina con su etiqueta de presentación.
                          type: object
                          properties:
                            label:
                              description: Etiqueta de presentación del total de deducciones.
                              type: string
                              example: Deducciones
                            value:
                              description: Valor total de deducciones en pesos colombianos. Es null si no hay datos.
                              type:
                                - integer
                                - 'null'
                              example: 250000
                        worker_payment:
                          description: Pago neto a la persona con su etiqueta de presentación.
                          type: object
                          properties:
                            label:
                              description: Etiqueta de presentación del total a pagar.
                              type: string
                              example: Total pago
                            value:
                              description: Valor neto a pagar en pesos colombianos.
                              type: integer
                              example: 1600000
                        subRows:
                          description: Detalle fila a fila de conceptos de ingresos y deducciones de la nómina.
                          type: array
                          items:
                            description: Par de concepto de ingreso y deducción para una fila del detalle.
                            type: object
                            properties:
                              income:
                                description: Concepto de ingreso para esta fila. Todas las propiedades son null si no hay concepto en esta posición.
                                type: object
                                properties:
                                  label:
                                    description: Nombre del concepto de ingreso.
                                    type:
                                      - string
                                      - 'null'
                                    example: Salario básico
                                  value:
                                    description: Valor del concepto de ingreso en pesos colombianos. Es null si no hay concepto en esta posición.
                                    type:
                                      - integer
                                      - 'null'
                                    example: 1850000
                              deductions:
                                description: Concepto de deducción para esta fila. Todas las propiedades son null si no hay concepto en esta posición.
                                type: object
                                properties:
                                  label:
                                    description: Nombre del concepto de deducción.
                                    type:
                                      - string
                                      - 'null'
                                    example: Seguridad social
                                  value:
                                    description: Valor del concepto de deducción en pesos colombianos. Es null si no hay concepto en esta posición.
                                    type:
                                      - integer
                                      - 'null'
                                    example: 250000
                  filters:
                    description: Metadatos de paginación del resultado.
                    type: object
                    properties:
                      total_records:
                        description: Total de nóminas electrónicas vigentes en el periodo que coinciden con el filtro de búsqueda.
                        type: integer
                        example: 2
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de registros por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado al resultado.
                        type: string
                        example: ''
              example:
                data:
                  - electronic_payroll_id: 6f637089-05d0-5996-a1c4-7cb36564368c
                    worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                    worker_name: María González
                    income:
                      label: Devengados
                      value: 1850000
                    deductions:
                      label: Deducciones
                      value: 250000
                    worker_payment:
                      label: Total pago
                      value: 1600000
                    subRows:
                      - income:
                          label: Salario básico
                          value: 1850000
                        deductions:
                          label: Seguridad social
                          value: 250000
                  - electronic_payroll_id: a03b18ca-9e5b-53af-a907-ab9babdc02c3
                    worker_id: 6626a96f-32b2-5890-bc03-af9d8b2854f7
                    worker_name: Carlos Ramírez
                    income:
                      label: Devengados
                      value: 2500000
                    deductions:
                      label: Deducciones
                      value: 400000
                    worker_payment:
                      label: Total pago
                      value: 2100000
                    subRows:
                      - income:
                          label: Salario básico
                          value: 2500000
                        deductions:
                          label: Seguridad social
                          value: 400000
                filters:
                  total_records: 2
                  page: 1
                  per_page: 20
                  search: ''
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: a60f884d-a74b-4d7e-9b6c-98f0cb432780
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
  /v1/{company_id}/electronic_payroll/periods/{period_id}/workers/{worker_id}/payroll_histories:
    get:
      operationId: indexElectronicPayrollPayrollHistories
      tags:
        - Historial por persona NE
      summary: Listar historial de nóminas electrónicas de persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial paginado de nóminas electrónicas de una persona en un periodo, incluyendo versiones anteriores reemplazadas. La nómina vigente aparece primero, seguida del historial ordenado por fecha de envío descendente.

        **¿Cuándo usar este endpoint?**

        * Consultar todas las versiones de la nómina electrónica de una persona en un periodo (emitidas, anuladas, reemplazadas).
        * Verificar el estado de cada versión histórica junto con los mensajes de respuesta de la DIAN.
        * Filtrar el historial por estado para ver solo las nóminas rechazadas o anuladas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Orden:** La nómina vigente (`current: true`) aparece siempre primera; el resto se ordena por fecha de última actualización descendente.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: filter
          required: false
          description: Filtra el historial por estado de la nómina electrónica ante la DIAN.
          schema:
            type: string
            enum:
              - pending
              - processing
              - issued
              - modified
              - rejected
              - canceled
              - replaced
            example: rejected
      responses:
        '200':
          description: Historial de nóminas electrónicas de la persona en el periodo
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del periodo, la persona y el listado de nóminas electrónicas históricas.
                    type: object
                    properties:
                      period:
                        description: Información del periodo de nómina electrónica.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
                            type: string
                            example: b8b5d397-19a0-5504-90ee-ee0355df88f0
                          initial_day:
                            description: Fecha de inicio del periodo de nómina electrónica.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del periodo de nómina electrónica.
                            type: string
                            format: date
                            example: '2024-01-31'
                      worker:
                        description: Información básica de la persona consultada.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la persona en la base de datos.
                            type: string
                            example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          name:
                            description: Nombre de la persona.
                            type: string
                            example: María
                          last_name:
                            description: Apellido de la persona.
                            type: string
                            example: González
                          id_number:
                            description: Número de documento de identificación de la persona.
                            type: string
                            example: '1023456789'
                      electronic_payrolls:
                        description: Listado histórico de nóminas electrónicas de la persona en el periodo. La nómina vigente aparece primero.
                        type: array
                        items:
                          description: Nómina electrónica con su estado y detalle de provisiones.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
                              type: string
                              example: 6f637089-05d0-5996-a1c4-7cb36564368c
                            cune:
                              description: Código Único de Nómina Electrónica asignado por la DIAN. Es null si aún no ha sido aceptada.
                              type:
                                - string
                                - 'null'
                              example: null
                            initial_day:
                              description: Fecha de inicio del periodo de la nómina electrónica.
                              type:
                                - string
                                - 'null'
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del periodo de la nómina electrónica.
                              type:
                                - string
                                - 'null'
                              format: date
                              example: '2024-01-31'
                            incomes:
                              description: Total de ingresos salariales de la nómina en pesos colombianos.
                              type: integer
                              example: 1850000
                            bonus_incomes:
                              description: Total de ingresos no salariales (conceptos adicionales) en pesos colombianos.
                              type: integer
                              example: 0
                            deductions:
                              description: Total de deducciones de la nómina en pesos colombianos.
                              type: integer
                              example: 250000
                            payment:
                              description: Valor neto a pagar de la nómina en pesos colombianos.
                              type: integer
                              example: 1600000
                            status:
                              description: Estado actual de la nómina electrónica ante la DIAN.
                              type: string
                              example: issued
                            response_message:
                              description: Mensaje de respuesta recibido de la DIAN. Contiene el error si el estado es rechazado.
                              type:
                                - string
                                - 'null'
                              example: ''
                            error_messages:
                              description: Detalle de errores de validación retornados por la DIAN. Es null si no hay errores.
                              type:
                                - string
                                - 'null'
                              example: null
                            provisions:
                              description: Valores de provisiones sociales reportados en el XML de gobierno enviado a la DIAN.
                              type: object
                              properties:
                                enjoyed_days:
                                  description: Valor de vacaciones disfrutadas reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                                service_bonus:
                                  description: Valor de prima de servicios reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                                severance:
                                  description: Valor de cesantías reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                                severance_interests:
                                  description: Valor de intereses de cesantías reportado en el XML de la DIAN en pesos colombianos. Es 0 si no aplica.
                                  type: integer
                                  example: 0
                            worker:
                              description: Información básica de la persona a quien corresponde la nómina electrónica.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: María González
                                id_number:
                                  description: Número de documento de identificación de la persona.
                                  type: string
                                  example: '1023456789'
                                picture:
                                  description: URL de la foto de perfil de la persona. Es null si no tiene foto cargada.
                                  type:
                                    - string
                                    - 'null'
                                  example: null
                            options:
                              description: Acciones disponibles sobre la nómina electrónica según su estado actual.
                              type: object
                              properties:
                                to_issue:
                                  description: Indica si la nómina puede ser emitida o reenviada a la DIAN.
                                  type: boolean
                                  example: true
                                cancelable:
                                  description: Indica si la nómina puede ser anulada ante la DIAN.
                                  type: boolean
                                  example: false
                                download_files:
                                  description: Indica si los archivos XML de la nómina están disponibles para descarga.
                                  type: boolean
                                  example: true
                                show_errors:
                                  description: Indica si hay errores de gobierno disponibles para mostrar.
                                  type: boolean
                                  example: false
                  filters:
                    description: Metadatos de paginación del resultado.
                    type: object
                    properties:
                      total_records:
                        description: Total de nóminas electrónicas de la persona en el periodo (sin aplicar filtro de estado).
                        type: integer
                        example: 2
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de registros por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado. Es null en este endpoint (no se usa búsqueda por nombre).
                        type:
                          - string
                          - 'null'
                        example: null
              examples:
                Con historial:
                  value:
                    data:
                      period:
                        id: b8b5d397-19a0-5504-90ee-ee0355df88f0
                        initial_day: '2024-01-01'
                        end_day: '2024-01-31'
                      worker:
                        id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        name: María
                        last_name: González
                        id_number: '1023456789'
                      electronic_payrolls:
                        - id: 6f637089-05d0-5996-a1c4-7cb36564368c
                          cune: abc123def456
                          initial_day: '2024-01-01'
                          end_day: '2024-01-31'
                          incomes: 1850000
                          bonus_incomes: 0
                          deductions: 250000
                          payment: 1600000
                          status: issued
                          response_message: ''
                          error_messages: null
                          provisions:
                            enjoyed_days: 0
                            service_bonus: 0
                            severance: 0
                            severance_interests: 0
                          worker:
                            id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            name: María González
                            id_number: '1023456789'
                            picture: null
                          options:
                            to_issue: false
                            cancelable: true
                            download_files: true
                            show_errors: false
                        - id: 2c3cad38-cd4a-5952-8da9-d48a1b758bbc
                          cune: null
                          initial_day: '2024-01-01'
                          end_day: '2024-01-31'
                          incomes: 1850000
                          bonus_incomes: 0
                          deductions: 250000
                          payment: 1600000
                          status: replaced
                          response_message: ''
                          error_messages: null
                          provisions:
                            enjoyed_days: 0
                            service_bonus: 0
                            severance: 0
                            severance_interests: 0
                          worker:
                            id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            name: María González
                            id_number: '1023456789'
                            picture: null
                          options:
                            to_issue: false
                            cancelable: false
                            download_files: false
                            show_errors: false
                    filters:
                      total_records: 2
                      page: 1
                      per_page: 20
                      search: null
                Sin historial:
                  value:
                    data:
                      period:
                        id: b8b5d397-19a0-5504-90ee-ee0355df88f0
                        initial_day: '2024-01-01'
                        end_day: '2024-01-31'
                      worker:
                        id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        name: María
                        last_name: González
                        id_number: '1023456789'
                      electronic_payrolls: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 4688756e-c00c-447f-af4d-d786b0b4fcd7
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/electronic_payroll/summaries/{id}:
    get:
      operationId: showElectronicPayrollSummary
      tags:
        - Resúmenes de nómina electrónica
      summary: Obtener archivo de resumen de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo Excel de resumen de nómina electrónica para un periodo.

        **¿Cuándo usar este endpoint?**

        * Descargar el resumen consolidado de todas las nóminas electrónicas de un periodo en formato Excel.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta varía según el parámetro `async`:

            - **Archivo listo**: retorna el campo `file` con la URL de descarga del Excel.
            - **En proceso**: retorna el campo `message` con confirmación.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel con el resumen de nóminas electrónicas del periodo.
                        type: string
                        example: https://storage.example.com/electronic_payroll_summaries/resumen_nomina_electronica_enero_2024.xlsx
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación indicando que la generación del archivo está en proceso.
                            type: string
                            example: Procesando
              examples:
                Archivo listo:
                  value:
                    file: https://storage.example.com/electronic_payroll_summaries/resumen_nomina_electronica_enero_2024.xlsx
                En proceso:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: bc0d0bc2-bcf6-4b76-8340-820928a0c4c9
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al periodo de nómina electrónica en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
  /v1/{company_id}/exogenous_information:
    get:
      operationId: showExogenousInformation
      tags:
        - Información exógena
      summary: Obtener información exógena
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo Excel de información exógena de la empresa para un año fiscal.

        **¿Cuándo usar este endpoint?**

        * Obtener el reporte de información exógena de la empresa para presentarlo ante la DIAN.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `async`:

            - **`async: false`**: retorna el campo `file` con la URL de descarga del archivo generado.
            - **Sin `async` o `async: true`**: retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta síncrona con archivo Excel
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel de información exógena.
                        type: string
                        example: https://storage.aleluya.com/exogenous_information.xlsx
                  - type: object
                    description: Respuesta asíncrona
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de encolamiento del archivo.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/exogenous_information.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/history_logs:
    get:
      operationId: indexHistoryLogs
      tags:
        - Dashboard y métricas
      summary: Historial de acciones de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial de acciones realizadas en la empresa, con información sobre el usuario que ejecutó cada acción y un comentario descriptivo. Soporta búsqueda por correo electrónico del usuario.

        **¿Cuándo usar este endpoint?**

        * Auditar las acciones realizadas en la empresa por los usuarios.
        * Buscar las acciones de un usuario específico filtrando por su correo electrónico.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca registros de historial por comentario del log o correo electrónico del usuario que realizó la acción. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: contrato
      responses:
        '200':
          description: Acciones registradas / Sin acciones registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    description: Listado de registros de actividad de la empresa.
                    items:
                      type: object
                      properties:
                        created_at:
                          type: string
                          description: Fecha y hora en que se realizó la acción.
                          example: 2024-01-15 10:30:00 UTC
                        comment:
                          type: string
                          description: Descripción de la acción realizada.
                          example: Creó el contrato de Juan Pérez
                        email:
                          type: string
                          description: Correo electrónico del usuario que realizó la acción.
                          example: admin@empresa.com
                  filters:
                    type: object
                    description: Metadatos de paginación y filtros aplicados.
                    properties:
                      total_records:
                        type: integer
                        description: Número total de logs que coinciden con los filtros aplicados.
                        example: 45
                      page:
                        type: integer
                        description: Página actual de resultados.
                        example: 1
                      per_page:
                        type: integer
                        description: Número de resultados por página.
                        example: 20
                      search:
                        type: string
                        description: Término de búsqueda aplicado por correo electrónico. Retorna cadena vacía si no se filtró.
                        example: admin@empresa.com
              examples:
                Acciones registradas:
                  value:
                    data:
                      - created_at: 2024-01-15 10:30:00 UTC
                        comment: Creó el contrato de Juan Pérez
                        email: admin@empresa.com
                      - created_at: 2024-01-14 09:15:00 UTC
                        comment: Liquidó la nómina de enero
                        email: contador@empresa.com
                    filters:
                      total_records: 45
                      page: 1
                      per_page: 20
                      search: ''
                Sin acciones registradas:
                  value:
                    data: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
  /v1/{company_id}/holidays_summary_files:
    get:
      operationId: showHolidaysSummaryFile
      tags:
        - Historial de vacaciones
      summary: Obtener reporte de vacaciones
      description: |
        **¿Qué hace este endpoint?**

        Genera un archivo Excel con el historial de vacaciones de todas las personas de la empresa
        en un rango de fechas. El resultado se publica en Firebase cuando el archivo está listo.

        **¿Cuándo usar este endpoint?**

        * Exportar el historial completo de vacaciones de la empresa para un rango de fechas antes de una auditoría.
        * Obtener el resumen de vacaciones disfrutadas, acumuladas y pendientes de todas las personas en un periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Generación asíncrona:** Este endpoint siempre genera el archivo de forma asíncrona. El resultado se publica en Firebase; no retorna URL directa.
        * **Formato de fechas:** `initial_day` y `end_day` deben enviarse en formato `YYYY-MM-DD`. Si el formato es inválido o `initial_day` es posterior a `end_day`, retorna 422.
      parameters:
        - in: query
          required: true
          name: initial_day
          description: Fecha inicial del rango a consultar, en formato `YYYY-MM-DD`.
          schema:
            type: string
            format: date
            example: '2024-01-01'
        - in: query
          required: true
          name: end_day
          description: Fecha final del rango a consultar, en formato `YYYY-MM-DD`.
          schema:
            type: string
            format: date
            example: '2024-12-31'
      responses:
        '200':
          description: Archivo de vacaciones encolado para generación asíncrona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento del archivo.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Fechas inválidas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Formato fecha inicial inválido:
                  value:
                    error:
                      - code: '0409'
                        index: 0
                        message: El formato de la fecha inicial es inválido.
                        object: initial_day
                Formato fecha final inválido:
                  value:
                    error:
                      - code: '0410'
                        index: 0
                        message: El formato de la fecha final es inválido.
                        object: end_day
                Fecha inicial mayor a fecha final:
                  value:
                    error:
                      - code: '0401'
                        index: 0
                        message: La fecha inicial no puede ser mayor a la fecha final.
                        object: initial_day
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/import_workers:
    get:
      operationId: downloadImportWorkersTemplate
      tags:
        - Importación masiva
      summary: Descargar plantilla de importación
      description: |
        **¿Qué hace este endpoint?**

        Genera de forma asíncrona el archivo Excel de plantilla para importar o actualizar personas de la empresa. El archivo se entrega a través de Firebase una vez procesado.

        **¿Cuándo usar este endpoint?**

        * Obtener la plantilla actualizada con las áreas, sedes, cargos y centros de trabajo de la empresa antes de preparar una importación masiva.
        * Descargar el archivo base que luego se enviará mediante el endpoint de importación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Prerequisitos:** La empresa debe tener configuradas al menos un área, una sede, un cargo y un centro de trabajo. Si alguna de estas secciones está incompleta, el endpoint retorna 422.
        * **Entrega asíncrona:** El archivo no se retorna directamente. Se encola un trabajo en segundo plano y el resultado se publica en Firebase en la ruta `{company_id}/import_workers/download_file`.
      responses:
        '200':
          description: Generación del archivo encolada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje que indica que el archivo está siendo procesado.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Información obligatoria de empresa incompleta
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '1410'
                    index: 0
                    message: 'Para generar el archivo de importaciones, primero completa las siguientes secciones en el módulo Empresa: Área. Debes ingresar a cada sección y llenar la información requerida para continuar.'
                    object: company
    post:
      operationId: importWorkers
      tags:
        - Importación masiva
      summary: Importar personas desde archivo
      description: |
        **¿Qué hace este endpoint?**

        Recibe el archivo Excel de importación de personas y encola un trabajo en segundo plano para procesarlo. Crea o actualiza personas según los datos del archivo.

        **¿Cuándo usar este endpoint?**

        * Crear o actualizar múltiples personas de la empresa a partir del archivo Excel descargado con el endpoint de plantilla.
        * Realizar una importación masiva de personas luego de preparar el archivo con los datos correctos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Formato del archivo:** Solo se aceptan archivos `.xlsx`. El archivo debe ser el generado por el endpoint de descarga de plantilla de esta empresa. Archivos de formato inválido o con firma corrompida retornan 422.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  description: Archivo Excel (.xlsx) de importación de personas generado por la plantilla de la empresa.
                  type: string
                  format: binary
              required:
                - file
      responses:
        '200':
          description: Importación encolada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje que indica que el archivo está siendo procesado.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Archivo inválido / Firma del archivo corrompida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Archivo inválido:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
                Firma del archivo corrompida:
                  value:
                    error:
                      - code: '0609'
                        index: 0
                        message: Ocurrio un error. Intenta cargar nuevamente el archivo.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: e65cd3d7-85f2-473c-a560-8f6c22d7e0f0
  /v1/{company_id}/inbox_provider:
    post:
      operationId: createInboxProviderToken
      tags:
        - Notificaciones
      summary: Generar token de bandeja de notificaciones
      description: |
        **¿Qué hace este endpoint?**

        Genera un token de acceso temporal para que la empresa pueda leer y gestionar notificaciones
        en la bandeja de entrada del proveedor Courier. El token tiene una validez de 4 horas.

        **¿Cuándo usar este endpoint?**

        * Obtener el token necesario para inicializar el SDK de Courier en el cliente y mostrar la bandeja de notificaciones.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Expiración:** El token expira en 4 horas. Debe solicitarse uno nuevo cuando expire.
      responses:
        '200':
          description: Token generado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del token de acceso a la bandeja de notificaciones.
                    type: object
                    properties:
                      token:
                        description: Token JWT de acceso temporal para el proveedor de notificaciones. Válido por 4 horas.
                        type: string
                        example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6InVzZXJfaWQ6NTZlMDZkOTAtMDI0NC01ODY2LTliMmEtYWY2ZGY1NDE4ZWVlIGluYm94OnJlYWQ6bWVzc2FnZXMgaW5ib3g6d3JpdGU6ZXZlbnRzIn0.example
                    required:
                      - token
                required:
                  - data
              example:
                data:
                  token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6InVzZXJfaWQ6NTZlMDZkOTAtMDI0NC01ODY2LTliMmEtYWY2ZGY1NDE4ZWVlIGluYm94OnJlYWQ6bWVzc2FnZXMgaW5ib3g6d3JpdGU6ZXZlbnRzIn0.example
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 1e2d7d34-ddaa-4d87-a07a-956c8b5cf207
  /v1/{company_id}/integrations:
    get:
      operationId: indexIntegrations
      tags:
        - Integraciones generales
      summary: Listar integraciones de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Retorna las integraciones contables y de seguridad social disponibles para la empresa,
        agrupadas por tipo. Incluye tanto las integraciones ya configuradas como las disponibles
        para configurar según el distribuidor de la empresa.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado de las integraciones antes de activar o desactivar una.
        * Verificar qué proveedores tiene habilitados la empresa y cuáles están activos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Integraciones disponibles:** Los proveedores listados dependen del distribuidor de la empresa. No todas las empresas tienen acceso a todos los proveedores.
      responses:
        '200':
          description: Integraciones listadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Integraciones de la empresa agrupadas por tipo.
                    type: object
                    properties:
                      accounting_integrations:
                        description: Integraciones con proveedores de software contable habilitados para la empresa (Alegra, Siigo, PYA).
                        type: array
                        items:
                          description: Estado de una integración contable.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la integración en la base de datos. Null si la integración aún no ha sido configurada.
                              type:
                                - string
                                - 'null'
                              example: 0320c770-848d-4d71-a583-08c9346c670e
                            provider:
                              description: 'Proveedor de la integración contable. Valores posibles: alegra (Alegra), siigo (Siigo), pya (PYA).'
                              type: string
                              example: siigo
                            active:
                              description: Indica si la integración está activa y puede usarse para sincronizar datos.
                              type: boolean
                              example: true
                            inactivation_reason:
                              description: Mensaje explicando el motivo por el que la integración fue desactivada. Null si la integración está activa.
                              type:
                                - string
                                - 'null'
                              example: Las credenciales son incorrectas para la integración.
                            last_sync:
                              description: Fecha y hora de la última sincronización exitosa con el proveedor, en formato ISO 8601. Null si nunca se ha sincronizado.
                              type:
                                - string
                                - 'null'
                              format: date-time
                              example: '2024-01-15T10:30:00.000-05:00'
                      social_security_integrations:
                        description: Integraciones con operadores de seguridad social habilitados para la empresa (Aportes En Línea, Enlace Operativo).
                        type: array
                        items:
                          description: Estado de una integración de seguridad social.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la integración en la base de datos. Null si la integración aún no ha sido configurada.
                              type:
                                - string
                                - 'null'
                              example: d0b98c2c-3e2a-42fa-9dc1-813c8b30c42d
                            provider:
                              description: 'Proveedor de la integración de seguridad social. Valores posibles: aportes_en_linea (Aportes En Línea), enlace (Enlace Operativo).'
                              type: string
                              example: aportes_en_linea
                            active:
                              description: Indica si la integración está activa y puede usarse para enviar planillas.
                              type: boolean
                              example: false
                            inactivation_reason:
                              description: Mensaje explicando el motivo por el que la integración fue desactivada. Null si la integración está activa.
                              type:
                                - string
                                - 'null'
                              example: null
                            last_sync:
                              description: Fecha y hora de la última sincronización exitosa con el operador, en formato ISO 8601. Null si nunca se ha sincronizado.
                              type:
                                - string
                                - 'null'
                              format: date-time
                              example: '2024-01-15T10:30:00.000-05:00'
              example:
                data:
                  accounting_integrations:
                    - id: 0320c770-848d-4d71-a583-08c9346c670e
                      provider: siigo
                      active: true
                      inactivation_reason: null
                      last_sync: '2024-01-15T10:30:00.000-05:00'
                    - id: null
                      provider: alegra
                      active: false
                      inactivation_reason: null
                      last_sync: null
                  social_security_integrations:
                    - id: d0b98c2c-3e2a-42fa-9dc1-813c8b30c42d
                      provider: aportes_en_linea
                      active: false
                      inactivation_reason: null
                      last_sync: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateIntegration
      tags:
        - Integraciones generales
      summary: Crear, actualizar o eliminar integración
      description: |
        **¿Qué hace este endpoint?**

        Gestiona las integraciones contables y de seguridad social de la empresa en una sola operación.
        La acción se determina automáticamente según los campos enviados:

        * **Crear:** Con `provider` y credenciales (sin `id`) — crea y activa la integración.
        * **Actualizar:** Con `id`, `provider` y credenciales — actualiza las credenciales de una integración existente.
        * **Desactivar/Activar:** Con `id` y `active` — cambia el estado de la integración.
        * **Eliminar:** Solo con `id` — elimina la integración de la empresa.

        **¿Cuándo usar este endpoint?**

        * Conectar la empresa con un proveedor contable o de seguridad social por primera vez.
        * Actualizar las credenciales de una integración existente cuando cambian.
        * Desactivar temporalmente una integración sin eliminarla.
        * Eliminar una integración que ya no se necesita.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa (solo para crear o actualizar).
        * **`secret_token`:** Solo requerido para Enlace Operativo (`enlace`).
        * **`username` para PYA:** Para el proveedor `pya`, el `username` se asigna automáticamente con el email del usuario autenticado.
      requestBody:
        required: true
        description: Crear integración / Actualizar integración / Eliminar integración
        content:
          application/json:
            schema:
              type: object
              properties:
                integration:
                  description: Datos de la integración a gestionar.
                  type: object
                  properties:
                    id:
                      description: Identificador único (ID) de la integración. Requerido para actualizar o eliminar. Omitir para crear.
                      type: string
                      example: 1c1c6fcc-1909-460b-9816-0484a767aae7
                    provider:
                      description: 'Proveedor de la integración. Valores posibles para contabilidad: alegra (Alegra), siigo (Siigo), pya (PYA). Valores posibles para seguridad social: aportes_en_linea (Aportes En Línea), enlace (Enlace Operativo).'
                      type: string
                      example: siigo
                    active:
                      description: Estado de la integración. Enviar `false` para desactivarla, `true` para activarla.
                      type: boolean
                      example: true
                    username:
                      description: Nombre de usuario o email de la cuenta en el proveedor. No aplica para PYA (se asigna automáticamente).
                      type: string
                      example: usuario@empresa.com
                    token:
                      description: Token de autenticación de la cuenta en el proveedor.
                      type: string
                      example: 6e6a8ed88d8ca2b27c22
                    secret_token:
                      description: Token secreto de autenticación. Solo requerido para Enlace Operativo.
                      type: string
                      example: ae3ae31aekjlo12lsd1l
              required:
                - integration
            examples:
              Crear integración:
                value:
                  integration:
                    provider: siigo
                    username: usuario@empresa.com
                    token: 6e6a8ed88d8ca2b27c22
              Actualizar integración:
                value:
                  integration:
                    id: 1c1c6fcc-1909-460b-9816-0484a767aae7
                    provider: siigo
                    username: nuevo@empresa.com
                    token: nuevo_token_siigo
              Eliminar integración:
                value:
                  integration:
                    id: 1c1c6fcc-1909-460b-9816-0484a767aae7
      responses:
        '200':
          description: Integración eliminada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La integración ha sido eliminada.
              example:
                data:
                  message: La integración ha sido eliminada.
        '201':
          description: Integración creada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la integración recién creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la integración en la base de datos.
                        type: string
                        example: fa41cbf0-13d1-455d-b6de-354d48425874
                      provider:
                        description: Proveedor de la integración creada.
                        type: string
                        example: siigo
                      active:
                        description: Indica si la integración está activa.
                        type: boolean
                        example: true
                      inactivation_reason:
                        description: Motivo de inactivación. Null si la integración está activa.
                        type:
                          - string
                          - 'null'
                        example: null
                      last_sync:
                        description: Fecha y hora de la última sincronización, en formato ISO 8601. Null si nunca se ha sincronizado.
                        type:
                          - string
                          - 'null'
                        format: date-time
                        example: '2024-01-15T10:30:00.000-05:00'
              example:
                data:
                  id: fa41cbf0-13d1-455d-b6de-354d48425874
                  provider: siigo
                  active: true
                  inactivation_reason: null
                  last_sync: null
        '202':
          description: Integración actualizada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la integración.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la integración en la base de datos.
                        type: string
                        example: fa41cbf0-13d1-455d-b6de-354d48425874
                      provider:
                        description: Proveedor de la integración.
                        type: string
                        example: siigo
                      active:
                        description: Indica si la integración está activa.
                        type: boolean
                        example: true
                      inactivation_reason:
                        description: Motivo de inactivación. Null si la integración está activa.
                        type:
                          - string
                          - 'null'
                        example: null
                      last_sync:
                        description: Fecha y hora de la última sincronización, en formato ISO 8601. Null si nunca se ha sincronizado.
                        type:
                          - string
                          - 'null'
                        format: date-time
                        example: '2024-01-15T10:30:00.000-05:00'
              example:
                data:
                  id: fa41cbf0-13d1-455d-b6de-354d48425874
                  provider: siigo
                  active: true
                  inactivation_reason: null
                  last_sync: '2024-01-15T10:30:00.000-05:00'
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin acceso a la integración
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '1218'
                    index: 0
                    message: No tienes acceso a esta integración.
                    object: integration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/integrations/{integration_id}/integration_codes:
    put:
      operationId: updateIntegrationCode
      tags:
        - Integración con Alegra
      summary: Crear, actualizar o eliminar código de integración
      description: |
        **¿Qué hace este endpoint?**

        Gestiona el código contable de un concepto de nómina en la integración con Alegra.
        La acción se determina automáticamente según los campos enviados:

        * **Crear:** Sin `id` existente para el concepto — asigna el código y contrapartida al concepto.
        * **Actualizar:** Con código existente — actualiza el código y/o contrapartida del concepto.
        * **Eliminar:** Solo con `payroll_concept_id` (sin `code` ni `counterpart_code`) — elimina el código asignado al concepto.

        **¿Cuándo usar este endpoint?**

        * Asignar una cuenta contable de Alegra a un concepto de nómina por primera vez.
        * Cambiar la cuenta contable asignada a un concepto tras reorganizar el plan de cuentas.
        * Eliminar el código de un concepto para volver a dejarlo sin configurar.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Concepto válido:** El `payroll_concept_id` debe corresponder a un concepto de nómina válido para configuración contable. Si no existe o no es válido, retorna 404.
      requestBody:
        required: true
        description: Crear código / Actualizar código / Eliminar código
        content:
          application/json:
            schema:
              type: object
              properties:
                integration_code:
                  description: Datos del código de integración a gestionar.
                  type: object
                  required:
                    - payroll_concept_id
                  properties:
                    payroll_concept_id:
                      description: Identificador único (ID) del concepto de nómina al que se asigna el código contable.
                      type: string
                      example: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
                    code:
                      description: Identificador de la cuenta contable en Alegra a usar como código principal. Omitir para eliminar el código del concepto.
                      type: string
                      example: '5001'
                    counterpart_code:
                      description: Identificador de la cuenta contable en Alegra a usar como contrapartida. Omitir si la categoría no maneja contrapartida.
                      type: string
                      example: '5047'
              required:
                - integration_code
            examples:
              Crear código:
                value:
                  integration_code:
                    payroll_concept_id: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
                    code: '5001'
                    counterpart_code: '5047'
              Actualizar código:
                value:
                  integration_code:
                    payroll_concept_id: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
                    code: '5009'
              Eliminar código:
                value:
                  integration_code:
                    payroll_concept_id: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
      responses:
        '200':
          description: Código de integración eliminado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: El código personalizado ha sido eliminado.
              example:
                data:
                  message: El código personalizado ha sido eliminado.
        '201':
          description: Código de integración creado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del código de integración recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al código de integración en la base de datos.
                        type: string
                        example: 522d0143-922e-42f7-b09e-7735520ecf6a
                      integration_id:
                        description: Identificador único (ID) asignado a la integración con Alegra en la base de datos.
                        type: string
                        example: f2af04af-082c-58d3-9eb8-c388139b9c43
                      payroll_concept_id:
                        description: Identificador único (ID) del concepto de nómina al que se asignó el código.
                        type: string
                        example: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
                      payroll_concept_name:
                        description: Nombre del concepto de nómina.
                        type: string
                        example: Cesantías
                      integration_code:
                        description: Cuenta contable de Alegra asignada como código principal.
                        type: object
                        properties:
                          id:
                            description: Identificador de la cuenta en Alegra.
                            type: string
                            example: '5001'
                          name:
                            description: Nombre de la cuenta en Alegra.
                            type: string
                            example: Inversiones
                      counterpart_code:
                        description: Cuenta contable de Alegra asignada como contrapartida. Null si no aplica para esta categoría.
                        type:
                          - object
                          - 'null'
                        properties:
                          id:
                            description: Identificador de la cuenta de contrapartida en Alegra.
                            type: string
                            example: '5047'
                          name:
                            description: Nombre de la cuenta de contrapartida en Alegra.
                            type: string
                            example: Cuentas por pagar - proveedores
              example:
                data:
                  id: 522d0143-922e-42f7-b09e-7735520ecf6a
                  integration_id: f2af04af-082c-58d3-9eb8-c388139b9c43
                  payroll_concept_id: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
                  payroll_concept_name: Cesantías
                  integration_code:
                    id: '5001'
                    name: Inversiones
                  counterpart_code:
                    id: '5047'
                    name: Cuentas por pagar - proveedores
        '202':
          description: Código de integración actualizado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados del código de integración.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al código de integración en la base de datos.
                        type: string
                        example: 522d0143-922e-42f7-b09e-7735520ecf6a
                      integration_id:
                        description: Identificador único (ID) asignado a la integración con Alegra en la base de datos.
                        type: string
                        example: f2af04af-082c-58d3-9eb8-c388139b9c43
                      payroll_concept_id:
                        description: Identificador único (ID) del concepto de nómina al que se asignó el código.
                        type: string
                        example: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
                      payroll_concept_name:
                        description: Nombre del concepto de nómina.
                        type: string
                        example: Cesantías
                      integration_code:
                        description: Cuenta contable de Alegra asignada como código principal.
                        type: object
                        properties:
                          id:
                            description: Identificador de la cuenta en Alegra.
                            type: string
                            example: '5009'
                          name:
                            description: Nombre de la cuenta en Alegra.
                            type: string
                            example: Salarios prueba
                      counterpart_code:
                        description: Cuenta contable de Alegra asignada como contrapartida. Null si no aplica para esta categoría.
                        type:
                          - object
                          - 'null'
                        properties:
                          id:
                            description: Identificador de la cuenta de contrapartida en Alegra.
                            type: string
                            example: '5047'
                          name:
                            description: Nombre de la cuenta de contrapartida en Alegra.
                            type: string
                            example: Cuentas por pagar - proveedores
              example:
                data:
                  id: 522d0143-922e-42f7-b09e-7735520ecf6a
                  integration_id: f2af04af-082c-58d3-9eb8-c388139b9c43
                  payroll_concept_id: 1b3ab682-98f7-5bbd-8b7a-d92c79c16eb0
                  payroll_concept_name: Cesantías
                  integration_code:
                    id: '5009'
                    name: Salarios prueba
                  counterpart_code:
                    id: '5047'
                    name: Cuentas por pagar - proveedores
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Concepto de nómina no válido para configuración contable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: integration_id
        description: Identificador único (ID) asignado a la integración con Alegra en la base de datos.
        schema:
          type: string
          example: f2af04af-082c-58d3-9eb8-c388139b9c43
  /v1/{company_id}/invitation_mail:
    post:
      operationId: createInvitationMail
      tags:
        - Invitaciones
      summary: Enviar correo de invitación
      description: |
        **¿Qué hace este endpoint?**

        Dispara el envío del correo de invitación para un usuario que ya tiene vínculo con la empresa, usando el
        `user_access` correspondiente. La respuesta es un mensaje genérico de confirmación cuando la petición se
        procesa sin error de autorización o de búsqueda.

        **¿Cuándo usar este endpoint?**

        * Reenviar o generar el correo de invitación a un usuario administrador, contador o revisor ya asociado a la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario autenticado debe tener acceso a la empresa en `{company_id}` con permisos acordes a `authorize!` (p. ej. administrador o contador). La persona (worker), el revisor (reviewer) y el organizador externo no pueden llamar este endpoint.
        * **Usuario destino:** Debe existir como usuario de la empresa (`@company.users`); si el `id` no corresponde a alguien de la empresa, la API responde 404.
        * **Sin `user_access` activo:** Si por datos el usuario no tuviera acceso registrado en la empresa, el envío no se ejecuta; aun así puede retornarse 200 con el mensaje estándar — conviene validar en integraciones el flujo previo de alta de acceso.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user:
                  description: Identificador del usuario destinatario del correo de invitación.
                  type: object
                  properties:
                    id:
                      description: Identificador único (ID) del usuario en la base de datos.
                      type: string
                      example: 1b8872f0-43a7-4568-8c53-b9c2c5591016
                  required:
                    - id
              required:
                - user
            example:
              user:
                id: 1b8872f0-43a7-4568-8c53-b9c2c5591016
      responses:
        '200':
          description: Solicitud procesada; mensaje informativo según respuestas globales del API.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de envío (texto definido en respuestas de la aplicación).
                        type: string
                        example: Se ha enviado el correo
              example:
                data:
                  message: Se ha enviado el correo
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/loans/{id}:
    get:
      operationId: showLoan
      tags:
        - Préstamos
      summary: Obtener préstamo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de un préstamo específico junto con el historial paginado de pagos
        realizados en nómina.

        **¿Cuándo usar este endpoint?**

        * Consultar el saldo, cuota y estado de un préstamo antes de editarlo.
        * Revisar el historial de descuentos aplicados en nómina para un préstamo específico.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
      responses:
        '200':
          description: Detalle del préstamo retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al préstamo en la base de datos.
                        type: string
                        example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      name:
                        description: Nombre del concepto de nómina asociado al préstamo.
                        type: string
                        example: Préstamo personal
                      value:
                        description: Valor total del préstamo en pesos colombianos.
                        type: integer
                        example: 1000000
                      balance:
                        description: Saldo pendiente del préstamo en pesos colombianos.
                        type: integer
                        example: 600000
                      paid_value:
                        description: Valor pagado hasta la fecha en pesos colombianos.
                        type: integer
                        example: 400000
                      monthly_fee:
                        description: Cuota mensual del préstamo en pesos colombianos.
                        type: integer
                        example: 100000
                      pending_months:
                        description: Número de meses restantes para pagar el préstamo.
                        type: integer
                        example: 6
                      active:
                        description: Indica si el préstamo está activo y se descuenta en nómina.
                        type: boolean
                        example: true
                      period_apply:
                        $ref: '#/components/schemas/ApplicationPeriod'
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                        type: string
                        example: f6a7b8c9-d0e1-2345-fabc-345678901234
                      deleteable:
                        description: Indica si el préstamo puede ser eliminado.
                        type: boolean
                        example: false
                      payments:
                        description: Historial paginado de pagos del préstamo descontados en nómina.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al pago en la base de datos.
                              type: string
                              example: c3d4e5f6-a7b8-9012-cdef-012345678901
                            date:
                              description: Fecha del último día del periodo en que se aplicó el pago, en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-31'
                            value:
                              description: Valor descontado en ese periodo en pesos colombianos.
                              type: integer
                              example: 100000
                      filters:
                        description: Información de paginación del historial de pagos.
                        type: object
                        properties:
                          total_records:
                            description: Número total de pagos registrados para el préstamo.
                            type: integer
                            example: 4
                          page:
                            description: Número de página actual.
                            type: integer
                            example: 1
                          per_page:
                            description: Número máximo de pagos retornados por página.
                            type: integer
                            example: 20
                          search:
                            description: Texto de búsqueda aplicado.
                            type: string
                            example: ''
              example:
                data:
                  id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  name: Préstamo personal
                  value: 1000000
                  balance: 600000
                  paid_value: 400000
                  monthly_fee: 100000
                  pending_months: 6
                  active: true
                  period_apply: all_periods
                  payroll_concept_id: f6a7b8c9-d0e1-2345-fabc-345678901234
                  deleteable: false
                  payments:
                    - id: c3d4e5f6-a7b8-9012-cdef-012345678901
                      date: '2024-01-31'
                      value: 100000
                    - id: d4e5f6a7-b8c9-0123-defa-123456789012
                      date: '2024-02-28'
                      value: 100000
                  filters:
                    total_records: 4
                    page: 1
                    per_page: 20
                    search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al préstamo en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-f6a7-8901-bcde-f12345678901
  /v1/{company_id}/locations:
    get:
      operationId: indexLocations
      tags:
        - Sedes
      summary: Listar sedes
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de sedes registradas para la empresa, incluyendo información de ciudad, departamento y caja de compensación de cada sede.

        **¿Cuándo usar este endpoint?**

        * Consultar las sedes disponibles para asignar a una persona al crear o modificar su contrato.
        * Verificar qué sedes pueden eliminarse antes de reorganizar la estructura de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Sedes registradas / Sin sedes registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de sedes de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la sede en la base de datos.
                          type: string
                          example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                        name:
                          description: Nombre de la sede.
                          type: string
                          example: Sede Principal
                        electronic_payroll_prefix:
                          description: Prefijo utilizado en la nómina electrónica para identificar esta sede. Puede ser null si no ha sido configurado.
                          type:
                            - string
                            - 'null'
                          example: BOG01
                        address:
                          description: Dirección física de la sede. Puede ser null si no ha sido configurada.
                          type:
                            - string
                            - 'null'
                          example: Calle 100
                        department:
                          description: Departamento donde se ubica la sede.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) del departamento en la base de datos.
                              type: string
                              example: a7106ca0-b758-570a-8c24-b043a7ef08fb
                            name:
                              description: Nombre del departamento.
                              type: string
                              example: Cundinamarca
                        city:
                          description: Ciudad donde se ubica la sede.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) de la ciudad en la base de datos.
                              type: string
                              example: 2d16c1b8-1768-5504-993e-d2306280586b
                            name:
                              description: Nombre de la ciudad.
                              type: string
                              example: Bogotá, D.C.
                        compensation_fund:
                          description: Caja de compensación familiar asociada a la sede.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) de la caja de compensación en la base de datos.
                              type: string
                              example: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                            name:
                              description: Nombre de la caja de compensación.
                              type: string
                              example: Compensar
                        deleteable:
                          description: Indica si la sede puede eliminarse. Es `false` cuando tiene personas asociadas en su historial de cargo.
                          type: boolean
                          example: false
              examples:
                Sedes registradas:
                  value:
                    data:
                      - id: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                        name: Sede Principal
                        electronic_payroll_prefix: BOG01
                        address: Calle 100
                        department:
                          id: a7106ca0-b758-570a-8c24-b043a7ef08fb
                          name: Cundinamarca
                        city:
                          id: 2d16c1b8-1768-5504-993e-d2306280586b
                          name: Bogotá, D.C.
                        compensation_fund:
                          id: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                          name: Compensar
                        deleteable: false
                Sin sedes registradas:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createLocation
      tags:
        - Sedes
      summary: Crear sede
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva sede para la empresa con nombre, ciudad, dirección, caja de compensación y prefijo de nómina electrónica.

        **¿Cuándo usar este endpoint?**

        * Registrar una nueva sede o sucursal de la empresa para asignar personas y configurar su nómina.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Caja de compensación:** El `compensation_fund_id` debe corresponder a una caja de compensación válida; de lo contrario se retorna un error 404.
        * **Nombre:** Debe tener entre 2 y 40 caracteres, ser único en la empresa y solo puede contener letras, números y los caracteres `-_`.
        * **Prefijo de nómina electrónica:** Opcional. Solo puede contener letras y los caracteres `'-`. Máximo 9 caracteres.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                location:
                  type: object
                  description: Datos de la sede a crear.
                  properties:
                    name:
                      type: string
                      description: Nombre de la sede.
                      example: Sede Norte
                    city_id:
                      type: string
                      description: Identificador único (ID) de la ciudad donde se ubica la sede.
                      example: 2d16c1b8-1768-5504-993e-d2306280586b
                    address:
                      type: string
                      description: Dirección física de la sede.
                      example: Calle 100
                    compensation_fund_id:
                      type: string
                      description: Identificador único (ID) de la caja de compensación familiar.
                      example: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                    electronic_payroll_prefix:
                      type: string
                      description: Prefijo utilizado en la nómina electrónica para esta sede. Opcional. Solo puede contener letras y los caracteres `'-`. Máximo 9 caracteres.
                      example: NOR
                  required:
                    - name
                    - city_id
                    - address
                    - compensation_fund_id
              required:
                - location
      responses:
        '201':
          description: Sede creada correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la sede recién creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la sede en la base de datos.
                        type: string
                        example: bb78df98-ec51-4fb6-971f-fa6bf260aef1
                      name:
                        description: Nombre de la sede.
                        type: string
                        example: Sede Norte
                      electronic_payroll_prefix:
                        description: Prefijo utilizado en la nómina electrónica para esta sede. Puede ser null si no fue configurado.
                        type:
                          - string
                          - 'null'
                        example: NOR
                      address:
                        description: Dirección física de la sede.
                        type: string
                        example: Calle 100
                      department:
                        description: Departamento donde se ubica la sede.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del departamento en la base de datos.
                            type: string
                            example: a7106ca0-b758-570a-8c24-b043a7ef08fb
                          name:
                            description: Nombre del departamento.
                            type: string
                            example: Cundinamarca
                      city:
                        description: Ciudad donde se ubica la sede.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) de la ciudad en la base de datos.
                            type: string
                            example: 2d16c1b8-1768-5504-993e-d2306280586b
                          name:
                            description: Nombre de la ciudad.
                            type: string
                            example: Bogotá, D.C.
                      compensation_fund:
                        description: Caja de compensación familiar asociada a la sede.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) de la caja de compensación en la base de datos.
                            type: string
                            example: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                          name:
                            description: Nombre de la caja de compensación.
                            type: string
                            example: Compensar
                      deleteable:
                        description: Indica si la sede puede eliminarse. Es `false` cuando tiene personas asociadas en su historial de cargo.
                        type: boolean
                        example: true
              example:
                data:
                  id: bb78df98-ec51-4fb6-971f-fa6bf260aef1
                  name: Sede Norte
                  electronic_payroll_prefix: NOR
                  address: Calle 100
                  department:
                    id: a7106ca0-b758-570a-8c24-b043a7ef08fb
                    name: Cundinamarca
                  city:
                    id: 2d16c1b8-1768-5504-993e-d2306280586b
                    name: Bogotá, D.C.
                  compensation_fund:
                    id: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                    name: Compensar
                  deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre en blanco / Nombre demasiado corto / Nombre demasiado largo / Nombre duplicado / Nombre con caracteres inválidos / Ciudad requerida / Caja de compensación de otro departamento
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nombre en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Nombre demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre es demasiado corto (2 caracteres mínimo).
                        object: name
                Nombre demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Nombre es demasiado largo (40 caracteres máximo).
                        object: name
                Nombre duplicado:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Nombre ya está en uso.
                        object: name
                Nombre con caracteres inválidos:
                  value:
                    error:
                      - code: '0116'
                        index: 0
                        message: 'Nombre solo puede contener números, letras y los siguientes caracteres: ''-_''.'
                        object: name
                Ciudad requerida:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Ciudad no puede estar en blanco.
                        object: city
                Caja de compensación de otro departamento:
                  value:
                    error:
                      - code: '4101'
                        index: 0
                        message: La caja de compensación debe ser del mismo departamento que la ciudad de la sede.
                        object: location
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 9ad6d11c-ca5d-40a4-8927-9a150bb3b638
  /v1/{company_id}/locations/{id}:
    patch:
      operationId: updateLocation
      tags:
        - Sedes
      summary: Actualizar sede
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los datos de una sede existente de la empresa, incluyendo nombre, ciudad, dirección, caja de compensación y prefijo de nómina electrónica.

        **¿Cuándo usar este endpoint?**

        * Corregir la dirección o ciudad de una sede registrada incorrectamente.
        * Cambiar la caja de compensación asociada a la sede.
        * Actualizar el prefijo de nómina electrónica de la sede.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Caja de compensación:** El `compensation_fund_id` debe corresponder a una caja de compensación válida; de lo contrario se retorna un error 404.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                location:
                  type: object
                  description: Datos actualizados de la sede.
                  properties:
                    name:
                      type: string
                      description: Nombre de la sede. Debe tener entre 2 y 40 caracteres, ser único en la empresa y solo puede contener letras, números y los caracteres `-_`.
                      example: Sede Centro
                    city_id:
                      type: string
                      description: Identificador único (ID) de la ciudad donde se ubica la sede.
                      example: 2d16c1b8-1768-5504-993e-d2306280586b
                    address:
                      type: string
                      description: Dirección física de la sede.
                      example: Calle 100
                    compensation_fund_id:
                      type: string
                      description: Identificador único (ID) de la caja de compensación familiar.
                      example: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                    electronic_payroll_prefix:
                      type:
                        - string
                        - 'null'
                      description: Prefijo utilizado en la nómina electrónica para esta sede.
                      example: BOG01
                  required:
                    - name
                    - city_id
                    - address
                    - compensation_fund_id
                    - electronic_payroll_prefix
              required:
                - location
      responses:
        '202':
          description: Sede actualizada correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la sede.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la sede en la base de datos.
                        type: string
                        example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                      name:
                        description: Nombre de la sede.
                        type: string
                        example: Sede Centro
                      electronic_payroll_prefix:
                        description: Prefijo utilizado en la nómina electrónica para esta sede. Puede ser null si no fue configurado.
                        type:
                          - string
                          - 'null'
                        example: BOG01
                      address:
                        description: Dirección física de la sede.
                        type: string
                        example: Calle 100
                      department:
                        description: Departamento donde se ubica la sede.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del departamento en la base de datos.
                            type: string
                            example: a7106ca0-b758-570a-8c24-b043a7ef08fb
                          name:
                            description: Nombre del departamento.
                            type: string
                            example: Cundinamarca
                      city:
                        description: Ciudad donde se ubica la sede.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) de la ciudad en la base de datos.
                            type: string
                            example: 2d16c1b8-1768-5504-993e-d2306280586b
                          name:
                            description: Nombre de la ciudad.
                            type: string
                            example: Bogotá, D.C.
                      compensation_fund:
                        description: Caja de compensación familiar asociada a la sede.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) de la caja de compensación en la base de datos.
                            type: string
                            example: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                          name:
                            description: Nombre de la caja de compensación.
                            type: string
                            example: Compensar
                      deleteable:
                        description: Indica si la sede puede eliminarse. Es `false` cuando tiene personas asociadas en su historial de cargo.
                        type: boolean
                        example: false
              example:
                data:
                  id: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                  name: Sede Centro
                  electronic_payroll_prefix: BOG01
                  address: Calle 100
                  department:
                    id: a7106ca0-b758-570a-8c24-b043a7ef08fb
                    name: Cundinamarca
                  city:
                    id: 2d16c1b8-1768-5504-993e-d2306280586b
                    name: Bogotá, D.C.
                  compensation_fund:
                    id: dd9d5fcb-8c89-5744-a5e0-9381aa6f8d32
                    name: Compensar
                  deleteable: false
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre en blanco / Nombre demasiado corto / Nombre demasiado largo / Nombre duplicado / Nombre con caracteres inválidos / Caja de compensación de otro departamento
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nombre en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Nombre demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre es demasiado corto (2 caracteres mínimo).
                        object: name
                Nombre demasiado largo:
                  value:
                    error:
                      - code: '0202'
                        index: 0
                        message: Nombre es demasiado largo (40 caracteres máximo).
                        object: name
                Nombre duplicado:
                  value:
                    error:
                      - code: '0003'
                        index: 0
                        message: Nombre ya está en uso.
                        object: name
                Nombre con caracteres inválidos:
                  value:
                    error:
                      - code: '0116'
                        index: 0
                        message: 'Nombre solo puede contener números, letras y los siguientes caracteres: ''-_''.'
                        object: name
                Caja de compensación de otro departamento:
                  value:
                    error:
                      - code: '4101'
                        index: 0
                        message: La caja de compensación debe ser del mismo departamento que la ciudad de la sede.
                        object: location
    delete:
      operationId: destroyLocation
      tags:
        - Sedes
      summary: Eliminar sede
      description: |
        **¿Qué hace este endpoint?**

        Elimina de forma permanente una sede de la empresa.

        **¿Cuándo usar este endpoint?**

        * Dar de baja una sede que ya no está en uso y no tiene personas asociadas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Eliminación:** Solo se puede eliminar una sede si no tiene personas asociadas. El campo `deleteable` del listado indica si es eliminable.
      responses:
        '200':
          description: Sede eliminada correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de que la sede fue eliminada correctamente.
                        type: string
                        example: La sede ha sido eliminada.
              example:
                data:
                  message: La sede ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sede con personas asociadas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0504'
                    index: 0
                    message: Sede no se puede eliminar porque tiene personas asociadas.
                    object: location
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 9ad6d11c-ca5d-40a4-8927-9a150bb3b638
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la sede en la base de datos.
        schema:
          type: string
          example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
  /v1/{company_id}/novelties_summary_files:
    get:
      operationId: showNoveltiesSummaryFile
      tags:
        - Historial de novedades
      summary: Generar archivo de novedades
      description: |
        **¿Qué hace este endpoint?**

        Genera el archivo resumen de novedades de la empresa para un rango de fechas dado. El archivo incluye todas las novedades registradas en ese periodo.

        **¿Cuándo usar este endpoint?**

        * Descargar el resumen de novedades de un periodo específico para análisis o auditoría.
        * Generar el archivo de novedades de forma masiva en segundo plano cuando el volumen de datos es alto.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Rango de fechas obligatorio:** Los parámetros `initial_day` y `end_day` son requeridos y deben tener formato `YYYY-MM-DD`. La fecha inicial no puede ser mayor a la fecha final.
        * **Modo síncrono vs. asíncrono:** Sin `async` (o con `async: false`) retorna la URL del archivo directamente. Con `async: true` retorna `message: Procesando` y el archivo se publica en Firebase en la ruta `companies/{company_id}/novelties_summary_file`.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          name: initial_day
          required: true
          description: Fecha de inicio del rango del reporte, en formato `YYYY-MM-DD`.
          schema:
            type: string
            format: date
            example: '2024-01-01'
        - in: query
          name: end_day
          required: true
          description: Fecha de fin del rango del reporte, en formato `YYYY-MM-DD`. Debe ser mayor o igual a `initial_day`.
          schema:
            type: string
            format: date
            example: '2024-01-31'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo de resumen de novedades generado.
                        type: string
                        example: https://storage.googleapis.com/bucket/novelties_summary.xlsx
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje que indica que el archivo se está procesando en segundo plano.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.googleapis.com/bucket/novelties_summary.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Formato de fecha inválido / Fecha inicial mayor a fecha final
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Formato de fecha inicial inválido:
                  value:
                    error:
                      - code: '0409'
                        index: 0
                        message: El formato de la fecha inicial es inválido.
                        object: initial_day
                Formato de fecha final inválido:
                  value:
                    error:
                      - code: '0410'
                        index: 0
                        message: El formato de la fecha final es inválido.
                        object: end_day
                Fecha inicial mayor a fecha final:
                  value:
                    error:
                      - code: '0401'
                        index: 0
                        message: La fecha final debe ser mayor o igual a la fecha inicial.
                        object: end_day
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/novelty_requests:
    get:
      operationId: indexNoveltyRequests
      tags:
        - Solicitudes de novedades
      summary: Listar solicitudes de novedad
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de solicitudes de novedad de la empresa, con soporte de búsqueda
        por nombre de persona y filtro por estado.

        **¿Cuándo usar este endpoint?**

        * Obtener las solicitudes de novedad pendientes de aprobación para gestionarlas.
        * Filtrar solicitudes por estado para revisar las aprobadas o rechazadas.
        * Buscar las solicitudes de una persona específica por nombre.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: search
          description: Busca solicitudes por nombre de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
        - in: query
          required: false
          name: filter
          description: |
            Filtra las solicitudes por estado.

            * `pending` — Pendiente de revisión
            * `approved` — Aprobada
            * `rejected` — Rechazada
          schema:
            $ref: '#/components/schemas/NoveltyRequestStatus'
      responses:
        '200':
          description: Listado de solicitudes de novedad retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del listado de solicitudes de novedad.
                    type: object
                    properties:
                      novelty_requests:
                        description: Listado paginado de solicitudes de novedad.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            worker_id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            worker_name:
                              description: Nombre completo de la persona.
                              type: string
                              example: Juan Pérez
                            contract_category:
                              $ref: '#/components/schemas/ContractCategory'
                            initial_day:
                              description: Fecha de inicio de la novedad solicitada en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-15'
                            end_day:
                              description: Fecha de fin de la novedad solicitada en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-29'
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: e5f6a7b8-c9d0-1234-efab-234567890123
                            payroll_concept_name:
                              description: Nombre del concepto de novedad solicitado.
                              type: string
                              example: Vacaciones disfrutadas
                            comment:
                              description: Comentario del administrador sobre la solicitud.
                              type:
                                - string
                                - 'null'
                              example: null
                            days:
                              description: Número de días de la novedad solicitada.
                              type: integer
                              example: 15
                            status:
                              $ref: '#/components/schemas/NoveltyRequestStatus'
                            evidence:
                              description: URL del archivo de evidencia adjunto. Null si no hay evidencia.
                              type:
                                - string
                                - 'null'
                              example: null
                  filters:
                    description: Información de paginación y filtros aplicados.
                    type: object
                    properties:
                      total_records:
                        description: Número total de solicitudes que coinciden con los filtros aplicados.
                        type: integer
                        example: 3
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de solicitudes retornadas por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado.
                        type: string
                        example: ''
                      filter:
                        description: Filtro de estado aplicado. Null si no se aplicó filtro.
                        type:
                          - string
                          - 'null'
                        example: null
              examples:
                Con solicitudes:
                  value:
                    data:
                      novelty_requests:
                        - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name: Juan Pérez
                          contract_category: employee
                          initial_day: '2024-01-15'
                          end_day: '2024-01-29'
                          payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                          payroll_concept_name: Vacaciones disfrutadas
                          comment: null
                          days: 15
                          status: pending
                          evidence: null
                    filters:
                      total_records: 3
                      page: 1
                      per_page: 20
                      search: ''
                      filter: null
                Sin solicitudes:
                  value:
                    data:
                      novelty_requests: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
                      filter: null
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/novelty_requests/{id}:
    get:
      operationId: showNoveltyRequest
      tags:
        - Solicitudes de novedades
      summary: Obtener solicitud de novedad
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle completo de una solicitud de novedad específica de la empresa.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado, fechas y concepto de una solicitud antes de aprobarla o rechazarla.
        * Verificar el comentario o el archivo de evidencia adjunto a una solicitud.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Detalle de la solicitud de novedad retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle de la solicitud de novedad.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name:
                        description: Nombre completo de la persona que realizó la solicitud.
                        type: string
                        example: Juan Pérez
                      contract_category:
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio de la novedad en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-15'
                      end_day:
                        description: Fecha de fin de la novedad en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-29'
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                        type: string
                        example: e5f6a7b8-c9d0-1234-efab-234567890123
                      payroll_concept_name:
                        description: Nombre del concepto de nómina asociado a la novedad.
                        type: string
                        example: Vacaciones disfrutadas
                      comment:
                        description: Comentario del administrador sobre la decisión tomada. Puede ser null si no se registró ningún comentario.
                        type:
                          - string
                          - 'null'
                        example: Aprobado conforme a política de vacaciones.
                      days:
                        description: Número de días de la novedad solicitada.
                        type: integer
                        example: 15
                      status:
                        $ref: '#/components/schemas/NoveltyRequestStatus'
                      evidence:
                        description: URL del archivo de evidencia adjunto. Puede ser null si no se adjuntó ningún archivo.
                        type:
                          - string
                          - 'null'
                        example: https://storage.aleluya.com/novelty_requests/certificado.pdf
              example:
                data:
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  worker_name: Juan Pérez
                  contract_category: employee
                  initial_day: '2024-01-15'
                  end_day: '2024-01-29'
                  payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                  payroll_concept_name: Vacaciones disfrutadas
                  comment: null
                  days: 15
                  status: pending
                  evidence: null
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateNoveltyRequest
      tags:
        - Solicitudes de novedades
      summary: Actualizar solicitud de novedad
      description: |
        **¿Qué hace este endpoint?**

        Actualiza una solicitud de novedad existente. Permite aprobar, rechazar o modificar
        los datos de la solicitud desde el rol administrador.

        **¿Cuándo usar este endpoint?**

        * Aprobar o rechazar una solicitud de novedad pendiente enviando el campo `status`.
        * Agregar un comentario al aprobar o rechazar una solicitud.
        * Modificar las fechas o el concepto de una solicitud antes de aprobarla.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Solicitudes aprobadas:** Una solicitud aprobada no puede volver a modificarse directamente; al actualizarla se resetea a estado pendiente automáticamente.
      requestBody:
        required: true
        description: Aprobar solicitud / Rechazar solicitud / Modificar solicitud
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                status:
                  description: Nuevo estado de la solicitud.
                  $ref: '#/components/schemas/NoveltyRequestStatus'
                comment:
                  description: Comentario del administrador sobre la decisión.
                  type: string
                  example: Solicitud aprobada conforme a la política de vacaciones de la empresa.
                initial_day:
                  description: Nueva fecha de inicio de la novedad en formato `YYYY-MM-DD`.
                  type: string
                  format: date
                  example: '2024-01-15'
                end_day:
                  description: Nueva fecha de fin de la novedad en formato `YYYY-MM-DD`.
                  type: string
                  format: date
                  example: '2024-01-29'
                payroll_concept_id:
                  description: Identificador único (ID) asignado al concepto de novedad en la base de datos.
                  type: string
                  example: e5f6a7b8-c9d0-1234-efab-234567890123
                evidence:
                  description: Archivo PDF de soporte (máximo 1 MB). Enviar vacío para eliminar el archivo existente.
                  type: string
                  format: binary
            examples:
              Aprobar solicitud:
                value:
                  status: approved
                  comment: Solicitud aprobada conforme a la política de vacaciones de la empresa.
              Rechazar solicitud:
                value:
                  status: rejected
                  comment: No hay disponibilidad del equipo en las fechas solicitadas.
              Modificar solicitud:
                value:
                  initial_day: '2024-01-15'
                  end_day: '2024-01-29'
                  payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
      responses:
        '200':
          description: Solicitud de novedad actualizada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Solicitud de novedad con sus datos actualizados.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name:
                        description: Nombre completo de la persona que realizó la solicitud.
                        type: string
                        example: Juan Pérez
                      contract_category:
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio de la novedad en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-15'
                      end_day:
                        description: Fecha de fin de la novedad en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-29'
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                        type: string
                        example: e5f6a7b8-c9d0-1234-efab-234567890123
                      payroll_concept_name:
                        description: Nombre del concepto de nómina asociado a la novedad.
                        type: string
                        example: Vacaciones disfrutadas
                      comment:
                        description: Comentario del administrador sobre la decisión tomada. Puede ser null si no se registró ningún comentario.
                        type:
                          - string
                          - 'null'
                        example: Aprobado.
                      days:
                        description: Número de días de la novedad.
                        type: integer
                        example: 15
                      status:
                        $ref: '#/components/schemas/NoveltyRequestStatus'
                      evidence:
                        description: URL del archivo de evidencia adjunto. Puede ser null si no se adjuntó ningún archivo.
                        type:
                          - string
                          - 'null'
                        example: https://storage.aleluya.com/novelty_requests/certificado.pdf
              example:
                data:
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  worker_name: Juan Pérez
                  contract_category: employee
                  initial_day: '2024-01-15'
                  end_day: '2024-01-29'
                  payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                  payroll_concept_name: Vacaciones disfrutadas
                  comment: Aprobado.
                  days: 15
                  status: approved
                  evidence: null
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    delete:
      operationId: destroyNoveltyRequest
      tags:
        - Solicitudes de novedades
      summary: Eliminar solicitud de novedad
      description: |
        **¿Qué hace este endpoint?**

        Elimina permanentemente una solicitud de novedad de la empresa.

        **¿Cuándo usar este endpoint?**

        * Cancelar una solicitud de novedad que fue enviada por error.
        * Eliminar solicitudes pendientes antes de que sean revisadas por el administrador.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Solo pendientes:** Solo se pueden eliminar solicitudes en estado `pending`. Las solicitudes aprobadas o rechazadas no se pueden eliminar.
      responses:
        '200':
          description: Solicitud de novedad eliminada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La solicitud de tiempo fuera ha sido eliminada.
              example:
                data:
                  message: La solicitud de tiempo fuera ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: La solicitud no puede eliminarse porque no está en estado pendiente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0501'
                    index: 0
                    message: Solicitud de novedad no se puede eliminar.
                    object: novelty_request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
        schema:
          type: string
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
  /v1/{company_id}/payments:
    get:
      operationId: indexPayments
      tags:
        - Pagos
      summary: Listar pagos de suscripción
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial paginado de pagos de suscripción de la empresa, con el estado,
        valor, plan y método de pago de cada transacción.

        **¿Cuándo usar este endpoint?**

        * Consultar el historial de pagos de la suscripción de la empresa.
        * Verificar el estado de un pago específico (aprobado, rechazado, pendiente).
        * Determinar si un pago tiene factura asociada para ofrecer la opción de descarga.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca pagos por nombre del plan u otros campos de texto. La búsqueda es parcial. Retorna cadena vacía en `filters.search` si no se aplica.
          schema:
            type: string
            example: Nómina Holística
      responses:
        '200':
          description: Historial de pagos retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado paginado de pagos de suscripción de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al pago en la base de datos.
                          type: string
                          example: 20933cce-e403-5f47-82a8-006752caabd3
                        date:
                          description: Fecha de la transacción de pago en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-07-01'
                        plan:
                          description: Nombre del plan de suscripción asociado al pago.
                          type: string
                          example: Nómina Holística
                        value:
                          description: Valor total del pago en pesos colombianos.
                          type: integer
                          example: 299900
                        category:
                          description: 'Método de pago utilizado en la transacción. Ejemplos: `pse`, `credit_card`, `automatic_debit`.'
                          type: string
                          example: credit_card
                        status:
                          description: 'Estado actual del pago. Valores posibles: `approved` (aprobado), `rejected` (rechazado), `pending` (pendiente).'
                          type: string
                          example: approved
                        invoice:
                          description: Indica si el pago tiene una factura disponible para descarga.
                          type: boolean
                          example: true
                        invoice_id:
                          description: Identificador de la factura asociada al pago. Null si el pago no tiene factura.
                          type:
                            - integer
                            - 'null'
                          example: 1
                        paid_workers:
                          description: Número de personas incluidas en el pago de suscripción. Null si no aplica para el tipo de plan.
                          type:
                            - string
                            - 'null'
                          example: '10'
                        paid_extra_workers:
                          description: Número de personas adicionales sobre el límite del plan incluidas en el pago.
                          type: integer
                          example: 0
                        rejected_comment:
                          description: Motivo de rechazo del pago traducido al español. Null si el pago no fue rechazado.
                          type:
                            - string
                            - 'null'
                          example: La tarjeta no tiene fondos suficientes.
                      required:
                        - id
                        - date
                        - plan
                        - value
                        - category
                        - status
                        - invoice
                        - invoice_id
                        - paid_workers
                        - paid_extra_workers
                        - rejected_comment
                  filters:
                    description: Información de paginación aplicada a la consulta.
                    type: object
                    properties:
                      total_records:
                        description: Número total de pagos que coinciden con los filtros aplicados, sin paginar.
                        type: integer
                        example: 12
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de registros retornados por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se envió ningún término.
                        type: string
                    required:
                      - total_records
                      - page
                      - per_page
                      - search
                required:
                  - data
                  - filters
              example:
                data:
                  - id: 20933cce-e403-5f47-82a8-006752caabd3
                    date: '2024-07-01'
                    plan: Nómina Holística
                    value: 299900
                    category: credit_card
                    status: approved
                    invoice: true
                    invoice_id: 14
                    paid_workers: '5'
                    paid_extra_workers: 0
                    rejected_comment: null
                  - id: 07e23464-415a-55a8-89b3-ab5f6b3e382d
                    date: '2024-06-01'
                    plan: Nómina Holística
                    value: 299900
                    category: automatic_debit
                    status: rejected
                    invoice: false
                    invoice_id: null
                    paid_workers: '5'
                    paid_extra_workers: 0
                    rejected_comment: La cuenta especificada ha sido cerrada.
                filters:
                  total_records: 12
                  page: 1
                  per_page: 20
                  search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 1742e7bb-6e5c-45a7-b0ed-9698ce385653
  /v1/{company_id}/payments/automatic_debit:
    put:
      operationId: updateAutomaticDebit
      tags:
        - Pagos
      summary: Procesar pago por débito automático
      description: |
        **¿Qué hace este endpoint?**

        Procesa un pago de suscripción vía débito automático o registra/actualiza los datos de la
        cuenta de débito. El comportamiento varía según el campo `action` enviado:

        * **Registrar y cobrar:** Sin `action` — registra la cuenta de débito y procesa el cobro de la suscripción actual o el upgrade indicado.
        * **Reutilizar cuenta:** `action: reuse` — reutiliza los datos de cuenta ya registrados para procesar el cobro sin volver a capturar los datos bancarios.
        * **Actualizar cuenta:** `action: update` — actualiza los datos de la cuenta de débito automático sin procesar un cobro inmediato.

        **¿Cuándo usar este endpoint?**

        * Cobrar la suscripción mensual o anual de la empresa usando una cuenta bancaria de débito automático.
        * Agregar personas adicionales a un plan anual con cargo inmediato por débito.
        * Hacer upgrade de plan con pago proporcional al tiempo restante del periodo.
        * Registrar o actualizar los datos de cuenta de débito para cobros futuros recurrentes.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Cuenta conectada:** Para procesar cobros de personas extras o cambios de suscripción, la empresa debe tener una cuenta de débito automático activa y aprobada.
        * **Tipo de documento:** La empresa debe tener el tipo de documento configurado. Si no lo tiene, retorna 422.
      requestBody:
        required: true
        description: Pago de suscripción / Pago con reutilización de cuenta / Actualización de cuenta
        content:
          application/json:
            schema:
              type: object
              properties:
                payment_info:
                  description: Datos del pago o de la cuenta de débito automático a registrar.
                  type: object
                  properties:
                    action:
                      description: 'Acción a ejecutar. Valores posibles: `reuse` (reutilizar datos de cuenta existente para el cobro), `update` (actualizar datos de cuenta sin cobrar). Si no se envía, registra la cuenta y procesa el cobro.'
                      type: string
                      enum:
                        - reuse
                        - update
                      example: reuse
                    payment_type:
                      $ref: '#/components/schemas/SubscriptionPaymentType'
                    plan_id:
                      description: Identificador único (ID) del plan a pagar en la base de datos.
                      type: string
                      example: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers:
                      description: Número de personas a incluir en el cobro de la suscripción. Solo aplica para planes por persona.
                      type: integer
                      example: 10
                    extra_workers_number:
                      description: Número de personas adicionales a agregar en una suscripción anual con cargo proporcional inmediato. Solo aplica para suscripciones anuales.
                      type: integer
                      example: 3
                    account_number:
                      description: Número de la cuenta bancaria de débito automático. Obligatorio cuando `action` no es `reuse`.
                      type: string
                      example: '91251668936'
                    account_type:
                      description: Tipo de cuenta bancaria. Obligatorio cuando `action` no es `reuse`.
                      $ref: '#/components/schemas/AccountType'
                    bank:
                      description: Identificador único (ID) del banco de la cuenta de débito en la base de datos. Obligatorio cuando `action` no es `reuse`.
                      type: string
                      example: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    document_type:
                      description: Tipo de documento de identificación de la empresa. Obligatorio cuando `action` no es `reuse`.
                      $ref: '#/components/schemas/CompanyDocumentType'
                    id_number:
                      description: Número de identificación de la empresa. Obligatorio cuando `action` no es `reuse`.
                      type: string
                      example: '900123456'
                    subscription_to_pay:
                      description: Datos del cambio de suscripción (upgrade de plan o frecuencia) a aplicar junto con el cobro. Omitir si no hay cambio de suscripción.
                      type: object
                      properties:
                        plan_id:
                          description: Identificador único (ID) del nuevo plan al que se cambiará la empresa en la base de datos.
                          type: string
                          example: 2de57027-9a42-4b13-b27b-50d1a405dea5
                        subscription_type:
                          description: 'Nueva frecuencia de pago de la suscripción. Valores posibles: `month` (mensual), `year` (anual).'
                          type: string
                          enum:
                            - month
                            - year
                          example: year
              required:
                - payment_info
            examples:
              Pago de suscripción:
                value:
                  payment_info:
                    payment_type: month
                    account_type: savings_account
                    account_number: '91251668936'
                    bank: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    document_type: ni
                    id_number: '900123456'
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers: 10
              Pago con reutilización de cuenta:
                value:
                  payment_info:
                    action: reuse
                    payment_type: month
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers: 10
              Pago con upgrade de plan:
                value:
                  payment_info:
                    payment_type: year
                    account_type: savings_account
                    account_number: '91251668936'
                    bank: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    document_type: ni
                    id_number: '900123456'
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    extra_workers_number: 3
                    subscription_to_pay:
                      plan_id: 2de57027-9a42-4b13-b27b-50d1a405dea5
                      subscription_type: year
              Actualización de cuenta:
                value:
                  payment_info:
                    action: update
                    payment_type: month
                    account_type: savings_account
                    account_number: '91251668936'
                    bank: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    document_type: ni
                    id_number: '900123456'
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers: 10
      responses:
        '200':
          description: Cobro procesado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  payment_status:
                    description: Estado del cobro procesado en mayúsculas.
                    type: string
                    example: PENDING
                  plan_id:
                    description: Identificador único (ID) del plan asociado al cobro en la base de datos.
                    type: string
                    example: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                  value:
                    description: Valor total del cobro procesado en pesos colombianos.
                    type: integer
                    example: 299900
                  paid_workers:
                    description: Número total de personas incluidas en el cobro. Solo presente cuando el plan cobra por persona.
                    type: integer
                    example: 10
              example:
                payment_status: PENDING
                plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                value: 299900
                paid_workers: 10
        '202':
          description: Datos de cuenta de débito actualizados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la actualización de los datos de débito automático.
                        type: string
                        example: En pocos minutos, verás reflejado el cambio en la información de tu débito automático.
                required:
                  - data
              example:
                data:
                  message: En pocos minutos, verás reflejado el cambio en la información de tu débito automático.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin cuenta conectada / Cuenta en estado pendiente / Cuenta rechazada / Pago pendiente activo / Tipo de documento no configurado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Sin cuenta conectada:
                  value:
                    error:
                      - code: '1125'
                        index: 0
                        message: No fue posible crear el pago, debido a que no tienes una cuenta conectada.
                        object: payment
                Cuenta en estado pendiente:
                  value:
                    error:
                      - code: '1121'
                        index: 0
                        message: No fue posible crear el pago, debido a que tu cuenta se encuentra en estado pendiente.
                        object: payment
                Cuenta rechazada:
                  value:
                    error:
                      - code: '1122'
                        index: 0
                        message: No fue posible crear el pago, debido a que tu cuenta se encuentra en estado rechazada.
                        object: payment
                Pago pendiente activo:
                  value:
                    error:
                      - code: '1123'
                        index: 0
                        message: No puedes actualizar la información para debito automático, debido a que tienes un pago en estado pendiente.
                        object: payment
                Tipo de documento no configurado:
                  value:
                    error:
                      - code: '1126'
                        index: 0
                        message: Para proceder con la acción, debes ingresar el tipo de documento de la empresa.
                        object: company
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 78bb7a59-aa8c-4be1-aebd-5c7dc94ed448
  /v1/{company_id}/payments/credit_card:
    put:
      operationId: updateCreditCard
      tags:
        - Pagos
      summary: Procesar pago por tarjeta de crédito
      description: |
        **¿Qué hace este endpoint?**

        Procesa un pago de suscripción vía tarjeta de crédito o débito, o registra/actualiza los datos de la tarjeta. El comportamiento varía según el campo `action` enviado:

        * **Registrar y cobrar:** Sin `action` — registra los datos de tarjeta y procesa el cobro de la suscripción actual o el upgrade indicado.
        * **Reutilizar tarjeta:** `action: reuse` — reutiliza los datos de tarjeta ya registrados para procesar el cobro sin volver a capturar los datos de la tarjeta.
        * **Actualizar tarjeta:** `action: update` — actualiza los datos de la tarjeta sin procesar un cobro inmediato.

        **¿Cuándo usar este endpoint?**

        * Cobrar la suscripción mensual o anual de la empresa usando una tarjeta de crédito o débito.
        * Agregar personas adicionales a un plan anual con cargo inmediato por tarjeta.
        * Hacer upgrade de plan con pago proporcional al tiempo restante del periodo.
        * Registrar o actualizar los datos de tarjeta para cobros futuros recurrentes.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      requestBody:
        required: true
        description: Pago de suscripción / Pago con reutilización de tarjeta / Actualización de tarjeta
        content:
          application/json:
            schema:
              type: object
              properties:
                payment_info:
                  description: Datos del pago o de la tarjeta de crédito/débito a registrar.
                  type: object
                  properties:
                    action:
                      description: 'Acción a ejecutar. Valores posibles: `reuse` (reutilizar datos de tarjeta existente para el cobro), `update` (actualizar datos de tarjeta sin cobrar). Si no se envía, registra la tarjeta y procesa el cobro.'
                      type: string
                      enum:
                        - reuse
                        - update
                      example: reuse
                    payment_type:
                      $ref: '#/components/schemas/SubscriptionPaymentType'
                    plan_id:
                      description: Identificador único (ID) del plan a pagar en la base de datos.
                      type: string
                      example: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers:
                      description: Número de personas a incluir en el cobro de la suscripción. Solo aplica para planes por persona.
                      type: integer
                      example: 10
                    extra_workers_number:
                      description: Número de personas adicionales a agregar en una suscripción anual con cargo proporcional inmediato. Solo aplica para suscripciones anuales.
                      type: integer
                      example: 3
                    card_number:
                      description: Número de la tarjeta de crédito o débito. Obligatorio cuando `action` no es `reuse`.
                      type: string
                      example: '5368220692926495'
                    expiration_date:
                      description: Fecha de expiración de la tarjeta en formato MM/YY. Obligatorio cuando `action` no es `reuse`.
                      type: string
                      example: 06/27
                    security_code:
                      description: Código de seguridad (CVV) de la tarjeta. Obligatorio cuando `action` no es `reuse`.
                      type: string
                      example: '537'
                    payer_name:
                      description: Nombre completo del titular de la tarjeta. Obligatorio cuando `action` no es `reuse`.
                      type: string
                      example: Van Nelson
                    subscription_to_pay:
                      description: Datos del cambio de suscripción (upgrade de plan o frecuencia) a aplicar junto con el cobro. Omitir si no hay cambio de suscripción.
                      type: object
                      properties:
                        plan_id:
                          description: Identificador único (ID) del nuevo plan al que se cambiará la empresa en la base de datos.
                          type: string
                          example: 2de57027-9a42-4b13-b27b-50d1a405dea5
                        subscription_type:
                          description: 'Nueva frecuencia de pago de la suscripción. Valores posibles: `month` (mensual), `year` (anual).'
                          type: string
                          enum:
                            - month
                            - year
                          example: year
              required:
                - payment_info
            examples:
              Pago de suscripción:
                value:
                  payment_info:
                    payment_type: month
                    card_number: '5368220692926495'
                    expiration_date: 06/27
                    security_code: '537'
                    payer_name: Van Nelson
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers: 10
              Pago con reutilización de tarjeta:
                value:
                  payment_info:
                    action: reuse
                    payment_type: month
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers: 10
              Pago con upgrade de plan:
                value:
                  payment_info:
                    payment_type: year
                    card_number: '5368220692926495'
                    expiration_date: 06/27
                    security_code: '537'
                    payer_name: Van Nelson
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    extra_workers_number: 3
                    subscription_to_pay:
                      plan_id: 2de57027-9a42-4b13-b27b-50d1a405dea5
                      subscription_type: year
              Actualización de tarjeta:
                value:
                  payment_info:
                    action: update
                    payment_type: month
                    card_number: '4672226263441073'
                    expiration_date: 06/27
                    security_code: '513'
                    payer_name: Van Nelson
      responses:
        '200':
          description: Cobro procesado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  payment_status:
                    description: Estado del cobro procesado en mayúsculas.
                    type: string
                    example: APPROVED
                  plan_id:
                    description: Identificador único (ID) del plan asociado al cobro en la base de datos.
                    type: string
                    example: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                  value:
                    description: Valor total del cobro procesado en pesos colombianos.
                    type: integer
                    example: 299900
                  order_id:
                    description: Identificador de la orden en el proveedor de pagos.
                    type: string
                    example: '846696993'
                  transaction_id:
                    description: Identificador de la transacción en el proveedor de pagos.
                    type: string
                    example: 43669e18-a8e0-4d33-9e40-3e87a604818c
                  paid_workers:
                    description: Número total de personas incluidas en el cobro. Solo presente cuando el plan cobra por persona.
                    type: integer
                    example: 10
              example:
                payment_status: APPROVED
                plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                value: 299900
                order_id: '846696993'
                transaction_id: 43669e18-a8e0-4d33-9e40-3e87a604818c
                paid_workers: 10
        '202':
          description: Datos de tarjeta actualizados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la actualización de los datos de la tarjeta.
                        type: string
                        example: La tarjeta de crédito ha sido actualizada.
                required:
                  - data
              example:
                data:
                  message: La tarjeta de crédito ha sido actualizada.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Plan obligatorio / Número de tarjeta inválido / Tarjeta vencida / Valor mínimo PSE no alcanzado / Número de personas inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Plan obligatorio:
                  value:
                    error:
                      - code: '1107'
                        index: 0
                        message: El plan es obligatorio.
                        object: payment
                Número de tarjeta inválido:
                  value:
                    error:
                      - code: '1119'
                        index: 0
                        message: Número de tarjeta de crédito inválido
                        object: payment
                Tarjeta vencida:
                  value:
                    error:
                      - code: '1134'
                        index: 0
                        message: No se puede crear el pago. La tarjeta está vencida. Por favor, actualízala para continuar
                        object: payment
                Número de personas inválido:
                  value:
                    error:
                      - code: '1111'
                        index: 0
                        message: El número de personas a pagar no puede ser menor al número de personas en la aplicación.
                        object: payment
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 13406ee3-0a71-4e74-bb01-9b5e6c85a986
  /v1/{company_id}/payments/pse:
    post:
      operationId: createPsePayment
      tags:
        - Pagos
      summary: Procesar pago por PSE
      description: |
        **¿Qué hace este endpoint?**

        Inicia un pago de suscripción vía PSE y retorna la URL del banco a la que se debe redirigir al usuario para completar la transacción.

        **¿Cuándo usar este endpoint?**

        * Cobrar la suscripción mensual o anual de la empresa usando PSE.
        * Agregar personas adicionales a un plan anual con cargo proporcional inmediato.
        * Hacer upgrade de plan con pago proporcional al tiempo restante del periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Flujo de pago:** La respuesta incluye `bank_url` con la URL del banco. Una vez el usuario completa el pago en el banco, consultar el estado con `GET /v1/{company_id}/payments/pse`.
      requestBody:
        required: true
        description: Pago de suscripción / Personas extras en anualidad / Upgrade de plan
        content:
          application/json:
            schema:
              type: object
              properties:
                payment_info:
                  description: Datos del pago por PSE a procesar.
                  type: object
                  properties:
                    bank:
                      description: Identificador único (ID) del banco en la base de datos para realizar el pago PSE.
                      type: string
                      example: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    client_type:
                      description: 'Tipo de persona para PSE. Valores posibles: `N` (persona natural), `J` (persona jurídica).'
                      type: string
                      enum:
                        - 'N'
                        - J
                      example: 'N'
                    payment_type:
                      $ref: '#/components/schemas/SubscriptionPaymentType'
                    plan_id:
                      description: Identificador único (ID) del plan a pagar en la base de datos.
                      type: string
                      example: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers:
                      description: Número de personas a incluir en el cobro de la suscripción. Solo aplica para planes por persona.
                      type: integer
                      example: 10
                    extra_workers_number:
                      description: Número de personas adicionales a agregar en una suscripción anual con cargo proporcional inmediato. Solo aplica para suscripciones anuales.
                      type: integer
                      example: 3
                    subscription_to_pay:
                      description: Datos del cambio de suscripción (upgrade de plan o frecuencia) a aplicar junto con el cobro. Omitir si no hay cambio de suscripción.
                      type: object
                      properties:
                        plan_id:
                          description: Identificador único (ID) del nuevo plan al que se cambiará la empresa en la base de datos.
                          type: string
                          example: 2de57027-9a42-4b13-b27b-50d1a405dea5
                        subscription_type:
                          description: 'Nueva frecuencia de pago de la suscripción. Valores posibles: `month` (mensual), `year` (anual).'
                          type: string
                          enum:
                            - month
                            - year
                          example: year
              required:
                - payment_info
            examples:
              Pago de suscripción:
                value:
                  payment_info:
                    bank: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    client_type: 'N'
                    payment_type: month
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    paid_workers: 10
              Pago por personas extras en anualidad:
                value:
                  payment_info:
                    bank: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    client_type: 'N'
                    payment_type: year
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    extra_workers_number: 3
              Pago con upgrade de plan:
                value:
                  payment_info:
                    bank: 9e60110e-41b5-59c2-9ea7-d23bedc0e737
                    client_type: 'N'
                    payment_type: year
                    plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                    extra_workers_number: 3
                    subscription_to_pay:
                      plan_id: 2de57027-9a42-4b13-b27b-50d1a405dea5
                      subscription_type: year
      responses:
        '200':
          description: Pago PSE iniciado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  order_id:
                    description: Identificador de la orden en el proveedor de pagos.
                    type: string
                    example: '120488653'
                  transaction_id:
                    description: Identificador de la transacción en el proveedor de pagos.
                    type: string
                    example: 34216bd1-8a8a-4308-b690-6b847400301c
                  bank_url:
                    description: URL del banco a la que se debe redirigir al usuario para completar el pago PSE.
                    type: string
                    example: https://pse.example.com/pay/34216bd1
              example:
                order_id: '120488653'
                transaction_id: 34216bd1-8a8a-4308-b690-6b847400301c
                bank_url: https://pse.example.com/pay/34216bd1
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Plan obligatorio / Valor PSE inferior al mínimo / Número de personas inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Plan obligatorio:
                  value:
                    error:
                      - code: '1107'
                        index: 0
                        message: El plan es obligatorio.
                        object: payment
                Valor PSE inferior al mínimo:
                  value:
                    error:
                      - code: '1110'
                        index: 0
                        message: 'El valor del pago PSE es inferior al permitido (mínimo: $9.662)'
                        object: payment
                Número de personas inválido:
                  value:
                    error:
                      - code: '1111'
                        index: 0
                        message: El número de personas a pagar no puede ser menor al número de personas en la aplicación.
                        object: payment
    get:
      operationId: showPsePayment
      tags:
        - Pagos
      summary: Obtener resultado de pago PSE
      description: |
        **¿Qué hace este endpoint?**

        Consulta el estado de un pago PSE previamente iniciado y retorna el resultado de la transacción. El código HTTP de respuesta varía según el estado: 200 si el pago fue aprobado, 202 si aún está pendiente, o 422 si fue rechazado.

        **¿Cuándo usar este endpoint?**

        * Consultar el resultado de una transacción PSE tras completar el flujo de redirección al portal bancario.
        * Determinar si la suscripción fue activada o si el pago quedó pendiente de procesamiento.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      responses:
        '200':
          description: Pago aprobado
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    description: Mensaje de confirmación del estado del pago.
                    type: string
                    example: Pago exitoso
                  paid_workers:
                    description: Número total de personas incluidas en el cobro. Null si el plan no cobra por persona.
                    type:
                      - integer
                      - 'null'
                    example: 10
                  payment_status:
                    description: Estado actual del pago en mayúsculas.
                    type: string
                    example: APPROVED
                  payment_type:
                    description: 'Frecuencia de pago de la suscripción cobrada. Valores posibles: `month` (mensual), `year` (anual).'
                    type: string
                    example: month
                  plan_id:
                    description: Identificador único (ID) del plan asociado al cobro en la base de datos.
                    type: string
                    example: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                  plan_name:
                    description: Nombre del plan de suscripción cobrado.
                    type: string
                    example: Nómina Holística
                  value:
                    description: Valor total del cobro en pesos colombianos.
                    type: integer
                    example: 299900
                  subscription_type_change:
                    description: Indica si el pago incluyó un cambio en la frecuencia de suscripción de la empresa.
                    type: boolean
                    example: false
              example:
                message: Pago exitoso
                paid_workers: 10
                payment_status: APPROVED
                payment_type: month
                plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                plan_name: Nómina Holística
                value: 299900
                subscription_type_change: false
        '202':
          description: Pago pendiente de procesamiento
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    description: Mensaje informativo sobre el estado pendiente del pago.
                    type: string
                    example: El pago se encuentra en proceso
                  paid_workers:
                    description: Número total de personas incluidas en el cobro. Null si el plan no cobra por persona.
                    type:
                      - integer
                      - 'null'
                    example: 10
                  payment_status:
                    description: Estado actual del pago en mayúsculas.
                    type: string
                    example: PENDING
                  payment_type:
                    description: 'Frecuencia de pago de la suscripción cobrada. Valores posibles: `month` (mensual), `year` (anual).'
                    type: string
                    example: month
                  plan_id:
                    description: Identificador único (ID) del plan asociado al cobro en la base de datos.
                    type: string
                    example: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                  plan_name:
                    description: Nombre del plan de suscripción cobrado.
                    type: string
                    example: Nómina Holística
                  value:
                    description: Valor total del cobro en pesos colombianos.
                    type: integer
                    example: 299900
                  subscription_type_change:
                    description: Indica si el pago incluyó un cambio en la frecuencia de suscripción de la empresa.
                    type: boolean
                    example: false
              example:
                message: El pago se encuentra en proceso
                paid_workers: 10
                payment_status: PENDING
                payment_type: month
                plan_id: 9ef307fa-af64-4831-83a3-cf4d0ef3e7e5
                plan_name: Nómina Holística
                value: 299900
                subscription_type_change: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 247d21fc-1638-4b83-87c7-bf673cf594f8
  /v1/{company_id}/payments/{payment_id}/send_invoice:
    post:
      operationId: sendInvoice
      tags:
        - Facturación
      summary: Enviar factura de pago por correo
      description: |
        **¿Qué hace este endpoint?**

        Envía la factura asociada a un pago de suscripción al correo electrónico de facturación registrado para la empresa.

        **¿Cuándo usar este endpoint?**

        * Reenviar la factura de un pago al correo cuando el usuario no la recibió originalmente.
        * Obtener una copia de la factura de un pago aprobado.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Factura requerida:** El pago especificado en `{payment_id}` debe tener una factura asociada. Si no la tiene, retorna 422.
      responses:
        '200':
          description: Factura enviada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del envío de la factura.
                        type: string
                        example: En pocos minutos tu factura será enviada a tu correo.
                required:
                  - data
              example:
                data:
                  message: En pocos minutos tu factura será enviada a tu correo.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Pago sin factura asociada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '1103'
                    index: 0
                    message: El pago no tiene factura.
                    object: payment
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: a1fa645d-cda3-4d24-a262-7876d2fd8745
      - in: path
        required: true
        name: payment_id
        description: Identificador único (ID) asignado al pago en la base de datos.
        schema:
          type: string
          example: 20933cce-e403-5f47-82a8-006752caabd3
  /v1/{company_id}/payroll_concepts:
    get:
      operationId: indexPayrollConcepts
      tags:
        - Conceptos de nómina
      summary: Listar conceptos de nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna los conceptos de nómina de la empresa disponibles para una categoría específica.
        Para las categorías `overtime` y `novelties`, los conceptos se retornan agrupados en
        subcategorías; para las demás, se retorna un arreglo plano.

        **¿Cuándo usar este endpoint?**

        * Obtener los conceptos disponibles de horas extras o recargos para agregar a una nómina (`category: overtime`).
        * Consultar los conceptos de novedades (vacaciones, incapacidades, licencias) disponibles para un contrato (`category: novelties`).
        * Listar los conceptos de ingresos no salariales, deducciones u otras categorías de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Estructura de respuesta variable por categoría:** La categoría horas extras retorna un objeto con tres grupos (horas extras, recargos y otros); la categoría novedades retorna un objeto con tres grupos (vacaciones, incapacidades y licencias); las demás categorías retornan un arreglo plano de conceptos.
        * **Filtro por periodo en horas extras:** El parámetro `period_id` filtra los conceptos de horas extras según la vigencia configurada hasta la fecha final del periodo indicado.
        * **Filtros para novedades:** Los parámetros `contract_category` y `novelty_initial_day` filtran los conceptos disponibles según la categoría del contrato y la fecha de inicio de la novedad.
      parameters:
        - in: query
          required: false
          name: category
          description: Categoría de conceptos a consultar.
          schema:
            type: string
            enum:
              - overtime
              - novelties
              - non_salary_income
              - occasional_non_salary_income
              - salary_income
              - deductions
              - loan
            example: overtime
        - in: query
          required: false
          name: period_id
          description: Identificador único (ID) del periodo. Requerido para filtrar conceptos de horas extras por vigencia.
          schema:
            type: string
            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
        - in: query
          required: false
          name: contract_category
          description: Filtra los conceptos de novedades disponibles para el tipo de contrato.
          schema:
            $ref: '#/components/schemas/ContractCategory'
        - in: query
          required: false
          name: novelty_initial_day
          description: Fecha de inicio de la novedad en formato `YYYY-MM-DD`. Filtra los conceptos de novedades según las leyes vigentes en esa fecha.
          schema:
            type: string
            format: date
            example: '2024-01-05'
      responses:
        '200':
          description: |
            La estructura de `data` depende de la categoría consultada:

            - **Horas extras** (`overtime`): objeto con tres grupos de conceptos — horas extras (`extra_hours`), recargos (`surcharges`) y otros (`others`).
            - **Novedades** (`novelties`): objeto con tres grupos — vacaciones (`holidays`), incapacidades (`incapacities`) y licencias (`licenses`).
            - **Otras categorías**: arreglo plano de conceptos.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Conceptos de nómina disponibles. Estructura varía según la categoría.
                    oneOf:
                      - type: array
                        description: Arreglo plano de conceptos para categorías distintas de overtime y novelties.
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            name:
                              description: Nombre del concepto de nómina.
                              type: string
                              example: Auxilio de transporte
                            coded_name:
                              description: Nombre codificado interno del concepto de nómina.
                              type: string
                              example: transport_subsidy
                            value:
                              description: Valor del ítem en la nómina indicada. Retorna `1` si no se envió `payroll_id`.
                              type: integer
                              example: 1
                            owner_type:
                              description: Tipo de propietario del concepto. `Company` para conceptos personalizados, null para conceptos del sistema.
                              type:
                                - string
                                - 'null'
                              example: Company
                            deleteable:
                              description: Indica si el concepto puede ser eliminado por la empresa.
                              type: boolean
                              example: false
                      - type: object
                        description: Conceptos de horas extras agrupados en extra_hours, surcharges y others.
                        properties:
                          extra_hours:
                            description: Arreglo de conceptos de horas extras.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Auxilio de transporte
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: transport_subsidy
                                value:
                                  description: Valor del ítem en la nómina indicada. Retorna `1` si no se envió `payroll_id`.
                                  type: integer
                                  example: 1
                                owner_type:
                                  description: Tipo de propietario del concepto. `Company` para conceptos personalizados, null para conceptos del sistema.
                                  type:
                                    - string
                                    - 'null'
                                  example: Company
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: false
                          surcharges:
                            description: Arreglo de conceptos de recargos.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Auxilio de transporte
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: transport_subsidy
                                value:
                                  description: Valor del ítem en la nómina indicada. Retorna `1` si no se envió `payroll_id`.
                                  type: integer
                                  example: 1
                                owner_type:
                                  description: Tipo de propietario del concepto. `Company` para conceptos personalizados, null para conceptos del sistema.
                                  type:
                                    - string
                                    - 'null'
                                  example: Company
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: false
                          others:
                            description: Arreglo de otros conceptos de horas extras no clasificados.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Auxilio de transporte
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: transport_subsidy
                                value:
                                  description: Valor del ítem en la nómina indicada. Retorna `1` si no se envió `payroll_id`.
                                  type: integer
                                  example: 1
                                owner_type:
                                  description: Tipo de propietario del concepto. `Company` para conceptos personalizados, null para conceptos del sistema.
                                  type:
                                    - string
                                    - 'null'
                                  example: Company
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: false
                      - type: object
                        description: Conceptos de novedades agrupados en holidays, incapacities y licenses.
                        properties:
                          holidays:
                            description: Arreglo de conceptos de vacaciones y días festivos.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Auxilio de transporte
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: transport_subsidy
                                value:
                                  description: Valor del ítem en la nómina indicada. Retorna `1` si no se envió `payroll_id`.
                                  type: integer
                                  example: 1
                                owner_type:
                                  description: Tipo de propietario del concepto. `Company` para conceptos personalizados, null para conceptos del sistema.
                                  type:
                                    - string
                                    - 'null'
                                  example: Company
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: false
                          incapacities:
                            description: Arreglo de conceptos de incapacidades.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Auxilio de transporte
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: transport_subsidy
                                value:
                                  description: Valor del ítem en la nómina indicada. Retorna `1` si no se envió `payroll_id`.
                                  type: integer
                                  example: 1
                                owner_type:
                                  description: Tipo de propietario del concepto. `Company` para conceptos personalizados, null para conceptos del sistema.
                                  type:
                                    - string
                                    - 'null'
                                  example: Company
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: false
                          licenses:
                            description: Arreglo de conceptos de licencias.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Auxilio de transporte
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: transport_subsidy
                                value:
                                  description: Valor del ítem en la nómina indicada. Retorna `1` si no se envió `payroll_id`.
                                  type: integer
                                  example: 1
                                owner_type:
                                  description: Tipo de propietario del concepto. `Company` para conceptos personalizados, null para conceptos del sistema.
                                  type:
                                    - string
                                    - 'null'
                                  example: Company
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: false
              examples:
                Ingresos no salariales:
                  value:
                    data:
                      - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        name: Auxilio de transporte
                        coded_name: transport_subsidy
                        value: 1
                        owner_type: null
                        deleteable: false
                Horas extras:
                  value:
                    data:
                      extra_hours:
                        - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                          name: Hora extra diurna
                          coded_name: daily_hour
                          value: 1
                          owner_type: null
                          deleteable: false
                      surcharges:
                        - id: c3d4e5f6-a7b8-9012-cdef-012345678901
                          name: Recargo nocturno
                          coded_name: nightly_surcharge
                          value: 1
                          owner_type: null
                          deleteable: false
                      others: []
                Novedades:
                  value:
                    data:
                      holidays:
                        - id: d4e5f6a7-b8c9-0123-defa-123456789012
                          name: Vacaciones disfrutadas
                          coded_name: enjoyed_days
                          value: 1
                          owner_type: null
                          deleteable: false
                      incapacities:
                        - id: e5f6a7b8-c9d0-1234-efab-234567890123
                          name: Incapacidad laboral
                          coded_name: labor_incapacity
                          value: 1
                          owner_type: null
                          deleteable: false
                      licenses: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updatePayrollConcepts
      tags:
        - Conceptos de nómina
      summary: Crear, actualizar o eliminar conceptos de nómina
      description: |
        **¿Qué hace este endpoint?**

        Gestiona de forma masiva los conceptos de nómina de la empresa en una sola operación. La acción
        se determina automáticamente según los campos enviados en cada objeto de `payroll_concepts`:

        * **Crear:** Sin `id` — crea un nuevo concepto con el `name` indicado en la `category` especificada.
        * **Actualizar:** Con `id` y `name` — actualiza el nombre del concepto existente.
        * **Eliminar:** Con `id` sin `name` — elimina el concepto de la empresa.

        Si se envía `payroll_id`, los cambios se aplican también al ítem de nómina correspondiente
        y la nómina se recalcula.

        **¿Cuándo usar este endpoint?**

        * Agregar un concepto de ingreso no salarial o deducción personalizada a la empresa.
        * Registrar horas extras de un tipo específico en una nómina enviando `payroll_id`, `quantity` y `value`.
        * Renombrar un concepto existente o eliminar uno que ya no se usa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Categoría obligatoria:** El campo `category` debe enviarse siempre para indicar en qué categoría se opera.
        * **Factor multiplicador para horas extras:** Al crear un concepto de horas extras, el campo `constant_value` define el factor multiplicador del concepto.
      requestBody:
        required: true
        description: Crear concepto / Registrar horas extras en nómina / Eliminar concepto
        content:
          application/json:
            schema:
              type: object
              required:
                - category
                - payroll_concepts
              properties:
                category:
                  description: |
                    Categoría de los conceptos a gestionar.

                    Valores posibles:

                    * `overtime` — Horas extras y recargos.
                    * `novelties` — Novedades (vacaciones, incapacidades, licencias).
                    * `non_salary_income` — Ingresos no salariales.
                    * `occasional_non_salary_income` — Ingresos no salariales ocasionales.
                    * `salary_income` — Ingresos salariales.
                    * `deductions` — Deducciones.
                    * `loan` — Préstamos.
                  type: string
                  enum:
                    - overtime
                    - novelties
                    - non_salary_income
                    - occasional_non_salary_income
                    - salary_income
                    - deductions
                    - loan
                  example: non_salary_income
                payroll_id:
                  description: Identificador único (ID) asignado a la nómina en la base de datos. Si no se envía, solo se gestiona el concepto sin afectar ninguna nómina.
                  type: string
                  example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                payroll_concepts:
                  description: |
                    Listado de operaciones a ejecutar sobre conceptos de nómina. La acción se determina por los campos enviados en cada objeto:

                    * **Crear:** Sin `id` — crea un nuevo concepto con el `name` indicado.
                    * **Actualizar:** Con `id` y `name` — actualiza el nombre del concepto existente.
                    * **Eliminar:** Con `id` sin `name` — elimina el concepto de la empresa.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al concepto en la base de datos. Omitir para crear uno nuevo.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      name:
                        description: Nombre del concepto. Requerido para crear o actualizar. Omitir para eliminar.
                        type: string
                        example: Bono de alimentación
                      value:
                        description: Valor monetario del ítem de nómina en pesos colombianos. Solo aplica cuando se envía `payroll_id`.
                        type: integer
                        example: 100000
                      quantity:
                        description: Cantidad del ítem (horas para overtime). Solo aplica cuando se envía `payroll_id`.
                        type: number
                        example: 4
                      constant_value:
                        description: Factor multiplicador del concepto de horas extras. Solo aplica cuando `category` es `overtime` al crear.
                        type: number
                        example: 1.25
            examples:
              Crear concepto:
                value:
                  category: non_salary_income
                  payroll_concepts:
                    - name: Bono de alimentación
              Registrar horas extras en nómina:
                value:
                  category: overtime
                  payroll_id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                  payroll_concepts:
                    - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      name: Hora extra diurna
                      quantity: 4
                      value: 50000
              Eliminar concepto:
                value:
                  category: non_salary_income
                  payroll_concepts:
                    - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
      responses:
        '202':
          description: |
            La estructura de `data` depende de si se envió `payroll_id`:

            - **Sin `payroll_id`:** retorna `period`, `payroll`, `payroll_concepts` y `category`. Los campos de `period` y `payroll` son null.
            - **Con `payroll_id`:** retorna todo lo anterior más `details` con el desglose de totales por categoría.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la operación con los totales actualizados.
                    oneOf:
                      - type: object
                        description: Solo se gestiona el concepto, sin asociarlo a una nómina. No incluye `details`.
                        required:
                          - period
                          - payroll
                          - payroll_concepts
                          - category
                        properties:
                          period:
                            description: Totales actualizados del periodo. Los campos son null si no se envió `payroll_id`.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al periodo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                              workers_payment:
                                description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 7500000
                              company_cost:
                                description: Costo total de la empresa en el periodo, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 9750000
                          payroll:
                            description: Totales actualizados de la nómina. Los campos son null si no se envió `payroll_id`.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la nómina en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                              worker_payment:
                                description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 1700000
                              company_cost:
                                description: Costo total de la empresa por esta nómina, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 2000000
                              novelties_days:
                                description: Total de días de novedades liquidados en la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              novelties_value:
                                description: Total en pesos colombianos de novedades liquidadas en la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              overtime_hours:
                                description: Total de horas extras y recargos registrados en la nómina.
                                type:
                                  - number
                                  - 'null'
                                example: 4
                              overtime_value:
                                description: Total en pesos colombianos de horas extras y recargos.
                                type:
                                  - integer
                                  - 'null'
                                example: 50000
                              salary_income:
                                description: Total en pesos colombianos de ingresos salariales de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 100000
                              occasional_non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              deductions:
                                description: Total en pesos colombianos de deducciones de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                          payroll_concepts:
                            description: Conceptos afectados por la operación con sus valores actualizados.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Bono de alimentación
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: bono_de_alimentacion
                                item_value:
                                  description: Valor del ítem en la nómina indicada, en pesos colombianos. Null si no se envió `payroll_id`.
                                  type:
                                    - number
                                    - 'null'
                                  example: 100000
                                constant_value:
                                  description: Factor multiplicador del concepto (overtime). Para otras categorías retorna `1`.
                                  type: number
                                  example: 1
                                quantity:
                                  description: Cantidad del ítem en la nómina indicada. Para categorías distintas de overtime retorna `1`.
                                  type: number
                                  example: 1
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: true
                          category:
                            description: Categoría de los conceptos operados.
                            type: string
                            example: non_salary_income
                      - type: object
                        description: El concepto se asocia a una nómina. Incluye `details` con el desglose de totales por categoría.
                        required:
                          - period
                          - payroll
                          - payroll_concepts
                          - category
                          - details
                        properties:
                          period:
                            description: Totales actualizados del periodo. Los campos son null si no se envió `payroll_id`.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al periodo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                              workers_payment:
                                description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 7500000
                              company_cost:
                                description: Costo total de la empresa en el periodo, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 9750000
                          payroll:
                            description: Totales actualizados de la nómina. Los campos son null si no se envió `payroll_id`.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la nómina en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                              worker_payment:
                                description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 1700000
                              company_cost:
                                description: Costo total de la empresa por esta nómina, en pesos colombianos.
                                type:
                                  - integer
                                  - 'null'
                                example: 2000000
                              novelties_days:
                                description: Total de días de novedades liquidados en la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              novelties_value:
                                description: Total en pesos colombianos de novedades liquidadas en la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              overtime_hours:
                                description: Total de horas extras y recargos registrados en la nómina.
                                type:
                                  - number
                                  - 'null'
                                example: 4
                              overtime_value:
                                description: Total en pesos colombianos de horas extras y recargos.
                                type:
                                  - integer
                                  - 'null'
                                example: 50000
                              salary_income:
                                description: Total en pesos colombianos de ingresos salariales de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 100000
                              occasional_non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                              deductions:
                                description: Total en pesos colombianos de deducciones de la nómina.
                                type:
                                  - integer
                                  - 'null'
                                example: 0
                          payroll_concepts:
                            description: Conceptos afectados por la operación con sus valores actualizados.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                  type: string
                                  example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                                name:
                                  description: Nombre del concepto de nómina.
                                  type: string
                                  example: Bono de alimentación
                                coded_name:
                                  description: Nombre codificado interno del concepto de nómina.
                                  type: string
                                  example: bono_de_alimentacion
                                item_value:
                                  description: Valor del ítem en la nómina indicada, en pesos colombianos. Null si no se envió `payroll_id`.
                                  type:
                                    - number
                                    - 'null'
                                  example: 100000
                                constant_value:
                                  description: Factor multiplicador del concepto (overtime). Para otras categorías retorna `1`.
                                  type: number
                                  example: 1
                                quantity:
                                  description: Cantidad del ítem en la nómina indicada. Para categorías distintas de overtime retorna `1`.
                                  type: number
                                  example: 1
                                deleteable:
                                  description: Indica si el concepto puede ser eliminado por la empresa.
                                  type: boolean
                                  example: true
                          category:
                            description: Categoría de los conceptos operados.
                            type: string
                            example: non_salary_income
                          details:
                            description: Desglose de totales de la nómina por categoría.
                            type: object
                            properties:
                              overtime:
                                description: Totales de horas extras de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de horas extras.
                                    type: number
                                    example: 4
                                  value:
                                    description: Valor en pesos colombianos de las horas extras.
                                    type: integer
                                    example: 50000
                              surcharge:
                                description: Totales de recargos de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de horas con recargo.
                                    type: number
                                    example: 2
                                  value:
                                    description: Valor en pesos colombianos de los recargos.
                                    type: integer
                                    example: 20000
                              company_overtime:
                                description: Totales de horas extras con conceptos creados por la empresa.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de horas extras con conceptos creados por la empresa.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                    type: integer
                                    example: 0
                              holidays:
                                description: Totales de vacaciones disfrutadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de días de vacaciones.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las vacaciones pagadas.
                                    type: integer
                                    example: 0
                              incapacities:
                                description: Totales de incapacidades liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de días de incapacidad.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las incapacidades.
                                    type: integer
                                    example: 0
                              licenses:
                                description: Totales de licencias liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de días de licencia.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las licencias.
                                    type: integer
                                    example: 0
                              additional_income:
                                description: Totales de ingresos adicionales (salariales y no salariales) de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor en pesos colombianos de los ingresos adicionales.
                                    type: integer
                                    example: 100000
                              deductions:
                                description: Totales de deducciones (excluye retención en la fuente y préstamos) de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor en pesos colombianos de las deducciones.
                                    type: integer
                                    example: 0
                              payroll_retention:
                                description: Totales de retención en la fuente aplicada en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor en pesos colombianos de la retención en la fuente.
                                    type: integer
                                    example: 0
                              loans:
                                description: Totales de cuotas de préstamos descontadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor en pesos colombianos de los préstamos descontados.
                                    type: integer
                                    example: 0
              examples:
                Solo concepto:
                  value:
                    data:
                      period:
                        id: null
                        workers_payment: null
                        company_cost: null
                      payroll:
                        id: null
                        worker_payment: null
                        company_cost: null
                        novelties_days: null
                        novelties_value: null
                        overtime_hours: null
                        overtime_value: null
                        salary_income: null
                        non_salary_income: null
                        occasional_non_salary_income: null
                        deductions: null
                      payroll_concepts:
                        - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name: Bono de alimentación
                          coded_name: bono_de_alimentacion
                          item_value: null
                          constant_value: 1
                          quantity: 1
                          deleteable: true
                      category: non_salary_income
                Concepto con nómina:
                  value:
                    data:
                      period:
                        id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                        workers_payment: 7600000
                        company_cost: 9850000
                      payroll:
                        id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        worker_payment: 1700000
                        company_cost: 2000000
                        novelties_days: 0
                        novelties_value: 0
                        overtime_hours: 0
                        overtime_value: 0
                        salary_income: 0
                        non_salary_income: 100000
                        occasional_non_salary_income: 0
                        deductions: 0
                      payroll_concepts:
                        - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name: Bono de alimentación
                          coded_name: bono_de_alimentacion
                          item_value: 100000
                          constant_value: 1
                          quantity: 1
                          deleteable: true
                      category: non_salary_income
                      details:
                        overtime:
                          quantity: 0
                          value: 0
                        surcharge:
                          quantity: 0
                          value: 0
                        company_overtime:
                          quantity: 0
                          value: 0
                        holidays:
                          quantity: 0
                          value: 0
                        incapacities:
                          quantity: 0
                          value: 0
                        licenses:
                          quantity: 0
                          value: 0
                        additional_income:
                          quantity: null
                          value: 100000
                        deductions:
                          quantity: null
                          value: 0
                        payroll_retention:
                          quantity: null
                          value: 0
                        loans:
                          quantity: null
                          value: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Categoría inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/payroll_concepts/{id}:
    delete:
      operationId: destroyPayrollConcept
      tags:
        - Conceptos de nómina
      summary: Eliminar concepto de nómina
      description: |
        **¿Qué hace este endpoint?**

        Elimina un concepto de nómina de la empresa de forma permanente.

        **¿Cuándo usar este endpoint?**

        * Eliminar un concepto personalizado que ya no se usa en la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Conceptos no eliminables:** Algunos conceptos del sistema no pueden eliminarse (`deleteable: false`). Intentar eliminarlos retorna 422.
      responses:
        '200':
          description: Concepto de nómina eliminado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: El concepto ha sido eliminado.
              example:
                data:
                  message: El concepto ha sido eliminado.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: El concepto no puede eliminarse porque tiene nóminas asociadas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0503'
                    index: 0
                    message: Concepto de nómina no se puede eliminar porque tiene nóminas asociadas.
                    object: payroll_concept
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
        schema:
          type: string
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
  /v1/{company_id}/payrolls:
    get:
      operationId: indexPayrolls
      tags:
        - Nóminas
      summary: Listar nóminas del periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de nóminas de un periodo con el detalle de cada nómina y los
        filtros de paginación.

        **¿Cuándo usar este endpoint?**

        * Obtener las nóminas de un periodo para construir el detalle de una liquidación.
        * Filtrar las nóminas del periodo por sede, categoría de contrato o estado de contrato.
        * Verificar si alguna nómina del periodo tiene pago anticipado de vacaciones activo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Periodo por defecto:** Si no se envía el identificador del periodo, se usan las nóminas del periodo actual de la empresa.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: period_id
          description: Identificador único (ID) del periodo cuyas nóminas se quieren consultar. Si no se envía, usa el periodo actual.
          schema:
            type: string
            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
        - in: query
          required: false
          name: search
          description: Busca nóminas por nombre de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
        - in: query
          required: false
          name: contract_category
          description: Filtra las nóminas por categoría del contrato de la persona.
          schema:
            $ref: '#/components/schemas/ContractCategory'
        - $ref: '#/components/parameters/contractStatusParam'
        - in: query
          required: false
          name: location
          description: Filtra las nóminas por sede. Se envía el identificador único (ID) de la sede.
          schema:
            type: string
            example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
      responses:
        '200':
          description: Con nóminas / Sin nóminas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del listado de nóminas y estado del pago anticipado del periodo.
                    type: object
                    properties:
                      payrolls:
                        description: Listado de nóminas del periodo con su detalle completo.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la nómina en la base de datos.
                              type: string
                              example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                            worker_id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            worker_name:
                              description: Nombre completo de la persona.
                              type: string
                              example: Juan Pérez
                            contract_id:
                              description: Identificador único (ID) asignado al contrato en la base de datos.
                              type: string
                              example: 3c4d5e6f-7a8b-9012-cdef-123456789012
                            contract_category:
                              $ref: '#/components/schemas/ContractCategory'
                            salary:
                              description: Salario base de la nómina en pesos colombianos.
                              type: integer
                              example: 1500000
                            worker_payment:
                              description: Pago neto a la persona en pesos colombianos.
                              type: integer
                              example: 1600000
                            company_cost:
                              description: Costo total para la empresa en pesos colombianos.
                              type: integer
                              example: 1900000
                            worked_time:
                              description: Días u horas trabajados en el periodo.
                              type: number
                              example: 15
                            locked:
                              description: Indica si la nómina está bloqueada (liquidada definitivamente).
                              type: boolean
                              example: false
                            early_payment_type:
                              $ref: '#/components/schemas/EarlyPaymentType'
                            details:
                              description: Desglose de totales de la nómina por categoría.
                              type: object
                              properties:
                                overtime:
                                  description: Horas extras diurnas.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Total de horas extras diurnas trabajadas.
                                      type: number
                                      example: 4
                                    value:
                                      description: Valor total de las horas extras diurnas en pesos colombianos.
                                      type: integer
                                      example: 45000
                                surcharge:
                                  description: Recargos nocturnos, dominicales y festivos.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Total de horas con recargo trabajadas.
                                      type: number
                                      example: 2
                                    value:
                                      description: Valor total de los recargos en pesos colombianos.
                                      type: integer
                                      example: 20000
                                company_overtime:
                                  description: Horas extras nocturnas y festivas.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Total de horas extras nocturnas y festivas trabajadas.
                                      type: number
                                      example: 0
                                    value:
                                      description: Valor total de las horas extras nocturnas y festivas en pesos colombianos.
                                      type: integer
                                      example: 0
                                holidays:
                                  description: Vacaciones del periodo.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Total de días de vacaciones aplicados.
                                      type: number
                                      example: 0
                                    value:
                                      description: Valor total de las vacaciones en pesos colombianos.
                                      type: integer
                                      example: 0
                                incapacities:
                                  description: Incapacidades del periodo.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Total de días de incapacidad aplicados.
                                      type: number
                                      example: 0
                                    value:
                                      description: Valor total de las incapacidades en pesos colombianos.
                                      type: integer
                                      example: 0
                                licenses:
                                  description: Licencias del periodo.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Total de días de licencia aplicados.
                                      type: number
                                      example: 0
                                    value:
                                      description: Valor total de las licencias en pesos colombianos.
                                      type: integer
                                      example: 0
                                additional_income:
                                  description: Ingresos adicionales del periodo.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Siempre null para esta categoría.
                                      type: 'null'
                                      example: null
                                    value:
                                      description: Valor total de los ingresos adicionales en pesos colombianos.
                                      type: integer
                                      example: 50000
                                deductions:
                                  description: Deducciones del periodo (sin retención ni préstamos).
                                  type: object
                                  properties:
                                    quantity:
                                      description: Siempre null para esta categoría.
                                      type: 'null'
                                      example: null
                                    value:
                                      description: Valor total de las deducciones en pesos colombianos.
                                      type: integer
                                      example: 30000
                                payroll_retention:
                                  description: Retención en la fuente del periodo.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Siempre null para esta categoría.
                                      type: 'null'
                                      example: null
                                    value:
                                      description: Valor de la retención en la fuente en pesos colombianos.
                                      type: integer
                                      example: 0
                                loans:
                                  description: Descuentos por préstamos del periodo.
                                  type: object
                                  properties:
                                    quantity:
                                      description: Siempre null para esta categoría.
                                      type: 'null'
                                      example: null
                                    value:
                                      description: Valor total descontado por préstamos en pesos colombianos.
                                      type: integer
                                      example: 100000
                      early_payment:
                        description: Indica si alguna nómina del periodo tiene pago anticipado de vacaciones activo.
                        type: boolean
                        example: false
                  filters:
                    description: Información de paginación y filtros aplicados.
                    type: object
                    properties:
                      location:
                        description: Identificador de la sede por la que se filtró, o `All` si no se aplicó filtro.
                        type: string
                        example: All
                      total_records:
                        description: Número total de nóminas que coinciden con los filtros aplicados.
                        type: integer
                        example: 5
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de nóminas retornadas por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado. Null si no se envió búsqueda.
                        type:
                          - string
                          - 'null'
                        example: ''
              examples:
                Con nóminas:
                  value:
                    data:
                      payrolls:
                        - id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name: Juan Pérez
                          contract_id: 3c4d5e6f-7a8b-9012-cdef-123456789012
                          contract_category: employee
                          salary: 1500000
                          worker_payment: 1600000
                          company_cost: 1900000
                          worked_time: 15
                          locked: false
                          early_payment_type: no_early_payment
                          details:
                            overtime:
                              quantity: 0
                              value: 0
                            surcharge:
                              quantity: 0
                              value: 0
                            company_overtime:
                              quantity: 0
                              value: 0
                            holidays:
                              quantity: 0
                              value: 0
                            incapacities:
                              quantity: 0
                              value: 0
                            licenses:
                              quantity: 0
                              value: 0
                            additional_income:
                              quantity: null
                              value: 50000
                            deductions:
                              quantity: null
                              value: 30000
                            payroll_retention:
                              quantity: null
                              value: 0
                            loans:
                              quantity: null
                              value: 100000
                      early_payment: false
                    filters:
                      location: All
                      total_records: 5
                      page: 1
                      per_page: 20
                      search: ''
                Sin nóminas:
                  value:
                    data:
                      payrolls: []
                      early_payment: false
                    filters:
                      location: All
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/payrolls/{id}:
    get:
      operationId: showPayroll
      tags:
        - Nóminas
      summary: Obtener nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle completo de una nómina individual, incluyendo todos sus campos editables,
        totales por categoría y los ítems de nómina agrupados por categoría de concepto.

        **¿Cuándo usar este endpoint?**

        * Consultar el detalle de una nómina específica antes de editarla o descargar su desprendible.
        * Obtener los ítems liquidados de la nómina agrupados por categoría para mostrarlos en el detalle de liquidación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Detalle de la nómina retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle completo de la nómina.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la nómina en la base de datos.
                        type: string
                        example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name:
                        description: Nombre completo de la persona.
                        type: string
                        example: Juan Pérez
                      contract_id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: 3c4d5e6f-7a8b-9012-cdef-123456789012
                      contract_category:
                        $ref: '#/components/schemas/ContractCategory'
                      base_salary:
                        description: Salario base de la nómina en pesos colombianos.
                        type: integer
                        example: 1500000
                      salary:
                        description: Salario devengado calculado en el periodo en pesos colombianos.
                        type: integer
                        example: 1500000
                      worker_payment:
                        description: Pago neto a la persona en pesos colombianos.
                        type: integer
                        example: 1600000
                      company_cost:
                        description: Costo total para la empresa en pesos colombianos.
                        type: integer
                        example: 1900000
                      worked_time:
                        description: Días u horas trabajados en el periodo.
                        type: number
                        example: 15
                      locked:
                        description: Indica si la nómina está bloqueada (liquidada definitivamente).
                        type: boolean
                        example: false
                      early_payment_type:
                        $ref: '#/components/schemas/EarlyPaymentType'
                      holidays_average_salary:
                        description: Salario promedio para el cálculo de vacaciones en pesos colombianos.
                        type: integer
                        example: 1500000
                      licenses_average_salary:
                        description: Salario promedio para el cálculo de licencias en pesos colombianos.
                        type: integer
                        example: 1500000
                      novelties_average_salary:
                        description: Salario promedio para el cálculo de incapacidades en pesos colombianos.
                        type: integer
                        example: 1500000
                      overtime_average_salary:
                        description: Salario promedio usado como base para el cálculo de horas extras y recargos en pesos colombianos.
                        type: integer
                        example: 1500000
                      parental_licenses_average_salary:
                        description: Salario promedio para licencias de maternidad/paternidad en pesos colombianos.
                        type: integer
                        example: 1500000
                      compensated_days_average_salary:
                        description: Salario promedio para días compensados en pesos colombianos.
                        type: integer
                        example: 1500000
                      comments:
                        description: Comentarios internos registrados en la nómina. Puede ser null si no se registró ningún comentario.
                        type:
                          - string
                          - 'null'
                        example: Persona trabajó medio tiempo por incapacidad
                      art_206_uvt_limit:
                        description: Límite en UVT del artículo 206 aplicado en esta nómina para retención en la fuente.
                        type: string
                        example: '1090'
                      art_336_uvt_limit:
                        description: Límite en UVT del artículo 336 aplicado en esta nómina para retención en la fuente.
                        type: string
                        example: '5040'
                      items:
                        description: Ítems de nómina agrupados por categoría de concepto (overtime, social_security, legal, novelties, deductions, loan, etc.).
                        type: object
                        additionalProperties:
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al ítem de nómina en la base de datos.
                                type: string
                                example: d1e2f3a4-b5c6-7890-def0-123456789012
                              payroll_concept_id:
                                description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                type: string
                                example: c1d2e3f4-a5b6-7890-cdef-012345678901
                              coded_name:
                                description: Nombre codificado del concepto de nómina.
                                type: string
                                example: salary
                              name:
                                description: Nombre legible del concepto de nómina.
                                type: string
                                example: Salario
                              value:
                                description: Valor monetario del ítem en pesos colombianos.
                                type: integer
                                example: 1500000
                              quantity:
                                description: Cantidad del ítem (días u horas). Solo presente para ítems de categoría `overtime` o `novelties`, y para el concepto `part_time_paid_rest`.
                                type: number
                                example: 2
                              loan_id:
                                description: Identificador único (ID) del préstamo asociado al ítem. Solo presente cuando el ítem corresponde a un descuento de préstamo.
                                type: string
                                example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                              category_total_value:
                                description: Valor total de todos los ítems de la misma categoría en esta nómina.
                                type: integer
                                example: 1500000
                              category_total_quantity:
                                description: Cantidad total de todos los ítems de la misma categoría en esta nómina.
                                type: number
                                example: 15
              example:
                data:
                  id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  worker_name: Juan Pérez
                  contract_id: 3c4d5e6f-7a8b-9012-cdef-123456789012
                  contract_category: employee
                  base_salary: 1500000
                  salary: 1500000
                  worker_payment: 1600000
                  company_cost: 1900000
                  worked_time: 15
                  locked: false
                  early_payment_type: no_early_payment
                  holidays_average_salary: 1500000
                  licenses_average_salary: 1500000
                  novelties_average_salary: 1500000
                  overtime_average_salary: 1500000
                  parental_licenses_average_salary: 1500000
                  compensated_days_average_salary: 1500000
                  comments: null
                  art_206_uvt_limit: '1090'
                  art_336_uvt_limit: '5040'
                  items:
                    legal:
                      - id: d1e2f3a4-b5c6-7890-def0-123456789012
                        payroll_concept_id: c1d2e3f4-a5b6-7890-cdef-012345678901
                        coded_name: salary
                        name: Salario
                        value: 1500000
                        category_total_value: 1600000
                        category_total_quantity: 15
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updatePayroll
      tags:
        - Nóminas
      summary: Actualizar nómina
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los campos editables de una nómina y recalcula los totales afectados. Permite
        modificar días trabajados, salarios promedio, comentarios, tipo de pago anticipado de
        vacaciones y límites de UVT para retención en la fuente.

        **¿Cuándo usar este endpoint?**

        * Corregir los días trabajados de una persona en el periodo antes de cerrar la nómina.
        * Actualizar los salarios promedio usados para el cálculo de vacaciones, licencias o incapacidades.
        * Configurar el tipo de pago anticipado de vacaciones para una nómina específica.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Nómina bloqueada:** Si la nómina está bloqueada (cerrada definitivamente), retorna 422.
        * **`worked_time` solo para salario por tiempo:** Solo puede modificarse si el contrato tiene una categoría de salario por tiempo (por hora o por día). Intentar modificarlo en contratos con salario fijo retorna 422.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                payroll:
                  type: object
                  properties:
                    worked_time:
                      description: Días u horas trabajados en el periodo. Solo válido para contratos con salario por tiempo.
                      type: number
                      example: 12
                    holidays_average_salary:
                      description: Salario promedio para el cálculo de vacaciones en pesos colombianos.
                      type: integer
                      example: 1500000
                    licenses_average_salary:
                      description: Salario promedio para el cálculo de licencias en pesos colombianos.
                      type: integer
                      example: 1500000
                    novelties_average_salary:
                      description: Salario promedio para el cálculo de incapacidades en pesos colombianos.
                      type: integer
                      example: 1500000
                    overtime_average_salary:
                      description: Salario promedio usado como base para el cálculo de horas extras y recargos en pesos colombianos.
                      type: integer
                      example: 1500000
                    parental_licenses_average_salary:
                      description: Salario promedio para licencias de maternidad/paternidad en pesos colombianos.
                      type: integer
                      example: 1500000
                    compensated_days_average_salary:
                      description: Salario promedio para días compensados en pesos colombianos.
                      type: integer
                      example: 1500000
                    early_payment_type:
                      $ref: '#/components/schemas/EarlyPaymentType'
                    comments:
                      description: Comentarios internos de la nómina.
                      type: string
                      example: Persona trabajó medio tiempo por incapacidad
                    art_206_uvt_limit:
                      description: Límite en UVT del artículo 206 para retención en la fuente.
                      type: string
                      example: '1090'
                    art_336_uvt_limit:
                      description: Límite en UVT del artículo 336 para retención en la fuente.
                      type: string
                      example: '5040'
            example:
              payroll:
                worked_time: 12
                comments: Persona trabajó medio tiempo por incapacidad
      responses:
        '202':
          description: Nómina actualizada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la actualización con los totales recalculados.
                    type: object
                    properties:
                      period:
                        description: Totales actualizados del periodo después del recálculo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7500000
                          company_cost:
                            description: Costo total de la empresa en el periodo, en pesos colombianos.
                            type: integer
                            example: 9750000
                      payroll:
                        description: Campos actualizados de la nómina después del recálculo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la nómina en la base de datos.
                            type: string
                            example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          base_salary:
                            description: Salario base en pesos colombianos.
                            type: integer
                            example: 1500000
                          worked_time:
                            description: Días u horas trabajados en el periodo.
                            type: number
                            example: 12
                          worker_payment:
                            description: Pago neto a la persona en pesos colombianos.
                            type: integer
                            example: 1200000
                          company_cost:
                            description: Costo total para la empresa en pesos colombianos.
                            type: integer
                            example: 1520000
                          early_payment_type:
                            $ref: '#/components/schemas/EarlyPaymentType'
                          comments:
                            description: Comentarios internos de la nómina.
                            type:
                              - string
                              - 'null'
                            example: Persona trabajó medio tiempo por incapacidad
                      details:
                        description: Desglose de totales de la nómina actualizada por categoría. Cada campo contiene `quantity` (cantidad, null si no aplica) y `value` (valor en pesos colombianos).
                        type: object
                        properties:
                          overtime:
                            description: Totales de horas extras de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas extras registradas.
                                type: number
                                example: 0
                              value:
                                description: Valor total de horas extras en pesos colombianos.
                                type: integer
                                example: 0
                          surcharge:
                            description: Totales de recargos de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas con recargo registradas.
                                type: number
                                example: 0
                              value:
                                description: Valor total de recargos en pesos colombianos.
                                type: integer
                                example: 0
                          company_overtime:
                            description: Totales de horas extras a cargo de la empresa.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas extras a cargo de la empresa.
                                type: number
                                example: 0
                              value:
                                description: Valor total de horas extras a cargo de la empresa en pesos colombianos.
                                type: integer
                                example: 0
                          holidays:
                            description: Totales de vacaciones liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de vacaciones liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de vacaciones en pesos colombianos.
                                type: integer
                                example: 0
                          incapacities:
                            description: Totales de incapacidades liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de incapacidad liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de incapacidades en pesos colombianos.
                                type: integer
                                example: 0
                          licenses:
                            description: Totales de licencias liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de licencia liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de licencias en pesos colombianos.
                                type: integer
                                example: 0
                          additional_income:
                            description: Totales de ingresos adicionales (salariales y no salariales) de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de ingresos adicionales. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de ingresos adicionales en pesos colombianos.
                                type: integer
                                example: 0
                          deductions:
                            description: Totales de deducciones de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de deducciones. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de deducciones en pesos colombianos.
                                type: integer
                                example: 0
                          payroll_retention:
                            description: Totales de retención en la fuente de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de retención. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de retención en la fuente en pesos colombianos.
                                type: integer
                                example: 0
                          loans:
                            description: Totales de préstamos descontados en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de préstamos. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de préstamos descontados en pesos colombianos.
                                type: integer
                                example: 0
              example:
                data:
                  period:
                    id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                    workers_payment: 7200000
                    company_cost: 9100000
                  payroll:
                    id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                    base_salary: 1500000
                    worked_time: 12
                    worker_payment: 1200000
                    company_cost: 1520000
                    early_payment_type: no_early_payment
                    comments: Persona trabajó medio tiempo por incapacidad
                  details:
                    overtime:
                      quantity: 0
                      value: 0
                    surcharge:
                      quantity: 0
                      value: 0
                    company_overtime:
                      quantity: 0
                      value: 0
                    holidays:
                      quantity: 0
                      value: 0
                    incapacities:
                      quantity: 0
                      value: 0
                    licenses:
                      quantity: 0
                      value: 0
                    additional_income:
                      quantity: null
                      value: 0
                    deductions:
                      quantity: null
                      value: 0
                    payroll_retention:
                      quantity: null
                      value: 0
                    loans:
                      quantity: null
                      value: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nómina bloqueada / días trabajados inválidos / tipo de pago anticipado inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nómina bloqueada:
                  value:
                    error:
                      - code: '1803'
                        index: 0
                        message: La nómina no puede ser editada.
                        object: payroll
                Tipo de salario no permite editar días trabajados:
                  value:
                    error:
                      - code: '0806'
                        index: 0
                        message: No puedes editar el tiempo trabajado para el tipo de salario.
                        object: wage
                Días trabajados exceden el límite del periodo:
                  value:
                    error:
                      - code: '1808'
                        index: 0
                        message: Los días trabajados no pueden ser mayores a los días del periodo ni a 29 días en el mes.
                        object: payroll
                Días trabajados exceden vigencia del contrato:
                  value:
                    error:
                      - code: '1809'
                        index: 0
                        message: Los días trabajados superan los días permitidos por la vigencia del contrato en este periodo.
                        object: payroll
                Pago anticipado inválido con liquidación:
                  value:
                    error:
                      - code: '1802'
                        index: 0
                        message: La persona se encuentra liquidada y el pago anticipado no se puede editar.
                        object: payroll
                Pago anticipado solo vacaciones inválido:
                  value:
                    error:
                      - code: '1807'
                        index: 0
                        message: La opción pago anticipado solo vacaciones no es válida, ya que la fecha inicial de las vacaciones es superior a la fecha final del periodo actual.
                        object: payroll
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
  /v1/{company_id}/payrolls/{payroll_id}/bank_file:
    get:
      operationId: showBankFile
      tags:
        - Archivos bancarios
      summary: Obtener archivo bancario de nómina
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo bancario para el pago de una nómina individual, usando la cuenta
        bancaria de la empresa indicada. El archivo se genera en el formato requerido por el banco configurado.

        **¿Cuándo usar este endpoint?**

        * Generar el archivo de pago para una nómina específica antes de enviarlo al banco.
        * Obtener el archivo de liquidación de prestaciones sociales o terminación de contrato de una persona.
        * Generar el archivo con un tramo específico cuando la nómina tiene vacaciones anticipadas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Cuenta bancaria requerida:** El parámetro `bank_account_id` es obligatorio. Si no se encuentra, retorna 404.
        * **Banco sin soporte:** Si el banco de la cuenta no tiene generación de archivo configurada, retorna 422.
      parameters:
        - in: query
          required: true
          name: bank_account_id
          description: Identificador único (ID) de la cuenta bancaria de la empresa que se usará para generar el archivo.
          schema:
            type: string
            example: 7b3a1f2e-9c4d-4e5f-a6b7-8c9d0e1f2a3b
        - in: query
          required: false
          name: payment_type
          schema:
            $ref: '#/components/schemas/PayrollBankPaymentType'
        - in: query
          required: false
          name: payroll_range
          description: Tramo de la nómina a incluir en el archivo. Solo aplica cuando la nómina fue liquidada con vacaciones anticipadas.
          schema:
            $ref: '#/components/schemas/PayrollRange'
        - in: query
          required: false
          name: pay_day
          description: Fecha de pago a registrar en el archivo bancario, en formato `YYYY-MM-DD`. Si no se envía, usa la fecha del sistema.
          schema:
            type: string
            format: date
            example: '2024-01-15'
        - in: query
          required: false
          name: file_format
          description: Formato específico del archivo a generar según el banco (ej. `PAB`, `xlsx`). Si no se envía, usa el formato por defecto del banco.
          schema:
            type: string
            example: PAB
      responses:
        '200':
          description: Archivo bancario generado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del archivo bancario generado.
                    type: string
                    example: https://storage.aleluya.com/bank_file.txt
                  size:
                    description: Número de personas incluidas en el archivo bancario.
                    type: integer
                    example: 3
                  total_value:
                    description: Valor total a pagar en pesos colombianos, suma de los pagos de todas las personas incluidas en el archivo.
                    type: integer
                    example: 4350000
              example:
                file: https://storage.aleluya.com/bank_file.txt
                size: 3
                total_value: 4350000
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Banco sin soporte de archivo bancario / Tipo de pago inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Banco sin soporte de archivo bancario:
                  value:
                    error:
                      - code: '0603'
                        index: 0
                        message: Todavía no hemos generando el archivo para este banco. Si requieres generarlo, comunícate con nuestro equipo de soporte.
                        object: file
                Tipo de pago inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Tipo de pago es inválido.
                        object: payment_type
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 95054e94-5320-5b30-bcf3-59c224171028
  /v1/{company_id}/payrolls/{payroll_id}/bank_file_options:
    get:
      operationId: showPayrollBankFileOptions
      tags:
        - Archivos bancarios
      summary: Obtener opciones bancarias de nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones disponibles para generar el archivo bancario de pago de una nómina individual: tipos de pago y, si la nómina tiene pago anticipado, los tramos de rango de nómina disponibles.

        **¿Cuándo usar este endpoint?**

        * Consultar las opciones disponibles antes de generar el archivo bancario de una nómina específica.
        * Verificar qué tramos de rango (`payroll_range`) están disponibles cuando la nómina tiene pago anticipado habilitado.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Medio de pago:** La persona asociada a la nómina debe tener configurado el medio de pago como transferencia bancaria. Si el medio de pago es efectivo, el endpoint retorna `422`.
        * **Pago anticipado:** La nómina debe tener pago anticipado habilitado. Si no lo tiene, el endpoint retorna `422`. Para nóminas regulares sin pago anticipado, use el endpoint de archivo bancario de periodo.
        * **Cuenta bancaria:** La empresa debe tener al menos una cuenta bancaria registrada. Si no la tiene, el endpoint retorna `422`.
      responses:
        '200':
          description: Opciones para generar el archivo bancario de la nómina
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones disponibles para la generación del archivo bancario de la nómina.
                    type: object
                    properties:
                      bank_name:
                        description: Nombre del banco principal configurado para la empresa. Puede ser null si no se encuentra el banco.
                        type:
                          - string
                          - 'null'
                        example: bancolombia
                      payment_type:
                        description: Tipos de pago disponibles para incluir en el archivo bancario. Depende de si la nómina tiene liquidaciones o prestaciones sociales asociadas.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Etiqueta legible del tipo de pago para mostrar al usuario.
                              type: string
                              example: Nómina
                            value:
                              description: Valor del tipo de pago que se envía al generar el archivo.
                              type: string
                              example: payroll
                        example:
                          - label: Nómina
                            value: payroll
                          - label: Liquidación
                            value: termination
                          - label: Liquidación más nómina (solo liquidados)
                            value: payroll_termination
                          - label: Nómina más prima de servicios
                            value: payroll_service_bonus
                          - label: Prima de servicios
                            value: service_bonus
                      payroll_range:
                        description: Tramos de rango de nómina disponibles cuando la nómina tiene pago anticipado habilitado. Permite generar el archivo bancario solo para un tramo específico del periodo (e.g., días 1-7 o días 8-15). Retorna un arreglo vacío si no aplica.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Etiqueta legible del tramo de nómina (e.g., "Del 1 al 7 (Nómina más vacaciones)").
                              type: string
                              example: Periodo completo
                            value:
                              description: Valor del tramo. El valor `full_period` corresponde al periodo completo; los valores numéricos corresponden a tramos parciales.
                              type: string
                              example: full_period
                        example:
                          - label: Periodo completo
                            value: full_period
                          - label: Del 1 al 7 (Nómina más vacaciones)
                            value: '0'
                          - label: Del 8 al 15 (Nómina)
                            value: '2'
              example:
                data:
                  bank_name: bancolombia
                  payment_type:
                    - label: Nómina
                      value: payroll
                    - label: Liquidación
                      value: termination
                  payroll_range:
                    - label: Periodo completo
                      value: full_period
                    - label: Del 1 al 7 (Nómina más vacaciones)
                      value: '0'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin cuenta bancaria / Pago en efectivo / Sin pago anticipado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Sin cuenta bancaria:
                  value:
                    error:
                      - code: '0604'
                        index: 0
                        message: Completa la información de tu empresa, ingresando un Banco y el número de cuenta.
                        object: company
                Pago en efectivo:
                  value:
                    error:
                      - code: '0605'
                        index: 0
                        message: Esta persona tiene como medio de pago efectivo.
                        object: worker
                Sin pago anticipado:
                  value:
                    error:
                      - code: '1801'
                        index: 0
                        message: Esta nómina no tiene pago anticipado.
                        object: payroll
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 3de5e282-6a26-5896-b2ab-ed2dcaf1f01d
  /v1/{company_id}/payrolls/{payroll_id}/compensated_days:
    put:
      operationId: updateCompensatedDays
      tags:
        - Vacaciones compensadas
      summary: Actualizar días compensados
      description: |
        **¿Qué hace este endpoint?**

        Registra o elimina el ítem de vacaciones compensadas en la nómina indicada.
        Enviar una cantidad mayor a cero crea o actualiza el ítem; enviar `0` lo elimina.
        La nómina se recalcula automáticamente tras aplicar el cambio.

        **¿Cuándo usar este endpoint?**

        * Registrar el número de días de vacaciones compensadas a pagar en la nómina de una persona.
        * Actualizar la cantidad de días compensados previamente registrada.
        * Eliminar el ítem de vacaciones compensadas enviando `quantity: 0`.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      requestBody:
        required: true
        description: Crear o actualizar días compensados / Eliminar ítem
        content:
          application/json:
            schema:
              type: object
              required:
                - compensated_days
              properties:
                compensated_days:
                  description: Datos del ítem de vacaciones compensadas a registrar o eliminar.
                  type: object
                  required:
                    - quantity
                  properties:
                    quantity:
                      description: Número de días compensados a registrar. Enviar `0` para eliminar el ítem.
                      type: number
                      example: 5
            examples:
              Crear o actualizar días compensados:
                value:
                  compensated_days:
                    quantity: 5
              Eliminar ítem:
                value:
                  compensated_days:
                    quantity: 0
      responses:
        '202':
          description: |
            La estructura de `compensated_days` en la respuesta depende de la operación:

            - **Días registrados** (`quantity > 0`): retorna el ítem con `id`, `quantity` y `value`.
            - **Días eliminados** (`quantity: 0`): retorna un objeto con `message` de confirmación.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la operación con los totales recalculados.
                    oneOf:
                      - type: object
                        description: Días compensados registrados o actualizados.
                        required:
                          - period
                          - payroll
                          - compensated_days
                          - worker
                          - details
                        properties:
                          period:
                            description: Totales actualizados del periodo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al periodo en la base de datos.
                                type: string
                                example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                              workers_payment:
                                description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                                type: integer
                                example: 7750000
                              company_cost:
                                description: Costo total de la empresa en el periodo, en pesos colombianos.
                                type: integer
                                example: 9900000
                          payroll:
                            description: Totales actualizados de la nómina.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la nómina en la base de datos.
                                type: string
                                example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                              worker_payment:
                                description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                                type: integer
                                example: 1750000
                              company_cost:
                                description: Costo total de la empresa por esta nómina, en pesos colombianos.
                                type: integer
                                example: 2000000
                              novelties_days:
                                description: Total de días de novedades liquidados en la nómina.
                                type: integer
                                example: 5
                              novelties_value:
                                description: Total en pesos colombianos de novedades liquidadas en la nómina.
                                type: integer
                                example: 250000
                              overtime_hours:
                                description: Total de horas extras y recargos registrados en la nómina.
                                type: number
                                example: 0
                              overtime_value:
                                description: Total en pesos colombianos de horas extras y recargos.
                                type: integer
                                example: 0
                              salary_income:
                                description: Total en pesos colombianos de ingresos salariales de la nómina.
                                type: integer
                                example: 0
                              non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales de la nómina.
                                type: integer
                                example: 0
                              occasional_non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                                type: integer
                                example: 0
                              deductions:
                                description: Total en pesos colombianos de deducciones de la nómina.
                                type: integer
                                example: 0
                          compensated_days:
                            description: Ítem de vacaciones compensadas registrado o actualizado.
                            type: object
                            required:
                              - id
                              - quantity
                              - value
                            properties:
                              id:
                                description: Identificador único (ID) asignado al ítem de nómina en la base de datos.
                                type: string
                                example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                              payroll_concept_id:
                                description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                type: string
                                example: c3d4e5f6-a7b8-9012-cdef-012345678901
                              name:
                                description: Nombre del concepto de vacaciones compensadas.
                                type: string
                                example: Vacaciones compensadas
                              coded_name:
                                description: Nombre codificado interno del concepto.
                                type:
                                  - string
                                  - 'null'
                                example: compensated_days
                              quantity:
                                description: Número de días de vacaciones compensadas registrados.
                                type: number
                                example: 5
                              value:
                                description: Valor liquidado de las vacaciones compensadas en pesos colombianos.
                                type: integer
                                example: 250000
                          worker:
                            description: Datos actualizados de la persona relacionados con vacaciones.
                            type: object
                            properties:
                              accumulated_holidays:
                                description: Total de días de vacaciones acumulados por la persona tras la operación.
                                type: number
                                example: 8.5
                          details:
                            description: Desglose de totales de la nómina por categoría.
                            type: object
                            properties:
                              overtime:
                                description: Totales de horas extras de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas extras registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de horas extras en pesos colombianos.
                                    type: integer
                                    example: 0
                              surcharge:
                                description: Totales de recargos de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas con recargo registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de recargos en pesos colombianos.
                                    type: integer
                                    example: 0
                              company_overtime:
                                description: Totales de horas extras con conceptos creados por la empresa.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de horas extras con conceptos creados por la empresa.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                    type: integer
                                    example: 0
                              holidays:
                                description: Totales de vacaciones liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de vacaciones liquidados.
                                    type: integer
                                    example: 5
                                  value:
                                    description: Valor total de vacaciones en pesos colombianos.
                                    type: integer
                                    example: 250000
                              incapacities:
                                description: Totales de incapacidades liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de incapacidad liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de incapacidades en pesos colombianos.
                                    type: integer
                                    example: 0
                              licenses:
                                description: Totales de licencias liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de licencia liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de licencias en pesos colombianos.
                                    type: integer
                                    example: 0
                              additional_income:
                                description: Totales de ingresos adicionales de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de ingresos adicionales en pesos colombianos.
                                    type: integer
                                    example: 0
                              deductions:
                                description: Totales de deducciones de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de deducciones en pesos colombianos.
                                    type: integer
                                    example: 0
                              payroll_retention:
                                description: Totales de retención en la fuente de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de retención en la fuente en pesos colombianos.
                                    type: integer
                                    example: 0
                              loans:
                                description: Totales de préstamos descontados en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de préstamos descontados en pesos colombianos.
                                    type: integer
                                    example: 0
                      - type: object
                        description: Días compensados eliminados.
                        required:
                          - period
                          - payroll
                          - compensated_days
                          - worker
                          - details
                        properties:
                          period:
                            description: Totales actualizados del periodo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al periodo en la base de datos.
                                type: string
                                example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                              workers_payment:
                                description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                                type: integer
                                example: 7750000
                              company_cost:
                                description: Costo total de la empresa en el periodo, en pesos colombianos.
                                type: integer
                                example: 9900000
                          payroll:
                            description: Totales actualizados de la nómina.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la nómina en la base de datos.
                                type: string
                                example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                              worker_payment:
                                description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                                type: integer
                                example: 1500000
                              company_cost:
                                description: Costo total de la empresa por esta nómina, en pesos colombianos.
                                type: integer
                                example: 1800000
                              novelties_days:
                                description: Total de días de novedades liquidados en la nómina.
                                type: integer
                                example: 0
                              novelties_value:
                                description: Total en pesos colombianos de novedades liquidadas en la nómina.
                                type: integer
                                example: 0
                              overtime_hours:
                                description: Total de horas extras y recargos registrados en la nómina.
                                type: number
                                example: 0
                              overtime_value:
                                description: Total en pesos colombianos de horas extras y recargos.
                                type: integer
                                example: 0
                              salary_income:
                                description: Total en pesos colombianos de ingresos salariales de la nómina.
                                type: integer
                                example: 0
                              non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales de la nómina.
                                type: integer
                                example: 0
                              occasional_non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                                type: integer
                                example: 0
                              deductions:
                                description: Total en pesos colombianos de deducciones de la nómina.
                                type: integer
                                example: 0
                          compensated_days:
                            description: Confirmación de eliminación del ítem de vacaciones compensadas.
                            type: object
                            required:
                              - message
                            properties:
                              message:
                                description: Mensaje de confirmación indicando que el ítem fue eliminado.
                                type: string
                                example: Las vacaciones compensadas fueron eliminadas
                          worker:
                            description: Datos actualizados de la persona relacionados con vacaciones.
                            type: object
                            properties:
                              accumulated_holidays:
                                description: Total de días de vacaciones acumulados por la persona tras la operación.
                                type: number
                                example: 13.5
                          details:
                            description: Desglose de totales de la nómina por categoría.
                            type: object
                            properties:
                              overtime:
                                description: Totales de horas extras de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas extras registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de horas extras en pesos colombianos.
                                    type: integer
                                    example: 0
                              surcharge:
                                description: Totales de recargos de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas con recargo registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de recargos en pesos colombianos.
                                    type: integer
                                    example: 0
                              company_overtime:
                                description: Totales de horas extras con conceptos creados por la empresa.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de horas extras con conceptos creados por la empresa.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                    type: integer
                                    example: 0
                              holidays:
                                description: Totales de vacaciones liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de vacaciones liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de vacaciones en pesos colombianos.
                                    type: integer
                                    example: 0
                              incapacities:
                                description: Totales de incapacidades liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de incapacidad liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de incapacidades en pesos colombianos.
                                    type: integer
                                    example: 0
                              licenses:
                                description: Totales de licencias liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de licencia liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de licencias en pesos colombianos.
                                    type: integer
                                    example: 0
                              additional_income:
                                description: Totales de ingresos adicionales de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de ingresos adicionales en pesos colombianos.
                                    type: integer
                                    example: 0
                              deductions:
                                description: Totales de deducciones de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de deducciones en pesos colombianos.
                                    type: integer
                                    example: 0
                              payroll_retention:
                                description: Totales de retención en la fuente de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de retención en la fuente en pesos colombianos.
                                    type: integer
                                    example: 0
                              loans:
                                description: Totales de préstamos descontados en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de préstamos descontados en pesos colombianos.
                                    type: integer
                                    example: 0
              examples:
                Días registrados:
                  value:
                    data:
                      period:
                        id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                        workers_payment: 7750000
                        company_cost: 9900000
                      payroll:
                        id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        worker_payment: 1750000
                        company_cost: 2000000
                        novelties_days: 5
                        novelties_value: 250000
                        overtime_hours: 0
                        overtime_value: 0
                        salary_income: 0
                        non_salary_income: 0
                        occasional_non_salary_income: 0
                        deductions: 0
                      compensated_days:
                        id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                        payroll_concept_id: c3d4e5f6-a7b8-9012-cdef-012345678901
                        name: Vacaciones compensadas
                        coded_name: compensated_days
                        quantity: 5
                        value: 250000
                      worker:
                        accumulated_holidays: 8.5
                      details:
                        overtime:
                          quantity: 0
                          value: 0
                        surcharge:
                          quantity: 0
                          value: 0
                        company_overtime:
                          quantity: 0
                          value: 0
                        holidays:
                          quantity: 5
                          value: 250000
                        incapacities:
                          quantity: 0
                          value: 0
                        licenses:
                          quantity: 0
                          value: 0
                        additional_income:
                          quantity: null
                          value: 0
                        deductions:
                          quantity: null
                          value: 0
                        payroll_retention:
                          quantity: null
                          value: 0
                        loans:
                          quantity: null
                          value: 0
                Días eliminados:
                  value:
                    data:
                      period:
                        id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                        workers_payment: 7500000
                        company_cost: 9750000
                      payroll:
                        id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        worker_payment: 1500000
                        company_cost: 1800000
                        novelties_days: 0
                        novelties_value: 0
                        overtime_hours: 0
                        overtime_value: 0
                        salary_income: 0
                        non_salary_income: 0
                        occasional_non_salary_income: 0
                        deductions: 0
                      compensated_days:
                        message: Las vacaciones compensadas fueron eliminadas
                      worker:
                        accumulated_holidays: 13.5
                      details:
                        overtime:
                          quantity: 0
                          value: 0
                        surcharge:
                          quantity: 0
                          value: 0
                        company_overtime:
                          quantity: 0
                          value: 0
                        holidays:
                          quantity: 0
                          value: 0
                        incapacities:
                          quantity: 0
                          value: 0
                        licenses:
                          quantity: 0
                          value: 0
                        additional_income:
                          quantity: null
                          value: 0
                        deductions:
                          quantity: null
                          value: 0
                        payroll_retention:
                          quantity: null
                          value: 0
                        loans:
                          quantity: null
                          value: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
  /v1/{company_id}/payrolls/{payroll_id}/connectivity_aid:
    put:
      operationId: updateConnectivityAid
      tags:
        - Auxilio de conectividad
      summary: Actualizar auxilio de conectividad
      description: |
        **¿Qué hace este endpoint?**

        Registra o elimina el ítem de auxilio de conectividad en la nómina indicada.
        Enviar una cantidad mayor a cero crea o actualiza el ítem; enviar `0` lo elimina.
        La nómina se recalcula automáticamente tras aplicar el cambio.

        **¿Cuándo usar este endpoint?**

        * Registrar los días de auxilio de conectividad a pagar en la nómina de una persona.
        * Actualizar la cantidad de días previamente registrada.
        * Eliminar el ítem de auxilio de conectividad enviando `quantity: 0`.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Requisito de configuración:** La nómina debe tener habilitada la opción de auxilio de conectividad. Si no está habilitada, el endpoint retorna 422.
      requestBody:
        required: true
        description: Crear o actualizar auxilio / Eliminar auxilio
        content:
          application/json:
            schema:
              type: object
              required:
                - connectivity_aid
              properties:
                connectivity_aid:
                  description: Datos del ítem de auxilio de conectividad a registrar o eliminar.
                  type: object
                  required:
                    - quantity
                  properties:
                    quantity:
                      description: Número de días de auxilio de conectividad a registrar. Enviar `0` para eliminar el ítem.
                      type: number
                      example: 30
            examples:
              Crear o actualizar auxilio:
                value:
                  connectivity_aid:
                    quantity: 30
              Eliminar auxilio:
                value:
                  connectivity_aid:
                    quantity: 0
      responses:
        '202':
          description: |
            La estructura de `connectivity_aid` en la respuesta depende de la operación:

            - **Auxilio registrado** (`quantity > 0`): retorna el ítem con `id`, `quantity` y `value`.
            - **Auxilio eliminado** (`quantity: 0`): retorna un objeto con `message` de confirmación.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la operación con los totales recalculados.
                    oneOf:
                      - type: object
                        description: Auxilio de conectividad registrado o actualizado.
                        required:
                          - period
                          - payroll
                          - connectivity_aid
                          - details
                        properties:
                          period:
                            description: Totales actualizados del periodo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al periodo en la base de datos.
                                type: string
                                example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                              workers_payment:
                                description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                                type: integer
                                example: 7660000
                              company_cost:
                                description: Costo total de la empresa en el periodo, en pesos colombianos.
                                type: integer
                                example: 9810000
                          payroll:
                            description: Totales actualizados de la nómina.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la nómina en la base de datos.
                                type: string
                                example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                              worker_payment:
                                description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                                type: integer
                                example: 1660000
                              company_cost:
                                description: Costo total de la empresa por esta nómina, en pesos colombianos.
                                type: integer
                                example: 1950000
                              novelties_days:
                                description: Total de días de novedades liquidados en la nómina.
                                type: integer
                                example: 0
                              novelties_value:
                                description: Total en pesos colombianos de novedades liquidadas en la nómina.
                                type: integer
                                example: 0
                              overtime_hours:
                                description: Total de horas extras y recargos registrados en la nómina.
                                type: number
                                example: 0
                              overtime_value:
                                description: Total en pesos colombianos de horas extras y recargos.
                                type: integer
                                example: 0
                              salary_income:
                                description: Total en pesos colombianos de ingresos salariales de la nómina.
                                type: integer
                                example: 0
                              non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales de la nómina.
                                type: integer
                                example: 160000
                              occasional_non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                                type: integer
                                example: 0
                              deductions:
                                description: Total en pesos colombianos de deducciones de la nómina.
                                type: integer
                                example: 0
                          connectivity_aid:
                            description: Ítem de auxilio de conectividad registrado o actualizado.
                            type: object
                            required:
                              - id
                              - quantity
                              - value
                            properties:
                              id:
                                description: Identificador único (ID) asignado al ítem de nómina en la base de datos.
                                type: string
                                example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                              payroll_concept_id:
                                description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                                type: string
                                example: d4e5f6a7-b8c9-0123-defa-123456789012
                              name:
                                description: Nombre del concepto de auxilio de conectividad.
                                type: string
                                example: Auxilio de conectividad
                              coded_name:
                                description: Nombre codificado interno del concepto.
                                type:
                                  - string
                                  - 'null'
                                example: connectivity_aid
                              quantity:
                                description: Número de días de auxilio de conectividad registrados.
                                type: number
                                example: 30
                              value:
                                description: Valor liquidado del auxilio de conectividad en pesos colombianos.
                                type: integer
                                example: 160000
                          details:
                            description: Desglose de totales de la nómina por categoría.
                            type: object
                            properties:
                              overtime:
                                description: Totales de horas extras de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas extras registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de horas extras en pesos colombianos.
                                    type: integer
                                    example: 0
                              surcharge:
                                description: Totales de recargos de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas con recargo registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de recargos en pesos colombianos.
                                    type: integer
                                    example: 0
                              company_overtime:
                                description: Totales de horas extras con conceptos creados por la empresa.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de horas extras con conceptos creados por la empresa.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                    type: integer
                                    example: 0
                              holidays:
                                description: Totales de vacaciones liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de vacaciones liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de vacaciones en pesos colombianos.
                                    type: integer
                                    example: 0
                              incapacities:
                                description: Totales de incapacidades liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de incapacidad liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de incapacidades en pesos colombianos.
                                    type: integer
                                    example: 0
                              licenses:
                                description: Totales de licencias liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de licencia liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de licencias en pesos colombianos.
                                    type: integer
                                    example: 0
                              additional_income:
                                description: Totales de ingresos adicionales de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de ingresos adicionales en pesos colombianos.
                                    type: integer
                                    example: 160000
                              deductions:
                                description: Totales de deducciones de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de deducciones en pesos colombianos.
                                    type: integer
                                    example: 0
                              payroll_retention:
                                description: Totales de retención en la fuente de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de retención en la fuente en pesos colombianos.
                                    type: integer
                                    example: 0
                              loans:
                                description: Totales de préstamos descontados en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de préstamos descontados en pesos colombianos.
                                    type: integer
                                    example: 0
                      - type: object
                        description: Auxilio de conectividad eliminado.
                        required:
                          - period
                          - payroll
                          - connectivity_aid
                          - details
                        properties:
                          period:
                            description: Totales actualizados del periodo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al periodo en la base de datos.
                                type: string
                                example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                              workers_payment:
                                description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                                type: integer
                                example: 7660000
                              company_cost:
                                description: Costo total de la empresa en el periodo, en pesos colombianos.
                                type: integer
                                example: 9810000
                          payroll:
                            description: Totales actualizados de la nómina.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la nómina en la base de datos.
                                type: string
                                example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                              worker_payment:
                                description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                                type: integer
                                example: 1660000
                              company_cost:
                                description: Costo total de la empresa por esta nómina, en pesos colombianos.
                                type: integer
                                example: 1950000
                              novelties_days:
                                description: Total de días de novedades liquidados en la nómina.
                                type: integer
                                example: 0
                              novelties_value:
                                description: Total en pesos colombianos de novedades liquidadas en la nómina.
                                type: integer
                                example: 0
                              overtime_hours:
                                description: Total de horas extras y recargos registrados en la nómina.
                                type: number
                                example: 0
                              overtime_value:
                                description: Total en pesos colombianos de horas extras y recargos.
                                type: integer
                                example: 0
                              salary_income:
                                description: Total en pesos colombianos de ingresos salariales de la nómina.
                                type: integer
                                example: 0
                              non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales de la nómina.
                                type: integer
                                example: 160000
                              occasional_non_salary_income:
                                description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                                type: integer
                                example: 0
                              deductions:
                                description: Total en pesos colombianos de deducciones de la nómina.
                                type: integer
                                example: 0
                          connectivity_aid:
                            description: Confirmación de eliminación del ítem de auxilio de conectividad.
                            type: object
                            required:
                              - message
                            properties:
                              message:
                                description: Mensaje de confirmación indicando que el ítem fue eliminado.
                                type: string
                                example: El auxilio de conectividad fue eliminado
                          details:
                            description: Desglose de totales de la nómina por categoría.
                            type: object
                            properties:
                              overtime:
                                description: Totales de horas extras de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas extras registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de horas extras en pesos colombianos.
                                    type: integer
                                    example: 0
                              surcharge:
                                description: Totales de recargos de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de horas con recargo registradas.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor total de recargos en pesos colombianos.
                                    type: integer
                                    example: 0
                              company_overtime:
                                description: Totales de horas extras con conceptos creados por la empresa.
                                type: object
                                properties:
                                  quantity:
                                    description: Cantidad de horas extras con conceptos creados por la empresa.
                                    type: number
                                    example: 0
                                  value:
                                    description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                    type: integer
                                    example: 0
                              holidays:
                                description: Totales de vacaciones liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de vacaciones liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de vacaciones en pesos colombianos.
                                    type: integer
                                    example: 0
                              incapacities:
                                description: Totales de incapacidades liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de incapacidad liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de incapacidades en pesos colombianos.
                                    type: integer
                                    example: 0
                              licenses:
                                description: Totales de licencias liquidadas en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: Total de días de licencia liquidados.
                                    type: integer
                                    example: 0
                                  value:
                                    description: Valor total de licencias en pesos colombianos.
                                    type: integer
                                    example: 0
                              additional_income:
                                description: Totales de ingresos adicionales de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de ingresos adicionales en pesos colombianos.
                                    type: integer
                                    example: 160000
                              deductions:
                                description: Totales de deducciones de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de deducciones en pesos colombianos.
                                    type: integer
                                    example: 0
                              payroll_retention:
                                description: Totales de retención en la fuente de la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de retención en la fuente en pesos colombianos.
                                    type: integer
                                    example: 0
                              loans:
                                description: Totales de préstamos descontados en la nómina.
                                type: object
                                properties:
                                  quantity:
                                    description: No aplica para esta categoría. Retorna null.
                                    type:
                                      - 'null'
                                    example: null
                                  value:
                                    description: Valor total de préstamos descontados en pesos colombianos.
                                    type: integer
                                    example: 0
              examples:
                Auxilio registrado:
                  value:
                    data:
                      period:
                        id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                        workers_payment: 7660000
                        company_cost: 9810000
                      payroll:
                        id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        worker_payment: 1660000
                        company_cost: 1950000
                        novelties_days: 0
                        novelties_value: 0
                        overtime_hours: 0
                        overtime_value: 0
                        salary_income: 0
                        non_salary_income: 160000
                        occasional_non_salary_income: 0
                        deductions: 0
                      connectivity_aid:
                        id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                        payroll_concept_id: d4e5f6a7-b8c9-0123-defa-123456789012
                        name: Auxilio de conectividad
                        coded_name: connectivity_aid
                        quantity: 30
                        value: 160000
                      details:
                        overtime:
                          quantity: 0
                          value: 0
                        surcharge:
                          quantity: 0
                          value: 0
                        company_overtime:
                          quantity: 0
                          value: 0
                        holidays:
                          quantity: 0
                          value: 0
                        incapacities:
                          quantity: 0
                          value: 0
                        licenses:
                          quantity: 0
                          value: 0
                        additional_income:
                          quantity: null
                          value: 160000
                        deductions:
                          quantity: null
                          value: 0
                        payroll_retention:
                          quantity: null
                          value: 0
                        loans:
                          quantity: null
                          value: 0
                Auxilio eliminado:
                  value:
                    data:
                      period:
                        id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                        workers_payment: 7500000
                        company_cost: 9750000
                      payroll:
                        id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        worker_payment: 1500000
                        company_cost: 1800000
                        novelties_days: 0
                        novelties_value: 0
                        overtime_hours: 0
                        overtime_value: 0
                        salary_income: 0
                        non_salary_income: 0
                        occasional_non_salary_income: 0
                        deductions: 0
                      connectivity_aid:
                        message: El auxilio de conectividad fue eliminado
                      details:
                        overtime:
                          quantity: 0
                          value: 0
                        surcharge:
                          quantity: 0
                          value: 0
                        company_overtime:
                          quantity: 0
                          value: 0
                        holidays:
                          quantity: 0
                          value: 0
                        incapacities:
                          quantity: 0
                          value: 0
                        licenses:
                          quantity: 0
                          value: 0
                        additional_income:
                          quantity: null
                          value: 0
                        deductions:
                          quantity: null
                          value: 0
                        payroll_retention:
                          quantity: null
                          value: 0
                        loans:
                          quantity: null
                          value: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
  /v1/{company_id}/payrolls/{payroll_id}/items:
    get:
      operationId: indexPayrollItems
      tags:
        - Ítems de nómina
      summary: Listar ítems de nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna los ítems de nómina de una categoría específica para la nómina indicada.

        **¿Cuándo usar este endpoint?**

        * Obtener los ítems de ingresos no salariales, deducciones u otras categorías registrados en la nómina.
        * Consultar los ítems de préstamos junto con las deducciones para mostrarlos agrupados.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Categoría obligatoria:** El parámetro `category` debe enviarse siempre para filtrar los ítems por categoría.
      parameters:
        - in: query
          required: true
          name: category
          description: |
            Categoría de los ítems a consultar.

            Valores posibles:

            * `non_salary_income` — Ingresos no salariales.
            * `salary_income` — Ingresos salariales.
            * `occasional_non_salary_income` — Ingresos no salariales ocasionales.
            * `deductions` — Deducciones.
            * `loan` — Préstamos.
          schema:
            type: string
            enum:
              - non_salary_income
              - salary_income
              - occasional_non_salary_income
              - deductions
              - loan
            example: non_salary_income
      responses:
        '200':
          description: Ítems de la categoría retornados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de ítems de nómina de la categoría indicada.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al ítem de nómina en la base de datos.
                          type: string
                          example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        name:
                          description: Nombre del concepto de nómina.
                          type: string
                          example: Auxilio de transporte
                        coded_name:
                          description: Nombre codificado del concepto de nómina.
                          type:
                            - string
                            - 'null'
                          example: transport_subsidy
                        quantity:
                          description: Cantidad del ítem (horas para overtime, unidades para otros).
                          type: number
                          example: 1
                        value:
                          description: Valor monetario del ítem en pesos colombianos.
                          type: integer
                          example: 117172
              example:
                data:
                  - id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                    payroll_concept_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Auxilio de transporte
                    coded_name: transport_subsidy
                    quantity: 1
                    value: 117172
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    put:
      operationId: updatePayrollItems
      tags:
        - Ítems de nómina
      summary: Actualizar ítems de nómina
      description: |
        **¿Qué hace este endpoint?**

        Gestiona los ítems de nómina de una categoría en una sola operación. La acción se determina
        automáticamente según los campos enviados en cada objeto de `items`:

        * **Crear o actualizar:** Con `payroll_concept_id` y `value` — crea o actualiza el ítem correspondiente al concepto indicado.
        * **Eliminar:** Con `id` y `value: 0` — elimina el ítem si el valor enviado es cero.

        La nómina se recalcula automáticamente tras aplicar los cambios.

        **¿Cuándo usar este endpoint?**

        * Registrar un ingreso no salarial, deducción u otro concepto en la nómina de una persona.
        * Actualizar el valor de un ítem existente.
        * Eliminar un ítem enviando su valor en cero.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      requestBody:
        required: true
        description: Crear o actualizar ítem / Eliminar ítem
        content:
          application/json:
            schema:
              type: object
              required:
                - items
              properties:
                items:
                  description: Listado de ítems a crear, actualizar o eliminar.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al ítem de nómina en la base de datos. Requerido para eliminar. Omitir para crear.
                        type: string
                        example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos. Requerido para crear. Si se envía `id`, se infiere automáticamente.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      value:
                        description: Valor monetario del ítem en pesos colombianos. Requerido para crear o actualizar. Enviar `0` junto con `id` para eliminar el ítem.
                        type: integer
                        example: 100000
            examples:
              Crear o actualizar ítem:
                value:
                  items:
                    - payroll_concept_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      value: 100000
              Eliminar ítem:
                value:
                  items:
                    - id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                      payroll_concept_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      value: 0
      responses:
        '202':
          description: Ítems actualizados y nómina recalculada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la operación con los totales recalculados.
                    type: object
                    properties:
                      period:
                        description: Totales actualizados del periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7500000
                          company_cost:
                            description: Costo total de la empresa en el periodo, en pesos colombianos.
                            type: integer
                            example: 9750000
                      payroll:
                        description: Totales actualizados de la nómina.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la nómina en la base de datos.
                            type: string
                            example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          worker_payment:
                            description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                            type: integer
                            example: 1700000
                          company_cost:
                            description: Costo total de la empresa por esta nómina, en pesos colombianos.
                            type: integer
                            example: 2000000
                          novelties_days:
                            description: Total de días de novedades liquidados en la nómina.
                            type: integer
                            example: 0
                          novelties_value:
                            description: Total en pesos colombianos de novedades liquidadas en la nómina.
                            type: integer
                            example: 0
                          overtime_hours:
                            description: Total de horas extras y recargos registrados en la nómina.
                            type: number
                            example: 0
                          overtime_value:
                            description: Total en pesos colombianos de horas extras y recargos.
                            type: integer
                            example: 0
                          salary_income:
                            description: Total en pesos colombianos de ingresos salariales de la nómina.
                            type: integer
                            example: 0
                          non_salary_income:
                            description: Total en pesos colombianos de ingresos no salariales de la nómina.
                            type: integer
                            example: 100000
                          occasional_non_salary_income:
                            description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                            type: integer
                            example: 0
                          deductions:
                            description: Total en pesos colombianos de deducciones de la nómina.
                            type: integer
                            example: 0
                      items:
                        description: Ítems afectados por la operación con sus valores actualizados.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem de nómina en la base de datos.
                              type: string
                              example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            name:
                              description: Nombre del concepto de nómina.
                              type: string
                              example: Bono de alimentación
                            coded_name:
                              description: Nombre codificado del concepto de nómina.
                              type:
                                - string
                                - 'null'
                              example: bono_de_alimentacion
                            quantity:
                              description: Cantidad del ítem (horas para overtime, unidades para otros).
                              type: number
                              example: 1
                            value:
                              description: Valor monetario del ítem en pesos colombianos.
                              type: integer
                              example: 100000
                      details:
                        description: Desglose de totales de la nómina actualizada por categoría. Cada campo contiene `quantity` (cantidad, null si no aplica) y `value` (valor en pesos colombianos).
                        type: object
                        properties:
                          overtime:
                            description: Totales de horas extras de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas extras registradas.
                                type: number
                                example: 0
                              value:
                                description: Valor total de horas extras en pesos colombianos.
                                type: integer
                                example: 0
                          surcharge:
                            description: Totales de recargos de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas con recargo registradas.
                                type: number
                                example: 0
                              value:
                                description: Valor total de recargos en pesos colombianos.
                                type: integer
                                example: 0
                          company_overtime:
                            description: Totales de horas extras con conceptos creados por la empresa.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de horas extras con conceptos creados por la empresa.
                                type: number
                                example: 0
                              value:
                                description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                type: integer
                                example: 0
                          holidays:
                            description: Totales de vacaciones liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de vacaciones liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de vacaciones en pesos colombianos.
                                type: integer
                                example: 0
                          incapacities:
                            description: Totales de incapacidades liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de incapacidad liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de incapacidades en pesos colombianos.
                                type: integer
                                example: 0
                          licenses:
                            description: Totales de licencias liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de licencia liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de licencias en pesos colombianos.
                                type: integer
                                example: 0
                          additional_income:
                            description: Totales de ingresos adicionales de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de ingresos adicionales. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de ingresos adicionales en pesos colombianos.
                                type: integer
                                example: 100000
                          deductions:
                            description: Totales de deducciones de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de deducciones. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de deducciones en pesos colombianos.
                                type: integer
                                example: 0
                          payroll_retention:
                            description: Totales de retención en la fuente de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de retención. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de retención en la fuente en pesos colombianos.
                                type: integer
                                example: 0
                          loans:
                            description: Totales de préstamos descontados en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de préstamos. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de préstamos descontados en pesos colombianos.
                                type: integer
                                example: 0
              example:
                data:
                  period:
                    id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                    workers_payment: 7600000
                    company_cost: 9850000
                  payroll:
                    id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                    worker_payment: 1700000
                    company_cost: 2000000
                    novelties_days: 0
                    novelties_value: 0
                    overtime_hours: 0
                    overtime_value: 0
                    salary_income: 0
                    non_salary_income: 100000
                    occasional_non_salary_income: 0
                    deductions: 0
                  items:
                    - id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                      payroll_concept_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      name: Bono de alimentación
                      coded_name: bono_de_alimentacion
                      quantity: 1
                      value: 100000
                  details:
                    overtime:
                      quantity: 0
                      value: 0
                    surcharge:
                      quantity: 0
                      value: 0
                    company_overtime:
                      quantity: 0
                      value: 0
                    holidays:
                      quantity: 0
                      value: 0
                    incapacities:
                      quantity: 0
                      value: 0
                    licenses:
                      quantity: 0
                      value: 0
                    additional_income:
                      quantity: null
                      value: 100000
                    deductions:
                      quantity: null
                      value: 0
                    payroll_retention:
                      quantity: null
                      value: 0
                    loans:
                      quantity: null
                      value: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
  /v1/{company_id}/payrolls/{payroll_id}/novelties:
    get:
      operationId: indexPayrollNovelties
      tags:
        - Novedades
      summary: Listar novedades de la nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna las novedades (vacaciones, incapacidades, licencias) registradas en la nómina indicada.

        **¿Cuándo usar este endpoint?**

        * Consultar las novedades activas de una persona en un periodo antes de editarlas.
        * Verificar si hay vacaciones o incapacidades registradas en la nómina antes de procesarla.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Novedades de la nómina retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de novedades registradas en la nómina.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la novedad en la base de datos.
                          type: string
                          example: d4e5f6a7-b8c9-0123-defa-123456789012
                        contract_id:
                          description: Identificador único (ID) asignado al contrato en la base de datos.
                          type: string
                          example: 3c4d5e6f-7a8b-9012-cdef-123456789012
                        payroll_id:
                          description: Identificador único (ID) asignado a la nómina en la base de datos.
                          type: string
                          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: e5f6a7b8-c9d0-1234-efab-234567890123
                        name:
                          description: Nombre del concepto de novedad.
                          type: string
                          example: Vacaciones disfrutadas
                        coded_name:
                          description: Nombre codificado del concepto de novedad.
                          type: string
                          example: enjoyed_days
                        code:
                          description: Código de la novedad según la norma. Presente solo para novedades de vacaciones calculadas.
                          type:
                            - string
                            - 'null'
                          example: null
                        counterpart_code:
                          description: Código de contrapartida de la novedad. Presente solo para novedades de vacaciones calculadas.
                          type:
                            - string
                            - 'null'
                          example: null
                        initial_day:
                          description: Fecha de inicio de la novedad en formato `YYYY-MM-DD`.
                          type: string
                          example: '2024-01-02'
                        end_day:
                          description: Fecha de fin de la novedad en formato `YYYY-MM-DD`.
                          type: string
                          example: '2024-01-16'
                        days:
                          description: Número de días de la novedad.
                          type: integer
                          example: 15
                        value:
                          description: Valor monetario de la novedad en pesos colombianos.
                          type: integer
                          example: 1500000
              examples:
                Con novedades:
                  value:
                    data:
                      - id: d4e5f6a7-b8c9-0123-defa-123456789012
                        contract_id: 3c4d5e6f-7a8b-9012-cdef-123456789012
                        payroll_id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                        name: Vacaciones disfrutadas
                        coded_name: enjoyed_days
                        code: null
                        counterpart_code: null
                        initial_day: '2024-01-02'
                        end_day: '2024-01-16'
                        days: 15
                        value: 1500000
                Sin novedades:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updatePayrollNovelties
      tags:
        - Novedades
      summary: Crear, actualizar o eliminar novedades
      description: |
        **¿Qué hace este endpoint?**

        Gestiona las novedades de la nómina en una sola operación. La acción se determina
        automáticamente según los campos enviados en cada objeto de `novelties`:

        * **Crear:** Sin `id` — crea una nueva novedad con el concepto, fecha de inicio y fecha de fin indicados.
        * **Actualizar:** Con `id` — actualiza las fechas de una novedad existente.
        * **Eliminar:** Con `id` sin `initial_day` ni `end_day` — elimina la novedad.

        La nómina se recalcula automáticamente tras aplicar los cambios.

        **¿Cuándo usar este endpoint?**

        * Registrar vacaciones, incapacidades o licencias en la nómina de una persona.
        * Actualizar las fechas de una novedad ya registrada.
        * Eliminar una novedad que fue ingresada por error.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Conceptos disponibles:** Usar `GET /v1/{company_id}/payroll_concepts?category=novelties` para obtener los conceptos válidos según el tipo de contrato y la fecha de inicio.
      requestBody:
        required: true
        description: Crear novedad / Actualizar novedad / Eliminar novedad
        content:
          application/json:
            schema:
              type: object
              required:
                - novelties
              properties:
                novelties:
                  description: Listado de novedades a crear, actualizar o eliminar.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) de la novedad existente. Omitir para crear una nueva.
                        type: string
                        example: d4e5f6a7-b8c9-0123-defa-123456789012
                      payroll_concept_id:
                        description: Identificador único (ID) del concepto de novedad.
                        type: string
                        example: e5f6a7b8-c9d0-1234-efab-234567890123
                      initial_day:
                        description: Fecha de inicio de la novedad en formato `YYYY-MM-DD`. Omitir junto con `end_day` para eliminar.
                        type: string
                        format: date
                        example: '2024-01-02'
                      end_day:
                        description: Fecha de fin de la novedad en formato `YYYY-MM-DD`. Omitir junto con `initial_day` para eliminar.
                        type: string
                        format: date
                        example: '2024-01-16'
            examples:
              Crear novedad:
                value:
                  novelties:
                    - payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                      initial_day: '2024-01-02'
                      end_day: '2024-01-16'
              Actualizar novedad:
                value:
                  novelties:
                    - id: d4e5f6a7-b8c9-0123-defa-123456789012
                      initial_day: '2024-01-05'
                      end_day: '2024-01-20'
              Eliminar novedad:
                value:
                  novelties:
                    - id: d4e5f6a7-b8c9-0123-defa-123456789012
      responses:
        '202':
          description: Novedades actualizadas y nómina recalculada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la operación con los totales recalculados.
                    type: object
                    properties:
                      period:
                        description: Totales actualizados del periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7500000
                          company_cost:
                            description: Costo total de la empresa en el periodo, en pesos colombianos.
                            type: integer
                            example: 9750000
                      payroll:
                        description: Totales actualizados de la nómina.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la nómina en la base de datos.
                            type: string
                            example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          worker_payment:
                            description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                            type: integer
                            example: 1500000
                          company_cost:
                            description: Costo total de la empresa por esta nómina, en pesos colombianos.
                            type: integer
                            example: 1800000
                          novelties_days:
                            description: Total de días de novedades liquidados en la nómina.
                            type: integer
                            example: 15
                          novelties_value:
                            description: Total en pesos colombianos de novedades liquidadas en la nómina.
                            type: integer
                            example: 1500000
                          overtime_hours:
                            description: Total de horas extras y recargos registrados en la nómina.
                            type: number
                            example: 0
                          overtime_value:
                            description: Total en pesos colombianos de horas extras y recargos.
                            type: integer
                            example: 0
                          salary_income:
                            description: Total en pesos colombianos de ingresos salariales de la nómina.
                            type: integer
                            example: 0
                          non_salary_income:
                            description: Total en pesos colombianos de ingresos no salariales de la nómina.
                            type: integer
                            example: 0
                          occasional_non_salary_income:
                            description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                            type: integer
                            example: 0
                          deductions:
                            description: Total en pesos colombianos de deducciones de la nómina.
                            type: integer
                            example: 0
                      novelties:
                        description: Novedades afectadas con sus valores actualizados.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la novedad en la base de datos.
                              type: string
                              example: d4e5f6a7-b8c9-0123-defa-123456789012
                            contract_id:
                              description: Identificador único (ID) asignado al contrato en la base de datos.
                              type: string
                              example: 3c4d5e6f-7a8b-9012-cdef-123456789012
                            payroll_id:
                              description: Identificador único (ID) asignado a la nómina en la base de datos.
                              type: string
                              example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: e5f6a7b8-c9d0-1234-efab-234567890123
                            name:
                              description: Nombre del concepto de novedad.
                              type: string
                              example: Vacaciones disfrutadas
                            coded_name:
                              description: Nombre codificado del concepto de novedad.
                              type: string
                              example: enjoyed_days
                            code:
                              description: Código de la novedad según la norma. Presente solo para novedades de vacaciones calculadas.
                              type:
                                - string
                                - 'null'
                              example: null
                            counterpart_code:
                              description: Código de contrapartida de la novedad. Presente solo para novedades de vacaciones calculadas.
                              type:
                                - string
                                - 'null'
                              example: null
                            initial_day:
                              description: Fecha de inicio de la novedad en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-02'
                            end_day:
                              description: Fecha de fin de la novedad en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-16'
                            days:
                              description: Número de días de la novedad.
                              type: integer
                              example: 15
                            value:
                              description: Valor monetario de la novedad en pesos colombianos.
                              type: integer
                              example: 1500000
                      worker:
                        description: Datos actualizados de la persona relacionados con vacaciones.
                        type: object
                        properties:
                          accumulated_holidays:
                            description: Total de días de vacaciones acumulados por la persona.
                            type: number
                            example: 0
                      details:
                        description: Desglose de totales de la nómina por categoría.
                        type: object
                        properties:
                          overtime:
                            description: Totales de horas extras de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas extras registradas.
                                type: number
                                example: 0
                              value:
                                description: Valor total de horas extras en pesos colombianos.
                                type: integer
                                example: 0
                          surcharge:
                            description: Totales de recargos de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas con recargo registradas.
                                type: number
                                example: 0
                              value:
                                description: Valor total de recargos en pesos colombianos.
                                type: integer
                                example: 0
                          company_overtime:
                            description: Totales de horas extras con conceptos creados por la empresa.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de horas extras con conceptos creados por la empresa.
                                type: number
                                example: 0
                              value:
                                description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                type: integer
                                example: 0
                          holidays:
                            description: Totales de vacaciones liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de vacaciones liquidados.
                                type: integer
                                example: 15
                              value:
                                description: Valor total de vacaciones en pesos colombianos.
                                type: integer
                                example: 1500000
                          incapacities:
                            description: Totales de incapacidades liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de incapacidad liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de incapacidades en pesos colombianos.
                                type: integer
                                example: 0
                          licenses:
                            description: Totales de licencias liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de licencia liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de licencias en pesos colombianos.
                                type: integer
                                example: 0
                          additional_income:
                            description: Totales de ingresos adicionales de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de ingresos adicionales. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de ingresos adicionales en pesos colombianos.
                                type: integer
                                example: 0
                          deductions:
                            description: Totales de deducciones de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de deducciones. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de deducciones en pesos colombianos.
                                type: integer
                                example: 0
                          payroll_retention:
                            description: Totales de retención en la fuente de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de retención. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de retención en la fuente en pesos colombianos.
                                type: integer
                                example: 0
                          loans:
                            description: Totales de préstamos descontados en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de préstamos. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de préstamos descontados en pesos colombianos.
                                type: integer
                                example: 0
              example:
                data:
                  period:
                    id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                    workers_payment: 7500000
                    company_cost: 9750000
                  payroll:
                    id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                    worker_payment: 1500000
                    company_cost: 1800000
                    novelties_days: 15
                    novelties_value: 1500000
                    overtime_hours: 0
                    overtime_value: 0
                    salary_income: 0
                    non_salary_income: 0
                    occasional_non_salary_income: 0
                    deductions: 0
                  novelties:
                    - id: d4e5f6a7-b8c9-0123-defa-123456789012
                      contract_id: 3c4d5e6f-7a8b-9012-cdef-123456789012
                      payroll_id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                      payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                      name: Vacaciones disfrutadas
                      coded_name: enjoyed_days
                      code: null
                      counterpart_code: null
                      initial_day: '2024-01-02'
                      end_day: '2024-01-16'
                      days: 15
                      value: 1500000
                  worker:
                    accumulated_holidays: 0
                  details:
                    overtime:
                      quantity: 0
                      value: 0
                    surcharge:
                      quantity: 0
                      value: 0
                    company_overtime:
                      quantity: 0
                      value: 0
                    holidays:
                      quantity: 15
                      value: 1500000
                    incapacities:
                      quantity: 0
                      value: 0
                    licenses:
                      quantity: 0
                      value: 0
                    additional_income:
                      quantity: null
                      value: 0
                    deductions:
                      quantity: null
                      value: 0
                    payroll_retention:
                      quantity: null
                      value: 0
                    loans:
                      quantity: null
                      value: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
  /v1/{company_id}/payrolls/{payroll_id}/overtime_items:
    get:
      operationId: indexOvertimeItems
      tags:
        - Horas extras y recargos
      summary: Listar ítems de horas extras
      description: |
        **¿Qué hace este endpoint?**

        Retorna los ítems de horas extras y recargos registrados en la nómina indicada.

        **¿Cuándo usar este endpoint?**

        * Consultar las horas extras y recargos registrados en la nómina antes de mostrarlos o editarlos.
        * Verificar qué conceptos de horas extras tiene activos una persona en un periodo determinado.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Con ítems de horas extras / Sin ítems de horas extras
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de ítems de horas extras y recargos de la nómina.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al ítem de nómina en la base de datos.
                          type: string
                          example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        name:
                          description: Nombre del concepto de horas extras.
                          type: string
                          example: Hora extra diurna
                        coded_name:
                          description: Nombre codificado del concepto.
                          type:
                            - string
                            - 'null'
                          example: daily_hour
                        quantity:
                          description: Número de horas registradas.
                          type: number
                          example: 4
                        value:
                          description: Valor monetario del ítem en pesos colombianos.
                          type: integer
                          example: 50000
              examples:
                Con ítems de horas extras:
                  value:
                    data:
                      - id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                        payroll_concept_id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        name: Hora extra diurna
                        coded_name: daily_hour
                        quantity: 4
                        value: 50000
                Sin ítems de horas extras:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateOvertimeItems
      tags:
        - Horas extras y recargos
      summary: Crear, actualizar o eliminar horas extras
      description: |
        **¿Qué hace este endpoint?**

        Registra o elimina horas extras y recargos en la nómina indicada. La acción se determina
        automáticamente según la cantidad enviada:

        * **Registrar:** Con `payroll_concept_id` y `quantity` mayor a cero — crea o actualiza el ítem del concepto indicado.
        * **Eliminar:** Con `quantity: 0` — elimina el ítem si existe.

        La nómina se recalcula automáticamente tras aplicar los cambios.

        **¿Cuándo usar este endpoint?**

        * Registrar horas extras diurnas, nocturnas o dominicales en la nómina de una persona.
        * Actualizar la cantidad de horas de un concepto ya registrado.
        * Eliminar un ítem de horas extras enviando su cantidad en cero.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Conceptos válidos:** Solo se aceptan conceptos de categoría `overtime`. Para obtener los conceptos disponibles usar `GET /v1/{company_id}/payroll_concepts?category=overtime`.
      requestBody:
        required: true
        description: Crear o actualizar horas extras / Eliminar ítem
        content:
          application/json:
            schema:
              type: object
              required:
                - items
              properties:
                items:
                  description: Listado de ítems de horas extras a registrar o eliminar.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al ítem de nómina en la base de datos. Omitir para crear uno nuevo.
                        type: string
                        example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                        type: string
                        example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      quantity:
                        description: Número de horas a registrar. Enviar `0` para eliminar el ítem.
                        type: number
                        example: 4
            examples:
              Crear o actualizar horas extras:
                value:
                  items:
                    - payroll_concept_id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      quantity: 4
              Eliminar ítem:
                value:
                  items:
                    - id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                      payroll_concept_id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      quantity: 0
      responses:
        '202':
          description: Ítems de horas extras actualizados y nómina recalculada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la operación con los totales recalculados.
                    type: object
                    properties:
                      period:
                        description: Totales actualizados del periodo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7550000
                          company_cost:
                            description: Costo total de la empresa en el periodo, en pesos colombianos.
                            type: integer
                            example: 9800000
                      payroll:
                        description: Totales actualizados de la nómina.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la nómina en la base de datos.
                            type: string
                            example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          worker_payment:
                            description: Total neto a pagar a la persona en esta nómina, en pesos colombianos.
                            type: integer
                            example: 1750000
                          company_cost:
                            description: Costo total de la empresa por esta nómina, en pesos colombianos.
                            type: integer
                            example: 2050000
                          novelties_days:
                            description: Total de días de novedades liquidados en la nómina.
                            type: integer
                            example: 0
                          novelties_value:
                            description: Total en pesos colombianos de novedades liquidadas en la nómina.
                            type: integer
                            example: 0
                          overtime_hours:
                            description: Total de horas extras y recargos registrados en la nómina.
                            type: number
                            example: 4
                          overtime_value:
                            description: Total en pesos colombianos de horas extras y recargos.
                            type: integer
                            example: 50000
                          salary_income:
                            description: Total en pesos colombianos de ingresos salariales de la nómina.
                            type: integer
                            example: 0
                          non_salary_income:
                            description: Total en pesos colombianos de ingresos no salariales de la nómina.
                            type: integer
                            example: 0
                          occasional_non_salary_income:
                            description: Total en pesos colombianos de ingresos no salariales ocasionales de la nómina.
                            type: integer
                            example: 0
                          deductions:
                            description: Total en pesos colombianos de deducciones de la nómina.
                            type: integer
                            example: 0
                      items:
                        description: Ítems de horas extras afectados con sus valores actualizados.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem de nómina en la base de datos.
                              type: string
                              example: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                            name:
                              description: Nombre del concepto de horas extras.
                              type: string
                              example: Hora extra diurna
                            coded_name:
                              description: Nombre codificado del concepto.
                              type:
                                - string
                                - 'null'
                              example: daily_hour
                            quantity:
                              description: Número de horas registradas.
                              type: number
                              example: 4
                            value:
                              description: Valor monetario del ítem en pesos colombianos.
                              type: integer
                              example: 50000
                      details:
                        description: Desglose de totales de la nómina por categoría.
                        type: object
                        properties:
                          overtime:
                            description: Totales de horas extras de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas extras registradas.
                                type: number
                                example: 4
                              value:
                                description: Valor total de horas extras en pesos colombianos.
                                type: integer
                                example: 50000
                          surcharge:
                            description: Totales de recargos de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de horas con recargo registradas.
                                type: number
                                example: 0
                              value:
                                description: Valor total de recargos en pesos colombianos.
                                type: integer
                                example: 0
                          company_overtime:
                            description: Totales de horas extras con conceptos creados por la empresa.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de horas extras con conceptos creados por la empresa.
                                type: number
                                example: 0
                              value:
                                description: Valor en pesos colombianos de las horas extras con conceptos creados por la empresa.
                                type: integer
                                example: 0
                          holidays:
                            description: Totales de vacaciones liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de vacaciones liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de vacaciones en pesos colombianos.
                                type: integer
                                example: 0
                          incapacities:
                            description: Totales de incapacidades liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de incapacidad liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de incapacidades en pesos colombianos.
                                type: integer
                                example: 0
                          licenses:
                            description: Totales de licencias liquidadas en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Total de días de licencia liquidados.
                                type: integer
                                example: 0
                              value:
                                description: Valor total de licencias en pesos colombianos.
                                type: integer
                                example: 0
                          additional_income:
                            description: Totales de ingresos adicionales de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de ingresos adicionales. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de ingresos adicionales en pesos colombianos.
                                type: integer
                                example: 0
                          deductions:
                            description: Totales de deducciones de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de deducciones. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de deducciones en pesos colombianos.
                                type: integer
                                example: 0
                          payroll_retention:
                            description: Totales de retención en la fuente de la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de retención. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de retención en la fuente en pesos colombianos.
                                type: integer
                                example: 0
                          loans:
                            description: Totales de préstamos descontados en la nómina.
                            type: object
                            properties:
                              quantity:
                                description: Cantidad de ítems de préstamos. Siempre null para esta categoría.
                                type: 'null'
                                example: null
                              value:
                                description: Valor total de préstamos descontados en pesos colombianos.
                                type: integer
                                example: 0
              example:
                data:
                  period:
                    id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                    workers_payment: 7550000
                    company_cost: 9800000
                  payroll:
                    id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                    worker_payment: 1750000
                    company_cost: 2050000
                    novelties_days: 0
                    novelties_value: 0
                    overtime_hours: 4
                    overtime_value: 50000
                    salary_income: 0
                    non_salary_income: 0
                    occasional_non_salary_income: 0
                    deductions: 0
                  items:
                    - id: f1a2b3c4-d5e6-7890-abcd-ef1234567890
                      payroll_concept_id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      name: Hora extra diurna
                      coded_name: daily_hour
                      quantity: 4
                      value: 50000
                  details:
                    overtime:
                      quantity: 4
                      value: 50000
                    surcharge:
                      quantity: 0
                      value: 0
                    company_overtime:
                      quantity: 0
                      value: 0
                    holidays:
                      quantity: 0
                      value: 0
                    incapacities:
                      quantity: 0
                      value: 0
                    licenses:
                      quantity: 0
                      value: 0
                    additional_income:
                      quantity: null
                      value: 0
                    deductions:
                      quantity: null
                      value: 0
                    payroll_retention:
                      quantity: null
                      value: 0
                    loans:
                      quantity: null
                      value: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
  /v1/{company_id}/payrolls/{payroll_id}/payslip:
    get:
      operationId: showPayrollPayslip
      tags:
        - Desprendibles de pago
      summary: Generar colilla de nómina individual
      description: |
        **¿Qué hace este endpoint?**

        Genera la colilla de pago de una nómina individual y retorna la URL del archivo PDF.
        Permite elegir qué sección de la nómina incluir: la nómina estándar, la liquidación de
        contrato, las prestaciones sociales o combinaciones de estas. Para nóminas liquidadas con
        anticipo, también permite generar la colilla de una quincena específica o del periodo completo.

        **¿Cuándo usar este endpoint?**

        * Descargar la colilla de una persona específica después de liquidar su nómina.
        * Generar el desprendible de liquidación cuando la nómina incluye terminación de contrato.
        * Obtener la colilla de prestaciones sociales cuando la nómina incluye prima o cesantías.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Tipo de colilla según contenido:** Solo se puede solicitar un tipo si la nómina contiene esa información. Si el tipo no corresponde al contenido de la nómina, el endpoint retorna 422.
        * **Modo asíncrono:** Cuando `async: true`, el endpoint retorna inmediatamente con `message: Procesando`. El resultado se publica en Firebase en `users/{user_id}/payrolls/{payroll_id}/payslips`.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          name: payroll_range
          required: false
          schema:
            $ref: '#/components/schemas/PayrollRange'
        - in: query
          required: false
          name: payslip_type
          schema:
            $ref: '#/components/schemas/PayslipType'
      responses:
        '200':
          description: Colilla síncrona / Colilla asíncrona
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta síncrona — retorna la URL del PDF generado.
                    properties:
                      file:
                        description: URL de descarga del archivo PDF de la colilla generada.
                        type: string
                        example: https://storage.example.com/payslips/nomina-enero-2024.pdf
                    required:
                      - file
                  - type: object
                    description: Respuesta asíncrona — la generación fue encolada.
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación indicando que el archivo está siendo procesado.
                            type: string
                            example: Procesando
                    required:
                      - data
              examples:
                Colilla síncrona:
                  value:
                    file: https://storage.example.com/payslips/nomina-enero-2024.pdf
                Colilla asíncrona:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de colilla inválido / Rango de fechas inválido / Error al generar el archivo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Tipo de colilla inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Tipo de colilla es inválido.
                        object: payslip_type
                Rango de fechas inválido:
                  value:
                    error:
                      - code: '0407'
                        index: 0
                        message: El rango de fechas es inválido.
                        object: payslip_range
                Error al generar el archivo:
                  value:
                    error:
                      - code: '0602'
                        index: 0
                        message: No es posible generar el archivo.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 3de5e282-6a26-5896-b2ab-ed2dcaf1f01d
  /v1/{company_id}/payrolls/{payroll_id}/payslip_mail:
    post:
      operationId: createPayrollPayslipMail
      tags:
        - Desprendibles de pago
      summary: Enviar colilla de pago por correo o WhatsApp
      description: |
        **¿Qué hace este endpoint?**

        Envía la colilla de pago de una nómina específica al correo electrónico de la persona o por WhatsApp.

        **¿Cuándo usar este endpoint?**

        * Notificar a una persona que su colilla de pago está disponible después de liquidar la nómina.
        * Enviar el desprendible de liquidación cuando la nómina incluye terminación de contrato.
        * Usar WhatsApp como canal alternativo al correo cuando la persona no tiene email registrado.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Correo requerido:** Si se envía por correo (`whatsapp_notification: false` o sin enviar), la persona debe tener un correo electrónico registrado. De lo contrario el endpoint retorna 404.
        * **Canal WhatsApp:** Si `whatsapp_notification: true`, el envío se realiza por WhatsApp y no se valida la presencia de correo electrónico.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                payslip_type:
                  description: Tipo de colilla a enviar. Si no se envía, se usa `payroll` por defecto.
                  $ref: '#/components/schemas/PayslipType'
                whatsapp_notification:
                  description: Si es `true`, envía la colilla por WhatsApp en lugar de correo electrónico.
                  type: boolean
                  example: false
                payroll_range:
                  $ref: '#/components/schemas/PayrollRange'
      responses:
        '200':
          description: Colilla enviada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del envío.
                        type: string
                        example: La colilla fue enviada.
                required:
                  - data
              example:
                data:
                  message: La colilla fue enviada.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Persona sin correo electrónico registrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0003'
                    index: 0
                    message: La persona no tiene un correo electrónico asociado.
                    object: worker
        '422':
          description: Tipo de colilla inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 162b2dca-bfed-4ed2-bff1-c98b249a4b4d
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 3de5e282-6a26-5896-b2ab-ed2dcaf1f01d
  /v1/{company_id}/payrolls/{payroll_id}/payslip_options:
    get:
      operationId: showPayrollPayslipOptions
      tags:
        - Desprendibles de pago
      summary: Obtener opciones de colilla de una nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones disponibles para generar la colilla de pago de una nómina específica:
        los tipos de colilla disponibles y, si la nómina tiene anticipo de nómina, los rangos de
        fecha seleccionables.

        **¿Cuándo usar este endpoint?**

        * Consultar los tipos de colilla disponibles antes de llamar al endpoint de generación o envío.
        * Obtener los rangos de fecha disponibles cuando la nómina fue liquidada con anticipo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Opciones de colilla retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones disponibles para la colilla de la nómina.
                    type: object
                    properties:
                      payslip_type:
                        description: Lista de tipos de colilla disponibles para esta nómina.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Nombre legible del tipo de colilla.
                              type: string
                              example: Nómina más intereses de las cesantías
                            value:
                              description: Valor a enviar en el parámetro `payslip_type` al generar o enviar la colilla.
                              type: string
                              example: payroll_severance_interests
                          required:
                            - label
                            - value
                      payroll_range:
                        description: Rangos de fecha disponibles para elegir al generar o enviar la colilla. Retorna un arreglo vacío cuando la nómina no fue liquidada con anticipo. Sus valores deben usarse como `payroll_range` al generar o enviar la colilla.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Nombre legible del rango de fechas.
                              type: string
                              example: Del 1 al 15 (Nómina)
                            value:
                              description: Valor a enviar en el parámetro `payroll_range`. Puede ser una cadena (`full_period`) o un entero como índice del rango.
                              type:
                                - string
                                - integer
                              example: full_period
                          required:
                            - label
                            - value
                    required:
                      - payslip_type
                      - payroll_range
                required:
                  - data
              example:
                data:
                  payslip_type:
                    - label: Nómina más intereses de las cesantías
                      value: payroll_severance_interests
                    - label: Nómina
                      value: payroll
                    - label: Intereses de las cesantías
                      value: severance_interests
                  payroll_range:
                    - label: Periodo completo
                      value: full_period
                    - label: Del 1 al 7 (Nómina más vacaciones)
                      value: 0
                    - label: Del 8 al 15 (Nómina)
                      value: 1
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 2544c76f-dbe5-4d02-83ce-0cb59c2bd882
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 3de5e282-6a26-5896-b2ab-ed2dcaf1f01d
  /v1/{company_id}/payrolls/{payroll_id}/view_details:
    get:
      operationId: showPayrollViewDetails
      tags:
        - Nóminas
      summary: Obtener detalles de nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de cálculo de una nómina organizado en secciones: encabezado, detalle de colilla, seguridad social y parafiscales, provisiones de prestaciones, prestaciones sociales liquidadas, retención en la fuente y liquidación laboral. Cada sección es opcional y se solicita mediante el parámetro `details_section`.

        **¿Cuándo usar este endpoint?**

        * Cargar el detalle completo de una nómina para mostrar el desglose de ingresos, deducciones y aportes de empresa.
        * Obtener el cálculo de una liquidación laboral con sus indemnizaciones y prestaciones.
        * Consultar la retención en la fuente aplicada a una nómina específica.
        * Verificar las provisiones de prestaciones sociales calculadas en el periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Secciones opcionales:** Si no se envía `details_section`, se retornan las secciones por defecto: `header`, `payslip_detail`, `social_security_and_parafiscals` y `social_benefits_provisions`. Se pueden solicitar secciones adicionales como `social_benefits`, `payroll_retention` o `termination`.
        * **Solo contratos laborales:** El endpoint no está disponible para nóminas de contratistas. Retorna 422 si la nómina corresponde a un contrato de tipo contratista.
      parameters:
        - in: query
          required: false
          name: details_section
          description: 'Secciones del detalle a retornar, separadas por coma. Si no se envía, retorna las secciones por defecto: header, payslip_detail, social_security_and_parafiscals y social_benefits_provisions. Valores posibles adicionales: social_benefits, payroll_retention, termination.'
          schema:
            type: string
            example: header,payslip_detail,social_security_and_parafiscals
        - in: query
          required: false
          name: payroll_retention_file
          description: Si es `true`, genera el archivo de retención en la fuente de forma asíncrona y notifica el resultado vía Firebase en `payroll_retentions/{payroll_id}/view_details`.
          schema:
            type: boolean
            example: false
        - in: query
          required: false
          name: social_benefit_period_id
          description: Identificador único (ID) del periodo de prestaciones sociales a consultar en la sección `social_benefits`.
          schema:
            type: string
            example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
        - in: query
          required: false
          name: termination_date
          description: Fecha de terminación del contrato para el cálculo de la liquidación laboral en la sección `termination`. Formato `YYYY-MM-DD`.
          schema:
            type: string
            format: date
            example: '2024-01-31'
        - in: query
          required: false
          name: with_just_cause
          description: Indica si la terminación del contrato fue con justa causa, para el cálculo de indemnización en la sección `termination`.
          schema:
            type: boolean
            example: false
      responses:
        '200':
          description: Detalle de cálculo de la nómina por secciones
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de detalle de la nómina organizados por sección.
                    type: object
                    properties:
                      termination:
                        description: Sección de liquidación laboral con las bases de cálculo y los conceptos liquidados.
                        type: object
                        properties:
                          termination_base:
                            description: Base de cálculo del salario promedio para la liquidación laboral.
                            type: object
                            properties:
                              information:
                                description: Información explicativa del cálculo con título, descripción y fórmulas de referencia.
                                type: object
                                properties:
                                  title:
                                    description: Título del cálculo mostrado en la sección.
                                    type: string
                                    example: Salario base
                                  description:
                                    description: Explicación del método de cálculo aplicado.
                                    type: string
                                    example: Se calcula como el promedio de ingresos salariales del año en el que se terminó el contrato, incluyendo bonificaciones, comisiones, horas extras, recargos y demás ingresos constitutivos de salario. Ten en cuenta que Aleluya calcula el promedio con la información histórica que tengas registrada.
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: string
                                      example: termination_base
                                    example:
                                      - termination_base
                                  link:
                                    description: URL del artículo de ayuda que explica el cálculo.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-el-salario-base-en-una-liquidaci%C3%B3n-laboral
                              data:
                                description: Filas del detalle de cálculo, una por periodo liquidado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha del periodo de la fila en formato YYYY-MM-DD. Ausente en la fila de totales.
                                      type: string
                                      example: '2019-10-31'
                                    worked_days:
                                      description: Días trabajados en el periodo.
                                      type: integer
                                      example: 15
                                    average_salary:
                                      description: Salario promedio calculado para el periodo en pesos colombianos.
                                      type: integer
                                      example: 500000
                                    salary_income:
                                      description: Ingresos salariales adicionales del periodo en pesos colombianos.
                                      type: integer
                                      example: 0
                                    total:
                                      description: Total acumulado de la fila en pesos colombianos.
                                      type: integer
                                      example: 500000
                                example:
                                  - symbol: +
                                    date: '2019-10-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-30'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: '='
                                    worked_days: 75
                                    average_salary: 2500000
                                    salary_income: 0
                                    total: 2500000
                              totals:
                                description: Resumen con fórmulas y total final del cálculo.
                                type: object
                                properties:
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        label:
                                          description: Etiqueta descriptiva de la fórmula.
                                          type: string
                                          example: Salario base
                                        numerator:
                                          description: Valor del numerador de la fórmula expresado como texto.
                                          type: string
                                          example: $ 2.500.000 * 30 días
                                        denominator:
                                          description: Valor del denominador de la fórmula expresado como texto.
                                          type: string
                                          example: 75 días
                                        complement:
                                          description: Complemento adicional de la fórmula. Puede ser null si no aplica.
                                          type:
                                            - string
                                            - 'null'
                                          example: + $ 97.032
                                        value:
                                          description: Valor monetario del concepto en pesos colombianos.
                                          type: integer
                                          example: 1000000
                                    example:
                                      - label: Salario base
                                        numerator: $ 2.500.000 * 30 días
                                        denominator: 75 días
                                        complement: null
                                        value: 1000000
                                  total:
                                    description: Total acumulado de la fila en pesos colombianos.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta descriptiva de la fórmula.
                                        type: string
                                        example: Salario base
                                      value:
                                        description: Valor monetario del concepto en pesos colombianos.
                                        type: integer
                                        example: 1000000
                          termination_holidays_base:
                            description: Base de cálculo para vacaciones en la liquidación laboral.
                            type: object
                            properties:
                              information:
                                description: Información explicativa del cálculo con título, descripción y fórmulas de referencia.
                                type: object
                                properties:
                                  title:
                                    description: Título del cálculo mostrado en la sección.
                                    type: string
                                    example: Vacaciones
                                  description:
                                    description: Explicación del método de cálculo aplicado.
                                    type: string
                                    example: Este empleado tiene salario fijo, por lo tanto, su base para vacaciones es el salario base actual.
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: string
                                      example: termination_base
                                    example:
                                      - termination_base
                                      - holidays_base
                                  link:
                                    description: URL del artículo de ayuda que explica el cálculo.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-la-base-para-vacaciones-en-una-liquidaci%C3%B3n-laboral
                              data:
                                description: Filas del detalle de cálculo, una por periodo liquidado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha del periodo de la fila en formato YYYY-MM-DD. Ausente en la fila de totales.
                                      type: string
                                      example: '2019-10-31'
                                    worked_days:
                                      description: Días trabajados en el periodo.
                                      type: integer
                                      example: 15
                                    average_salary:
                                      description: Salario promedio calculado para el periodo en pesos colombianos.
                                      type: integer
                                      example: 500000
                                    salary_income:
                                      description: Ingresos salariales adicionales del periodo en pesos colombianos.
                                      type: integer
                                      example: 0
                                    nightly_surcharge:
                                      description: Valor de recargos nocturnos del periodo en pesos colombianos.
                                      type: integer
                                      example: 0
                                    total:
                                      description: Total acumulado de la fila en pesos colombianos.
                                      type: integer
                                      example: 500000
                                example:
                                  - symbol: +
                                    date: '2019-10-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    nightly_surcharge: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    nightly_surcharge: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-30'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    nightly_surcharge: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    nightly_surcharge: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    nightly_surcharge: 0
                                    total: 500000
                                  - symbol: '='
                                    worked_days: 75
                                    average_salary: 2500000
                                    salary_income: 0
                                    nightly_surcharge: 0
                                    total: 2500000
                              totals:
                                description: Resumen con fórmulas y total final del cálculo.
                                type: object
                                properties:
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        label:
                                          description: Etiqueta descriptiva de la fórmula.
                                          type: string
                                          example: Salario base
                                        numerator:
                                          description: Valor del numerador de la fórmula expresado como texto.
                                          type: string
                                          example: $ 2.500.000 * 30 días
                                        denominator:
                                          description: Valor del denominador de la fórmula expresado como texto.
                                          type: string
                                          example: 75 días
                                        complement:
                                          description: Complemento adicional de la fórmula. Puede ser null si no aplica.
                                          type:
                                            - string
                                            - 'null'
                                          example: + $ 97.032
                                        value:
                                          description: Valor monetario del concepto en pesos colombianos.
                                          type: integer
                                          example: 1000000
                                    example:
                                      - label: Salario base
                                        numerator: $ 2.500.000 * 30 días
                                        denominator: 75 días
                                        complement: null
                                        value: 1000000
                                      - label: Vacaciones
                                        numerator: $ 1.000.000 * 15,000 días
                                        denominator: 30 días
                                        complement: null
                                        value: 500000
                                  total:
                                    description: Total acumulado de la fila en pesos colombianos.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta descriptiva de la fórmula.
                                        type: string
                                        example: Vacaciones
                                      value:
                                        description: Valor monetario del concepto en pesos colombianos.
                                        type: integer
                                        example: 500000
                          termination_severance_base:
                            description: Base de cálculo para cesantías en la liquidación laboral.
                            type: object
                            properties:
                              information:
                                description: Información explicativa del cálculo con título, descripción y fórmulas de referencia.
                                type: object
                                properties:
                                  title:
                                    description: Título del cálculo mostrado en la sección.
                                    type: string
                                    example: Cesantías
                                  description:
                                    description: Explicación del método de cálculo aplicado.
                                    type: string
                                    example: Se calcula como el promedio de los ingresos salariales del año. Ten en cuenta que si el promedio es inferior a 2 SMMLV y el empleado tiene la opción de subsidio de transporte activa en Aleluya, el promedio será calculado incluyendo estos valores.
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: string
                                      example: base_salary_with_transport_subsidy
                                    example:
                                      - base_salary_with_transport_subsidy
                                      - severance_base
                                  link:
                                    description: URL del artículo de ayuda que explica el cálculo.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-la-base-para-cesant%C3%ADas-en-una-liquidaci%C3%B3n-laboral
                              data:
                                description: Filas del detalle de cálculo, una por periodo liquidado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha del periodo de la fila en formato YYYY-MM-DD. Ausente en la fila de totales.
                                      type: string
                                      example: '2019-01-15'
                                    worked_days:
                                      description: Días trabajados en el periodo.
                                      type: integer
                                      example: 15
                                    average_salary:
                                      description: Salario promedio calculado para el periodo en pesos colombianos.
                                      type: integer
                                      example: 414058
                                    salary_income:
                                      description: Ingresos salariales adicionales del periodo en pesos colombianos.
                                      type: integer
                                      example: 0
                                    total:
                                      description: Total acumulado de la fila en pesos colombianos.
                                      type: integer
                                      example: 414058
                                example:
                                  - symbol: +
                                    date: '2019-01-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-01-31'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-02-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-02-28'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-03-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-03-31'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-04-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-04-30'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-05-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-05-31'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-06-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-06-30'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-07-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-07-31'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-08-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-08-31'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-09-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-09-30'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-10-15'
                                    worked_days: 15
                                    average_salary: 494271
                                    salary_income: 0
                                    total: 494271
                                  - symbol: +
                                    date: '2019-10-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-30'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: '='
                                    worked_days: 360
                                    average_salary: 10447315
                                    salary_income: 0
                                    total: 10447315
                              totals:
                                description: Resumen con fórmulas y total final del cálculo.
                                type: object
                                properties:
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        label:
                                          description: Etiqueta descriptiva de la fórmula.
                                          type: string
                                          example: Salario base
                                        numerator:
                                          description: Valor del numerador de la fórmula expresado como texto.
                                          type: string
                                          example: $ 10.447.315 * 30 días
                                        denominator:
                                          description: Valor del denominador de la fórmula expresado como texto.
                                          type: string
                                          example: 360 días
                                        complement:
                                          description: Complemento adicional de la fórmula. Puede ser null si no aplica.
                                          type: string
                                          example: + $ 97.032
                                        value:
                                          description: Valor monetario del concepto en pesos colombianos.
                                          type: integer
                                          example: 967642
                                    example:
                                      - label: Salario base
                                        numerator: $ 10.447.315 * 30 días
                                        denominator: 360 días
                                        complement: + $ 97.032
                                        value: 967642
                                      - label: Cesantías
                                        numerator: $ 967.642 * 360 días
                                        denominator: 360 días
                                        complement: null
                                        value: 967642
                                  total:
                                    description: Total acumulado de la fila en pesos colombianos.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta descriptiva de la fórmula.
                                        type: string
                                        example: Cesantías
                                      value:
                                        description: Valor monetario del concepto en pesos colombianos.
                                        type: integer
                                        example: 967642
                          termination_service_bonus_base:
                            type: object
                            properties:
                              information:
                                description: Información explicativa del cálculo con título, descripción y fórmulas de referencia.
                                type: object
                                properties:
                                  title:
                                    description: Título del cálculo mostrado en la sección.
                                    type: string
                                    example: Prima de servicios
                                  description:
                                    type: string
                                    example: Este empleado tiene salario fijo, por lo tanto, su base para prima de servicios es el salario base actual. Ten en cuenta que si el salario base es inferior a 2 SMMLV y el empleado tiene la opción de subsidio de transporte activa en Aleluya, la base será calculada incluyendo estos valores.
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: string
                                      example: base_salary_with_transport_subsidy
                                    example:
                                      - base_salary_with_transport_subsidy
                                      - service_bonus_base
                                  link:
                                    description: URL del artículo de ayuda que explica el cálculo.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-las-bases-de-la-liquidaci%C3%B3n-laboral
                              data:
                                description: Filas del detalle de cálculo, una por periodo liquidado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: +
                                    date:
                                      description: Fecha del periodo de la fila en formato YYYY-MM-DD. Ausente en la fila de totales.
                                      type: string
                                      example: '2019-07-15'
                                    worked_days:
                                      description: Días trabajados en el periodo.
                                      type: integer
                                      example: 15
                                    average_salary:
                                      description: Salario promedio calculado para el periodo en pesos colombianos.
                                      type: integer
                                      example: 414058
                                    salary_income:
                                      description: Ingresos salariales adicionales del periodo en pesos colombianos.
                                      type: integer
                                      example: 0
                                    total:
                                      description: Total acumulado de la fila en pesos colombianos.
                                      type: integer
                                      example: 414058
                                example:
                                  - symbol: +
                                    date: '2019-07-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-07-31'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-08-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-08-31'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-09-15'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-09-30'
                                    worked_days: 15
                                    average_salary: 414058
                                    salary_income: 0
                                    total: 414058
                                  - symbol: +
                                    date: '2019-10-15'
                                    worked_days: 15
                                    average_salary: 494271
                                    salary_income: 0
                                    total: 494271
                                  - symbol: +
                                    date: '2019-10-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-11-30'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-15'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: +
                                    date: '2019-12-31'
                                    worked_days: 15
                                    average_salary: 500000
                                    salary_income: 0
                                    total: 500000
                                  - symbol: '='
                                    worked_days: 180
                                    average_salary: 5478619
                                    salary_income: 0
                                    total: 5478619
                              totals:
                                description: Resumen con fórmulas y total final del cálculo.
                                type: object
                                properties:
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        label:
                                          description: Etiqueta descriptiva de la fórmula.
                                          type: string
                                          example: Salario base
                                        numerator:
                                          description: Valor del numerador de la fórmula expresado como texto.
                                          type: string
                                          example: $ 5.478.619 * 30 días
                                        denominator:
                                          description: Valor del denominador de la fórmula expresado como texto.
                                          type: string
                                          example: 180 días
                                        complement:
                                          description: Complemento adicional de la fórmula. Puede ser null si no aplica.
                                          type: string
                                          example: + $ 97.032
                                        value:
                                          description: Valor monetario del concepto en pesos colombianos.
                                          type: integer
                                          example: 1010135
                                    example:
                                      - label: Salario base
                                        numerator: $ 5.478.619 * 30 días
                                        denominator: 180 días
                                        complement: + $ 97.032
                                        value: 1010135
                                      - label: Prima de servicios
                                        numerator: $ 1.010.135 * 180 días
                                        denominator: 360 días
                                        complement: null
                                        value: 505068
                                  total:
                                    description: Total acumulado de la fila en pesos colombianos.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta descriptiva de la fórmula.
                                        type: string
                                        example: Prima de servicios
                                      value:
                                        description: Valor monetario del concepto en pesos colombianos.
                                        type: integer
                                        example: 505068
                          compensation:
                            type: object
                            properties:
                              information:
                                description: Información explicativa del cálculo con título, descripción y fórmulas de referencia.
                                type: object
                                properties:
                                  title:
                                    description: Título del cálculo mostrado en la sección.
                                    type: string
                                    example: Indemnización laboral
                                  description:
                                    type: string
                                    example: Ten en cuenta que este empleado tiene más de un año de servicio continuo y su contrato es a término indefinido con un salario inferior o igual a 10 SMMLV, por lo que le corresponden 30 días de salario por el primer año más 20 días por cada año de servicio adicional.
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      oneOf: []
                                      example: ''
                                    example: []
                                  link:
                                    description: URL del artículo de ayuda que explica el cálculo.
                                    type: string
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-la-indemnizaci%C3%B3n-por-liquidaci%C3%B3n-sin-justa-causa
                              data:
                                description: Filas del detalle de cálculo, una por periodo liquidado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: +
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario base
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 1000000
                                example:
                                  - symbol: +
                                    name: Salario base
                                    value: 1000000
                                  - symbol: x
                                    name: Días a pagar por indemnización
                                    value: 34.22222
                                  - symbol: ÷
                                    name: Días del mes
                                    value: 30
                                  - symbol: '='
                                    name: Indemnización laboral
                                    value: 1140741
                              totals:
                                description: Resumen con fórmulas y total final del cálculo.
                                type: object
                                properties:
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      oneOf: []
                                      example: ''
                                    example: []
                                  total:
                                    description: Total acumulado de la fila en pesos colombianos.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta descriptiva de la fórmula.
                                        type: string
                                        example: Indemnización laboral
                                      value:
                                        description: Valor monetario del concepto en pesos colombianos.
                                        type: integer
                                        example: 1140741
                          termination_compensation_retention:
                            type: object
                            properties:
                              information:
                                description: Información explicativa del cálculo con título, descripción y fórmulas de referencia.
                                type: object
                                properties:
                                  title:
                                    description: Título del cálculo mostrado en la sección.
                                    type: string
                                    example: Retención en la fuente por indemnización laboral
                                  description:
                                    type: string
                                    example: Ten en cuenta que esta retención aplica cuando los ingresos brutos o el salario base superan los 204 UVTs y esta es equivalente al 20% de la indemnización por despido.
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      oneOf: []
                                      example: ''
                                    example: []
                                  link:
                                    description: URL del artículo de ayuda que explica el cálculo.
                                    type:
                                      - string
                                      - 'null'
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-las-bases-de-la-liquidaci%C3%B3n-laboral
                              data:
                                description: Filas del detalle de cálculo, una por periodo liquidado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: ''
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Base para retención en la fuente por indemnización
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 1667032
                                example:
                                  - symbol: ''
                                    name: Base para retención en la fuente por indemnización
                                    value: 1667032
                                  - symbol: ''
                                    name: Indemnización laboral
                                    value: 1140741
                                  - symbol: ''
                                    name: Valor de UVT
                                    value: '47065.0'
                                  - symbol: ''
                                    name: Valor límite para aplicar a retención (204 UVT)
                                    value: '9601260.0'
                                  - symbol: '='
                                    name: Valor total de la retención en la fuente por indemnización
                                    value: 0
                              totals:
                                description: Resumen con fórmulas y total final del cálculo.
                                type: object
                                properties:
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      oneOf: []
                                      example: ''
                                    example: []
                                  total:
                                    description: Total acumulado de la fila en pesos colombianos.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta descriptiva de la fórmula.
                                        type: string
                                        example: Valor total de la retención en la fuente por indemnización
                                      value:
                                        description: Valor monetario del concepto en pesos colombianos.
                                        type: integer
                                        example: 0
                          termination_service_bonus_retention:
                            type: object
                            properties:
                              information:
                                description: Información explicativa del cálculo con título, descripción y fórmulas de referencia.
                                type: object
                                properties:
                                  title:
                                    description: Título del cálculo mostrado en la sección.
                                    type: string
                                    example: Retención en la fuente por prima de servicios
                                  description:
                                    description: Explicación del método de cálculo aplicado.
                                    type: string
                                    example: Se calcula tomando el 75% de la prima de servicios y con el valor obtenido realizamos los cálculos pertinentes según la tabla del art. 383 del ET.
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      oneOf: []
                                      example: ''
                                    example: []
                                  link:
                                    description: URL del artículo de ayuda que explica el cálculo.
                                    type:
                                      - string
                                      - 'null'
                                    example: https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-calcula-aleluya-las-bases-de-la-liquidaci%C3%B3n-laboral
                              data:
                                description: Filas del detalle de cálculo, una por periodo liquidado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: ''
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Prima de servicios
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 505068
                                example:
                                  - symbol: ''
                                    name: Prima de servicios
                                    value: 505068
                                  - symbol: ''
                                    name: Renta exenta de acuerdo a numeral 10 artículo 206 ET (25% hasta 790 UVTs anuales)
                                    value: 378801
                                  - symbol: ''
                                    name: Valor de UVT
                                    value: '47065.0'
                                  - symbol: ''
                                    name: Base para retención por prima en UVT
                                    value: '8.05'
                                  - symbol: '='
                                    name: Total de retención en la fuente por prima
                                    value: 0
                              totals:
                                description: Resumen con fórmulas y total final del cálculo.
                                type: object
                                properties:
                                  formulas:
                                    description: Claves de las fórmulas utilizadas en el cálculo.
                                    type: array
                                    items:
                                      oneOf: []
                                      example: ''
                                    example: []
                                  total:
                                    description: Total acumulado de la fila en pesos colombianos.
                                    type: object
                                    properties:
                                      label:
                                        description: Etiqueta descriptiva de la fórmula.
                                        type: string
                                        example: Total de retención en la fuente por prima
                                      value:
                                        description: Valor monetario del concepto en pesos colombianos.
                                        type: integer
                                        example: 0
                      header:
                        description: Encabezado de la nómina con información de la empresa, el empleado y el período.
                        type: object
                        properties:
                          company:
                            description: Información de la empresa empleadora.
                            type: object
                            properties:
                              name:
                                description: Nombre de la empresa.
                                type: string
                                example: Fortnightly Company
                              document_type:
                                description: Tipo de documento de identificación.
                                type: string
                                example: ni
                              id_number:
                                description: Número de documento de identificación.
                                type: string
                                example: '900123001'
                          worker:
                            description: Información del empleado.
                            type: object
                            properties:
                              name:
                                description: Nombre completo de la persona.
                                type: string
                                example: name_1 MyString
                              document_type:
                                description: Tipo de documento de identificación.
                                type: string
                                example: cc
                              id_number:
                                description: Número de documento de identificación.
                                type: string
                                example: '123456789'
                              contract_category:
                                $ref: '#/components/schemas/ContractCategory'
                          period:
                            description: Período de pago de la nómina.
                            type: object
                            properties:
                              period_payment:
                                description: Rango de fechas del período de pago.
                                type: object
                                properties:
                                  initial_day:
                                    description: Fecha de inicio del período en formato YYYY-MM-DD.
                                    type: string
                                    example: '2019-01-01'
                                  end_day:
                                    description: Fecha de fin del período en formato YYYY-MM-DD.
                                    type: string
                                    example: '2019-01-15'
                              worked_days:
                                description: Días trabajados en el periodo.
                                type: integer
                                example: 4
                          payroll_options:
                            description: Secciones habilitadas para el detalle de esta nómina.
                            type: object
                            properties:
                              payslip_detail:
                                description: Detalle de la colilla de pago con ingresos, deducciones y retenciones del empleado.
                                type: boolean
                                example: true
                              social_security_and_parafiscals:
                                description: Aportes de seguridad social y parafiscales a cargo de la empresa.
                                type: boolean
                                example: true
                              social_benefits_provisions:
                                description: Provisiones de prestaciones sociales calculadas en el período.
                                type: boolean
                                example: true
                              payroll_retention:
                                description: Indica si la sección de retención en la fuente está habilitada.
                                type: boolean
                                example: true
                              termination:
                                description: Sección de liquidación laboral con las bases de cálculo y los conceptos liquidados.
                                type: boolean
                                example: false
                              social_benefits:
                                description: Detalle de las provisiones de cesantías, prima, vacaciones e intereses.
                                type: boolean
                                example: true
                      payslip_detail:
                        description: Detalle de la colilla de pago con ingresos, deducciones y retenciones del empleado.
                        type: object
                        properties:
                          payment_summary:
                            description: Resumen de los conceptos principales del pago neto al empleado.
                            type: object
                            properties:
                              data:
                                description: Conceptos incluidos en el resumen del pago neto al empleado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 110415
                                example:
                                  - name: Salario
                                    value: 110415
                                  - name: Subsidio de transporte
                                    value: 12938
                                  - name: Horas extras, ordinarias y recargos
                                    value: 4313
                                  - name: Vacaciones, Licencias e Incapacidades
                                    value: 466667
                                  - name: Ingresos adicionales
                                    value: 150000
                                  - name: Retenciones y deducciones
                                    value: -92386
                                  - name: Total neto a pagar al empleado
                                    value: 651947
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                          worked_days:
                            description: Días trabajados en el periodo.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Días del período
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 15
                                example:
                                  - name: Días del período
                                    value: 15
                                  - name: Vacaciones disfrutadas
                                    value: -6
                                  - name: Incapacidad laboral
                                    value: -5
                                  - name: Total días trabajados
                                    value: 4
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: A los 15 días del período se deben descontar los días que la persona tuvo novedad para obtener los días realmente trabajados
                                example:
                                  - A los 15 días del período se deben descontar los días que la persona tuvo novedad para obtener los días realmente trabajados
                          base_salary:
                            description: Detalle del cálculo del salario base y subsidio de transporte según los días trabajados.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    monthly_value:
                                      description: Valor mensual del concepto en pesos colombianos.
                                      type: integer
                                      example: 828116
                                    worked_days:
                                      description: Días trabajados en el periodo.
                                      type: integer
                                      example: 4
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 110415
                                example:
                                  - name: Salario
                                    monthly_value: 828116
                                    worked_days: 4
                                    value: 110415
                                  - name: Subsidio de transporte
                                    monthly_value: 97032
                                    worked_days: 4
                                    value: 12938
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = Valor mensual * Días trabajados / 30 Días
                                example:
                                  - Fórmula = Valor mensual * Días trabajados / 30 Días
                                  - Tienes configurado el pago de subsidio de transporte quincenal
                          paid_rest:
                            description: Detalle del descanso obligatorio remunerado del período.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Descanso obligatorio remunerado
                                    days:
                                      description: Número de días de la novedad.
                                      type: number
                                      example: 2.17
                                    symbol:
                                      description: Símbolo de la operación matemática aplicada en la fila (`+` para suma, `=` para total).
                                      type: string
                                      example: +
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 50000
                                example:
                                  - name: Descanso obligatorio remunerado
                                    days: 2.17
                                    symbol: +
                                    value: 50000
                                  - name: Total descanso obligatorio remunerado
                                    symbol: '='
                                    value: 50000
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                example: []
                          overtime:
                            description: Detalle de horas extras, ordinarias y recargos del período.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Hora Extra Ordinaria
                                    constant_value:
                                      description: Factor multiplicador aplicado sobre la hora ordinaria.
                                      type: number
                                      example: 1.25
                                    quantity:
                                      description: Cantidad de horas del concepto.
                                      type: number
                                      example: 1
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 4313
                                example:
                                  - name: Hora Extra Ordinaria
                                    constant_value: 1.25
                                    quantity: 1
                                    value: 4313
                                  - name: Total pago por horas
                                    value: 4313
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = Salario Promedio * Valor sobre hora ordinaria * Horas / (30 días * 8.0 horas)
                                example:
                                  - Fórmula = Salario Promedio * Valor sobre hora ordinaria * Horas / (30 días * 8.0 horas)
                          holidays:
                            description: Detalle de vacaciones disfrutadas y su valor liquidado.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Vacaciones disfrutadas
                                    days:
                                      description: Número de días de la novedad.
                                      type: integer
                                      example: 6
                                    average_salary:
                                      description: Salario promedio calculado para el periodo en pesos colombianos.
                                      type: integer
                                      example: 1000000
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 300000
                                example:
                                  - name: Vacaciones disfrutadas
                                    days: 6
                                    average_salary: 1000000
                                    value: 300000
                                  - name: Total días remunerados
                                    value: 300000
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = Salario Promedio * días / 30 días
                                example:
                                  - Fórmula = Salario Promedio * días / 30 días
                                  - Los días de vacaciones disfrutadas son diferentes a los días hábiles que se le descuentan a la persona de sus vacaciones acumuladas. Los días hábiles los puedes consultar en el perfil de la persona, en su histórico de novedades
                          incapacities:
                            description: Detalle de incapacidades y su valor liquidado.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Incapacidad laboral
                                    days:
                                      description: Número de días de la novedad.
                                      type: integer
                                      example: 5
                                    average_salary:
                                      description: Salario promedio calculado para el periodo en pesos colombianos.
                                      type: integer
                                      example: 1000000
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 166667
                                example:
                                  - name: Incapacidad laboral
                                    days: 5
                                    average_salary: 1000000
                                    value: 166667
                                  - name: Total días remunerados
                                    value: 166667
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = Salario Promedio * días / 30 días
                                example:
                                  - Fórmula = Salario Promedio * días / 30 días
                                  - El auxilio por incapacidad no puede ser menor al salario mínimo diario legal vigente. Si la persona gana menos de este valor, la cifra se aproximará automáticamente al mínimo = $ 828.116 / 30 = $ 27.604
                          licenses:
                            description: Detalle de licencias del período.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría. Retorna un arreglo vacío si no hay conceptos en esta categoría.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                          additional_incomes:
                            description: Detalle de ingresos adicionales no salariales del período.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Bonificación a mera liberalidad
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 100000
                                example:
                                  - name: Bonificación a mera liberalidad
                                    value: 100000
                                  - name: Otros ingresos no prestacionales
                                    value: 50000
                                  - name: Total ingresos adicionales
                                    value: 150000
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Los beneficios no salariales recurrentes se pagan al 100%, es decir, no dependen del número de días trabajados ya que tienes configurado que estos pagos sean fijos
                                example:
                                  - Los beneficios no salariales recurrentes se pagan al 100%, es decir, no dependen del número de días trabajados ya que tienes configurado que estos pagos sean fijos
                          retentions:
                            description: Detalle del IBC de seguridad social y los conceptos que lo componen.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 110415
                                example:
                                  - name: Salario
                                    value: 110415
                                  - name: Horas extras, ordinarias y recargos
                                    value: 4313
                                  - name: Vacaciones
                                    value: 248435
                                  - name: Incapacidades
                                    value: 166667
                                  - name: IBC Seguridad Social
                                    value: 529830
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Para el cálculo del IBC Seguridad Social no se tiene en cuenta el subsidio de transporte, valor de vacaciones compensadas ni demás ingresos no constitutivos de salario
                                example:
                                  - Para el cálculo del IBC Seguridad Social no se tiene en cuenta el subsidio de transporte, valor de vacaciones compensadas ni demás ingresos no constitutivos de salario
                                  - El IBC de vacaciones se calcula teniendo en cuenta el IBC cotizado a Seguridad Social en el mes inmediatamente anterior al inicio de las vacaciones. Este puede variar respecto al salario base con que se liquidan las vacaciones si tu empleado tiene salario variable. [Ver más aquí, https://ayuda.aleluya.com/portal/es/kb/articles/%C2%BFc%C3%B3mo-se-calcula-el-ibc-de-seguridad-social-cuando-tu-empleado-tiene-vacaciones-disfrutadas]
                          social_security_retentions:
                            description: Detalle de las retenciones de seguridad social (salud y pensión) del empleado.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salud
                                    percentage:
                                      description: Porcentaje aplicado al IBC en el cálculo.
                                      type: number
                                      example: 4
                                    ibc_social_security:
                                      description: IBC (Ingreso Base de Cotización) para seguridad social en pesos colombianos.
                                      type: integer
                                      example: 529830
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 21193
                                example:
                                  - name: Salud
                                    percentage: 4
                                    ibc_social_security: 529830
                                    value: 21193
                                  - name: Pensión
                                    percentage: 4
                                    ibc_social_security: 529830
                                    value: 21193
                                  - name: Total Retenciones
                                    value: 42386
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = % * IBC Seguridad Social
                                example:
                                  - Fórmula = % * IBC Seguridad Social
                          deductions:
                            description: Detalle de deducciones adicionales como préstamos o descuentos del período.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Préstamo
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 50000
                                example:
                                  - name: Préstamo
                                    value: 50000
                                  - name: Total Deducciones
                                    value: 50000
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                      social_security_and_parafiscals:
                        description: Aportes de seguridad social y parafiscales a cargo de la empresa.
                        type: object
                        properties:
                          social_security_company:
                            description: Detalle de los aportes de seguridad social a cargo de la empresa.
                            type: object
                            properties:
                              data:
                                description: Conceptos de seguridad social a cargo de la empresa con su IBC, porcentaje y valor.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Pensión
                                    ibc_value:
                                      description: IBC (Ingreso Base de Cotización) utilizado en el cálculo en pesos colombianos.
                                      type: integer
                                      example: 529830
                                    percentage:
                                      description: Porcentaje aplicado al IBC en el cálculo.
                                      type: number
                                      example: 12
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 63580
                                example:
                                  - name: Pensión
                                    ibc_value: 529830
                                    percentage: 12
                                    value: 63580
                                  - name: Riesgo 1 - Mínimo
                                    ibc_value: 114728
                                    percentage: 0.522
                                    value: 599
                                  - name: Seguridad Social
                                    value: 64179
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = % Empresa * IBC
                                example:
                                  - Fórmula = % Empresa * IBC
                                  - La empresa está exenta de pago de Aportes a Salud, ya que tienes configurado que aplica para Ley 1607 de 2012. Para conocer más al respecto haz [clic aquí,https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-aplica-la-ley-1607-de-2012-en-la-liquidaci%C3%B3n-de-los-aportes-de-seguridad-social-y-parafiscales-de-tu-compa%C3%B1%C3%ADa]
                          parafiscals_company:
                            description: Detalle de los aportes parafiscales a cargo de la empresa.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Caja de Compensación
                                    ibc_value:
                                      description: IBC (Ingreso Base de Cotización) utilizado en el cálculo en pesos colombianos.
                                      type: integer
                                      example: 414728
                                    percentage:
                                      description: Porcentaje aplicado al IBC en el cálculo.
                                      type: number
                                      example: 4
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 16589
                                example:
                                  - name: Caja de Compensación
                                    ibc_value: 414728
                                    percentage: 4
                                    value: 16589
                                  - name: Parafiscales
                                    value: 16589
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = % Empresa * IBC
                                example:
                                  - Fórmula = % Empresa * IBC
                                  - La empresa está exenta de pago de Parafiscales, ya que tienes configurado que aplica para Ley 1607 de 2012. Para conocer más al respecto haz [clic aquí,https://ayuda.aleluya.com/portal/es/kb/articles/conoce-c%C3%B3mo-aplica-la-ley-1607-de-2012-en-la-liquidaci%C3%B3n-de-los-aportes-de-seguridad-social-y-parafiscales-de-tu-compa%C3%B1%C3%ADa]
                          ibc_health:
                            description: Detalle del IBC de salud y los conceptos que lo componen.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría. Retorna un arreglo vacío si no hay conceptos en esta categoría.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                          ibc_pension:
                            description: Detalle del IBC de pensión y los conceptos que lo componen.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 110415
                                example:
                                  - name: Salario
                                    value: 110415
                                  - name: Horas extras, ordinarias y recargos
                                    value: 4313
                                  - name: Vacaciones
                                    value: 248435
                                  - name: Incapacidades
                                    value: 166667
                                  - name: IBC Pensión
                                    value: 529830
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Durante el periodo de incapacidad general o laboral, continúa la obligación del empleador de realizar los aportes a pensión
                                example:
                                  - Durante el periodo de incapacidad general o laboral, continúa la obligación del empleador de realizar los aportes a pensión
                                  - El IBC de vacaciones se calcula teniendo en cuenta el IBC cotizado a Seguridad Social en el mes inmediatamente anterior al inicio de las vacaciones. Este puede variar respecto al salario base con que se liquidan las vacaciones si tu empleado tiene salario variable. [Ver más aquí, https://ayuda.aleluya.com/portal/es/kb/articles/%C2%BFc%C3%B3mo-se-calcula-el-ibc-de-seguridad-social-cuando-tu-empleado-tiene-vacaciones-disfrutadas]
                          ibc_risks:
                            description: Detalle del IBC de riesgos laborales (ARL) y los conceptos que lo componen.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 110415
                                example:
                                  - name: Salario
                                    value: 110415
                                  - name: Horas extras, ordinarias y recargos
                                    value: 4313
                                  - name: IBC Riesgos
                                    value: 114728
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Para el cálculo del IBC Seguridad Social no se tiene en cuenta subsidio de transporte, valor de vacaciones compensadas ni demás ingresos no constitutivos de salario
                                example:
                                  - Para el cálculo del IBC Seguridad Social no se tiene en cuenta subsidio de transporte, valor de vacaciones compensadas ni demás ingresos no constitutivos de salario
                                  - Durante el período de vacaciones disfrutadas, no se genera pago al Sistema de Riesgos Laborales (ARL)
                                  - Durante el periodo de incapacidades generales o laborales, no se genera pago al Sistema de Riesgos Laborales (ARL)
                          ibc_parafiscals:
                            description: Detalle del IBC parafiscales y los conceptos que lo componen.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 110415
                                example:
                                  - name: Salario
                                    value: 110415
                                  - name: Horas extras, ordinarias y recargos
                                    value: 4313
                                  - name: Vacaciones y licencias
                                    value: 300000
                                  - name: IBC Parafiscales
                                    value: 414728
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Durante el período de vacaciones disfrutadas, continúa la obligación del empleados de realizar los Aportes Parafiscales
                                example:
                                  - Durante el período de vacaciones disfrutadas, continúa la obligación del empleados de realizar los Aportes Parafiscales
                                  - Durante el período de incapacidad, general o laboral, no hay lugar al pago de Aportes Parafiscales
                      social_benefits_provisions:
                        description: Provisiones de prestaciones sociales calculadas en el período.
                        type: object
                        properties:
                          social_benefits:
                            description: Detalle de las provisiones de cesantías, prima, vacaciones e intereses.
                            type: object
                            properties:
                              data:
                                description: Provisiones de prestaciones sociales calculadas en el periodo con su base, porcentaje y valor.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Cesantías
                                    base:
                                      description: Base de cálculo de la provisión en pesos colombianos.
                                      type: integer
                                      example: 559402
                                    percentage:
                                      description: Porcentaje aplicado al IBC en el cálculo.
                                      type: number
                                      example: 8.33
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 46617
                                example:
                                  - name: Cesantías
                                    base: 559402
                                    percentage: 8.33
                                    value: 46617
                                  - name: Intereses a las Cesantías
                                    base: 46617
                                    percentage: 12
                                    value: 5594
                                  - name: Prima de Servicios
                                    base: 559402
                                    percentage: 8.33
                                    value: 46617
                                  - name: Vacaciones
                                    base: 496870
                                    percentage: 4.17
                                    value: 20703
                                  - name: Total provisiones
                                    value: 119531
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                          severance_base:
                            description: Detalle de los conceptos que conforman la base para cesantías.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 496870
                                example:
                                  - name: Salario
                                    value: 496870
                                  - name: Subsidio de transporte
                                    value: 58219
                                  - name: Horas extras, ordinarias y recargos
                                    value: 4313
                                  - name: Base Cesantías
                                    value: 559402
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Se incluye el Subsidio de transporte en la Base para Cesantías ya que es inferior a 2 SMMLV y la persona tiene configurado este auxilio
                                example:
                                  - Se incluye el Subsidio de transporte en la Base para Cesantías ya que es inferior a 2 SMMLV y la persona tiene configurado este auxilio
                          service_bonus_base:
                            description: Detalle de los conceptos que conforman la base para prima de servicios.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 496870
                                example:
                                  - name: Salario
                                    value: 496870
                                  - name: Subsidio de transporte
                                    value: 58219
                                  - name: Horas extras, ordinarias y recargos
                                    value: 4313
                                  - name: Base Prima
                                    value: 559402
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Las licencias no remuneradas o suspensiones no afectan el pago de la Prima, solo afectan las Vacaciones y Cesantías. Pero las ausencias injustificadas si afectan la prima.
                                example:
                                  - Las licencias no remuneradas o suspensiones no afectan el pago de la Prima, solo afectan las Vacaciones y Cesantías. Pero las ausencias injustificadas si afectan la prima.
                                  - Se incluye el Subsidio de transporte en la Base para Prima ya que es inferior a 2 SMMLV y la persona tiene configurado este auxilio
                          holidays_base:
                            description: Detalle de los conceptos que conforman la base para vacaciones.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría con su valor calculado.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    name:
                                      description: Nombre del concepto de nómina.
                                      type: string
                                      example: Salario
                                    value:
                                      description: Valor monetario del concepto en pesos colombianos.
                                      type: integer
                                      example: 496870
                                example:
                                  - name: Salario
                                    value: 496870
                                  - name: Base Vacaciones
                                    value: 496870
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: De Horas Extras y Recargos, sólo se incluyen los Recargos Nocturnos en la Base para Vacaciones
                                example:
                                  - De Horas Extras y Recargos, sólo se incluyen los Recargos Nocturnos en la Base para Vacaciones
                          holidays_provisions:
                            description: Detalle del cálculo de las provisiones de vacaciones acumuladas.
                            type: object
                            properties:
                              data:
                                description: Conceptos de nómina de esta categoría. Retorna un arreglo vacío si no hay conceptos en esta categoría.
                                type: array
                                items:
                                  oneOf: []
                                  example: ''
                                example: []
                              comments:
                                description: Comentarios explicativos del cálculo de la sección.
                                type: array
                                items:
                                  type: string
                                  example: Fórmula = (Días trabajados * 4.167%) - Días de hábiles de vacaciones disfrutadas o compensadas en dinero
                                example:
                                  - Fórmula = (Días trabajados * 4.167%) - Días de hábiles de vacaciones disfrutadas o compensadas en dinero
                                  - Para efectos laborales, todos los meses tienen 30 días y un año tiene 360 días
                                  - Se toman los días trabajados (o en vacaciones o incapacidades) sin incluir los días de suspensión, licencia no remunerada o ausencia injustificada
                                  - El factor 4.167% corresponde a 15 días hábiles de descanso remunerado por cada año cumplido de labor (15 días / 360 días = 0.041666667 = 4.157 %)
                                  - Los días hábiles de las vacaciones que empezaron en este periodo que la persona haya disfrutado o le hayan sido compensadas en dinero, se deben descontar de sus vacaciones acumuladas
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nómina de contratista / Fecha de terminación inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nómina de contratista:
                  value:
                    description: Valor monetario del concepto en pesos colombianos.
                    error:
                      - code: '0101'
                        index: 0
                        message: Contrato es inválido.
                        object: contract
                Fecha de terminación inválida:
                  value:
                    description: Valor monetario del concepto en pesos colombianos.
                    error:
                      - code: '0412'
                        index: 0
                        message: El formato de la fecha es inválido.
                        object: date
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: c8f8577a-a87e-4e0e-b46f-50e9f63c7dc5
      - in: path
        required: true
        name: payroll_id
        description: Identificador único (ID) asignado a la nómina en la base de datos.
        schema:
          type: string
          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
  /v1/{company_id}/periods:
    get:
      operationId: indexPeriods
      tags:
        - Periodos de nómina
      summary: Listar periodos de nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de periodos de nómina de la empresa con sus totales consolidados:
        salarios, otros pagos, prestaciones sociales, costo empresa y deducciones.

        **¿Cuándo usar este endpoint?**

        * Obtener el listado de periodos de nómina de una empresa para mostrar su historial de liquidaciones.
        * Obtener los periodos de un mes y año específico para consultar o reportar una liquidación pasada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: month
          description: Filtra los periodos por mes (1–12).
          schema:
            type: integer
            example: 1
        - in: query
          required: false
          name: year
          description: Filtra los periodos por año.
          schema:
            type: integer
            example: 2024
      responses:
        '200':
          description: Listado de periodos retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de periodos de nómina con sus totales consolidados.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al periodo en la base de datos.
                          type: string
                          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                        initial_day:
                          description: Fecha inicial del periodo, en formato `YYYY-MM-DD`.
                          type: string
                          format: date
                          example: '2024-01-01'
                        end_day:
                          description: Fecha final del periodo, en formato `YYYY-MM-DD`.
                          type: string
                          format: date
                          example: '2024-01-15'
                        length:
                          description: Duración del periodo en días.
                          type: integer
                          example: 15
                        payrolls_paid:
                          description: Indica si las nóminas del periodo han sido marcadas como pagadas.
                          type: boolean
                          example: true
                        payrolls_number:
                          description: Número de nóminas liquidadas en el periodo.
                          type: integer
                          example: 5
                        salaries:
                          description: Total de salarios del periodo en pesos colombianos.
                          type: integer
                          example: 7500000
                        other_payments:
                          description: Total de otros pagos del periodo (horas extras, novedades, ingresos adicionales) en pesos colombianos.
                          type: integer
                          example: 450000
                        total_benefits:
                          description: Total de prestaciones sociales provisionadas en el periodo en pesos colombianos.
                          type: integer
                          example: 650000
                        company_cost:
                          description: Costo total de la empresa en el periodo incluyendo aportes de seguridad social y parafiscales, en pesos colombianos.
                          type: integer
                          example: 9750000
                        deductions_retentions:
                          description: Total de retenciones y deducciones del periodo en pesos colombianos.
                          type: integer
                          example: 250000
                        has_overtime_anomaly:
                          description: Indica si el periodo tiene una anomalía detectada en el análisis de horas extras y está entre los últimos 3 periodos del historial. Es `true` solo cuando ambas condiciones se cumplen simultáneamente.
                          type: boolean
                          example: false
                  filters:
                    description: Información de paginación y filtros aplicados a la respuesta.
                    type: object
                    properties:
                      filter:
                        description: Filtro activo. Retorna `All` si no se aplicó filtro.
                        type: string
                        example: All
                      total_records:
                        description: Número total de periodos que coinciden con los filtros aplicados.
                        type: integer
                        example: 24
                      page:
                        description: Número de página actual de la respuesta.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de periodos retornados por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado. Null si no se envió búsqueda.
                        type:
                          - string
                          - 'null'
                        example: ''
              example:
                data:
                  - id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                    initial_day: '2024-01-01'
                    end_day: '2024-01-15'
                    length: 15
                    payrolls_paid: true
                    payrolls_number: 5
                    salaries: 7500000
                    other_payments: 450000
                    total_benefits: 650000
                    company_cost: 9750000
                    deductions_retentions: 250000
                    has_overtime_anomaly: false
                filters:
                  filter: All
                  total_records: 24
                  page: 1
                  per_page: 20
                  search: ''
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createPeriod
      tags:
        - Periodos de nómina
      summary: Crear periodo de nómina
      description: |
        **¿Qué hace este endpoint?**

        Crea uno o más periodos de nómina para la empresa. Puede crear el siguiente periodo,
        el periodo más antiguo del mes anterior aún sin liquidar, o todos los periodos de un año para liquidar nóminas retroactivas.

        **¿Cuándo usar este endpoint?**

        * Crear el siguiente periodo de nómina una vez que el periodo actual ha sido procesado.
        * Crear todos los periodos de un año anterior cuando la empresa necesita liquidar nóminas de forma retroactiva.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Siguiente periodo (`next`):** Crea el periodo inmediatamente siguiente al último registrado en la empresa.
        * **Periodo anterior (sin tipo):** Crea el periodo del mes anterior al primer periodo registrado de la empresa.
        * **Año completo (`historical`):** Crea todos los periodos de un año específico. Requiere enviar el campo `year` con el año deseado.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - period
              properties:
                period:
                  description: Parámetros para la creación del periodo de nómina.
                  type: object
                  properties:
                    range_type:
                      description: 'Tipo de creación de periodo. Valores posibles: `next` (siguiente periodo), `historical` (todos los periodos del año indicado en `year`). Si no se envía, crea el periodo del mes anterior al primer periodo registrado de la empresa.'
                      type: string
                      enum:
                        - next
                        - historical
                      example: next
                    year:
                      description: Año para el cual crear los periodos. Solo requerido cuando `range_type` es `historical`.
                      type: integer
                      example: 2024
            examples:
              Siguiente periodo:
                value:
                  period:
                    range_type: next
              Periodos históricos:
                value:
                  period:
                    range_type: historical
                    year: 2023
      responses:
        '201':
          description: Creación de periodo encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del encolamiento.
                        type: string
                        example: La información se agregó a la cola, en unos minutos verás el periodo creado.
              example:
                data:
                  message: La información se agregó a la cola, en unos minutos verás el periodo creado.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: No es posible crear los periodos / Falta salario mínimo del año
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                No es posible crear los periodos:
                  value:
                    error:
                      - code: '1502'
                        index: 0
                        message: No es posible crear los periodos.
                        object: Period
                Falta salario mínimo del año:
                  value:
                    error:
                      - code: '0416'
                        index: 0
                        message: No es posible crear periodos sin tener el salario mínimo del año.
                        object: date
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/periods/{id}:
    get:
      operationId: showPeriod
      tags:
        - Periodos de nómina
      summary: Obtener periodo de nómina
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de un periodo de nómina con sus totales consolidados, el conteo de
        contratos por categoría, los periodos relacionados y el listado paginado de nóminas.

        **¿Cuándo usar este endpoint?**

        * Obtener los totales y el estado de un periodo específico.
        * Obtener el listado de nóminas de un periodo con soporte de búsqueda y filtros por sede, categoría o estado de contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Consulta sin nóminas (`without_payrolls: true`):** La respuesta omite el listado de nóminas, los filtros de paginación y el conteo de nóminas del periodo.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: without_payrolls
          description: Cuando es `true`, omite el listado de nóminas y los filtros de paginación en la respuesta.
          schema:
            type: boolean
            example: false
        - in: query
          required: false
          name: search
          description: Busca nóminas por nombre de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
        - in: query
          required: false
          name: contract_category
          description: Filtra las nóminas por categoría del contrato de la persona.
          schema:
            $ref: '#/components/schemas/ContractCategory'
        - in: query
          required: false
          name: contract_status
          description: 'Filtra las nóminas por estado del contrato. Valores posibles: `active` (contratos sin terminación), `terminated` (contratos con terminación registrada).'
          schema:
            type: string
            enum:
              - active
              - terminated
            example: active
        - in: query
          required: false
          name: location
          description: Filtra las nóminas por sede. Se envía el identificador único (ID) de la sede.
          schema:
            type: string
            example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `without_payrolls`:

            - **Sin `without_payrolls`** (por defecto): retorna `data` con el listado de nóminas y `filters` con la paginación.
            - **`without_payrolls: true`**: retorna solo `data` con los totales y contadores del periodo, sin nóminas ni paginación.
          content:
            application/json:
              schema:
                oneOf:
                  - description: Respuesta con nóminas y paginación
                    required:
                      - data
                      - filters
                    type: object
                    properties:
                      data:
                        description: Detalle del periodo con totales consolidados, nóminas y periodos relacionados.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          initial_day:
                            description: Fecha inicial del periodo, en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha final del periodo, en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-15'
                          length:
                            description: Duración del periodo en días.
                            type: integer
                            example: 15
                          payrolls_paid:
                            description: Indica si las nóminas del periodo han sido marcadas como pagadas.
                            type: boolean
                            example: true
                          electronic_payroll_period_id:
                            description: Identificador único (ID) del periodo de nómina electrónica mensual asociado. Null si no tiene.
                            type:
                              - string
                              - 'null'
                            example: 4a2b3c4d-5e6f-7890-abcd-ef1234567890
                          payrolls_number:
                            description: Número total de nóminas del periodo.
                            type: integer
                            example: 5
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7500000
                          social_benefits_provision:
                            description: Total de prestaciones sociales provisionadas en el periodo, en pesos colombianos.
                            type: integer
                            example: 650000
                          company_cost:
                            description: Costo total de la empresa en el periodo incluyendo aportes de seguridad social y parafiscales, en pesos colombianos.
                            type: integer
                            example: 9750000
                          social_security_payment:
                            description: Total del aporte de seguridad social del periodo, en pesos colombianos.
                            type: integer
                            example: 800000
                          editable:
                            description: Indica si el periodo puede ser editado.
                            type: boolean
                            example: true
                          contracts_counter:
                            description: Conteo de nóminas del periodo agrupado por categoría de contrato.
                            type: object
                            properties:
                              all:
                                description: Total de nóminas del periodo.
                                type: integer
                                example: 5
                              employee:
                                description: Nóminas de empleados a tiempo completo.
                                type: integer
                                example: 3
                              part_time_contract:
                                description: Nóminas de empleados a tiempo parcial.
                                type: integer
                                example: 1
                              apprentice:
                                description: Nóminas de aprendices.
                                type: integer
                                example: 0
                              student:
                                description: Nóminas de estudiantes.
                                type: integer
                                example: 0
                              contractor:
                                description: Nóminas de contratistas.
                                type: integer
                                example: 1
                          terminated_contracts_counter:
                            description: Número de nóminas del periodo con liquidación de contrato registrada.
                            type: integer
                            example: 0
                          related_periods:
                            description: Periodos del mismo mes (quincenas del mismo periodo mensual). Vacío si el periodo no tiene relacionados.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al periodo en la base de datos.
                                  type: string
                                  example: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                                initial_day:
                                  description: Fecha inicial del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-16'
                                end_day:
                                  description: Fecha final del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-31'
                          payrolls:
                            description: Listado de nóminas del periodo con su detalle completo.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la nómina en la base de datos.
                                  type: string
                                  example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                                worker_id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                worker_name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: Juan Pérez
                                contract_id:
                                  description: Identificador único (ID) asignado al contrato en la base de datos.
                                  type: string
                                  example: 3c4d5e6f-7a8b-9012-cdef-123456789012
                                contract_category:
                                  $ref: '#/components/schemas/ContractCategory'
                                salary:
                                  description: Salario base de la nómina en pesos colombianos.
                                  type: integer
                                  example: 1500000
                                worker_payment:
                                  description: Pago neto a la persona en pesos colombianos.
                                  type: integer
                                  example: 1600000
                                company_cost:
                                  description: Costo total para la empresa en pesos colombianos.
                                  type: integer
                                  example: 1900000
                                worked_time:
                                  description: Días u horas trabajados en el periodo.
                                  type: number
                                  example: 15
                                locked:
                                  description: Indica si la nómina está bloqueada (liquidada definitivamente).
                                  type: boolean
                                  example: false
                                editable:
                                  description: Indica si la nómina puede ser editada.
                                  type: boolean
                                  example: true
                      filters:
                        description: Información de paginación de las nóminas del periodo.
                        type: object
                        properties:
                          location:
                            description: Identificador de la sede por la que se filtró, o `All` si no se aplicó filtro de sede.
                            type: string
                            example: All
                          total_records:
                            description: Número total de nóminas del periodo que coinciden con los filtros.
                            type: integer
                            example: 5
                          page:
                            description: Número de página actual.
                            type: integer
                            example: 1
                          per_page:
                            description: Número máximo de nóminas retornadas por página.
                            type: integer
                            example: 20
                          search:
                            description: Texto de búsqueda aplicado. Null si no se envió búsqueda.
                            type:
                              - string
                              - 'null'
                            example: ''
                  - description: Respuesta con totales del periodo sin nóminas
                    required:
                      - data
                    type: object
                    properties:
                      data:
                        description: Detalle del periodo con totales consolidados y periodos relacionados.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo en la base de datos.
                            type: string
                            example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          initial_day:
                            description: Fecha inicial del periodo, en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha final del periodo, en formato `YYYY-MM-DD`.
                            type: string
                            format: date
                            example: '2024-01-15'
                          length:
                            description: Duración del periodo en días.
                            type: integer
                            example: 15
                          payrolls_paid:
                            description: Indica si las nóminas del periodo han sido marcadas como pagadas.
                            type: boolean
                            example: true
                          electronic_payroll_period_id:
                            description: Identificador único (ID) del periodo de nómina electrónica mensual asociado. Null si no tiene.
                            type:
                              - string
                              - 'null'
                            example: 4a2b3c4d-5e6f-7890-abcd-ef1234567890
                          workers_payment:
                            description: Total neto a pagar a todas las personas del periodo, en pesos colombianos.
                            type: integer
                            example: 7500000
                          social_benefits_provision:
                            description: Total de prestaciones sociales provisionadas en el periodo, en pesos colombianos.
                            type: integer
                            example: 650000
                          company_cost:
                            description: Costo total de la empresa en el periodo incluyendo aportes de seguridad social y parafiscales, en pesos colombianos.
                            type: integer
                            example: 9750000
                          social_security_payment:
                            description: Total del aporte de seguridad social del periodo, en pesos colombianos.
                            type: integer
                            example: 800000
                          editable:
                            description: Indica si el periodo puede ser editado.
                            type: boolean
                            example: true
                          contracts_counter:
                            description: Conteo de nóminas del periodo agrupado por categoría de contrato.
                            type: object
                            properties:
                              all:
                                description: Total de nóminas del periodo.
                                type: integer
                                example: 5
                              employee:
                                description: Nóminas de empleados a tiempo completo.
                                type: integer
                                example: 3
                              part_time_contract:
                                description: Nóminas de empleados a tiempo parcial.
                                type: integer
                                example: 1
                              apprentice:
                                description: Nóminas de aprendices.
                                type: integer
                                example: 0
                              student:
                                description: Nóminas de estudiantes.
                                type: integer
                                example: 0
                              contractor:
                                description: Nóminas de contratistas.
                                type: integer
                                example: 1
                          terminated_contracts_counter:
                            description: Número de nóminas del periodo con liquidación de contrato registrada.
                            type: integer
                            example: 0
                          related_periods:
                            description: Periodos del mismo mes (quincenas del mismo periodo mensual). Vacío si el periodo no tiene relacionados.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al periodo en la base de datos.
                                  type: string
                                  example: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                                initial_day:
                                  description: Fecha inicial del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-16'
                                end_day:
                                  description: Fecha final del periodo relacionado, en formato `YYYY-MM-DD`.
                                  type: string
                                  format: date
                                  example: '2024-01-31'
              examples:
                Con nóminas:
                  value:
                    data:
                      id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                      initial_day: '2024-01-01'
                      end_day: '2024-01-15'
                      length: 15
                      payrolls_paid: true
                      electronic_payroll_period_id: 4a2b3c4d-5e6f-7890-abcd-ef1234567890
                      payrolls_number: 5
                      workers_payment: 7500000
                      social_benefits_provision: 650000
                      company_cost: 9750000
                      social_security_payment: 800000
                      editable: true
                      contracts_counter:
                        all: 5
                        employee: 3
                        part_time_contract: 1
                        apprentice: 0
                        student: 0
                        contractor: 1
                      terminated_contracts_counter: 0
                      related_periods:
                        - id: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                          initial_day: '2024-01-16'
                          end_day: '2024-01-31'
                      payrolls:
                        - id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name: Juan Pérez
                          contract_id: 3c4d5e6f-7a8b-9012-cdef-123456789012
                          contract_category: employee
                          salary: 1500000
                          worker_payment: 1600000
                          company_cost: 1900000
                          worked_time: 15
                          locked: false
                          editable: true
                    filters:
                      location: All
                      total_records: 5
                      page: 1
                      per_page: 20
                      search: ''
                Sin nóminas:
                  value:
                    data:
                      id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                      initial_day: '2024-01-01'
                      end_day: '2024-01-15'
                      length: 15
                      payrolls_paid: true
                      electronic_payroll_period_id: 4a2b3c4d-5e6f-7890-abcd-ef1234567890
                      workers_payment: 7500000
                      social_benefits_provision: 650000
                      company_cost: 9750000
                      social_security_payment: 800000
                      editable: true
                      contracts_counter:
                        all: 5
                        employee: 3
                        part_time_contract: 1
                        apprentice: 0
                        student: 0
                        contractor: 1
                      terminated_contracts_counter: 0
                      related_periods:
                        - id: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                          initial_day: '2024-01-16'
                          end_day: '2024-01-31'
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
  /v1/{company_id}/periods/{period_id}/accounting/files:
    get:
      operationId: showAccountingFile
      tags:
        - Archivos y documentos contables
      summary: Generar archivo contable
      description: |
        **¿Qué hace este endpoint?**

        Genera uno o varios archivos contables para un periodo de nómina, compatibles con el software
        contable configurado en la empresa. Soporta generación síncrona (retorna la URL del archivo)
        y asíncrona (encola el trabajo y notifica por Firebase cuando el archivo está listo).

        **¿Cuándo usar este endpoint?**

        * Descargar el archivo de provisión de nómina tras cerrar un periodo.
        * Obtener el comprobante de egreso de seguridad social para registrarlo en el software contable.
        * Generar varios tipos de archivo en una sola llamada enviando múltiples valores en `file_options[]`.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Proveedor contable:** Si no se envía `provider_id`, se usa el proveedor contable por defecto de la empresa. El proveedor debe estar habilitado para la empresa; si no lo está, retorna error `0615`.
        * **Respuesta asíncrona:** Con `async: true`, el archivo se genera en segundo plano. El resultado se publica en la ruta de Firebase `users/{user_id}/periods/{period_id}/accounting_file` cuando esté listo.
        * **Comprobante de seguridad social:** Para generar `social_security_payment`, el periodo debe tener la información de seguridad social completa; si no, retorna error `0614`.
      parameters:
        - name: provider_id
          in: query
          required: false
          description: Identificador único (ID) de la institución proveedora de software contable. Si no se envía, se usa el proveedor contable por defecto de la empresa.
          schema:
            type: string
            example: 840e02c3-adca-476a-b78f-e313b896293d
        - name: file_options[]
          in: query
          required: false
          description: Tipos de archivo a generar. Puede enviarse como string (un tipo) o como array (varios tipos). Si no se envía, genera `payroll` por defecto.
          schema:
            oneOf:
              - $ref: '#/components/schemas/AccountingDocumentType'
              - type: array
                items:
                  $ref: '#/components/schemas/AccountingDocumentType'
                example:
                  - payroll
                  - social_benefits
        - name: period_option
          in: query
          required: false
          description: 'Tipo de periodo a generar. Solo aplica para periodos quincenales. Valores posibles: monthly (mensual, acumula ambas quincenas), fortnightly (quincenal).'
          schema:
            type: string
            enum:
              - monthly
              - fortnightly
            example: monthly
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo generado.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/periods/{period_id}/accounting_file`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo contable generado.
                        type: string
                        example: https://storage.aleluya.com/files/accounting_payroll_2024_01.xlsx
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que el archivo está siendo procesado en segundo plano.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/files/accounting_payroll_2024_01.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Opciones de archivo inválidas / Proveedor no habilitado / Información SS incompleta / Error al generar archivo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Opciones de archivo inválidas:
                  value:
                    error:
                      - code: '0618'
                        index: 0
                        message: Las opciones de archivo son inválidas.
                        object: file
                Proveedor contable no habilitado:
                  value:
                    error:
                      - code: '0615'
                        index: 0
                        message: El proveedor contable seleccionado no está habilitado para esta empresa.
                        object: accounting_provider
                Información de seguridad social incompleta:
                  value:
                    error:
                      - code: '0614'
                        index: 0
                        message: Completa o corrige la información de seguridad social para poder generar la interfaz contable de pago de seguridad social.
                        object: file
                Error al generar el archivo:
                  value:
                    error:
                      - code: '0602'
                        index: 0
                        message: No es posible generar el archivo.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/accounting/options:
    get:
      operationId: showAccountingOptions
      tags:
        - Archivos y documentos contables
      summary: Obtener opciones contables del periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones disponibles para generar archivos contables de un periodo:
        los proveedores de software contable habilitados, los tipos de archivo disponibles
        y las opciones de periodo (aplica solo para periodos quincenales).

        **¿Cuándo usar este endpoint?**

        * Cargar las opciones antes de presentar el formulario de generación de archivos contables.
        * Determinar qué proveedores contables están habilitados para la empresa y cuál está seleccionado por defecto.
        * Saber si el periodo es quincenal para mostrar la opción de generar el archivo mensual acumulado.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Opciones de periodo:** `period_options` solo retorna valores cuando el periodo es quincenal y corresponde a la segunda quincena. Para periodos mensuales o primera quincena, retorna `null`.
        * **Tipos de archivo:** `file_options` siempre incluye los cuatro tipos base (nómina, prestaciones, seguridad social, comprobante de nómina). La opción `social_security_payment` (comprobante de seguridad social) se incluye únicamente si el periodo tiene información de seguridad social completa.
      responses:
        '200':
          description: Opciones contables del periodo
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones disponibles para la generación de archivos contables del periodo.
                    type: object
                    properties:
                      provider_options:
                        description: Proveedores de software contable habilitados para la empresa. El campo `selected` indica cuál es el proveedor por defecto configurado en la empresa.
                        type: array
                        items:
                          description: Proveedor de software contable habilitado.
                          type: object
                          properties:
                            label:
                              description: Nombre del proveedor de software contable.
                              type: string
                              example: Siigo
                            value:
                              description: Identificador único (ID) asignado al proveedor en la base de datos.
                              type: string
                              example: 35ee2870-2464-5d61-bf46-8d364b5e8a30
                            selected:
                              description: Indica si este proveedor es el proveedor contable por defecto configurado en la empresa.
                              type: boolean
                              example: true
                      period_options:
                        description: Opciones de periodo para la generación del archivo. Solo retorna valores cuando el periodo es quincenal y corresponde a la segunda quincena; en caso contrario retorna null.
                        type:
                          - array
                          - 'null'
                        items:
                          description: Opción de periodo disponible para la generación del archivo contable.
                          type: object
                          properties:
                            label:
                              description: Nombre legible de la opción de periodo en español.
                              type: string
                              example: Quincenal
                            value:
                              description: 'Valor de la opción de periodo. Valores posibles: fortnightly (quincenal), monthly (mensual acumulado de ambas quincenas).'
                              type: string
                              example: fortnightly
                      file_options:
                        description: Tipos de archivo contable disponibles para generar en el periodo.
                        type: array
                        items:
                          description: Tipo de archivo contable disponible.
                          type: object
                          properties:
                            label:
                              description: Nombre legible del tipo de archivo contable en español.
                              type: string
                              example: Nómina (provisión)
                            value:
                              description: 'Identificador del tipo de archivo. Valores posibles: payroll (nómina), social_benefits (prestaciones), social_security (seguridad social), payroll_payment (comprobante de nómina), social_security_payment (comprobante de seguridad social).'
                              type: string
                              example: payroll
              example:
                data:
                  provider_options:
                    - label: Siigo
                      value: 35ee2870-2464-5d61-bf46-8d364b5e8a30
                      selected: true
                    - label: Alegra
                      value: 68d7b426-5a8d-59a8-9cac-bcaed834b656
                      selected: false
                  period_options:
                    - label: Quincenal
                      value: fortnightly
                    - label: Mensual
                      value: monthly
                  file_options:
                    - label: Nómina (provisión)
                      value: payroll
                    - label: Prestaciones sociales (provisión)
                      value: social_benefits
                    - label: Seguridad social (provisión)
                      value: social_security
                    - label: Nómina y Prestaciones (comprobante de egreso)
                      value: payroll_payment
                    - label: Seguridad social (comprobante de egreso)
                      value: social_security_payment
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/analyses/overtime/file:
    get:
      operationId: showOvertimeFile
      tags:
        - Análisis de horas extras y recargos
      summary: Generar archivo de horas extras y recargos
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo de reporte de horas extras y recargos del periodo indicado.
        El archivo contiene el detalle de horas extras y recargos liquidados para todos los contratos
        de la empresa en el periodo seleccionado.

        Soporta dos modos de operación según el parámetro `async`:

        * **Síncrono (por defecto):** Genera el archivo de inmediato y retorna la URL de descarga.
        * **Asíncrono (`async=true`):** Encola el trabajo en segundo plano y retorna un mensaje de confirmación. El archivo se
          notifica al usuario vía Firebase cuando está listo, publicando el archivo en la ruta:

          `users/{user_id}/periods/{period_id}/analyses/overtime_surcharges_report_file`

        **¿Cuándo usar este endpoint?**

        * **Descargar el reporte del periodo:** Obtener el archivo XLSX con el detalle de horas extras y recargos para revisión o carga en sistemas externos.
        * **Consultar análisis de nómina:** Obtener el archivo como parte del flujo de revisión del análisis de horas extras y recargos de un periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Periodo válido:** El periodo especificado en `{period_id}` debe pertenecer a la empresa indicada en `{company_id}`.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: Archivo generado / Procesamiento en cola
          content:
            application/json; charset=utf-8:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del archivo XLSX generado con el reporte de horas extras y recargos. Presente únicamente en modo síncrono.
                    type:
                      - string
                      - 'null'
                    example: https://storage.example.com/Reporte_horas_extras_y_recargos.xlsx
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación retornado en modo asíncrono indicando que el trabajo fue encolado para procesamiento. Presente únicamente cuando `async=true`.
                        type:
                          - string
                          - 'null'
                        example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.example.com/Reporte_horas_extras_y_recargos.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador de la empresa
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador del periodo
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/accounting/sync_journals:
    post:
      operationId: createAccountingSyncJournals
      tags:
        - Archivos y documentos contables
      summary: Sincronizar asientos contables
      description: |
        **¿Qué hace este endpoint?**

        Inicia la sincronización de asientos contables del periodo con la integración contable
        activa de la empresa (Siigo o PYA). El proceso se ejecuta en segundo plano
        y notifica el resultado vía Firebase cuando finaliza.

        **¿Cuándo usar este endpoint?**

        * Enviar los asientos contables del periodo al software contable tras cerrar la nómina.
        * Resincronizar los asientos contables si se realizaron ajustes en el periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Integración activa requerida:** La empresa debe tener activa una integración contable con el proveedor especificado en `provider`. Si no existe o no está activa, retorna error `1216`.
        * **Resultado vía Firebase:** El resultado de la sincronización se publica en `users/{user_id}/accounting_integrations/{integration_id}/syncs/{period_id}` cuando el proceso finaliza.
      parameters:
        - in: query
          name: provider
          required: true
          description: 'Identificador del proveedor de la integración contable activa de la empresa. Valores posibles: siigo (Siigo), pya (PYA).'
          schema:
            type: string
            enum:
              - siigo
              - pya
            example: siigo
        - in: query
          name: period_id
          required: true
          description: Identificador único (ID) del periodo de nómina cuyos asientos contables se sincronizan.
          schema:
            type: string
            example: 86e4bbab-7a86-536e-85a0-2ac57955857d
      requestBody:
        required: true
        description: Un tipo de documento / Varios tipos de documento
        content:
          application/json:
            schema:
              type: object
              properties:
                file_options:
                  description: Tipos de documento contable a sincronizar. Puede enviarse como string (un tipo) o como array (varios tipos).
                  oneOf:
                    - $ref: '#/components/schemas/AccountingDocumentType'
                    - type: array
                      items:
                        $ref: '#/components/schemas/AccountingDocumentType'
                      example:
                        - payroll
                        - social_benefits
                accounting_scope:
                  description: 'Alcance del periodo a sincronizar. Solo aplica para periodos quincenales de segunda quincena. Valores posibles: fortnightly (solo la quincena actual), monthly (acumula ambas quincenas).'
                  type: string
                  enum:
                    - monthly
                    - fortnightly
                  example: fortnightly
            examples:
              Un tipo de documento:
                value:
                  file_options: payroll
                  accounting_scope: fortnightly
              Varios tipos de documento:
                value:
                  file_options:
                    - payroll
                    - social_benefits
                  accounting_scope: fortnightly
      responses:
        '200':
          description: Sincronización iniciada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de que la sincronización fue iniciada y se está procesando en segundo plano.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Integración contable inactiva / Sin acceso a la integración
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Integración contable inactiva:
                  value:
                    error:
                      - code: '1216'
                        index: 0
                        message: La empresa no tiene activa ninguna integración contable.
                        object: integration
                Sin acceso a la integración:
                  value:
                    error:
                      - code: '1218'
                        index: 0
                        message: No tienes acceso a esta integración.
                        object: integration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/periods/{period_id}/bank_file_options:
    get:
      operationId: showPeriodBankFileOptions
      tags:
        - Archivos bancarios
      summary: Obtener opciones bancarias de periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones disponibles para generar el archivo bancario de pago de un periodo completo: tipos de contrato, sedes, tipos de pago según las liquidaciones y prestaciones sociales del periodo.

        **¿Cuándo usar este endpoint?**

        * Consultar las opciones disponibles antes de generar el archivo bancario de un periodo de nómina.
        * Verificar qué sedes y tipos de contrato están disponibles para filtrar los pagos al generar el archivo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Cuenta bancaria:** La empresa debe tener al menos una cuenta bancaria registrada. Si no la tiene, el endpoint retorna `422`.
      responses:
        '200':
          description: Opciones para generar el archivo bancario del periodo
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones disponibles para la generación del archivo bancario del periodo.
                    type: object
                    properties:
                      bank_name:
                        description: Nombre del banco principal configurado para la empresa. Puede ser null si no se encuentra el banco.
                        type:
                          - string
                          - 'null'
                        example: bancolombia
                      contract_type:
                        description: Tipos de contrato con personas activas en el periodo. Solo incluye las opciones con personas para pagos.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Etiqueta legible del tipo de contrato.
                              type: string
                              example: Nómina
                            value:
                              description: Valor del tipo de contrato que se envía al generar el archivo.
                              type: string
                              example: payroll
                        example:
                          - label: Nómina
                            value: payroll
                          - label: Contratistas
                            value: contractor
                      locations:
                        description: Sedes de la empresa disponibles para filtrar personas al generar el archivo bancario. Siempre incluye la opción "Empresa" para todas las sedes.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Nombre de la sede o "Empresa" para la opción que agrupa todas las sedes.
                              type: string
                              example: Empresa
                            value:
                              description: Identificador de la sede. El valor `company` agrupa todas las sedes; los UUIDs corresponden a sedes específicas.
                              type: string
                              example: company
                        example:
                          - label: Empresa
                            value: company
                          - label: Sede Principal
                            value: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                      payment_type:
                        description: Tipos de pago disponibles para incluir en el archivo bancario. Depende de si el periodo tiene liquidaciones o prestaciones sociales.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Etiqueta legible del tipo de pago para mostrar al usuario.
                              type: string
                              example: Nómina
                            value:
                              description: Valor del tipo de pago que se envía al generar el archivo.
                              type: string
                              example: payroll
                        example:
                          - label: Nómina
                            value: payroll
                          - label: Liquidación
                            value: termination
                          - label: Liquidación más nómina (solo liquidados)
                            value: payroll_termination
                          - label: Nómina completa (sin pago anticipado) más liquidación
                            value: payroll_termination_full
                          - label: Nómina más prima de servicios
                            value: payroll_service_bonus
                          - label: Prima de servicios
                            value: service_bonus
              example:
                data:
                  bank_name: bancolombia
                  contract_type:
                    - label: Nómina
                      value: payroll
                    - label: Contratistas
                      value: contractor
                  locations:
                    - label: Empresa
                      value: company
                    - label: Sede Principal
                      value: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                  payment_type:
                    - label: Nómina
                      value: payroll
                    - label: Liquidación
                      value: termination
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin cuenta bancaria
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0604'
                    index: 0
                    message: Completa la información de tu empresa, ingresando un Banco y el número de cuenta.
                    object: company
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
  /v1/{company_id}/periods/{period_id}/bank_files:
    get:
      operationId: indexBankFiles
      tags:
        - Archivos bancarios
      summary: Obtener archivo bancario del periodo
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo bancario para el pago de nómina de todas las personas de un periodo.
        Permite incluir solo un subconjunto de personas según sede, tipo de contrato o tipo de pago.

        **¿Cuándo usar este endpoint?**

        * Generar el archivo de pago masivo para todas las nóminas de un periodo antes de enviarlo al banco.
        * Filtrar el archivo por sede cuando la empresa paga desde cuentas distintas por sede.
        * Obtener el archivo de prestaciones sociales o liquidaciones del periodo de forma masiva.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Cuenta bancaria requerida:** El parámetro `bank_account_id` es obligatorio. Si no se encuentra, retorna 404.
        * **Banco sin soporte:** Si el banco de la cuenta no tiene generación de archivo configurada, retorna 422.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: true
          name: bank_account_id
          description: Identificador único (ID) de la cuenta bancaria de la empresa que se usará para generar el archivo.
          schema:
            type: string
            example: 7b3a1f2e-9c4d-4e5f-a6b7-8c9d0e1f2a3b
        - in: query
          required: false
          name: payment_type
          schema:
            $ref: '#/components/schemas/PeriodBankPaymentType'
        - in: query
          required: false
          name: contract_type
          description: 'Tipo de contrato a incluir en el archivo. Valores posibles: `payroll` (empleados y aprendices, por defecto), `contractor` (contratistas). Si no se envía, usa `payroll`.'
          schema:
            type: string
            enum:
              - payroll
              - contractor
            example: payroll
        - in: query
          required: false
          name: file_format
          description: Formato específico del archivo a generar según el banco (ej. `PAB`, `xlsx`, `non_av_villas`). Si no se envía, usa el formato por defecto del banco.
          schema:
            type: string
            example: PAB
        - in: query
          required: false
          name: pay_day
          description: Fecha de pago a registrar en el archivo bancario, en formato `YYYY-MM-DD`. Si no se envía, usa la fecha del sistema.
          schema:
            type: string
            format: date
            example: '2024-01-15'
        - in: query
          required: false
          name: locations[]
          description: Lista de identificadores únicos (IDs) de sedes para filtrar las nóminas incluidas en el archivo. Si no se envía, incluye todas las sedes.
          schema:
            type: array
            items:
              type: string
            example:
              - 64967d4b-7d9b-5188-a014-0a18767ca4c9
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el archivo generado con el conteo de personas y el valor total.
            - **Asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta síncrona
                    required:
                      - file
                      - size
                      - total_value
                    properties:
                      file:
                        description: URL de descarga del archivo bancario generado.
                        type: string
                        example: https://storage.aleluya.com/bank_file.txt
                      size:
                        description: Número de personas incluidas en el archivo bancario.
                        type: integer
                        example: 5
                      total_value:
                        description: Valor total a pagar en pesos colombianos, suma de los pagos de todas las personas incluidas en el archivo.
                        type: integer
                        example: 9750000
                  - type: object
                    description: Respuesta asíncrona
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de encolamiento del archivo.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/bank_file.txt
                    size: 5
                    total_value: 9750000
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Banco sin soporte de archivo bancario / Formato de archivo inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Banco sin soporte de archivo bancario:
                  value:
                    error:
                      - code: '0603'
                        index: 0
                        message: Todavía no hemos generando el archivo para este banco. Si requieres generarlo, comunícate con nuestro equipo de soporte.
                        object: file
                Formato de archivo inválido:
                  value:
                    error:
                      - code: '0606'
                        index: 0
                        message: El tipo de archivo es inválido.
                        object: file_type
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/decree376/period_payment_files/{id}:
    get:
      operationId: showDecree376PeriodPaymentFile
      tags:
        - Decreto 376
      summary: Obtener archivo de pagos del Decreto 376
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo Excel con el detalle de pagos de pensión del Decreto 376
        para el periodo especificado. Puede ejecutarse de forma síncrona o asíncrona.

        **¿Cuándo usar este endpoint?**

        * Descargar el reporte de pagos del Decreto 376 para revisión contable o como soporte.
        * Generar el archivo en segundo plano cuando el volumen de datos es grande.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Periodo aplica Decreto 376:** El periodo especificado en `{period_id}` debe ser
          un periodo que aplique el Decreto 376. Si no lo es, se retorna un error 422.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/periods/{period_id}/decree376/payments_file/{id}` para recibir
          la URL del archivo cuando esté listo.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: Archivo generado / Generación encolada
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel de pagos del Decreto 376 generado.
                        type: string
                        example: https://storage.aleluya.com/documents/decreto376-pagos-enero-2024.xlsx
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que la generación del archivo fue encolada.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/documents/decreto376-pagos-enero-2024.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo no aplica el Decreto 376
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0422'
                    index: 0
                    message: Periodo es inválido.
                    object: period
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al periodo del Decreto 376 en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-f6a7-8901-bcde-f01234567890
  /v1/{company_id}/periods/{period_id}/decree376/periods/{id}:
    get:
      operationId: showDecree376Period
      tags:
        - Decreto 376
      summary: Obtener periodo del Decreto 376
      description: |
        **¿Qué hace este endpoint?**

        Retorna los datos del periodo del Decreto 376 junto con el listado de pagos
        de pensión por persona: aportes empresa, aportes trabajador, saldos pendientes y
        opciones de pago disponibles según el estado de cada contrato.

        **¿Cuándo usar este endpoint?**

        * Consultar los pagos pendientes del Decreto 376 antes de liquidarlos en el periodo.
        * Verificar los saldos de pensión de cada persona para determinar qué acción aplicar.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Periodo aplica Decreto 376:** El periodo especificado en `{period_id}` debe ser
          un periodo que aplique el Decreto 376. Si no lo es, se retorna un error 422.
      responses:
        '200':
          description: Periodo del Decreto 376 obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del periodo y los pagos del Decreto 376.
                    type: object
                    properties:
                      decree376_period:
                        description: Información del periodo del Decreto 376 con sus totales de aportes.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo del Decreto 376 en la base de datos.
                            type: string
                            example: b2c3d4e5-f6a7-8901-bcde-f01234567890
                          initial_day:
                            description: Fecha de inicio del periodo del Decreto 376 en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del periodo del Decreto 376 en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-03-31'
                          period_initial_day:
                            description: Fecha de inicio del periodo de nómina asociado en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          period_end_day:
                            description: Fecha de fin del periodo de nómina asociado en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-31'
                          total_pension_contribution:
                            description: Total de aportes de pensión calculados para el periodo del Decreto 376 en pesos colombianos.
                            type: integer
                            example: 5000000
                          total_pension_paid_contribution:
                            description: Total de aportes de pensión ya pagados en el periodo del Decreto 376 en pesos colombianos.
                            type: integer
                            example: 3000000
                          pension_contribution_balance:
                            description: Saldo pendiente de aportes de pensión del periodo del Decreto 376 en pesos colombianos.
                            type: integer
                            example: 2000000
                      decree376_payments:
                        description: Lista de pagos del Decreto 376 por persona.
                        type: array
                        items:
                          description: Datos de pago del Decreto 376 para una persona.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al pago del Decreto 376 en la base de datos.
                              type: string
                              example: c3d4e5f6-a7b8-9012-cdef-012345678901
                            worker_id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            worker_name:
                              description: Nombre completo de la persona para efectos del Decreto 376.
                              type: string
                              example: Juan Pérez
                            contract_id:
                              description: Identificador único (ID) asignado al contrato en la base de datos.
                              type: string
                              example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                            paid_in_period:
                              description: Tipo de pago ya realizado en el periodo para esta persona. Es `null` si no se ha realizado ningún pago en el periodo actual.
                              type:
                                - string
                                - 'null'
                              example: company_and_worker
                            ibc:
                              description: Ingreso base de cotización de la persona para el periodo del Decreto 376 en pesos colombianos.
                              type: integer
                              example: 3500000
                            company_contribution_value:
                              description: Valor del aporte de pensión a cargo de la empresa en pesos colombianos.
                              type: integer
                              example: 280000
                            company_paid_contribution:
                              description: Valor del aporte de pensión ya pagado por la empresa en pesos colombianos.
                              type: integer
                              example: 140000
                            company_balance:
                              description: Saldo pendiente del aporte de pensión a cargo de la empresa en pesos colombianos.
                              type: integer
                              example: 140000
                            worker_contribution_value:
                              description: Valor del aporte de pensión a cargo del trabajador en pesos colombianos.
                              type: integer
                              example: 140000
                            worker_paid_contribution:
                              description: Valor del aporte de pensión ya pagado por el trabajador en pesos colombianos.
                              type: integer
                              example: 70000
                            worker_balance:
                              description: Saldo pendiente del aporte de pensión a cargo del trabajador en pesos colombianos.
                              type: integer
                              example: 70000
                            payment_options:
                              description: Opciones de pago disponibles para esta persona según el estado del contrato. `company_and_worker` paga ambas partes, `company` solo empresa, `delete` elimina el pago del periodo.
                              type: array
                              items:
                                type: string
                              example:
                                - company_and_worker
                                - company
              example:
                data:
                  decree376_period:
                    id: b2c3d4e5-f6a7-8901-bcde-f01234567890
                    initial_day: '2024-01-01'
                    end_day: '2024-03-31'
                    period_initial_day: '2024-01-01'
                    period_end_day: '2024-01-31'
                    total_pension_contribution: 5000000
                    total_pension_paid_contribution: 3000000
                    pension_contribution_balance: 2000000
                  decree376_payments:
                    - id: c3d4e5f6-a7b8-9012-cdef-012345678901
                      worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name: Juan Pérez
                      contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      paid_in_period: null
                      ibc: 3500000
                      company_contribution_value: 280000
                      company_paid_contribution: 0
                      company_balance: 280000
                      worker_contribution_value: 140000
                      worker_paid_contribution: 0
                      worker_balance: 140000
                      payment_options:
                        - company_and_worker
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo no aplica el Decreto 376
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0422'
                    index: 0
                    message: Periodo es inválido.
                    object: period
    put:
      operationId: updateDecree376Period
      tags:
        - Decreto 376
      summary: Actualizar pagos del Decreto 376
      description: |
        **¿Qué hace este endpoint?**

        Procesa los pagos del Decreto 376 para las personas indicadas en el periodo.
        La acción aplicada por persona determina si se crean, actualizan o eliminan los
        ítems de nómina correspondientes a los aportes de pensión:

        * **`company_and_worker`:** Registra el pago de aportes tanto de la empresa como del trabajador.
        * **`company`:** Registra solo el pago del aporte a cargo de la empresa (aplica para contratos terminados antes del Decreto 376).
        * **`delete`:** Elimina el pago del Decreto 376 registrado en el periodo para la persona.

        Todas las operaciones se ejecutan en una transacción atómica.

        **¿Cuándo usar este endpoint?**

        * Liquidar los aportes de pensión del Decreto 376 para las personas del periodo.
        * Eliminar pagos registrados incorrectamente para una persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Periodo editable:** El periodo de nómina debe estar en estado editable.
        * **Periodo aplica Decreto 376:** El periodo especificado en `{period_id}` debe ser
          un periodo que aplique el Decreto 376.
        * **Acciones válidas:** Solo se pueden enviar acciones disponibles en el campo
          `payment_options` de cada pago retornado por el GET.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                decree376_payments:
                  description: Lista de pagos del Decreto 376 a procesar con la acción a aplicar.
                  type: array
                  items:
                    type: object
                    properties:
                      contract_id:
                        description: Identificador único (ID) del contrato de la persona a procesar.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      action:
                        description: Acción a aplicar. `company_and_worker` paga empresa y trabajador, `company` solo empresa, `delete` elimina el pago del periodo.
                        type: string
                        enum:
                          - company_and_worker
                          - company
                          - delete
                        example: company_and_worker
              required:
                - decree376_payments
            example:
              decree376_payments:
                - contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  action: company_and_worker
                - contract_id: 1b2c3d4e-5f6a-7890-abcd-ef1234567890
                  action: company
      responses:
        '202':
          description: Pagos del Decreto 376 actualizados exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados del periodo y los pagos del Decreto 376.
                    type: object
                    properties:
                      decree376_period:
                        description: Información actualizada del periodo del Decreto 376 con sus totales de aportes.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al periodo del Decreto 376 en la base de datos.
                            type: string
                            example: b2c3d4e5-f6a7-8901-bcde-f01234567890
                          initial_day:
                            description: Fecha de inicio del periodo del Decreto 376 en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del periodo del Decreto 376 en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-03-31'
                          period_initial_day:
                            description: Fecha de inicio del periodo de nómina asociado en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          period_end_day:
                            description: Fecha de fin del periodo de nómina asociado en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-31'
                          total_pension_contribution:
                            description: Total de aportes de pensión calculados para el periodo del Decreto 376 en pesos colombianos.
                            type: integer
                            example: 5000000
                          total_pension_paid_contribution:
                            description: Total de aportes de pensión ya pagados en el periodo del Decreto 376 en pesos colombianos.
                            type: integer
                            example: 5000000
                          pension_contribution_balance:
                            description: Saldo pendiente de aportes de pensión del periodo del Decreto 376 en pesos colombianos.
                            type: integer
                            example: 0
                      decree376_payments:
                        description: Lista actualizada de pagos del Decreto 376 por persona.
                        type: array
                        items:
                          description: Datos actualizados de pago del Decreto 376 para una persona.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al pago del Decreto 376 en la base de datos.
                              type: string
                              example: c3d4e5f6-a7b8-9012-cdef-012345678901
                            worker_id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            worker_name:
                              description: Nombre completo de la persona para efectos del Decreto 376.
                              type: string
                              example: Juan Pérez
                            contract_id:
                              description: Identificador único (ID) asignado al contrato en la base de datos.
                              type: string
                              example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                            paid_in_period:
                              description: Tipo de pago realizado en el periodo para esta persona. Es `null` si no se realizó ningún pago.
                              type:
                                - string
                                - 'null'
                              example: company_and_worker
                            ibc:
                              description: Ingreso base de cotización de la persona en pesos colombianos.
                              type: integer
                              example: 3500000
                            company_contribution_value:
                              description: Valor del aporte de pensión a cargo de la empresa en pesos colombianos.
                              type: integer
                              example: 280000
                            company_paid_contribution:
                              description: Valor del aporte de pensión ya pagado por la empresa en pesos colombianos.
                              type: integer
                              example: 280000
                            company_balance:
                              description: Saldo pendiente del aporte de pensión a cargo de la empresa en pesos colombianos.
                              type: integer
                              example: 0
                            worker_contribution_value:
                              description: Valor del aporte de pensión a cargo del trabajador en pesos colombianos.
                              type: integer
                              example: 140000
                            worker_paid_contribution:
                              description: Valor del aporte de pensión ya pagado por el trabajador en pesos colombianos.
                              type: integer
                              example: 140000
                            worker_balance:
                              description: Saldo pendiente del aporte de pensión a cargo del trabajador en pesos colombianos.
                              type: integer
                              example: 0
                            payment_options:
                              description: Opciones de pago disponibles para esta persona según el estado actual del contrato.
                              type: array
                              items:
                                type: string
                              example:
                                - delete
                                - company_and_worker
              example:
                data:
                  decree376_period:
                    id: b2c3d4e5-f6a7-8901-bcde-f01234567890
                    initial_day: '2024-01-01'
                    end_day: '2024-03-31'
                    period_initial_day: '2024-01-01'
                    period_end_day: '2024-01-31'
                    total_pension_contribution: 5000000
                    total_pension_paid_contribution: 5000000
                    pension_contribution_balance: 0
                  decree376_payments:
                    - id: c3d4e5f6-a7b8-9012-cdef-012345678901
                      worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name: Juan Pérez
                      contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      paid_in_period: company_and_worker
                      ibc: 3500000
                      company_contribution_value: 280000
                      company_paid_contribution: 280000
                      company_balance: 0
                      worker_contribution_value: 140000
                      worker_paid_contribution: 140000
                      worker_balance: 0
                      payment_options:
                        - delete
                        - company_and_worker
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo no editable / Periodo no aplica el Decreto 376
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Periodo no editable:
                  value:
                    error:
                      - code: '0902'
                        index: 0
                        message: no se puede editar porque la nómina no es editable.
                        object: social_benefit
                Periodo no aplica el Decreto 376:
                  value:
                    error:
                      - code: '0422'
                        index: 0
                        message: Periodo es inválido.
                        object: period
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al periodo del Decreto 376 en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-f6a7-8901-bcde-f01234567890
  /v1/{company_id}/periods/{period_id}/decree376/social_security_files/{id}:
    get:
      operationId: showDecree376SocialSecurityFile
      tags:
        - Decreto 376
      summary: Obtener archivo PILA de corrección Decreto 376
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo de planilla PILA de corrección bajo el Decreto 376
        para el periodo especificado. Requiere el número de planilla original y la fecha
        de pago para generar la corrección. Puede ejecutarse de forma síncrona o asíncrona.

        **¿Cuándo usar este endpoint?**

        * Generar la planilla PILA de corrección para enviarla al operador de seguridad social.
        * Descargar el archivo de corrección en segundo plano cuando el volumen de datos es grande.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Periodo con archivo de seguridad social:** El periodo del Decreto 376 debe tener
          un periodo de seguridad social asociado con archivo generado. Si no lo tiene, se
          retorna un error 422.
        * **Información completa:** Todos los contratos del periodo deben tener la información
          de seguridad social completa.
        * **`associated_form` obligatorio:** Número de planilla de seguridad social original
          a la que se asocia esta corrección. Máximo 10 caracteres.
        * **`payment_date` obligatorio:** Fecha en que se realizó el pago de la planilla
          original, en formato YYYY-MM-DD.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/periods/{period_id}/decree376/social_security_file/{id}` para
          recibir la URL del archivo cuando esté listo.
      parameters:
        - in: query
          name: associated_form
          required: true
          description: Número de la planilla de seguridad social original a la que se asocia esta corrección del Decreto 376. Máximo 10 caracteres.
          schema:
            type: string
            example: '123456789'
        - in: query
          name: payment_date
          required: true
          description: Fecha en que se realizó el pago de la planilla original, en formato YYYY-MM-DD.
          schema:
            type: string
            format: date
            example: '2024-01-25'
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo generado.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/periods/{period_id}/decree376/social_security_file/{id}`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo PILA de corrección Decreto 376 generado.
                        type: string
                        example: https://storage.aleluya.com/documents/pila-decreto376-correccion-enero-2024.txt
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que la generación del archivo fue encolada.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/documents/pila-decreto376-correccion-enero-2024.txt
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo no apto para archivo / Parámetros obligatorios ausentes / Formato de fecha inválido / Información de seguridad social incompleta
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Periodo no apto para archivo:
                  value:
                    error:
                      - code: '0602'
                        index: 0
                        message: No es posible generar el archivo.
                        object: file
                Parámetros obligatorios ausentes:
                  value:
                    error:
                      - code: '0610'
                        index: 0
                        message: Debes enviar el número de planilla y la fecha en la que se realizó el pago de la misma para realizar esta correción.
                        object: file
                Número de planilla demasiado largo:
                  value:
                    error:
                      - code: '0611'
                        index: 0
                        message: El número de la planilla tiene un máximo de 10 caracteres.
                        object: file
                Formato de fecha inválido:
                  value:
                    error:
                      - code: '0412'
                        index: 0
                        message: El formato de la fecha es inválido.
                        object: date
                Información de seguridad social incompleta:
                  value:
                    error:
                      - code: '0607'
                        index: 0
                        message: Completa o corrige la información de seguridad social para poder generar la planilla de seguridad social.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al periodo del Decreto 376 en la base de datos.
        schema:
          type: string
          example: b2c3d4e5-f6a7-8901-bcde-f01234567890
  /v1/{company_id}/periods/{period_id}/import_payroll_novelties:
    get:
      operationId: showImportPayrollNovelties
      tags:
        - Novedades
      summary: Descargar plantilla de novedades
      description: |
        **¿Qué hace este endpoint?**

        Genera el archivo Excel (plantilla) con las personas del periodo para diligenciar y cargar las novedades de nómina.

        **¿Cuándo usar este endpoint?**

        * Obtener la plantilla de importación de novedades de nómina de un periodo.
        * Descargar el formato Excel para diligenciar las novedades antes de importarlas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** La empresa debe tener un plan activo para acceder a esta funcionalidad.
      responses:
        '200':
          description: Descarga de plantilla encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que la generación fue encolada. El resultado se notifica vía Firebase.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createImportPayrollNovelties
      tags:
        - Novedades
      summary: Importar novedades de nómina
      description: |
        **¿Qué hace este endpoint?**

        Recibe el archivo Excel con las novedades de nómina diligenciadas y las aplica masivamente a las nóminas del periodo.

        **¿Cuándo usar este endpoint?**

        * Cargar masivamente novedades de nómina (horas extras, licencias, ingresos, deducciones, etc.) para un periodo.
        * Importar el archivo Excel diligenciado a partir de la plantilla descargada con el GET de este mismo endpoint.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Formato del archivo:** El archivo debe ser de tipo Excel (`.xlsx`). Archivos de otro formato serán rechazados.
        * **Pago activo:** La empresa debe tener un plan activo para usar esta funcionalidad.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  description: Archivo Excel (`.xlsx`) con las novedades de nómina a importar.
                  type: string
                  format: binary
      responses:
        '200':
          description: Archivo de novedades encolado correctamente para su procesamiento
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que el archivo fue recibido y está siendo procesado.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: El archivo enviado no es válido o tiene un formato incorrecto
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    put:
      operationId: updateImportPayrollNovelties
      tags:
        - Novedades
      summary: Reprocesar novedades con errores
      description: |
        **¿Qué hace este endpoint?**

        Recibe el resultado de una importación previa de novedades que tuvo registros fallidos y encola el reprocesamiento únicamente de los casos que fallaron en cada hoja (horas extras, novedades, licencias, ingresos y deducciones).

        **¿Cuándo usar este endpoint?**

        * Reintentar el procesamiento de los registros que fallaron tras una importación de novedades con errores.
        * Enviar las correcciones una vez revisados y ajustados los datos del archivo de errores generado por la importación inicial.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** La empresa debe tener un plan activo para usar esta funcionalidad.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - updated_novelties_data
              properties:
                updated_novelties_data:
                  description: Objeto con los resultados de la importación anterior, incluyendo conteos de éxito, fallos y los datos de las hojas con errores.
                  type: object
                  required:
                    - success_workers_count
                    - success_workers_ids
                    - failure_cases_total_count
                    - file_with_errors
                    - overtime
                    - novelties
                    - licenses
                    - incomes
                    - deductions
                  properties:
                    success_workers_count:
                      description: Número de trabajadores procesados correctamente en la importación anterior.
                      type: integer
                      example: 0
                    success_workers_ids:
                      description: Lista de IDs de los trabajadores procesados correctamente.
                      type: array
                      items:
                        type: string
                        example: d2bc3e5a-dc49-4160-8d01-6dedbba4c0c0
                    failure_cases_total_count:
                      description: Número total de registros con error en la importación anterior.
                      type: integer
                      example: 8
                    file_with_errors:
                      description: Indica si existe un archivo con los errores de la importación anterior.
                      type: boolean
                      example: true
                    overtime:
                      description: Datos de la hoja de horas extras con resultados de éxito y fallo.
                      type: object
                      required:
                        - success_cases
                        - failure_cases_count
                        - failure_cases
                      properties:
                        success_cases:
                          description: Número de casos procesados correctamente en esta hoja.
                          type: integer
                          example: 0
                        failure_cases_count:
                          description: Número de casos con error en esta hoja.
                          type: integer
                          example: 2
                        failure_cases:
                          description: Detalle de los registros que fallaron, con columnas y filas del archivo original.
                          type: object
                          required:
                            - columns
                            - rows
                          properties:
                            columns:
                              description: Nombres de las columnas de la hoja con errores.
                              type: array
                              items:
                                type: string
                              example: []
                            rows:
                              description: Filas con los datos de los registros que fallaron.
                              type: array
                              items:
                                type: string
                              example: []
                    novelties:
                      description: Datos de la hoja de novedades con resultados de éxito y fallo.
                      type: object
                      required:
                        - success_cases
                        - failure_cases_count
                        - failure_cases
                      properties:
                        success_cases:
                          description: Número de casos procesados correctamente en esta hoja.
                          type: integer
                          example: 0
                        failure_cases_count:
                          description: Número de casos con error en esta hoja.
                          type: integer
                          example: 2
                        failure_cases:
                          description: Detalle de los registros que fallaron, con columnas y filas del archivo original.
                          type: object
                          required:
                            - columns
                            - rows
                          properties:
                            columns:
                              description: Nombres de las columnas de la hoja con errores.
                              type: array
                              items:
                                type: string
                              example: []
                            rows:
                              description: Filas con los datos de los registros que fallaron.
                              type: array
                              items:
                                type: string
                              example: []
                    licenses:
                      description: Datos de la hoja de licencias con resultados de éxito y fallo.
                      type: object
                      required:
                        - success_cases
                        - failure_cases_count
                        - failure_cases
                      properties:
                        success_cases:
                          description: Número de casos procesados correctamente en esta hoja.
                          type: integer
                          example: 0
                        failure_cases_count:
                          description: Número de casos con error en esta hoja.
                          type: integer
                          example: 2
                        failure_cases:
                          description: Detalle de los registros que fallaron, con columnas y filas del archivo original.
                          type: object
                          required:
                            - columns
                            - rows
                          properties:
                            columns:
                              description: Nombres de las columnas de la hoja con errores.
                              type: array
                              items:
                                type: string
                              example: []
                            rows:
                              description: Filas con los datos de los registros que fallaron.
                              type: array
                              items:
                                type: string
                              example: []
                    incomes:
                      description: Datos de la hoja de ingresos con resultados de éxito y fallo.
                      type: object
                      required:
                        - success_cases
                        - failure_cases_count
                        - failure_cases
                      properties:
                        success_cases:
                          description: Número de casos procesados correctamente en esta hoja.
                          type: integer
                          example: 0
                        failure_cases_count:
                          description: Número de casos con error en esta hoja.
                          type: integer
                          example: 2
                        failure_cases:
                          description: Detalle de los registros que fallaron, con columnas y filas del archivo original.
                          type: object
                          required:
                            - columns
                            - rows
                          properties:
                            columns:
                              description: Nombres de las columnas de la hoja con errores.
                              type: array
                              items:
                                type: string
                              example: []
                            rows:
                              description: Filas con los datos de los registros que fallaron.
                              type: array
                              items:
                                type: string
                              example: []
                    deductions:
                      description: Datos de la hoja de deducciones con resultados de éxito y fallo.
                      type: object
                      required:
                        - success_cases
                        - failure_cases_count
                        - failure_cases
                      properties:
                        success_cases:
                          description: Número de casos procesados correctamente en esta hoja.
                          type: integer
                          example: 0
                        failure_cases_count:
                          description: Número de casos con error en esta hoja.
                          type: integer
                          example: 2
                        failure_cases:
                          description: Detalle de los registros que fallaron, con columnas y filas del archivo original.
                          type: object
                          required:
                            - columns
                            - rows
                          properties:
                            columns:
                              description: Nombres de las columnas de la hoja con errores.
                              type: array
                              items:
                                type: string
                              example: []
                            rows:
                              description: Filas con los datos de los registros que fallaron.
                              type: array
                              items:
                                type: string
                              example: []
            example:
              updated_novelties_data:
                success_workers_count: 0
                success_workers_ids: []
                failure_cases_total_count: 8
                file_with_errors: true
                overtime:
                  success_cases: 0
                  failure_cases_count: 2
                  failure_cases:
                    columns: []
                    rows: []
                novelties:
                  success_cases: 0
                  failure_cases_count: 2
                  failure_cases:
                    columns: []
                    rows: []
                licenses:
                  success_cases: 0
                  failure_cases_count: 2
                  failure_cases:
                    columns: []
                    rows: []
                incomes:
                  success_cases: 0
                  failure_cases_count: 2
                  failure_cases:
                    columns: []
                    rows: []
                deductions:
                  success_cases: 0
                  failure_cases_count: 2
                  failure_cases:
                    columns: []
                    rows: []
      responses:
        '200':
          description: Corrección de novedades encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación indicando que el reprocesamiento fue encolado.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Los parámetros enviados en `updated_novelties_data` son inválidos o están ausentes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: d2bc3e5a-dc49-4160-8d01-6dedbba4c0c0
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
  /v1/{company_id}/periods/{period_id}/locations_counters:
    get:
      tags:
        - Sedes
      description: Sedes del periodo inválidas
      summary: Listar contadores de sede
      responses:
        '200':
          description: Sedes del periodo listadas correctamente
          content:
            application/json; charset=utf-8:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      locations:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                              example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                            name:
                              type: string
                              example: Location One
                            workers:
                              type: integer
                              example: 3
                          required:
                            - id
                            - name
                            - workers
                        example:
                          - id: 64967d4b-7d9b-5188-a014-0a18767ca4c9
                            name: Location One
                            workers: 3
                    required:
                      - locations
                required:
                  - data
        '401':
          description: Sedes del periodo inválidas
          content:
            application/json; charset=utf-8:
              schema:
                type: object
                properties:
                  error:
                    type: array
                    items:
                      type: object
                      properties:
                        message:
                          type: string
                          example: Credenciales inválidas.
                        code:
                          type: string
                          example: '0001'
                        object:
                          type: string
                          example: user
                        index:
                          type: integer
                          example: 0
                      required:
                        - message
                        - code
                        - object
                        - index
                    example:
                      - message: Credenciales inválidas.
                        code: '0001'
                        object: user
                        index: 0
                required:
                  - error
        '403':
          description: Sedes del periodo inválidas
          content:
            application/json; charset=utf-8:
              schema:
                type: object
                properties:
                  error:
                    type: array
                    items:
                      type: object
                      properties:
                        message:
                          type: string
                          example: No tienes permisos para realizar esta acción.
                        code:
                          type: string
                          example: '0001'
                        object:
                          type: string
                          example: user
                        index:
                          type: integer
                          example: 0
                      required:
                        - message
                        - code
                        - object
                        - index
                    example:
                      - message: No tienes permisos para realizar esta acción.
                        code: '0001'
                        object: user
                        index: 0
                required:
                  - error
        '404':
          description: Sedes del periodo inválidas
          content:
            application/json; charset=utf-8:
              schema:
                type: object
                properties:
                  error:
                    type: array
                    items:
                      type: object
                      properties:
                        message:
                          type: string
                          example: Empresa no existe
                        code:
                          type: string
                          example: '0001'
                        object:
                          type: string
                          example: company
                        index:
                          type: integer
                          example: 0
                      required:
                        - message
                        - code
                        - object
                        - index
                    example:
                      - message: Empresa no existe
                        code: '0001'
                        object: company
                        index: 0
                required:
                  - error
    parameters:
      - in: path
        required: true
        name: company_id
        schema:
          type: string
          example: 558ad131-7a64-4343-977e-cebccef2cd8e
      - in: path
        required: true
        name: period_id
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
  /v1/{company_id}/periods/{period_id}/novelties_history:
    get:
      operationId: showPeriodNoveltiesHistory
      tags:
        - Historial de novedades
      summary: Obtener historial de novedades del periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial de novedades registradas en todas las nóminas del periodo, agrupadas
        por categoría y por persona. También permite exportar el historial completo en un archivo Excel.

        **¿Cuándo usar este endpoint?**

        * Consultar todas las novedades liquidadas en un periodo para revisión o auditoría.
        * Filtrar por categoría para ver solo horas extras, deducciones o ingresos no salariales.
        * Exportar el historial completo de novedades del periodo en formato Excel.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Parámetro `async`:** Solo tiene efecto cuando se envía `file_format: xlsx`. Para la respuesta JSON se ignora.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: false
          name: file_format
          description: Cuando se envía con valor `xlsx`, retorna un archivo Excel con el historial completo en lugar del JSON paginado.
          schema:
            type: string
            example: xlsx
        - $ref: '#/components/parameters/noveltyFilterParam'
        - in: query
          required: false
          name: search
          description: Busca novedades por nombre de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `file_format`:

            - **Sin `file_format`** (por defecto): retorna el historial de novedades en JSON paginado con `data` y `filters`.
            - **`file_format: xlsx` síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga.
            - **`file_format: xlsx` asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta JSON paginada
                    required:
                      - data
                      - filters
                    properties:
                      data:
                        description: Listado de novedades del periodo con la información de cada registro.
                        type: array
                        items:
                          type: object
                          properties:
                            worker_id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            worker_name:
                              description: Nombre completo de la persona a quien corresponde la novedad.
                              type: string
                              example: Juan Pérez
                            id:
                              description: Identificador único (ID) asignado a la novedad en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            name:
                              description: Nombre del concepto de nómina o tipo de novedad.
                              type: string
                              example: Horas extras diurnas
                            initial_date:
                              description: Fecha inicial del periodo de aplicación de la novedad, en formato `YYYY-MM-DD`. Null si la novedad no tiene fecha inicial definida.
                              type:
                                - string
                                - 'null'
                              example: '2024-01-01'
                            end_date:
                              description: Fecha final del periodo de aplicación de la novedad, en formato `YYYY-MM-DD`. Null si la novedad no tiene fecha final definida.
                              type:
                                - string
                                - 'null'
                              example: '2024-01-15'
                            quantity:
                              description: Cantidad aplicada en la novedad (días, horas u otras unidades según el tipo de novedad).
                              type: number
                              example: 2
                            value:
                              description: Valor monetario de la novedad en pesos colombianos.
                              type: integer
                              example: 45000
                            date:
                              description: Fecha puntual asociada a la novedad, en formato `YYYY-MM-DD`. Aplica para novedades de fecha específica. Null si no aplica.
                              type:
                                - string
                                - 'null'
                              example: '2024-01-10'
                      filters:
                        description: Información de paginación y filtros aplicados a la respuesta.
                        type: object
                        properties:
                          total_records:
                            description: Número total de novedades que coinciden con los filtros aplicados.
                            type: integer
                            example: 6
                          filter:
                            description: Categoría de novedad activa en la consulta.
                            type: string
                            example: novelties
                          page:
                            description: Número de página actual de la respuesta.
                            type: integer
                            example: 1
                          per_page:
                            description: Número máximo de novedades retornadas por página.
                            type: integer
                            example: 20
                          search:
                            description: Texto de búsqueda aplicado. Cadena vacía si no se envió búsqueda.
                            type: string
                            example: Juan Pérez
                  - type: object
                    description: Respuesta síncrona con archivo Excel
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel con el historial de novedades del periodo.
                        type: string
                        example: https://storage.aleluya.com/novelties_history.xlsx
                  - type: object
                    description: Respuesta asíncrona con archivo Excel
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento del archivo.
                        type: string
                        example: Procesando
              examples:
                JSON:
                  value:
                    data:
                      - worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        worker_name: Juan Pérez
                        id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        name: Horas extras diurnas
                        initial_date: '2024-01-01'
                        end_date: '2024-01-15'
                        quantity: 2
                        value: 45000
                        date: null
                      - worker_id: 7f8e9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b
                        worker_name: María González
                        id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        name: Incapacidad
                        initial_date: '2024-01-05'
                        end_date: '2024-01-10'
                        quantity: 6
                        value: 120000
                        date: null
                    filters:
                      total_records: 6
                      filter: novelties
                      page: 1
                      per_page: 20
                      search: ''
                Archivo síncrono:
                  value:
                    file: https://storage.aleluya.com/novelties_history.xlsx
                Archivo asíncrono:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
  /v1/{company_id}/periods/{period_id}/options:
    get:
      operationId: showPeriodOptions
      tags:
        - Periodos de nómina
      summary: Obtener opciones del periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones disponibles para un periodo específico: generación de colillas
        en PDF, archivo ZIP, envío por correo, archivo de resumen, reporte de novedades,
        archivo contable, archivo bancario, archivo de retenciones, prestaciones sociales,
        periodos del decreto 376, nómina electrónica, contador de nóminas electrónicas,
        integración con seguridad social y actualización de salarios.

        **¿Cuándo usar este endpoint?**

        * Consultar qué acciones están disponibles para un periodo antes de procesarlo.
        * Verificar el estado de la nómina electrónica y la integración con seguridad social.
        * Obtener los periodos de prestaciones sociales disponibles para el mes del periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Opciones del periodo retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones disponibles para el periodo indicado.
                    type: object
                    properties:
                      accounting_file:
                        description: Indica si la generación del archivo contable está disponible para el periodo.
                        type: boolean
                        example: true
                      bank_file:
                        description: Indica si la generación del archivo bancario está disponible para el periodo.
                        type: boolean
                        example: true
                      decree376_periods:
                        description: Listado de periodos del decreto 376 disponibles para el periodo.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al periodo del decreto 376 en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            label:
                              description: Etiqueta del periodo en formato mes y año.
                              type: string
                              example: Enero 2024
                            social_security_file:
                              description: Indica si existe archivo de seguridad social generado para el periodo.
                              type: boolean
                              example: false
                      electronic_payroll:
                        description: Estado de la nómina electrónica para el periodo.
                        type: object
                        properties:
                          authorized:
                            description: Indica si la nómina electrónica está autorizada por la DIAN.
                            type: boolean
                            example: false
                          transmission_authorized:
                            description: Indica si la transmisión de nómina electrónica está autorizada.
                            type: boolean
                            example: false
                      electronic_payrolls_counter:
                        description: Contador de nóminas electrónicas del periodo agrupadas por estado.
                        type: object
                        properties:
                          total:
                            description: Total de nóminas electrónicas del periodo.
                            type: integer
                            example: 5
                          to_issue:
                            description: Nóminas electrónicas pendientes de emitir.
                            type: integer
                            example: 3
                          issued:
                            description: Nóminas electrónicas emitidas correctamente.
                            type: integer
                            example: 2
                          modified:
                            description: Nóminas electrónicas con modificaciones pendientes.
                            type: integer
                            example: 0
                          rejected:
                            description: Nóminas electrónicas rechazadas por la DIAN.
                            type: integer
                            example: 0
                          processing:
                            description: Nóminas electrónicas en proceso de transmisión.
                            type: integer
                            example: 0
                          pending:
                            description: Nóminas electrónicas pendientes de revisión.
                            type: integer
                            example: 0
                          canceled:
                            description: Nóminas electrónicas anuladas.
                            type: integer
                            example: 0
                      novelties_report:
                        description: Indica si la generación del reporte de novedades está disponible para el periodo.
                        type: boolean
                        example: true
                      payroll_summary_file:
                        description: Indica si la generación del archivo de resumen de nómina está disponible para el periodo.
                        type: boolean
                        example: true
                      payslips_emails:
                        description: Indica si el envío de colillas por correo está disponible para el periodo.
                        type: boolean
                        example: true
                      payslips_pdf:
                        description: Indica si la generación de colillas en PDF está disponible para el periodo.
                        type: boolean
                        example: true
                      payslips_zip:
                        description: Indica si la generación del archivo ZIP de colillas está disponible para el periodo.
                        type: boolean
                        example: true
                      retentions_summary_file:
                        description: Indica si la generación del archivo de retenciones está disponible para el periodo.
                        type: boolean
                        example: true
                      social_benefits:
                        description: Prestaciones sociales disponibles para liquidar en el periodo.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Nombre de la prestación social.
                              type: string
                              example: Prima de servicios
                            category:
                              description: Categoría de la prestación social.
                              type: string
                              enum:
                                - service_bonus
                                - severance_interests
                                - severance
                              example: service_bonus
                            social_benefits_period_id:
                              description: Identificador único (ID) asignado al periodo de la prestación social en la base de datos.
                              type: string
                              example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                            action:
                              description: Acción disponible para la prestación social en este periodo.
                              type: string
                              enum:
                                - create
                                - update
                              example: create
                            show_reminder:
                              description: Indica si se debe mostrar un recordatorio para liquidar esta prestación.
                              type: boolean
                              example: false
                      social_security_file:
                        description: Indica si la generación del archivo de seguridad social para empleados está disponible.
                        type: boolean
                        example: true
                      social_security_integration:
                        description: Estado y opciones de la integración con el operador de seguridad social.
                        type: object
                        properties:
                          active:
                            description: Indica si la integración con seguridad social está activa para la empresa.
                            type: boolean
                            example: false
                          forms_keys:
                            description: Claves de las planillas del proveedor de seguridad social por tipo de contrato.
                            type: object
                            properties:
                              employee:
                                description: Identificador de la planilla del proveedor para empleados.
                                type: string
                                example: EMP-12345
                              student:
                                description: Identificador de la planilla del proveedor para estudiantes.
                                type: string
                                example: EST-67890
                          providers_options:
                            description: Listado de proveedores de seguridad social disponibles para la empresa.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único del proveedor de seguridad social.
                                  type: string
                                  example: aportes_en_linea
                                provider:
                                  description: Nombre del proveedor de seguridad social.
                                  type: string
                                  enum:
                                    - aportes_en_linea
                                    - enlace
                                  example: aportes_en_linea
                      students_social_security_file:
                        description: Indica si la generación del archivo de seguridad social para estudiantes está disponible.
                        type: boolean
                        example: false
                      wages_update:
                        description: Indica si la actualización de salarios está disponible para el periodo.
                        type: boolean
                        example: false
              example:
                data:
                  accounting_file: true
                  bank_file: true
                  decree376_periods:
                    - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      label: Enero 2024
                      social_security_file: false
                  electronic_payroll:
                    authorized: false
                    transmission_authorized: false
                  electronic_payrolls_counter:
                    total: 5
                    to_issue: 3
                    issued: 2
                    modified: 0
                    rejected: 0
                    processing: 0
                    pending: 0
                    canceled: 0
                  novelties_report: true
                  payroll_summary_file: true
                  payslips_emails: true
                  payslips_pdf: true
                  payslips_zip: true
                  retentions_summary_file: true
                  social_benefits:
                    - label: Prima de servicios
                      category: service_bonus
                      social_benefits_period_id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      action: create
                      show_reminder: false
                  social_security_file: true
                  social_security_integration:
                    active: false
                    forms_keys:
                      employee: EMP-12345
                      student: EST-67890
                    providers_options:
                      - id: aportes_en_linea
                        provider: aportes_en_linea
                  students_social_security_file: false
                  wages_update: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Empresa o periodo no existe
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
  /v1/{company_id}/periods/{period_id}/payroll_summary:
    get:
      operationId: showPayrollSummary
      tags:
        - Resúmenes de nómina
      summary: Obtener archivo de resumen de nómina
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo de resumen de nómina de un periodo. Para periodos quincenales,
        permite generar el resumen de solo esa quincena o el consolidado mensual de ambas quincenas.

        **¿Cuándo usar este endpoint?**

        * Descargar el resumen de nómina de un periodo mensual o quincenal para revisión o archivo.
        * Obtener el archivo detallado con el desglose completo de conceptos de cada persona.
        * Generar el resumen mensual consolidado a partir de la segunda quincena de un periodo quincenal.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Parámetro `file_type`:** Solo aplica para la segunda quincena de un periodo quincenal. Valores posibles: `fortnightly` (genera el resumen de solo esa quincena) o `monthly` (genera el resumen mensual consolidado de ambas quincenas). Para periodos mensuales o primera quincena, se ignora.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: false
          name: file_type
          description: 'Tipo de archivo a generar para la segunda quincena de un periodo quincenal. Valores posibles: `fortnightly` (solo esa quincena), `monthly` (resumen mensual de ambas quincenas). Si no se envía en segunda quincena, genera el mensual por defecto.'
          schema:
            type: string
            enum:
              - fortnightly
              - monthly
            example: monthly
        - in: query
          required: false
          name: data_type
          description: Cuando se envía con valor `detailed`, genera el archivo con el desglose completo de conceptos por persona en lugar del resumen agrupado.
          schema:
            type: string
            enum:
              - detailed
            example: detailed
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga.
            - **Asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta síncrona
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo de resumen de nómina generado.
                        type: string
                        example: https://storage.aleluya.com/payroll_summary.xlsx
                  - type: object
                    description: Respuesta asíncrona
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de encolamiento del archivo.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/payroll_summary.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de archivo inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0606'
                    index: 0
                    message: El tipo de archivo es inválido.
                    object: file_type
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
  /v1/{company_id}/periods/{period_id}/payslip_options:
    get:
      operationId: showPeriodPayslipOptions
      tags:
        - Desprendibles de pago
      summary: Obtener opciones de colilla de un periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna los tipos de colilla disponibles para enviar masivamente a todas las personas de un periodo de nómina.

        **¿Cuándo usar este endpoint?**

        * Consultar los tipos de colilla disponibles antes de llamar al endpoint de envío masivo del periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Opciones de colilla retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Opciones disponibles para las colillas del periodo.
                    type: object
                    properties:
                      payslip_type:
                        description: Lista de tipos de colilla disponibles para este periodo.
                        type: array
                        items:
                          type: object
                          properties:
                            label:
                              description: Nombre legible del tipo de colilla.
                              type: string
                              example: Liquidación de prestaciones sociales
                            value:
                              description: Valor a enviar en el parámetro `payslip_type` al enviar las colillas.
                              type: string
                              example: social_benefit
                          required:
                            - label
                            - value
                    required:
                      - payslip_type
                required:
                  - data
              example:
                data:
                  payslip_type:
                    - label: Nómina
                      value: payroll
                    - label: Liquidación de prestaciones sociales
                      value: social_benefit
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: b8b5d397-19a0-5504-90ee-ee0355df88f0
  /v1/{company_id}/periods/{period_id}/analyses/overtime:
    get:
      operationId: indexOvertimeAnalysis
      tags:
        - Análisis de horas extras y recargos
      summary: Obtener análisis de horas extras y recargos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el análisis estadístico de horas extras y recargos del periodo indicado. Compara los
        valores actuales con periodos anteriores usando desviación estándar para detectar anomalías.
        Incluye un resumen global, detalle por tipo de hora extra y desagregación por área, sede y cargo.

        **¿Cuándo usar este endpoint?**

        * **Monitorear variaciones inusuales:** Detectar si las horas extras o recargos del periodo presentan
          un comportamiento estadísticamente anómalo respecto al histórico.
        * **Analizar distribución por dimensión:** Consultar qué áreas, sedes o cargos concentran más horas
          extras o recargos en el periodo.
        * **Revisar breakdown por tipo:** Conocer la distribución de horas extras por tipo (diurnas, nocturnas,
          festivas, etc.) y su peso porcentual sobre el total.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol
          administrador (admin), contador (accountant) o revisor (reviewer).
        * **Datos insuficientes:** Si no hay suficientes periodos históricos para calcular la estadística,
          el campo `insufficient_data` del resumen será `true` y los arreglos de dimensiones estarán vacíos.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
      responses:
        '200':
          description: Análisis con datos / Sin datos suficientes para análisis
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del análisis de horas extras y recargos.
                    type: object
                    properties:
                      summary:
                        description: Resumen estadístico global del periodo para horas extras y recargos.
                        type: object
                        properties:
                          has_anomaly:
                            description: Indica si el periodo presenta una anomalía estadística en horas extras o recargos.
                            type: boolean
                            example: false
                          insufficient_data:
                            description: Indica si no hay suficientes periodos históricos para calcular el análisis estadístico.
                            type: boolean
                            example: false
                          period_id:
                            description: Identificador único (ID) del periodo analizado en la base de datos.
                            type: string
                            example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                          period_name:
                            description: Nombre legible del periodo. Para periodos mensuales el formato es 'Enero 2024'. Para quincenales 'Enero 2024 - Quincena 1' o 'Enero 2024 - Quincena 2'.
                            type: string
                            example: Enero 2024
                          overtime:
                            description: Bloque de métricas estadísticas para horas extras del periodo.
                            type: object
                            properties:
                              current_hours:
                                description: Total de horas extras trabajadas en el periodo actual.
                                type: number
                                example: 45.5
                              current_value:
                                description: Valor total pagado por horas extras en el periodo actual en pesos colombianos.
                                type: number
                                example: 1250000
                              has_anomaly:
                                description: Indica si las horas extras presentan una anomalía estadística en este periodo.
                                type: boolean
                                example: false
                              mean:
                                description: Promedio histórico del valor de horas extras en periodos anteriores.
                                type: number
                                example: 980000
                              previous_period_hours:
                                description: Total de horas extras trabajadas en el periodo anterior.
                                type: number
                                example: 40
                              previous_period_value:
                                description: Valor total pagado por horas extras en el periodo anterior en pesos colombianos.
                                type: number
                                example: 1100000
                              severity:
                                description: 'Nivel de severidad de la anomalía. Valores posibles: normal, low, medium, high.'
                                type: string
                                example: normal
                              std_dev:
                                description: Desviación estándar histórica del valor de horas extras.
                                type: number
                                example: 150000
                              z_score:
                                description: Puntuación Z que indica cuántas desviaciones estándar se aleja el valor actual del promedio histórico.
                                type: number
                                example: 1.8
                              statistical_variation_percent:
                                description: Variación porcentual estadística respecto al promedio histórico.
                                type: number
                                example: 27.55
                              threshold:
                                description: Umbral calculado (media + desviación estándar) a partir del cual se considera anomalía.
                                oneOf:
                                  - type: 'null'
                                  - type: number
                                example: 1130000
                              variation_percent:
                                description: Variación porcentual del valor actual respecto al periodo anterior.
                                oneOf:
                                  - type: 'null'
                                  - type: number
                                example: 13.64
                          surcharge:
                            description: Bloque de métricas estadísticas para recargos del periodo. Contiene los mismos campos que el bloque `overtime`.
                            type: object
                      by_dimension:
                        description: Análisis desagregado por dimensión organizacional (área, sede, cargo).
                        type: object
                        properties:
                          area:
                            description: Análisis de horas extras y recargos agrupado por área.
                            type: object
                            properties:
                              overtime:
                                description: Listado de áreas con sus métricas de horas extras.
                                type: array
                                items:
                                  type: object
                                  properties:
                                    id:
                                      description: Identificador único (ID) del área en la base de datos. Puede ser null para personas sin área asignada.
                                      oneOf:
                                        - type: 'null'
                                        - type: string
                                      example: 3b9f2c1a-1234-5678-abcd-ef0123456789
                                    name:
                                      description: Nombre del área. Retorna un texto indicando "Sin área" si la persona no tiene área asignada.
                                      type: string
                                      example: Operaciones
                                    insufficient_data:
                                      description: Indica si no hay datos suficientes para calcular la variación estadística de esta dimensión.
                                      type: boolean
                                      example: false
                                    current_value:
                                      description: Valor total de horas extras del área en el periodo actual en pesos colombianos.
                                      type: number
                                      example: 450000
                                    has_anomaly:
                                      description: Indica si el área presenta una anomalía estadística en horas extras.
                                      type: boolean
                                      example: false
                                    mean:
                                      description: Promedio histórico del valor de horas extras del área.
                                      type: number
                                      example: 380000
                                    previous_period_value:
                                      description: Valor de horas extras del área en el periodo anterior en pesos colombianos.
                                      type: number
                                      example: 410000
                                    severity:
                                      description: 'Nivel de severidad de la anomalía del área. Valores posibles: normal, low, medium, high.'
                                      type: string
                                      example: normal
                                    statistical_variation_percent:
                                      description: Variación porcentual estadística del área respecto a su promedio histórico. Puede ser null si no hay datos suficientes.
                                      oneOf:
                                        - type: 'null'
                                        - type: number
                                      example: 18.42
                                    variation_percent:
                                      description: Variación porcentual del valor actual del área respecto al periodo anterior. Puede ser null si el periodo anterior no tiene valor.
                                      oneOf:
                                        - type: 'null'
                                        - type: number
                                      example: 9.76
                                    z_score:
                                      description: Puntuación Z del área respecto a su historial. Puede ser null si no hay datos suficientes.
                                      oneOf:
                                        - type: 'null'
                                        - type: number
                                      example: 0.93
                              surcharge:
                                description: Listado de áreas con sus métricas de recargos. Contiene los mismos campos que `overtime`.
                                type: array
                                items:
                                  type: object
                          location:
                            description: Análisis agrupado por sede. Misma estructura que `area`.
                            type: object
                          position:
                            description: Análisis agrupado por cargo. Misma estructura que `area`.
                            type: object
                      by_type:
                        description: Distribución de horas extras y recargos por tipo de concepto.
                        type: object
                        properties:
                          overtime:
                            description: Listado de tipos de horas extras con su valor, horas y porcentaje sobre el total.
                            type: array
                            items:
                              type: object
                              properties:
                                type:
                                  description: Código del tipo de hora extra según clasificación del sistema.
                                  type: string
                                  example: diurnal_overtime
                                value:
                                  description: Valor total pagado por este tipo de hora extra en el periodo en pesos colombianos.
                                  type: number
                                  example: 780000
                                hours:
                                  description: Total de horas de este tipo en el periodo.
                                  type: number
                                  example: 28.5
                                percent_of_total:
                                  description: Porcentaje que representa este tipo sobre el total de horas extras del periodo.
                                  type: number
                                  example: 62.4
                          surcharge:
                            description: Listado de tipos de recargos. Misma estructura que `overtime`.
                            type: array
                            items:
                              type: object
                      metadata:
                        description: Información sobre el método y condiciones del análisis estadístico.
                        type: object
                        properties:
                          analysis_method:
                            description: Método estadístico utilizado para el análisis de anomalías.
                            type: string
                            example: standard_deviation
                          baseline_periods_count:
                            description: Número de periodos históricos utilizados como línea base para el cálculo estadístico.
                            type: integer
                            example: 6
                          calculated_at:
                            description: Fecha y hora en que se realizó el cálculo del análisis, en formato ISO 8601. Puede ser null si aún no se ha calculado.
                            oneOf:
                              - type: 'null'
                              - type: string
                            example: '2024-01-31T18:00:00.000Z'
                      dimensions_counter:
                        description: Conteo de dimensiones con datos de horas extras en el periodo.
                        type: object
                        properties:
                          all:
                            description: Número total de dimensiones con datos.
                            type: integer
                            example: 12
                          area:
                            description: Número de áreas con datos de horas extras.
                            type: integer
                            example: 4
                          location:
                            description: Número de sedes con datos de horas extras.
                            type: integer
                            example: 3
                          position:
                            description: Número de cargos con datos de horas extras.
                            type: integer
                            example: 5
                  filters:
                    description: Información de paginación aplicada al listado de dimensiones.
                    type: object
                    properties:
                      total_records:
                        description: Número total de registros encontrados.
                        type: integer
                        example: 12
                      page:
                        description: Página actual del listado.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de registros por página.
                        type: integer
                        example: 20
              examples:
                Análisis con datos:
                  value:
                    data:
                      summary:
                        has_anomaly: false
                        insufficient_data: false
                        period_id: a1b2c3d4-5678-9abc-def0-123456789abc
                        period_name: Enero 2026
                        overtime:
                          current_hours: 45.5
                          current_value: 1250000
                          has_anomaly: false
                          mean: 980000
                          previous_period_hours: 40
                          previous_period_value: 1100000
                          severity: normal
                          std_dev: 75000
                          z_score: 1.8
                          statistical_variation_percent: 27.55
                          threshold: 1130000
                          variation_percent: 13.64
                        surcharge:
                          current_hours: 12
                          current_value: 350000
                          has_anomaly: false
                          mean: 320000
                          previous_period_hours: 10
                          previous_period_value: 310000
                          severity: normal
                          std_dev: 25000
                          z_score: 0.9
                          statistical_variation_percent: 9.38
                          threshold: 370000
                          variation_percent: 12.9
                      by_dimension:
                        area:
                          overtime:
                            - id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                              name: Operaciones
                              insufficient_data: false
                              current_value: 1250000
                              has_anomaly: false
                              mean: 980000
                              previous_period_value: 1100000
                              severity: normal
                              statistical_variation_percent: 27.55
                              variation_percent: 13.64
                              z_score: 1.8
                          surcharge: []
                        location:
                          overtime: []
                          surcharge: []
                        position:
                          overtime: []
                          surcharge: []
                      by_type:
                        overtime: []
                        surcharge: []
                      metadata:
                        analysis_method: standard_deviation
                        baseline_periods_count: 6
                        calculated_at: '2026-01-31T10:00:00Z'
                      dimensions_counter:
                        all: 1
                        area: 1
                        location: 0
                        position: 0
                    filters:
                      total_records: 1
                      page: 1
                      per_page: 20
                Sin datos suficientes para análisis:
                  value:
                    data:
                      summary:
                        has_anomaly: false
                        insufficient_data: true
                        period_id: a1b2c3d4-5678-9abc-def0-123456789abc
                        period_name: Enero 2026
                      by_dimension:
                        area:
                          overtime: []
                          surcharge: []
                        location:
                          overtime: []
                          surcharge: []
                        position:
                          overtime: []
                          surcharge: []
                      by_type:
                        overtime: []
                        surcharge: []
                      metadata:
                        analysis_method: standard_deviation
                        baseline_periods_count: 0
                        calculated_at: null
                      dimensions_counter:
                        all: 0
                        area: 0
                        location: 0
                        position: 0
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo en la base de datos.
        schema:
          type: string
          example: 7d4e9b2a-3f1c-4a5d-8e6f-0b2c4d6e8f0a
  /v1/{company_id}/periods/{period_id}/payslip_mails:
    post:
      operationId: createPeriodPayslipMails
      tags:
        - Desprendibles de pago
      summary: Enviar colillas del periodo
      description: |
        **¿Qué hace este endpoint?**

        Envía las colillas de pago de todas las nóminas del periodo a las personas por correo
        electrónico o WhatsApp. Permite filtrar el tipo de colilla a enviar: nómina, liquidación,
        prima de servicios, intereses de las cesantías o combinaciones de estos.

        **¿Cuándo usar este endpoint?**

        * Notificar masivamente a todas las personas una vez liquidado el periodo de nómina.
        * Enviar colillas de prestaciones sociales cuando el periodo incluye prima, cesantías o intereses de cesantías.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Canal WhatsApp:** Si `whatsapp_notification: true`, el envío se encola en segundo plano. El canal de WhatsApp debe estar configurado previamente.
        * **Filtrado automático:** Solo se envían las colillas que corresponden al tipo indicado en `payslip_type`. Las nóminas sin datos del tipo solicitado se omiten automáticamente.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                payslip_type:
                  description: Tipo de colilla a enviar. Si se omite, se envía la colilla de nómina estándar.
                  $ref: '#/components/schemas/PayslipType'
                payroll_range:
                  $ref: '#/components/schemas/PayrollRange'
                whatsapp_notification:
                  description: Si es `true`, envía las colillas por WhatsApp en lugar de correo electrónico.
                  type: boolean
                  example: false
      responses:
        '200':
          description: Colillas enviadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del envío masivo.
                        type: string
                        example: Las colillas fueron enviadas.
                required:
                  - data
              example:
                data:
                  message: Las colillas fueron enviadas.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de colilla inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0101'
                    index: 0
                    message: Tipo de colilla es inválido.
                    object: payslip_type
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 7d4e9b2a-3f1c-4a5d-8e6f-0b2c4d6e8f0a
  /v1/{company_id}/periods/{period_id}/payslips:
    get:
      operationId: indexPeriodPayslips
      tags:
        - Desprendibles de pago
      summary: Generar colillas del periodo
      description: |
        **¿Qué hace este endpoint?**

        Genera un archivo con las colillas de pago de todas las nóminas del periodo. El archivo puede
        ser un PDF individual por persona o un ZIP con todos los PDFs agrupados.

        **¿Cuándo usar este endpoint?**

        * Descargar las colillas de todas las personas de un periodo de nómina en un solo archivo.
        * Generar el archivo en segundo plano cuando el tiempo de respuesta es crítico.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Modo asíncrono:** Cuando `async: true`, el endpoint retorna inmediatamente con `message: Procesando`. El resultado se publica en Firebase en `users/{user_id}/periods/{period_id}/payslips`.
        * **Formato ZIP:** Cuando `file_format: zip`, el archivo descargable contiene un PDF por cada persona del periodo.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: false
          name: file_format
          description: Formato del archivo generado. Si es `zip`, retorna un archivo comprimido con un PDF por persona. Si no se envía, retorna un único PDF con todas las colillas.
          schema:
            type: string
            enum:
              - pdf
              - zip
            example: zip
        - in: query
          required: false
          name: payslip_type
          schema:
            $ref: '#/components/schemas/PayslipType'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL del archivo generado.
            - **Asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase en `users/{user_id}/periods/{period_id}/payslips`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Colillas del periodo síncronas
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo generado (PDF o ZIP).
                        type: string
                        example: https://storage.aleluya.com/colillas-periodo.zip
                  - type: object
                    description: Colillas del periodo asíncronas
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de encolamiento.
                            type: string
                            example: Procesando
              examples:
                Colillas del periodo síncronas:
                  value:
                    file: https://storage.aleluya.com/colillas-periodo.zip
                Colillas del periodo asíncronas:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de colilla inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0101'
                    index: 0
                    message: Tipo de colilla es inválido.
                    object: payslip_type
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/period_payrolls_summary:
    get:
      operationId: showPeriodPayrollsSummary
      tags:
        - Resúmenes de nómina
      summary: Obtener resumen de nóminas del periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el resumen de nóminas del periodo agrupado por persona, con los totales de ingresos,
        deducciones, seguridad social, parafiscales y prestaciones. Incluye el desglose detallado
        por concepto para cada nómina.

        **¿Cuándo usar este endpoint?**

        * Consultar los totales de nómina de cada persona en un periodo para mostrarlos en una tabla resumen.
        * Filtrar las nóminas del periodo por categoría de contrato, estado o sede antes de exportar.
        * Buscar una persona específica dentro del resumen de nóminas del periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: search
          description: Busca nóminas por nombre de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
        - in: query
          required: false
          name: contract_category
          description: Filtra las nóminas por categoría del contrato de la persona.
          schema:
            $ref: '#/components/schemas/ContractCategory'
        - in: query
          required: false
          name: contract_status
          description: 'Filtra las nóminas por estado del contrato. Valores posibles: `active` (contratos sin terminación), `terminated` (contratos con terminación registrada).'
          schema:
            type: string
            enum:
              - active
              - terminated
            example: active
        - in: query
          required: false
          name: location
          description: Filtra las nóminas por sede. Se envía el identificador único (ID) de la sede en la base de datos.
          schema:
            type: string
            example: 64967d4b-7d9b-5188-a014-0a18767ca4c9
      responses:
        '200':
          description: Resumen de nóminas del periodo retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de nóminas del periodo con sus totales por categoría y desglose de conceptos.
                    type: array
                    items:
                      type: object
                      properties:
                        payroll_id:
                          description: Identificador único (ID) asignado a la nómina en la base de datos.
                          type: string
                          example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        worker_id:
                          description: Identificador único (ID) asignado a la persona en la base de datos.
                          type: string
                          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        worker_name:
                          description: Nombre completo de la persona.
                          type: string
                          example: Juan Pérez
                        contract_category:
                          $ref: '#/components/schemas/ContractCategory'
                        worked_time:
                          description: Tiempo trabajado en el periodo (días u horas según el tipo de contrato).
                          type: object
                          properties:
                            label:
                              description: Etiqueta del tiempo trabajado (ej. "Días trabajados" u "Horas trabajadas").
                              type: string
                              example: Días trabajados
                            value:
                              description: Cantidad de días u horas trabajados en el periodo.
                              type: integer
                              example: 15
                        worker_payment:
                          description: Total neto a pagar a la persona en el periodo.
                          type: object
                          properties:
                            label:
                              description: Etiqueta del pago neto de la persona.
                              type: string
                              example: Pago neto
                            value:
                              description: Valor total neto a pagar a la persona en pesos colombianos.
                              type: integer
                              example: 1450000
                        company_cost:
                          description: Costo total para la empresa incluyendo aportes de seguridad social y parafiscales del periodo.
                          type: object
                          properties:
                            label:
                              description: Etiqueta del costo empresa.
                              type: string
                              example: Costo empresa
                            value:
                              description: Valor total del costo empresa en pesos colombianos.
                              type: integer
                              example: 1900000
                        income:
                          description: Total de ingresos de la nómina (resumen del primer nivel).
                          type: object
                          properties:
                            label:
                              description: Etiqueta de la categoría de ingresos.
                              type: string
                              example: Ingresos
                            value:
                              description: Valor total de ingresos en pesos colombianos.
                              type: integer
                              example: 1600000
                        deductions:
                          description: Total de retenciones y deducciones de la nómina (resumen del primer nivel).
                          type: object
                          properties:
                            label:
                              description: Etiqueta de la categoría de deducciones.
                              type: string
                              example: Retenciones y deducciones
                            value:
                              description: Valor total de deducciones en pesos colombianos.
                              type: integer
                              example: 50000
                        social_security:
                          description: Total del aporte de seguridad social a cargo de la empresa en el periodo.
                          type: object
                          properties:
                            label:
                              description: Etiqueta de la categoría de seguridad social.
                              type: string
                              example: SS empresa
                            value:
                              description: Valor total de seguridad social en pesos colombianos.
                              type: integer
                              example: 265000
                        parafiscals:
                          description: Total de parafiscales a cargo de la empresa en el periodo.
                          type: object
                          properties:
                            label:
                              description: Etiqueta de la categoría de parafiscales.
                              type: string
                              example: Parafiscales
                            value:
                              description: Valor total de parafiscales en pesos colombianos.
                              type: integer
                              example: 72000
                        social_benefits:
                          description: Total de provisión de prestaciones sociales del periodo.
                          type: object
                          properties:
                            label:
                              description: Etiqueta de la categoría de prestaciones sociales.
                              type: string
                              example: Provisión prestaciones sociales
                            value:
                              description: Valor total de la provisión de prestaciones en pesos colombianos.
                              type: integer
                              example: 113000
                        subRows:
                          description: Desglose detallado por concepto de cada categoría. Cada fila representa un concepto; los campos de categorías no aplicables retornan `null`.
                          type: array
                          items:
                            type: object
                            properties:
                              income:
                                description: Concepto de ingreso de esta fila de detalle. Puede ser null si la fila no corresponde a un ingreso.
                                type: object
                                properties:
                                  label:
                                    description: Nombre del concepto de ingreso.
                                    type:
                                      - string
                                      - 'null'
                                    example: Salario
                                  value:
                                    description: Valor del concepto de ingreso en pesos colombianos.
                                    type:
                                      - integer
                                      - 'null'
                                    example: 1500000
                              deductions:
                                description: Concepto de deducción de esta fila de detalle. Puede ser null si la fila no corresponde a una deducción.
                                type: object
                                properties:
                                  label:
                                    description: Nombre del concepto de deducción.
                                    type:
                                      - string
                                      - 'null'
                                    example: Otras deducciones
                                  value:
                                    description: Valor del concepto de deducción en pesos colombianos.
                                    type:
                                      - integer
                                      - 'null'
                                    example: 50000
                              social_security:
                                description: Concepto de seguridad social de esta fila de detalle. Puede ser null si la fila no corresponde a seguridad social.
                                type: object
                                properties:
                                  label:
                                    description: Nombre del concepto de seguridad social.
                                    type:
                                      - string
                                      - 'null'
                                    example: Salud empleador
                                  value:
                                    description: Valor del concepto de seguridad social en pesos colombianos.
                                    type:
                                      - integer
                                      - 'null'
                                    example: 64000
                              parafiscals:
                                description: Concepto de parafiscal de esta fila de detalle. Puede ser null si la fila no corresponde a un parafiscal.
                                type: object
                                properties:
                                  label:
                                    description: Nombre del concepto de parafiscal.
                                    type:
                                      - string
                                      - 'null'
                                    example: SENA
                                  value:
                                    description: Valor del concepto de parafiscal en pesos colombianos.
                                    type:
                                      - integer
                                      - 'null'
                                    example: 30000
                              social_benefits:
                                description: Concepto de prestación social de esta fila de detalle. Puede ser null si la fila no corresponde a una prestación.
                                type: object
                                properties:
                                  label:
                                    description: Nombre del concepto de prestación social.
                                    type:
                                      - string
                                      - 'null'
                                    example: Cesantías
                                  value:
                                    description: Valor del concepto de prestación social en pesos colombianos.
                                    type:
                                      - integer
                                      - 'null'
                                    example: 83000
                  filters:
                    description: Información de paginación y filtros aplicados a la respuesta.
                    type: object
                    properties:
                      total_records:
                        description: Número total de nóminas que coinciden con los filtros aplicados.
                        type: integer
                        example: 3
                      page:
                        description: Número de página actual de la respuesta.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de nóminas retornadas por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado. Null si no se envió búsqueda.
                        type:
                          - string
                          - 'null'
                        example: Juan Pérez
                      location:
                        description: Identificador de la sede por la que se filtró, o `All` si no se aplicó filtro de sede.
                        type: string
                        example: All
              example:
                data:
                  - payroll_id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                    worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                    worker_name: Juan Pérez
                    contract_category: employee
                    worked_time:
                      label: Días trabajados
                      value: 15
                    worker_payment:
                      label: Pago neto
                      value: 1450000
                    company_cost:
                      label: Costo empresa
                      value: 1900000
                    income:
                      label: Ingresos
                      value: 1600000
                    deductions:
                      label: Retenciones y deducciones
                      value: 50000
                    social_security:
                      label: SS empresa
                      value: 265000
                    parafiscals:
                      label: Parafiscales
                      value: 72000
                    social_benefits:
                      label: Provisión prestaciones sociales
                      value: 113000
                    subRows:
                      - income:
                          label: Salario
                          value: 1500000
                        deductions:
                          label: Otras deducciones
                          value: 50000
                        social_security:
                          label: null
                          value: null
                        parafiscals:
                          label: null
                          value: null
                        social_benefits:
                          label: null
                          value: null
                      - income:
                          label: Vac. Incap. y Licen.
                          value: 100000
                        deductions:
                          label: null
                          value: null
                        social_security:
                          label: null
                          value: null
                        parafiscals:
                          label: null
                          value: null
                        social_benefits:
                          label: null
                          value: null
                filters:
                  total_records: 3
                  page: 1
                  per_page: 20
                  search: null
                  location: All
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
  /v1/{company_id}/periods/{period_id}/severance_payment_file:
    get:
      operationId: showSeverancePaymentFile
      tags:
        - Archivos de prestaciones
      summary: Obtener archivo de pago de cesantías
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo Excel con el detalle de pago de cesantías para un
        periodo de nómina y un periodo de prestaciones de tipo cesantía. Puede ejecutarse
        de forma síncrona o asíncrona.

        **¿Cuándo usar este endpoint?**

        * Descargar el archivo de cesantías para entregarlo al fondo o para archivo contable.
        * Generar el archivo en segundo plano cuando se prefiere respuesta no bloqueante.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Solo cesantías:** El `social_benefit_period_id` debe corresponder a un periodo
          de categoría `severance`. Otros tipos de prestación retornan error 422.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/severance_payment_files` para recibir la URL del archivo cuando esté listo.
      parameters:
        - in: query
          name: social_benefit_period_id
          required: true
          description: Identificador único (ID) del periodo de prestaciones sociales de tipo cesantía para el cual se genera el archivo.
          schema:
            type: string
            example: 6b47eb70-fc2f-55b0-93ac-6332450c39c1
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo generado.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/severance_payment_files`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel de pago de cesantías generado.
                        type: string
                        example: https://storage.aleluya.com/documents/cesantias-2024.xlsx
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que la generación del archivo fue encolada.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/documents/cesantias-2024.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo de prestaciones no es de tipo cesantía
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0613'
                    index: 0
                    message: El archivo solo se puede generar si tienes pago de cesantías en el periodo.
                    object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: d12accd0-86e5-4c95-b198-12bac9da7e21
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 1dd2eb3f-d0e4-5e09-97b2-92f4226f1b4d
  /v1/{company_id}/periods/{period_id}/social_benefit_periods/{id}:
    get:
      operationId: showSocialBenefitPeriod
      tags:
        - Periodos de prestaciones
      summary: Obtener periodo de prestaciones
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información de un periodo de prestaciones sociales (prima de servicios,
        cesantías o intereses de cesantías) en el contexto de un periodo de nómina específico,
        incluyendo la acción disponible para liquidar las prestaciones de ese periodo.

        **¿Cuándo usar este endpoint?**

        * Consultar los datos de un periodo de prestaciones antes de liquidar o actualizar
          las prestaciones sociales de las personas.
        * Verificar si el periodo ya tiene prestaciones liquidadas (`action: update`) o si
          aún no se han liquidado (`action: create`).
        * Obtener las fechas del periodo de prestaciones y su fecha límite de pago.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Rango del periodo:** El periodo de nómina debe estar dentro del rango de fechas
          del periodo de prestaciones. Si no lo está, se retorna un error 422.
      responses:
        '200':
          description: Información del periodo de prestaciones obtenida exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información del periodo de prestaciones sociales.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al periodo de prestaciones en la base de datos.
                        type: string
                        example: 9b8bb4a5-e03f-5381-86f5-da2a659c95f5
                      action:
                        description: Acción disponible para las prestaciones de este periodo. `create` indica que aún no se han liquidado; `update` indica que ya existen prestaciones liquidadas.
                        type: string
                        enum:
                          - create
                          - update
                        example: update
                      category:
                        description: 'Categoría del periodo de prestaciones. Valores posibles: `service_bonus` (prima de servicios), `severance_interests` (intereses de cesantías), `severance` (cesantías).'
                        type: string
                        enum:
                          - service_bonus
                          - severance_interests
                          - severance
                        example: service_bonus
                      end_day:
                        description: Fecha de fin del periodo de prestaciones sociales.
                        type: string
                        format: date
                        example: '2024-06-30'
                      initial_day:
                        description: Fecha de inicio del periodo de prestaciones sociales.
                        type: string
                        format: date
                        example: '2024-01-01'
                      label:
                        description: Nombre legible del periodo de prestaciones (ej. "Prima de Servicios 2024-1").
                        type: string
                        example: Prima de Servicios 2024-1
                      payment_limit_day:
                        description: Fecha límite legal para el pago de las prestaciones de este periodo.
                        type: string
                        format: date
                        example: '2024-06-30'
                      period_end_day:
                        description: Fecha de fin del periodo de nómina al que pertenece la consulta.
                        type: string
                        format: date
                        example: '2024-01-31'
                      period_initial_day:
                        description: Fecha de inicio del periodo de nómina al que pertenece la consulta.
                        type: string
                        format: date
                        example: '2024-01-01'
              example:
                data:
                  id: 9b8bb4a5-e03f-5381-86f5-da2a659c95f5
                  action: update
                  category: service_bonus
                  end_day: '2024-06-30'
                  initial_day: '2024-01-01'
                  label: Prima de Servicios 2024-1
                  payment_limit_day: '2024-06-30'
                  period_end_day: '2024-01-31'
                  period_initial_day: '2024-01-01'
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo fuera del rango del periodo de prestaciones
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '1505'
                    index: 0
                    message: El periodo está fuera del rango del periodo de prestaciones sociales.
                    object: Period
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 25512677-5c6c-4724-a60f-0c377568c520
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 4406267a-f699-5a56-b2c1-218f4d275dd9
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al periodo de prestaciones sociales en la base de datos.
        schema:
          type: string
          example: 9b8bb4a5-e03f-5381-86f5-da2a659c95f5
  /v1/{company_id}/periods/{period_id}/social_benefit_periods/{social_benefit_period_id}/social_benefits:
    get:
      operationId: indexSocialBenefits
      tags:
        - Prestaciones por periodo
      summary: Listar prestaciones por periodo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de prestaciones sociales de las personas en el contexto
        de un periodo de nómina y un periodo de prestaciones específico. Incluye tanto
        las prestaciones ya liquidadas como las pendientes de liquidar.

        **¿Cuándo usar este endpoint?**

        * Obtener las prestaciones sociales a liquidar o ya liquidadas para un periodo
          de nómina, antes de procesar el pago masivo o individual.
        * Verificar el estado de pago de cada persona (valor liquidado, pagado, saldo pendiente).
        * Buscar las prestaciones de una persona específica por nombre para revisión individual.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Rango del periodo:** El periodo de nómina debe estar dentro del rango del
          periodo de prestaciones. Si no lo está, se retorna un error 422.
        * **Prestaciones pendientes:** Las personas que aún no tienen una prestación liquidada
          aparecen en la lista con `id: null` y `value` calculado según sus datos de contrato.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca prestaciones por nombre completo de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
      responses:
        '200':
          description: Listado de prestaciones obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Lista de prestaciones sociales del periodo. Puede incluir prestaciones pendientes de liquidar.
                    type: array
                    items:
                      description: Datos de la prestación social de una persona en el periodo.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la prestación social en la base de datos. Es null cuando la prestación aún no ha sido liquidada en este periodo.
                          type:
                            - string
                            - 'null'
                          example: 225898da-0f78-5ed4-b0bf-b2da389adaad
                        balance:
                          description: Saldo pendiente de pago de la prestación social, en pesos colombianos.
                          type: number
                          example: 1500000
                        base_value:
                          description: Valor base del salario usado para calcular la prestación, en pesos colombianos.
                          type: number
                          example: 3000000
                        contract_id:
                          description: Identificador único (ID) asignado al contrato en la base de datos.
                          type: string
                          example: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                        days:
                          description: Número de días trabajados usados para el cálculo de la prestación.
                          type: integer
                          example: 180
                        item_value:
                          description: Valor del pago realizado en este periodo de nómina, en pesos colombianos.
                          type: integer
                          example: 750000
                        paid_value:
                          description: Valor total ya pagado de la prestación social hasta el momento, en pesos colombianos.
                          type: integer
                          example: 750000
                        payroll_id:
                          description: Identificador único (ID) asignado a la nómina en la base de datos.
                          type: string
                          example: 95054e94-5320-5b30-bcf3-59c224171028
                        worker_id:
                          description: Identificador único (ID) asignado a la persona en la base de datos.
                          type: string
                          example: afdd5821-d148-5fd7-8a7b-95c76bffa250
                        worker_name:
                          description: Nombre completo de la persona con su estado de liquidación entre paréntesis.
                          type: string
                          example: Juan Pérez (Liquidado)
                        id_number:
                          description: Número de documento de identificación de la persona.
                          type: string
                          example: '1234567890'
                        value:
                          description: Valor total calculado de la prestación social para el periodo, en pesos colombianos.
                          type: integer
                          example: 1500000
                        service_bonus_retention:
                          description: Valor de la retención sobre la prima de servicios, en pesos colombianos. Solo presente para prestaciones de categoría `service_bonus` cuando aplica retención.
                          type: integer
                          example: 45000
                  filters:
                    description: Información de paginación y totales del listado.
                    type: object
                    properties:
                      page:
                        description: Número de página actual de los resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de registros por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado al listado. Solo presente si se envió el parámetro `search`.
                        type: string
                        example: Juan Pérez
                      total_records:
                        description: Número total de prestaciones en el periodo (sin paginación).
                        type: integer
                        example: 15
              examples:
                Con prestaciones:
                  value:
                    data:
                      - id: 225898da-0f78-5ed4-b0bf-b2da389adaad
                        balance: 750000
                        base_value: 3000000
                        contract_id: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                        days: 180
                        item_value: 750000
                        paid_value: 750000
                        payroll_id: 95054e94-5320-5b30-bcf3-59c224171028
                        worker_id: afdd5821-d148-5fd7-8a7b-95c76bffa250
                        worker_name: Juan Pérez (Liquidado)
                        id_number: '1234567890'
                        value: 1500000
                      - id: null
                        balance: 0
                        base_value: 2500000
                        contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                        days: 180
                        item_value: 0
                        paid_value: 0
                        payroll_id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                        worker_name: María González (Liquidado)
                        id_number: '9876543210'
                        value: 1250000
                    filters:
                      page: 1
                      per_page: 20
                      total_records: 2
                Sin prestaciones:
                  value:
                    data: []
                    filters:
                      page: 1
                      per_page: 20
                      total_records: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo fuera del rango del periodo de prestaciones
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '1505'
                    index: 0
                    message: El periodo está fuera del rango del periodo de prestaciones sociales.
                    object: Period
    post:
      operationId: createSocialBenefit
      tags:
        - Prestaciones por periodo
      summary: Crear prestación social
      description: |
        **¿Qué hace este endpoint?**

        Liquida la prestación social de una persona en el periodo actual. Puede ejecutarse
        de forma individual para un contrato específico, o de forma masiva para todos los
        contratos del periodo.

        **¿Cuándo usar este endpoint?**

        * Liquidar la prima de servicios, cesantías o intereses de cesantías de una persona
          concreta antes del vencimiento del periodo.
        * Procesar el pago masivo de prestaciones para todos los contratos del periodo
          en un solo llamado.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Proceso en curso:** Si ya hay un proceso de liquidación masiva ejecutándose,
          la solicitud es rechazada con error 422 hasta que el proceso anterior termine.
        * **Liquidación masiva:** Al enviar `bulk_create: true`, la operación se encola.
          Escucha la ruta de Firebase `companies/{company_id}/periods/{period_id}/social_benefit_periods/{social_benefit_period_id}/social_benefits/action_bulk_create`
          para recibir el resultado.
      requestBody:
        required: true
        description: Crear individual / Crear masivo
        content:
          application/json:
            schema:
              type: object
              properties:
                contract_id:
                  description: Identificador único (ID) del contrato de la persona a liquidar. Requerido para la creación individual.
                  type: string
                  example: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                base_value:
                  description: Valor base del salario para calcular la prestación, en pesos colombianos.
                  type: integer
                  example: 3000000
                days:
                  description: Número de días trabajados a considerar en el cálculo.
                  type: integer
                  example: 180
                item_value:
                  description: Valor a pagar en este periodo de nómina, en pesos colombianos.
                  type: integer
                  example: 1500000
                service_bonus_retention:
                  description: Indica si se aplica retención sobre la prima de servicios. Solo aplica para periodos de categoría `service_bonus`.
                  type: boolean
                  example: false
                bulk_create:
                  description: Si es `true`, liquida las prestaciones de todos los contratos del periodo de forma masiva. En este caso, los demás campos son ignorados.
                  type: boolean
                  example: false
            examples:
              Crear individual:
                value:
                  contract_id: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                  base_value: 3000000
                  days: 180
                  item_value: 1500000
              Crear masivo:
                value:
                  bulk_create: true
      responses:
        '200':
          description: Prestación creada / Liquidación masiva encolada
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        description: Datos de la prestación social recién liquidada.
                        type: object
                        required:
                          - id
                          - balance
                          - base_value
                          - contract_id
                          - days
                          - item_value
                          - paid_value
                          - payroll_id
                          - worker_id
                          - worker_name
                          - id_number
                          - value
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la prestación social en la base de datos.
                            type: string
                            example: 037cb3c2-6039-4001-96e4-67b50d580d66
                          balance:
                            description: Saldo pendiente de pago de la prestación, en pesos colombianos.
                            type: number
                            example: 1500000
                          base_value:
                            description: Valor base del salario usado en el cálculo, en pesos colombianos.
                            type: number
                            example: 3000000
                          contract_id:
                            description: Identificador único (ID) asignado al contrato en la base de datos.
                            type: string
                            example: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                          days:
                            description: Número de días usados en el cálculo.
                            type: integer
                            example: 180
                          item_value:
                            description: Valor pagado en este periodo de nómina, en pesos colombianos.
                            type: integer
                            example: 1500000
                          paid_value:
                            description: Valor total pagado de la prestación hasta el momento, en pesos colombianos.
                            type: integer
                            example: 1500000
                          payroll_id:
                            description: Identificador único (ID) asignado a la nómina en la base de datos.
                            type: string
                            example: 95054e94-5320-5b30-bcf3-59c224171028
                          worker_id:
                            description: Identificador único (ID) asignado a la persona en la base de datos.
                            type: string
                            example: afdd5821-d148-5fd7-8a7b-95c76bffa250
                          worker_name:
                            description: Nombre completo de la persona con su estado de liquidación.
                            type: string
                            example: Juan Pérez (Liquidado)
                          id_number:
                            description: Número de documento de identificación de la persona.
                            type: string
                            example: '1234567890'
                          value:
                            description: Valor total calculado de la prestación, en pesos colombianos.
                            type: integer
                            example: 1500000
                  - type: object
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de que la liquidación masiva fue encolada para procesamiento.
                        type: string
                        example: Procesando
              examples:
                Crear individual:
                  value:
                    data:
                      id: 037cb3c2-6039-4001-96e4-67b50d580d66
                      balance: 1500000
                      base_value: 3000000
                      contract_id: 4100d633-6ed3-5f9f-9c38-68fdaf8e4101
                      days: 180
                      item_value: 1500000
                      paid_value: 1500000
                      payroll_id: 95054e94-5320-5b30-bcf3-59c224171028
                      worker_id: afdd5821-d148-5fd7-8a7b-95c76bffa250
                      worker_name: Juan Pérez (Liquidado)
                      id_number: '1234567890'
                      value: 1500000
                Crear masivo:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Proceso en curso / Valor base inválido / Valor a pagar cero / Prestación ya pagada / Contrato liquidado / Prestación completamente pagada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Proceso en curso:
                  value:
                    error:
                      - code: '4214'
                        index: 0
                        message: Ya tienes un proceso ejecutándose, debes esperar a que termine.
                        object: social_benefit
                Valor base inválido:
                  value:
                    error:
                      - code: '4215'
                        index: 0
                        message: No es posible crear una prestación social para Juan Pérez con un valor base tan bajo.
                        object: social_benefit
                Valor a pagar cero:
                  value:
                    error:
                      - code: '4213'
                        index: 0
                        message: No se puede crear la prestación social para Juan Pérez porque el valor a pagar es cero.
                        object: social_benefit
                Prestación ya pagada en el periodo:
                  value:
                    error:
                      - code: '4201'
                        index: 0
                        message: Ya pagaste la prestación de Juan Pérez en este periodo
                        object: social_benefit
                Contrato liquidado:
                  value:
                    error:
                      - code: '4205'
                        index: 0
                        message: No se puede crear la prestación de Juan Pérez porque ya se encuentra liquidado el contrato actual
                        object: social_benefit
                Prestación completamente pagada:
                  value:
                    error:
                      - code: '4206'
                        index: 0
                        message: No se puede crear la prestación de Juan Pérez porque ya se encuentra pagada en su totalidad
                        object: social_benefit
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 2f836bd7-51a0-4bb3-9d4f-ddd4b36bde9b
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
      - in: path
        required: true
        name: social_benefit_period_id
        description: Identificador único (ID) asignado al periodo de prestaciones sociales en la base de datos.
        schema:
          type: string
          example: 9b8bb4a5-e03f-5381-86f5-da2a659c95f5
  /v1/{company_id}/periods/{period_id}/social_benefit_periods/{social_benefit_period_id}/social_benefits/{id}:
    patch:
      operationId: updateSocialBenefit
      tags:
        - Prestaciones por periodo
      summary: Actualizar prestación social
      description: |
        **¿Qué hace este endpoint?**

        Actualiza una prestación social ya liquidada en el periodo. Puede ejecutarse
        de forma individual para modificar los valores de una prestación, recalcular
        automáticamente el saldo, o de forma masiva para todos los contratos del periodo.

        **¿Cuándo usar este endpoint?**

        * Corregir el valor base o los días de una prestación ya liquidada.
        * Registrar un pago parcial adicional sobre una prestación existente.
        * Recalcular automáticamente las prestaciones de un contrato según sus datos actuales.
        * Procesar el recálculo masivo de todas las prestaciones del periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Proceso en curso:** Si ya hay un proceso de actualización masiva ejecutándose,
          la solicitud es rechazada con error 422 hasta que el proceso anterior termine.
        * **Actualización masiva:** Al enviar `bulk_update: true`, la operación se encola.
          Escucha la ruta de Firebase `companies/{company_id}/periods/{period_id}/social_benefit_periods/{social_benefit_period_id}/social_benefits/action_bulk_update`
          para recibir el resultado.
      requestBody:
        required: true
        description: Actualizar individual / Recalcular / Actualizar masivo
        content:
          application/json:
            schema:
              type: object
              properties:
                base_value:
                  description: Nuevo valor base del salario para el cálculo de la prestación, en pesos colombianos.
                  type: integer
                  example: 3500000
                days:
                  description: Número de días trabajados a considerar en el cálculo.
                  type: integer
                  example: 180
                item_value:
                  description: Nuevo valor a pagar en este periodo de nómina, en pesos colombianos.
                  type: integer
                  example: 800000
                service_bonus_retention:
                  description: Indica si se aplica retención sobre la prima de servicios. Solo aplica para periodos de categoría `service_bonus`.
                  type: boolean
                  example: false
                recalculate:
                  description: Si es `true`, recalcula automáticamente el valor de la prestación según los datos actuales del contrato, sin necesidad de enviar `base_value` o `days`.
                  type: boolean
                  example: false
                bulk_update:
                  description: Si es `true`, recalcula masivamente las prestaciones de todos los contratos del periodo. En este caso, los demás campos son ignorados.
                  type: boolean
                  example: false
            examples:
              Actualizar individual:
                value:
                  base_value: 3500000
                  days: 180
                  item_value: 800000
              Recalcular:
                value:
                  recalculate: true
              Actualizar masivo:
                value:
                  bulk_update: true
      responses:
        '200':
          description: Prestación actualizada / Recálculo masivo encolado
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        description: Datos actualizados de la prestación social.
                        type: object
                        required:
                          - id
                          - balance
                          - base_value
                          - contract_id
                          - days
                          - item_value
                          - paid_value
                          - payroll_id
                          - worker_id
                          - worker_name
                          - id_number
                          - value
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la prestación social en la base de datos.
                            type: string
                            example: 225898da-0f78-5ed4-b0bf-b2da389adaad
                          balance:
                            description: Saldo pendiente de pago de la prestación, en pesos colombianos.
                            type: integer
                            example: 700000
                          base_value:
                            description: Valor base del salario usado en el cálculo, en pesos colombianos.
                            type: integer
                            example: 3500000
                          contract_id:
                            description: Identificador único (ID) asignado al contrato en la base de datos.
                            type: string
                            example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                          days:
                            description: Número de días usados en el cálculo.
                            type: integer
                            example: 180
                          item_value:
                            description: Valor pagado en este periodo de nómina, en pesos colombianos.
                            type: integer
                            example: 800000
                          paid_value:
                            description: Valor total pagado de la prestación hasta el momento, en pesos colombianos.
                            type: integer
                            example: 800000
                          payroll_id:
                            description: Identificador único (ID) asignado a la nómina en la base de datos.
                            type: string
                            example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                          worker_id:
                            description: Identificador único (ID) asignado a la persona en la base de datos.
                            type: string
                            example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name:
                            description: Nombre completo de la persona con su estado de liquidación.
                            type: string
                            example: María González (Liquidado)
                          id_number:
                            description: Número de documento de identificación de la persona.
                            type: string
                            example: '9876543210'
                          value:
                            description: Valor total calculado de la prestación, en pesos colombianos.
                            type: integer
                            example: 1500000
                  - type: object
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de que el recálculo masivo fue encolado para procesamiento.
                        type: string
                        example: Procesando
              examples:
                Actualizar individual:
                  value:
                    data:
                      id: 225898da-0f78-5ed4-b0bf-b2da389adaad
                      balance: 700000
                      base_value: 3500000
                      contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      days: 180
                      item_value: 800000
                      paid_value: 800000
                      payroll_id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                      worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      worker_name: María González (Liquidado)
                      id_number: '9876543210'
                      value: 1500000
                Actualizar masivo:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Proceso en curso / Saldo negativo en recálculo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Proceso en curso:
                  value:
                    error:
                      - code: '4214'
                        index: 0
                        message: Ya tienes un proceso ejecutándose, debes esperar a que termine.
                        object: social_benefit
                Saldo negativo en recálculo:
                  value:
                    error:
                      - code: '4208'
                        index: 0
                        message: No se puede recalcular la prestación de Juan Pérez porque el saldo pendiente daría en negativo
                        object: social_benefit
    delete:
      operationId: destroySocialBenefit
      tags:
        - Prestaciones por periodo
      summary: Eliminar prestación social
      description: |
        **¿Qué hace este endpoint?**

        Elimina la prestación social del periodo, revirtiendo la liquidación realizada.
        La operación siempre se procesa de forma masiva para el periodo completo.

        **¿Cuándo usar este endpoint?**

        * Anular la liquidación de prestaciones de un periodo antes de cerrar la nómina.
        * Corregir errores en la liquidación eliminando los pagos del periodo y volviendo
          a liquidar desde cero.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Proceso en curso:** Si ya hay un proceso de eliminación ejecutándose, la solicitud
          es rechazada con error 422 hasta que el proceso anterior termine.
        * **Resultado:** Escucha la ruta de Firebase `companies/{company_id}/periods/{period_id}/social_benefit_periods/{social_benefit_period_id}/social_benefits/action_bulk_destroy`
          para recibir el resultado final.
      responses:
        '200':
          description: Eliminación de prestaciones encolada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de que la eliminación fue encolada para procesamiento.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Proceso en curso
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '4214'
                    index: 0
                    message: Ya tienes un proceso ejecutándose, debes esperar a que termine.
                    object: social_benefit
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 2f836bd7-51a0-4bb3-9d4f-ddd4b36bde9b
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 640191cc-59a7-5090-b5e9-1036dc2053f9
      - in: path
        required: true
        name: social_benefit_period_id
        description: Identificador único (ID) asignado al periodo de prestaciones sociales en la base de datos.
        schema:
          type: string
          example: 9b8bb4a5-e03f-5381-86f5-da2a659c95f5
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la prestación social en la base de datos.
        schema:
          type: string
          example: 225898da-0f78-5ed4-b0bf-b2da389adaad
  /v1/{company_id}/periods/{period_id}/social_benefits_file:
    get:
      operationId: showSocialBenefitsFile
      tags:
        - Archivos de prestaciones
      summary: Obtener archivo de prestaciones
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo Excel con el resumen de prestaciones sociales
        (prima de servicios, cesantías o intereses de cesantías) para un periodo de nómina
        y un periodo de prestaciones específico. Puede ejecutarse de forma síncrona o asíncrona.

        **¿Cuándo usar este endpoint?**

        * Descargar el reporte de prestaciones de un periodo para revisión contable o
          como soporte de los pagos realizados.
        * Generar el archivo en segundo plano cuando se prefiere respuesta no bloqueante.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/periods/{period_id}/social_benefits_file` para recibir
          la URL del archivo cuando esté listo.
      parameters:
        - in: query
          name: social_benefit_period_id
          required: true
          description: Identificador único (ID) del periodo de prestaciones sociales para el cual se genera el archivo (prima de servicios, cesantías o intereses de cesantías).
          schema:
            type: string
            example: 9b8bb4a5-e03f-5381-86f5-da2a659c95f5
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo generado.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/periods/{period_id}/social_benefits_file`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel de prestaciones sociales generado.
                        type: string
                        example: https://storage.aleluya.com/documents/prestaciones-2024-prima.xlsx
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que la generación del archivo fue encolada.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/documents/prestaciones-2024-prima.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 6f6e5c85-df85-4a27-95b6-891a983b9ee9
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 1dd2eb3f-d0e4-5e09-97b2-92f4226f1b4d
  /v1/{company_id}/periods/{period_id}/social_security_file:
    get:
      operationId: showSocialSecurityFile
      tags:
        - Planilla PILA
      summary: Obtener archivo de seguridad social
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo de planilla de seguridad social (PILA) para un
        periodo específico. El archivo puede ser en formato TXT (por defecto) o XLSX.

        **¿Cuándo usar este endpoint?**

        * Descargar el archivo PILA para enviarlo al operador de seguridad social.
        * Generar el archivo en formato Excel cuando se requiere revisión previa.
        * Generar el archivo en segundo plano cuando el volumen de personas es grande.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Periodo de seguridad social:** El periodo especificado en `{period_id}` debe
          ser un periodo de tipo seguridad social. Si no lo es, se retorna un error 422.
        * **Información completa:** Todos los contratos del periodo deben tener la
          información de seguridad social completa antes de generar el archivo.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/periods/{period_id}/social_security_file` para recibir
          la URL del archivo cuando esté listo.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          name: file_type
          required: false
          description: Formato del archivo a generar. `txt` genera el archivo de texto plano para enviar al operador. `xlsx` genera un resumen en Excel. Por defecto es `txt`.
          schema:
            type: string
            enum:
              - txt
              - xlsx
            example: txt
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social a usar para filtrar la generación del archivo. Si se omite, se genera el archivo para todas las sucursales.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a generar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055, `decree376_correction` para correcciones bajo el Decreto 376.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
              - decree376_correction
            example: employee
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga del archivo generado.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/periods/{period_id}/social_security_file`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo de planilla PILA generado.
                        type: string
                        example: https://storage.aleluya.com/documents/pila-enero-2024.txt
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que la generación del archivo fue encolada.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/documents/pila-enero-2024.txt
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Periodo no es de seguridad social / Información de seguridad social incompleta
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Periodo no es de seguridad social:
                  value:
                    error:
                      - code: '0602'
                        index: 0
                        message: No es posible generar el archivo.
                        object: file
                Información de seguridad social incompleta:
                  value:
                    error:
                      - code: '0607'
                        index: 0
                        message: Completa o corrige la información de seguridad social para poder generar la planilla de seguridad social.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: e387722c-4415-447a-9e32-9b166f848833
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/social_security_integration/form:
    get:
      operationId: showSocialSecurityIntegrationForm
      tags:
        - Integración con operador
      summary: Obtener planilla de integración
      description: |
        **¿Qué hace este endpoint?**

        Retorna los datos de la planilla de seguridad social del periodo junto con los
        totales de validación (trabajadores, errores, alertas y correcciones posibles)
        reportados por el operador.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado actual de la planilla antes de proceder al pago.
        * Verificar los errores o alertas reportados por el operador para corregirlos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
      parameters:
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a consultar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
            example: employee
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social de la planilla a consultar.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
      responses:
        '200':
          description: Planilla obtenida exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la planilla de integración de seguridad social.
                    type: object
                    properties:
                      form:
                        description: Información de la planilla.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la planilla en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          type:
                            description: Tipo de planilla. `employee` para empleados, `student_decree_055` para estudiantes bajo el Decreto 055.
                            type: string
                            example: employee
                          provider:
                            description: Proveedor del operador de integración. `aportes_en_linea` para Aportes En Línea, `enlace` para Enlace Operativo.
                            type: string
                            example: aportes_en_linea
                          key:
                            description: Clave de la planilla asignada por el operador. Es `null` si aún no fue asignada.
                            type:
                              - string
                              - 'null'
                            example: '123456789'
                          status:
                            description: Estado actual de la planilla. `created` recién creada, `pending` en proceso de pago, `paid` pagada, `declined` rechazada.
                            type: string
                            example: paid
                          pension_period:
                            description: Periodo de liquidación de pensión reportado por el operador.
                            type:
                              - string
                              - 'null'
                            example: 2024-01
                          health_period:
                            description: Periodo de liquidación de salud reportado por el operador.
                            type:
                              - string
                              - 'null'
                            example: 2024-01
                          due_date:
                            description: Fecha límite para el pago de la planilla. Es `null` si aún no está disponible.
                            type:
                              - string
                              - 'null'
                            example: '2024-02-05'
                          payment_date:
                            description: Fecha en que se realizó el pago de la planilla. Es `null` si no se ha pagado.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-25'
                          value:
                            description: Valor total de la planilla en pesos colombianos.
                            type: integer
                            example: 1500000
                          social_security_branch:
                            description: Sucursal de seguridad social asociada a la planilla.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sucursal en la base de datos. Es `null` si no tiene sucursal asignada.
                                type:
                                  - string
                                  - 'null'
                                example: e387722c-4415-447a-9e32-9b166f848833
                              name:
                                description: Nombre de la sucursal. Es `null` si no tiene sucursal asignada.
                                type:
                                  - string
                                  - 'null'
                                example: Sucursal Norte
                              code:
                                description: Código numérico de la sucursal. Es `null` si no tiene sucursal asignada.
                                type:
                                  - string
                                  - 'null'
                                example: '001'
                      totals:
                        description: Totales de validación reportados por el operador para la planilla.
                        type: object
                        properties:
                          workers:
                            description: Número de personas incluidas en la planilla.
                            type:
                              - integer
                              - 'null'
                            example: 15
                          errors:
                            description: Número de errores reportados por el operador en la planilla.
                            type:
                              - integer
                              - 'null'
                            example: 0
                          alerts:
                            description: Número de alertas reportadas por el operador en la planilla.
                            type:
                              - integer
                              - 'null'
                            example: 2
                          possible_fixes:
                            description: Número de correcciones posibles sugeridas por el operador.
                            type:
                              - integer
                              - 'null'
                            example: 1
              example:
                data:
                  form:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    type: employee
                    provider: aportes_en_linea
                    key: '123456789'
                    status: paid
                    pension_period: 2024-01
                    health_period: 2024-01
                    due_date: '2024-02-05'
                    payment_date: '2024-01-25'
                    value: 1500000
                    social_security_branch:
                      id: e387722c-4415-447a-9e32-9b166f848833
                      name: Sucursal Norte
                      code: '001'
                  totals:
                    workers: 15
                    errors: 0
                    alerts: 2
                    possible_fixes: 1
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de planilla inválido / Integración inactiva
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Tipo de planilla inválido:
                  value:
                    error:
                      - code: '0422'
                        index: 0
                        message: Tipo de planilla es inválido.
                        object: social_security_integration_payment
                Integración inactiva con Aportes En Línea:
                  value:
                    error:
                      - code: '1212'
                        index: 0
                        message: La empresa no tiene activa la integración con Aportes En Línea para pago de seguridad social.
                        object: integration
                Integración inactiva con Enlace Operativo:
                  value:
                    error:
                      - code: '1213'
                        index: 0
                        message: La empresa no tiene activa la integración con Enlace Operativo para pago de seguridad social.
                        object: integration
    delete:
      operationId: destroySocialSecurityIntegrationForm
      tags:
        - Integración con operador
      summary: Eliminar planilla de integración
      description: |
        **¿Qué hace este endpoint?**

        Elimina la planilla de seguridad social del periodo en el operador de integración
        y en el sistema. Para planillas de Enlace Operativo, también debe eliminarse
        manualmente en www.suaporte.com.co.

        **¿Cuándo usar este endpoint?**

        * Eliminar una planilla creada por error antes de proceder al pago.
        * Reiniciar el proceso de integración para volver a enviar la planilla.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **No eliminable si está pagada o pendiente:** Solo se pueden eliminar planillas en
          estado `created` o `declined`. Las planillas con estado `paid` o `pending` retornan
          un error 422.
      parameters:
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a eliminar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
            example: employee
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social de la planilla a eliminar.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
      responses:
        '200':
          description: Planilla eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: Planilla eliminada con éxito.
              example:
                data:
                  message: Planilla eliminada con éxito.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Integración inactiva / Sin acceso a la integración
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Integración inactiva:
                  value:
                    error:
                      - code: '1215'
                        index: 0
                        message: La empresa no tiene activa ninguna integración para el pago de seguridad social.
                        object: integration
                Sin acceso a la integración:
                  value:
                    error:
                      - code: '1218'
                        index: 0
                        message: No tienes acceso a esta integración.
                        object: integration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/social_security_integration/payment:
    get:
      operationId: showSocialSecurityIntegrationPayment
      tags:
        - Integración con operador
      summary: Obtener estado de pago de planilla
      description: |
        **¿Qué hace este endpoint?**

        Consulta el estado actual del pago de la planilla de seguridad social en el
        operador y retorna los datos de la empresa y el pago actualizado.

        **¿Cuándo usar este endpoint?**

        * Verificar si el pago de la planilla fue confirmado por el operador.
        * Consultar los datos del pago después de redirigir al usuario desde el portal PSE.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Integración activa requerida:** La empresa debe tener activa la integración del
          proveedor correspondiente a la planilla.
      parameters:
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a consultar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
            example: employee
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social de la planilla.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
      responses:
        '200':
          description: Estado de pago obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la empresa y el pago de la planilla de seguridad social.
                    type: object
                    properties:
                      company:
                        description: Información básica de la empresa.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la empresa en la base de datos.
                            type: string
                            example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
                          id_number:
                            description: Número de identificación tributaria de la empresa (NIT u otro tipo).
                            type: string
                            example: '900123456'
                          name:
                            description: Razón social de la empresa.
                            type: string
                            example: Empresa de prueba S.A.S.
                          email:
                            description: Correo electrónico de contacto de la empresa.
                            type: string
                            example: empresa@ejemplo.com
                      social_security_integration_payment:
                        description: Datos actualizados de la planilla de integración de seguridad social.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la planilla en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          form_key:
                            description: Clave de la planilla asignada por el operador.
                            type:
                              - string
                              - 'null'
                            example: '123456789'
                          form_status:
                            description: Estado actual de la planilla. `created` recién creada, `pending` en proceso de pago, `paid` pagada, `declined` rechazada.
                            type: string
                            example: pending
                          form_type:
                            description: Tipo de planilla. `employee` para empleados, `student_decree_055` para estudiantes bajo el Decreto 055.
                            type: string
                            example: employee
                          health_period:
                            description: Periodo de liquidación de salud reportado por el operador.
                            type:
                              - string
                              - 'null'
                            example: 2024-01
                          pension_period:
                            description: Periodo de liquidación de pensión reportado por el operador.
                            type:
                              - string
                              - 'null'
                            example: 2024-01
                          payment_date:
                            description: Fecha en que se realizó el pago de la planilla.
                            type: string
                            format: date
                            example: '2024-01-25'
                          provider:
                            description: Proveedor del operador de integración. `aportes_en_linea` para Aportes En Línea, `enlace` para Enlace Operativo.
                            type: string
                            example: aportes_en_linea
                          value:
                            description: Valor total de la planilla en pesos colombianos.
                            type: integer
                            example: 1500000
              example:
                data:
                  company:
                    id: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
                    id_number: '900123456'
                    name: Empresa de prueba S.A.S.
                    email: empresa@ejemplo.com
                  social_security_integration_payment:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    form_key: '123456789'
                    form_status: pending
                    form_type: employee
                    health_period: 2024-01
                    pension_period: 2024-01
                    payment_date: '2024-01-25'
                    provider: aportes_en_linea
                    value: 1500000
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Integración inactiva / Sin acceso a la integración
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Integración inactiva:
                  value:
                    error:
                      - code: '1215'
                        index: 0
                        message: La empresa no tiene activa ninguna integración para el pago de seguridad social.
                        object: integration
                Sin acceso a la integración:
                  value:
                    error:
                      - code: '1218'
                        index: 0
                        message: No tienes acceso a esta integración.
                        object: integration
    post:
      operationId: createSocialSecurityIntegrationPayment
      tags:
        - Integración con operador
      summary: Iniciar pago de planilla
      description: |
        **¿Qué hace este endpoint?**

        Inicia el proceso de pago PSE de la planilla de seguridad social en el operador
        y retorna la URL de pago para redirigir al usuario.

        **¿Cuándo usar este endpoint?**

        * Generar la URL de pago PSE para que el usuario complete el pago de la planilla.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Integración activa requerida:** La empresa debe tener activa la integración del
          proveedor correspondiente a la planilla.
        * **Horario restringido:** Por regulación colombiana, no es posible pagar entre las
          4:30 p.m. y las 6:30 p.m.
      parameters:
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a pagar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
            example: employee
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social de la planilla a pagar.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
      responses:
        '200':
          description: URL de pago PSE generada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la URL de pago generada por el operador.
                    type: object
                    properties:
                      payment_url:
                        description: URL de redirección al portal PSE para completar el pago de la planilla.
                        type: string
                        example: https://pse.redeban.com/PSEHostingUI/ShowDefaultForm.aspx?enc=xxx
              example:
                data:
                  payment_url: https://pse.redeban.com/PSEHostingUI/ShowDefaultForm.aspx?enc=xxx
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Horario restringido / Integración inactiva / Sin acceso a la integración
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Horario restringido:
                  value:
                    error:
                      - code: '1214'
                        index: 0
                        message: Por reglamentación en Colombia, no es posible pagar la planilla electrónica de seguridad social entre las 4:30 p.m. y las 6:30 pm.
                        object: integration
                Integración inactiva:
                  value:
                    error:
                      - code: '1215'
                        index: 0
                        message: La empresa no tiene activa ninguna integración para el pago de seguridad social.
                        object: integration
                Sin acceso a la integración:
                  value:
                    error:
                      - code: '1218'
                        index: 0
                        message: No tienes acceso a esta integración.
                        object: integration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/social_security_integration/payment_file:
    get:
      operationId: showSocialSecurityIntegrationPaymentFile
      tags:
        - Integración con operador
      summary: Validar token de archivo de seguridad social
      description: |
        **¿Qué hace este endpoint?**

        Valida el token del archivo de seguridad social enviado al operador y confirma
        si fue procesado correctamente.

        **¿Cuándo usar este endpoint?**

        * Confirmar que el archivo enviado al operador fue aceptado y procesado.
        * Verificar el estado del token antes de proceder al pago de la planilla.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Integración activa requerida:** La empresa debe tener activa la integración con
          el proveedor correspondiente al archivo enviado.
      parameters:
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a validar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
            example: employee
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social del archivo a validar.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
      responses:
        '200':
          description: Token validado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  file_validated:
                    description: Indica si el archivo fue validado exitosamente por el operador.
                    type: boolean
                    example: true
              example:
                file_validated: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Pago de seguridad social no encontrado / Integración inactiva
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Pago no encontrado:
                  value:
                    error:
                      - code: '1207'
                        index: 0
                        message: No se encuentra pago de seguridad social para el periodo.
                        object: integration
                Integración inactiva con Aportes En Línea:
                  value:
                    error:
                      - code: '1212'
                        index: 0
                        message: La empresa no tiene activa la integración con Aportes En Línea para pago de seguridad social.
                        object: integration
                Sin integración activa:
                  value:
                    error:
                      - code: '1206'
                        index: 0
                        message: La empresa no tiene activa ninguna integración para el pago de la seguridad social.
                        object: integration
    post:
      operationId: createSocialSecurityIntegrationPaymentFile
      tags:
        - Integración con operador
      summary: Enviar archivo de seguridad social al operador
      description: |
        **¿Qué hace este endpoint?**

        Genera el archivo de planilla PILA y lo envía al operador de integración de
        seguridad social. Puede ejecutarse de forma síncrona o asíncrona.

        **¿Cuándo usar este endpoint?**

        * Enviar la planilla generada al operador para su validación antes del pago.
        * Enviar el archivo en segundo plano cuando el volumen de personas es grande.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Integración activa requerida:** La empresa debe tener activa al menos una
          integración con un operador de seguridad social.
        * **Proveedor obligatorio con múltiples integraciones:** Si la empresa tiene activas
          tanto la integración de Aportes En Línea como la de Enlace Operativo, debe
          especificar el parámetro `provider` para indicar cuál usar.
        * **Horario restringido:** Por regulación colombiana, no es posible enviar la planilla
          entre las 4:30 p.m. y las 6:30 p.m.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/periods/{period_id}/social_security_integration/payment_file`
          para recibir el resultado cuando esté listo.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a enviar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
            example: employee
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social para la cual se envía el archivo.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
        - in: query
          name: provider
          required: false
          description: Proveedor al que se envía el archivo. Requerido cuando la empresa tiene activas ambas integraciones (Aportes En Línea y Enlace Operativo). `aportes_en_linea` o `enlace`.
          schema:
            type: string
            enum:
              - aportes_en_linea
              - enlace
            example: aportes_en_linea
      responses:
        '201':
          description: |
            La estructura de la respuesta depende del modo de envío indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `file_generated: true` confirmando que el archivo fue generado y enviado al operador.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. El archivo se envía en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/periods/{period_id}/social_security_integration/payment_file`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - file_generated
                    properties:
                      file_generated:
                        description: Indica que el archivo fue generado y enviado exitosamente al operador.
                        type: boolean
                        example: true
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          message:
                            description: Mensaje de confirmación de que el envío del archivo fue encolado.
                            type: string
                            example: Procesando
              examples:
                Síncrono:
                  value:
                    file_generated: true
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Horario restringido / Sin integración activa / Proveedor requerido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Horario restringido:
                  value:
                    error:
                      - code: '1214'
                        index: 0
                        message: Por reglamentación en Colombia, no es posible crear la planilla electrónica de seguridad social entre las 4:30 p.m. y las 6:30 pm.
                        object: integration
                Sin integración activa:
                  value:
                    error:
                      - code: '1206'
                        index: 0
                        message: La empresa no tiene activa ninguna integración para el pago de la seguridad social.
                        object: integration
                Proveedor requerido:
                  value:
                    error:
                      - code: '1209'
                        index: 0
                        message: Tienes varias integraciones activas para realizar el pago de seguridad social. Por favor, indicanos cuál deseas utilizar.
                        object: integration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/social_security_integration/validation_report:
    get:
      operationId: showSocialSecurityIntegrationValidationReport
      tags:
        - Integración con operador
      summary: Obtener reporte de validación
      description: |
        **¿Qué hace este endpoint?**

        Retorna el reporte de validación de la planilla de seguridad social del operador,
        con los errores, alertas y correcciones posibles para cada persona. Puede retornar
        el reporte en formato JSON (por defecto) o en formato Excel.

        **¿Cuándo usar este endpoint?**

        * Consultar los errores que impiden el procesamiento de la planilla en el operador.
        * Descargar el reporte de validación en Excel para revisión y corrección.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Tipo de planilla obligatorio:** El parámetro `form_type` solo acepta `employee`
          o `student_decree_055`. Otros valores retornan error 422.
        * **Reporte requerido:** La planilla debe tener un reporte de validación generado
          por el operador. Si no lo tiene, se retorna un error 422.
        * **Generación asíncrona del Excel:** Al enviar `file_format=xlsx` y `async=true`,
          escucha la ruta de Firebase `users/{user_id}/social_security_validation_files/{period_id}`
          para recibir la URL del archivo cuando esté listo.
      parameters:
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla cuyo reporte se desea consultar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
            example: employee
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social de la planilla.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
        - in: query
          name: file_format
          required: false
          description: Formato de respuesta. Si es `xlsx`, genera y retorna el reporte en formato Excel (síncrono o asíncrono según el parámetro `async`). Si se omite, retorna el reporte en formato JSON.
          schema:
            type: string
            enum:
              - xlsx
            example: xlsx
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `file_format` y `async`:

            - **JSON** (sin `file_format`): retorna el campo `data` con el reporte de validación estructurado con errores, alertas y correcciones posibles.
            - **Excel síncrono** (`file_format=xlsx`, `async: false` o sin enviar): retorna el campo `file` con la URL de descarga del reporte en formato Excel.
            - **Excel asíncrono** (`file_format=xlsx`, `async: true`): retorna el campo `message: Procesando`. El archivo se genera en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/social_security_validation_files/{period_id}`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        description: Reporte de validación en formato JSON con errores, alertas y correcciones posibles.
                        type: object
                        properties:
                          errors:
                            description: Lista de errores que impiden el procesamiento de la planilla.
                            type: array
                            items:
                              description: Detalle de un error de validación reportado por el operador.
                              type: object
                              properties:
                                id:
                                  description: Índice del error dentro del reporte de validación.
                                  type: integer
                                  example: 1
                                position_info:
                                  description: Información del cargo o posición de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: Empleado
                                id_number:
                                  description: Número de documento de identidad de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: '123456789'
                                document_type:
                                  description: Tipo de documento de identidad de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: CC
                                current_value:
                                  description: Valor actual reportado en la planilla para este campo.
                                  type:
                                    - string
                                    - 'null'
                                  example: '1500000'
                                expected_value:
                                  description: Valor esperado por el operador para este campo.
                                  type:
                                    - string
                                    - 'null'
                                  example: '1600000'
                                description:
                                  description: Descripción del error reportado por el operador.
                                  type:
                                    - string
                                    - 'null'
                                  example: El valor de cotización de pensión no corresponde al IBC.
                          alerts:
                            description: Lista de alertas que el operador recomienda revisar.
                            type: array
                            items:
                              description: Detalle de una alerta de validación reportada por el operador.
                              type: object
                              properties:
                                id:
                                  description: Índice de la alerta dentro del reporte de validación.
                                  type: integer
                                  example: 1
                                position_info:
                                  description: Información del cargo o posición de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: Empleado
                                id_number:
                                  description: Número de documento de identidad de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: '987654321'
                                document_type:
                                  description: Tipo de documento de identidad de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: CC
                                current_value:
                                  description: Valor actual reportado en la planilla para este campo.
                                  type:
                                    - string
                                    - 'null'
                                  example: '500000'
                                expected_value:
                                  description: Valor esperado por el operador para este campo.
                                  type:
                                    - string
                                    - 'null'
                                  example: '600000'
                                description:
                                  description: Descripción de la alerta reportada por el operador.
                                  type:
                                    - string
                                    - 'null'
                                  example: El valor de IBC es inferior al salario mínimo.
                          possible_fixes:
                            description: Lista de correcciones posibles sugeridas por el operador.
                            type: array
                            items:
                              description: Detalle de una corrección posible sugerida por el operador.
                              type: object
                              properties:
                                id:
                                  description: Índice de la corrección dentro del reporte de validación.
                                  type: integer
                                  example: 1
                                position_info:
                                  description: Información del cargo o posición de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: Empleado
                                id_number:
                                  description: Número de documento de identidad de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: '111222333'
                                document_type:
                                  description: Tipo de documento de identidad de la persona afectada.
                                  type:
                                    - string
                                    - 'null'
                                  example: CC
                                current_value:
                                  description: Valor actual reportado en la planilla para este campo.
                                  type:
                                    - string
                                    - 'null'
                                  example: '0'
                                expected_value:
                                  description: Valor sugerido por el operador para este campo.
                                  type:
                                    - string
                                    - 'null'
                                  example: '100000'
                                description:
                                  description: Descripción de la corrección sugerida por el operador.
                                  type:
                                    - string
                                    - 'null'
                                  example: Se recomienda revisar el aporte a fondo de solidaridad.
                  - type: object
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del reporte de validación en formato Excel.
                        type: string
                        example: https://storage.aleluya.com/documents/reporte-validacion-2024-01.xlsx
                  - type: object
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de que la generación del Excel fue encolada.
                        type: string
                        example: Procesando
              examples:
                JSON:
                  value:
                    data:
                      errors:
                        - id: 1
                          position_info: Empleado
                          id_number: '123456789'
                          document_type: CC
                          current_value: '1500000'
                          expected_value: '1600000'
                          description: El valor de cotización de pensión no corresponde al IBC.
                      alerts:
                        - id: 1
                          position_info: Empleado
                          id_number: '987654321'
                          document_type: CC
                          current_value: '500000'
                          expected_value: '600000'
                          description: El valor de IBC es inferior al salario mínimo.
                      possible_fixes: []
                Excel síncrono:
                  value:
                    file: https://storage.aleluya.com/documents/reporte-validacion-2024-01.xlsx
                Excel asíncrono:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Tipo de planilla inválido / Reporte de validación no disponible
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Tipo de planilla inválido:
                  value:
                    error:
                      - code: '0422'
                        index: 0
                        message: Tipo de planilla es inválido.
                        object: social_security_integration_payment
                Reporte no disponible:
                  value:
                    error:
                      - code: '0422'
                        index: 0
                        message: Reporte de validación es requerido.
                        object: social_security_integration_payment
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods/{period_id}/social_security_summary_data:
    get:
      operationId: showSocialSecuritySummaryData
      tags:
        - Integración con operador
      summary: Obtener resumen de seguridad social
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna los datos de resumen de seguridad social del periodo para cada
        persona: aportes a pensión, salud, riesgos laborales, parafiscales y total por
        persona, junto con los totales consolidados del periodo. Puede ejecutarse de forma
        síncrona o asíncrona.

        **¿Cuándo usar este endpoint?**

        * Obtener el detalle de aportes por persona antes de enviar la planilla al operador.
        * Verificar los totales del periodo para conciliar con el operador de seguridad social.
        * Generar el resumen en segundo plano cuando el volumen de personas es grande.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Integración activa:** La empresa debe tener activa al menos una integración de pago
          de seguridad social (AEL o Enlace Operativo). Si no tiene ninguna activa, se retorna
          un error 422.
        * **Periodo de seguridad social:** El periodo especificado en `{period_id}` debe
          ser un periodo de tipo seguridad social.
        * **Información completa:** Todos los contratos del periodo deben tener la
          información de seguridad social completa.
        * **Generación asíncrona:** Al enviar `async=true`, escucha la ruta de Firebase
          `users/{user_id}/periods/{period_id}/social_security_summary_data` para recibir
          los datos cuando estén listos.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          name: social_security_branch_id
          required: false
          description: Identificador único (ID) de la sucursal de seguridad social a usar para filtrar los datos del resumen. Si se omite, se incluyen todas las sucursales.
          schema:
            type: string
            example: e387722c-4415-447a-9e32-9b166f848833
        - in: query
          name: form_type
          required: false
          description: Tipo de planilla a consultar. `employee` para empleados (por defecto), `student_decree_055` para estudiantes bajo el Decreto 055, `decree376_correction` para correcciones bajo el Decreto 376.
          schema:
            type: string
            enum:
              - employee
              - student_decree_055
              - decree376_correction
            example: employee
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del modo de generación indicado en `async`:

            - **Síncrono** (`async: false` o sin enviar): retorna el campo `data` con el resumen de aportes de seguridad social por persona y los totales consolidados del periodo.
            - **Asíncrono** (`async: true`): retorna el campo `message: Procesando`. Los datos se generan en segundo plano y el resultado se publica en Firebase en la ruta `users/{user_id}/periods/{period_id}/social_security_summary_data`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        description: Resumen de aportes de seguridad social del periodo.
                        type: object
                        properties:
                          workers:
                            description: Lista de personas con el detalle de sus aportes de seguridad social.
                            type: array
                            items:
                              description: Datos de aportes de seguridad social de una persona.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la persona en la base de datos.
                                  type: string
                                  example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                                name:
                                  description: Nombre completo de la persona.
                                  type: string
                                  example: Juan Pérez
                                id_number:
                                  description: Número de documento de identidad de la persona.
                                  type: string
                                  example: '123456789'
                                pension:
                                  description: Monto total del aporte a pensión de la persona en pesos colombianos.
                                  type: integer
                                  example: 134500
                                health:
                                  description: Monto total del aporte a salud de la persona en pesos colombianos.
                                  type: integer
                                  example: 33800
                                risks:
                                  description: Monto total del aporte a riesgos laborales de la persona en pesos colombianos.
                                  type: integer
                                  example: 2400
                                parafiscals:
                                  description: Monto total de aportes parafiscales de la persona en pesos colombianos.
                                  type: integer
                                  example: 28500
                                total:
                                  description: Monto total de todos los aportes de seguridad social de la persona en pesos colombianos.
                                  type: integer
                                  example: 199200
                          totals:
                            description: Totales consolidados de todos los aportes del periodo.
                            type: object
                            properties:
                              pension:
                                description: Total de aportes a pensión del periodo en pesos colombianos.
                                type: integer
                                example: 841700
                              health:
                                description: Total de aportes a salud del periodo en pesos colombianos.
                                type: integer
                                example: 314200
                              risks:
                                description: Total de aportes a riesgos laborales del periodo en pesos colombianos.
                                type: integer
                                example: 28400
                              parafiscals:
                                description: Total de aportes parafiscales del periodo en pesos colombianos.
                                type: integer
                                example: 194100
                              total:
                                description: Monto total de todos los aportes de seguridad social del periodo en pesos colombianos.
                                type: integer
                                example: 1378400
                              workers_size:
                                description: Número de personas incluidas en el resumen del periodo.
                                type: integer
                                example: 4
                  - type: object
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de que la generación de los datos fue encolada.
                        type: string
                        example: Procesando
              examples:
                Síncrono:
                  value:
                    data:
                      workers:
                        - id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          name: Juan Pérez
                          id_number: '123456789'
                          pension: 134500
                          health: 33800
                          risks: 2400
                          parafiscals: 28500
                          total: 199200
                        - id: d83dbeef-931a-5d13-a956-8f9b904d0252
                          name: María González
                          id_number: '987654321'
                          pension: 208000
                          health: 52000
                          risks: 6800
                          parafiscals: 52000
                          total: 318800
                      totals:
                        pension: 342500
                        health: 85800
                        risks: 9200
                        parafiscals: 80500
                        total: 518000
                        workers_size: 2
                Asíncrono:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin integración activa / Periodo no es de seguridad social / Información incompleta
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Sin integración activa:
                  value:
                    error:
                      - code: '1206'
                        index: 0
                        message: La empresa no tiene activa ninguna integración para el pago de la seguridad social.
                        object: integration
                Periodo no es de seguridad social:
                  value:
                    error:
                      - code: '0602'
                        index: 0
                        message: No es posible generar el archivo.
                        object: file
                Información de seguridad social incompleta:
                  value:
                    error:
                      - code: '0607'
                        index: 0
                        message: Completa o corrige la información de seguridad social para poder generar la planilla de seguridad social.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/periods_dates:
    get:
      operationId: indexPeriodsDates
      tags:
        - Periodos de nómina
      summary: Listar fechas de periodos
      description: |
        **¿Qué hace este endpoint?**

        Retorna las fechas de inicio y fin de todos los periodos de nómina existentes para la empresa.

        **¿Cuándo usar este endpoint?**

        * Obtener las fechas disponibles para construir selectores de periodos en formularios de liquidación.
        * Verificar qué fechas de inicio y fin de periodo existen antes de crear un nuevo periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Fechas de periodos retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Fechas de inicio y fin de los periodos de nómina de la empresa.
                    type: object
                    properties:
                      initial_dates:
                        description: Listado de fechas de inicio de los periodos de nómina, en formato `YYYY-MM-DD`.
                        type: array
                        items:
                          type: string
                        example:
                          - '2024-01-01'
                          - '2024-01-16'
                      end_dates:
                        description: Listado de fechas de fin de los periodos de nómina, en formato `YYYY-MM-DD`.
                        type: array
                        items:
                          type: string
                        example:
                          - '2024-01-15'
                          - '2024-01-31'
              example:
                data:
                  initial_dates:
                    - '2024-01-01'
                    - '2024-01-16'
                  end_dates:
                    - '2024-01-15'
                    - '2024-01-31'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          description: Empresa no existe
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/plans:
    get:
      operationId: indexPlans
      tags:
        - Planes
      summary: Listar planes disponibles
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de planes disponibles para la empresa con sus valores mensuales y anuales,
        incluyendo el costo por persona adicional y los descuentos del distribuidor aplicables.

        **¿Cuándo usar este endpoint?**

        * Mostrar al usuario los planes a los que puede cambiar su suscripción actual.
        * Comparar precios entre planes antes de hacer un upgrade o downgrade.
        * Conocer los valores exactos de cada plan con los descuentos del distribuidor ya aplicados.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Planes disponibles retornados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de planes disponibles para la empresa con sus valores y descuentos calculados.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al plan en la base de datos.
                          type: string
                          example: a9d5261c-62bc-5be2-bafa-7dd6f754ba2e
                        name:
                          description: Nombre legible del plan.
                          type: string
                          example: Solo Nómina
                        coded_name:
                          description: Nombre codificado del plan usado como identificador interno.
                          type: string
                          example: premium_per_worker_plan
                        max_workers:
                          description: Número máximo de personas incluidas en el plan base sin costo adicional.
                          type: integer
                          example: 40
                        selected:
                          description: Indica si este plan está pre-seleccionado en el listado según el plan actual de la empresa o su número de personas registradas.
                          type: boolean
                          example: false
                        monthly_value:
                          description: Valor mensual del plan en pesos colombianos.
                          type: integer
                          example: 189900
                        monthly_extra_worker_value:
                          description: Costo adicional mensual por cada persona que supere el límite del plan, en pesos colombianos.
                          type: integer
                          example: 0
                        yearly_value_by_month:
                          description: Valor mensual equivalente al contratar el plan anual, en pesos colombianos.
                          type: integer
                          example: 170910
                        total_yearly_value:
                          description: Valor total a pagar por el plan anual completo (12 meses) en pesos colombianos.
                          type: integer
                          example: 2050920
                        yearly_extra_worker_value:
                          description: Costo adicional anual por cada persona que supere el límite del plan, en pesos colombianos.
                          type: integer
                          example: 0
                        discount_value:
                          description: Valor del descuento aplicado al contratar el plan anual en pesos colombianos.
                          type: integer
                          example: 227880
                        current_plan:
                          description: Indica si este es el plan activo actualmente de la empresa.
                          type: boolean
                          example: false
                        subscription_value:
                          description: Desglose detallado del costo de la suscripción para frecuencia mensual y anual, incluyendo descuentos del distribuidor.
                          type: object
                          properties:
                            monthly:
                              description: Desglose del costo para suscripción mensual.
                              type: object
                              properties:
                                subtotal_extra_workers_value:
                                  description: Subtotal en pesos colombianos correspondiente a las personas adicionales sobre el límite del plan.
                                  type: integer
                                  example: 0
                                workers_number:
                                  description: Número de personas adicionales sobre el límite del plan incluidas en el cálculo.
                                  type: integer
                                  example: 0
                                value:
                                  description: Valor base mensual del plan en pesos colombianos.
                                  type: integer
                                  example: 189900
                                subtotal:
                                  description: Subtotal mensual antes de aplicar descuentos del distribuidor, en pesos colombianos.
                                  type: integer
                                  example: 189900
                                extra_worker_value:
                                  description: Costo unitario mensual por persona adicional sobre el límite del plan, en pesos colombianos.
                                  type: integer
                                  example: 0
                                extra_charge:
                                  description: Cargos adicionales aplicados sobre el valor base mensual.
                                  type: object
                                  properties:
                                    nominapp:
                                      description: Cargo adicional mensual aplicado por Aleluya en pesos colombianos.
                                      type: integer
                                      example: 0
                                    distributor:
                                      description: Cargo adicional mensual aplicado por el distribuidor en pesos colombianos. Negativo si es un descuento.
                                      type: integer
                                      example: 0
                                total:
                                  description: Total mensual a pagar incluyendo cargos adicionales del distribuidor, en pesos colombianos.
                                  type: integer
                                  example: 189900
                            yearly:
                              description: Desglose del costo para suscripción anual.
                              type: object
                              properties:
                                subtotal_extra_workers_value:
                                  description: Subtotal en pesos colombianos correspondiente a las personas adicionales sobre el límite del plan (anual).
                                  type: integer
                                  example: 0
                                workers_number:
                                  description: Número de personas adicionales sobre el límite del plan incluidas en el cálculo anual.
                                  type: integer
                                  example: 0
                                value:
                                  description: Valor base mensual equivalente al contratar el plan anual, en pesos colombianos.
                                  type: integer
                                  example: 170910
                                subtotal:
                                  description: Subtotal anual antes de aplicar descuentos del distribuidor, en pesos colombianos.
                                  type: integer
                                  example: 2278800
                                extra_worker_value:
                                  description: Costo unitario anual por persona adicional sobre el límite del plan, en pesos colombianos.
                                  type: integer
                                  example: 0
                                extra_charge:
                                  description: Cargos adicionales aplicados sobre el valor base anual.
                                  type: object
                                  properties:
                                    nominapp:
                                      description: Cargo adicional anual aplicado por Aleluya en pesos colombianos.
                                      type: integer
                                      example: 0
                                    distributor:
                                      description: Cargo adicional anual aplicado por el distribuidor en pesos colombianos. Negativo si es un descuento.
                                      type: integer
                                      example: -227880
                                total:
                                  description: Total anual a pagar incluyendo cargos adicionales del distribuidor, en pesos colombianos.
                                  type: integer
                                  example: 2050920
                            discounts:
                              description: Descuentos del distribuidor aplicables a la suscripción mensual y anual.
                              type: object
                              properties:
                                first_payment:
                                  description: Indica si la empresa tiene 1 o menos pagos aprobados.
                                  type: boolean
                                  example: true
                                yearly_distributor:
                                  description: Nombre del distribuidor que aplica el descuento anual. Null si no hay descuento anual activo.
                                  type:
                                    - string
                                    - 'null'
                                  example: Nominapp
                                yearly_percentage:
                                  description: Porcentaje de descuento aplicado al plan anual. Negativo representa un descuento (ej. -0.1 = 10% de descuento).
                                  type: number
                                  example: -0.1
                                monthly_distributor:
                                  description: Nombre del distribuidor que aplica el descuento mensual. Null si no hay descuento mensual activo.
                                  type:
                                    - string
                                    - 'null'
                                  example: Nominapp
                                monthly_percentage:
                                  description: Porcentaje de descuento aplicado al plan mensual. Negativo representa un descuento.
                                  type: number
                                  example: 0
              example:
                data:
                  - id: a9d5261c-62bc-5be2-bafa-7dd6f754ba2e
                    name: Emprendedor
                    coded_name: entrepreneur_per_worker_plan
                    max_workers: 10
                    selected: false
                    monthly_value: 50000
                    monthly_extra_worker_value: 0
                    yearly_value_by_month: 0
                    total_yearly_value: 0
                    yearly_extra_worker_value: 0
                    discount_value: 0
                    current_plan: true
                    subscription_value:
                      monthly:
                        subtotal_extra_workers_value: 0
                        workers_number: 0
                        value: 50000
                        subtotal: 50000
                        extra_worker_value: 0
                        extra_charge:
                          nominapp: 0
                          distributor: 0
                        total: 50000
                      discounts:
                        first_payment: true
                        yearly_distributor: null
                        yearly_percentage: 0
                        monthly_distributor: null
                        monthly_percentage: 0
                  - id: ceecd11c-490f-510e-944e-dbdc78ae43dc
                    name: Solo Nómina
                    coded_name: premium_per_worker_plan
                    max_workers: 40
                    selected: false
                    monthly_value: 189900
                    monthly_extra_worker_value: 0
                    yearly_value_by_month: 170910
                    total_yearly_value: 2050920
                    yearly_extra_worker_value: 0
                    discount_value: 227880
                    current_plan: false
                    subscription_value:
                      monthly:
                        subtotal_extra_workers_value: 0
                        workers_number: 0
                        value: 189900
                        subtotal: 189900
                        extra_worker_value: 0
                        extra_charge:
                          nominapp: 0
                          distributor: 0
                        total: 189900
                      yearly:
                        subtotal_extra_workers_value: 0
                        workers_number: 0
                        value: 170910
                        subtotal: 2278800
                        extra_worker_value: 0
                        extra_charge:
                          nominapp: 0
                          distributor: -227880
                        total: 2050920
                      discounts:
                        first_payment: true
                        yearly_distributor: Nominapp
                        yearly_percentage: -0.1
                        monthly_distributor: null
                        monthly_percentage: 0
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 3037494f-4ba9-44d4-915b-f31288152587
  /v1/{company_id}/plans/{id}:
    get:
      operationId: showPlan
      tags:
        - Planes
      summary: Obtener detalle de plan
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de un plan específico con el costo calculado según el número de personas
        que se desean incluir, ya sea usando las personas activas actuales de la empresa o un número
        personalizado de personas adicionales.

        **¿Cuándo usar este endpoint?**

        * Obtener el costo exacto de un plan al que la empresa quiere cambiar, considerando sus personas activas actuales.
        * Calcular el precio al agregar un número específico de personas adicionales sobre el límite del plan.
        * Mostrar el desglose de valores mensuales y anuales antes de confirmar un cambio de plan.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Parámetros requeridos:** Se debe enviar `without_extra_workers=true` para usar las personas activas de la empresa, o `workers_number` con el número de personas a calcular. Si no se envía ninguno, retorna 422. Si se envían ambos, `without_extra_workers` tiene precedencia.
      parameters:
        - in: query
          required: false
          name: without_extra_workers
          description: Cuando es `true`, el cálculo se realiza usando el número de personas activas actuales de la empresa, sin agregar personas extras. No se puede enviar junto con `workers_number`.
          schema:
            type: boolean
            example: true
        - in: query
          required: false
          name: workers_number
          description: Número de personas a usar en el cálculo del plan. Debe ser mayor a cero. Si se envía junto con `without_extra_workers=true`, este parámetro se ignora.
          schema:
            type: integer
            minimum: 1
            example: 3
      responses:
        '200':
          description: Detalle del plan retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Detalle del plan con el cálculo de costos según las personas indicadas.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al plan en la base de datos.
                        type: string
                        example: 1793e4c8-84ed-56ae-a6e7-74b05855bec0
                      name:
                        description: Nombre legible del plan.
                        type: string
                        example: Nómina Holística
                      coded_name:
                        description: Nombre codificado del plan usado como identificador interno.
                        type: string
                        example: premium_full_per_worker_plan
                      max_workers:
                        description: Número máximo de personas incluidas en el plan base sin costo adicional.
                        type: integer
                        example: 80
                      selected:
                        description: Indica si este plan está pre-seleccionado en el listado según el plan actual de la empresa o su número de personas registradas.
                        type: boolean
                        example: false
                      monthly_value:
                        description: Valor mensual del plan en pesos colombianos.
                        type: integer
                        example: 299900
                      monthly_extra_worker_value:
                        description: Costo adicional mensual por cada persona que supere el límite del plan, en pesos colombianos.
                        type: integer
                        example: 5000
                      yearly_value_by_month:
                        description: Valor mensual equivalente al contratar el plan anual, en pesos colombianos.
                        type: integer
                        example: 269910
                      total_yearly_value:
                        description: Valor total a pagar por el plan anual completo (12 meses) en pesos colombianos.
                        type: integer
                        example: 3238920
                      yearly_extra_worker_value:
                        description: Costo adicional anual por cada persona que supere el límite del plan, en pesos colombianos.
                        type: integer
                        example: 4500
                      discount_value:
                        description: Valor del descuento aplicado al contratar el plan anual en pesos colombianos.
                        type: integer
                        example: 359880
                      current_plan:
                        description: Indica si este es el plan activo actualmente de la empresa.
                        type: boolean
                        example: false
                      subscription_value:
                        description: Desglose detallado del costo de la suscripción para frecuencia mensual y anual, incluyendo descuentos del distribuidor.
                        type: object
                        properties:
                          monthly:
                            description: Desglose del costo para suscripción mensual.
                            type: object
                            properties:
                              subtotal_extra_workers_value:
                                description: Subtotal en pesos colombianos correspondiente a las personas adicionales sobre el límite del plan.
                                type: integer
                                example: 15000
                              workers_number:
                                description: Número de personas adicionales sobre el límite del plan incluidas en el cálculo.
                                type: integer
                                example: 3
                              value:
                                description: Valor base mensual del plan en pesos colombianos.
                                type: integer
                                example: 299900
                              subtotal:
                                description: Subtotal mensual antes de aplicar descuentos del distribuidor, en pesos colombianos.
                                type: integer
                                example: 314900
                              extra_worker_value:
                                description: Costo unitario mensual por persona adicional sobre el límite del plan, en pesos colombianos.
                                type: integer
                                example: 5000
                              extra_charge:
                                description: Cargos adicionales aplicados sobre el valor base mensual.
                                type: object
                                properties:
                                  nominapp:
                                    description: Cargo adicional mensual aplicado por Aleluya en pesos colombianos.
                                    type: integer
                                    example: 0
                                  distributor:
                                    description: Cargo adicional mensual aplicado por el distribuidor en pesos colombianos. Negativo si es un descuento.
                                    type: integer
                                    example: 0
                              total:
                                description: Total mensual a pagar incluyendo cargos adicionales del distribuidor, en pesos colombianos.
                                type: integer
                                example: 314900
                          yearly:
                            description: Desglose del costo para suscripción anual.
                            type: object
                            properties:
                              subtotal_extra_workers_value:
                                description: Subtotal en pesos colombianos correspondiente a las personas adicionales sobre el límite del plan (anual).
                                type: integer
                                example: 13500
                              workers_number:
                                description: Número de personas adicionales sobre el límite del plan incluidas en el cálculo anual.
                                type: integer
                                example: 3
                              value:
                                description: Valor base mensual equivalente al contratar el plan anual, en pesos colombianos.
                                type: integer
                                example: 269910
                              subtotal:
                                description: Subtotal anual antes de aplicar descuentos del distribuidor, en pesos colombianos.
                                type: integer
                                example: 3760920
                              extra_worker_value:
                                description: Costo unitario anual por persona adicional sobre el límite del plan, en pesos colombianos.
                                type: integer
                                example: 4500
                              extra_charge:
                                description: Cargos adicionales aplicados sobre el valor base anual.
                                type: object
                                properties:
                                  nominapp:
                                    description: Cargo adicional anual aplicado por Aleluya en pesos colombianos.
                                    type: integer
                                    example: 0
                                  distributor:
                                    description: Cargo adicional anual aplicado por el distribuidor en pesos colombianos. Negativo si es un descuento.
                                    type: integer
                                    example: -359880
                              total:
                                description: Total anual a pagar incluyendo cargos adicionales del distribuidor, en pesos colombianos.
                                type: integer
                                example: 3401040
                          discounts:
                            description: Descuentos del distribuidor aplicables a la suscripción mensual y anual.
                            type: object
                            properties:
                              first_payment:
                                description: Indica si la empresa tiene 1 o menos pagos aprobados.
                                type: boolean
                                example: true
                              yearly_distributor:
                                description: Nombre del distribuidor que aplica el descuento anual. Null si no hay descuento anual activo.
                                type:
                                  - string
                                  - 'null'
                                example: Nominapp
                              yearly_percentage:
                                description: Porcentaje de descuento aplicado al plan anual. Negativo representa un descuento (ej. -0.1 = 10% de descuento).
                                type: number
                                example: -0.1
                              monthly_distributor:
                                description: Nombre del distribuidor que aplica el descuento mensual. Null si no hay descuento mensual activo.
                                type:
                                  - string
                                  - 'null'
                                example: Nominapp
                              monthly_percentage:
                                description: Porcentaje de descuento aplicado al plan mensual. Negativo representa un descuento.
                                type: number
                                example: 0
                required:
                  - data
              example:
                data:
                  id: 1793e4c8-84ed-56ae-a6e7-74b05855bec0
                  name: Nómina Holística
                  coded_name: premium_full_per_worker_plan
                  max_workers: 80
                  selected: false
                  monthly_value: 299900
                  monthly_extra_worker_value: 5000
                  yearly_value_by_month: 269910
                  total_yearly_value: 3238920
                  yearly_extra_worker_value: 4500
                  discount_value: 359880
                  current_plan: false
                  subscription_value:
                    monthly:
                      subtotal_extra_workers_value: 15000
                      workers_number: 3
                      value: 299900
                      subtotal: 314900
                      extra_worker_value: 5000
                      extra_charge:
                        nominapp: 0
                        distributor: 0
                      total: 314900
                    yearly:
                      subtotal_extra_workers_value: 13500
                      workers_number: 3
                      value: 269910
                      subtotal: 3760920
                      extra_worker_value: 4500
                      extra_charge:
                        nominapp: 0
                        distributor: -359880
                      total: 3401040
                    discounts:
                      first_payment: true
                      yearly_distributor: Nominapp
                      yearly_percentage: -0.1
                      monthly_distributor: null
                      monthly_percentage: 0
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Plan sin personas adicionales / Número de personas no enviado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Plan sin personas adicionales:
                  value:
                    error:
                      - code: '0110'
                        index: 0
                        message: Este plan no permite personas adicionales.
                        object: plan
                Número de personas no enviado:
                  value:
                    error:
                      - code: '0111'
                        index: 0
                        message: La cantidad de personas debe ser mayor a cero.
                        object: plan
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: b3d9fa6b-f1b4-4c57-8f73-68ac672b6237
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al plan en la base de datos.
        schema:
          type: string
          example: 1793e4c8-84ed-56ae-a6e7-74b05855bec0
  /v1/{company_id}/positions:
    get:
      operationId: indexPositions
      tags:
        - Cargos
      summary: Listar cargos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de cargos registrados para la empresa, ordenados alfabéticamente.

        **¿Cuándo usar este endpoint?**

        * Consultar los cargos disponibles para asignar a una persona al crear o modificar su contrato.
        * Verificar qué cargos pueden eliminarse antes de reorganizar la estructura de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Cargos registrados / Sin cargos registrados
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de cargos de la empresa, ordenados alfabéticamente.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al cargo en la base de datos.
                          type: string
                          example: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                        name:
                          description: Nombre del cargo.
                          type: string
                          example: Desarrollador de Software
                        deleteable:
                          description: Indica si el cargo puede eliminarse. Es `false` cuando tiene personas asociadas en su historial de cargo.
                          type: boolean
                          example: false
              examples:
                Cargos registrados:
                  value:
                    data:
                      - id: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                        name: Desarrollador de Software
                        deleteable: false
                      - id: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                        name: Analista Contable
                        deleteable: true
                Sin cargos registrados:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updatePositions
      tags:
        - Cargos
      summary: Gestionar cargos
      description: |
        **¿Qué hace este endpoint?**

        Gestiona de forma masiva los cargos de la empresa en una sola operación. La acción se determina automáticamente según los campos enviados en cada objeto:

        * **Crear:** Sin `id` — crea un nuevo cargo con el `name` indicado.
        * **Actualizar:** Con `id` y `name` — actualiza el nombre del cargo existente.
        * **Eliminar:** Con `id` sin `name` — elimina el cargo si no tiene personas asociadas.

        **¿Cuándo usar este endpoint?**

        * Configurar los cargos de la empresa antes de registrar personas.
        * Renombrar o eliminar cargos tras cambios organizacionales.
        * Crear, actualizar y eliminar varios cargos en una sola llamada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Eliminación:** Solo se puede eliminar un cargo si no tiene personas asociadas en su historial de cargo. El campo `deleteable` del GET indica si el cargo es eliminable.
      requestBody:
        required: true
        description: Crear cargo / Actualizar cargo / Eliminar cargo / Operación combinada
        content:
          application/json:
            schema:
              type: object
              properties:
                positions:
                  description: Arreglo de operaciones a ejecutar sobre los cargos de la empresa.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Identificador único (ID) del cargo en la base de datos. Omitir para crear un cargo nuevo.
                        example: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                      name:
                        type: string
                        description: Nombre del cargo. Omitir para eliminar el cargo.
                        example: Desarrollador de Software
              required:
                - positions
            examples:
              Crear cargo:
                value:
                  positions:
                    - name: Analista de Datos
              Actualizar cargo:
                value:
                  positions:
                    - id: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                      name: Desarrollador de Software Senior
              Eliminar cargo:
                value:
                  positions:
                    - id: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
              Operación combinada:
                value:
                  positions:
                    - name: Analista de Datos
                    - id: 46e4c9cc-edca-52d9-a36d-8d85ecdee0a4
                      name: Desarrollador de Software Senior
                    - id: 3ecf3b5d-e414-53d4-a170-f4615e832a78
      responses:
        '202':
          description: Cargos gestionados exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de cargos creados o actualizados en la operación. Los eliminados no se incluyen.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al cargo en la base de datos.
                          type: string
                          example: 3a3e4418-3a9d-4876-946a-f48a8789f162
                        name:
                          description: Nombre del cargo.
                          type: string
                          example: Desarrollador de Software
                        deleteable:
                          description: Indica si el cargo puede eliminarse. Es `false` cuando tiene personas asociadas en su historial de cargo.
                          type: boolean
                          example: true
              example:
                data:
                  - id: 3a3e4418-3a9d-4876-946a-f48a8789f162
                    name: Desarrollador de Software
                    deleteable: true
                  - id: 7b1c2d3e-4f5a-6b7c-8d9e-0a1b2c3d4e5f
                    name: Analista de Datos
                    deleteable: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Parámetro positions ausente o inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0102'
                    index: 0
                    message: Los datos enviados son inválidos.
                    object: request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: da79cc32-436a-4fd2-a96f-bb8e0ca8437c
  /v1/{company_id}/reports_datasets/{id}:
    get:
      operationId: showReportDataset
      tags:
        - Datasets de reportes
      summary: Obtener dataset de reportes
      description: |
        **¿Qué hace este endpoint?**

        Retorna un conjunto de datos de períodos (dataset) específicos
        de una empresa. Proporciona información estructurada de períodos de nómina,
        nómina electrónica, seguridad social, prestaciones sociales y rangos de
        fechas para la generación de reportes.

        **¿Cuándo usar este endpoint?**

        * Saber qué periodos de nómina tiene disponibles una empresa antes de consultar un reporte de nómina.
        * Saber qué periodos de prestaciones sociales (primas, cesantías, intereses) tiene disponibles una empresa antes de consultar un reporte de prestaciones.
        * Consultar el historial completo de fechas de los periodos de la empresa para validar rangos en reportes por fecha.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Estructura variable según tipo:** Los tipos de periodos retornan un arreglo `items` con cada periodo. Los tipos de prestaciones sociales incluyen además los campos del periodo especial asociado. El tipo de rango de fechas retorna dos arreglos (`from` y `to`) en lugar de `items`.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: |
            La estructura de la respuesta varía según el tipo solicitado y el modo de generación:

            - **Periodos de nómina, nómina electrónica o seguridad social**: retorna `data.items` con `period_id`, `initial_day`, `end_day` y `label`.
            - **Periodos de prestaciones sociales**: retorna `data.items` con los mismos campos anteriores más los campos del periodo especial (`special_period_id`, `special_period_initial_day`, `special_period_end_day`).
            - **Rango de fechas**: retorna `data.from` y `data.to` en lugar de `data.items`.
            - **Asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Periodos de nómina, nómina electrónica o seguridad social
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          dataset:
                            description: Tipo de periodos retornado, corresponde al valor de `{id}`.
                            type: string
                            example: payroll_periods
                          details:
                            description: Mensaje informativo cuando no hay registros disponibles. Vacío si hay registros.
                            type: string
                            example: ''
                          items:
                            description: Listado de periodos disponibles.
                            type: array
                            items:
                              type: object
                              properties:
                                period_id:
                                  description: Identificador único (ID) del periodo.
                                  type: string
                                  example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                                initial_day:
                                  description: Fecha inicial del periodo, en formato `YYYY-MM-DD`.
                                  type: string
                                  example: '2024-01-01'
                                end_day:
                                  description: Fecha final del periodo, en formato `YYYY-MM-DD`.
                                  type: string
                                  example: '2024-01-15'
                                label:
                                  description: Etiqueta legible del periodo.
                                  type: string
                                  example: 1–15-ene-2024
                  - type: object
                    description: Periodos de prestaciones sociales (primas, cesantías, intereses)
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          dataset:
                            description: Tipo de periodos retornado, corresponde al valor de `{id}`.
                            type: string
                            example: service_bonus_periods
                          details:
                            description: Mensaje informativo cuando no hay registros disponibles. Vacío si hay registros.
                            type: string
                            example: ''
                          items:
                            description: Listado de periodos de prestaciones disponibles.
                            type: array
                            items:
                              type: object
                              properties:
                                period_id:
                                  description: Identificador único (ID) del periodo de nómina asociado.
                                  type: string
                                  example: 640191cc-59a7-5090-b5e9-1036dc2053f9
                                special_period_id:
                                  description: Identificador único (ID) del periodo especial de prestación social.
                                  type: string
                                  example: 4a2b3c4d-5e6f-7890-abcd-ef1234567890
                                initial_day:
                                  description: Fecha inicial del periodo, en formato `YYYY-MM-DD`.
                                  type: string
                                  example: '2024-01-01'
                                end_day:
                                  description: Fecha final del periodo, en formato `YYYY-MM-DD`.
                                  type: string
                                  example: '2024-06-30'
                                special_period_initial_day:
                                  description: Fecha inicial del periodo especial de prestación social, en formato `YYYY-MM-DD`.
                                  type: string
                                  example: '2024-01-01'
                                special_period_end_day:
                                  description: Fecha final del periodo especial de prestación social, en formato `YYYY-MM-DD`.
                                  type: string
                                  example: '2024-06-30'
                                label:
                                  description: Etiqueta legible del periodo.
                                  type: string
                                  example: 2024-1 (1–30-jun-2024)
                  - type: object
                    description: Rango de fechas de todos los periodos
                    required:
                      - data
                    properties:
                      data:
                        type: object
                        properties:
                          dataset:
                            description: Tipo de periodos retornado, corresponde al valor de `{id}`.
                            type: string
                            example: date_range
                          details:
                            description: Mensaje informativo cuando no hay registros disponibles. Vacío si hay registros.
                            type: string
                            example: ''
                          from:
                            description: Fechas de inicio de todos los periodos de la empresa, en formato `YYYY-MM-DD`.
                            type: array
                            items:
                              type: string
                              example: '2024-01-01'
                          to:
                            description: Fechas de fin de todos los periodos de la empresa, en formato `YYYY-MM-DD`.
                            type: array
                            items:
                              type: string
                              example: '2024-01-15'
                  - type: object
                    description: Asíncrono
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento del dataset.
                        type: string
                        example: Procesando
              examples:
                Periodos de nómina:
                  value:
                    data:
                      dataset: payroll_periods
                      details: ''
                      items:
                        - period_id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          initial_day: '2024-01-01'
                          end_day: '2024-01-15'
                          label: 1–15-ene-2024
                        - period_id: 7a8b9c0d-1e2f-3456-abcd-ef1234567890
                          initial_day: '2024-01-16'
                          end_day: '2024-01-31'
                          label: 16–31-ene-2024
                Periodos de prestaciones:
                  value:
                    data:
                      dataset: service_bonus_periods
                      details: ''
                      items:
                        - period_id: 640191cc-59a7-5090-b5e9-1036dc2053f9
                          special_period_id: 4a2b3c4d-5e6f-7890-abcd-ef1234567890
                          initial_day: '2024-01-01'
                          end_day: '2024-06-30'
                          special_period_initial_day: '2024-01-01'
                          special_period_end_day: '2024-06-30'
                          label: 2024-1 (1–30-jun-2024)
                Rango de fechas:
                  value:
                    data:
                      dataset: date_range
                      details: ''
                      from:
                        - '2024-01-01'
                        - '2024-01-16'
                      to:
                        - '2024-01-15'
                        - '2024-01-31'
                Asíncrono:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Clave de dataset inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '6501'
                    index: 0
                    message: La clave del dataset no es válida.
                    object: report_dataset
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: |
          Tipo de periodos a retornar. Valores posibles:

          * `payroll_periods` — Periodos de nómina ordinaria
          * `electronic_payroll_periods` — Periodos de nómina electrónica
          * `social_security_periods` — Periodos de seguridad social
          * `service_bonus_periods` — Periodos de prima de servicios
          * `severance_periods` — Periodos de cesantías
          * `severance_interests_periods` — Periodos de intereses de cesantías
          * `date_range` — Fechas de inicio y fin de todos los periodos de la empresa
        schema:
          type: string
          enum:
            - payroll_periods
            - electronic_payroll_periods
            - social_security_periods
            - service_bonus_periods
            - severance_periods
            - severance_interests_periods
            - date_range
          example: payroll_periods
  /v1/{company_id}/send_import_workers_file:
    post:
      operationId: sendImportWorkersFile
      tags:
        - Importación masiva
      summary: Enviar archivo de importación por email
      description: |
        **¿Qué hace este endpoint?**

        Recibe un archivo de personas y lo envía por correo electrónico al equipo de Aleluya para que realice la importación manualmente.

        **¿Cuándo usar este endpoint?**

        * Solicitar soporte para importar personas enviando un archivo preparado externamente.
        * Enviar un archivo personalizado cuando el flujo de importación directa no aplica.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Formatos aceptados:** `.pdf`, `.txt`, `.xlsx`, `.csv` y `.xml`. Archivos con extensión inválida retornan 422.
        * **Tamaño máximo:** 5 MB. Archivos más grandes retornan 422.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  description: Archivo de personas a enviar por correo. Formatos aceptados .pdf, .txt, .xlsx, .csv y .xml. Tamaño máximo 5 MB.
                  type: string
                  format: binary
              required:
                - file
      responses:
        '200':
          description: Archivo enviado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del envío del archivo.
                        type: string
                        example: El archivo fue enviado correctamente. Estamos validando la información y pronto comenzaremos la importación.
              example:
                data:
                  message: El archivo fue enviado correctamente. Estamos validando la información y pronto comenzaremos la importación.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Archivo demasiado grande / Extensión inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Archivo demasiado grande:
                  value:
                    error:
                      - code: '0310'
                        index: 0
                        message: El archivo es muy grande. Su peso máximo debe ser 5 MB.
                        object: file
                Extensión inválida:
                  value:
                    error:
                      - code: '0315'
                        index: 0
                        message: 'El formato del archivo para importar personsas es inválido, la extensión del archivo debe ser alguno de los siguientes: .pdf, .txt, .xslx, .csv y .xml'
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: a1fa645d-cda3-4d24-a262-7876d2fd8745
  /v1/{company_id}/social_security_integration/forms:
    get:
      operationId: indexSocialSecurityIntegrationForms
      tags:
        - Integración con operador
      summary: Listar planillas de integración
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de planillas de seguridad social creadas en el operador de
        integración para la empresa, ordenadas por fecha de vencimiento.

        **¿Cuándo usar este endpoint?**

        * Consultar el historial de planillas enviadas al operador para un proveedor dado.
        * Verificar el estado y el valor de cada planilla antes de realizar el pago.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: provider
          required: false
          description: Proveedor del operador de integración a filtrar. `aportes_en_linea` para Aportes En Línea, `enlace` para Enlace Operativo.
          schema:
            type: string
            enum:
              - aportes_en_linea
              - enlace
            example: aportes_en_linea
      responses:
        '200':
          description: Listado de planillas obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Lista de planillas de integración de seguridad social.
                    type: array
                    items:
                      description: Datos de una planilla de integración de seguridad social.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la planilla en la base de datos.
                          type: string
                          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        deleteable:
                          description: Indica si la planilla puede ser eliminada. Es `true` cuando no tiene clave ni valor asignado.
                          type: boolean
                          example: false
                        period_id:
                          description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
                          type: string
                          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
                        period_payment_date:
                          description: Fecha de fin del periodo de nómina en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-01-31'
                        form_type:
                          description: Tipo de planilla. `employee` para empleados, `student_decree_055` para estudiantes bajo el Decreto 055.
                          type: string
                          enum:
                            - employee
                            - student_decree_055
                          example: employee
                        key:
                          description: Clave de la planilla asignada por el operador. Es `null` si aún no fue procesada.
                          type:
                            - string
                            - 'null'
                          example: '123456789'
                        value:
                          description: Valor total a pagar de la planilla en pesos colombianos. Es `null` si aún no está disponible.
                          type:
                            - number
                            - 'null'
                          example: 1500000
                        status:
                          description: Estado actual de la planilla. `created` recién creada, `pending` en proceso de pago, `paid` pagada, `declined` rechazada.
                          type: string
                          enum:
                            - created
                            - paid
                            - pending
                            - declined
                          example: created
                        payment_date:
                          description: Fecha y hora en que se realizó el pago de la planilla. Es `null` si no se ha pagado.
                          type:
                            - string
                            - 'null'
                          format: date-time
                          example: '2024-01-25T10:30:00.000Z'
                        due_date:
                          description: Fecha límite para el pago de la planilla. Es `null` si aún no está disponible.
                          type:
                            - string
                            - 'null'
                          example: '2024-02-05'
                        social_security_branch:
                          description: Sucursal de seguridad social asociada a la planilla.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la sucursal en la base de datos. Es `null` si no tiene sucursal asignada.
                              type:
                                - string
                                - 'null'
                              example: e387722c-4415-447a-9e32-9b166f848833
                            name:
                              description: Nombre de la sucursal. Es `null` si no tiene sucursal asignada.
                              type:
                                - string
                                - 'null'
                              example: Sucursal Norte
                            code:
                              description: Código numérico de la sucursal. Es `null` si no tiene sucursal asignada.
                              type:
                                - string
                                - 'null'
                              example: '001'
                  filters:
                    description: Información de paginación del listado.
                    type: object
                    properties:
                      total_records:
                        description: Total de planillas que coinciden con los filtros aplicados.
                        type: integer
                        example: 12
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Cantidad de planillas por página.
                        type: integer
                        example: 10
                      search:
                        description: Término de búsqueda aplicado. Cadena vacía si no se aplicó búsqueda.
                        type: string
                        example: ''
              example:
                data:
                  - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    deleteable: false
                    period_id: 86e4bbab-7a86-536e-85a0-2ac57955857d
                    period_payment_date: '2024-01-31'
                    form_type: employee
                    key: '123456789'
                    value: 1500000
                    status: paid
                    payment_date: '2024-01-25T10:30:00.000Z'
                    due_date: '2024-02-05'
                    social_security_branch:
                      id: e387722c-4415-447a-9e32-9b166f848833
                      name: Sucursal Norte
                      code: '001'
                filters:
                  total_records: 1
                  page: 1
                  per_page: 10
                  search: ''
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 77915ab5-e4d2-4f3b-abcb-be72bef867bd
  /v1/{company_id}/subscription:
    get:
      operationId: showSubscription
      tags:
        - Suscripción
      summary: Obtener suscripción
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información de la suscripción activa de la empresa. Según los parámetros enviados,
        también puede calcular el costo estimado de agregar personas adicionales o de hacer un upgrade de plan.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado actual de la suscripción de la empresa.
        * Verificar si hay un downgrade programado para el próximo periodo de facturación.
        * Calcular el costo de agregar personas extras a una suscripción anual.
        * Calcular el costo de cambiar de plan o de frecuencia de pago.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Estimación de costo de upgrade en suscripción anual:** Solo aplica para cambios a un plan superior o para agregar personas extras. Enviar `plan_id` para calcular el costo del cambio de plan, `extra_workers_number` para el costo de agregar personas extras, o ambos para calcular los dos a la vez. La respuesta incluye `additional_workers_info` con el resultado.

          Solo cambio de plan:
          ```curl
          curl -X GET "https://api.aleluya.com/v1/{company_id}/subscription?plan_id=<id>&extra_workers_number=0"
          ```

          Cambio de plan y personas extras:
          ```curl
          curl -X GET "https://api.aleluya.com/v1/{company_id}/subscription?plan_id=<id>&extra_workers_number=5"
          ```

        * **Estimación de costo de upgrade en suscripción mensual:** Solo aplica para cambios a un plan superior o cambio de frecuencia a anual. Requiere además `action_type=upgrade_info`.
          Para calcular el costo de cambiar también la frecuencia a anual, enviar adicionalmente
          `subscription_type=year`.

          Solo cambio de plan:
          ```curl
          curl -X GET "https://api.aleluya.com/v1/{company_id}/subscription?plan_id=<id>&extra_workers_number=0&action_type=upgrade_info"
          ```

          Cambio de plan y frecuencia a anual con personas extras:
          ```curl
          curl -X GET "https://api.aleluya.com/v1/{company_id}/subscription?plan_id=<id>&subscription_type=year&extra_workers_number=5&action_type=upgrade_info"
          ```

          Solo cambio de frecuencia a anual:
          ```curl
          curl -X GET "https://api.aleluya.com/v1/{company_id}/subscription?subscription_type=year&extra_workers_number=0&action_type=upgrade_info"
          ```

        * **Información de downgrade:** Con `action_type=downgrade_info`, retorna únicamente
          `downgrade_subscription_info` con el plan inferior, su valor y la fecha en que se aplicará
          el cambio. No incluye el resto de la información de suscripción.

          ```curl
          curl -X GET "https://api.aleluya.com/v1/{company_id}/subscription?action_type=downgrade_info"
          ```
      parameters:
        - in: query
          required: false
          name: plan_id
          description: Identificador único (ID) del plan al que se desea cambiar. Cuando se envía, la respuesta incluye `additional_workers_info` con el costo estimado del cambio.
          schema:
            type: string
            example: 4f2b8dce-8314-517f-9f47-a5f90adf71f9
        - in: query
          required: false
          name: extra_workers_number
          description: Número de personas adicionales a incluir en la estimación de costo. Si no se envía, la respuesta retorna la información de la suscripción sin estimación de costo adicional.
          schema:
            type: integer
            example: 5
        - in: query
          required: false
          name: subscription_type
          description: 'Frecuencia de pago a la que se desea cambiar. Valores posibles: `month` (mensual), `year` (anual).'
          schema:
            type: string
            enum:
              - month
              - year
            example: year
        - in: query
          required: false
          name: action_type
          description: 'Acción a ejecutar. Valores posibles: `upgrade_info` (información de upgrade en suscripciones mensuales), `downgrade_info` (información del próximo plan tras un downgrade programado).'
          schema:
            type: string
            enum:
              - upgrade_info
              - downgrade_info
            example: upgrade_info
      responses:
        '200':
          description: Información de suscripción / Información de downgrade programado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Información de la suscripción activa o del downgrade programado. La estructura varía según el parámetro `action_type`.
                    oneOf:
                      - description: Respuesta estándar de suscripción. Retornada cuando `action_type` no es `downgrade_info`.
                        type: object
                        required:
                          - type
                        properties:
                          type:
                            description: 'Tipo de suscripción de la empresa. Valores posibles: `month` (mensual), `year` (anual).'
                            type: string
                            example: year
                          partner:
                            description: Indica si la empresa es partner de Aleluya.
                            type: boolean
                            example: false
                          month_value:
                            description: Valor mensual de la suscripción en pesos colombianos.
                            type: integer
                            example: 29900
                          year_value:
                            description: Valor anual de la suscripción en pesos colombianos.
                            type: integer
                            example: 322920
                          active_until:
                            description: Fecha hasta la cual está activa la suscripción.
                            type: string
                            format: date
                            example: '2024-08-02'
                          payrolls_size:
                            description: Número de personas activas en la empresa.
                            type: integer
                            example: 5
                          payment_category:
                            description: 'Categoría del método de pago principal. Ejemplo: `credit_card`, `automatic_debit`.'
                            type: string
                            example: credit_card
                          plan_category:
                            description: Categoría interna del plan de la empresa.
                            type: string
                            example: per_worker_plan20230710
                          paid_workers:
                            description: Número de personas pagadas en la suscripción actual.
                            type: integer
                            example: 5
                          distributor:
                            description: Información del distribuidor y los descuentos aplicados a la suscripción.
                            type: object
                            properties:
                              name:
                                description: Nombre del distribuidor.
                                type: string
                                example: Aleluya
                              month_discount:
                                description: Valor del descuento mensual en pesos colombianos aplicado por el distribuidor.
                                type: integer
                                example: 0
                              year_discount:
                                description: Valor del descuento anual en pesos colombianos aplicado por el distribuidor.
                                type: integer
                                example: 35880
                              has_distributor_discount:
                                description: Indica si la empresa tiene un precio personalizado activo configurado por su distribuidor.
                                type: boolean
                                example: true
                              distributor_discount_months:
                                description: Número de meses restantes del descuento del distribuidor. Null si no hay descuento activo.
                                type:
                                  - integer
                                  - 'null'
                                example: 6
                              has_early_payment_discount:
                                description: Indica si la empresa aplica al descuento por pago anticipado.
                                type: boolean
                                example: true
                          payment_methods:
                            description: Métodos de pago habilitados para la empresa. Solo incluye los métodos activos; los desactivados no aparecen en el objeto.
                            type: object
                            properties:
                              credit_card:
                                description: Indica si la empresa tiene habilitado el pago con tarjeta de crédito. Solo aparece en el objeto si está activo.
                                type: boolean
                                example: true
                              automatic_debit:
                                description: Indica si la empresa tiene habilitado el pago por débito automático. Solo aparece en el objeto si está activo.
                                type: boolean
                                example: true
                              pse:
                                description: Indica si la empresa tiene habilitado el pago por PSE. Solo aparece en el objeto si está activo.
                                type: boolean
                                example: true
                          plan:
                            description: Información del plan activo de la empresa.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al plan en la base de datos.
                                type: string
                                example: f7605220-ac98-5048-a068-e02a6b8fccb0
                              coded_name:
                                description: Nombre codificado del plan.
                                type: string
                                example: nominapp_plan_unipersonal
                              name:
                                description: Nombre legible del plan.
                                type: string
                                example: Plan Básico
                              description:
                                description: Descripción del plan.
                                type: string
                                example: Unipersonal (1 persona)
                          status:
                            description: |
                              Estado actual de la suscripción. Valores posibles:

                              * `free` — empresa en plan gratuito sin suscripción activa.
                              * `premium_trial` — empresa en periodo de prueba.
                              * `premium_due` — suscripción vencida, pendiente de pago.
                              * `active_premium` — suscripción activa.
                              * `active_premium_full` — suscripción full activa.
                              * `premium_expired` — suscripción expirada.
                              * `premium_canceled` — suscripción cancelada.
                              * `exonerated_payment` — empresa exonerada de pago.
                            type: string
                            example: active_premium
                          payment_status:
                            description: Estado del último pago de la suscripción.
                            type: string
                            example: approved
                          additional_workers_info:
                            description: Estimación del costo de cambio de plan o de agregar personas adicionales. Null si no se enviaron `plan_id` ni `extra_workers_number`.
                            type:
                              - object
                              - 'null'
                            properties:
                              add_workers:
                                description: Indica si la empresa puede agregar personas adicionales. `false` cuando ya alcanzó el límite o no cumple las condiciones.
                                type: boolean
                                example: true
                              extra_workers_number:
                                description: Número de personas adicionales sobre las que se calculó el costo.
                                type: integer
                                example: 3
                              plan_id:
                                description: Identificador único (ID) del plan usado como referencia para el cálculo en la base de datos.
                                type: string
                                example: 4f2b8dce-8314-517f-9f47-a5f90adf71f9
                              subscription_initial_day:
                                description: Fecha de inicio del periodo de facturación activo, usado para calcular el valor proporcional a pagar.
                                type: string
                                format: date
                                example: '2023-04-01'
                              subscription_end_day:
                                description: Fecha de fin del periodo de facturación activo, usado para calcular el valor proporcional a pagar.
                                type: string
                                format: date
                                example: '2024-04-01'
                              discount_category:
                                description: Tipo de descuento aplicado al cálculo. Siempre es `percentage` (porcentaje sobre el valor).
                                type: string
                                example: percentage
                              discount_value:
                                description: Porcentaje de descuento aplicado expresado como decimal (ej. `0.1` equivale al 10%).
                                type: number
                                example: 0.1
                              extra_workers_value:
                                description: Valor total estimado a pagar en pesos colombianos, calculado de forma proporcional al tiempo restante del periodo. Puede incluir el costo por personas adicionales, la diferencia entre planes, o ambos.
                                type: integer
                                example: 904400
                              minimum_payment_value:
                                description: Valor mínimo de pago aceptado en pesos colombianos. Si `extra_workers_value` es menor que este valor, el pago no puede procesarse.
                                type: integer
                                example: 9662
                          premium_trial_end_date:
                            description: Fecha de finalización del periodo de prueba. Null si no aplica.
                            type:
                              - string
                              - 'null'
                            format: date
                            example: '2024-08-02'
                          company_access:
                            $ref: '#/components/schemas/CompanyAccess'
                          utm_campaign:
                            description: Código de campaña con el que se registró la empresa. Null si no aplica.
                            type:
                              - string
                              - 'null'
                            example: Aleluya10mil
                          subscription_payment_methods_info:
                            description: Listado de métodos de pago registrados por la empresa para su suscripción.
                            type: array
                            items:
                              type: object
                              properties:
                                category:
                                  description: 'Tipo de método de pago. Valores posibles: `credit_card` (tarjeta de crédito), `automatic_debit` (débito automático).'
                                  type: string
                                  example: automatic_debit
                                main_payment_method:
                                  description: Indica si este es el método principal de pago de la empresa.
                                  type: boolean
                                  example: true
                                automatic_debit_account_last_numbers:
                                  description: Últimos 4 dígitos de la cuenta de débito automático. Solo presente cuando `category` es `automatic_debit`.
                                  type: string
                                  example: ...3456
                                automatic_debit_bank:
                                  description: Nombre del banco de la cuenta de débito automático. Solo presente cuando `category` es `automatic_debit`.
                                  type: string
                                  example: Bancolombia
                                automatic_debit_account_status:
                                  description: Estado de la cuenta de débito automático. Solo presente cuando `category` es `automatic_debit`.
                                  type: string
                                  example: approved
                                automatic_debit_rejected_comment:
                                  description: Motivo de rechazo de la cuenta. Solo presente cuando `category` es `automatic_debit`.
                                  type:
                                    - string
                                    - 'null'
                                  example: La cuenta especificada ha sido cerrada.
                                credit_card_brand:
                                  description: Marca de la tarjeta de crédito. Solo presente cuando `category` es `credit_card`.
                                  type: string
                                  example: VISA
                                credit_card_last_numbers:
                                  description: Últimos 4 dígitos de la tarjeta de crédito. Solo presente cuando `category` es `credit_card`.
                                  type: string
                                  example: ...1234
                          additional_downgrade_info:
                            description: Información del cambio a un plan inferior programado. Null si no hay ninguno programado.
                            type:
                              - object
                              - 'null'
                            properties:
                              current_type:
                                description: 'Frecuencia de pago del plan inferior al que cambiará la empresa. Valores posibles: `month` (mensual), `year` (anual).'
                                type: string
                                example: month
                              date:
                                description: Fecha en que se aplicará el cambio al plan inferior.
                                type: string
                                format: date
                                example: '2024-09-01'
                              plan:
                                description: Nombre del plan inferior al que cambiará la empresa.
                                type: string
                                example: Plan Básico
                              plan_value:
                                description: Valor mensual del plan inferior en pesos colombianos.
                                type: integer
                                example: 49900
                      - description: Respuesta de downgrade. Retornada cuando se envía `action_type=downgrade_info`.
                        type: object
                        required:
                          - downgrade_subscription_info
                        properties:
                          downgrade_subscription_info:
                            description: Información del plan al que cambiará la empresa tras el downgrade programado.
                            type: object
                            properties:
                              current_type:
                                description: 'Frecuencia de pago del plan inferior. Valores posibles: `month` (mensual), `year` (anual).'
                                type: string
                                example: month
                              date:
                                description: Fecha en que se aplicará el cambio al plan inferior.
                                type: string
                                format: date
                                example: '2024-09-01'
                              plan:
                                description: Nombre del plan inferior al que cambiará la empresa.
                                type: string
                                example: Plan Básico
                              plan_value:
                                description: Valor mensual del plan inferior en pesos colombianos.
                                type: integer
                                example: 49900
                required:
                  - data
              examples:
                Información de suscripción:
                  value:
                    data:
                      type: year
                      partner: false
                      month_value: 29900
                      year_value: 322920
                      active_until: '2024-08-02'
                      payrolls_size: 5
                      payment_category: credit_card
                      plan_category: per_worker_plan20230710
                      paid_workers: 5
                      distributor:
                        name: Aleluya
                        month_discount: 0
                        year_discount: 35880
                        has_distributor_discount: true
                        distributor_discount_months: null
                        has_early_payment_discount: false
                      payment_methods:
                        credit_card: true
                      plan:
                        id: f7605220-ac98-5048-a068-e02a6b8fccb0
                        coded_name: plan_basico
                        name: Plan Básico
                        description: Básico (5 personas)
                      status: active_premium
                      payment_status: approved
                      additional_workers_info:
                        add_workers: true
                        extra_workers_number: 3
                        plan_id: 4f2b8dce-8314-517f-9f47-a5f90adf71f9
                        subscription_initial_day: '2024-01-01'
                        subscription_end_day: '2025-01-01'
                        discount_category: percentage
                        discount_value: 0.1
                        extra_workers_value: 904400
                        minimum_payment_value: 9662
                      premium_trial_end_date: null
                      company_access: premium_full
                      utm_campaign: null
                      subscription_payment_methods_info:
                        - category: credit_card
                          main_payment_method: true
                          credit_card_brand: VISA
                          credit_card_last_numbers: ...7921
                      additional_downgrade_info: null
                Información de downgrade programado:
                  value:
                    data:
                      downgrade_subscription_info:
                        current_type: month
                        date: '2024-09-01'
                        plan: Plan Básico
                        plan_value: 49900
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateSubscription
      tags:
        - Suscripción
      summary: Actualizar suscripción
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el plan y/o la frecuencia de pago de la suscripción de la empresa.
        El cambio de plan y el cambio de frecuencia se evalúan de forma independiente:

        * **Plan:** puede ser upgrade (plan de mayor valor) o downgrade (plan de menor valor).
        * **Frecuencia:** puede ser upgrade (de mensual a anual) o downgrade (de anual a mensual).
        * También puede haber cambios mixtos (por ejemplo, subir de plan y pasar de anual a mensual en la misma solicitud).

        También permite activar el periodo de prueba cuando la empresa no está asociada a un partner.

        **¿Cuándo usar este endpoint?**

        * Cambiar la empresa a un plan superior o inferior.
        * Cambiar la frecuencia de pago de mensual a anual o viceversa.
        * Activar el periodo de prueba.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Periodo de prueba:** Solo se puede activar en empresas que no están asociadas a un partner. Si la empresa está asociada a partner, retorna 422.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                plan_id:
                  description: Identificador único (ID) del nuevo plan al que se desea cambiar.
                  type: string
                  example: 4f2b8dce-8314-517f-9f47-a5f90adf71f9
                subscription_type:
                  description: 'Nueva frecuencia de pago. Valores posibles: `month` (mensual), `year` (anual).'
                  type: string
                  enum:
                    - month
                    - year
                  example: year
                extra_workers_number:
                  description: Número de personas extras a incluir en el cambio de suscripción. Se usa al hacer upgrade para calcular el costo proporcional del periodo restante.
                  type: integer
                  example: 3
                active_premium_trial:
                  description: Indica si se desea activar el periodo de prueba. Solo aplica en empresas que no están asociadas a un partner.
                  type: boolean
                  example: false
      responses:
        '202':
          description: Suscripción actualizada / Periodo de prueba activado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la actualización de la suscripción.
                    type: object
                    properties:
                      active_until:
                        description: Fecha hasta la cual está activa la suscripción actualizada.
                        type: string
                        format: date
                        example: '2025-08-02'
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 2ade05cb-d781-4826-bc0f-425f3bbe6ca0
                      payrolls_size:
                        description: Número de personas activas en la empresa tras la actualización.
                        type: integer
                        example: 5
                      plan:
                        description: Nombre del nuevo plan de la empresa.
                        type: string
                        example: Full Juguetes
                      plan_value:
                        description: Valor del nuevo plan en pesos colombianos.
                        type: integer
                        example: 99900
                      subscription_type:
                        description: 'Frecuencia de pago resultante. Valores posibles: `month` (mensual), `year` (anual).'
                        type: string
                        example: year
                      plan_id:
                        description: Identificador único (ID) del plan asignado. Solo presente cuando se activa el periodo de prueba.
                        type: string
                        example: f7605220-ac98-5048-a068-e02a6b8fccb0
                required:
                  - data
              examples:
                Suscripción actualizada:
                  value:
                    data:
                      active_until: '2025-08-02'
                      company_id: 2ade05cb-d781-4826-bc0f-425f3bbe6ca0
                      payrolls_size: 5
                      plan: Full Juguetes
                      plan_value: 99900
                      subscription_type: year
                Periodo de prueba activado:
                  value:
                    data:
                      company_id: 2ade05cb-d781-4826-bc0f-425f3bbe6ca0
                      plan_id: f7605220-ac98-5048-a068-e02a6b8fccb0
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Empresa no elegible para el periodo de prueba / Cambio de suscripción no permitido / Cambio ya existente en el ciclo / Mismo día con cambio registrado / Plan emprendedor no aplica
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Empresa no elegible para el periodo de prueba:
                  value:
                    error:
                      - code: '2101'
                        index: 0
                        message: No puedes acceder al periodo de prueba.
                        object: company
                Cambio de suscripción no permitido:
                  value:
                    error:
                      - code: '3902'
                        index: 0
                        message: Lo sentimos. No puedes realizar cambios a tu suscripción. Contacta a soporte para realizar este ajuste.
                        object: subscriptions
                Cambio ya existente en el ciclo:
                  value:
                    error:
                      - code: '3901'
                        index: 0
                        message: Lo sentimos. Solo puedes realizar un cambio a tu suscripción por ciclo de facturación. Espera al próximo ciclo para realizar los cambios que necesitas.
                        object: subscriptions
                Mismo día con cambio registrado:
                  value:
                    error:
                      - code: '3903'
                        index: 0
                        message: Lo sentimos. No puedes realizar varios cambios a tu suscripción durante el mismo día.
                        object: subscriptions
                Plan emprendedor no aplica con descuento activo:
                  value:
                    error:
                      - code: '3904'
                        index: 0
                        message: El plan emprendedor no aplica para empresas con descuento activo por aliado.
                        object: subscriptions
    parameters:
      - name: company_id
        in: path
        required: true
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 2ade05cb-d781-4826-bc0f-425f3bbe6ca0
  /v1/{company_id}/subscription_cancellation:
    put:
      operationId: updateSubscriptionCancellation
      tags:
        - Suscripción
      summary: Cancelar suscripción
      description: |
        **¿Qué hace este endpoint?**

        Cancela la suscripción activa de la empresa, programando el fin del servicio al término del periodo actual.

        **¿Cuándo usar este endpoint?**

        * Procesar la solicitud de cancelación cuando la empresa decide darse de baja.
        * Registrar el motivo de cancelación para seguimiento interno.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago pendiente:** No se puede cancelar la suscripción si el pago actual está en estado pendiente. En ese caso retorna 422.
        * **Campo `comment`:** Es obligatorio cuando `reason` es `another_reason` (mínimo 10 caracteres, máximo 300).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                subscription_cancellation:
                  description: Datos de la solicitud de cancelación de la suscripción.
                  type: object
                  properties:
                    reason:
                      description: |
                        Motivo principal de la cancelación de suscripción.

                        Valores posibles:

                        * `economic_reasons` — Razones económicas.
                        * `missing_features` — Faltan funcionalidades necesarias.
                        * `no_workers` — La empresa ya no tiene empleados.
                        * `company_closes` — La empresa cierra operaciones.
                        * `another_reason` — Otro motivo no listado.
                        * `switching_competitor` — Migración a otra plataforma de nómina.
                        * `poor_support` — Insatisfacción con el soporte recibido.
                        * `outsourced_payroll` — La nómina se terceriza con un proveedor externo.
                      type: string
                      enum:
                        - economic_reasons
                        - missing_features
                        - no_workers
                        - company_closes
                        - another_reason
                        - switching_competitor
                        - poor_support
                        - outsourced_payroll
                      example: economic_reasons
                    comment:
                      description: |
                        Comentario sobre la cancelación. Obligatorio cuando `reason` es `another_reason`
                        (entre 10 y 300 caracteres). Opcional para el resto de motivos (hasta 300 caracteres).
                      type: string
                      maxLength: 300
                      example: No puedo seguir pagando el plan actual.
                    phone:
                      description: Número de teléfono de contacto de la empresa.
                      type: string
                      example: '3204589658'
                    next_payment_date:
                      description: Fecha del próximo pago de referencia.
                      type: string
                      format: date
                      example: '2025-06-10'
                  required:
                    - reason
              required:
                - subscription_cancellation
      responses:
        '202':
          description: Suscripción cancelada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la cancelación de la suscripción.
                    type: object
                    properties:
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 56e06d90-0244-5866-9b2a-af6df5418eee
                      active_subscription:
                        description: Indica si la empresa tiene una suscripción activa tras la cancelación.
                        type: boolean
                        example: false
                    required:
                      - company_id
                      - active_subscription
                required:
                  - data
              example:
                data:
                  company_id: 56e06d90-0244-5866-9b2a-af6df5418eee
                  active_subscription: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Pago actual en estado pendiente
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '3502'
                    index: 0
                    message: El pago actual está en estado pendiente. No se puede cancelar la suscripción hasta tener respuesta del pago.
                    object: payment
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: cded4bb9-61e4-4e6f-b43e-bfde500cd8b2
  /v1/{company_id}/total_workers:
    get:
      operationId: indexTotalWorkers
      tags:
        - Personas
      summary: Listar total de personas por categoría
      description: |
        **¿Qué hace este endpoint?**

        Retorna el conteo de personas de la empresa agrupado por tipo de contrato y estado, incluyendo el total general.

        **¿Cuándo usar este endpoint?**

        * Mostrar en la vista de personas el número de personas por cada categoría disponible antes de aplicar filtros.
        * Saber cuántas personas activas, liquidadas o sin registro terminado tiene la empresa antes de ejecutar operaciones masivas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Totales de personas por categoría
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de categorías de personas con su conteo respectivo.
                    type: array
                    items:
                      type: object
                      properties:
                        coded_name:
                          description: Código identificador de la categoría. Corresponde a los valores válidos del filtro del endpoint de listado de personas.
                          type: string
                          example: active
                        name:
                          description: Nombre legible de la categoría en español.
                          type: string
                          example: Activos
                        size:
                          description: Número de personas que pertenecen a esta categoría.
                          type: integer
                          example: 20
              example:
                data:
                  - coded_name: all
                    name: Todos
                    size: 23
                  - coded_name: active
                    name: Activos
                    size: 20
                  - coded_name: employee
                    name: Empleados
                    size: 7
                  - coded_name: part_time_contract
                    name: Tiempo parcial
                    size: 1
                  - coded_name: apprentice
                    name: Aprendices
                    size: 2
                  - coded_name: student
                    name: Estudiantes
                    size: 5
                  - coded_name: contractor
                    name: Contratistas
                    size: 3
                  - coded_name: not_finished
                    name: Sin terminar registro
                    size: 2
                  - coded_name: terminated_worker
                    name: Liquidados
                    size: 3
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: fe9d7ba9-f8b9-4039-95b9-854e8838de73
  /v1/{company_id}/users:
    get:
      operationId: indexUsers
      tags:
        - Usuarios
      summary: Listar usuarios de la empresa
      description: |
        **¿Qué hace este endpoint?**

        Devuelve el listado paginado de usuarios con acceso a la empresa (nombre mostrado, correo, rol, teléfono,
        estado y si el acceso puede eliminarse), con filtros por rol, estado y búsqueda por texto.

        **¿Cuándo usar este endpoint?**

        * Administrar o auditar quién tiene acceso a la empresa y con qué rol.
        * Filtrar por usuarios activos o inactivos, o por rol (administrador, contador, revisor o persona).
        * Buscar por fragmento de nombre o correo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer). La persona (worker) no puede listar usuarios.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca por nombre completo o correo electrónico del usuario. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: name_1
        - in: query
          name: filter
          required: false
          description: Filtra por rol del acceso en la empresa. Si no es un valor admitido, se omite el filtro de rol.
          schema:
            $ref: '#/components/schemas/UserAccessRole'
        - in: query
          name: status
          required: false
          description: Filtra por estado del acceso (activo o inactivo).
          schema:
            type: string
            enum:
              - active
              - inactive
            example: active
      responses:
        '200':
          description: Listado de usuarios obtenido correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Usuarios con acceso a la empresa, ordenados con activos primero y luego por nombre.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al usuario en la base de datos.
                          type: string
                          example: 83287bfa-e85b-5aa6-97cb-a07b9eaaf418
                        name:
                          description: Nombre mostrado (persona vinculada en la empresa o nombre del usuario).
                          type: string
                          example: Juan Pérez
                        email:
                          description: Correo electrónico del usuario.
                          type: string
                          example: usuario@ejemplo.com
                        role:
                          description: Rol del acceso del usuario en esta empresa.
                          $ref: '#/components/schemas/UserAccessRole'
                        phone:
                          description: Teléfono de contacto del usuario. Puede ser una cadena vacía si no está definido.
                          type: string
                          example: '3000000000'
                        active:
                          description: Indica si el acceso del usuario a la empresa está activo.
                          type: boolean
                          example: true
                        deleteable:
                          description: Indica si el acceso puede eliminarse vía API; es `false` para el usuario autenticado (no se puede eliminar a uno mismo).
                          type: boolean
                          example: true
                  filters:
                    description: Metadatos de paginación y filtros aplicados (incluye estado y categoría de rol).
                    type: object
                    properties:
                      filter:
                        description: Rol filtrado o `All` si no se aplicó filtro de rol válido.
                        type: string
                        example: All
                      status:
                        description: Estado filtrado (`active`, `inactive`) o `All` si no se envió `status`.
                        type: string
                        example: All
                      total_records:
                        description: Total de registros que cumplen los filtros antes de paginar.
                        type: integer
                        example: 9
                      page:
                        description: Página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Registros por página (máximo 50).
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda enviado; cadena vacía si no se buscó.
                        type: string
                        example: ''
              example:
                data:
                  - id: 83287bfa-e85b-5aa6-97cb-a07b9eaaf418
                    name: Juan Pérez
                    email: usuario@ejemplo.com
                    role: admin
                    phone: '3000000000'
                    active: true
                    deleteable: true
                filters:
                  filter: All
                  status: All
                  total_records: 9
                  page: 1
                  per_page: 20
                  search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createUser
      tags:
        - Usuarios
      summary: Crear usuario de empresa
      description: |
        **¿Qué hace este endpoint?**

        Crea un nuevo acceso de usuario a la empresa: registra un usuario nuevo o asocia un correo ya existente
        y le asigna rol (administrador, contador o revisor). No permite crear accesos con rol persona (`worker`).

        **¿Cuándo usar este endpoint?**

        * Invitar a un administrador o contador a la empresa.
        * Dar acceso de revisor a un usuario existente con ese correo.

        **Consideraciones importantes**

        * **Accesos:** El usuario autenticado debe tener acceso a la empresa en `{company_id}` con permiso de edición. El revisor (reviewer) no puede crear usuarios. La persona (worker) no puede crear usuarios.
        * **Correo duplicado en la empresa:** Si el correo ya tiene acceso a la empresa, la solicitud falla.
        * **Límite de usuarios sin suscripción:** Las empresas sin suscripción activa solo pueden tener un administrador o contador. Si ya existe uno, la respuesta es `402`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user:
                  description: Datos del usuario a invitar o asociar.
                  type: object
                  properties:
                    email:
                      description: Correo electrónico del usuario. Debe ser único a nivel global de usuario y no duplicar acceso en la misma empresa.
                      type: string
                      format: email
                      example: nuevo.usuario@ejemplo.com
                    role:
                      description: Rol del acceso en la empresa. No puede ser `worker`.
                      type: string
                      enum:
                        - admin
                        - accountant
                        - reviewer
                      example: admin
                    name:
                      description: Nombre completo del usuario.
                      type: string
                      example: María González
                    phone:
                      description: Teléfono celular colombiano (10 dígitos numéricos) si se envía.
                      type: string
                      pattern: ^[0-9]{10}$
                      example: '3001234567'
                    area:
                      $ref: '#/components/schemas/UserArea'
                    area_other_info:
                      description: Texto cuando el área es `other` (longitud y formato validados en servidor).
                      type: string
                      example: Auxiliar administrativo
                    password:
                      description: 'Contraseña inicial codificada en Base64. Debe cumplir los requisitos de seguridad: mínimo 8 caracteres, al menos una mayúscula, una minúscula, un número y un carácter especial. Si se omite, el sistema genera una contraseña segura y la envía al usuario por correo.'
                      type: string
                      example: cGFzc3dvcmQxMkEh
                    invited_from_registry:
                      description: Indica si el usuario fue invitado durante el proceso de registro de la empresa.
                      type: boolean
                      example: false
                  required:
                    - email
                    - role
              required:
                - user
      responses:
        '200':
          description: Usuario creado o asociado correctamente; cuerpo con datos del usuario y del acceso.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Usuario y acceso creados en la empresa.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al usuario en la base de datos.
                        type: string
                        example: f6a81e98-5f25-4000-a8c8-bbbaa58671b6
                      area:
                        description: Área del usuario. Es null si no se asignó.
                        oneOf:
                          - $ref: '#/components/schemas/UserArea'
                          - type: 'null'
                      active:
                        description: Estado del acceso a la empresa (activo al crear).
                        type: boolean
                        example: true
                      email:
                        description: Correo electrónico del usuario.
                        type: string
                        example: admin.prueba@ejemplo.com
                      name:
                        description: Nombre del usuario.
                        type: string
                        example: Admin
                      role:
                        description: Rol del acceso en la empresa.
                        $ref: '#/components/schemas/UserAccessRole'
              example:
                data:
                  id: f6a81e98-5f25-4000-a8c8-bbbaa58671b6
                  area: hr
                  active: true
                  email: admin.prueba@ejemplo.com
                  name: Admin
                  role: admin
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Rol inválido o no permitido / Correo duplicado en la empresa / Validaciones de modelo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Rol no permitido (worker):
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Rol es inválido.
                        object: user
                Correo ya asociado a la empresa:
                  value:
                    error:
                      - code: '0004'
                        index: 0
                        message: Ya existe un usuario con este email.
                        object: user
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/users/{id}:
    patch:
      operationId: updateUser
      tags:
        - Usuarios
      summary: Actualizar usuario de empresa
      description: |
        **¿Qué hace este endpoint?**

        Actualiza datos del usuario y de su acceso a la empresa (rol, activo/inactivo, nombre, correo, teléfono, área).

        **¿Cuándo usar este endpoint?**

        * Cambiar rol o estado de un colaborador con acceso a la empresa.
        * Actualizar teléfono u otros datos de contacto o de área.

        **Consideraciones importantes**

        * **Accesos:** Administrador (admin) o contador (accountant) pueden actualizar usuarios según las reglas de negocio. El revisor (reviewer) solo puede actualizar **su propio** registro (mismo `{id}` que el usuario autenticado). La persona (worker) no puede usar este endpoint.
        * **Restricciones:** No se puede pasar el propio usuario a rol `worker` desde admin; no se puede inactivar el propio usuario.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user:
                  description: Campos a actualizar; solo se modifican los atributos enviados.
                  type: object
                  properties:
                    active:
                      description: Activa o inactiva el acceso del usuario a la empresa.
                      type: boolean
                      example: true
                    area:
                      $ref: '#/components/schemas/UserArea'
                    area_other_info:
                      description: Detalle cuando el área es `other`.
                      type: string
                      minLength: 5
                      maxLength: 60
                      example: Auxiliar administrativo
                    email:
                      description: Nuevo correo del usuario. Debe ser único en el sistema.
                      type: string
                      format: email
                      minLength: 4
                      maxLength: 254
                      example: actualizado@ejemplo.com
                    name:
                      description: Nombre completo del usuario.
                      type: string
                      pattern: ^[0-9a-zA-ZÑñáéíóúüÁÉÍÓÚ&\-_ ]+$
                      example: Pedro Gómez
                    phone:
                      description: Teléfono celular colombiano de 10 dígitos.
                      type: string
                      pattern: ^3(0[0-9]|1[0-9]|2[0-4]|33|50|51)[0-9]{7}$
                      example: '3001234567'
                    role:
                      description: Nuevo rol del acceso en la empresa.
                      allOf:
                        - $ref: '#/components/schemas/UserAccessRole'
                    password:
                      description: Nueva contraseña en Base64, si aplica el flujo de cambio de contraseña.
                      type: string
                      example: cGFzc3dvcmQxMkEh
                    invited_from_registry:
                      description: Bandera de contexto de registro para validaciones de plan.
                      type: boolean
                      example: false
              required:
                - user
      responses:
        '200':
          description: Usuario actualizado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados del usuario y del acceso en la empresa.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al usuario en la base de datos.
                        type: string
                        example: 731843e9-0fc9-5e81-ae36-41e72e9dcc43
                      area:
                        oneOf:
                          - $ref: '#/components/schemas/UserArea'
                          - type: 'null'
                        description: Área funcional del usuario en la empresa. Es `null` si no fue especificada.
                      active:
                        description: Indica si el acceso a la empresa está activo.
                        type: boolean
                        example: true
                      email:
                        description: Correo electrónico del usuario.
                        type: string
                        example: usuario@ejemplo.com
                      name:
                        description: Nombre del usuario.
                        type: string
                        example: Admin
                      role:
                        description: Rol del acceso en la empresa.
                        allOf:
                          - $ref: '#/components/schemas/UserAccessRole'
              example:
                data:
                  id: 731843e9-0fc9-5e81-ae36-41e72e9dcc43
                  area: hr
                  active: false
                  email: usuario@ejemplo.com
                  name: Admin
                  role: admin
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Rol inválido / No puede inactivarse a sí mismo / No puede cambiarse el rol / Validaciones
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                No puede cambiar el rol propio a worker:
                  value:
                    error:
                      - code: '1602'
                        index: 0
                        message: No es posible cambiar el rol de tu usuario.
                        object: user
                No puede inactivarse a sí mismo:
                  value:
                    error:
                      - code: '1603'
                        index: 0
                        message: No es posible inactivar tu usuario.
                        object: user
    delete:
      operationId: destroyUser
      tags:
        - Usuarios
      summary: Eliminar acceso de usuario
      description: |
        **¿Qué hace este endpoint?**

        Elimina el acceso del usuario indicado a la empresa (y gestiona la relación de usuario según la lógica interna).

        **¿Cuándo usar este endpoint?**

        * Quitar a un colaborador el acceso a la empresa cuando ya no debe operar en ella.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Restricción:** No es posible eliminar el propio usuario autenticado.
      responses:
        '200':
          description: Acceso eliminado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje confirmando la eliminación del acceso.
                        type: string
                        example: Se ha eliminado el acceso a este usuario.
              example:
                data:
                  message: Se ha eliminado el acceso a este usuario.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: No se puede eliminar el usuario actual
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '1601'
                    index: 0
                    message: No se puede eliminar el usuario actual.
                    object: user
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) del usuario cuyo acceso se actualiza o elimina (no es el ID del `user_access`).
        schema:
          type: string
          example: 731843e9-0fc9-5e81-ae36-41e72e9dcc43
  /v1/{company_id}/wages/{id}:
    patch:
      operationId: updateWage
      tags:
        - Salarios
      summary: Actualizar salario
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los datos del salario vigente de un contrato laboral.

        **¿Cuándo usar este endpoint?**

        * Corregir el monto del salario base registrado incorrectamente.
        * Ajustar la modalidad salarial o la fecha de inicio del salario actual.
        * Activar o desactivar el teletrabajo o el auxilio de transporte del salario vigente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Contrato liquidado:** No es posible editar el salario de un contrato ya liquidado.
        * **Solo salario actual:** Únicamente se puede editar el salario vigente del contrato.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                wage:
                  description: Objeto con los campos del salario a actualizar.
                  type: object
                  properties:
                    base_salary:
                      description: Monto del salario base en pesos colombianos (COP).
                      type: integer
                      example: 2800000
                    category:
                      $ref: '#/components/schemas/SalaryCategory'
                    initial_day:
                      description: Fecha de inicio de vigencia del salario en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-01-01'
                    end_day:
                      description: Fecha de fin de vigencia del salario en formato YYYY-MM-DD. Null si es el salario vigente.
                      type:
                        - string
                        - 'null'
                      example: '2024-12-31'
                    remote_work:
                      description: Indica si la persona trabaja de forma remota (teletrabajo).
                      type: boolean
                      example: false
                    transport_subsidy:
                      description: Indica si la persona tiene derecho al auxilio de transporte.
                      type: boolean
                      example: true
              required:
                - wage
      responses:
        '202':
          description: Salario actualizado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con los datos actualizados del salario.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al salario en la base de datos.
                        type: string
                        example: 43541d40-259f-52e3-9f78-31f966b0e828
                      base_salary:
                        description: Monto del salario base en pesos colombianos (COP).
                        type: integer
                        example: 2800000
                      category:
                        $ref: '#/components/schemas/SalaryCategory'
                      initial_day:
                        description: Fecha de inicio de vigencia del salario en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin de vigencia del salario en formato YYYY-MM-DD. Null si es el salario vigente.
                        type:
                          - string
                          - 'null'
                        example: null
                      editable:
                        description: Indica si el salario puede ser editado.
                        type: boolean
                        example: true
                      deleteable:
                        description: Indica si el salario puede ser eliminado.
                        type: boolean
                        example: false
                      remote_work:
                        description: Indica si la persona trabaja de forma remota (teletrabajo).
                        type: boolean
                        example: false
                      transport_subsidy:
                        description: Indica si la persona tiene derecho al auxilio de transporte.
                        type: boolean
                        example: true
              example:
                data:
                  id: 43541d40-259f-52e3-9f78-31f966b0e828
                  base_salary: 2800000
                  category: monthly
                  initial_day: '2024-01-01'
                  end_day: null
                  editable: true
                  deleteable: false
                  remote_work: false
                  transport_subsidy: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato liquidado / Solo salario actual editable / Categoría inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato liquidado:
                  value:
                    error:
                      - code: '3105'
                        index: 0
                        message: El contrato ya ha sido liquidado, por lo cual no puedes editarlo.
                        object: contract
                Solo salario actual editable:
                  value:
                    error:
                      - code: '0802'
                        index: 0
                        message: Solo puedes editar el salario actual.
                        object: wage
                Categoría de salario inválida:
                  value:
                    error:
                      - code: '0804'
                        index: 0
                        message: La categoría del salario es inválida para el tipo de contrato.
                        object: wage
    delete:
      operationId: destroyWage
      tags:
        - Salarios
      summary: Eliminar salario
      description: |
        **¿Qué hace este endpoint?**

        Elimina un salario del historial de un contrato laboral. Al eliminarse, el salario
        anterior recupera su fecha de fin automáticamente.

        **¿Cuándo usar este endpoint?**

        * Eliminar un cambio salarial registrado por error en el historial del contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Restricción de eliminación:** Solo pueden eliminarse salarios con `deleteable: true`.
      responses:
        '200':
          description: Salario eliminado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: El salario ha sido eliminado.
              example:
                data:
                  message: El salario ha sido eliminado.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Salario no eliminable / Salario mínimo de aprendiz no eliminable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Salario no eliminable:
                  value:
                    error:
                      - code: '0501'
                        index: 0
                        message: Salario no se puede eliminar.
                        object: wage
                Salario mínimo de aprendiz no eliminable:
                  value:
                    error:
                      - code: '0810'
                        index: 0
                        message: No puedes eliminar este salario porque es el único que cumple con el mínimo permitido por la ley para este periodo.
                        object: wage
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al salario en la base de datos.
        schema:
          type: string
          example: 43541d40-259f-52e3-9f78-31f966b0e828
  /v1/{company_id}/work_centers:
    get:
      operationId: indexWorkCenters
      tags:
        - Centros de trabajo
      summary: Listar centros de trabajo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de todos los centros de trabajo asociados a la empresa, incluyendo el código de actividad económica vigente de cada uno.

        **¿Cuándo usar este endpoint?**

        * Consultar los centros de trabajo disponibles para asignar a contratos.
        * Verificar qué centros de trabajo pueden eliminarse antes de reorganizar la estructura de la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Centros de trabajo registrados / Sin centros de trabajo registrados
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de centros de trabajo de la empresa, ordenados alfabéticamente.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                          type: string
                          example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                        name:
                          description: Nombre del centro de trabajo.
                          type: string
                          example: Sede Principal
                        code:
                          description: Código numérico del centro de trabajo.
                          type: integer
                          example: 123
                        initial_day:
                          description: Fecha de inicio del historial de actividad económica del centro de trabajo en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2020-01-01'
                        deleteable:
                          description: Indica si el centro de trabajo puede eliminarse. Es `false` cuando tiene contratos asociados.
                          type: boolean
                          example: false
                        activity_code:
                          description: Código de actividad económica vigente del centro de trabajo.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) del código de actividad económica en la base de datos.
                              type: string
                              example: bca4c459-1a30-56c0-9c0c-055567614101
                            ciiu_code:
                              description: Código CIIU de la actividad económica.
                              type: string
                              example: '0123'
                            social_security_code:
                              description: Código de la actividad económica usado en la planilla de seguridad social.
                              type: string
                              example: '1011101'
                            risk_type:
                              description: Nombre legible del nivel de riesgo laboral asociado a la actividad económica.
                              type: string
                              example: Riesgo 1 - Mínimo
                            risk_type_coded_name:
                              description: Identificador interno del nivel de riesgo laboral.
                              type: string
                              example: risk_1
                            description:
                              description: Descripción de la actividad económica.
                              type: string
                              example: Actividades de servicios de apoyo a las empresas
              examples:
                Centros de trabajo registrados:
                  value:
                    data:
                      - id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                        name: Sede Principal
                        code: 123
                        initial_day: '2020-01-01'
                        deleteable: false
                        activity_code:
                          id: bca4c459-1a30-56c0-9c0c-055567614101
                          ciiu_code: '0123'
                          social_security_code: '1011101'
                          risk_type: Riesgo 1 - Mínimo
                          risk_type_coded_name: risk_1
                          description: Actividades de servicios de apoyo a las empresas
                Sin centros de trabajo registrados:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createWorkCenter
      tags:
        - Centros de trabajo
      summary: Crear centro de trabajo
      description: |
        **¿Qué hace este endpoint?**

        Crea un nuevo centro de trabajo para la empresa con su código de actividad económica y fecha de inicio del historial.

        **¿Cuándo usar este endpoint?**

        * Registrar un nuevo centro de trabajo para clasificar contratos según el riesgo laboral correspondiente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Nombre:** Obligatorio, mínimo 2 caracteres. Solo puede contener números, letras y los caracteres `-_`.
        * **Código de actividad:** El `activity_code_id` debe corresponder a un código de actividad económica válido registrado en el sistema.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                work_center:
                  type: object
                  description: Datos del centro de trabajo a crear.
                  properties:
                    name:
                      type: string
                      description: Nombre del centro de trabajo.
                      example: Sede Norte
                    code:
                      type:
                        - string
                        - 'null'
                      description: Código numérico del centro de trabajo.
                      example: '2035'
                    initial_day:
                      type:
                        - string
                        - 'null'
                      description: Fecha de inicio del historial en formato YYYY-MM-DD. Si no se envía, se usa la fecha de inicio de la empresa.
                      example: '2024-01-01'
                    activity_code_id:
                      type: string
                      description: Identificador único (ID) del código de actividad económica a asociar.
                      example: bca4c459-1a30-56c0-9c0c-055567614101
                  required:
                    - name
                    - activity_code_id
              required:
                - work_center
      responses:
        '201':
          description: Centro de trabajo creado correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del centro de trabajo recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                        type: string
                        example: 0694f485-13cc-4b8e-b3ae-d3cc46fa1933
                      name:
                        description: Nombre del centro de trabajo.
                        type: string
                        example: Sede Norte
                      code:
                        description: Código numérico del centro de trabajo.
                        type: integer
                        example: 2035
                      initial_day:
                        description: Fecha de inicio del historial de actividad económica en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      deleteable:
                        description: Indica si el centro de trabajo puede eliminarse. Es `false` cuando tiene contratos asociados.
                        type: boolean
                        example: true
                      activity_code:
                        description: Código de actividad económica asociado al centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del código de actividad económica en la base de datos.
                            type: string
                            example: bca4c459-1a30-56c0-9c0c-055567614101
                          ciiu_code:
                            description: Código CIIU de la actividad económica.
                            type: string
                            example: '0123'
                          social_security_code:
                            description: Código de la actividad económica usado en la planilla de seguridad social.
                            type: string
                            example: '1011101'
                          risk_type:
                            description: Nombre legible del nivel de riesgo laboral asociado a la actividad económica.
                            type: string
                            example: Riesgo 1 - Mínimo
                          risk_type_coded_name:
                            description: Identificador interno del nivel de riesgo laboral.
                            type: string
                            example: risk_1
                          description:
                            description: Descripción de la actividad económica.
                            type: string
                            example: Actividades de servicios de apoyo a las empresas
              example:
                data:
                  id: 0694f485-13cc-4b8e-b3ae-d3cc46fa1933
                  name: Sede Norte
                  code: 2035
                  initial_day: '2024-01-01'
                  deleteable: true
                  activity_code:
                    id: bca4c459-1a30-56c0-9c0c-055567614101
                    ciiu_code: '0123'
                    social_security_code: '1011101'
                    risk_type: Riesgo 1 - Mínimo
                    risk_type_coded_name: risk_1
                    description: Actividades de servicios de apoyo a las empresas
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre en blanco / Nombre demasiado corto / Nombre con caracteres inválidos
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nombre en blanco:
                  value:
                    error:
                      - code: '0002'
                        index: 0
                        message: Nombre no puede estar en blanco.
                        object: name
                Nombre demasiado corto:
                  value:
                    error:
                      - code: '0201'
                        index: 0
                        message: Nombre es demasiado corto (2 caracteres mínimo).
                        object: name
                Nombre con caracteres inválidos:
                  value:
                    error:
                      - code: '0116'
                        index: 0
                        message: 'Nombre solo puede contener números, letras y los siguientes caracteres: ''-_''.'
                        object: name
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: e5599014-cc9d-4530-856f-414be7bce792
  /v1/{company_id}/work_centers/{id}:
    get:
      operationId: showWorkCenter
      tags:
        - Centros de trabajo
      summary: Obtener centro de trabajo
      description: |
        **¿Qué hace este endpoint?**

        Retorna el detalle de un centro de trabajo específico, incluyendo el historial completo de cambios de código de actividad económica.

        **¿Cuándo usar este endpoint?**

        * Mostrar la información detallada de un centro de trabajo con sus períodos históricos de actividad económica y riesgo laboral.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Centro de trabajo obtenido correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del centro de trabajo con su historial de actividad económica.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                        type: string
                        example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 56e06d90-0244-5866-9b2a-af6df5418eee
                      name:
                        description: Nombre del centro de trabajo.
                        type: string
                        example: Sede Principal
                      code:
                        description: Código numérico del centro de trabajo.
                        type: integer
                        example: 123
                      work_center_histories:
                        description: Historial de períodos de actividad económica del centro de trabajo, ordenados por fecha de inicio.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) del registro histórico en la base de datos.
                              type: string
                              example: 4c544502-17b4-55c3-afd7-d4380bfcb1d6
                            work_center_id:
                              description: Identificador único (ID) del centro de trabajo al que pertenece este historial.
                              type: string
                              example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                            initial_day:
                              description: Fecha de inicio del período de actividad económica en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2020-01-01'
                            end_day:
                              description: Fecha de fin del período de actividad económica en formato YYYY-MM-DD. Puede ser null si el período sigue vigente.
                              type:
                                - string
                                - 'null'
                              example: '2024-12-31'
                            activity_code:
                              description: Código de actividad económica vigente durante este período.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) del código de actividad económica en la base de datos.
                                  type: string
                                  example: bca4c459-1a30-56c0-9c0c-055567614101
                                ciiu_code:
                                  description: Código CIIU de la actividad económica.
                                  type: string
                                  example: '0123'
                                social_security_code:
                                  description: Código de la actividad económica usado en la planilla de seguridad social.
                                  type: string
                                  example: '1011101'
                                risk_type:
                                  description: Nombre legible del nivel de riesgo laboral asociado a la actividad económica.
                                  type: string
                                  example: Riesgo 1 - Mínimo
                                risk_type_coded_name:
                                  description: Identificador interno del nivel de riesgo laboral.
                                  type: string
                                  example: risk_1
                                description:
                                  description: Descripción de la actividad económica.
                                  type: string
                                  example: Actividades de servicios de apoyo a las empresas
              example:
                data:
                  id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                  company_id: 56e06d90-0244-5866-9b2a-af6df5418eee
                  name: Sede Principal
                  code: 123
                  work_center_histories:
                    - id: 4c544502-17b4-55c3-afd7-d4380bfcb1d6
                      work_center_id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                      initial_day: '2020-01-01'
                      end_day: '2024-12-31'
                      activity_code:
                        id: bca4c459-1a30-56c0-9c0c-055567614101
                        ciiu_code: '0123'
                        social_security_code: '1011101'
                        risk_type: Riesgo 1 - Mínimo
                        risk_type_coded_name: risk_1
                        description: Actividades de servicios de apoyo a las empresas
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateWorkCenter
      tags:
        - Centros de trabajo
      summary: Actualizar centro de trabajo
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el nombre y/o el código del centro de trabajo y ajusta su historial de actividad económica según los campos enviados.

        Si se envía `new_history: true` junto con `initial_day`, se crea un nuevo registro en el historial de actividad económica. Si `new_history` no es `true`, el `initial_day` actualiza el historial vigente.

        **¿Cuándo usar este endpoint?**

        * Cambiar el nombre o código de un centro de trabajo existente.
        * Registrar un cambio de actividad económica a partir de una nueva fecha creando un nuevo historial.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * Cuando `new_history` es `true`, la fecha `initial_day` debe ser posterior al inicio del historial vigente.
        * Para crear un nuevo historial también se debe enviar `activity_code_id`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                work_center:
                  type: object
                  description: Datos del centro de trabajo a actualizar. Todos los campos son opcionales.
                  properties:
                    name:
                      type: string
                      description: Nuevo nombre del centro de trabajo.
                      example: Sede Norte
                    code:
                      type: integer
                      description: Código numérico del centro de trabajo.
                      example: 124
                    initial_day:
                      type: string
                      format: date
                      description: Fecha de inicio del historial de actividad económica en formato YYYY-MM-DD.
                      example: '2024-01-01'
                    new_history:
                      type: string
                      description: Enviar `"true"` para crear un nuevo registro en el historial de actividad.
                      example: 'true'
                    activity_code_id:
                      type: string
                      description: Identificador único (ID) del nuevo código de actividad económica a asociar.
                      example: bca4c459-1a30-56c0-9c0c-055567614101
              required:
                - work_center
      responses:
        '202':
          description: Centro de trabajo actualizado correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados del centro de trabajo.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                        type: string
                        example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                      name:
                        description: Nombre del centro de trabajo.
                        type: string
                        example: Sede Norte
                      code:
                        description: Código numérico del centro de trabajo.
                        type: integer
                        example: 124
                      initial_day:
                        description: Fecha de inicio del historial de actividad económica vigente en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      deleteable:
                        description: Indica si el centro de trabajo puede eliminarse. Es `false` cuando tiene contratos asociados.
                        type: boolean
                        example: false
                      activity_code:
                        description: Código de actividad económica actualmente asociado al centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) del código de actividad económica en la base de datos.
                            type: string
                            example: bca4c459-1a30-56c0-9c0c-055567614101
                          ciiu_code:
                            description: Código CIIU de la actividad económica.
                            type: string
                            example: '0123'
                          social_security_code:
                            description: Código de la actividad económica usado en la planilla de seguridad social.
                            type: string
                            example: '1011101'
                          risk_type:
                            description: Nombre legible del nivel de riesgo laboral asociado a la actividad económica.
                            type: string
                            example: Riesgo 1 - Mínimo
                          risk_type_coded_name:
                            description: Identificador interno del nivel de riesgo laboral.
                            type: string
                            example: risk_1
                          description:
                            description: Descripción de la actividad económica.
                            type: string
                            example: Actividades de servicios de apoyo a las empresas
              example:
                data:
                  id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                  name: Sede Norte
                  code: 124
                  initial_day: '2024-01-01'
                  deleteable: false
                  activity_code:
                    id: bca4c459-1a30-56c0-9c0c-055567614101
                    ciiu_code: '0123'
                    social_security_code: '1011101'
                    risk_type: Riesgo 1 - Mínimo
                    risk_type_coded_name: risk_1
                    description: Actividades de servicios de apoyo a las empresas
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Fecha inicial inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '3401'
                    index: 0
                    message: El día inicial debe ser de un mes posterior a la versión actual del Centro de Trabajo.
                    object: work_center
    delete:
      operationId: destroyWorkCenter
      tags:
        - Centros de trabajo
      summary: Eliminar centro de trabajo
      description: |
        **¿Qué hace este endpoint?**

        Elimina permanentemente un centro de trabajo de la empresa.

        **¿Cuándo usar este endpoint?**

        * Dar de baja un centro de trabajo que ya no sea necesario y no tenga contratos asociados.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * **Eliminación:** Un centro de trabajo no puede eliminarse si tiene contratos asociados. El campo `deleteable` del listado indica si puede ser eliminado.
      responses:
        '200':
          description: Centro de trabajo eliminado correctamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de que el centro de trabajo fue eliminado correctamente.
                        type: string
                        example: Se ha eliminado el centro de trabajo.
              example:
                data:
                  message: Se ha eliminado el centro de trabajo.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Centro de trabajo con contratos asociados
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0507'
                    index: 0
                    message: No se puede eliminar el centro de trabajo porque tiene contratos asociados.
                    object: work_center
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 2059e26a-4d2c-48d2-b7dc-1372b8a97d17
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
        schema:
          type: string
          example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
  /v1/{company_id}/social_security_branches:
    get:
      operationId: indexSocialSecurityBranches
      tags:
        - Sucursales
      summary: Listar sucursales
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de sucursales de seguridad social registradas para la empresa,
        ordenadas por fecha de creación.

        **¿Cuándo usar este endpoint?**

        * Obtener las sucursales disponibles para asignarlas a personas antes de generar
          la planilla PILA.
        * Verificar el código y nombre de cada sucursal registrada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
      responses:
        '200':
          description: Sucursales registradas / Sin sucursales registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Lista de sucursales de seguridad social de la empresa.
                    type: array
                    items:
                      description: Datos de una sucursal de seguridad social.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la sucursal en la base de datos.
                          type: string
                          example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                        code:
                          description: Código numérico de la sucursal, de hasta 10 dígitos.
                          type: string
                          example: '001'
                        name:
                          description: Nombre de la sucursal de seguridad social.
                          type: string
                          example: Sucursal Norte
                        workers:
                          description: Número de personas asociadas actualmente a esta sucursal.
                          type: integer
                          example: 12
              examples:
                Sucursales registradas:
                  value:
                    data:
                      - id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                        code: '001'
                        name: Sucursal Norte
                        workers: 12
                      - id: 0694f485-13cc-4b8e-b3ae-d3cc46fa1933
                        code: '002'
                        name: Sucursal Sur
                        workers: 5
                Sin sucursales registradas:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createSocialSecurityBranch
      tags:
        - Sucursales
      summary: Crear sucursal
      description: |
        **¿Qué hace este endpoint?**

        Registra una nueva sucursal de seguridad social para la empresa.

        **¿Cuándo usar este endpoint?**

        * Registrar una sucursal antes de asignarla a las personas de la empresa.
        * Agregar una nueva sucursal cuando la empresa abre operaciones en una nueva ubicación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Código único:** El código de la sucursal debe ser numérico y único dentro de la empresa.
        * **Nombre único:** El nombre de la sucursal debe ser único dentro de la empresa
          (sin distinguir mayúsculas) y tener entre 1 y 40 caracteres.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                social_security_branch:
                  description: Datos de la sucursal a crear.
                  type: object
                  properties:
                    code:
                      description: Código numérico de la sucursal, de hasta 10 dígitos.
                      type: string
                      example: '003'
                    name:
                      description: Nombre de la sucursal. Entre 1 y 40 caracteres, único en la empresa.
                      type: string
                      example: Sucursal Centro
                  required:
                    - code
                    - name
              required:
                - social_security_branch
            example:
              social_security_branch:
                code: '003'
                name: Sucursal Centro
      responses:
        '201':
          description: Sucursal creada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la sucursal recién creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la sucursal en la base de datos.
                        type: string
                        example: 0694f485-13cc-4b8e-b3ae-d3cc46fa1933
                      code:
                        description: Código numérico de la sucursal.
                        type: string
                        example: '003'
                      name:
                        description: Nombre de la sucursal de seguridad social.
                        type: string
                        example: Sucursal Centro
                      workers:
                        description: Número de personas asociadas a esta sucursal. Siempre es 0 al crear.
                        type: integer
                        example: 0
              example:
                data:
                  id: 0694f485-13cc-4b8e-b3ae-d3cc46fa1933
                  code: '003'
                  name: Sucursal Centro
                  workers: 0
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: e5599014-cc9d-4530-856f-414be7bce792
  /v1/{company_id}/social_security_branches/{id}:
    get:
      operationId: showSocialSecurityBranch
      tags:
        - Sucursales
      summary: Obtener sucursal
      description: |
        **¿Qué hace este endpoint?**

        Retorna los datos de una sucursal de seguridad social específica de la empresa.

        **¿Cuándo usar este endpoint?**

        * Consultar el detalle de una sucursal antes de editarla o eliminarla.
        * Verificar cuántas personas están actualmente asignadas a la sucursal.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
      responses:
        '200':
          description: Sucursal obtenida exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la sucursal de seguridad social.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la sucursal en la base de datos.
                        type: string
                        example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                      code:
                        description: Código numérico de la sucursal, de hasta 10 dígitos.
                        type: string
                        example: '001'
                      name:
                        description: Nombre de la sucursal de seguridad social.
                        type: string
                        example: Sucursal Norte
                      workers:
                        description: Número de personas asociadas actualmente a esta sucursal.
                        type: integer
                        example: 12
              example:
                data:
                  id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                  code: '001'
                  name: Sucursal Norte
                  workers: 12
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateSocialSecurityBranch
      tags:
        - Sucursales
      summary: Actualizar sucursal
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el código o el nombre de una sucursal de seguridad social existente.

        **¿Cuándo usar este endpoint?**

        * Corregir el código o nombre de una sucursal registrada incorrectamente.
        * Renombrar una sucursal por cambios organizacionales.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Código único:** El nuevo código debe ser numérico y único dentro de la empresa.
        * **Nombre único:** El nuevo nombre debe ser único dentro de la empresa y tener
          entre 1 y 40 caracteres.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                social_security_branch:
                  description: Campos de la sucursal a actualizar. Se pueden enviar solo los campos a modificar.
                  type: object
                  properties:
                    code:
                      description: Nuevo código numérico de la sucursal, de hasta 10 dígitos.
                      type: string
                      example: '005'
                    name:
                      description: Nuevo nombre de la sucursal. Entre 1 y 40 caracteres, único en la empresa.
                      type: string
                      example: Sucursal Norte Actualizada
              required:
                - social_security_branch
            example:
              social_security_branch:
                code: '005'
                name: Sucursal Norte Actualizada
      responses:
        '202':
          description: Sucursal actualizada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la sucursal.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la sucursal en la base de datos.
                        type: string
                        example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                      code:
                        description: Código numérico actualizado de la sucursal.
                        type: string
                        example: '005'
                      name:
                        description: Nombre actualizado de la sucursal.
                        type: string
                        example: Sucursal Norte Actualizada
                      workers:
                        description: Número de personas asociadas actualmente a esta sucursal.
                        type: integer
                        example: 12
              example:
                data:
                  id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                  code: '005'
                  name: Sucursal Norte Actualizada
                  workers: 12
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    delete:
      operationId: destroySocialSecurityBranch
      tags:
        - Sucursales
      summary: Eliminar sucursal
      description: |
        **¿Qué hace este endpoint?**

        Elimina una sucursal de seguridad social de la empresa. Las personas asociadas
        a la sucursal eliminada quedan sin sucursal asignada.

        **¿Cuándo usar este endpoint?**

        * Eliminar una sucursal creada por error.
        * Consolidar sucursales cuando la empresa reduce su número de ubicaciones.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}`
          con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Mínimo una sucursal:** La empresa debe conservar al menos una sucursal. No es
          posible eliminar la última sucursal registrada.
      responses:
        '200':
          description: Sucursal eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La Sucursal ha sido eliminada.
              example:
                data:
                  message: La Sucursal ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 2059e26a-4d2c-48d2-b7dc-1372b8a97d17
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la sucursal en la base de datos.
        schema:
          type: string
          example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
  /v1/{company_id}/work_hours_configurations:
    get:
      operationId: indexWorkHoursConfigurations
      tags:
        - Configuración de horas trabajadas
      summary: Listar configuraciones de horas trabajadas
      description: |
        **¿Qué hace este endpoint?**

        Retorna todas las configuraciones de horas semanales trabajadas registradas para la empresa,
        ordenadas por fecha de inicio.

        **¿Cuándo usar este endpoint?**

        * Consultar las vigencias de horas semanales configuradas para la empresa antes de agregar una nueva.
        * Verificar qué configuración de horas aplica para un periodo específico.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Configuraciones de horas trabajadas retornadas correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de configuraciones de horas semanales de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la configuración de horas trabajadas en la base de datos.
                          type: string
                          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        initial_day:
                          description: Fecha de inicio de la vigencia en formato `YYYY-MM-DD`.
                          type: string
                          format: date
                          example: '2024-01-01'
                        end_day:
                          description: Fecha de fin de la vigencia en formato `YYYY-MM-DD`. Null si no tiene fecha de fin.
                          type:
                            - string
                            - 'null'
                          format: date
                          example: '2024-12-31'
                        weekly_hours:
                          description: Número de horas semanales de trabajo configuradas.
                          type: number
                          example: 46
                        company_id:
                          description: Identificador único (ID) asignado a la empresa en la base de datos.
                          type: string
                          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
              example:
                data:
                  - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    initial_day: '2024-01-01'
                    end_day: '2024-12-31'
                    weekly_hours: 46
                    company_id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createWorkHoursConfiguration
      tags:
        - Configuración de horas trabajadas
      summary: Crear configuración de horas trabajadas
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva configuración de horas semanales trabajadas para la empresa a partir de una
        fecha de inicio. Las nóminas del rango afectado se recalculan automáticamente para reflejar
        el nuevo valor de horas extras.

        **¿Cuándo usar este endpoint?**

        * Registrar un cambio en las horas semanales de trabajo por reforma legal o acuerdo laboral.
        * Configurar la jornada laboral inicial de la empresa al comenzar a usar el sistema.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Fechas no solapadas:** No puede existir otra configuración con la misma `initial_day` para la misma empresa.
        * **Máximo de horas:** Las horas semanales no pueden superar el máximo legal vigente según la fecha de inicio configurada.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - initial_day
                - weekly_hours
              properties:
                initial_day:
                  description: Fecha de inicio de la vigencia en formato `YYYY-MM-DD`.
                  type: string
                  format: date
                  example: '2024-01-01'
                end_day:
                  description: Fecha de fin de la vigencia en formato `YYYY-MM-DD`. Opcional.
                  type: string
                  format: date
                  example: '2024-12-31'
                weekly_hours:
                  description: Número de horas semanales de trabajo.
                  type: number
                  example: 46
            example:
              initial_day: '2024-01-01'
              weekly_hours: 46
      responses:
        '201':
          description: Configuración de horas trabajadas creada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la configuración de horas trabajadas creada.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de horas trabajadas en la base de datos.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      initial_day:
                        description: Fecha de inicio de la vigencia en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin de la vigencia en formato `YYYY-MM-DD`. Null si no tiene fecha de fin.
                        type:
                          - string
                          - 'null'
                        format: date
                        example: '2024-12-31'
                      weekly_hours:
                        description: Número de horas semanales de trabajo configuradas.
                        type: number
                        example: 46
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
              example:
                data:
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  initial_day: '2024-01-01'
                  end_day: '2024-12-31'
                  weekly_hours: 46
                  company_id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
  /v1/{company_id}/work_hours_configurations/{id}:
    patch:
      operationId: updateWorkHoursConfiguration
      tags:
        - Configuración de horas trabajadas
      summary: Actualizar configuración de horas trabajadas
      description: |
        **¿Qué hace este endpoint?**

        Actualiza una configuración de horas semanales trabajadas existente. Las nóminas de los
        rangos afectados (antes y después del cambio) se recalculan automáticamente.

        **¿Cuándo usar este endpoint?**

        * Corregir el número de horas semanales o las fechas de una configuración existente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Fechas no solapadas:** La `initial_day` actualizada no puede coincidir con la de otra configuración de la misma empresa.
        * **Máximo de horas:** Las horas semanales no pueden superar el máximo legal vigente según la fecha de inicio.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                initial_day:
                  description: Nueva fecha de inicio de la vigencia en formato `YYYY-MM-DD`.
                  type: string
                  format: date
                  example: '2024-01-01'
                end_day:
                  description: Nueva fecha de fin de la vigencia en formato `YYYY-MM-DD`.
                  type: string
                  format: date
                  example: '2024-12-31'
                weekly_hours:
                  description: Nuevo número de horas semanales de trabajo.
                  type: number
                  example: 40
            example:
              weekly_hours: 40
      responses:
        '202':
          description: Configuración de horas trabajadas actualizada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos actualizados de la configuración de horas trabajadas.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de horas trabajadas en la base de datos.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      initial_day:
                        description: Fecha de inicio de la vigencia de la configuración en formato `YYYY-MM-DD`.
                        type: string
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin de la vigencia de la configuración en formato `YYYY-MM-DD`. Null si no tiene fecha de fin.
                        type:
                          - string
                          - 'null'
                        example: null
                      weekly_hours:
                        description: Número de horas semanales de trabajo configuradas.
                        type: number
                        example: 40
                      company_id:
                        description: Identificador único (ID) asignado a la empresa en la base de datos.
                        type: string
                        example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
              example:
                data:
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  initial_day: '2024-01-01'
                  end_day: null
                  weekly_hours: 40
                  company_id: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    delete:
      operationId: destroyWorkHoursConfiguration
      tags:
        - Configuración de horas trabajadas
      summary: Eliminar configuración de horas trabajadas
      description: |
        **¿Qué hace este endpoint?**

        Elimina una configuración de horas semanales trabajadas. Las nóminas del rango afectado
        se recalculan automáticamente.

        **¿Cuándo usar este endpoint?**

        * Eliminar una configuración de horas registrada por error.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      responses:
        '200':
          description: Configuración de horas trabajadas eliminada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La información fue eliminada con éxito.
              example:
                data:
                  message: La información fue eliminada con éxito.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la configuración de horas trabajadas en la base de datos.
        schema:
          type: string
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
  /v1/{company_id}/worker_onboardings:
    get:
      operationId: indexWorkerOnboardings
      tags:
        - Onboarding de personas
      summary: Listar onboardings de personas
      description: |
        **¿Qué hace este endpoint?**

        El onboarding es el proceso de vinculación de una persona a la empresa: agrupa las tareas previas al inicio del contrato (verificación de antecedentes y firma electrónica) y puede estar en estado `unstarted`, `in_progress`, `completed` o `canceled`.

        Este endpoint retorna el listado paginado de onboardings de personas de la empresa, con el estado de progreso de cada uno.

        **¿Cuándo usar este endpoint?**

        * Consultar el estado de los procesos de onboarding en curso para hacer seguimiento.
        * Filtrar onboardings por estado (completados, cancelados, etc.) antes de tomar acciones sobre ellos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Filtro `canceled`:** Al usar `filter=canceled` se retorna un listado vacío, ya que los onboardings cancelados no se muestran en el listado activo.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca onboardings por nombre completo de la persona. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: María González
        - in: query
          required: false
          name: filter
          description: 'Filtro por estado del onboarding. Valores posibles: completed (completado), in_progress (en progreso), unstarted (no iniciado).'
          schema:
            type: string
            enum:
              - completed
              - in_progress
              - unstarted
            example: completed
      responses:
        '200':
          description: Listado de onboardings de personas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de onboardings activos de personas de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al onboarding en la base de datos.
                          type: string
                          example: 063a821c-1ef3-5f84-866b-921d086106c5
                        worker:
                          description: Información básica de la persona asociada al onboarding.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
                            email:
                              description: Correo electrónico de la persona.
                              type: string
                              example: persona@ejemplo.com
                            full_name:
                              description: Nombre completo de la persona.
                              type: string
                              example: María González Pérez
                            picture:
                              description: URL de la foto de perfil de la persona. Retorna null si no tiene foto.
                              type:
                                - string
                                - 'null'
                              example: https://storage.aleluya.com/pictures/worker.jpg
                            finished_registration:
                              description: Indica si la persona completó su registro de datos personales.
                              type: boolean
                              example: true
                            position:
                              description: Nombre del cargo actual de la persona. Retorna null si no tiene contrato activo.
                              type:
                                - string
                                - 'null'
                              example: Analista de nómina
                            contract_category:
                              description: Categoría del contrato activo de la persona. Retorna null si no tiene contrato.
                              oneOf:
                                - $ref: '#/components/schemas/ContractCategory'
                                - type: 'null'
                        canceled:
                          description: Indica si el proceso de onboarding fue cancelado.
                          type: boolean
                          example: false
                        completed:
                          description: Indica si el proceso de onboarding fue completado exitosamente.
                          type: boolean
                          example: true
                        onboarding_percentage:
                          description: Porcentaje de completitud del proceso de onboarding (0 a 100).
                          type: integer
                          example: 100
                        background_check:
                          description: Estado del proceso de verificación de antecedentes. Retorna null si no aplica para este onboarding.
                          type:
                            - object
                            - 'null'
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la verificación de antecedentes en la base de datos. Retorna null si no aplica.
                              type:
                                - string
                                - 'null'
                              example: 24d20c41-4813-53bc-949e-1f22511cd1fd
                            status:
                              description: 'Estado del proceso de verificación de antecedentes. Valores posibles: unstarted (no iniciado), in_progress (en progreso), finished (finalizado), not_apply (no aplica).'
                              type: string
                              example: finished
                        electronic_signature:
                          description: Estado del proceso de firma electrónica. Retorna null si no aplica para este onboarding.
                          type:
                            - object
                            - 'null'
                          properties:
                            id:
                              description: Identificador único (ID) asignado al proceso de firma electrónica en la base de datos. Retorna null si no aplica.
                              type:
                                - string
                                - 'null'
                              example: 7c4c41c6-a404-5041-8f81-633f6c5438dd
                            status:
                              description: 'Estado del proceso de firma electrónica. Valores posibles: unstarted (no iniciado), in_progress (en progreso), finished (finalizado), not_apply (no aplica).'
                              type: string
                              example: finished
                  filters:
                    $ref: '#/components/schemas/FiltersModel'
              example:
                data:
                  - id: 063a821c-1ef3-5f84-866b-921d086106c5
                    worker:
                      id: 6626a96f-32b2-5890-bc03-af9d8b2854f7
                      email: persona@ejemplo.com
                      full_name: María González Pérez
                      picture: null
                      finished_registration: true
                      position: Analista de nómina
                      contract_category: employee
                    canceled: false
                    completed: true
                    onboarding_percentage: 100
                    background_check:
                      id: 24d20c41-4813-53bc-949e-1f22511cd1fd
                      status: finished
                    electronic_signature:
                      id: 7c4c41c6-a404-5041-8f81-633f6c5438dd
                      status: finished
                filters:
                  total_records: 1
                  page: 1
                  per_page: 20
                  filter: All
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 9ec6bbc3-ed55-42cb-a137-cb317fdfa271
  /v1/{company_id}/worker_onboardings/{id}:
    patch:
      operationId: updateWorkerOnboarding
      tags:
        - Onboarding de personas
      summary: Actualizar onboarding de persona
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el estado de un onboarding de persona. Permite completar el onboarding (`status: complete_onboarding`) o descartar una acción pendiente (`action_to_discard`).

        **¿Cuándo usar este endpoint?**

        * Marcar el onboarding como completado una vez que todos los procesos requeridos están finalizados.
        * Descartar una acción específica del onboarding (como verificación de antecedentes o firma electrónica) cuando no aplica para la persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Procesos pendientes:** No se puede completar el onboarding si hay procesos en estado pendiente. Retorna 422 con el nombre del proceso bloqueante.
        * **Acción a descartar:** El valor de `action_to_discard` debe coincidir con el nombre de una acción válida del onboarding (ej. `background_checks`, `electronic_signatures`).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  description: Acción de estado a ejecutar sobre el onboarding. Enviar `complete_onboarding` para marcar el proceso como completado.
                  type: string
                  enum:
                    - complete_onboarding
                  example: complete_onboarding
                action_to_discard:
                  description: Nombre de la acción del onboarding que se desea descartar porque no aplica para esta persona.
                  type: string
                  example: background_checks
            examples:
              Completar onboarding:
                value:
                  status: complete_onboarding
              Descartar acción:
                value:
                  action_to_discard: background_checks
      responses:
        '200':
          description: Onboarding actualizado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la actualización.
                        type: string
                        example: El onboarding ha sido actualizado correctamente
              example:
                data:
                  message: El onboarding ha sido actualizado correctamente
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Acciones pendientes / Nóminas emitidas / Acción inválida / Proceso no finalizado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Acciones pendientes:
                  value:
                    error:
                      - code: '3601'
                        index: 0
                        message: Este proceso no se puede finalizar, debido a que hay acciones pendientes.
                        object: worker_onboarding
                Nóminas emitidas o pagadas:
                  value:
                    error:
                      - code: '3602'
                        index: 0
                        message: Este proceso no se puede cancelar, debido a que esta persona tiene nóminas electrónicas emitidas o nóminas pagadas.
                        object: worker_onboarding
                Proceso no finalizado:
                  value:
                    error:
                      - code: '3605'
                        index: 0
                        message: No puedes modificar el onboarding porque el proceso de Firma electrónica no está finalizado.
                        object: worker_onboarding
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al onboarding en la base de datos.
        schema:
          type: string
          example: 063a821c-1ef3-5f84-866b-921d086106c5
  /v1/{company_id}/workers:
    get:
      operationId: indexWorkers
      tags:
        - Personas
      summary: Listar personas
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de personas registradas en la empresa, con información básica de identificación, contrato y estado.

        **¿Cuándo usar este endpoint?**

        * Obtener el listado de personas de la empresa para mostrarlas en una tabla con filtros por tipo o estado.
        * Consultar qué contratos tienen asignados las personas antes de ejecutar operaciones sobre nómina o novedades.
        * Verificar el estado de registro de cada persona antes de liquidar nómina.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * Las personas con `demo_flag: true` son personas de prueba que permiten experimentar el flujo de nómina sin crear personas reales. Se pueden eliminar sin restricciones.
      parameters:
        - in: query
          name: filter
          required: false
          description: 'Filtra las personas por tipo de contrato o estado. Valores posibles: `active` (activas), `inactive` (inactivas), `employee` (empleados), `contractor` (contratistas), `apprentice` (aprendices), `student` (estudiantes), `part_time_contract` (tiempo parcial), `terminated_worker` (liquidadas), `disabled` (deshabilitadas), `not_finished` (registro sin terminar), `invalid_social_security` (seguridad social incompleta).'
          schema:
            type: string
            enum:
              - active
              - inactive
              - employee
              - contractor
              - apprentice
              - student
              - part_time_contract
              - terminated_worker
              - disabled
              - not_finished
              - invalid_social_security
            example: active
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca personas por nombre completo o número de documento. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
        - $ref: '#/components/parameters/locationParam'
      responses:
        '200':
          description: Personas registradas / Sin personas registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de personas de la empresa con información básica de contrato.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la persona en la base de datos.
                          type: string
                          example: 65c7c863-ff51-583a-ab4f-b91566ad1e0f
                        document_type:
                          $ref: '#/components/schemas/WorkerDocumentType'
                        id_number:
                          description: Número de documento de identificación de la persona.
                          type: string
                          example: '45688789012'
                        demo_flag:
                          description: Indica si la persona es de prueba (demo). Las personas demo permiten experimentar el flujo de nómina y se pueden eliminar sin restricciones.
                          type: boolean
                          example: false
                        name:
                          description: Nombre de la persona.
                          type: string
                          example: Juan Pablo
                        last_name:
                          description: Apellido de la persona.
                          type: string
                          example: García Romero
                        picture:
                          description: URL de la foto de perfil de la persona. Retorna null si no tiene foto asignada.
                          type:
                            - string
                            - 'null'
                          example: https://storage.example.com/pictures/worker.jpg
                        position:
                          description: Nombre del cargo asignado a la persona en su contrato. Retorna null si no tiene cargo asignado.
                          type:
                            - string
                            - 'null'
                          example: Desarrollador de Software
                        location:
                          description: Nombre de la sede asignada a la persona en su contrato. Retorna null si no tiene sede asignada.
                          type:
                            - string
                            - 'null'
                          example: Sede Principal Bogotá
                        email:
                          description: Correo electrónico de la persona. Retorna null si no tiene usuario creado.
                          type:
                            - string
                            - 'null'
                          example: juan.garcia@empresa.com
                        active:
                          description: Indica si la persona está activa en la empresa.
                          type: boolean
                          example: true
                        terminated:
                          description: Indica si el contrato de la persona ha sido liquidado.
                          type: boolean
                          example: false
                        finish_registration:
                          description: Indica si la persona ha completado el proceso de registro con todos los datos requeridos.
                          type: boolean
                          example: true
                        contract_id:
                          description: Identificador único (ID) asignado al contrato activo de la persona en la base de datos. Retorna null si no tiene contrato.
                          type:
                            - string
                            - 'null'
                          example: 3f625fab-c21a-54b4-bd9c-9a6cb97000cc
                        contract_initial_day:
                          description: Fecha de inicio del contrato activo de la persona en formato YYYY-MM-DD. Retorna null si no tiene contrato.
                          type:
                            - string
                            - 'null'
                          example: '2023-01-15'
                        contract_end_day:
                          description: Fecha de fin del contrato activo de la persona en formato YYYY-MM-DD. Retorna null si el contrato es indefinido o no tiene contrato.
                          type:
                            - string
                            - 'null'
                          example: null
                        contract_category:
                          description: Categoría del contrato activo de la persona. Null si no tiene contrato activo.
                          oneOf:
                            - $ref: '#/components/schemas/ContractCategory'
                            - type: 'null'
                        contract_term:
                          description: 'Duración del contrato activo. Retorna null si no tiene contrato. Valores posibles: indefinite (indefinido), fixed (término fijo), project (obra o labor).'
                          type:
                            - string
                            - 'null'
                          enum:
                            - indefinite
                            - fixed
                            - project
                          example: indefinite
                        contract_contributor_subtype:
                          description: 'Subtipo de cotizante del contrato activo. Retorna null si no tiene contrato. Valores posibles: no_subtype (sin subtipo), pensioner (pensionado), age_exempt_contributor (cotizante exonerado por edad), qualified_for_pension (apto para pensión), compensado_contributor (cotizante compensado).'
                          type:
                            - string
                            - 'null'
                          enum:
                            - no_subtype
                            - pensioner
                            - age_exempt_contributor
                            - qualified_for_pension
                            - compensated_contributor
                          example: no_subtype
                        base_salary:
                          description: Salario base mensual de la persona en pesos colombianos. Retorna null si no tiene contrato.
                          type:
                            - integer
                            - 'null'
                          example: 3500000
                  filters:
                    description: Metadatos de paginación y filtros aplicados en la consulta.
                    type: object
                    properties:
                      filter:
                        description: Valor del filtro aplicado. Retorna el valor enviado o `All` si no se filtró.
                        type: string
                        example: active
                      total_records:
                        description: Total de personas que coinciden con los filtros aplicados.
                        type: integer
                        example: 20
                      page:
                        description: Número de página actual de la paginación.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de personas por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se buscó.
                        type: string
                        example: ''
                      location:
                        description: Filtro de sede aplicado. Retorna `All` si no se filtró por sede.
                        type: string
                        example: All
              examples:
                Personas registradas:
                  value:
                    data:
                      - id: 65c7c863-ff51-583a-ab4f-b91566ad1e0f
                        document_type: cc
                        id_number: '45688789012'
                        demo_flag: false
                        name: Juan Pablo
                        last_name: García Romero
                        picture: null
                        position: Desarrollador de Software
                        location: Sede Principal Bogotá
                        email: juan.garcia@empresa.com
                        active: true
                        terminated: false
                        finish_registration: true
                        contract_id: 3f625fab-c21a-54b4-bd9c-9a6cb97000cc
                        contract_initial_day: '2023-01-15'
                        contract_end_day: null
                        contract_category: employee
                        contract_term: indefinite
                        contract_contributor_subtype: no_subtype
                        base_salary: 3500000
                    filters:
                      filter: active
                      total_records: 1
                      page: 1
                      per_page: 20
                      search: ''
                      location: All
                Sin personas registradas:
                  value:
                    data: []
                    filters:
                      filter: All
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
                      location: All
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createWorker
      tags:
        - Personas
      summary: Crear persona
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva persona en la empresa junto con su contrato y salario inicial. Puede crear personas regulares o personas de prueba (demo).

        Para crear una **persona demo**, envía `demo_flag: true`. Las personas demo:
        * Solo requieren `name`, `last_name`, `base_salary` y `demo_flag`.
        * Se crean con un número de identificación generado automáticamente.
        * Permiten experimentar el flujo completo de nómina sin registrar personas reales.
        * Se pueden eliminar sin restricciones.

        Para crear una **persona regular**, además de los datos personales se requiere información del contrato: `initial_day`, `category`, `term`, y los proveedores de seguridad social.

        **¿Cuándo usar este endpoint?**

        * Registrar una nueva persona en la empresa para incluirla en la nómina.
        * Crear personas de prueba para validar el flujo de liquidación antes de registrar personas reales.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * El límite de personas está determinado por el plan activo de la empresa.
      requestBody:
        required: true
        description: Persona regular / Persona demo
        content:
          application/json:
            schema:
              type: object
              properties:
                worker:
                  description: Datos de la persona a crear junto con la información de su contrato y salario.
                  type: object
                  properties:
                    name:
                      description: Nombre de la persona.
                      type: string
                      example: Patricia
                    last_name:
                      description: Apellido de la persona.
                      type: string
                      example: Olivera Rosales
                    document_type:
                      description: Tipo de documento de identificación. Requerido para personas regulares.
                      $ref: '#/components/schemas/WorkerDocumentType'
                    id_number:
                      description: Número de documento de identificación. Requerido para personas regulares.
                      type: string
                      example: '52799616'
                    email:
                      description: Correo electrónico de la persona. Se usa para crear el acceso de usuario al portal.
                      type:
                        - string
                        - 'null'
                      example: patricia.olivera@empresa.com
                    active_user:
                      description: Indica si se debe crear acceso de usuario activo para la persona en el portal.
                      type: boolean
                      example: true
                    birthday:
                      description: Fecha de nacimiento de la persona en formato YYYY-MM-DD.
                      type:
                        - string
                        - 'null'
                      example: '1988-01-15'
                    phone:
                      description: Número de teléfono de contacto de la persona.
                      type:
                        - string
                        - 'null'
                      example: '3009011100'
                    address:
                      description: Dirección de residencia de la persona.
                      type:
                        - string
                        - 'null'
                      example: Calle 45
                    city_address_id:
                      description: Identificador único (ID) asignado a la ciudad de residencia de la persona en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 2d16c1b8-1768-5504-993e-d2306280586b
                    payment_method:
                      description: Método de pago del salario de la persona.
                      $ref: '#/components/schemas/PaymentMethod'
                    bank_id:
                      description: Identificador único (ID) asignado al banco para pago de nómina en la base de datos. Requerido cuando `payment_method` es `wire_transfer`.
                      type:
                        - string
                        - 'null'
                      example: 9e81acc1-7158-5d30-8119-c47d26f8a323
                    account_number:
                      description: Número de cuenta bancaria para pago por transferencia. Requerido cuando `payment_method` es `wire_transfer`.
                      type:
                        - string
                        - 'null'
                      example: '62113480'
                    account_type:
                      description: Tipo de cuenta bancaria para pago. Requerido cuando `payment_method` es `wire_transfer`.
                      $ref: '#/components/schemas/AccountType'
                    rest_days:
                      description: Días de descanso de la persona. Se representan como strings donde "0" es domingo, "1" lunes, ..., "6" sábado.
                      type: array
                      items:
                        type: string
                      example:
                        - '0'
                        - '6'
                    picture:
                      description: Foto de perfil de la persona codificada en base64.
                      type:
                        - object
                        - 'null'
                      properties:
                        image:
                          description: Contenido de la imagen en formato base64 con prefijo data URI (p.ej. `data:image/png;base64,...`).
                          type: string
                          example: data:image/png;base64,iVBORw0KGgo=
                        name:
                          description: Nombre del archivo de imagen.
                          type:
                            - string
                            - 'null'
                          example: foto_perfil.png
                    social_security_branch_id:
                      description: Identificador único (ID) asignado a la sucursal de seguridad social en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    cost_center_id:
                      description: Identificador único (ID) asignado al centro de costos en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                    demo_flag:
                      description: Indica si se debe crear una persona de prueba (demo). Si es `true`, solo se requieren `name`, `last_name` y `base_salary`.
                      type: boolean
                      example: false
                    initial_day:
                      description: Fecha de inicio del contrato en formato YYYY-MM-DD. Requerido para personas regulares.
                      type: string
                      format: date
                      example: '2024-01-15'
                    end_day:
                      description: Fecha de fin del contrato en formato YYYY-MM-DD. Requerido cuando `term` es `fixed`.
                      type:
                        - string
                        - 'null'
                      example: null
                    category:
                      description: Categoría del contrato. Requerido para personas regulares.
                      $ref: '#/components/schemas/ContractCategory'
                    term:
                      description: 'Duración del contrato. Requerido para personas regulares. Valores posibles: indefinite (indefinido), fixed (término fijo), project (obra o labor).'
                      type: string
                      enum:
                        - indefinite
                        - fixed
                        - project
                      example: indefinite
                    health_provider_id:
                      description: Identificador único (ID) asignado a la EPS en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    pension_provider_id:
                      description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    severance_provider_id:
                      description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 16881701-ff67-5895-913b-dfdf4ab03797
                    risk_type:
                      description: Código del tipo de riesgo ARL del centro de trabajo del contrato.
                      $ref: '#/components/schemas/RiskType'
                    base_salary:
                      description: Salario base mensual de la persona en pesos colombianos.
                      type: number
                      example: 3500000
                    wage_category:
                      description: Modalidad del salario. Determina cómo se liquida el salario en nómina.
                      $ref: '#/components/schemas/SalaryCategory'
                    transport_subsidy:
                      description: Indica si la persona tiene derecho a auxilio de transporte.
                      type: boolean
                      example: true
                    remote_work:
                      description: Indica si la persona trabaja en modalidad de teletrabajo.
                      type: boolean
                      example: false
                    contributor_subtype:
                      description: 'Subtipo de cotizante del contrato. Valores posibles: no_subtype (sin subtipo), pensioner (pensionado), age_exempt_contributor (cotizante exonerado por edad), qualified_for_pension (apto para pensión), compensated_contributor (cotizante compensado).'
                      type: string
                      enum:
                        - no_subtype
                        - pensioner
                        - age_exempt_contributor
                        - qualified_for_pension
                        - compensated_contributor
                      example: no_subtype
                    area_id:
                      description: Identificador único (ID) asignado al área en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 53772730-00c6-5292-aa7b-715d1e62962d
                    location_id:
                      description: Identificador único (ID) asignado a la sede en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                    position_id:
                      description: Identificador único (ID) asignado al cargo en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 3ecf3b5d-e414-53d4-a170-f4615e832a78
              required:
                - worker
            examples:
              Persona regular:
                value:
                  worker:
                    name: Patricia
                    last_name: Olivera Rosales
                    document_type: cc
                    id_number: '52799616'
                    email: patricia.olivera@empresa.com
                    active_user: true
                    birthday: '1988-01-15'
                    phone: '3009011100'
                    address: Calle 45
                    city_address_id: 2d16c1b8-1768-5504-993e-d2306280586b
                    payment_method: wire_transfer
                    bank_id: 9e81acc1-7158-5d30-8119-c47d26f8a323
                    account_number: '62113480'
                    account_type: savings_account
                    initial_day: '2024-01-15'
                    category: employee
                    term: indefinite
                    health_provider_id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    pension_provider_id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    severance_provider_id: 16881701-ff67-5895-913b-dfdf4ab03797
                    risk_type: risk_1
                    base_salary: 3500000
                    wage_category: monthly
                    transport_subsidy: true
                    remote_work: false
                    contributor_subtype: no_subtype
                    area_id: 53772730-00c6-5292-aa7b-715d1e62962d
                    location_id: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                    position_id: 3ecf3b5d-e414-53d4-a170-f4615e832a78
              Persona demo:
                value:
                  worker:
                    name: Persona
                    last_name: Demo
                    base_salary: 1500000
                    demo_flag: true
      responses:
        '201':
          description: Persona creada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos completos de la persona recién creada con su contrato y salario.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: ded08047-6d7d-458a-917e-cb21517ae541
                      active:
                        description: Indica si la persona está activa en la empresa.
                        type: boolean
                        example: true
                      name:
                        description: Nombre de la persona.
                        type: string
                        example: Patricia
                      last_name:
                        description: Apellido de la persona.
                        type: string
                        example: Olivera Rosales
                      picture:
                        description: URL de la foto de perfil de la persona. Retorna null si no tiene foto.
                        type:
                          - string
                          - 'null'
                        example: null
                      payroll_id:
                        description: Identificador único (ID) asignado a la nómina activa en la base de datos. Retorna null si no hay nómina liquidada.
                        type:
                          - string
                          - 'null'
                        example: null
                      document_type:
                        $ref: '#/components/schemas/WorkerDocumentType'
                      id_number:
                        description: Número de documento de identificación de la persona.
                        type: string
                        example: '52799616'
                      email:
                        description: Correo electrónico de la persona. Retorna null si no tiene usuario creado.
                        type:
                          - string
                          - 'null'
                        example: patricia.olivera@empresa.com
                      active_user:
                        description: Indica si la persona tiene acceso activo al portal.
                        type: boolean
                        example: true
                      phone:
                        description: Número de teléfono de contacto de la persona.
                        type:
                          - string
                          - 'null'
                        example: '3009011100'
                      address:
                        description: Dirección de residencia de la persona.
                        type:
                          - string
                          - 'null'
                        example: Calle 45
                      city_address:
                        description: Ciudad de residencia de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la ciudad de residencia en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 2d16c1b8-1768-5504-993e-d2306280586b
                          name:
                            description: Nombre de la ciudad de residencia.
                            type:
                              - string
                              - 'null'
                            example: Bogotá, D.C.
                      department_address:
                        description: Departamento de residencia de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al departamento de residencia en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: a7106ca0-b758-570a-8c24-b043a7ef08fb
                          name:
                            description: Nombre del departamento de residencia.
                            type:
                              - string
                              - 'null'
                            example: Cundinamarca
                      birthday:
                        description: Fecha de nacimiento de la persona en formato YYYY-MM-DD.
                        type:
                          - string
                          - 'null'
                        example: '1988-01-15'
                      payment_method:
                        description: Método de pago del salario de la persona.
                        $ref: '#/components/schemas/PaymentMethod'
                      pension_reform_2381_transition_regime:
                        description: Indica si la persona está en régimen de transición de la reforma pensional (Ley 2381 de 2024).
                        type: boolean
                        example: false
                      bank:
                        description: Banco para pago de nómina por transferencia.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al banco en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 9e81acc1-7158-5d30-8119-c47d26f8a323
                          name:
                            description: Nombre del banco.
                            type:
                              - string
                              - 'null'
                            example: Bancolombia
                      account_number:
                        description: Número de cuenta bancaria para pago de nómina por transferencia.
                        type:
                          - string
                          - 'null'
                        example: '62113480'
                      account_type:
                        description: Tipo de cuenta bancaria para pago de nómina.
                        $ref: '#/components/schemas/AccountType'
                      accumulated_holidays:
                        description: Saldo acumulado de días de vacaciones de la persona.
                        type: number
                        example: 5.5
                      rest_days:
                        description: Días de descanso de la persona como arreglo de strings. "0" es domingo, "1" lunes, ..., "6" sábado.
                        type: array
                        items:
                          type: string
                        example:
                          - '0'
                          - '6'
                      terminatable:
                        description: Indica si el contrato de la persona puede liquidarse. Retorna null si no tiene contrato.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      deleteable:
                        description: Indica si la persona puede eliminarse. Es false cuando tiene nóminas liquidadas u otros registros históricos.
                        type: boolean
                        example: false
                      demo_flag:
                        description: Indica si la persona es de prueba (demo). Las personas demo se pueden eliminar sin restricciones.
                        type: boolean
                        example: false
                      multiple_contracts:
                        description: Indica si la persona tiene más de un contrato registrado en la empresa.
                        type: boolean
                        example: false
                      finish_registration:
                        description: Indica si la persona ha completado el proceso de registro con todos los datos requeridos.
                        type: boolean
                        example: true
                      finish_onboarding:
                        description: Indica si la persona completó el proceso de onboarding digital.
                        type: boolean
                        example: false
                      finish_onboarding_at:
                        description: Fecha y hora en que la persona completó el onboarding en formato ISO 8601. Retorna null si no lo ha completado.
                        type:
                          - string
                          - 'null'
                        example: null
                      retention_configuration:
                        description: Indica si la persona tiene configuración de retención en la fuente.
                        type: boolean
                        example: false
                      payroll_retention:
                        description: Indica si la persona tiene retención activa en la nómina actual.
                        type: boolean
                        example: false
                      recurrent_concepts_incomes_total:
                        description: Suma mensual de conceptos recurrentes de ingresos activos de la persona en pesos colombianos.
                        type: integer
                        example: 200000
                      recurrent_concepts_deductions_total:
                        description: Suma mensual de conceptos recurrentes de deducciones activos y cuotas de préstamos de la persona en pesos colombianos.
                        type: integer
                        example: 50000
                      city:
                        description: Nombre de la ciudad de trabajo de la persona (sede del contrato). Retorna null si no aplica.
                        type:
                          - string
                          - 'null'
                        example: Bogotá
                      department:
                        description: Nombre del departamento de trabajo de la persona (sede del contrato). Retorna null si no aplica.
                        type:
                          - string
                          - 'null'
                        example: Cundinamarca
                      contract_id:
                        description: Identificador único (ID) asignado al contrato activo de la persona en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: cb8e6c5f-285f-4742-8357-e7e406d38875
                      apply_art102_cst:
                        description: Indica si el contrato aplica el artículo 102 del Código Sustantivo del Trabajo (salario integral).
                        type:
                          - boolean
                          - 'null'
                        example: false
                      contract_category:
                        description: Categoría del contrato activo de la persona. Null si no tiene contrato activo.
                        oneOf:
                          - $ref: '#/components/schemas/ContractCategory'
                          - type: 'null'
                      initial_day:
                        description: Fecha de inicio del contrato activo en formato YYYY-MM-DD.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-15'
                      end_day:
                        description: Fecha de fin del contrato activo en formato YYYY-MM-DD. Retorna null si el contrato es indefinido.
                        type:
                          - string
                          - 'null'
                        example: null
                      term:
                        description: 'Duración del contrato activo. Valores posibles: indefinite (indefinido), fixed (término fijo), project (obra o labor).'
                        type:
                          - string
                          - 'null'
                        enum:
                          - indefinite
                          - fixed
                          - project
                        example: indefinite
                      period_end_day:
                        description: Fecha de cierre del periodo de nómina actual de la empresa en formato YYYY-MM-DD. Retorna null si no hay periodo activo.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-31'
                      terminated:
                        description: Indica si el contrato de la persona ha sido liquidado.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      termination:
                        description: Información de la liquidación del contrato. Los campos son null si el contrato no ha sido liquidado.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la liquidación en la base de datos. Retorna null si no está liquidado.
                            type:
                              - string
                              - 'null'
                            example: null
                          date:
                            description: Fecha de la liquidación en formato YYYY-MM-DD. Retorna null si no está liquidado.
                            type:
                              - string
                              - 'null'
                            example: null
                          deleteable:
                            description: Indica si la liquidación puede eliminarse. Retorna null si no está liquidado.
                            type:
                              - boolean
                              - 'null'
                            example: null
                      base_salary:
                        description: Salario base mensual de la persona en pesos colombianos.
                        type: integer
                        example: 3500000
                      wage_id:
                        description: Identificador único (ID) asignado al salario activo de la persona en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: 62af0f36-e765-41b9-b6c2-2899501151db
                      wage_category:
                        description: Modalidad del salario activo de la persona.
                        $ref: '#/components/schemas/SalaryCategory'
                      transport_subsidy:
                        description: Indica si la persona tiene derecho a auxilio de transporte.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      remote_work:
                        description: Indica si la persona trabaja en modalidad de teletrabajo.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      contract_detail:
                        description: Información del detalle del contrato activo de la persona con subtipo de cotizante y centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 730bad0c-03e6-4016-a1d1-fd94ca5b2292
                          contributor_subtype:
                            description: 'Subtipo de cotizante del detalle del contrato. Valores posibles: no_subtype, pensioner, age_exempt_contributor, qualified_for_pension, compensated_contributor.'
                            type:
                              - string
                              - 'null'
                            example: no_subtype
                          initial_day:
                            description: Fecha de inicio del detalle de contrato en formato YYYY-MM-DD.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-15'
                          end_day:
                            description: Fecha de fin del detalle de contrato en formato YYYY-MM-DD. Retorna null si no tiene fecha de fin.
                            type:
                              - string
                              - 'null'
                            example: null
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: cb8e6c5f-285f-4742-8357-e7e406d38875
                          deleteable:
                            description: Indica si el detalle de contrato puede eliminarse.
                            type:
                              - boolean
                              - 'null'
                            example: false
                      contract_position_history:
                        description: Historial de cargo, sede y área actual de la persona en el contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: a1b2c3d4-1234-5678-abcd-ef0123456789
                          initial_day:
                            description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-15'
                          end_day:
                            description: Fecha de fin del historial de cargo en formato YYYY-MM-DD. Retorna null si es el cargo actual.
                            type:
                              - string
                              - 'null'
                            example: null
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este historial de cargo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: cb8e6c5f-285f-4742-8357-e7e406d38875
                          area:
                            description: Área organizacional asignada en este historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al área en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 53772730-00c6-5292-aa7b-715d1e62962d
                              name:
                                description: Nombre del área.
                                type:
                                  - string
                                  - 'null'
                                example: Tecnología
                          location:
                            description: Sede asignada en este historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sede en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                              name:
                                description: Nombre de la sede.
                                type:
                                  - string
                                  - 'null'
                                example: Sede Principal Bogotá
                          position:
                            description: Cargo asignado en este historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al cargo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                              name:
                                description: Nombre del cargo.
                                type:
                                  - string
                                  - 'null'
                                example: Desarrollador de Software
                          deleteable:
                            description: Indica si este registro de historial de cargo puede eliminarse.
                            type:
                              - boolean
                              - 'null'
                            example: false
                      work_center:
                        description: Centro de trabajo asignado al contrato de la persona. Retorna objeto vacío si no tiene centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                            type: string
                            example: aaf4a611-3293-594c-9054-9d77df5aa372
                          name:
                            description: Nombre del centro de trabajo con su nivel de riesgo incluido.
                            type: string
                            example: Centro de Trabajo Principal - Riesgo 1 - Mínimo
                          risk_type:
                            description: Nombre del tipo de riesgo ARL asociado al centro de trabajo.
                            type: string
                            example: Riesgo 1 - Mínimo
                      risk_type:
                        description: |
                          Código del tipo de riesgo ARL del centro de trabajo.

                          Valores posibles:
                          * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
                          * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
                          * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
                          * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
                          * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)

                          `null` si no tiene centro de trabajo asignado.
                        type:
                          - string
                          - 'null'
                        enum:
                          - risk_1
                          - risk_2
                          - risk_3
                          - risk_4
                          - risk_5
                        example: risk_1
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo.
                        type: boolean
                        example: false
                      health_provider:
                        description: EPS (Entidad Promotora de Salud) de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la EPS en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name:
                            description: Nombre de la EPS.
                            type:
                              - string
                              - 'null'
                            example: Compensar EPS
                      pension_provider:
                        description: Fondo de pensiones de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name:
                            description: Nombre del fondo de pensiones.
                            type:
                              - string
                              - 'null'
                            example: Porvenir
                      severance_provider:
                        description: Fondo de cesantías de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 16881701-ff67-5895-913b-dfdf4ab03797
                          name:
                            description: Nombre del fondo de cesantías.
                            type:
                              - string
                              - 'null'
                            example: Fondo Nacional del Ahorro
                      risk_provider:
                        description: Aseguradora de riesgos laborales ARL de la persona. Solo presente para contratos con riesgo laboral activo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la ARL en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: null
                          name:
                            description: Nombre de la ARL.
                            type:
                              - string
                              - 'null'
                            example: null
                      area:
                        description: Área organizacional actual de la persona en su contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al área en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 53772730-00c6-5292-aa7b-715d1e62962d
                          name:
                            description: Nombre del área.
                            type:
                              - string
                              - 'null'
                            example: Tecnología
                      compensation_fund:
                        description: Caja de compensación familiar de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la caja de compensación en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: null
                          name:
                            description: Nombre de la caja de compensación.
                            type:
                              - string
                              - 'null'
                            example: null
                      cost_center:
                        description: Centro de costos al que pertenece la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de costos en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                          name:
                            description: Nombre del centro de costos.
                            type:
                              - string
                              - 'null'
                            example: Centro de Costos Principal
                      location:
                        description: Sede actual de la persona en su contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sede en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                          name:
                            description: Nombre de la sede.
                            type:
                              - string
                              - 'null'
                            example: Sede Principal Bogotá
                      position:
                        description: Cargo actual de la persona en su contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al cargo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                          name:
                            description: Nombre del cargo.
                            type:
                              - string
                              - 'null'
                            example: Desarrollador de Software
                      social_security_branch:
                        description: Sucursal de seguridad social asignada a la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sucursal de seguridad social en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name:
                            description: Nombre de la sucursal de seguridad social.
                            type:
                              - string
                              - 'null'
                            example: Sucursal Bogotá
              example:
                data:
                  id: ded08047-6d7d-458a-917e-cb21517ae541
                  active: true
                  name: Patricia
                  last_name: Olivera Rosales
                  picture: null
                  payroll_id: null
                  document_type: cc
                  id_number: '52799616'
                  email: patricia.olivera@empresa.com
                  active_user: true
                  phone: '3009011100'
                  address: Calle 45
                  city_address:
                    id: 2d16c1b8-1768-5504-993e-d2306280586b
                    name: Bogotá, D.C.
                  department_address:
                    id: a7106ca0-b758-570a-8c24-b043a7ef08fb
                    name: Cundinamarca
                  birthday: '1988-01-15'
                  payment_method: wire_transfer
                  pension_reform_2381_transition_regime: false
                  bank:
                    id: 9e81acc1-7158-5d30-8119-c47d26f8a323
                    name: Bancolombia
                  account_number: '62113480'
                  account_type: savings_account
                  accumulated_holidays: 0
                  rest_days:
                    - '0'
                    - '6'
                  terminatable: false
                  deleteable: true
                  demo_flag: false
                  multiple_contracts: false
                  finish_registration: true
                  finish_onboarding: false
                  finish_onboarding_at: null
                  retention_configuration: false
                  payroll_retention: false
                  recurrent_concepts_incomes_total: 0
                  recurrent_concepts_deductions_total: 0
                  city: Bogotá
                  department: Cundinamarca
                  contract_id: cb8e6c5f-285f-4742-8357-e7e406d38875
                  apply_art102_cst: false
                  contract_category: employee
                  initial_day: '2024-01-15'
                  end_day: null
                  term: indefinite
                  period_end_day: '2024-01-31'
                  terminated: false
                  termination:
                    id: null
                    date: null
                    deleteable: null
                  base_salary: 3500000
                  wage_id: 62af0f36-e765-41b9-b6c2-2899501151db
                  wage_category: monthly
                  transport_subsidy: true
                  remote_work: false
                  contract_detail:
                    id: 730bad0c-03e6-4016-a1d1-fd94ca5b2292
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-15'
                    end_day: null
                    contract_id: cb8e6c5f-285f-4742-8357-e7e406d38875
                    deleteable: false
                  contract_position_history:
                    id: a1b2c3d4-1234-5678-abcd-ef0123456789
                    initial_day: '2024-01-15'
                    end_day: null
                    contract_id: cb8e6c5f-285f-4742-8357-e7e406d38875
                    area:
                      id: 53772730-00c6-5292-aa7b-715d1e62962d
                      name: Tecnología
                    location:
                      id: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                      name: Sede Principal Bogotá
                    position:
                      id: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                      name: Desarrollador de Software
                    deleteable: false
                  work_center:
                    id: aaf4a611-3293-594c-9054-9d77df5aa372
                    name: Centro de Trabajo Principal - Riesgo 1 - Mínimo
                    risk_type: Riesgo 1 - Mínimo
                  risk_type: risk_1
                  high_risk_pension: false
                  health_provider:
                    id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    name: Compensar EPS
                  pension_provider:
                    id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    name: Porvenir
                  severance_provider:
                    id: 16881701-ff67-5895-913b-dfdf4ab03797
                    name: Fondo Nacional del Ahorro
                  risk_provider:
                    id: null
                    name: null
                  area:
                    id: 53772730-00c6-5292-aa7b-715d1e62962d
                    name: Tecnología
                  compensation_fund:
                    id: null
                    name: null
                  cost_center:
                    id: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                    name: Centro de Costos Principal
                  location:
                    id: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                    name: Sede Principal Bogotá
                  position:
                    id: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                    name: Desarrollador de Software
                  social_security_branch:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Sucursal Bogotá
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 40ac62bc-e6c2-456a-9b5d-70f6bd88e71d
  /v1/{company_id}/workers/income_certificate:
    get:
      operationId: indexWorkersIncomeCertificate
      tags:
        - Certificados de ingresos
      summary: Generar certificados de ingresos de todas las personas
      description: |
        **¿Qué hace este endpoint?**

        Encola la generación de los certificados de ingresos de todas las personas de la empresa para un año fiscal.
        El resultado se publica vía Firebase cuando el archivo esté listo.

        **¿Cuándo usar este endpoint?**

        * Generar masivamente los certificados de ingresos de todas las personas al cierre del año fiscal.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Siempre asíncrono:** Este endpoint siempre procesa en segundo plano. El archivo se publica en Firebase en la ruta `{company_id}/income_certificate`.
        * **`certificate_year`:** Obligatorio. Debe ser un valor numérico. Si no hay nóminas liquidadas para el año indicado, el endpoint retorna 422.
      parameters:
        - in: query
          required: true
          name: certificate_year
          description: Año fiscal para el cual se generan los certificados. Debe ser un valor numérico (ej. 2024).
          schema:
            type: integer
            example: 2024
        - in: query
          required: false
          name: file_format
          schema:
            $ref: '#/components/schemas/CertificateFileFormat'
      responses:
        '200':
          description: Generación encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento. El archivo se notifica vía Firebase cuando esté listo.
                        type: string
                        example: Procesando
                required:
                  - data
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '422':
          description: Año inválido / Sin nóminas para el año indicado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Año inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Año es inválido.
                        object: year
                Sin nóminas para el año indicado:
                  value:
                    error:
                      - code: '0601'
                        index: 0
                        message: No hay información para generar el archivo.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
  /v1/{company_id}/workers_retention_summary_file/{period_id}:
    get:
      operationId: showWorkersRetentionSummaryFile
      tags:
        - Archivos de retefuente
      summary: Generar resumen de retención del periodo
      description: |
        **¿Qué hace este endpoint?**

        Genera un archivo con el resumen de retención en la fuente de todas las personas
        de un periodo de nómina.

        **¿Cuándo usar este endpoint?**

        * Obtener el consolidado de retención en la fuente de todas las personas de un periodo para revisión contable.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Siempre asíncrono:** El archivo se publica en Firebase en la ruta `users/{user_id}/periods/{period_id}/workers_retention_summary`.
      responses:
        '200':
          description: Generación encolada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento. El archivo se notifica vía Firebase cuando esté listo.
                        type: string
                        example: Procesando
                required:
                  - data
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 120a6990-830e-4304-9779-f0c7aaad9415
      - in: path
        required: true
        name: period_id
        description: Identificador único (ID) asignado al periodo de nómina en la base de datos.
        schema:
          type: string
          example: 86e4bbab-7a86-536e-85a0-2ac57955857d
  /v1/{company_id}/workers/wages_update:
    get:
      operationId: indexWagesUpdate
      tags:
        - Salarios
      summary: Listar salarios para actualización masiva
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado de personas activas con su salario actual y el salario mínimo sugerido
        para la próxima actualización, considerando el tipo de contrato y la modalidad salarial.

        **¿Cuándo usar este endpoint?**

        * Obtener la lista de personas cuyo salario puede ser actualizado antes de iniciar el proceso de actualización masiva.
        * Identificar qué personas tienen un salario por debajo del mínimo sugerido para el próximo periodo.
        * Filtrar personas por nombre o número de documento antes de actualizar sus salarios.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Sin personas activas:** Retorna `422` si la empresa no tiene personas activas registradas.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca personas por nombre completo o número de documento. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Juan Pérez
      responses:
        '200':
          description: Listado de salarios para actualización masiva
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo con la información salarial de cada persona activa de la empresa.
                    type: array
                    items:
                      type: object
                      properties:
                        worker_id:
                          description: Identificador único (ID) asignado a la persona en la base de datos.
                          type: string
                          example: 353b16dc-ce2b-5bd7-8345-363ca35c9cab
                        name:
                          description: Nombre completo de la persona.
                          type: string
                          example: María González
                        picture:
                          description: URL de la foto de perfil de la persona. Null si no tiene foto registrada.
                          type:
                            - string
                            - 'null'
                          example: https://storage.googleapis.com/nominapp/workers/foto.jpg
                        contract_category:
                          $ref: '#/components/schemas/ContractCategory'
                        contract_initial_day:
                          description: Fecha de inicio del contrato activo de la persona en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2022-01-01'
                        wage_category:
                          $ref: '#/components/schemas/SalaryCategory'
                        base_salary:
                          description: Monto del salario base actual de la persona en pesos colombianos (COP).
                          type: integer
                          example: 1300000
                        new_base_salary:
                          description: Monto del salario mínimo sugerido para la próxima actualización en pesos colombianos (COP), calculado según el tipo de contrato.
                          type: integer
                          example: 1423500
                        date_new_salary:
                          description: Fecha de inicio sugerida para el nuevo salario en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-01-01'
                        transport_subsidy:
                          description: Indica si la persona tiene derecho al auxilio de transporte con el salario actual.
                          type: boolean
                          example: true
                        remote_work:
                          description: Indica si la persona trabaja de forma remota (teletrabajo).
                          type: boolean
                          example: false
                  filters:
                    description: Información de paginación y búsqueda aplicada a los resultados.
                    type: object
                    properties:
                      page:
                        description: Página actual de los resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de registros por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Cadena vacía si no se especificó ningún filtro.
                        type: string
                      total_records:
                        description: Total de personas activas que coinciden con la búsqueda.
                        type: integer
                        example: 45
              example:
                data:
                  - worker_id: 353b16dc-ce2b-5bd7-8345-363ca35c9cab
                    name: María González
                    picture: null
                    contract_category: employee
                    contract_initial_day: '2022-01-01'
                    wage_category: monthly
                    base_salary: 1300000
                    new_base_salary: 1423500
                    date_new_salary: '2024-01-01'
                    transport_subsidy: true
                    remote_work: false
                  - worker_id: fc7367a9-64b8-54fc-bbdd-2b892c741759
                    name: Carlos Rodríguez
                    picture: null
                    contract_category: employee
                    contract_initial_day: '2022-01-01'
                    wage_category: integral_salary
                    base_salary: 10765508
                    new_base_salary: 13000000
                    date_new_salary: '2024-01-01'
                    transport_subsidy: false
                    remote_work: false
                filters:
                  page: 1
                  per_page: 20
                  search: ''
                  total_records: 45
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin personas activas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '2601'
                    index: 0
                    message: La compañía no tiene personas activas.
                    object: company
    post:
      operationId: createWageUpdate
      tags:
        - Salarios
      summary: Actualizar salario de persona
      description: |
        **¿Qué hace este endpoint?**

        Crea un nuevo salario para la persona activa especificada, reemplazando el salario vigente
        de su contrato activo.

        **¿Cuándo usar este endpoint?**

        * Aplicar el nuevo salario mínimo a una persona específica tras consultar el listado de actualización masiva.
        * Registrar un incremento salarial individual sin liquidar el contrato.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Sin personas activas:** Retorna `422` si la empresa no tiene personas activas registradas.
        * **Sin contrato activo:** Retorna `422` si la persona indicada no tiene un contrato activo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                wage:
                  description: Objeto con los datos del nuevo salario a registrar.
                  type: object
                  properties:
                    worker_id:
                      description: Identificador único (ID) asignado a la persona en la base de datos.
                      type: string
                      example: 353b16dc-ce2b-5bd7-8345-363ca35c9cab
                    base_salary:
                      description: Monto del nuevo salario base en pesos colombianos (COP).
                      type: integer
                      example: 1423500
                    category:
                      $ref: '#/components/schemas/SalaryCategory'
                    initial_day:
                      description: Fecha de inicio de vigencia del nuevo salario en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-01-01'
                    transport_subsidy:
                      description: Indica si la persona tiene derecho al auxilio de transporte.
                      type: boolean
                      example: true
                    remote_work:
                      description: Indica si la persona trabaja de forma remota (teletrabajo).
                      type: boolean
                      example: false
                  required:
                    - worker_id
                    - base_salary
                    - category
                    - initial_day
                    - transport_subsidy
                    - remote_work
              required:
                - wage
      responses:
        '200':
          description: Salario actualizado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con los atributos del salario recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al salario en la base de datos.
                        type: string
                        example: b67cdfbd-9070-42e0-9ac3-78da9f07fb0a
                      base_salary:
                        description: Monto del salario base en pesos colombianos (COP).
                        type: integer
                        example: 1423500
                      category:
                        $ref: '#/components/schemas/SalaryCategory'
                      initial_day:
                        description: Fecha de inicio de vigencia del salario en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin de vigencia del salario en formato YYYY-MM-DD. Null si es el salario vigente.
                        type:
                          - string
                          - 'null'
                        example: null
                      transport_subsidy:
                        description: Indica si la persona tiene derecho al auxilio de transporte.
                        type: boolean
                        example: true
                      remote_work:
                        description: Indica si la persona trabaja de forma remota (teletrabajo).
                        type: boolean
                        example: false
                      contract_id:
                        description: Identificador único (ID) asignado al contrato al que pertenece el salario en la base de datos.
                        type: string
                        example: b5ee90e9-921c-55c5-8dda-728eea651b2d
                      created_at:
                        description: Fecha y hora de creación del registro en formato ISO 8601.
                        type: string
                        format: date-time
                        example: '2024-01-01T08:00:00.000Z'
                      updated_at:
                        description: Fecha y hora de la última actualización del registro en formato ISO 8601.
                        type: string
                        format: date-time
                        example: '2024-01-01T08:00:00.000Z'
              example:
                data:
                  id: b67cdfbd-9070-42e0-9ac3-78da9f07fb0a
                  base_salary: 1423500
                  category: monthly
                  initial_day: '2024-01-01'
                  end_day: null
                  transport_subsidy: true
                  remote_work: false
                  contract_id: b5ee90e9-921c-55c5-8dda-728eea651b2d
                  created_at: '2024-01-01T08:00:00.000Z'
                  updated_at: '2024-01-01T08:00:00.000Z'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Sin personas activas / Persona sin contrato activo / Salario duplicado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Sin personas activas:
                  value:
                    error:
                      - code: '2601'
                        index: 0
                        message: La compañía no tiene personas activas.
                        object: company
                Persona sin contrato activo:
                  value:
                    error:
                      - code: '2602'
                        index: 0
                        message: La persona no tiene ningún contrato activo
                        object: worker
                Salario duplicado:
                  value:
                    error:
                      - code: '0808'
                        index: 0
                        message: El nuevo salario debe ser diferente al actual.
                        object: wage
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
  /v1/{company_id}/workers/{id}:
    get:
      operationId: showWorker
      tags:
        - Personas
      summary: Obtener persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna la información completa de una persona: datos personales, bancarios, contrato activo, salario, proveedores de seguridad social, historial de cargo, y métricas de conceptos recurrentes.

        **¿Cuándo usar este endpoint?**

        * Obtener los datos completos de una persona para mostrar su perfil detallado antes de editarla.
        * Consultar el estado del contrato, salario y proveedores de seguridad social de una persona antes de procesar su nómina.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Información detallada de la persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos completos de la persona con su contrato, salario y proveedores de seguridad social.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: ded08047-6d7d-458a-917e-cb21517ae541
                      active:
                        description: Indica si la persona está activa en la empresa.
                        type: boolean
                        example: true
                      name:
                        description: Nombre de la persona.
                        type: string
                        example: Patricia
                      last_name:
                        description: Apellido de la persona.
                        type: string
                        example: Olivera Rosales
                      picture:
                        description: URL de la foto de perfil de la persona. Retorna null si no tiene foto.
                        type:
                          - string
                          - 'null'
                        example: https://storage.example.com/pictures/worker.jpg
                      payroll_id:
                        description: Identificador único (ID) asignado a la nómina activa de la persona en la base de datos. Retorna null si no hay nómina liquidada.
                        type:
                          - string
                          - 'null'
                        example: 62af0f36-e765-41b9-b6c2-2899501151dc
                      document_type:
                        $ref: '#/components/schemas/WorkerDocumentType'
                      id_number:
                        description: Número de documento de identificación de la persona.
                        type: string
                        example: '52799616'
                      email:
                        description: Correo electrónico de la persona. Retorna null si no tiene usuario creado.
                        type:
                          - string
                          - 'null'
                        example: patricia.olivera@empresa.com
                      active_user:
                        description: Indica si la persona tiene acceso activo al portal.
                        type: boolean
                        example: true
                      phone:
                        description: Número de teléfono de contacto de la persona.
                        type:
                          - string
                          - 'null'
                        example: '3009011100'
                      address:
                        description: Dirección de residencia de la persona.
                        type:
                          - string
                          - 'null'
                        example: Calle 45
                      city_address:
                        description: Ciudad de residencia de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la ciudad de residencia en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 2d16c1b8-1768-5504-993e-d2306280586b
                          name:
                            description: Nombre de la ciudad de residencia.
                            type:
                              - string
                              - 'null'
                            example: Bogotá, D.C.
                      department_address:
                        description: Departamento de residencia de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al departamento de residencia en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: a7106ca0-b758-570a-8c24-b043a7ef08fb
                          name:
                            description: Nombre del departamento de residencia.
                            type:
                              - string
                              - 'null'
                            example: Cundinamarca
                      birthday:
                        description: Fecha de nacimiento de la persona en formato YYYY-MM-DD.
                        type:
                          - string
                          - 'null'
                        example: '1988-01-15'
                      payment_method:
                        description: Método de pago del salario de la persona. Null si no está configurado.
                        oneOf:
                          - $ref: '#/components/schemas/PaymentMethod'
                          - type: 'null'
                      pension_reform_2381_transition_regime:
                        description: Indica si la persona está en régimen de transición de la reforma pensional (Ley 2381 de 2024).
                        type: boolean
                        example: false
                      bank:
                        description: Banco para pago de nómina por transferencia.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al banco en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 9e81acc1-7158-5d30-8119-c47d26f8a323
                          name:
                            description: Nombre del banco.
                            type:
                              - string
                              - 'null'
                            example: Bancolombia
                      account_number:
                        description: Número de cuenta bancaria para pago de nómina por transferencia.
                        type:
                          - string
                          - 'null'
                        example: '62113480'
                      account_type:
                        description: Tipo de cuenta bancaria para pago de nómina. Null si no está configurado.
                        oneOf:
                          - $ref: '#/components/schemas/AccountType'
                          - type: 'null'
                      accumulated_holidays:
                        description: Saldo acumulado de días de vacaciones de la persona.
                        type: number
                        example: 5.5
                      rest_days:
                        description: Días de descanso de la persona como arreglo de strings. "0" es domingo, "1" lunes, ..., "6" sábado.
                        type: array
                        items:
                          type: string
                        example:
                          - '0'
                          - '6'
                      terminatable:
                        description: Indica si el contrato de la persona puede liquidarse. Retorna null si no tiene contrato.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      deleteable:
                        description: Indica si la persona puede eliminarse. Es false cuando tiene nóminas liquidadas u otros registros históricos.
                        type: boolean
                        example: false
                      demo_flag:
                        description: Indica si la persona es de prueba (demo). Las personas demo se pueden eliminar sin restricciones.
                        type: boolean
                        example: false
                      multiple_contracts:
                        description: Indica si la persona tiene más de un contrato registrado en la empresa.
                        type: boolean
                        example: false
                      finish_registration:
                        description: Indica si la persona ha completado el proceso de registro con todos los datos requeridos.
                        type: boolean
                        example: true
                      finish_onboarding:
                        description: Indica si la persona completó el proceso de onboarding digital.
                        type: boolean
                        example: false
                      finish_onboarding_at:
                        description: Fecha y hora en que la persona completó el onboarding en formato ISO 8601. Retorna null si no lo ha completado.
                        type:
                          - string
                          - 'null'
                        format: date-time
                        example: '2025-01-15T10:30:00.000Z'
                      retention_configuration:
                        description: Indica si la persona tiene configuración de retención en la fuente.
                        type: boolean
                        example: false
                      payroll_retention:
                        description: Indica si la persona tiene retención activa en la nómina actual.
                        type: boolean
                        example: false
                      recurrent_concepts_incomes_total:
                        description: Suma mensual de conceptos recurrentes de ingresos activos de la persona en pesos colombianos.
                        type: integer
                        example: 200000
                      recurrent_concepts_deductions_total:
                        description: Suma mensual de conceptos recurrentes de deducciones activos y cuotas de préstamos de la persona en pesos colombianos.
                        type: integer
                        example: 50000
                      city:
                        description: Nombre de la ciudad de trabajo de la persona (sede del contrato). Retorna null si no aplica.
                        type:
                          - string
                          - 'null'
                        example: Bogotá
                      department:
                        description: Nombre del departamento de trabajo de la persona (sede del contrato). Retorna null si no aplica.
                        type:
                          - string
                          - 'null'
                        example: Cundinamarca
                      contract_id:
                        description: Identificador único (ID) asignado al contrato activo de la persona en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: cb8e6c5f-285f-4742-8357-e7e406d38875
                      apply_art102_cst:
                        description: Indica si el contrato aplica el artículo 102 del Código Sustantivo del Trabajo (salario integral).
                        type:
                          - boolean
                          - 'null'
                        example: false
                      contract_category:
                        description: Categoría del contrato activo de la persona. Null si no tiene contrato activo.
                        oneOf:
                          - $ref: '#/components/schemas/ContractCategory'
                          - type: 'null'
                      initial_day:
                        description: Fecha de inicio del contrato activo en formato YYYY-MM-DD.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-15'
                      end_day:
                        description: Fecha de fin del contrato activo en formato YYYY-MM-DD. Retorna null si el contrato es indefinido.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      term:
                        description: 'Duración del contrato activo. Valores posibles: indefinite (indefinido), fixed (término fijo), project (obra o labor).'
                        type:
                          - string
                          - 'null'
                        enum:
                          - indefinite
                          - fixed
                          - project
                        example: indefinite
                      period_end_day:
                        description: Fecha de cierre del periodo de nómina actual de la empresa en formato YYYY-MM-DD. Retorna null si no hay periodo activo.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-31'
                      terminated:
                        description: Indica si el contrato de la persona ha sido liquidado.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      termination:
                        description: Información de la liquidación del contrato. Los campos son null si el contrato no ha sido liquidado.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la liquidación en la base de datos. Retorna null si no está liquidado.
                            type:
                              - string
                              - 'null'
                            example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                          date:
                            description: Fecha de la liquidación en formato YYYY-MM-DD. Retorna null si no está liquidado.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          deleteable:
                            description: Indica si la liquidación puede eliminarse. Retorna null si no está liquidado.
                            type:
                              - boolean
                              - 'null'
                            example: true
                      base_salary:
                        description: Salario base mensual de la persona en pesos colombianos. Null si no tiene salario configurado.
                        type:
                          - integer
                          - 'null'
                        example: 3500000
                      wage_id:
                        description: Identificador único (ID) asignado al salario activo de la persona en la base de datos.
                        type:
                          - string
                          - 'null'
                        example: 62af0f36-e765-41b9-b6c2-2899501151db
                      wage_category:
                        description: Modalidad del salario activo de la persona. Null si no tiene salario configurado.
                        oneOf:
                          - $ref: '#/components/schemas/SalaryCategory'
                          - type: 'null'
                      transport_subsidy:
                        description: Indica si la persona tiene derecho a auxilio de transporte.
                        type:
                          - boolean
                          - 'null'
                        example: true
                      remote_work:
                        description: Indica si la persona trabaja en modalidad de teletrabajo.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      contract_detail:
                        description: Información del detalle del contrato activo de la persona con subtipo de cotizante y centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 730bad0c-03e6-4016-a1d1-fd94ca5b2292
                          contributor_subtype:
                            description: Subtipo de cotizante aplicado al detalle del contrato para la liquidación de seguridad social. Null si no tiene contrato activo.
                            oneOf:
                              - $ref: '#/components/schemas/ContributorSubtype'
                              - type: 'null'
                          initial_day:
                            description: Fecha de inicio del detalle de contrato en formato YYYY-MM-DD.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-15'
                          end_day:
                            description: Fecha de fin del detalle de contrato en formato YYYY-MM-DD. Retorna null si no tiene fecha de fin.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: cb8e6c5f-285f-4742-8357-e7e406d38875
                          deleteable:
                            description: Indica si el detalle de contrato puede eliminarse.
                            type:
                              - boolean
                              - 'null'
                            example: false
                      contract_position_history:
                        description: Historial de cargo, sede y área actual de la persona en el contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: a1b2c3d4-1234-5678-abcd-ef0123456789
                          initial_day:
                            description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-15'
                          end_day:
                            description: Fecha de fin del historial de cargo en formato YYYY-MM-DD. Retorna null si es el cargo actual.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: cb8e6c5f-285f-4742-8357-e7e406d38875
                          area:
                            description: Área organizacional asignada en este historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al área en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 53772730-00c6-5292-aa7b-715d1e62962d
                              name:
                                description: Nombre del área.
                                type:
                                  - string
                                  - 'null'
                                example: Tecnología
                          location:
                            description: Sede asignada en este historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sede en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                              name:
                                description: Nombre de la sede.
                                type:
                                  - string
                                  - 'null'
                                example: Sede Principal Bogotá
                          position:
                            description: Cargo asignado en este historial de cargo.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al cargo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                              name:
                                description: Nombre del cargo.
                                type:
                                  - string
                                  - 'null'
                                example: Desarrollador de Software
                          deleteable:
                            description: Indica si este registro de historial de cargo puede eliminarse.
                            type:
                              - boolean
                              - 'null'
                            example: false
                      work_center:
                        description: Centro de trabajo asignado al contrato de la persona. Retorna objeto vacío si no tiene centro de trabajo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                            type: string
                            example: aaf4a611-3293-594c-9054-9d77df5aa372
                          name:
                            description: Nombre del centro de trabajo con su nivel de riesgo incluido.
                            type: string
                            example: Centro de Trabajo Principal - Riesgo 1 - Mínimo
                          risk_type:
                            description: Nombre del tipo de riesgo ARL asociado al centro de trabajo.
                            type: string
                            example: Riesgo 1 - Mínimo
                      risk_type:
                        description: Código del tipo de riesgo ARL del centro de trabajo. Null si no tiene centro de trabajo asignado.
                        oneOf:
                          - $ref: '#/components/schemas/RiskType'
                          - type: 'null'
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo. Null si no tiene contrato activo.
                        type:
                          - boolean
                          - 'null'
                        example: false
                      health_provider:
                        description: EPS (Entidad Promotora de Salud) de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la EPS en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name:
                            description: Nombre de la EPS.
                            type:
                              - string
                              - 'null'
                            example: Compensar EPS
                      pension_provider:
                        description: Fondo de pensiones de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name:
                            description: Nombre del fondo de pensiones.
                            type:
                              - string
                              - 'null'
                            example: Porvenir
                      severance_provider:
                        description: Fondo de cesantías de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 16881701-ff67-5895-913b-dfdf4ab03797
                          name:
                            description: Nombre del fondo de cesantías.
                            type:
                              - string
                              - 'null'
                            example: Fondo Nacional del Ahorro
                      risk_provider:
                        description: Aseguradora de riesgos laborales ARL de la persona. Solo presente para contratos con riesgo laboral activo.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la ARL en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 7a3f1c2d-8b4e-5f60-a9d2-3c1e7b8f9a01
                          name:
                            description: Nombre de la ARL.
                            type:
                              - string
                              - 'null'
                            example: Positiva Compañía de Seguros
                      area:
                        description: Área organizacional actual de la persona en su contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al área en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 53772730-00c6-5292-aa7b-715d1e62962d
                          name:
                            description: Nombre del área.
                            type:
                              - string
                              - 'null'
                            example: Tecnología
                      compensation_fund:
                        description: Caja de compensación familiar de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la caja de compensación en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 4d2a9b1e-3f7c-5e80-b6d4-8a2f1c3d5e70
                          name:
                            description: Nombre de la caja de compensación.
                            type:
                              - string
                              - 'null'
                            example: Compensar
                      location:
                        description: Sede actual de la persona en su contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sede en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                          name:
                            description: Nombre de la sede.
                            type:
                              - string
                              - 'null'
                            example: Sede Principal Bogotá
                      position:
                        description: Cargo actual de la persona en su contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al cargo en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                          name:
                            description: Nombre del cargo.
                            type:
                              - string
                              - 'null'
                            example: Desarrollador de Software
                      social_security_branch:
                        description: Sucursal de seguridad social asignada a la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la sucursal de seguridad social en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          name:
                            description: Nombre de la sucursal de seguridad social.
                            type:
                              - string
                              - 'null'
                            example: Sucursal Bogotá
                      cost_center:
                        description: Centro de costos al que pertenece la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de costos en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                          name:
                            description: Nombre del centro de costos.
                            type:
                              - string
                              - 'null'
                            example: Centro de Costos Principal
                      cost_center_configuration:
                        description: Configuración de centros de costo activa para el contrato de la persona.
                        type: object
                        properties:
                          id:
                            description: Identificador único de la configuración de centros de costo.
                            type:
                              - string
                              - 'null'
                            example: 7f3a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c
                          initial_day:
                            description: Fecha de inicio de la configuración.
                            type:
                              - string
                              - 'null'
                            example: '2024-01-15'
                          end_day:
                            description: Fecha de fin de la configuración.
                            type:
                              - string
                              - 'null'
                            example: null
                          editable:
                            description: Indica si la configuración puede ser editada.
                            type: boolean
                            example: true
                          deleteable:
                            description: Indica si la configuración puede ser eliminada.
                            type: boolean
                            example: false
                          items:
                            description: Distribución porcentual entre centros de costo.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único del ítem.
                                  type: string
                                  example: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
                                cost_center_id:
                                  description: Identificador del centro de costo.
                                  type: string
                                  example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                                cost_center_name:
                                  description: Nombre del centro de costo.
                                  type: string
                                  example: Centro de Costos Principal
                                cost_center_accounting_code:
                                  description: Código contable del centro de costo.
                                  type: string
                                  example: '1001'
                                percentage:
                                  description: Porcentaje asignado a este centro de costo.
                                  type: number
                                  example: 100
              example:
                data:
                  id: ded08047-6d7d-458a-917e-cb21517ae541
                  active: true
                  name: Patricia
                  last_name: Olivera Rosales
                  picture: null
                  payroll_id: null
                  document_type: cc
                  id_number: '52799616'
                  email: patricia.olivera@empresa.com
                  active_user: true
                  phone: '3009011100'
                  address: Calle 45
                  city_address:
                    id: 2d16c1b8-1768-5504-993e-d2306280586b
                    name: Bogotá, D.C.
                  department_address:
                    id: a7106ca0-b758-570a-8c24-b043a7ef08fb
                    name: Cundinamarca
                  birthday: '1988-01-15'
                  payment_method: wire_transfer
                  pension_reform_2381_transition_regime: false
                  bank:
                    id: 9e81acc1-7158-5d30-8119-c47d26f8a323
                    name: Bancolombia
                  account_number: '62113480'
                  account_type: savings_account
                  accumulated_holidays: 5.5
                  rest_days:
                    - '0'
                    - '6'
                  terminatable: true
                  deleteable: false
                  demo_flag: false
                  multiple_contracts: false
                  finish_registration: true
                  finish_onboarding: false
                  finish_onboarding_at: null
                  retention_configuration: false
                  payroll_retention: false
                  recurrent_concepts_incomes_total: 200000
                  recurrent_concepts_deductions_total: 50000
                  city: Bogotá
                  department: Cundinamarca
                  contract_id: cb8e6c5f-285f-4742-8357-e7e406d38875
                  apply_art102_cst: false
                  contract_category: employee
                  initial_day: '2024-01-15'
                  end_day: null
                  term: indefinite
                  period_end_day: '2024-01-31'
                  terminated: false
                  termination:
                    id: null
                    date: null
                    deleteable: null
                  base_salary: 3500000
                  wage_id: 62af0f36-e765-41b9-b6c2-2899501151db
                  wage_category: monthly
                  transport_subsidy: true
                  remote_work: false
                  contract_detail:
                    id: 730bad0c-03e6-4016-a1d1-fd94ca5b2292
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-15'
                    end_day: null
                    contract_id: cb8e6c5f-285f-4742-8357-e7e406d38875
                    deleteable: false
                  contract_position_history:
                    id: a1b2c3d4-1234-5678-abcd-ef0123456789
                    initial_day: '2024-01-15'
                    end_day: null
                    contract_id: cb8e6c5f-285f-4742-8357-e7e406d38875
                    area:
                      id: 53772730-00c6-5292-aa7b-715d1e62962d
                      name: Tecnología
                    location:
                      id: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                      name: Sede Principal Bogotá
                    position:
                      id: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                      name: Desarrollador de Software
                    deleteable: false
                  work_center:
                    id: aaf4a611-3293-594c-9054-9d77df5aa372
                    name: Centro de Trabajo Principal - Riesgo 1 - Mínimo
                    risk_type: Riesgo 1 - Mínimo
                  risk_type: risk_1
                  high_risk_pension: false
                  health_provider:
                    id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    name: Compensar EPS
                  pension_provider:
                    id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    name: Porvenir
                  severance_provider:
                    id: 16881701-ff67-5895-913b-dfdf4ab03797
                    name: Fondo Nacional del Ahorro
                  risk_provider:
                    id: null
                    name: null
                  area:
                    id: 53772730-00c6-5292-aa7b-715d1e62962d
                    name: Tecnología
                  compensation_fund:
                    id: null
                    name: null
                  cost_center:
                    id: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                    name: Centro de Costos Principal
                  cost_center_configuration:
                    id: 7f3a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c
                    initial_day: '2024-01-15'
                    end_day: null
                    editable: true
                    deleteable: false
                    items:
                      - id: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
                        cost_center_id: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                        cost_center_name: Centro de Costos Principal
                        cost_center_accounting_code: '1001'
                        percentage: 100
                  location:
                    id: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                    name: Sede Principal Bogotá
                  position:
                    id: 3ecf3b5d-e414-53d4-a170-f4615e832a78
                    name: Desarrollador de Software
                  social_security_branch:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    name: Sucursal Bogotá
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateWorker
      tags:
        - Personas
      summary: Actualizar persona
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los datos de una persona existente: información personal, bancaria, contrato, salario y proveedores de seguridad social.

        **¿Cuándo usar este endpoint?**

        * Actualizar los datos personales o bancarios de una persona cuando cambian.
        * Cambiar la EPS, fondo de pensiones o cesantías de una persona al inicio de un periodo.
        * Modificar el cargo, sede o área de la persona tras un cambio organizacional.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * Las personas demo no permiten modificar `name`, `last_name` ni `id_number`. Solo se puede convertir a persona real mediante el campo `demo_flag: false`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                worker:
                  description: Campos de la persona a actualizar. Solo se necesita enviar los campos que cambian.
                  type: object
                  properties:
                    name:
                      description: Nombre de la persona.
                      type: string
                      example: Patricia
                    last_name:
                      description: Apellido de la persona.
                      type: string
                      example: Olivera Rosales
                    document_type:
                      description: Tipo de documento de identificación.
                      $ref: '#/components/schemas/WorkerDocumentType'
                    id_number:
                      description: Número de documento de identificación.
                      type: string
                      example: '52799616'
                    email:
                      description: Correo electrónico de la persona para su acceso al portal.
                      type: string
                      example: patricia.olivera@empresa.com
                    active_user:
                      description: Indica si la persona debe tener acceso activo al portal.
                      type: boolean
                      example: true
                    active:
                      description: Indica si la persona está activa en la empresa.
                      type: boolean
                      example: true
                    birthday:
                      description: Fecha de nacimiento de la persona en formato YYYY-MM-DD.
                      type:
                        - string
                        - 'null'
                      example: '1988-01-15'
                    phone:
                      description: Número de teléfono de contacto de la persona.
                      type: string
                      example: '3009011100'
                    address:
                      description: Dirección de residencia de la persona.
                      type: string
                      example: Calle 45
                    city_address_id:
                      description: Identificador único (ID) asignado a la ciudad de residencia en la base de datos.
                      type: string
                      example: 2d16c1b8-1768-5504-993e-d2306280586b
                    payment_method:
                      description: Método de pago del salario de la persona.
                      $ref: '#/components/schemas/PaymentMethod'
                    bank_id:
                      description: Identificador único (ID) asignado al banco en la base de datos.
                      type: string
                      example: 9e81acc1-7158-5d30-8119-c47d26f8a323
                    account_number:
                      description: Número de cuenta bancaria para pago de nómina por transferencia.
                      type: string
                      example: '62113480'
                    account_type:
                      description: Tipo de cuenta bancaria para pago de nómina.
                      $ref: '#/components/schemas/AccountType'
                    rest_days:
                      description: Días de descanso de la persona. "0" es domingo, "1" lunes, ..., "6" sábado.
                      type: array
                      items:
                        type: string
                      example:
                        - '0'
                        - '6'
                    picture:
                      description: Foto de perfil de la persona codificada en base64.
                      type:
                        - object
                        - 'null'
                      properties:
                        image:
                          description: Contenido de la imagen en formato base64 con prefijo data URI.
                          type: string
                          example: data:image/png;base64,iVBORw0KGgo=
                        name:
                          description: Nombre del archivo de imagen.
                          type:
                            - string
                            - 'null'
                          example: foto_perfil.png
                    social_security_branch_id:
                      description: Identificador único (ID) asignado a la sucursal de seguridad social en la base de datos.
                      type: string
                      example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    cost_center_id:
                      description: Identificador único (ID) asignado al centro de costos en la base de datos.
                      type: string
                      example: 6c37c2eb-e0e9-5c56-be63-ff652d59c06f
                    demo_flag:
                      description: Permite convertir una persona demo en persona regular enviando `false`. No se puede cambiar a `true` en una persona regular.
                      type: boolean
                      example: false
                    initial_day:
                      description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-01-15'
                    end_day:
                      description: Fecha de fin del contrato en formato YYYY-MM-DD. Requerido cuando `term` es `fixed`.
                      type:
                        - string
                        - 'null'
                      example: '2024-12-31'
                    category:
                      description: Categoría del contrato.
                      $ref: '#/components/schemas/ContractCategory'
                    term:
                      description: Duración del contrato.
                      $ref: '#/components/schemas/ContractTerm'
                    health_provider_id:
                      description: Identificador único (ID) asignado a la EPS en la base de datos.
                      type: string
                      example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    pension_provider_id:
                      description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                      type: string
                      example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    severance_provider_id:
                      description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                      type: string
                      example: 16881701-ff67-5895-913b-dfdf4ab03797
                    risk_type:
                      description: Código del tipo de riesgo ARL del centro de trabajo de la persona.
                      $ref: '#/components/schemas/RiskType'
                    base_salary:
                      description: Salario base mensual de la persona en pesos colombianos.
                      type: integer
                      example: 3500000
                    wage_category:
                      description: Modalidad del salario.
                      $ref: '#/components/schemas/SalaryCategory'
                    transport_subsidy:
                      description: Indica si la persona tiene derecho a auxilio de transporte.
                      type: boolean
                      example: true
                    remote_work:
                      description: Indica si la persona trabaja en modalidad de teletrabajo.
                      type: boolean
                      example: false
                    accumulated_holidays:
                      description: Saldo acumulado de días de vacaciones a ajustar manualmente.
                      type: number
                      example: 5.5
                    finish_onboarding:
                      description: Indica si se debe marcar el onboarding de la persona como completado.
                      type: boolean
                      example: true
                    pension_reform_2381_transition_regime:
                      description: Indica si la persona está en régimen de transición de la reforma pensional (Ley 2381 de 2024).
                      type: boolean
                      example: false
                    area_id:
                      description: Identificador único (ID) asignado al área en la base de datos.
                      type: string
                      example: 53772730-00c6-5292-aa7b-715d1e62962d
                    location_id:
                      description: Identificador único (ID) asignado a la sede en la base de datos.
                      type: string
                      example: 8bfac02d-0e83-57c3-94b6-5b2e79770d20
                    position_id:
                      description: Identificador único (ID) asignado al cargo en la base de datos.
                      type: string
                      example: 3ecf3b5d-e414-53d4-a170-f4615e832a78
              required:
                - worker
      responses:
        '202':
          description: Persona actualizada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos completos de la persona con los cambios aplicados.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: ded08047-6d7d-458a-917e-cb21517ae541
                      active:
                        description: Indica si la persona está activa en la empresa.
                        type: boolean
                        example: true
                      name:
                        description: Nombre de la persona.
                        type: string
                        example: Patricia
                      last_name:
                        description: Apellido de la persona.
                        type: string
                        example: Olivera Rosales
                      document_type:
                        $ref: '#/components/schemas/WorkerDocumentType'
                      id_number:
                        description: Número de documento de identificación de la persona.
                        type: string
                        example: '52799616'
                      payment_method:
                        description: Método de pago del salario de la persona. Null si no está configurado.
                        oneOf:
                          - $ref: '#/components/schemas/PaymentMethod'
                          - type: 'null'
                      account_type:
                        description: Tipo de cuenta bancaria para pago de nómina. Null si no está configurado.
                        oneOf:
                          - $ref: '#/components/schemas/AccountType'
                          - type: 'null'
                      contract_category:
                        description: Categoría del contrato activo de la persona. Null si no tiene contrato activo.
                        oneOf:
                          - $ref: '#/components/schemas/ContractCategory'
                          - type: 'null'
                      wage_category:
                        description: Modalidad del salario activo de la persona. Null si no tiene salario configurado.
                        oneOf:
                          - $ref: '#/components/schemas/SalaryCategory'
                          - type: 'null'
                      base_salary:
                        description: Salario base mensual de la persona en pesos colombianos. Null si no tiene salario configurado.
                        type:
                          - integer
                          - 'null'
                        example: 3500000
              example:
                data:
                  id: ded08047-6d7d-458a-917e-cb21517ae541
                  active: true
                  name: Patricia
                  last_name: Olivera Rosales
                  document_type: cc
                  id_number: '52799616'
                  payment_method: wire_transfer
                  account_type: savings_account
                  contract_category: employee
                  wage_category: monthly
                  base_salary: 3500000
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    delete:
      operationId: destroyWorker
      tags:
        - Personas
      summary: Eliminar persona
      description: |
        **¿Qué hace este endpoint?**

        Elimina permanentemente una persona de la empresa junto con todos sus registros asociados.

        **¿Cuándo usar este endpoint?**

        * Eliminar una persona registrada por error antes de que tenga nóminas liquidadas.
        * Eliminar personas de prueba (demo) que ya no se necesitan.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Suscripción activa:** Requiere que la empresa tenga una suscripción activa al momento de ejecutar la operación.
        * Solo se puede eliminar una persona si no tiene nóminas liquidadas u otros registros históricos. El campo `deleteable` del GET indica si puede eliminarse.
        * Las personas demo (`demo_flag: true`) siempre pueden eliminarse sin restricciones.
      responses:
        '200':
          description: Persona eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La persona ha sido eliminada.
              example:
                data:
                  message: La persona ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 72cbe4f4-faaa-481c-9229-b7b78554196a
  /v1/{company_id}/workers/{worker_id}/background_checks:
    get:
      operationId: showWorkerBackgroundChecks
      tags:
        - Consulta de antecedentes
      summary: Obtener antecedentes de persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el estado de las consultas de antecedentes asociadas al onboarding activo de la persona: Policía Nacional (criminal_records), Procuraduría (disciplinary_records), Contraloría (fiscal_history) y Lista Clinton (ofac_compliance).

        **¿Cuándo usar este endpoint?**

        * Consultar el estado actual de cada verificación de antecedentes antes de completar el onboarding.
        * Obtener el archivo de resultado o el mensaje de respuesta de cada institución una vez finalizadas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Sin onboarding activo:** Si la persona no tiene un onboarding activo con consultas iniciadas, retorna `institutions: []`.
      responses:
        '200':
          description: Antecedentes con consultas / Sin consultas iniciadas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de las consultas de antecedentes del onboarding activo de la persona.
                    type: object
                    properties:
                      institutions:
                        description: Listado de consultas de antecedentes por institución. Vacío si no se han iniciado consultas.
                        type: array
                        items:
                          description: Resultado de la consulta de antecedentes de una institución.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la consulta de antecedentes en la base de datos.
                              type: string
                              example: 25382602-9777-429e-bdd5-306e046deb8a
                            label:
                              description: Nombre legible de la institución consultada.
                              type: string
                              example: Policía Nacional
                            coded_name:
                              description: 'Nombre en código de la institución. Valores posibles: criminal_records (Policía Nacional), disciplinary_records (Procuraduría), fiscal_history (Contraloría), ofac_compliance (Lista Clinton).'
                              type: string
                              enum:
                                - criminal_records
                                - disciplinary_records
                                - fiscal_history
                                - ofac_compliance
                              example: criminal_records
                            status:
                              description: 'Estado actual de la consulta. Valores posibles: unstarted (sin iniciar), not_apply (no aplica), in_progress (en progreso), pending (pendiente), finished (finalizada), failure_provider (error del proveedor).'
                              type: string
                              enum:
                                - unstarted
                                - not_apply
                                - in_progress
                                - pending
                                - finished
                                - failure_provider
                              example: finished
                            response:
                              description: Mensaje de respuesta de la institución. Puede ser null si la consulta aún no ha finalizado.
                              type:
                                - string
                                - 'null'
                              example: Sin antecedentes registrados
                            file:
                              description: URL del archivo de resultado de la consulta. Puede ser null si no se generó archivo.
                              type:
                                - string
                                - 'null'
                              example: https://storage.aleluya.com/background_checks/resultado.pdf
                        example:
                          - id: 25382602-9777-429e-bdd5-306e046deb8a
                            label: Policía Nacional
                            coded_name: criminal_records
                            status: finished
                            response: Sin antecedentes registrados
                            file: https://storage.aleluya.com/background_checks/resultado.pdf
              examples:
                Antecedentes con consultas:
                  value:
                    data:
                      institutions:
                        - id: 25382602-9777-429e-bdd5-306e046deb8a
                          label: Policía Nacional
                          coded_name: criminal_records
                          status: finished
                          response: Sin antecedentes registrados
                          file: https://storage.aleluya.com/background_checks/resultado.pdf
                        - id: 7f4c822b-3474-48b8-bf53-ab66fb2aae44
                          label: Procuraduría
                          coded_name: disciplinary_records
                          status: in_progress
                          response: null
                          file: null
                Sin consultas iniciadas:
                  value:
                    data:
                      institutions: []
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createWorkerBackgroundChecks
      tags:
        - Consulta de antecedentes
      summary: Iniciar consulta de antecedentes
      description: |
        **¿Qué hace este endpoint?**

        Inicia las consultas de antecedentes de la persona en las cuatro instituciones disponibles: Policía Nacional, Procuraduría, Contraloría y Lista Clinton. Las consultas quedan en estado `in_progress` mientras el proveedor procesa los resultados.

        **¿Cuándo usar este endpoint?**

        * Iniciar el proceso de verificación de antecedentes como parte del onboarding de la persona.
        * Lanzar las cuatro consultas simultáneamente en una sola llamada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Onboarding activo requerido:** La persona debe tener un onboarding activo. Si no lo tiene, se crea automáticamente.
      responses:
        '200':
          description: Consultas de antecedentes iniciadas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de consultas de antecedentes iniciadas, una por institución.
                    type: array
                    items:
                      description: Consulta de antecedentes iniciada para una institución.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la consulta de antecedentes en la base de datos.
                          type: string
                          example: 25382602-9777-429e-bdd5-306e046deb8a
                        label:
                          description: Nombre legible de la institución consultada.
                          type: string
                          example: Policía Nacional
                        coded_name:
                          description: 'Nombre en código de la institución. Valores posibles: criminal_records (Policía Nacional), disciplinary_records (Procuraduría), fiscal_history (Contraloría), ofac_compliance (Lista Clinton).'
                          type: string
                          enum:
                            - criminal_records
                            - disciplinary_records
                            - fiscal_history
                            - ofac_compliance
                          example: criminal_records
                        status:
                          description: Estado inicial de la consulta al momento de crearla. Siempre retorna `in_progress`.
                          type: string
                          example: in_progress
                        response:
                          description: Mensaje de respuesta de la institución. Siempre null al momento de la creación.
                          type:
                            - string
                            - 'null'
                          example: null
                        file:
                          description: URL del archivo de resultado. Siempre null al momento de la creación.
                          type:
                            - string
                            - 'null'
                          example: null
              example:
                data:
                  - id: 25382602-9777-429e-bdd5-306e046deb8a
                    label: Policía Nacional
                    coded_name: criminal_records
                    status: in_progress
                    response: null
                    file: null
                  - id: 7f4c822b-3474-48b8-bf53-ab66fb2aae44
                    label: Procuraduría
                    coded_name: disciplinary_records
                    status: in_progress
                    response: null
                    file: null
                  - id: 8b535720-890b-490c-aa61-19205581f094
                    label: Contraloría
                    coded_name: fiscal_history
                    status: in_progress
                    response: null
                    file: null
                  - id: 4b4b1c87-7e85-4e36-97aa-08e8ee52c4da
                    label: Lista Clinton
                    coded_name: ofac_compliance
                    status: in_progress
                    response: null
                    file: null
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Institución inválida / Tipo de documento no soportado / Error del proveedor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Institución inválida:
                  value:
                    error:
                      - code: '3701'
                        index: 0
                        message: Esta institución no está en la lista.
                        object: background_check
                Tipo de documento no soportado:
                  value:
                    error:
                      - code: '3702'
                        index: 0
                        message: El tipo de documento no es soportado para la consulta.
                        object: background_check
                Error del proveedor:
                  value:
                    error:
                      - code: '3703'
                        index: 0
                        message: El proveedor está presentando fallas.
                        object: background_check
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 12994516-97ee-427f-a835-a1c8f97270c4
  /v1/{company_id}/workers/{worker_id}/contract:
    get:
      operationId: showCurrentContract
      tags:
        - Contratos
      summary: Obtener contrato actual
      description: |
        **¿Qué hace este endpoint?**

        Retorna el contrato activo actual de la persona, incluyendo salario vigente, detalle del contrato,
        historial de cargo, proveedores de seguridad social y centro de trabajo.

        **¿Cuándo usar este endpoint?**

        * Obtener las condiciones laborales actuales de una persona sin necesidad de conocer el ID del contrato.
        * Verificar las afiliaciones de seguridad social vigentes antes de generar una nómina.
        * Consultar el cargo, área y sede actuales de una persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Sin contrato activo:** Si la persona no tiene un contrato activo, el endpoint retorna 404.
      responses:
        '200':
          description: Contrato actual de la persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información del contrato activo.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                      category:
                        description: Categoría del contrato laboral.
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del contrato en formato YYYY-MM-DD. Null si el contrato es indefinido.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      period_end_day:
                        description: Fecha de fin del periodo de nómina actual del contrato. Null si no hay un periodo abierto.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-31'
                      apply_art102_cst:
                        description: Indica si el contrato aplica el Artículo 102 del CST (pago de vacaciones sobre 360 días).
                        type: boolean
                        example: false
                      term:
                        description: Tipo de duración del contrato.
                        $ref: '#/components/schemas/ContractTerm'
                      terminated:
                        description: Indica si el contrato ha sido liquidado.
                        type: boolean
                        example: false
                      termination:
                        description: Información de la liquidación del contrato, si existe.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la liquidación en la base de datos. Null si el contrato no ha sido liquidado.
                            type:
                              - string
                              - 'null'
                            example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                          date:
                            description: Fecha de la liquidación en formato YYYY-MM-DD. Null si el contrato no ha sido liquidado.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          deleteable:
                            description: Indica si la liquidación puede ser eliminada. Null si el contrato no ha sido liquidado.
                            type:
                              - boolean
                              - 'null'
                            example: true
                      wage_id:
                        description: Identificador único (ID) asignado al salario vigente del contrato en la base de datos.
                        type: string
                        example: c9803794-bd6c-5b9c-995d-c7807cfccf44
                      wage_category:
                        description: Modalidad del salario vigente del contrato.
                        $ref: '#/components/schemas/SalaryCategory'
                      base_salary:
                        description: Valor del salario básico mensual del contrato en pesos colombianos.
                        type: integer
                        example: 2500000
                      remote_work:
                        description: Indica si la persona trabaja en modalidad de teletrabajo o trabajo en casa.
                        type: boolean
                        example: false
                      transport_subsidy:
                        description: Indica si el contrato incluye auxilio de transporte.
                        type: boolean
                        example: true
                      contract_detail:
                        description: Detalle vigente del contrato con información del subtipo de cotizante.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                            type: string
                            example: 4853f212-17fa-5631-884f-bed5587f7976
                          contributor_subtype:
                            description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social.
                            $ref: '#/components/schemas/ContributorSubtype'
                          initial_day:
                            description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin de vigencia del detalle del contrato. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                            type: string
                            example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                          deleteable:
                            description: Indica si el detalle del contrato puede ser eliminado.
                            type: boolean
                            example: false
                      contract_position_history:
                        description: Historial de cargo vigente del contrato con área, sede y cargo asignados.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          initial_day:
                            description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del historial de cargo. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: '2024-12-31'
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este historial en la base de datos.
                            type: string
                            example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                          area:
                            description: Área asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al área en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                              name:
                                description: Nombre del área.
                                type:
                                  - string
                                  - 'null'
                                example: Administración
                          location:
                            description: Sede asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sede en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                              name:
                                description: Nombre de la sede.
                                type:
                                  - string
                                  - 'null'
                                example: Oficina principal
                          position:
                            description: Cargo asignado al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al cargo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                              name:
                                description: Nombre del cargo.
                                type:
                                  - string
                                  - 'null'
                                example: Coordinador de proyectos
                          deleteable:
                            description: Indica si el historial de cargo puede ser eliminado.
                            type: boolean
                            example: false
                      work_center:
                        description: |
                          Centro de trabajo asignado al contrato.

                          - Si el contrato tiene centro de trabajo, retorna el objeto con su información.
                          - Si no tiene centro de trabajo asignado, retorna un objeto vacío `{}`.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                            type: string
                            example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                          name:
                            description: Nombre del centro de trabajo junto con el tipo de riesgo.
                            type: string
                            example: Sede Principal - Riesgo 1 - Mínimo
                          risk_type:
                            description: Nombre del tipo de riesgo del centro de trabajo.
                            type:
                              - string
                              - 'null'
                            example: Riesgo 1 - Mínimo
                      risk_type:
                        description: |
                          Código del tipo de riesgo ARL del centro de trabajo.

                          Valores posibles:
                          * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
                          * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
                          * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
                          * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
                          * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)

                          `null` si no tiene centro de trabajo asignado.
                        type:
                          - string
                          - 'null'
                        enum:
                          - risk_1
                          - risk_2
                          - risk_3
                          - risk_4
                          - risk_5
                        example: risk_1
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo.
                        type: boolean
                        example: false
                      health_provider:
                        description: Entidad prestadora de salud (EPS) afiliada al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la EPS en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name:
                            description: Nombre de la EPS.
                            type:
                              - string
                              - 'null'
                            example: Sura EPS
                      pension_provider:
                        description: Fondo de pensiones afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name:
                            description: Nombre del fondo de pensiones.
                            type:
                              - string
                              - 'null'
                            example: Porvenir
                      severance_provider:
                        description: Fondo de cesantías afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 16881701-ff67-5895-913b-dfdf4ab03797
                          name:
                            description: Nombre del fondo de cesantías.
                            type:
                              - string
                              - 'null'
                            example: Protección
              example:
                data:
                  id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                  category: employee
                  initial_day: '2024-01-01'
                  end_day: null
                  period_end_day: '2024-01-31'
                  apply_art102_cst: false
                  term: indefinite
                  terminated: false
                  termination:
                    id: null
                    date: null
                    deleteable: null
                  wage_id: c9803794-bd6c-5b9c-995d-c7807cfccf44
                  wage_category: monthly
                  base_salary: 2500000
                  remote_work: false
                  transport_subsidy: true
                  contract_detail:
                    id: 4853f212-17fa-5631-884f-bed5587f7976
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                    deleteable: false
                  contract_position_history:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                    area:
                      id: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                      name: Administración
                    location:
                      id: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                      name: Oficina principal
                    position:
                      id: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                      name: Coordinador de proyectos
                    deleteable: false
                  work_center:
                    id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                    name: Sede Principal - Riesgo 1 - Mínimo
                    risk_type: Riesgo 1 - Mínimo
                  risk_type: risk_1
                  high_risk_pension: false
                  health_provider:
                    id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    name: Sura EPS
                  pension_provider:
                    id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    name: Porvenir
                  severance_provider:
                    id: 16881701-ff67-5895-913b-dfdf4ab03797
                    name: Protección
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: c8339696-203d-4018-b873-297c0c40e994
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/contracts:
    get:
      operationId: indexContracts
      tags:
        - Contratos
      summary: Listar contratos de una persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial completo de contratos de una persona en la empresa, ordenados del más reciente al más antiguo.

        **¿Cuándo usar este endpoint?**

        * Consultar todos los contratos activos e históricos de una persona para visualizar su trayectoria laboral.
        * Obtener el contrato actual de una persona junto con sus condiciones de seguridad social y salario.
        * Verificar si una persona tiene contratos previos antes de crear uno nuevo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Sin contratos:** Si la persona no tiene contratos, `data` retorna un arreglo vacío `[]`.
      responses:
        '200':
          description: Contratos de la persona / Sin contratos
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Arreglo con el historial de contratos de la persona, ordenado del más reciente al más antiguo.
                    type: array
                    items:
                      description: Registro de un contrato en el historial de la persona.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al contrato en la base de datos.
                          type: string
                          example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                        category:
                          description: Categoría del contrato laboral.
                          $ref: '#/components/schemas/ContractCategory'
                        initial_day:
                          description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-01-01'
                        end_day:
                          description: Fecha de fin del contrato en formato YYYY-MM-DD. Null si el contrato es indefinido.
                          type:
                            - string
                            - 'null'
                          example: '2024-12-31'
                        period_end_day:
                          description: Fecha de fin del periodo de nómina actual del contrato. Null si no hay un periodo abierto.
                          type:
                            - string
                            - 'null'
                          example: '2024-01-31'
                        apply_art102_cst:
                          description: Indica si el contrato aplica el Artículo 102 del CST (pago de vacaciones sobre 360 días).
                          type: boolean
                          example: false
                        term:
                          description: Tipo de duración del contrato.
                          $ref: '#/components/schemas/ContractTerm'
                        terminated:
                          description: Indica si el contrato ha sido liquidado.
                          type: boolean
                          example: false
                        termination:
                          description: Información de la liquidación del contrato, si existe.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la liquidación en la base de datos. Null si el contrato no ha sido liquidado.
                              type:
                                - string
                                - 'null'
                              example: d2e8cb60-372b-4dfe-bfb5-91e7ccb16833
                            date:
                              description: Fecha de la liquidación en formato YYYY-MM-DD. Null si el contrato no ha sido liquidado.
                              type:
                                - string
                                - 'null'
                              example: '2024-12-31'
                            deleteable:
                              description: Indica si la liquidación puede ser eliminada. Null si el contrato no ha sido liquidado.
                              type:
                                - boolean
                                - 'null'
                              example: true
                        wage_id:
                          description: Identificador único (ID) asignado al salario vigente del contrato en la base de datos.
                          type: string
                          example: c9803794-bd6c-5b9c-995d-c7807cfccf44
                        wage_category:
                          description: Modalidad del salario vigente del contrato.
                          $ref: '#/components/schemas/SalaryCategory'
                        base_salary:
                          description: Valor del salario básico mensual del contrato en pesos colombianos.
                          type: integer
                          example: 2500000
                        remote_work:
                          description: Indica si la persona trabaja en modalidad de teletrabajo o trabajo en casa.
                          type: boolean
                          example: false
                        transport_subsidy:
                          description: Indica si el contrato incluye auxilio de transporte.
                          type: boolean
                          example: true
                        contract_detail:
                          description: Detalle vigente del contrato con información del subtipo de cotizante.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                              type: string
                              example: 4853f212-17fa-5631-884f-bed5587f7976
                            contributor_subtype:
                              description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social.
                              $ref: '#/components/schemas/ContributorSubtype'
                            initial_day:
                              description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin de vigencia del detalle del contrato. Null si está vigente.
                              type:
                                - string
                                - 'null'
                              example: '2024-12-31'
                            contract_id:
                              description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                              type: string
                              example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                            deleteable:
                              description: Indica si el detalle del contrato puede ser eliminado.
                              type: boolean
                              example: false
                        contract_position_history:
                          description: Historial de cargo vigente del contrato con área, sede y cargo asignados.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            initial_day:
                              description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-01'
                            end_day:
                              description: Fecha de fin del historial de cargo. Null si está vigente.
                              type:
                                - string
                                - 'null'
                              example: '2024-12-31'
                            contract_id:
                              description: Identificador único (ID) asignado al contrato al que pertenece este historial en la base de datos.
                              type: string
                              example: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                            area:
                              description: Área asignada al contrato.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al área en la base de datos.
                                  type:
                                    - string
                                    - 'null'
                                  example: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                                name:
                                  description: Nombre del área.
                                  type:
                                    - string
                                    - 'null'
                                  example: Administración
                            location:
                              description: Sede asignada al contrato.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado a la sede en la base de datos.
                                  type:
                                    - string
                                    - 'null'
                                  example: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                                name:
                                  description: Nombre de la sede.
                                  type:
                                    - string
                                    - 'null'
                                  example: Oficina principal
                            position:
                              description: Cargo asignado al contrato.
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al cargo en la base de datos.
                                  type:
                                    - string
                                    - 'null'
                                  example: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                                name:
                                  description: Nombre del cargo.
                                  type:
                                    - string
                                    - 'null'
                                  example: Coordinador de proyectos
                            deleteable:
                              description: Indica si el historial de cargo puede ser eliminado.
                              type: boolean
                              example: false
                        work_center:
                          description: |
                            Centro de trabajo asignado al contrato.

                            - Si el contrato tiene centro de trabajo, retorna el objeto con su información.
                            - Si no tiene centro de trabajo asignado, retorna un objeto vacío `{}`.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                              type: string
                              example: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                            name:
                              description: Nombre del centro de trabajo junto con el tipo de riesgo.
                              type: string
                              example: Sede Principal - Riesgo 1 - Mínimo
                            risk_type:
                              description: Nombre del tipo de riesgo del centro de trabajo.
                              type:
                                - string
                                - 'null'
                              example: Riesgo 1 - Mínimo
                        risk_type:
                          description: |
                            Código del tipo de riesgo ARL del centro de trabajo.

                            Valores posibles:
                            * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
                            * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
                            * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
                            * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
                            * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)

                            `null` si no tiene centro de trabajo asignado.
                          type:
                            - string
                            - 'null'
                          enum:
                            - risk_1
                            - risk_2
                            - risk_3
                            - risk_4
                            - risk_5
                          example: risk_1
                        high_risk_pension:
                          description: Indica si el contrato aplica pensión de alto riesgo.
                          type: boolean
                          example: false
                        health_provider:
                          description: Entidad prestadora de salud (EPS) afiliada al contrato.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la EPS en la base de datos.
                              type:
                                - string
                                - 'null'
                              example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                            name:
                              description: Nombre de la EPS.
                              type:
                                - string
                                - 'null'
                              example: Sura EPS
                        pension_provider:
                          description: Fondo de pensiones afiliado al contrato.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                              type:
                                - string
                                - 'null'
                              example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                            name:
                              description: Nombre del fondo de pensiones.
                              type:
                                - string
                                - 'null'
                              example: Porvenir
                        severance_provider:
                          description: Fondo de cesantías afiliado al contrato.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                              type:
                                - string
                                - 'null'
                              example: 16881701-ff67-5895-913b-dfdf4ab03797
                            name:
                              description: Nombre del fondo de cesantías.
                              type:
                                - string
                                - 'null'
                              example: Protección
              examples:
                Con contratos:
                  value:
                    data:
                      - id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                        category: employee
                        initial_day: '2024-01-01'
                        end_day: null
                        period_end_day: '2024-01-31'
                        apply_art102_cst: false
                        term: indefinite
                        terminated: false
                        termination:
                          id: null
                          date: null
                          deleteable: null
                        wage_id: c9803794-bd6c-5b9c-995d-c7807cfccf44
                        wage_category: monthly
                        base_salary: 2500000
                        remote_work: false
                        transport_subsidy: true
                        contract_detail:
                          id: 4853f212-17fa-5631-884f-bed5587f7976
                          contributor_subtype: no_subtype
                          initial_day: '2024-01-01'
                          end_day: null
                          contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                          deleteable: false
                        contract_position_history:
                          id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          initial_day: '2024-01-01'
                          end_day: null
                          contract_id: 0a9b9419-d4b1-5dcb-945b-4f802df84a23
                          area:
                            id: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                            name: Administración
                          location:
                            id: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                            name: Oficina principal
                          position:
                            id: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                            name: Coordinador de proyectos
                          deleteable: false
                        work_center:
                          id: f84c4df6-b10f-51fb-b7ce-4c0810a03cb5
                          name: Sede Principal - Riesgo 1 - Mínimo
                          risk_type: Riesgo 1 - Mínimo
                        risk_type: risk_1
                        high_risk_pension: false
                        health_provider:
                          id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name: Sura EPS
                        pension_provider:
                          id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name: Porvenir
                        severance_provider:
                          id: 16881701-ff67-5895-913b-dfdf4ab03797
                          name: Protección
                Sin contratos:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createContract
      tags:
        - Contratos
      summary: Crear contrato
      description: |
        **¿Qué hace este endpoint?**

        Crea un nuevo contrato laboral para la persona especificada en `{worker_id}`, incluyendo salario,
        detalle del contrato e historial de cargo inicial.

        **¿Cuándo usar este endpoint?**

        * Registrar el primer contrato de una persona recién creada con sus condiciones de seguridad social.
        * Crear un nuevo contrato tras liquidar el anterior, cuando la persona reingresa a la empresa.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Contrato activo:** Si la persona ya tiene un contrato activo sin liquidar, debe liquidarse primero antes de crear uno nuevo.
        * **Pago activo:** Requiere que la empresa tenga una suscripción activa o en periodo de prueba.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                contract:
                  description: Objeto con los datos del contrato a crear.
                  type: object
                  properties:
                    category:
                      description: Categoría del contrato laboral.
                      $ref: '#/components/schemas/ContractCategory'
                    term:
                      description: Tipo de duración del contrato.
                      $ref: '#/components/schemas/ContractTerm'
                    initial_day:
                      description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                      type: string
                      format: date
                      example: '2024-01-01'
                    end_day:
                      description: Fecha de fin del contrato en formato YYYY-MM-DD. Solo aplica para contratos a término fijo o por obra.
                      type:
                        - string
                        - 'null'
                      example: '2024-12-31'
                    apply_art102_cst:
                      description: Indica si aplica el Artículo 102 del CST para calcular vacaciones sobre 360 días.
                      type: boolean
                      example: false
                    health_provider_id:
                      description: Identificador único (ID) asignado a la EPS en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
                    pension_provider_id:
                      description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    severance_provider_id:
                      description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 16881701-ff67-5895-913b-dfdf4ab03797
                    base_salary:
                      description: Salario base del contrato en pesos colombianos.
                      type: integer
                      example: 2500000
                    wage_category:
                      description: Modalidad del salario.
                      $ref: '#/components/schemas/SalaryCategory'
                    transport_subsidy:
                      description: Indica si la persona recibe auxilio de transporte.
                      type: boolean
                      example: true
                    remote_work:
                      description: Indica si la persona labora en modalidad de teletrabajo o trabajo en casa.
                      type: boolean
                      example: false
                    contributor_subtype:
                      description: Subtipo de cotizante para seguridad social.
                      $ref: '#/components/schemas/ContributorSubtype'
                    high_risk_pension:
                      description: Indica si la persona realiza actividades de alto riesgo que requieren cotización adicional a pensión. Requiere Colpensiones como fondo de pensiones.
                      type: boolean
                      example: false
                    work_center_id:
                      description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                      type:
                        - string
                        - 'null'
                      example: 97a1f505-fbd5-554c-a620-ca0017f9bada
                    risk_type:
                      description: Código del tipo de riesgo ARL del centro de trabajo del contrato.
                      $ref: '#/components/schemas/RiskType'
                    area_id:
                      description: Identificador único (ID) asignado al área de la empresa en la base de datos.
                      type: string
                      example: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                    location_id:
                      description: Identificador único (ID) asignado a la sede de la empresa en la base de datos.
                      type: string
                      example: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                    position_id:
                      description: Identificador único (ID) asignado al cargo en la base de datos.
                      type: string
                      example: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                  required:
                    - category
                    - term
                    - initial_day
                    - base_salary
                    - wage_category
                    - area_id
                    - location_id
                    - position_id
              required:
                - contract
      responses:
        '201':
          description: Contrato creado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Objeto con la información del contrato recién creado.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al contrato en la base de datos.
                        type: string
                        example: d7680c34-2562-4b4c-a191-31ca71436245
                      category:
                        description: Categoría del contrato laboral.
                        $ref: '#/components/schemas/ContractCategory'
                      initial_day:
                        description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                        type: string
                        format: date
                        example: '2024-01-01'
                      end_day:
                        description: Fecha de fin del contrato en formato YYYY-MM-DD. Null si el contrato es indefinido.
                        type:
                          - string
                          - 'null'
                        example: '2024-12-31'
                      period_end_day:
                        description: Fecha de fin del periodo de nómina actual del contrato. Null si no hay un periodo abierto.
                        type:
                          - string
                          - 'null'
                        example: '2024-01-31'
                      apply_art102_cst:
                        description: Indica si el contrato aplica el Artículo 102 del CST (pago de vacaciones sobre 360 días).
                        type: boolean
                        example: false
                      term:
                        description: Tipo de duración del contrato.
                        $ref: '#/components/schemas/ContractTerm'
                      terminated:
                        description: Indica si el contrato ha sido liquidado. Siempre es false en la respuesta de creación.
                        type: boolean
                        example: false
                      termination:
                        description: Información de la liquidación. Siempre es null en la respuesta de creación.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la liquidación en la base de datos. Null al crear.
                            type:
                              - string
                              - 'null'
                            example: null
                          date:
                            description: Fecha de la liquidación. Null al crear.
                            type:
                              - string
                              - 'null'
                            example: null
                          deleteable:
                            description: Indica si la liquidación puede ser eliminada. Null al crear.
                            type:
                              - boolean
                              - 'null'
                            example: null
                      wage_id:
                        description: Identificador único (ID) asignado al salario vigente del contrato en la base de datos.
                        type: string
                        example: e15a189a-dcfe-4753-8dcb-7efddddd5aa1
                      wage_category:
                        description: Modalidad del salario vigente del contrato.
                        $ref: '#/components/schemas/SalaryCategory'
                      base_salary:
                        description: Valor del salario básico mensual del contrato en pesos colombianos.
                        type: integer
                        example: 2500000
                      remote_work:
                        description: Indica si la persona trabaja en modalidad de teletrabajo o trabajo en casa.
                        type: boolean
                        example: false
                      transport_subsidy:
                        description: Indica si el contrato incluye auxilio de transporte.
                        type: boolean
                        example: true
                      contract_detail:
                        description: Detalle vigente del contrato con información del subtipo de cotizante.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al detalle del contrato en la base de datos.
                            type: string
                            example: 0d2d271d-4bcf-4a46-853d-dfa159fb3fce
                          contributor_subtype:
                            description: Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social.
                            $ref: '#/components/schemas/ContributorSubtype'
                          initial_day:
                            description: Fecha de inicio de vigencia del detalle del contrato en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin de vigencia del detalle del contrato. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: null
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este detalle en la base de datos.
                            type: string
                            example: d7680c34-2562-4b4c-a191-31ca71436245
                          deleteable:
                            description: Indica si el detalle del contrato puede ser eliminado.
                            type: boolean
                            example: false
                      contract_position_history:
                        description: Historial de cargo inicial del contrato con área, sede y cargo asignados.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al historial de cargo en la base de datos.
                            type: string
                            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          initial_day:
                            description: Fecha de inicio del historial de cargo en formato YYYY-MM-DD.
                            type: string
                            format: date
                            example: '2024-01-01'
                          end_day:
                            description: Fecha de fin del historial de cargo. Null si está vigente.
                            type:
                              - string
                              - 'null'
                            example: null
                          contract_id:
                            description: Identificador único (ID) asignado al contrato al que pertenece este historial en la base de datos.
                            type: string
                            example: d7680c34-2562-4b4c-a191-31ca71436245
                          area:
                            description: Área asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al área en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                              name:
                                description: Nombre del área.
                                type:
                                  - string
                                  - 'null'
                                example: Administración
                          location:
                            description: Sede asignada al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado a la sede en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                              name:
                                description: Nombre de la sede.
                                type:
                                  - string
                                  - 'null'
                                example: Oficina principal
                          position:
                            description: Cargo asignado al contrato.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al cargo en la base de datos.
                                type:
                                  - string
                                  - 'null'
                                example: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                              name:
                                description: Nombre del cargo.
                                type:
                                  - string
                                  - 'null'
                                example: Coordinador de proyectos
                          deleteable:
                            description: Indica si el historial de cargo puede ser eliminado.
                            type: boolean
                            example: false
                      work_center:
                        description: Centro de trabajo asignado al contrato. Retorna objeto vacío `{}` si no tiene centro de trabajo asignado.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al centro de trabajo en la base de datos.
                            type: string
                            example: 97a1f505-fbd5-554c-a620-ca0017f9bada
                          name:
                            description: Nombre del centro de trabajo junto con el tipo de riesgo.
                            type: string
                            example: Sede Principal - Riesgo 1 - Mínimo
                          risk_type:
                            description: Nombre del tipo de riesgo del centro de trabajo.
                            type:
                              - string
                              - 'null'
                            example: Riesgo 1 - Mínimo
                      risk_type:
                        description: |
                          Código del tipo de riesgo ARL del centro de trabajo.

                          Valores posibles:
                          * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
                          * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
                          * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
                          * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
                          * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)

                          `null` si no tiene centro de trabajo asignado.
                        type:
                          - string
                          - 'null'
                        enum:
                          - risk_1
                          - risk_2
                          - risk_3
                          - risk_4
                          - risk_5
                        example: risk_1
                      high_risk_pension:
                        description: Indica si el contrato aplica pensión de alto riesgo.
                        type: boolean
                        example: false
                      health_provider:
                        description: Entidad prestadora de salud (EPS) afiliada al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado a la EPS en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                          name:
                            description: Nombre de la EPS.
                            type:
                              - string
                              - 'null'
                            example: Sura EPS
                      pension_provider:
                        description: Fondo de pensiones afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de pensiones en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                          name:
                            description: Nombre del fondo de pensiones.
                            type:
                              - string
                              - 'null'
                            example: Porvenir
                      severance_provider:
                        description: Fondo de cesantías afiliado al contrato.
                        type: object
                        properties:
                          id:
                            description: Identificador único (ID) asignado al fondo de cesantías en la base de datos.
                            type:
                              - string
                              - 'null'
                            example: 16881701-ff67-5895-913b-dfdf4ab03797
                          name:
                            description: Nombre del fondo de cesantías.
                            type:
                              - string
                              - 'null'
                            example: Protección
              example:
                data:
                  id: d7680c34-2562-4b4c-a191-31ca71436245
                  category: employee
                  initial_day: '2024-01-01'
                  end_day: null
                  period_end_day: '2024-01-31'
                  apply_art102_cst: false
                  term: indefinite
                  terminated: false
                  termination:
                    id: null
                    date: null
                    deleteable: null
                  wage_id: e15a189a-dcfe-4753-8dcb-7efddddd5aa1
                  wage_category: monthly
                  base_salary: 2500000
                  remote_work: false
                  transport_subsidy: true
                  contract_detail:
                    id: 0d2d271d-4bcf-4a46-853d-dfa159fb3fce
                    contributor_subtype: no_subtype
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: d7680c34-2562-4b4c-a191-31ca71436245
                    deleteable: false
                  contract_position_history:
                    id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    initial_day: '2024-01-01'
                    end_day: null
                    contract_id: d7680c34-2562-4b4c-a191-31ca71436245
                    area:
                      id: 3f4e5d6c-7b8a-9012-3456-789abcdef012
                      name: Administración
                    location:
                      id: c1d2e3f4-a5b6-7890-cdef-0123456789ab
                      name: Oficina principal
                    position:
                      id: d4e5f6a7-b8c9-0123-4567-89abcdef0123
                      name: Coordinador de proyectos
                    deleteable: false
                  work_center:
                    id: 97a1f505-fbd5-554c-a620-ca0017f9bada
                    name: Sede Principal - Riesgo 1 - Mínimo
                    risk_type: Riesgo 1 - Mínimo
                  risk_type: risk_1
                  high_risk_pension: false
                  health_provider:
                    id: 3edf0b14-01b3-561b-bbc4-ba2a7493306a
                    name: Sura EPS
                  pension_provider:
                    id: b86c3b81-3584-5ed6-91a3-f07f54c115e3
                    name: Porvenir
                  severance_provider:
                    id: 16881701-ff67-5895-913b-dfdf4ab03797
                    name: Protección
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Contrato activo sin liquidar / Fecha inicial inválida / Pensión de alto riesgo inválida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Contrato activo sin liquidar:
                  value:
                    error:
                      - code: '0701'
                        index: 0
                        message: Si deseas crear un nuevo contrato, primero debes liquidar el actual. Si requieres renovar este contrato por el mismo tipo sin liquidarlo, sólo debes extender (editar) su fecha de terminación.
                        object: contract
                Fecha inicial inválida:
                  value:
                    error:
                      - code: '0702'
                        index: 0
                        message: La fecha inicial no puede ser una fecha superior a la fecha final del periodo actual más 15 días.
                        object: initial_day
                Pensión de alto riesgo inválida:
                  value:
                    error:
                      - code: '4009'
                        index: 0
                        message: La pensión de alto riesgo requiere Colpensiones como administradora de pensiones (Resolución 6072 de 2024).
                        object: contract_detail
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: c8339696-203d-4018-b873-297c0c40e994
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/electronic_signatures:
    get:
      operationId: showElectronicSignature
      tags:
        - Firma electrónica
      summary: Obtener firma electrónica
      description: |
        **¿Qué hace este endpoint?**

        Retorna la lista de procesos de firma electrónica activos para una persona, incluyendo
        el estado de cada firmante, las URLs del documento firmado y sin firmar, y el estado
        general del proceso.

        **¿Cuándo usar este endpoint?**

        * Verificar si una persona tiene un proceso de firma electrónica en curso (onboarding).
        * Consultar el estado de avance de las firmas pendientes por firmante.
        * Obtener la URL del documento una vez que ha sido firmado.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Origen fijo:** Este endpoint siempre retorna firmas electrónicas de origen `onboarding`.
      responses:
        '200':
          description: Lista de firmas electrónicas obtenida exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: |
                      Lista de procesos de firma electrónica activos para la persona.
                      Retorna un arreglo vacío si la persona no tiene procesos activos.
                    type: array
                    items:
                      description: Proceso de firma electrónica con sus firmantes y estado actual.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) del proceso de firma electrónica.
                          type: string
                          example: b3e89841-a20e-4f06-98a7-cba094a48fc0
                        filename:
                          description: Nombre del archivo del documento enviado a firmar.
                          type: string
                          example: contrato_juan_perez.pdf
                        origin:
                          description: Origen del proceso de firma electrónica. Siempre es `onboarding` para este endpoint.
                          type: string
                          example: onboarding
                        signed_file:
                          description: URL del documento firmado por todos los firmantes. Nulo si el proceso aún no ha sido completado.
                          type:
                            - string
                            - 'null'
                          example: https://storage.aleluya.com/documents/contrato_juan_perez_signed.pdf
                        signers:
                          description: Lista de firmantes del documento con su estado individual.
                          type: array
                          items:
                            description: Datos de un firmante del documento.
                            type: object
                            properties:
                              email:
                                description: Correo electrónico del firmante.
                                type: string
                                example: juan.perez@empresa.com
                              name:
                                description: Nombre completo del firmante.
                                type: string
                                example: Juan Pérez
                              status:
                                description: Estado actual de la firma de este firmante (ej. `Pendiente`, `Firmado`).
                                type: string
                                example: Pendiente
                        status:
                          description: Estado general del proceso de firma electrónica (ej. `in_progress`, `completed`, `cancelled`).
                          type: string
                          example: in_progress
                        unsigned_file:
                          description: URL del documento original sin firmar enviado al proveedor de firma electrónica.
                          type: string
                          example: https://storage.aleluya.com/documents/contrato_juan_perez.pdf
              example:
                data:
                  - id: b3e89841-a20e-4f06-98a7-cba094a48fc0
                    filename: contrato_juan_perez.pdf
                    origin: onboarding
                    signed_file: null
                    signers:
                      - email: juan.perez@empresa.com
                        name: Juan Pérez
                        status: Pendiente
                      - email: hr@empresa.com
                        name: Ana Gómez
                        status: Firmado
                    status: in_progress
                    unsigned_file: https://storage.aleluya.com/documents/contrato_juan_perez.pdf
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createElectronicSignature
      tags:
        - Firma electrónica
      summary: Crear e iniciar proceso de firma electrónica
      description: |
        **¿Qué hace este endpoint?**

        Inicia un proceso de firma electrónica para un documento asociado a una persona.
        El documento es enviado al proveedor de firma electrónica y se notifica a cada
        firmante por correo electrónico.

        **¿Cuándo usar este endpoint?**

        * Enviar un contrato u otro documento para ser firmado electrónicamente.
        * Registrar múltiples firmantes (empleado, empleador, testigos) con sus correos.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Formato de documento:** Solo se aceptan archivos PDF con tamaño máximo de 1 MB.
        * **Correos de firmantes:** Todos los correos electrónicos deben ser válidos.
        * **Un proceso activo:** La persona no puede tener otro proceso de firma en curso.
        * **Correo de la persona:** La persona debe tener un correo electrónico registrado para poder ser firmante.
        * **Resultado:** La operación es asíncrona. Escucha la ruta de Firebase `workers/{worker_id}/electronic_signatures/action_create` para recibir el resultado final (`success` o `failure`).
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                document:
                  description: Archivo PDF del documento a firmar. Tamaño máximo 1 MB.
                  type: string
                  format: binary
                signers:
                  description: |
                    Lista de firmantes del documento en formato JSON. Cada firmante debe tener
                    `signed_name` (nombre) y `signed_email` (correo electrónico válido).
                  type: string
                  example: '[{"signed_name":"Juan Pérez","signed_email":"juan@empresa.com"},{"signed_name":"Ana Gómez","signed_email":"ana@empresa.com"}]'
                with_attachments:
                  description: Indica si el proceso incluye documentos adjuntos adicionales al documento principal.
                  type: boolean
                  example: false
                date_limit_to_sign:
                  description: Fecha límite para que los firmantes completen el proceso, en formato YYYY-MM-DD. Debe ser mayor o igual a la fecha actual.
                  type: string
                  format: date
                  example: '2025-01-31'
                require_selfie_photo:
                  description: Indica si se requiere que los firmantes adjunten una selfie como verificación de identidad.
                  type: boolean
                  example: false
              required:
                - document
                - signers
                - with_attachments
                - date_limit_to_sign
      responses:
        '200':
          description: Proceso de firma electrónica iniciado. El resultado final se notifica de forma asíncrona vía Firebase.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de que la solicitud fue recibida y está siendo procesada.
                        type: string
                        example: La solicitud de firma electrónica se ha realizado de forma exitosa.
              example:
                data:
                  message: La solicitud de firma electrónica se ha realizado de forma exitosa.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Documento inválido / Fecha límite inválida / Correo inválido / Proceso duplicado / Sin correo registrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Fallo del proveedor de firma:
                  value:
                    error:
                      - code: '3801'
                        index: 0
                        message: Nuestro proveedor está presentando fallas. Por favor, vuelve a subir el documento.
                        object: electronic_signature
                Formato de archivo inválido:
                  value:
                    error:
                      - code: '3802'
                        index: 0
                        message: El documento cargado debe estar en formato PDF.
                        object: electronic_signature
                Tamaño de archivo excedido:
                  value:
                    error:
                      - code: '3803'
                        index: 0
                        message: El documento cargado debe tener un tamaño máximo de 1 MB.
                        object: electronic_signature
                Error al cargar el documento:
                  value:
                    error:
                      - code: '3804'
                        index: 0
                        message: Hay un error con el documento y no se puede cargar. Por favor, verifica el documento y vuélvelo a subir.
                        object: electronic_signature
                Fecha límite en el pasado:
                  value:
                    error:
                      - code: '3805'
                        index: 0
                        message: La fecha límite de firma debe ser mayor o igual a la fecha actual.
                        object: electronic_signatures
                Formato de fecha límite inválido:
                  value:
                    error:
                      - code: '3806'
                        index: 0
                        message: El formato de la fecha límite de firma es inválido.
                        object: electronic_signature
                Correo electrónico de firmante inválido:
                  value:
                    error:
                      - code: '3807'
                        index: 0
                        message: El correo electrónico correo@invalid es inválido.
                        object: electronic_signature
                Proceso de firma duplicado:
                  value:
                    error:
                      - code: '3810'
                        index: 0
                        message: Ya tiene un proceso de firma electrónica.
                        object: electronic_signature
                Persona sin correo registrado:
                  value:
                    error:
                      - code: '3809'
                        index: 0
                        message: No es posible iniciar el proceso de firma porque la persona no tiene un correo electrónico registrado.
                        object: worker
    delete:
      operationId: destroyElectronicSignature
      tags:
        - Firma electrónica
      summary: Eliminar proceso de firma electrónica
      description: |
        **¿Qué hace este endpoint?**

        Elimina el proceso de firma electrónica activo de una persona, cancelando las
        solicitudes de firma pendientes ante el proveedor.

        **¿Cuándo usar este endpoint?**

        * Cancelar un proceso de firma enviado por error.
        * Reenviar un nuevo documento corregido (primero eliminar el existente y luego crear uno nuevo).

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Pago activo:** El plan de la empresa debe tener una suscripción activa.
        * **Proceso existente:** La persona debe tener un proceso de firma activo para poder eliminarlo.
        * **Resultado:** La operación es asíncrona. Escucha la ruta de Firebase `workers/{worker_id}/electronic_signatures/action_destroy` para recibir el resultado final.
      responses:
        '200':
          description: Solicitud de eliminación recibida. El resultado final se notifica de forma asíncrona vía Firebase.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de que la solicitud de eliminación fue recibida y está siendo procesada.
                        type: string
                        example: Procesando
              example:
                data:
                  message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Documento de firma no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '3808'
                    index: 0
                    message: No se encontró el documento de firma electrónica.
                    object: electronic_signature
    parameters:
      - in: path
        required: true
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        name: company_id
        schema:
          type: string
          example: 526a932f-46a6-40b5-8fe7-55c74afdd992
      - in: path
        required: true
        description: Identificador único (ID) asignado a la persona en la base de datos.
        name: worker_id
        schema:
          type: string
          example: 9b779b26-6fbb-45da-b250-5f9867c4c064
  /v1/{company_id}/workers/{worker_id}/folders:
    get:
      operationId: indexWorkerFolders
      tags:
        - Documentos de personas
      summary: Listar carpetas de persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de carpetas de documentos de una persona, incluyendo el número de archivos en cada carpeta.

        **¿Cuándo usar este endpoint?**

        * Mostrar las carpetas disponibles de una persona antes de subir o consultar documentos.
        * Determinar qué carpetas son eliminables antes de intentar borrarlas.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          name: search
          required: false
          description: Busca carpetas de documentos por nombre. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Contratos
      responses:
        '200':
          description: Carpetas de la persona / Sin carpetas registradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de carpetas de documentos de la persona.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado a la carpeta en la base de datos.
                          type: string
                          example: d292de70-a803-5e2d-a87f-3ad1128f38fc
                        name:
                          description: Nombre de la carpeta.
                          type: string
                          example: Contratos laborales
                        total_files:
                          description: Número de archivos almacenados en la carpeta para esta persona.
                          type: integer
                          example: 3
                        created_at:
                          description: Fecha de creación de la carpeta en formato YYYY-MM-DD.
                          type: string
                          format: date
                          example: '2024-07-03'
                        deleteable:
                          description: Indica si la carpeta puede eliminarse. Es false cuando contiene archivos adjuntos.
                          type: boolean
                          example: false
                  filters:
                    description: Metadatos de paginación y búsqueda aplicados a la consulta.
                    type: object
                    properties:
                      total_records:
                        description: Total de carpetas que coinciden con el criterio de búsqueda.
                        type: integer
                        example: 3
                      page:
                        description: Página actual de resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de carpetas por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se filtró.
                        type: string
                        example: ''
              examples:
                Carpetas de la persona:
                  value:
                    data:
                      - id: d292de70-a803-5e2d-a87f-3ad1128f38fc
                        name: Contratos laborales
                        total_files: 2
                        created_at: '2024-07-03'
                        deleteable: false
                      - id: b4000992-0c47-54e2-a5d2-26b3ad8bd635
                        name: Seguridad social
                        total_files: 0
                        created_at: '2024-07-03'
                        deleteable: true
                    filters:
                      total_records: 2
                      page: 1
                      per_page: 20
                      search: ''
                Sin carpetas registradas:
                  value:
                    data: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createWorkerFolder
      tags:
        - Documentos de personas
      summary: Crear carpeta de persona
      description: |
        **¿Qué hace este endpoint?**

        Crea una nueva carpeta de documentos para la persona. Opcionalmente permite adjuntar un documento al momento de la creación y configurar si la persona tiene acceso a la carpeta desde su perfil.

        **¿Cuándo usar este endpoint?**

        * Organizar documentos de una persona creando carpetas específicas (contratos, certificados, etc.).
        * Crear una carpeta y subir el primer documento en una sola operación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Nombre único:** No pueden existir dos carpetas con el mismo nombre para la misma persona o empresa.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                name:
                  description: Nombre de la nueva carpeta.
                  type: string
                  example: Contratos laborales
                worker_access:
                  description: Si es `true`, la persona puede ver esta carpeta desde su perfil.
                  type: boolean
                  example: true
                worker_folder:
                  description: Si es `true`, la carpeta pertenece a la empresa (compartida). Si es `false`, pertenece a la persona.
                  type: boolean
                  example: false
                document:
                  description: Archivo PDF opcional para adjuntar al crear la carpeta.
                  type: string
                  format: binary
              required:
                - name
      responses:
        '201':
          description: Carpeta creada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la carpeta en la base de datos.
                        type: string
                        example: 49d8735a-0055-4e0d-ae7d-835a8f0abeb5
                      name:
                        description: Nombre de la carpeta creada.
                        type: string
                        example: Contratos laborales
                      updated_at:
                        description: Fecha y hora de la última actualización de la carpeta en formato ISO 8601.
                        type: string
                        format: date-time
                        example: '2024-07-03T19:23:15.222Z'
              example:
                data:
                  id: 49d8735a-0055-4e0d-ae7d-835a8f0abeb5
                  name: Contratos laborales
                  updated_at: '2024-07-03T19:23:15.222Z'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre de carpeta ya en uso
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0003'
                    index: 0
                    message: Nombre de la carpeta ya está en uso.
                    object: name
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 09c7a938-64f2-43a1-8413-4a97904c289d
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
  /v1/{company_id}/workers/{worker_id}/folders/{folder_id}/documents:
    post:
      operationId: createWorkerFolderDocument
      tags:
        - Documentos de personas
      summary: Subir documento a carpeta
      description: |
        **¿Qué hace este endpoint?**

        Sube un archivo PDF a una carpeta de documentos de la persona.

        **¿Cuándo usar este endpoint?**

        * Adjuntar documentos laborales o de identificación a una carpeta de la persona.
        * Registrar archivos de soporte como contratos, certificados o comprobantes de seguridad social.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Formato:** Solo se aceptan archivos PDF.
        * **Límite:** Máximo 30 archivos por persona.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                document:
                  description: Archivo PDF a subir.
                  type: string
                  format: binary
                document_name:
                  description: Nombre personalizado para el documento. Si se omite, se usa el nombre original del archivo.
                  type: string
                  example: Contrato firmado
              required:
                - document
      responses:
        '201':
          description: Documento subido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del documento creado dentro de la carpeta.
                    type: object
                    properties:
                      folder:
                        description: Carpeta donde se almacenó el documento con la información del archivo creado.
                        type: object
                        properties:
                          name:
                            description: Nombre de la carpeta donde se subió el documento.
                            type: string
                            example: Seguridad social
                          file:
                            description: Información del archivo recién subido.
                            type: object
                            properties:
                              id:
                                description: Identificador único (ID) asignado al documento en la base de datos.
                                type: string
                                example: 5e5bdef2-3f99-4276-a67e-a589b5f61ce2
                              name:
                                description: Nombre del archivo con extensión.
                                type: string
                                example: Contrato firmado.pdf
                              url_file:
                                description: URL de acceso al archivo para descarga o visualización.
                                type: string
                                example: https://storage.aleluya.com/documents/contrato_firmado.pdf
                              created_at:
                                description: Fecha de subida del documento en formato YYYY-MM-DD.
                                type: string
                                format: date
                                example: '2024-07-03'
              example:
                data:
                  folder:
                    name: Seguridad social
                    file:
                      id: 5e5bdef2-3f99-4276-a67e-a589b5f61ce2
                      name: Contrato firmado.pdf
                      url_file: https://storage.aleluya.com/documents/contrato_firmado.pdf
                      created_at: '2024-07-03'
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Archivo inválido / Límite de archivos alcanzado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Archivo inválido:
                  value:
                    error:
                      - code: '3301'
                        index: 0
                        message: El archivo es inválido.
                        object: folder_document
                Límite de archivos alcanzado:
                  value:
                    error:
                      - code: '0113'
                        index: 0
                        message: El límite de archivos por persona es 30.
                        object: folder_document
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 70fda00b-4993-4e22-b9d3-e2071c8c706b
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
      - in: path
        required: true
        name: folder_id
        description: Identificador único (ID) asignado a la carpeta en la base de datos.
        schema:
          type: string
          example: b4000992-0c47-54e2-a5d2-26b3ad8bd635
  /v1/{company_id}/workers/{worker_id}/folders/{folder_id}/documents/{id}:
    put:
      operationId: updateWorkerFolderDocument
      tags:
        - Documentos de personas
      summary: Actualizar documento de carpeta
      description: |
        **¿Qué hace este endpoint?**

        Actualiza un documento de la carpeta de la persona. Permite renombrar el archivo o moverlo a otra carpeta. Solo se puede realizar una acción por llamada: renombrar o mover.

        **¿Cuándo usar este endpoint?**

        * Corregir el nombre de un archivo ya subido.
        * Reorganizar documentos moviéndolos entre carpetas de la persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Una acción por llamada:** Si se envía `new_folder_id`, se mueve el documento. Si se envía `document_name`, se renombra. No se procesan ambos a la vez.
        * **Formato del nombre:** El nombre no debe contener caracteres especiales inválidos. La extensión `.pdf` se agrega automáticamente si no se incluye.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                document_name:
                  description: Nuevo nombre del archivo sin extensión. Se le agrega `.pdf` automáticamente.
                  type: string
                  example: Contrato actualizado
                new_folder_id:
                  description: Identificador único (ID) de la carpeta destino a la que se moverá el documento.
                  type: string
                  example: 94615fd3-b00c-4f2f-ad09-4f4c239a67eb
            examples:
              Renombrar documento:
                value:
                  document_name: Contrato actualizado
              Mover a otra carpeta:
                value:
                  new_folder_id: 94615fd3-b00c-4f2f-ad09-4f4c239a67eb
      responses:
        '200':
          description: Documento renombrado / Documento movido a otra carpeta
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación describiendo la acción realizada.
                        type: string
                        example: Se movió el archivo de Seguridad social a Contratos laborales
              examples:
                Documento renombrado:
                  value:
                    data:
                      message: Se cambió el nombre del archivo de contrato_original.pdf a Contrato actualizado.pdf
                Documento movido:
                  value:
                    data:
                      message: Se movió el archivo de Seguridad social a Contratos laborales
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nombre de archivo inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '3302'
                    index: 0
                    message: El nombre del archivo es inválido.
                    object: folder_document
    delete:
      operationId: destroyWorkerFolderDocument
      tags:
        - Documentos de personas
      summary: Eliminar documento de carpeta
      description: |
        **¿Qué hace este endpoint?**

        Elimina un documento de la carpeta de documentos de la persona.

        **¿Cuándo usar este endpoint?**

        * Borrar un archivo subido por error o que ya no es relevante.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      responses:
        '200':
          description: Documento eliminado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: El documento ha sido eliminado.
              example:
                data:
                  message: El documento ha sido eliminado.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 10019fc1-65c2-4bce-aa94-202076d84beb
      - in: path
        required: true
        name: folder_id
        description: Identificador único (ID) asignado a la carpeta en la base de datos.
        schema:
          type: string
          example: b4000992-0c47-54e2-a5d2-26b3ad8bd635
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado al documento en la base de datos.
        schema:
          type: string
          example: f5ab122c-84bf-59b2-8517-a8229f3220e2
  /v1/{company_id}/workers/{worker_id}/folders/{id}:
    get:
      operationId: showWorkerFolder
      tags:
        - Documentos de personas
      summary: Obtener carpeta con documentos
      description: |
        **¿Qué hace este endpoint?**

        Retorna los datos de una carpeta de documentos de la persona junto con el listado paginado de archivos que contiene.

        **¿Cuándo usar este endpoint?**

        * Mostrar el contenido de una carpeta específica de la persona para navegar sus documentos.
        * Obtener las URLs de descarga de los archivos almacenados en una carpeta.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Carpeta con documentos / Carpeta vacía
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la carpeta con el listado de archivos.
                    type: object
                    properties:
                      folder:
                        description: Información de la carpeta y sus documentos.
                        type: object
                        properties:
                          name:
                            description: Nombre de la carpeta.
                            type: string
                            example: Contratos laborales
                          files:
                            description: Listado de archivos almacenados en la carpeta.
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  description: Identificador único (ID) asignado al documento en la base de datos.
                                  type: string
                                  example: d35cf725-cf12-5a94-bea1-085865853262
                                name:
                                  description: Nombre del archivo con extensión.
                                  type: string
                                  example: contrato_laboral.pdf
                                url_file:
                                  description: URL de acceso al archivo para descarga o visualización.
                                  type: string
                                  example: https://storage.aleluya.com/documents/contrato_laboral.pdf
                                created_at:
                                  description: Fecha de subida del documento en formato YYYY-MM-DD.
                                  type: string
                                  format: date
                                  example: '2024-07-03'
                  filters:
                    description: Metadatos de paginación de los documentos de la carpeta.
                    type: object
                    properties:
                      total_records:
                        description: Total de documentos en la carpeta.
                        type: integer
                        example: 1
                      page:
                        description: Página actual de resultados.
                        type: integer
                        example: 1
                      per_page:
                        description: Número de documentos por página.
                        type: integer
                        example: 20
                      search:
                        description: Término de búsqueda aplicado. Retorna cadena vacía si no se filtró.
                        type: string
                        example: ''
              examples:
                Carpeta con documentos:
                  value:
                    data:
                      folder:
                        name: Contratos laborales
                        files:
                          - id: d35cf725-cf12-5a94-bea1-085865853262
                            name: contrato_laboral.pdf
                            url_file: https://storage.aleluya.com/documents/contrato_laboral.pdf
                            created_at: '2024-07-03'
                    filters:
                      total_records: 1
                      page: 1
                      per_page: 20
                      search: ''
                Carpeta vacía:
                  value:
                    data:
                      folder:
                        name: Contratos laborales
                        files: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    patch:
      operationId: updateWorkerFolder
      tags:
        - Documentos de personas
      summary: Actualizar carpeta de persona
      description: |
        **¿Qué hace este endpoint?**

        Actualiza el nombre y/o la configuración de acceso de una carpeta de documentos de la persona. Si solo se envía `name`, retorna un mensaje de confirmación del cambio de nombre. Si se envían otros campos como `worker_access`, retorna el objeto carpeta actualizado.

        **¿Cuándo usar este endpoint?**

        * Renombrar una carpeta de documentos.
        * Cambiar si la persona tiene acceso a ver la carpeta desde su perfil.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  description: Nuevo nombre de la carpeta.
                  type: string
                  example: Documentos de contrato
                worker_access:
                  description: Si es `true`, la persona puede ver esta carpeta desde su perfil.
                  type: boolean
                  example: true
      responses:
        '200':
          description: Nombre de carpeta actualizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación del cambio de nombre.
                        type: string
                        example: Se cambió el nombre de la carpeta de Contratos laborales a Documentos de contrato
              example:
                data:
                  message: Se cambió el nombre de la carpeta de Contratos laborales a Documentos de contrato
        '202':
          description: Carpeta actualizada con acceso de persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la carpeta en la base de datos.
                        type: string
                        example: d292de70-a803-5e2d-a87f-3ad1128f38fc
                      name:
                        description: Nombre actualizado de la carpeta.
                        type: string
                        example: Documentos de contrato
                      worker_access:
                        description: Indica si la persona puede ver la carpeta desde su perfil.
                        type: boolean
                        example: true
                      updated_at:
                        description: Fecha y hora de la última actualización en formato ISO 8601.
                        type: string
                        format: date-time
                        example: '2024-07-03T19:23:14.634Z'
              example:
                data:
                  id: d292de70-a803-5e2d-a87f-3ad1128f38fc
                  name: Documentos de contrato
                  worker_access: true
                  updated_at: '2024-07-03T19:23:14.634Z'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    delete:
      operationId: destroyWorkerFolder
      tags:
        - Documentos de personas
      summary: Eliminar carpeta de persona
      description: |
        **¿Qué hace este endpoint?**

        Elimina una carpeta de documentos de la persona.

        **¿Cuándo usar este endpoint?**

        * Eliminar una carpeta vacía que ya no se necesita.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Solo carpetas vacías:** No se puede eliminar una carpeta que tenga archivos adjuntos. Verificar `deleteable: true` en el listado antes de intentar eliminarla.
      responses:
        '200':
          description: Carpeta eliminada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La carpeta ha sido eliminada.
              example:
                data:
                  message: La carpeta ha sido eliminada.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Carpeta con archivos adjuntos
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '0506'
                    index: 0
                    message: No se puede eliminar la carpeta porque contiene archivos adjuntos.
                    object: folder_category
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 532a1b69-4b21-4f8c-934c-ce4cf28b0a2e
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 6626a96f-32b2-5890-bc03-af9d8b2854f7
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la carpeta en la base de datos.
        schema:
          type: string
          example: b4000992-0c47-54e2-a5d2-26b3ad8bd635
  /v1/{company_id}/workers/{worker_id}/holidays_history:
    get:
      operationId: showWorkerHolidaysHistory
      tags:
        - Historial de vacaciones
      summary: Obtener historial de vacaciones de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial de vacaciones de una persona con el detalle de cada periodo: días
        disfrutados, días del periodo, acumulados, saldo anterior y si corresponde a una liquidación.
        También permite exportar el historial completo en un archivo Excel.

        **¿Cuándo usar este endpoint?**

        * Consultar el historial completo de vacaciones de una persona para revisión o auditoría.
        * Exportar el historial de vacaciones de la persona en formato Excel.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Exportación asíncrona:** Cuando se envía `file_format: xlsx`, la generación siempre es asíncrona. El resultado se publica en Firebase; no retorna URL directa.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: file_format
          description: Cuando se envía con valor `xlsx`, genera un archivo Excel asíncrono con el historial completo en lugar del JSON paginado.
          schema:
            type: string
            example: xlsx
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `file_format`:

            - **Sin `file_format`** (por defecto): retorna el historial de vacaciones en JSON paginado con `data` y `filters`.
            - **`file_format: xlsx`**: retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta JSON paginada
                    required:
                      - data
                      - filters
                    properties:
                      data:
                        description: Listado de registros de vacaciones de la persona.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al registro de vacaciones en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            initial_day:
                              description: Fecha inicial del periodo de vacaciones, en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-01'
                            end_day:
                              description: Fecha final del periodo de vacaciones, en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-12-31'
                            enjoyed_holidays:
                              description: Días de vacaciones disfrutados en este registro.
                              type: number
                              example: 15
                            period_holidays:
                              description: Días de vacaciones causados en el periodo.
                              type: number
                              example: 15
                            accumulated_holidays:
                              description: Días de vacaciones acumulados al cierre del periodo.
                              type: number
                              example: 3.5
                            previous_holidays:
                              description: Saldo de vacaciones acumulado del periodo anterior.
                              type: number
                              example: 3.5
                            termination:
                              description: Indica si el registro corresponde a una liquidación de vacaciones por terminación de contrato.
                              type: boolean
                              example: false
                            user_email:
                              description: Correo electrónico del usuario que registró las vacaciones. Null si el usuario ya no existe.
                              type:
                                - string
                                - 'null'
                              example: admin@empresa.com
                      filters:
                        description: Información de paginación aplicada a la respuesta.
                        type: object
                        properties:
                          total_records:
                            description: Número total de registros de vacaciones de la persona.
                            type: integer
                            example: 5
                          page:
                            description: Número de página actual de la respuesta.
                            type: integer
                            example: 1
                          per_page:
                            description: Número máximo de registros retornados por página.
                            type: integer
                            example: 20
                          search:
                            description: Texto de búsqueda aplicado. Cadena vacía si no se envió búsqueda.
                            type: string
                            example: ''
                  - type: object
                    description: Respuesta asíncrona con archivo Excel
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento del archivo.
                        type: string
                        example: Procesando
              examples:
                JSON:
                  value:
                    data:
                      - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        initial_day: '2024-01-01'
                        end_day: '2024-12-31'
                        enjoyed_holidays: 15
                        period_holidays: 15
                        accumulated_holidays: 3.5
                        previous_holidays: 3.5
                        termination: false
                        user_email: admin@empresa.com
                    filters:
                      total_records: 5
                      page: 1
                      per_page: 20
                      search: ''
                Archivo asíncrono:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/income_certificate:
    get:
      operationId: showWorkerIncomeCertificate
      tags:
        - Certificados de ingresos
      summary: Generar certificado de ingresos de una persona
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el certificado de ingresos de una persona para un año fiscal en formato XLSX o PDF.

        **¿Cuándo usar este endpoint?**

        * Obtener el certificado de ingresos de una persona específica para declaración de renta u otros trámites fiscales.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **`certificate_year`:** Obligatorio. Debe ser un valor numérico. Si no hay nóminas liquidadas para el año indicado, el endpoint retorna 422.
      parameters:
        - in: query
          required: true
          name: certificate_year
          description: Año fiscal para el cual se genera el certificado. Debe ser un valor numérico (ej. 2024).
          schema:
            type: integer
            example: 2024
        - in: query
          required: false
          name: file_format
          schema:
            $ref: '#/components/schemas/CertificateFileFormat'
      responses:
        '200':
          description: Certificado de ingresos generado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del certificado de ingresos.
                    type: string
                    example: https://storage.aleluya.com/certificado-ingresos-2024.xlsx
                required:
                  - file
              example:
                file: https://storage.aleluya.com/certificado-ingresos-2024.xlsx
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Año inválido / Sin nóminas para el año indicado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Año inválido:
                  value:
                    error:
                      - code: '0101'
                        index: 0
                        message: Año es inválido.
                        object: year
                Sin nóminas para el año indicado:
                  value:
                    error:
                      - code: '0601'
                        index: 0
                        message: No hay información para generar el archivo.
                        object: file
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 8dd8c425-ea37-4560-a142-4f4f02c2ea71
  /v1/{company_id}/workers/{worker_id}/labor_certificate:
    get:
      operationId: showWorkerLaborCertificate
      tags:
        - Certificados laborales
      summary: Generar certificado laboral de una persona
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el certificado laboral de una persona en formato PDF.
        Permite elegir qué modalidad de salario incluir: salario base, salario promedio o
        promedio de ingresos no salariales. Si no se especifica, el certificado se genera
        sin información de salario.

        **¿Cuándo usar este endpoint?**

        * Obtener el certificado laboral para trámites bancarios, visas u otras gestiones que requiera la persona.
        * Generar el certificado con el salario base cuando se requiere el valor contractual fijo.
        * Generar el certificado con el salario promedio cuando se requiere reflejar los ingresos variables del último periodo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Suscripción activa:** La empresa debe tener una suscripción de pago activa.
        * **Firma configurada:** La empresa debe tener configurada una firma para certificados laborales. Si no está configurada, el endpoint retorna 422.
        * **Contrato activo:** La persona debe tener al menos un contrato registrado. Si no tiene contratos, el endpoint retorna 404.
      parameters:
        - name: salary_type
          in: query
          required: false
          description: Modalidad de salario a incluir en el certificado. Si no se envía, el certificado se genera sin información de salario. `base_salary` incluye el salario base del contrato; `average_salary` incluye el salario promedio del último periodo; `average_non_salary_income` incluye el salario promedio más el promedio de ingresos no salariales.
          schema:
            type: string
            enum:
              - base_salary
              - average_salary
              - average_non_salary_income
            example: base_salary
      responses:
        '200':
          description: Certificado laboral generado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del certificado laboral en formato PDF.
                    type: string
                    example: https://storage.aleluya.com/certificado-laboral.pdf
                required:
                  - file
              example:
                file: https://storage.aleluya.com/certificado-laboral.pdf
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Empresa sin firma configurada para certificados laborales
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '4701'
                    index: 0
                    message: La empresa no tiene configurada una firma para certificados laborales. Un administrador debe agregar esta configuración.
                    object: company_configuration
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 59e26cd6-2741-4bf6-8e13-6f5f66ed19f0
  /v1/{company_id}/workers/{worker_id}/loans:
    get:
      operationId: indexWorkerLoans
      tags:
        - Préstamos
      summary: Listar préstamos de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de préstamos de la persona con su saldo, cuota mensual
        y estado de pago.

        **¿Cuándo usar este endpoint?**

        * Consultar los préstamos activos e históricos de una persona para mostrarlos o gestionarlos.
        * Buscar un préstamo específico por nombre del concepto o valor.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: search
          description: Busca préstamos por nombre del concepto de nómina o por valor del préstamo.
          schema:
            type: string
            example: préstamo
      responses:
        '200':
          description: Con préstamos / Sin préstamos
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de préstamos de la persona.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al préstamo en la base de datos.
                          type: string
                          example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        name:
                          description: Nombre del concepto de nómina asociado al préstamo.
                          type: string
                          example: Préstamo personal
                        value:
                          description: Valor total del préstamo en pesos colombianos.
                          type: integer
                          example: 1000000
                        balance:
                          description: Saldo pendiente del préstamo en pesos colombianos.
                          type: integer
                          example: 600000
                        paid_value:
                          description: Valor pagado hasta la fecha en pesos colombianos.
                          type: integer
                          example: 400000
                        monthly_fee:
                          description: Cuota mensual del préstamo en pesos colombianos.
                          type: integer
                          example: 100000
                        pending_months:
                          description: Número de meses restantes para pagar el préstamo.
                          type: integer
                          example: 6
                        active:
                          description: Indica si el préstamo está activo y se descuenta en nómina.
                          type: boolean
                          example: true
                        period_apply:
                          $ref: '#/components/schemas/ApplicationPeriod'
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: f6a7b8c9-d0e1-2345-fabc-345678901234
                        deleteable:
                          description: Indica si el préstamo puede ser eliminado.
                          type: boolean
                          example: false
                        date:
                          description: Fecha de creación del préstamo en formato `YYYY-MM-DD`.
                          type: string
                          format: date
                          example: '2024-01-15'
                  filters:
                    description: Información de paginación aplicada.
                    type: object
                    properties:
                      total_records:
                        description: Número total de préstamos que coinciden con la búsqueda.
                        type: integer
                        example: 2
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de préstamos retornados por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado.
                        type: string
                        example: ''
              examples:
                Con préstamos:
                  value:
                    data:
                      - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        name: Préstamo personal
                        value: 1000000
                        balance: 600000
                        paid_value: 400000
                        monthly_fee: 100000
                        pending_months: 6
                        active: true
                        period_apply: all_periods
                        payroll_concept_id: f6a7b8c9-d0e1-2345-fabc-345678901234
                        deleteable: false
                        date: '2024-01-15'
                    filters:
                      total_records: 2
                      page: 1
                      per_page: 20
                      search: ''
                Sin préstamos:
                  value:
                    data: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateWorkerLoans
      tags:
        - Préstamos
      summary: Crear, actualizar o eliminar préstamos
      description: |
        **¿Qué hace este endpoint?**

        Gestiona los préstamos de la persona en una sola operación. La acción se determina
        automáticamente según los campos enviados en cada objeto de `loans`:

        * **Crear:** Sin `id` — crea un nuevo préstamo con el valor, cuota mensual y concepto indicados.
        * **Actualizar:** Con `id` y al menos un campo a modificar — actualiza los datos del préstamo.
        * **Eliminar:** Con `id` y `value: 0` (sin `monthly_fee`, `active` ni `period_apply`) — elimina el préstamo.

        **¿Cuándo usar este endpoint?**

        * Registrar un nuevo préstamo otorgado a la persona para descontarlo en nómina.
        * Activar o desactivar el descuento mensual de un préstamo existente.
        * Modificar la cuota mensual o el periodo de aplicación de un préstamo.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **`period_apply` por defecto:** Al crear, si no se envía `period_apply`, se asigna `all_periods` automáticamente.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - loans
              properties:
                loans:
                  description: Listado de operaciones a ejecutar sobre préstamos.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al préstamo en la base de datos. Omitir para crear uno nuevo.
                        type: string
                        example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos. Requerido para crear.
                        type: string
                        example: f6a7b8c9-d0e1-2345-fabc-345678901234
                      value:
                        description: Valor total del préstamo en pesos colombianos. Enviar `0` junto con `id` (sin otros campos) para eliminar.
                        type: integer
                        example: 1000000
                      monthly_fee:
                        description: Cuota mensual del préstamo en pesos colombianos. Requerida para crear.
                        type: integer
                        example: 100000
                      active:
                        description: Indica si el préstamo está activo y se descuenta en nómina.
                        type: boolean
                        example: true
                      period_apply:
                        $ref: '#/components/schemas/ApplicationPeriod'
            examples:
              Crear préstamo:
                value:
                  loans:
                    - payroll_concept_id: f6a7b8c9-d0e1-2345-fabc-345678901234
                      value: 1000000
                      monthly_fee: 100000
                      period_apply: all_periods
              Desactivar préstamo:
                value:
                  loans:
                    - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      active: false
              Eliminar préstamo:
                value:
                  loans:
                    - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                      value: 0
      responses:
        '202':
          description: Préstamos actualizados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de préstamos afectados por la operación.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al préstamo en la base de datos.
                          type: string
                          example: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        name:
                          description: Nombre del concepto de nómina asociado al préstamo.
                          type: string
                          example: Préstamo personal
                        value:
                          description: Valor total del préstamo en pesos colombianos.
                          type: integer
                          example: 1000000
                        balance:
                          description: Saldo pendiente del préstamo en pesos colombianos.
                          type: integer
                          example: 600000
                        paid_value:
                          description: Valor pagado hasta la fecha en pesos colombianos.
                          type: integer
                          example: 400000
                        monthly_fee:
                          description: Cuota mensual del préstamo en pesos colombianos.
                          type: integer
                          example: 100000
                        pending_months:
                          description: Número de meses restantes para pagar el préstamo.
                          type: integer
                          example: 6
                        active:
                          description: Indica si el préstamo está activo y se descuenta en nómina.
                          type: boolean
                          example: true
                        period_apply:
                          $ref: '#/components/schemas/ApplicationPeriod'
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: f6a7b8c9-d0e1-2345-fabc-345678901234
                        deleteable:
                          description: Indica si el préstamo puede ser eliminado.
                          type: boolean
                          example: false
                        date:
                          description: Fecha de creación del préstamo en formato `YYYY-MM-DD`.
                          type: string
                          format: date
                          example: '2024-01-15'
              example:
                data:
                  - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                    name: Préstamo personal
                    value: 1000000
                    balance: 1000000
                    paid_value: 0
                    monthly_fee: 100000
                    pending_months: 10
                    active: true
                    period_apply: all_periods
                    payroll_concept_id: f6a7b8c9-d0e1-2345-fabc-345678901234
                    deleteable: true
                    date: '2024-01-15'
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/novelties_history:
    get:
      operationId: showWorkerNoveltiesHistory
      tags:
        - Historial de novedades
      summary: Obtener historial de novedades de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial de novedades registradas en todas las nóminas de una persona, agrupadas
        por categoría. También permite exportar el historial completo en un archivo Excel.

        **¿Cuándo usar este endpoint?**

        * Consultar todas las novedades históricas de una persona para revisión o auditoría.
        * Filtrar por categoría para ver solo horas extras, deducciones o préstamos de la persona.
        * Exportar el historial completo de novedades de la persona en formato Excel.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Parámetro `async`:** Solo tiene efecto cuando se envía `file_format: xlsx`. Para la respuesta JSON se ignora.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: false
          name: file_format
          description: Cuando se envía con valor `xlsx`, retorna un archivo Excel con el historial completo en lugar del JSON paginado.
          schema:
            type: string
            example: xlsx
        - $ref: '#/components/parameters/noveltyFilterParam'
        - in: query
          required: false
          name: search
          description: Busca novedades por nombre del concepto. La búsqueda es parcial y no distingue tildes ni mayúsculas/minúsculas.
          schema:
            type: string
            example: Horas extras
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `file_format`:

            - **Sin `file_format`** (por defecto): retorna el historial de novedades en JSON paginado con `data` y `filters`.
            - **`file_format: xlsx` síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga.
            - **`file_format: xlsx` asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta JSON paginada
                    required:
                      - data
                      - filters
                    properties:
                      data:
                        description: Listado de novedades históricas de la persona con la información de cada registro.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la novedad en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            name:
                              description: Nombre del concepto de nómina o tipo de novedad.
                              type: string
                              example: Horas extras diurnas
                            initial_date:
                              description: Fecha inicial del periodo de aplicación de la novedad, en formato `YYYY-MM-DD`. Null si la novedad no tiene fecha inicial definida.
                              type:
                                - string
                                - 'null'
                              example: '2024-01-01'
                            end_date:
                              description: Fecha final del periodo de aplicación de la novedad, en formato `YYYY-MM-DD`. Null si la novedad no tiene fecha final definida.
                              type:
                                - string
                                - 'null'
                              example: '2024-01-15'
                            quantity:
                              description: Cantidad aplicada en la novedad (días, horas u otras unidades según el tipo de novedad).
                              type: number
                              example: 2
                            value:
                              description: Valor monetario de la novedad en pesos colombianos.
                              type: integer
                              example: 45000
                            date:
                              description: Fecha puntual asociada a la novedad, en formato `YYYY-MM-DD`. Aplica para novedades de fecha específica. Null si no aplica.
                              type:
                                - string
                                - 'null'
                              example: '2024-01-10'
                      filters:
                        description: Información de paginación y filtros aplicados a la respuesta.
                        type: object
                        properties:
                          total_records:
                            description: Número total de novedades que coinciden con los filtros aplicados.
                            type: integer
                            example: 8
                          filter:
                            description: Categoría de novedad activa en la consulta.
                            type: string
                            example: novelties
                          page:
                            description: Número de página actual de la respuesta.
                            type: integer
                            example: 1
                          per_page:
                            description: Número máximo de novedades retornadas por página.
                            type: integer
                            example: 20
                          search:
                            description: Texto de búsqueda aplicado. Null si no se envió búsqueda.
                            type:
                              - string
                              - 'null'
                            example: Horas extras
                  - type: object
                    description: Respuesta síncrona con archivo Excel
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel con el historial de novedades de la persona.
                        type: string
                        example: https://storage.example.com/novelties_history.xlsx
                  - type: object
                    description: Respuesta asíncrona con archivo Excel
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento del archivo.
                        type: string
                        example: Procesando
              examples:
                JSON:
                  value:
                    data:
                      - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        name: Horas extras diurnas
                        initial_date: '2024-01-01'
                        end_date: '2024-01-15'
                        quantity: 2
                        value: 45000
                        date: '2024-01-10'
                      - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                        name: Incapacidad
                        initial_date: '2024-01-05'
                        end_date: '2024-01-10'
                        quantity: 6
                        value: 120000
                        date: '2024-01-10'
                    filters:
                      total_records: 8
                      filter: novelties
                      page: 1
                      per_page: 20
                      search: ''
                Archivo síncrono:
                  value:
                    file: https://storage.example.com/novelties_history.xlsx
                Archivo asíncrono:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/novelty_requests:
    get:
      operationId: indexWorkerNoveltyRequests
      tags:
        - Solicitudes de novedades
      summary: Listar solicitudes de novedad de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de solicitudes de novedad de una persona específica,
        con soporte de búsqueda y filtro por estado.

        **¿Cuándo usar este endpoint?**

        * Consultar todas las solicitudes de novedad de una persona para revisarlas o gestionarlas.
        * Filtrar por estado para ver solo las solicitudes pendientes o aprobadas de la persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: search
          description: Busca solicitudes por nombre de la persona.
          schema:
            type: string
            example: Juan Pérez
        - in: query
          required: false
          name: filter
          description: Filtra las solicitudes por estado.
          schema:
            $ref: '#/components/schemas/NoveltyRequestStatus'
      responses:
        '200':
          description: Listado de solicitudes de novedad de la persona retornado correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos del listado de solicitudes de novedad de la persona.
                    type: object
                    properties:
                      novelty_requests:
                        description: Listado paginado de solicitudes de novedad de la persona.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado a la solicitud de novedad en la base de datos.
                              type: string
                              example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                            worker_id:
                              description: Identificador único (ID) asignado a la persona en la base de datos.
                              type: string
                              example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                            worker_name:
                              description: Nombre completo de la persona.
                              type: string
                              example: Juan Pérez
                            contract_category:
                              $ref: '#/components/schemas/ContractCategory'
                            initial_day:
                              description: Fecha de inicio de la novedad solicitada en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-15'
                            end_day:
                              description: Fecha de fin de la novedad solicitada en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-29'
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: e5f6a7b8-c9d0-1234-efab-234567890123
                            payroll_concept_name:
                              description: Nombre del concepto de novedad solicitado.
                              type: string
                              example: Vacaciones disfrutadas
                            comment:
                              description: Comentario del administrador sobre la solicitud.
                              type:
                                - string
                                - 'null'
                              example: null
                            days:
                              description: Número de días de la novedad solicitada.
                              type: integer
                              example: 15
                            status:
                              $ref: '#/components/schemas/NoveltyRequestStatus'
                            evidence:
                              description: URL del archivo de evidencia adjunto. Null si no hay evidencia.
                              type:
                                - string
                                - 'null'
                              example: null
                  filters:
                    description: Información de paginación y filtros aplicados.
                    type: object
                    properties:
                      total_records:
                        description: Número total de solicitudes que coinciden con los filtros aplicados.
                        type: integer
                        example: 2
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de solicitudes retornadas por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado.
                        type: string
                        example: ''
                      filter:
                        description: Filtro de estado aplicado. Null si no se aplicó filtro.
                        type:
                          - string
                          - 'null'
                        example: null
              examples:
                Con solicitudes:
                  value:
                    data:
                      novelty_requests:
                        - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                          worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                          worker_name: Juan Pérez
                          contract_category: employee
                          initial_day: '2024-01-15'
                          end_day: '2024-01-29'
                          payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                          payroll_concept_name: Vacaciones disfrutadas
                          comment: null
                          days: 15
                          status: approved
                          evidence: null
                    filters:
                      total_records: 2
                      page: 1
                      per_page: 20
                      search: ''
                      filter: null
                Sin solicitudes:
                  value:
                    data:
                      novelty_requests: []
                    filters:
                      total_records: 0
                      page: 1
                      per_page: 20
                      search: ''
                      filter: null
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/payments_history:
    get:
      operationId: indexWorkerPaymentsHistory
      tags:
        - Historial de pagos de la persona
      summary: Listar historial de pagos
      description: |
        **¿Qué hace este endpoint?**

        Retorna el historial de nóminas pagadas de una persona, con los totales de salario,
        otros ingresos, deducciones y pago neto por cada periodo.

        **¿Cuándo usar este endpoint?**

        * Consultar el historial completo de pagos de una persona para revisión o auditoría.
        * Obtener los totales por periodo para verificar pagos anteriores.
        * Exportar el historial completo en formato Excel.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Campo `payslip_options`:** Solo se popula cuando la nómina tiene liquidación de contrato o prestaciones sociales pagadas. En los demás casos retorna un arreglo vacío. Cada opción indica un tipo de desprendible disponible para esa nómina.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - $ref: '#/components/parameters/asyncParam'
        - in: query
          required: false
          name: file_format
          description: Cuando se envía con valor `xlsx`, retorna un archivo Excel con el historial completo en lugar del JSON paginado.
          schema:
            type: string
            example: xlsx
      responses:
        '200':
          description: |
            La estructura de la respuesta depende del parámetro `file_format`:

            - **Sin `file_format`** (por defecto): retorna el historial de pagos en JSON paginado con `data` y `filters`.
            - **`file_format: xlsx` síncrono** (`async: false` o sin enviar): retorna el campo `file` con la URL de descarga.
            - **`file_format: xlsx` asíncrono** (`async: true`): retorna `message: Procesando`. El resultado se publica en Firebase.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Respuesta JSON paginada
                    required:
                      - data
                      - filters
                    properties:
                      data:
                        description: Listado de nóminas pagadas de la persona con totales por periodo.
                        type: array
                        items:
                          type: object
                          properties:
                            payroll_id:
                              description: Identificador único (ID) asignado a la nómina en la base de datos.
                              type: string
                              example: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                            initial_day:
                              description: Fecha inicial del periodo de nómina, en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-01'
                            end_day:
                              description: Fecha final del periodo de nómina, en formato `YYYY-MM-DD`.
                              type: string
                              example: '2024-01-15'
                            salary:
                              description: Valor del salario base correspondiente al periodo, en pesos colombianos.
                              type: integer
                              example: 1500000
                            other_income:
                              description: Total de otros ingresos del periodo (ingresos adicionales, novedades, prestaciones pagadas, liquidación), en pesos colombianos.
                              type: integer
                              example: 150000
                            deductions_retentions:
                              description: Total de retenciones y deducciones del periodo, en pesos colombianos.
                              type: integer
                              example: 50000
                            worker_payment:
                              description: Valor neto a pagar a la persona en el periodo, en pesos colombianos.
                              type: integer
                              example: 1600000
                            payslip_options:
                              description: Opciones de tipo de desprendible disponibles para esta nómina. Solo se popula cuando la nómina tiene liquidación de contrato o prestaciones sociales pagadas; en los demás casos retorna un arreglo vacío.
                              type: array
                              items:
                                type: object
                                properties:
                                  label:
                                    description: Nombre legible del tipo de desprendible.
                                    type: string
                                    example: Nómina + liquidación
                                  value:
                                    description: Valor del tipo de desprendible usado como parámetro en la descarga del desprendible.
                                    type: string
                                    example: payroll_termination
                      filters:
                        description: Información de paginación aplicada a la respuesta.
                        type: object
                        properties:
                          total_records:
                            description: Número total de nóminas pagadas de la persona.
                            type: integer
                            example: 3
                          page:
                            description: Número de página actual de la respuesta.
                            type: integer
                            example: 1
                          per_page:
                            description: Número máximo de registros retornados por página.
                            type: integer
                            example: 20
                          search:
                            description: Texto de búsqueda aplicado. Null si no se envió búsqueda.
                            type:
                              - string
                              - 'null'
                            example: ''
                  - type: object
                    description: Respuesta síncrona con archivo Excel
                    required:
                      - file
                    properties:
                      file:
                        description: URL de descarga del archivo Excel con el historial de pagos de la persona.
                        type: string
                        example: https://storage.example.com/payments_history.xlsx
                  - type: object
                    description: Respuesta asíncrona con archivo Excel
                    required:
                      - message
                    properties:
                      message:
                        description: Mensaje de confirmación de encolamiento del archivo.
                        type: string
                        example: Procesando
              examples:
                JSON:
                  value:
                    data:
                      - payroll_id: 486a6163-82cb-556f-97b2-f9e98cdfc0a4
                        initial_day: '2024-01-01'
                        end_day: '2024-01-15'
                        salary: 1500000
                        other_income: 150000
                        deductions_retentions: 50000
                        worker_payment: 1600000
                        payslip_options: []
                      - payroll_id: 95054e94-5320-5b30-bcf3-59c224171028
                        initial_day: '2023-12-16'
                        end_day: '2023-12-31'
                        salary: 1500000
                        other_income: 800000
                        deductions_retentions: 50000
                        worker_payment: 2250000
                        payslip_options:
                          - label: Nómina
                            value: payroll
                          - label: Liquidación
                            value: termination
                          - label: Nómina + liquidación
                            value: payroll_termination
                    filters:
                      total_records: 3
                      page: 1
                      per_page: 20
                      search: ''
                Archivo síncrono:
                  value:
                    file: https://storage.example.com/payments_history.xlsx
                Archivo asíncrono:
                  value:
                    message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/recurrent_concepts:
    get:
      operationId: indexWorkerRecurrentConcepts
      tags:
        - Conceptos recurrentes de la persona
      summary: Listar conceptos recurrentes de la persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna el listado paginado de conceptos recurrentes de la persona, incluyendo ingresos,
        deducciones y préstamos según el tipo solicitado.

        **¿Cuándo usar este endpoint?**

        * Consultar los conceptos recurrentes activos de una persona para mostrarlos antes de editarlos.
        * Filtrar por tipo de concepto (ingresos, deducciones, préstamos) según la sección que se esté mostrando.
        * Verificar el balance y estado de los préstamos recurrentes de una persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Estructura variable por tipo:** Los registros de categoría `loan` incluyen campos adicionales (`paid_value`, `monthly_fee`, `pending_months`) que no están presentes en los demás tipos.
      parameters:
        - $ref: '#/components/parameters/pageParam'
        - $ref: '#/components/parameters/perPageParam'
        - in: query
          required: false
          name: type
          description: |
            Filtra los conceptos por categoría. Sin este parámetro retorna todos.

            * `salary_income` — Ingresos salariales
            * `non_salary_income` — Ingresos no salariales
            * `occasional_non_salary_income` — Ingresos no salariales ocasionales
            * `incomes` — Ingresos salariales y no salariales
            * `deductions` — Deducciones
            * `deductions_and_loans` — Deducciones y préstamos
            * `loans` — Préstamos
          schema:
            type: string
            enum:
              - salary_income
              - non_salary_income
              - occasional_non_salary_income
              - incomes
              - deductions
              - deductions_and_loans
              - loans
            example: deductions_and_loans
        - in: query
          required: false
          name: filter
          description: 'Filtra los conceptos por estado. Valores: `active` (activos), `inactive` (inactivos).'
          schema:
            type: string
            enum:
              - active
              - inactive
            example: active
        - in: query
          required: false
          name: search
          description: Busca conceptos por nombre del concepto de nómina.
          schema:
            type: string
            example: auxilio
      responses:
        '200':
          description: Conceptos recurrentes retornados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: |
                      Listado de conceptos recurrentes. Cada elemento puede ser un concepto recurrente
                      estándar o un préstamo (categoría `loan`). Los préstamos incluyen campos adicionales.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al concepto recurrente en la base de datos.
                          type: string
                          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        active:
                          description: Indica si el concepto recurrente está activo.
                          type: boolean
                          example: true
                        balance:
                          description: Saldo pendiente del concepto o préstamo, en pesos colombianos.
                          type:
                            - integer
                            - 'null'
                          example: 500000
                        monthly_value:
                          description: Valor mensual del concepto recurrente. Null para préstamos.
                          type:
                            - integer
                            - 'null'
                          example: 100000
                        concept_type:
                          description: Tipo de cálculo del concepto. `proportional` se ajusta proporcionalmente a los días trabajados; `fixed` se aplica siempre completo. Null para préstamos.
                          type:
                            - string
                            - 'null'
                          enum:
                            - proportional
                            - fixed
                          example: proportional
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: e5f6a7b8-c9d0-1234-efab-234567890123
                        name:
                          description: Nombre del concepto de nómina.
                          type: string
                          example: Auxilio de alimentación
                        category:
                          description: Categoría del concepto.
                          type: string
                          enum:
                            - non_salary_income
                            - salary_income
                            - occasional_non_salary_income
                            - deductions
                            - loan
                          example: non_salary_income
                        deleteable:
                          description: Indica si el concepto puede ser eliminado.
                          type: boolean
                          example: true
                        period_apply:
                          $ref: '#/components/schemas/ApplicationPeriod'
                        value:
                          description: Valor fijo del concepto en pesos colombianos. Null si no aplica.
                          type:
                            - integer
                            - 'null'
                          example: 50000
                        paid_value:
                          description: Valor pagado del préstamo hasta la fecha. Solo presente para categoría `loan`.
                          type: integer
                          example: 300000
                        monthly_fee:
                          description: Cuota mensual del préstamo. Solo presente para categoría `loan`.
                          type: integer
                          example: 100000
                        pending_months:
                          description: Número de meses pendientes para pagar el préstamo. Solo presente para categoría `loan`.
                          type: integer
                          example: 5
                  filters:
                    description: Información de paginación y filtros aplicados.
                    type: object
                    properties:
                      total_records:
                        description: Número total de conceptos que coinciden con los filtros aplicados.
                        type: integer
                        example: 4
                      page:
                        description: Número de página actual.
                        type: integer
                        example: 1
                      per_page:
                        description: Número máximo de conceptos retornados por página.
                        type: integer
                        example: 20
                      search:
                        description: Texto de búsqueda aplicado.
                        type: string
                        example: ''
                      filter:
                        description: Filtro de estado aplicado. Null si no se aplicó filtro.
                        type:
                          - string
                          - 'null'
                        example: active
              example:
                data:
                  - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    active: true
                    balance: 0
                    monthly_value: 100000
                    concept_type: proportional
                    payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                    name: Auxilio de alimentación
                    category: non_salary_income
                    deleteable: true
                    period_apply: all_periods
                    value: 50000
                  - id: b2c3d4e5-f6a7-8901-bcde-f12345678901
                    active: true
                    balance: 500000
                    monthly_value: 100000
                    concept_type: proportional
                    payroll_concept_id: f6a7b8c9-d0e1-2345-fabc-345678901234
                    name: Préstamo personal
                    category: loan
                    deleteable: false
                    period_apply: all_periods
                    value: 800000
                    paid_value: 300000
                    monthly_fee: 100000
                    pending_months: 5
                filters:
                  total_records: 4
                  page: 1
                  per_page: 20
                  search: ''
                  filter: active
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateWorkerRecurrentConcepts
      tags:
        - Conceptos recurrentes de la persona
      summary: Crear, actualizar o eliminar conceptos recurrentes
      description: |
        **¿Qué hace este endpoint?**

        Gestiona los conceptos recurrentes de la persona en una sola operación. La acción se determina
        automáticamente según los campos enviados en cada objeto de `recurrent_concepts`:

        * **Crear:** Sin `id` — crea un nuevo concepto recurrente con el concepto de nómina y valor mensual indicados.
        * **Actualizar:** Con `id` y al menos un campo a modificar — actualiza los datos del concepto existente.
        * **Eliminar:** Con `id` únicamente (sin `monthly_value`, `payroll_concept_id`, `active`, `concept_type`, `period_apply` ni `value`) — elimina el concepto.

        **¿Cuándo usar este endpoint?**

        * Asignar un auxilio de alimentación u otro ingreso recurrente que se suma automáticamente en cada nómina.
        * Activar o desactivar un concepto recurrente sin eliminarlo.
        * Eliminar un concepto recurrente que ya no aplica para la persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Contratos de tiempo parcial:** Para contratos de tiempo parcial, los conceptos de deducción solo pueden tener `concept_type: proportional`.
        * **Retención configurada:** No se puede activar un concepto recurrente de retención en la fuente (`withholding_tax`) si la persona tiene una configuración de retención activa.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - recurrent_concepts
              properties:
                recurrent_concepts:
                  description: Listado de operaciones a ejecutar sobre conceptos recurrentes.
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado al concepto recurrente en la base de datos. Omitir para crear uno nuevo.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      payroll_concept_id:
                        description: Identificador único (ID) asignado al concepto de nómina en la base de datos. Requerido para crear.
                        type: string
                        example: e5f6a7b8-c9d0-1234-efab-234567890123
                      monthly_value:
                        description: Valor mensual del concepto en pesos colombianos.
                        type: integer
                        example: 100000
                      active:
                        description: Indica si el concepto recurrente está activo.
                        type: boolean
                        example: true
                      concept_type:
                        description: Tipo de cálculo. `proportional` ajusta el valor proporcionalmente a los días trabajados; `fixed` aplica el valor completo siempre.
                        type: string
                        enum:
                          - proportional
                          - fixed
                        example: proportional
                      period_apply:
                        $ref: '#/components/schemas/ApplicationPeriod'
                      value:
                        description: Valor fijo del concepto en pesos colombianos. Enviar `null` para limpiar el valor fijo.
                        type:
                          - integer
                          - 'null'
                        example: 50000
            examples:
              Crear concepto recurrente:
                value:
                  recurrent_concepts:
                    - payroll_concept_id: e5f6a7b8-c9d0-1234-efab-234567890123
                      monthly_value: 100000
                      concept_type: proportional
                      period_apply: all_periods
              Desactivar concepto:
                value:
                  recurrent_concepts:
                    - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      active: false
              Eliminar concepto:
                value:
                  recurrent_concepts:
                    - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
      responses:
        '202':
          description: Conceptos recurrentes actualizados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de conceptos recurrentes afectados con sus valores actualizados.
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al concepto recurrente en la base de datos.
                          type: string
                          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        active:
                          description: Indica si el concepto recurrente está activo.
                          type: boolean
                          example: true
                        balance:
                          description: Saldo pendiente del concepto o préstamo, en pesos colombianos. Null si no aplica.
                          type:
                            - integer
                            - 'null'
                          example: 500000
                        concept_type:
                          description: Tipo de cálculo del concepto. `proportional` ajusta el valor proporcionalmente a los días trabajados; `fixed` aplica el valor completo siempre. Null para préstamos.
                          type:
                            - string
                            - 'null'
                          enum:
                            - proportional
                            - fixed
                          example: proportional
                        deleteable:
                          description: Indica si el concepto puede ser eliminado.
                          type: boolean
                          example: true
                        monthly_value:
                          description: Valor mensual del concepto recurrente en pesos colombianos.
                          type: integer
                          example: 100000
                        period_apply:
                          $ref: '#/components/schemas/ApplicationPeriod'
                        value:
                          description: Valor fijo del concepto en pesos colombianos. Null si no aplica.
                          type:
                            - integer
                            - 'null'
                          example: 50000
                        payroll_concept:
                          description: Concepto de nómina asociado al concepto recurrente.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: e5f6a7b8-c9d0-1234-efab-234567890123
                            name:
                              description: Nombre del concepto de nómina.
                              type: string
                              example: Auxilio de alimentación
              example:
                data:
                  - id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                    active: true
                    balance: 0
                    concept_type: proportional
                    deleteable: true
                    monthly_value: 100000
                    period_apply: all_periods
                    value: 50000
                    payroll_concept:
                      id: e5f6a7b8-c9d0-1234-efab-234567890123
                      name: Auxilio de alimentación
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/retention_configurations:
    get:
      operationId: showRetentionConfiguration
      tags:
        - Configuración de retención en la fuente
      summary: Obtener configuración de retención
      description: |
        **¿Qué hace este endpoint?**

        Retorna la configuración de retención en la fuente de la persona, incluyendo si está activa,
        la fecha de activación y los valores de deducciones aplicables (intereses de vivienda,
        medicina prepagada y deducción por dependientes).

        **¿Cuándo usar este endpoint?**

        * Consultar si una persona tiene retención en la fuente configurada antes de editarla.
        * Verificar los valores de deducción actuales para mostrarlos en el formulario de configuración.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Configuración de retención retornada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la configuración de retención en la fuente de la persona.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de retención en la base de datos.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      active:
                        description: Indica si la retención en la fuente está activa para esta persona.
                        type: boolean
                        example: true
                      activate_since:
                        description: Fecha desde la que aplica la retención, ajustada al primer día del mes, en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-01'
                      housing_interests:
                        description: Valor mensual de intereses de crédito hipotecario deducibles, en pesos colombianos.
                        type: integer
                        example: 0
                      prepaid_medicine:
                        description: Valor mensual de medicina prepagada deducible, en pesos colombianos.
                        type: integer
                        example: 0
                      dependents_deduction:
                        description: Indica si aplica la deducción por dependientes (25% del ingreso laboral, hasta 240 UVT).
                        type: boolean
                        example: false
              example:
                data:
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  active: true
                  activate_since: '2024-01-01'
                  housing_interests: 0
                  prepaid_medicine: 0
                  dependents_deduction: false
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    post:
      operationId: createRetentionConfiguration
      tags:
        - Configuración de retención en la fuente
      summary: Crear configuración de retención
      description: |
        **¿Qué hace este endpoint?**

        Crea la configuración de retención en la fuente para la persona. Solo puede existir
        una configuración por persona.

        **¿Cuándo usar este endpoint?**

        * Activar la retención en la fuente para una persona que aún no tiene configuración registrada.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **`activate_since`:** Si no se envía, se usa la fecha actual. Al guardar, siempre se ajusta al primer día del mes correspondiente.
        * **Concepto recurrente activo:** No se puede activar la retención si la persona tiene un concepto recurrente activo de retención en la fuente (`withholding_tax`). Eliminar o desactivar el concepto recurrente primero.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - retention_configuration
              properties:
                retention_configuration:
                  description: Datos de la configuración de retención en la fuente a crear.
                  type: object
                  required:
                    - active
                  properties:
                    active:
                      description: Indica si la retención en la fuente está activa.
                      type: boolean
                      example: true
                    activate_since:
                      description: Fecha desde la que aplica la retención en formato `YYYY-MM-DD`. Por defecto usa la fecha actual si no se envía.
                      type: string
                      format: date
                      example: '2024-01-15'
                    housing_interests:
                      description: Valor mensual de intereses de crédito hipotecario deducibles, en pesos colombianos.
                      type: integer
                      example: 0
                    prepaid_medicine:
                      description: Valor mensual de medicina prepagada deducible, en pesos colombianos.
                      type: integer
                      example: 0
                    dependents_deduction:
                      description: Indica si aplica la deducción por dependientes.
                      type: boolean
                      example: false
            example:
              retention_configuration:
                active: true
                activate_since: '2024-01-15'
                housing_interests: 0
                prepaid_medicine: 0
                dependents_deduction: false
      responses:
        '201':
          description: Configuración de retención creada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la configuración de retención en la fuente de la persona.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de retención en la base de datos.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      active:
                        description: Indica si la retención en la fuente está activa para esta persona.
                        type: boolean
                        example: true
                      activate_since:
                        description: Fecha desde la que aplica la retención, ajustada al primer día del mes, en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-01'
                      housing_interests:
                        description: Valor mensual de intereses de crédito hipotecario deducibles, en pesos colombianos.
                        type: integer
                        example: 0
                      prepaid_medicine:
                        description: Valor mensual de medicina prepagada deducible, en pesos colombianos.
                        type: integer
                        example: 0
                      dependents_deduction:
                        description: Indica si aplica la deducción por dependientes (25% del ingreso laboral, hasta 240 UVT).
                        type: boolean
                        example: false
              example:
                data:
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  active: true
                  activate_since: '2024-01-01'
                  housing_interests: 0
                  prepaid_medicine: 0
                  dependents_deduction: false
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    patch:
      operationId: updateRetentionConfiguration
      tags:
        - Configuración de retención en la fuente
      summary: Actualizar configuración de retención
      description: |
        **¿Qué hace este endpoint?**

        Actualiza la configuración de retención en la fuente de la persona.

        **¿Cuándo usar este endpoint?**

        * Cambiar los valores de deducción (intereses de vivienda, medicina prepagada, dependientes).
        * Activar o desactivar la retención en la fuente para la persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **`activate_since`:** Al guardar con `active: true`, la fecha se ajusta automáticamente al primer día del mes.
        * **Concepto recurrente activo:** No se puede activar la retención si la persona tiene un concepto recurrente activo de retención en la fuente (`withholding_tax`).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - retention_configuration
              properties:
                retention_configuration:
                  description: Datos de la configuración de retención en la fuente a actualizar.
                  type: object
                  properties:
                    active:
                      description: Indica si la retención en la fuente está activa.
                      type: boolean
                      example: false
                    activate_since:
                      description: Nueva fecha desde la que aplica la retención en formato `YYYY-MM-DD`.
                      type: string
                      format: date
                      example: '2024-02-01'
                    housing_interests:
                      description: Valor mensual de intereses de crédito hipotecario deducibles, en pesos colombianos.
                      type: integer
                      example: 500000
                    prepaid_medicine:
                      description: Valor mensual de medicina prepagada deducible, en pesos colombianos.
                      type: integer
                      example: 200000
                    dependents_deduction:
                      description: Indica si aplica la deducción por dependientes.
                      type: boolean
                      example: true
            example:
              retention_configuration:
                housing_interests: 500000
                dependents_deduction: true
      responses:
        '202':
          description: Configuración de retención actualizada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Datos de la configuración de retención en la fuente de la persona.
                    type: object
                    properties:
                      id:
                        description: Identificador único (ID) asignado a la configuración de retención en la base de datos.
                        type: string
                        example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      worker_id:
                        description: Identificador único (ID) asignado a la persona en la base de datos.
                        type: string
                        example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                      active:
                        description: Indica si la retención en la fuente está activa para esta persona.
                        type: boolean
                        example: true
                      activate_since:
                        description: Fecha desde la que aplica la retención, ajustada al primer día del mes, en formato `YYYY-MM-DD`.
                        type: string
                        format: date
                        example: '2024-01-01'
                      housing_interests:
                        description: Valor mensual de intereses de crédito hipotecario deducibles, en pesos colombianos.
                        type: integer
                        example: 0
                      prepaid_medicine:
                        description: Valor mensual de medicina prepagada deducible, en pesos colombianos.
                        type: integer
                        example: 0
                      dependents_deduction:
                        description: Indica si aplica la deducción por dependientes (25% del ingreso laboral, hasta 240 UVT).
                        type: boolean
                        example: false
              example:
                data:
                  id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                  worker_id: 0cb5b128-6b32-58e7-ae22-a52438eccf52
                  active: true
                  activate_since: '2024-01-01'
                  housing_interests: 500000
                  prepaid_medicine: 0
                  dependents_deduction: true
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          $ref: '#/components/responses/422'
    delete:
      operationId: destroyRetentionConfiguration
      tags:
        - Configuración de retención en la fuente
      summary: Eliminar configuración de retención
      description: |
        **¿Qué hace este endpoint?**

        Elimina la configuración de retención en la fuente de la persona de forma permanente.

        **¿Cuándo usar este endpoint?**

        * Eliminar la configuración de retención cuando ya no aplica para la persona.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
      responses:
        '200':
          description: Configuración de retención eliminada correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la eliminación.
                        type: string
                        example: La información fue eliminada con éxito.
              example:
                data:
                  message: La información fue eliminada con éxito.
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 91c77755-5ca2-42fc-8221-f4f2c030bb6c
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers/{worker_id}/worker_options:
    get:
      operationId: showWorkerOptions
      tags:
        - Personas
      summary: Obtener opciones de persona
      description: |
        **¿Qué hace este endpoint?**

        Retorna las opciones disponibles para una persona: qué certificados puede generar, qué historiales puede consultar, qué opciones de colillas tiene disponibles, si su liquidación es editable y qué contratos tienen retención en la fuente configurada.

        **¿Cuándo usar este endpoint?**

        * Determinar qué acciones están habilitadas para una persona antes de mostrar las opciones disponibles en su perfil.
        * Consultar los contratos de una persona que tienen retención en la fuente configurada y los años en que aplica.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Opciones disponibles de la persona
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Conjunto de opciones disponibles para la persona.
                    type: object
                    properties:
                      certificate_options:
                        description: Lista de tipos de certificados que pueden generarse para la persona.
                        type: array
                        items:
                          type: string
                          enum:
                            - income_certificate
                            - labor_certificate
                      history_options:
                        description: |
                          Lista de historiales disponibles para consultar de la persona.

                          Valores posibles:

                          * `contracts` — Contratos
                          * `contract_details` — Detalles del contrato
                          * `novelties` — Novedades
                          * `payments` — Pagos
                          * `social_benefits` — Prestaciones sociales (solo si aplica al contrato activo)
                          * `loans` — Préstamos (solo si aplica al contrato activo)
                          * `contract_position_histories` — Historial de cargos
                          * `cost_center_configurations` — Centros de costos
                          * `with_retention` — Retención en la fuente (solo si aplica al contrato activo)
                          * `wages` — Salarios
                          * `holidays` — Vacaciones (solo si aplica al contrato activo)
                        type: array
                        items:
                          type: string
                          enum:
                            - cost_center_configurations
                            - contracts
                            - contract_details
                            - novelties
                            - payments
                            - social_benefits
                            - loans
                            - contract_position_histories
                            - with_retention
                            - wages
                            - holidays
                      payslips_options:
                        description: Lista de opciones de colillas de pago disponibles para la persona.
                        type: array
                        items:
                          type: string
                          enum:
                            - last_payslip
                            - payroll_history
                      editable_termination:
                        description: Indica si la liquidación de la persona puede ser editada.
                        type: boolean
                        example: true
                      contracts_with_retention:
                        description: Listado de contratos de la persona que tienen configurada retención en la fuente, con los años en que aplica.
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al contrato en la base de datos.
                              type: string
                              example: 2e49fbef-2edd-495c-8bf6-cfbdbd2ac110
                            initial_day:
                              description: Fecha de inicio del contrato en formato YYYY-MM-DD.
                              type: string
                              format: date
                              example: '2024-01-15'
                            years:
                              description: Años en los que aplica retención en la fuente para el contrato.
                              type: array
                              items:
                                type: integer
                              example:
                                - 2023
                                - 2024
              example:
                data:
                  certificate_options:
                    - income_certificate
                    - labor_certificate
                  history_options:
                    - cost_center_configurations
                    - contracts
                    - novelties
                    - payments
                    - loans
                    - wages
                    - contract_details
                    - holidays
                    - social_benefits
                    - with_retention
                  payslips_options:
                    - last_payslip
                    - payroll_history
                  editable_termination: true
                  contracts_with_retention:
                    - id: 2e49fbef-2edd-495c-8bf6-cfbdbd2ac110
                      initial_day: '2024-01-15'
                      years:
                        - 2023
                        - 2024
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 57c0fe06-891f-4d8b-bf0b-41a08abf15b0
      - in: path
        required: true
        name: worker_id
        description: Identificador único (ID) asignado a la persona en la base de datos.
        schema:
          type: string
          example: 0cb5b128-6b32-58e7-ae22-a52438eccf52
  /v1/{company_id}/workers_file:
    get:
      operationId: downloadWorkersFile
      tags:
        - Importación masiva
      summary: Descargar archivo de personas
      description: |
        **¿Qué hace este endpoint?**

        Genera y retorna el archivo Excel con la información de todas las personas de la empresa. Puede operar de forma síncrona (retorna la URL directamente) o asíncrona (encola el trabajo y entrega el resultado por Firebase).

        **¿Cuándo usar este endpoint?**

        * Exportar el listado completo de personas de la empresa en formato Excel.
        * Obtener el archivo base para editarlo y luego reimportarlo con el endpoint de importación.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Modo asíncrono:** Si se envía `async=true`, el archivo se encola en segundo plano y el resultado se publica en Firebase en la ruta `companies/{company_id}/workers_file`. La respuesta retorna `message: Procesando`.
        * **Modo síncrono:** Sin el parámetro `async`, el archivo se genera en el momento y se retorna la URL de descarga directamente.
      parameters:
        - $ref: '#/components/parameters/asyncParam'
      responses:
        '200':
          description: URL del archivo generado / Generación encolada
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    description: URL de descarga del archivo Excel con la información de personas. Presente en modo síncrono.
                    type:
                      - string
                      - 'null'
                    example: https://storage.aleluya.com/workers_file.xlsx
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje que indica que el archivo está siendo procesado. Presente en modo asíncrono.
                        type:
                          - string
                          - 'null'
                        example: Procesando
              examples:
                Síncrono:
                  value:
                    file: https://storage.aleluya.com/workers_file.xlsx
                Asíncrono:
                  value:
                    data:
                      message: Procesando
        '401':
          $ref: '#/components/responses/401'
        '402':
          $ref: '#/components/responses/402'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: edd4f948-d0b0-41e0-8fb1-d69509f51113
  /v1/{company_id}/{id}/electronic_payroll_items:
    get:
      operationId: indexElectronicPayrollItems
      tags:
        - Emisión de nómina electrónica
      summary: Listar ítems de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Retorna los conceptos de nómina registrados manualmente en una nómina electrónica. Estos conceptos complementan los valores calculados automáticamente del periodo de nómina al momento de la emisión ante la DIAN.

        **¿Cuándo usar este endpoint?**

        * Consultar los conceptos registrados en una nómina electrónica antes de emitirla.
        * Verificar los valores existentes para decidir si se deben actualizar antes de retransmitir.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
      responses:
        '200':
          description: Listado de ítems de la nómina electrónica
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Listado de ítems registrados en la nómina electrónica.
                    type: array
                    items:
                      description: Ítem de nómina electrónica con su concepto y valor.
                      type: object
                      properties:
                        id:
                          description: Identificador único (ID) asignado al ítem de nómina electrónica en la base de datos.
                          type: string
                          example: 412d7580-cf69-570c-8ff5-2e99bf564487
                        payroll_concept_id:
                          description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                          type: string
                          example: 107b0dcf-7a49-5f69-a3e6-de6d58eac388
                        name:
                          description: Nombre legible del concepto de nómina asociado al ítem.
                          type: string
                          example: Bono no salarial de alimentación
                        coded_name:
                          description: Nombre en código del concepto de nómina, usado internamente para identificar el tipo de concepto.
                          type: string
                          example: non_wage_food_bonus
                        value:
                          description: Valor del ítem en pesos colombianos, redondeado al entero más cercano.
                          type: integer
                          example: 90000
              examples:
                Con ítems:
                  value:
                    data:
                      - id: 412d7580-cf69-570c-8ff5-2e99bf564487
                        payroll_concept_id: 107b0dcf-7a49-5f69-a3e6-de6d58eac388
                        name: Bono no salarial de alimentación
                        coded_name: non_wage_food_bonus
                        value: 90000
                Sin ítems:
                  value:
                    data: []
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
    put:
      operationId: updateElectronicPayrollItems
      tags:
        - Emisión de nómina electrónica
      summary: Actualizar ítems de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Crea o actualiza los ítems (conceptos de nómina adicionales) de una nómina electrónica. Si ya existen ítems, los reemplaza con los nuevos valores enviados. Puede crear una nueva versión de la nómina electrónica si la actual ya fue procesada.

        **¿Cuándo usar este endpoint?**

        * Agregar o modificar conceptos de nómina adicionales antes de emitir la nómina electrónica.
        * Corregir valores de ítems en una nómina electrónica rechazada o pendiente.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin), contador (accountant) o revisor (reviewer).
        * **Nómina actual:** Solo se pueden modificar ítems de la nómina electrónica actual (`current: true`). Si la nómina ya fue reemplazada, se retorna un error 422.
        * **Nueva versión:** Si al actualizar los ítems se genera una nueva nómina electrónica (por cambio de estado), el campo `electronic_payroll_id` en la respuesta puede diferir del `{id}` enviado en la ruta.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                items:
                  description: Listado de ítems a crear o actualizar en la nómina electrónica.
                  type: array
                  items:
                    description: Ítem con el concepto de nómina y su valor.
                    type: object
                    properties:
                      payroll_concept_id:
                        description: Identificador único (ID) del concepto de nómina a asociar al ítem.
                        type: string
                        example: b124c515-db8e-58d3-93c7-b3055ab5f7b1
                      value:
                        description: Valor del ítem en pesos colombianos.
                        type: number
                        example: 107000
                    required:
                      - payroll_concept_id
                      - value
              required:
                - items
      responses:
        '202':
          description: Ítems actualizados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    description: Resultado de la actualización con el ID de la nómina electrónica y sus ítems.
                    type: object
                    properties:
                      electronic_payroll_id:
                        description: Identificador único (ID) de la nómina electrónica que contiene los ítems actualizados. Puede diferir del `{id}` enviado si se generó una nueva versión.
                        type: string
                        example: 60057aae-6eea-425a-b6c2-7589306d3e9e
                      electronic_payroll_items:
                        description: Listado de ítems de la nómina electrónica tras la actualización.
                        type: array
                        items:
                          description: Ítem de nómina electrónica actualizado.
                          type: object
                          properties:
                            id:
                              description: Identificador único (ID) asignado al ítem en la base de datos.
                              type: string
                              example: 34dc33b0-ae33-424e-b5d6-7650c47a86e7
                            payroll_concept_id:
                              description: Identificador único (ID) asignado al concepto de nómina en la base de datos.
                              type: string
                              example: b124c515-db8e-58d3-93c7-b3055ab5f7b1
                            name:
                              description: Nombre legible del concepto de nómina.
                              type: string
                              example: Dotación
                            coded_name:
                              description: Nombre en código del concepto de nómina.
                              type: string
                              example: endowment_bonus
                            value:
                              description: Valor del ítem en pesos colombianos, redondeado al entero más cercano.
                              type: integer
                              example: 107000
              example:
                data:
                  electronic_payroll_id: 60057aae-6eea-425a-b6c2-7589306d3e9e
                  electronic_payroll_items:
                    - id: 34dc33b0-ae33-424e-b5d6-7650c47a86e7
                      payroll_concept_id: b124c515-db8e-58d3-93c7-b3055ab5f7b1
                      name: Dotación
                      coded_name: endowment_bonus
                      value: 107000
                    - id: a6442ff7-0502-4ef6-9036-a821d598eff3
                      payroll_concept_id: 107b0dcf-7a49-5f69-a3e6-de6d58eac388
                      name: Bono no salarial de alimentación
                      coded_name: non_wage_food_bonus
                      value: 90000
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Nómina no actual / Ítems vacíos
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              examples:
                Nómina no actual:
                  value:
                    error:
                      - code: '2701'
                        index: 0
                        message: La nómina electrónica no es la actual, razón por la cual no puede ser actualizada.
                        object: electronic_payroll
                Ítems vacíos:
                  value:
                    error:
                      - code: '0102'
                        index: 0
                        message: Los datos enviados son inválidos.
                        object: request
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: bce251f3-840c-45e1-ad5b-44b0be6a8235
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
        schema:
          type: string
          example: a03b18ca-9e5b-53af-a907-ab9babdc02c3
  /v1/{company_id}/{id}/government_data:
    patch:
      operationId: updateElectronicPayrollGovernmentData
      tags:
        - Archivos XML y gobierno
      summary: Ajustar datos de gobierno de nómina electrónica
      description: |
        **¿Qué hace este endpoint?**

        Actualiza los valores de provisiones sociales (vacaciones, prima, cesantías e intereses) en el dato de gobierno de una nómina electrónica, para corregir o ajustar la información que se enviará a la DIAN. Si un valor se envía en cero, el concepto correspondiente se elimina del XML.

        **¿Cuándo usar este endpoint?**

        * Corregir el valor de vacaciones disfrutadas reportado en una nómina electrónica antes de emitirla.
        * Ajustar el valor de prima, cesantías o intereses de cesantías en el dato de gobierno de la DIAN.
        * Eliminar un concepto del XML enviando su valor en cero.

        **Consideraciones importantes**

        * **Accesos:** El usuario debe tener acceso a la empresa especificada en `{company_id}` con rol administrador (admin) o contador (accountant).
        * **Valor en cero:** Si `enjoyed_days` es `0`, se eliminan las vacaciones del XML. Si `severance` y `severance_interests` son ambos `0`, se eliminan las cesantías. Si `service_bonus` es `0`, se elimina la prima.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                enjoyed_days:
                  description: Valor del pago de vacaciones disfrutadas en pesos colombianos. Si es `0`, elimina las vacaciones del XML de gobierno.
                  type: integer
                  example: 583333
                service_bonus:
                  description: Valor del pago de prima de servicios en pesos colombianos. Si es `0`, elimina la prima del XML de gobierno.
                  type: integer
                  example: 750000
                severance:
                  description: Valor del pago de cesantías en pesos colombianos. Si es `0` junto con `severance_interests`, elimina las cesantías del XML de gobierno.
                  type: integer
                  example: 1850000
                severance_interests:
                  description: Valor del pago de intereses de cesantías en pesos colombianos. Si es `0` junto con `severance`, elimina las cesantías del XML de gobierno.
                  type: integer
                  example: 222000
      responses:
        '202':
          description: Datos de gobierno actualizados correctamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      message:
                        description: Mensaje de confirmación de la actualización de los ajustes a provisiones.
                        type: string
                        example: Ajustes a provisiones de nómina electrónica actualizados exitosamente.
              example:
                data:
                  message: Ajustes a provisiones de nómina electrónica actualizados exitosamente.
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '404':
          $ref: '#/components/responses/404'
        '422':
          description: Información de gobierno incompleta
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorModel'
              example:
                error:
                  - code: '2707'
                    index: 0
                    message: La información de la nómina electrónica no se encuentra completa, por favor contacta a soporte.
                    object: electronic_payroll
    parameters:
      - in: path
        required: true
        name: company_id
        description: Identificador único (ID) asignado a la empresa en la base de datos.
        schema:
          type: string
          example: 56e06d90-0244-5866-9b2a-af6df5418eee
      - in: path
        required: true
        name: id
        description: Identificador único (ID) asignado a la nómina electrónica en la base de datos.
        schema:
          type: string
          example: 779f3d38-21ad-435c-aaf1-f005b2e4b57b
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        JWT token obtenido al autenticarse con el endpoint /v1/sessions.
        Se debe incluir en el header Authorization como `Bearer {token}`.
        Este token tiene una duración de 30 minutos.
    BasicAuth:
      type: http
      scheme: basic
      description: |
        Autenticación básica con usuario (email o id) y contraseña o API token.
        Se debe incluir en el header Authorization como `Basic base64(email:password)` o `Basic base64(email:api_token)`.
        Este método solo se usa para crear sesiones y obtener el token JWT.
  schemas:
    BasicErrorModel:
      type: object
      properties:
        error:
          type: array
          items:
            type: object
            properties:
              code:
                description: Código de error.
                type: string
              index:
                description: Índice relacionado con el error.
                type: integer
              message:
                description: Descripción del error.
                type: string
              object:
                description: Objeto relacionado con el error.
                type: string
    CompanyDocumentType:
      type: string
      description: |
        Tipo de documento de identificación de la empresa.

        Valores posibles:

        * `ni` — NIT (Número de Identificación Tributaria)
        * `cc` — Cédula de Ciudadanía
        * `ce` — Cédula de Extranjería
        * `ti` — Tarjeta de Identidad
        * `pa` — Pasaporte
      enum:
        - ni
        - cc
        - ce
        - ti
        - pa
      example: ni
    UserAccessRole:
      type: string
      description: |
        Rol del usuario en la empresa.

        Valores posibles:

        * `admin` — Administrador (acceso total)
        * `accountant` — Contador (acceso a nómina y contabilidad)
        * `reviewer` — Revisor (acceso de solo lectura)
        * `worker` — Persona (acceso a su propio perfil)
      enum:
        - admin
        - accountant
        - reviewer
        - worker
      example: admin
    WorkersNumberRange:
      type: string
      description: |
        Rango del número de personas activas en la empresa.

        Valores posibles:

        * `1-19` — Entre 1 y 19 personas
        * `20-49` — Entre 20 y 49 personas
        * `50-99` — Entre 50 y 99 personas
        * `100-149` — Entre 100 y 149 personas
        * `150-200` — Entre 150 y 200 personas
        * `over_200` — Más de 200 personas
      enum:
        - 1-19
        - 20-49
        - 50-99
        - 100-149
        - 150-200
        - over_200
      example: 1-19
    PayrollFrequency:
      type: string
      description: |
        Frecuencia de liquidación de nómina.

        Valores posibles:

        * `monthly` — Mensual
        * `fortnightly` — Quincenal
        * `mixed` — Mixta (algunos empleados mensual, otros quincenal)
      enum:
        - monthly
        - fortnightly
        - mixed
      example: monthly
    PaymentMethod:
      type: string
      description: |
        Método de pago de nómina.

        Valores posibles:

        * `wire_transfer` — Transferencia bancaria
        * `cash` — Efectivo
      enum:
        - wire_transfer
        - cash
      example: wire_transfer
    UserArea:
      type: string
      description: |
        Área funcional del usuario en la empresa:
        * `accounting` — Contabilidad.
        * `administrative` — Administrativa.
        * `general_management` — Gerencia general.
        * `hr` — Recursos humanos.
        * `other` — Otra área (especificar en `area_other_info`).
        * `student` — Estudiante en práctica.
      enum:
        - accounting
        - administrative
        - general_management
        - hr
        - other
        - student
      example: hr
    CompanyAccess:
      type: string
      description: |
        Nivel de acceso de la empresa según su suscripción activa:
        * `free` — Sin suscripción activa.
        * `premium` — Suscripción básica activa.
        * `premium_plus` — Suscripción extendida con funcionalidades adicionales.
        * `premium_full` — Suscripción con acceso completo a todos los módulos (incluye módulo de gestión humana).
      enum:
        - free
        - premium
        - premium_plus
        - premium_full
      example: premium_full
    UserInformation:
      type: object
      description: Información del usuario autenticado y su contexto de acceso dentro de la empresa.
      properties:
        active:
          type:
            - boolean
            - 'null'
          description: Indica si el acceso del usuario a la empresa está activo. Es `null` si no tiene empresa asociada.
          example: true
        area:
          oneOf:
            - $ref: '#/components/schemas/UserArea'
            - type: 'null'
          description: Área funcional del usuario en la empresa.
        company_access:
          oneOf:
            - $ref: '#/components/schemas/CompanyAccess'
            - type: 'null'
          description: Nivel de acceso de la empresa según su suscripción activa.
        company_created_at:
          type:
            - string
            - 'null'
          description: Fecha de creación de la empresa como cadena numérica con marca de tiempo Unix en segundos (UTC).
          example: '1456385484'
        company_id:
          type:
            - string
            - 'null'
          description: Identificador único (ID) asignado a la empresa en la base de datos.
          example: 3b7d03f0-e067-3d72-84f4-e410ac36ef57
        company_name:
          type:
            - string
            - 'null'
          description: Razón social o nombre comercial de la empresa.
          example: Empresa Demo S.A.S.
        email:
          type: string
          description: Correo electrónico del usuario.
          format: email
          example: usuario@ejemplo.com
        id:
          type: string
          description: Identificador único (ID) asignado al usuario en la base de datos.
          example: 3117a7ea-8471-40ed-ac8e-3db728f32c5a
        is_new_invited_admin_user:
          type: boolean
          description: Indica si el usuario fue creado después de la fecha de corte definida para "nuevo admin invitado".
          example: false
        multicompany:
          type: boolean
          description: Indica si el usuario no tiene una única empresa asociada en este contexto.
          example: false
        name:
          type: string
          description: Nombre corto mostrable del usuario.
          example: María
        picture:
          type:
            - string
            - 'null'
          description: URL de la imagen de perfil del usuario.
          example: null
        phone:
          type:
            - string
            - 'null'
          description: Teléfono celular del usuario.
          example: '3001234567'
        premium:
          type: boolean
          description: Indica si la empresa tiene plan premium o suscripción premium activa.
          example: true
        role:
          $ref: '#/components/schemas/UserAccessRole'
        worker_id:
          type:
            - string
            - 'null'
          description: Identificador único (ID) de la persona en la empresa, si existe vínculo.
          example: cc2690e7-7cca-4cf9-94bb-305d0433459a
        worker_with_benefits:
          type:
            - boolean
            - 'null'
          description: Indica si la empresa tiene módulo o personas con beneficios configurados.
          example: true
        workers_handle_novelties:
          type:
            - boolean
            - 'null'
          description: Indica si en la configuración de empresa las personas pueden autogestionar novedades.
          example: true
        workers_income_certificate_access:
          type:
            - boolean
            - 'null'
          description: Indica si aplica acceso a certificados de ingresos según configuración de empresa.
          example: true
        workers_labor_certificate_access:
          type:
            - boolean
            - 'null'
          description: Indica si aplica acceso a certificados laborales según configuración de empresa.
          example: true
        workers_payslips_access:
          type:
            - boolean
            - 'null'
          description: Indica si aplica acceso a colillas según configuración de empresa.
          example: true
        distributor:
          type:
            - string
            - 'null'
          description: Identificador del distribuidor asociado a la empresa.
          example: null
        sign_up:
          type: boolean
          description: Indica si es la primera vez que el usuario inicia sesión. Solo está presente cuando la empresa tiene un distribuidor asociado.
          example: false
    WorkerDocumentType:
      type: string
      description: |
        Tipo de documento de identificación de la persona.

        Valores posibles:

        * `cc` — Cédula de Ciudadanía
        * `ce` — Cédula de Extranjería
        * `ti` — Tarjeta de Identidad
        * `rc` — Registro Civil
        * `pa` — Pasaporte
        * `pe` — Permiso Especial de Permanencia (PEP)
        * `ce_no_pension` — Cédula de Extranjería sin obligación de pensión
        * `pe_no_pension` — Permiso Especial de Permanencia sin obligación de pensión
        * `pt` — Permiso por Protección Temporal (PPT)
        * `pt_no_pension` — Permiso por Protección Temporal sin obligación de pensión
      enum:
        - cc
        - ce
        - ti
        - rc
        - pa
        - pe
        - ce_no_pension
        - pe_no_pension
        - pt
        - pt_no_pension
      example: cc
    AccountType:
      type: string
      description: |
        Tipo de cuenta bancaria.

        Valores posibles:

        * `savings_account` — Cuenta de ahorros
        * `current_account` — Cuenta corriente
      enum:
        - savings_account
        - current_account
      example: savings_account
    ContractCategory:
      type: string
      description: |
        Categoría del contrato laboral.

        Valores posibles:

        * `employee` — Empleado
        * `contractor` — Contratista
        * `schooling_trainee` — Aprendiz SENA etapa lectiva
        * `productive_trainee` — Aprendiz SENA etapa productiva
        * `dual_trainee` — Aprendiz SENA formación dual
        * `intern` — Practicante universitario
        * `student_decree_055` — Estudiante pasantía (Decreto 055 de 2015)
        * `student_law_789` — Estudiante (Régimen especial Ley 789 de 2002)
        * `part_time_contract` — Contrato a tiempo parcial
      enum:
        - employee
        - contractor
        - schooling_trainee
        - productive_trainee
        - dual_trainee
        - intern
        - student_decree_055
        - student_law_789
        - part_time_contract
      example: employee
    SalaryCategory:
      type: string
      description: |
        Modalidad del salario.

        Valores posibles:

        * `monthly` — Salario mensual fijo
        * `per_hour` — Salario por hora
        * `integral_salary` — Salario integral
        * `part_time` — Tiempo parcial
      enum:
        - monthly
        - per_hour
        - integral_salary
        - part_time
      example: monthly
    ApplicationPeriod:
      type: string
      description: |
        Periodo de nómina en el que se aplica el descuento del préstamo.

        Valores posibles:

        * `all_periods` — Todos los periodos
        * `first_fortnightly` — Primera quincena
        * `second_fortnightly` — Segunda quincena
      enum:
        - all_periods
        - first_fortnightly
        - second_fortnightly
      example: all_periods
    NoveltyRequestStatus:
      type: string
      description: |
        Estado actual de la solicitud de novedad.

        Valores posibles:

        * `pending` — Pendiente de revisión por el administrador
        * `approved` — Aprobada por el administrador
        * `rejected` — Rechazada por el administrador
      enum:
        - pending
        - approved
        - rejected
      example: pending
    PayslipType:
      type: string
      description: |
        Tipo de colilla de pago.

        Valores posibles:

        * `payroll` — Nómina estándar (valor por defecto)
        * `termination` — Liquidación de contrato
        * `payroll_termination` — Nómina con liquidación de contrato
        * `social_benefit` — Prestación social (prima, cesantías o intereses)
        * `payroll_social_benefit` — Nómina con prestación social
        * `service_bonus` — Prima de servicios (alias de `social_benefit`)
        * `severance_interests` — Intereses de cesantías (alias de `social_benefit`)
        * `payroll_service_bonus` — Nómina con prima de servicios (alias de `payroll_social_benefit`)
        * `payroll_severance_interests` — Nómina con intereses de cesantías (alias de `payroll_social_benefit`)
      enum:
        - payroll
        - termination
        - payroll_termination
        - social_benefit
        - payroll_social_benefit
        - service_bonus
        - severance_interests
        - payroll_service_bonus
        - payroll_severance_interests
      example: payroll
    RecurrentConceptCategory:
      type: string
      description: |
        Categoría del concepto recurrente de nómina.

        Valores posibles:

        * `incomes` — Ingresos (salariales y no salariales)
        * `salary_income` — Ingresos salariales
        * `non_salary_income` — Ingresos no salariales
        * `deductions_and_loans` — Deducciones y préstamos
        * `deductions` — Deducciones
        * `loans` — Préstamos
      enum:
        - incomes
        - salary_income
        - non_salary_income
        - deductions_and_loans
        - deductions
        - loans
      example: salary_income
    AccountingCategory:
      type: string
      description: |
        Categoría contable de los conceptos de nómina.

        Valores posibles:

        * `incapacities_licenses` — Incapacidades y licencias
        * `salary_income` — Ingresos salariales
        * `non_salary_income` — Ingresos no salariales
        * `occasional_non_salary_income` — Ingresos no salariales ocasionales
        * `overtime` — Horas extras y recargos
        * `deductions` — Deducciones
        * `social_benefits` — Prestaciones sociales
        * `social_security` — Seguridad social
        * `retentions` — Retenciones
        * `termination` — Liquidación
        * `payment_method` — Método de pago
        * `legal` — Legales
        * `loan` — Préstamos
      enum:
        - incapacities_licenses
        - salary_income
        - non_salary_income
        - occasional_non_salary_income
        - overtime
        - deductions
        - social_benefits
        - social_security
        - retentions
        - termination
        - payment_method
        - legal
        - loan
      example: salary_income
    AccountingDocumentType:
      type: string
      description: |
        Tipo de documento contable para la integración con el proveedor.

        Valores posibles:

        * `payroll` — Nómina (provisión)
        * `social_benefits` — Prestaciones sociales (provisión)
        * `social_security` — Seguridad social (provisión)
        * `payroll_payment` — Nómina y prestaciones (comprobante de egreso)
        * `social_security_payment` — Seguridad social (comprobante de egreso)
      enum:
        - payroll
        - social_benefits
        - social_security
        - payroll_payment
        - social_security_payment
      example: payroll
    ContractTerm:
      type: string
      description: |
        Tipo de duración del contrato.

        Valores posibles:

        * `indefinite` — Contrato a término indefinido
        * `fixed` — Contrato a término fijo
        * `project` — Contrato por obra o labor
      enum:
        - indefinite
        - fixed
        - project
      example: indefinite
    ContributorSubtype:
      type: string
      description: |
        Subtipo de cotizante aplicado al contrato para la liquidación de seguridad social.

        Valores posibles:

        * `no_subtype` — Sin subtipo
        * `pensioner` — Pensionado
        * `age_exempt_contributor` — Cotizante exonerado por edad
        * `qualified_for_pension` — Habilitado para pensión
        * `compensated_contributor` — Cotizante compensado
      enum:
        - no_subtype
        - pensioner
        - age_exempt_contributor
        - qualified_for_pension
        - compensated_contributor
      example: no_subtype
    RiskType:
      type: string
      description: |
        Código del tipo de riesgo laboral ARL (Administradora de Riesgos Laborales).

        Valores posibles:

        * `risk_1` — Clase I: Riesgo mínimo (ej. oficinas, trabajo administrativo)
        * `risk_2` — Clase II: Riesgo bajo (ej. algunos procesos manufactureros)
        * `risk_3` — Clase III: Riesgo medio (ej. maquinaria industrial)
        * `risk_4` — Clase IV: Riesgo alto (ej. minería, construcción)
        * `risk_5` — Clase V: Riesgo máximo (ej. manejo de explosivos)
      enum:
        - risk_1
        - risk_2
        - risk_3
        - risk_4
        - risk_5
      example: risk_1
    ElectronicPayrollSocialBenefits:
      type: string
      description: |
        Modo de reporte de prestaciones sociales en la nómina electrónica ante la DIAN.

        Valores posibles:

        * `provision_per_month` — Las prestaciones sociales se incluyen mensualmente de acuerdo al concepto de devengo
        * `at_the_time_of_payment` — Las prestaciones sociales se incluyen al momento del pago
        * `payment_in_year` — Las cesantías e intereses se reportan en diciembre si no se han pagado durante el año; la prima al momento del pago
      enum:
        - provision_per_month
        - at_the_time_of_payment
        - payment_in_year
      example: at_the_time_of_payment
    ElectronicPayrollGovernmentStatus:
      type: string
      description: |
        Estado de habilitación de la empresa ante la DIAN para emitir nómina electrónica.

        Valores posibles:

        * `unauthorized` — No habilitada, sin envío previo a la DIAN
        * `authorized` — Habilitada y autorizada por la DIAN
        * `waiting_response` — Esperando respuesta de la DIAN
        * `pending_to_send` — Pendiente de envío a la DIAN
        * `rejected` — Rechazada por la DIAN
        * `failed` — Error en el proceso de habilitación
      enum:
        - unauthorized
        - authorized
        - waiting_response
        - pending_to_send
        - rejected
        - failed
      example: unauthorized
    ElectronicPayrollHolidays:
      type: string
      description: |
        Modo de reporte de vacaciones en la nómina electrónica ante la DIAN.

        Valores posibles:

        * `holidays_provision_per_month` — Las vacaciones se incluyen mensualmente de acuerdo al concepto de devengo
        * `holidays_at_the_time_of_payment` — Las vacaciones se incluyen al momento del pago
        * `holidays_payment_in_year` — Las vacaciones se reportan en diciembre si no se han pagado durante el año
      enum:
        - holidays_provision_per_month
        - holidays_at_the_time_of_payment
        - holidays_payment_in_year
      example: holidays_at_the_time_of_payment
    SubscriptionPaymentType:
      type: string
      description: |
        Frecuencia de pago de la suscripción a cobrar.

        Valores posibles:

        * `month` — Mensual
        * `year` — Anual
      enum:
        - month
        - year
      example: month
    EarlyPaymentType:
      type: string
      description: |
        Tipo de pago anticipado de vacaciones aplicado a la nómina.

        Valores posibles:

        * `no_early_payment` — Sin pago anticipado de vacaciones.
        * `early_payment_holidays_only` — Solo vacaciones anticipadas.
        * `early_payment_holidays_and_payroll` — Vacaciones y nómina anticipadas.
      enum:
        - no_early_payment
        - early_payment_holidays_only
        - early_payment_holidays_and_payroll
      example: no_early_payment
    PayrollBankPaymentType:
      type: string
      description: |
        Tipo de pago a incluir en el archivo bancario de una nómina individual.

        Valores posibles:

        * `payroll` — Solo nómina (valor por defecto)
        * `service_bonus` — Solo prima de servicios
        * `payroll_service_bonus` — Nómina más prima de servicios
        * `termination` — Solo liquidación de contrato
        * `payroll_termination` — Nómina más liquidación (solo liquidados)
        * `severance_interests` — Solo intereses de cesantías
        * `payroll_severance_interests` — Nómina más intereses de cesantías
        * `social_benefit` — Solo prestaciones sociales (cuando hay múltiples categorías)
        * `payroll_social_benefit` — Nómina más prestaciones sociales (cuando hay múltiples categorías)
      enum:
        - payroll
        - service_bonus
        - payroll_service_bonus
        - termination
        - payroll_termination
        - severance_interests
        - payroll_severance_interests
        - social_benefit
        - payroll_social_benefit
      example: payroll
    PayrollRange:
      type: string
      description: |
        Tramo de la nómina a incluir en la colilla. Solo aplica cuando la nómina fue liquidada con vacaciones anticipadas;
        en ese caso el periodo se divide en tramos según los conceptos de cada parte.

        Valores posibles:

        * `full_period` — Periodo completo
        * `0`, `1`, `2`... — Índice del tramo (los disponibles varían por nómina)

        Los valores exactos se obtienen del campo `payroll_range` del endpoint
        `GET /v1/{company_id}/payrolls/{payroll_id}/payslip_options`.
        Si no se envía, se usa `full_period` por defecto.
      example: full_period
    PeriodBankPaymentType:
      type: string
      description: |
        Tipo de pago a incluir en el archivo bancario de un periodo completo.

        Valores posibles:

        * `payroll` — Solo nómina (valor por defecto)
        * `service_bonus` — Solo prima de servicios
        * `payroll_service_bonus` — Nómina más prima de servicios
        * `termination` — Solo liquidaciones de contrato
        * `payroll_termination` — Nómina más liquidaciones (solo liquidados)
        * `payroll_termination_full` — Nómina completa (sin pago anticipado) más liquidaciones
        * `severance_interests` — Solo intereses de cesantías
        * `payroll_severance_interests` — Nómina más intereses de cesantías
        * `social_benefit` — Solo prestaciones sociales (cuando hay múltiples categorías)
        * `payroll_social_benefit` — Nómina más prestaciones sociales (cuando hay múltiples categorías)
      enum:
        - payroll
        - service_bonus
        - payroll_service_bonus
        - termination
        - payroll_termination
        - payroll_termination_full
        - severance_interests
        - payroll_severance_interests
        - social_benefit
        - payroll_social_benefit
      example: payroll
    FiltersModel:
      type: object
      description: Información sobre los filtros aplicados a la consulta
      properties:
        page:
          type: integer
          description: Número de página actual en la paginación
          example: 1
        per_page:
          type: integer
          description: Número de registros por página
          example: 50
        search:
          type: string
          description: Término de búsqueda aplicado. Cadena vacía si no se aplicó ningún filtro de búsqueda.
          example: ''
        total_records:
          type: integer
          description: Número total de registros que coinciden con los filtros
          example: 1
    CertificateFileFormat:
      type: string
      description: |
        Formato del archivo generado para el certificado.

        Valores posibles:

        * `pdf` — Genera el certificado en PDF
        * `xlsx` — Genera el certificado en Excel (valor por defecto si se omite)
      enum:
        - pdf
        - xlsx
      example: xlsx
  responses:
    '401':
      description: Credenciales inválidas
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BasicErrorModel'
          example:
            error:
              - code: '0001'
                index: 0
                message: Credenciales invalidas
                object: user
    '402':
      description: Funcionalidad de pago no disponible
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BasicErrorModel'
          example:
            error:
              - code: '0006'
                index: 0
                message: Esta es una funcionalidad premium. Si quieres usarla, comienza el periodo de prueba premium.
                object: company
    '403':
      description: No tienes permiso para esta acción
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BasicErrorModel'
          example:
            error:
              - code: '0001'
                index: 0
                message: No tienes permiso para esta acción
                object: user
    '404':
      description: El objeto no existe
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BasicErrorModel'
          example:
            error:
              - code: '0001'
                index: 0
                message: Objeto no existe
                object: object
    '422':
      description: No se pudo procesar la petición
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/BasicErrorModel'
          example:
            error:
              - code: '0102'
                index: 0
                message: Los datos enviados son inválidos.
                object: request
  parameters:
    pageParam:
      in: query
      name: page
      required: false
      description: Número de página para la paginación. Por defecto `1`.
      schema:
        type: integer
        minimum: 1
        example: 1
    perPageParam:
      in: query
      name: per_page
      required: false
      description: Cantidad de registros por página. Por defecto `20`, máximo `50`.
      schema:
        type: integer
        minimum: 1
        maximum: 50
        example: 20
    asyncParam:
      in: query
      name: async
      required: false
      description: 'Si es `true`, encola la generación del archivo y retorna inmediatamente con `message: Procesando`. El resultado se notifica vía Firebase cuando el archivo esté listo. Si es `false` o no se envía, genera el archivo de forma síncrona y retorna la URL directamente.'
      schema:
        type: boolean
        example: false
    contractCategoryPayrollConceptsParam:
      in: query
      name: contract_category
      schema:
        type: string
        enum:
          - employee
          - contractor
          - schooling_trainee
          - productive_trainee
          - intern
          - student_decree_055
          - student_law_789
          - part_time_contract
          - dual_trainee
        example: schooling_trainee
      description: |
        Categoría del contrato de la persona para filtrar conceptos de nómina válidos por tipo de contrato.

        * `employee` — Empleado
        * `contractor` — Contratista
        * `schooling_trainee` — Aprendiz SENA etapa lectiva
        * `productive_trainee` — Aprendiz SENA etapa productiva
        * `intern` — Estudiante universitario (aprendiz)
        * `student_decree_055` — Estudiante pasantía (decreto 055 de 2015)
        * `student_law_789` — Estudiante (régimen especial ley 789 de 2002)
        * `part_time_contract` — Contrato a tiempo parcial
        * `dual_trainee` — Aprendiz Sena Etapa Dual

        Los conceptos disponibles varían según el tipo de contrato y la aplicación de la reforma laboral (Ley 2466 de 2025).
    noveltyInitialDayParam:
      in: query
      required: false
      name: novelty_initial_day
      schema:
        type: string
        format: date
        example: '2025-07-01'
      description: |
        Fecha inicial de la novedad para aplicar reglas de reforma laboral (Ley 2466 de 2025).
        La reforma laboral (Ley 2466 de 2025) amplía los beneficios disponibles para contratos de aprendizaje según la fecha:
        - **Antes del 25 junio 2025**: Los aprendices tienen acceso limitado a conceptos básicos
        - **A partir del 25 junio 2025**: Los aprendices obtienen acceso a conceptos de nómina ampliados
        - **A partir del 1 julio 2025**: Los aprendices obtienen acceso completo a seguridad social

        Este parámetro es especialmente relevante cuando se usa junto con `contract_category` para determinar la disponibilidad de conceptos como vacaciones e incapacidades laborales en contratos de aprendizaje.
    withoutPayrollsParam:
      in: query
      name: without_payrolls
      schema:
        type: boolean
        example: false
      description: |
        Si se establece en true, la respuesta no incluirá la lista de nóminas asociadas al periodo. Esto es útil cuando solo se necesita la información básica del periodo sin cargar todas las nóminas.
    contractCategoryParam:
      in: query
      name: contract_category
      schema:
        type: string
        enum:
          - employee
          - contractor
          - apprentice
          - student
          - part_time_contract
          - all
        example: employee
      description: |
        Filtra las nóminas por categoría de contrato. Algunos valores agrupan múltiples categorías internas:

        * `employee` — Empleado
        * `contractor` — Contratista
        * `apprentice` — Aprendices SENA (lectiva, productiva, formación dual) y practicantes universitarios
        * `student` — Estudiantes (Decreto 055 de 2015 y Ley 789 de 2002)
        * `part_time_contract` — Contrato a tiempo parcial
        * `all` — Todos los tipos de contrato
    contractStatusParam:
      in: query
      name: contract_status
      schema:
        type: string
        enum:
          - active
          - terminated
          - all
        example: active
      description: |
        Estado de los contratos de la persona.

        * `active` — Nóminas de contratos activos.
        * `terminated` — Nóminas de contratos liquidados.
        * `all` — Nóminas de contratos activos y liquidados.
    locationParam:
      in: query
      name: location
      schema:
        type: string
        example: c5fc6f3d-fc8b-4953-ac5d-b725c204af5c
      description: ID de la ubicación de la persona
    noveltyFilterParam:
      in: query
      name: filter
      required: false
      description: |
        Filtra el historial por categoría de novedad. Si no se envía, usa `novelties`.

        Valores posibles:

        * `novelties` — Novedades generales (por defecto)
        * `overtime` — Horas extras y recargos
        * `non_salary_income` — Ingresos no salariales
        * `occasional_non_salary_income` — Ingresos no salariales ocasionales
        * `salary_income` — Ingresos salariales
        * `deductions` — Deducciones
        * `loan` — Préstamos
        * `contract_novelties` — Novedades de contrato
      schema:
        type: string
        enum:
          - novelties
          - overtime
          - non_salary_income
          - occasional_non_salary_income
          - salary_income
          - deductions
          - loan
          - contract_novelties
        example: novelties
x-tagGroups:
  - name: Autenticación
    tags:
      - Autenticación
      - Generar token de sesión
      - Tokens de acceso
  - name: Gestión de empresas
    tags:
      - Información de la empresa
      - Registro e onboarding
      - Configuración de empresa
      - Áreas
      - Cargos
      - Sedes
      - Centros de costos
      - Centros de trabajo
      - Cuentas bancarias
      - Credenciales de empresa
      - Documentos de la empresa
      - Dashboard y métricas
  - name: Gestión de personas
    tags:
      - Personas
      - Importación masiva
      - Documentos de personas
      - Onboarding de personas
      - Consulta de antecedentes
  - name: Perfil de la persona
    tags:
      - Información del perfil de la persona
      - Nómina de la persona
      - Colillas de la persona
      - Préstamos de la persona
      - Conceptos recurrentes de la persona
      - Solicitudes de novedad de la persona
      - Historial de pagos de la persona
      - Carpetas de la persona
      - Certificados de la persona
  - name: Contratos y relaciones laborales
    tags:
      - Contratos
      - Detalles del contrato
      - Historial de cargos
      - Salarios
      - Terminación de contratos
      - Firma electrónica
      - Distribución de centros de costos
  - name: Nómina y liquidación
    tags:
      - Periodos de nómina
      - Nóminas
      - Conceptos de nómina
      - Ítems de nómina
      - Horas extras y recargos
      - Novedades
      - Solicitudes de novedades
      - Vacaciones compensadas
      - Auxilio de conectividad
      - Conceptos recurrentes
      - Configuración de horas trabajadas
      - Configuración de retención en la fuente
      - Préstamos
  - name: Análisis e indicadores
    tags:
      - Análisis de horas extras y recargos
  - name: Nómina electrónica (DIAN)
    tags:
      - Configuración de nómina electrónica
      - Periodos de nómina electrónica
      - Emisión de nómina electrónica
      - Colillas electrónicas
      - Archivos XML y gobierno
      - Anulación de nómina electrónica
      - Resúmenes de nómina electrónica
      - Historial por persona NE
  - name: Prestaciones sociales
    tags:
      - Periodos de prestaciones
      - Prestaciones por periodo
      - Prestaciones por contrato
      - Archivos de prestaciones
  - name: Seguridad social
    tags:
      - Sucursales
      - Planilla PILA
      - Integración con operador
      - Decreto 376
  - name: Pagos y facturación
    tags:
      - Suscripción
      - Planes
      - Pagos
      - Facturación
  - name: Documentos y certificados
    tags:
      - Desprendibles de pago
      - Certificados laborales
      - Certificados de ingresos
      - Archivos de retefuente
  - name: Contabilidad e integraciones
    tags:
      - Configuración contable
      - Configuración para instituciones
      - Archivos y documentos contables
      - Integración con Alegra
      - Integraciones generales
  - name: Reportes y consultas
    tags:
      - Resúmenes de nómina
      - Archivos bancarios
      - Historial de novedades
      - Historial de vacaciones
      - Historial de pagos
      - Información exógena
      - Datasets de reportes
  - name: Gestión de usuarios y accesos
    tags:
      - Usuarios
      - Información de usuario
      - Sesión y seguridad
      - Invitaciones
  - name: Comunicaciones
    tags:
      - Notificaciones
      - Pulso Chat
  - name: Recursos de referencia
    tags:
      - Datos geográficos
      - Instituciones
      - Actividades económicas
      - Sectores económicos
