Módulo de Solicitudes

Solicitud de Adelanto( Solicitar de adelanto de sueldo (1) ) - [guardarAdelantosMensual]

🧾 Descripción

Registra la solicitud de adelanto salarial mensual para un empleado, validando una serie de reglas de negocio relacionadas con:

El servicio crea o actualiza el registro correspondiente al empleado dentro del documento mensual de adelantos.


🚀 Endpoint

POST /guardar-adelantos-mensual/{employee}/{amount}

Recibe:


🔐 Seguridad

Requiere autenticación del ERP (realizada internamente vía ServiceErp()).


🧠 Flujo del Servicio (lógica real)

1️⃣ Validación inicial del monto

2️⃣ Obtiene la ficha del empleado


GET Employee/{employee}

Se validan:

3️⃣ Validaciones por fecha

4️⃣ Validaciones por tipo de trabajo

5️⃣ Validación de asistencia

Se verifica si hoy está con licencia:

GET Attendance?filters=[ employee=..., status="On Leave", attendance_date=hoy, docstatus=1 ]

Si está con licencia → no puede solicitar adelanto.

6️⃣ Ubica o crea el documento mensual tipo "Solicitud de Adelanto Mensual"

Se busca:

GET Solicitud de Adelanto Mensual?filters=[ ["id","=",employee.id_sucursal], ["mes","=",mesTexto], ["anio","=",anio] ]

7️⃣ Registra o actualiza al trabajador dentro de la tabla interna table_12

8️⃣ Devuelve la respuesta con todos los registros procesados.


📥 Request Body

No recibe body (los parámetros son por URL).


📤 Response 200 – Ejemplo

{ "valor": true, "msn": "Solicitud de adelanto registrado correctamente.", "data": { "SAL-MENS-0001": { "id_empleado": "EMP-001", "monto": 150, "from_app": 1 } } }

❗ Posibles Errores

1. Monto inválido

{ "valor": false, "msn": "Seleccione un monto valido." }

2. Empresa no permitida

{ "valor": false, "msn": "Solo se pueden solicitar los trabajadores de la compañia Shalom Empresarial" }

3. Empleado deshabilitado

{ "valor": false, "msn": "Su empleado se encuentra deshabilitado" }

4. Fecha fuera de rango

{ "valor": false, "msn": "Solo se pueden realizar solicitudes desde el día 01 hasta el 14 del mismo mes." }

5. Restricción por área o tipo de empleado

{ "valor": false, "msn": "Los conductores no pueden solicitar adelanto salarial." }

6. Empleado con licencia

{ "valor": false, "msn": "Usted se encuentra de licencia, no puede solicitar adelanto salarial." }

7. Error al crear documento mensual

{ "valor": false, "msn": "Ocurrió un error al registrar su solicitud de adelanto" }

📚 Schemas utilizados

Employee (GET Employee/{id})

Campos relevantes:

{ "company": "string", "status": "string", "employment_type": "string", "department": "string", "designation": "string", "tipo_de_empleado": "string", "id_sucursal": "int", "passport_number": "string", "employee_name": "string", "branch": "string", "fecha_de_ingreso_real": "Y-m-d" }

Solicitud de Adelanto Mensual (GET/POST)

Campos usados:

{ "id": "int", "mes": "string", "anio": "int", "sucursal": "string", "departamento": "string (opcional)" }

Registro en tabla interna (table_12)

{ "id_empleado": "string", "dni": "string", "nombre_completo": "string", "fecha_de_ingreso": "Y-m-d", "monto": "int", "sucursal": "string", "from_app": 1 }

🧠 Lógica en pseudo-código

if amount == "Seleccionar": return error employeeData = GET Employee/{employee} validar empresa, estado, fecha, tipo, área, puesto... if falla alguna regla: return error validar licencia del día buscar documento mensual de adelantos if no existe: crear nuevo documento obtener tabla interna del documento si empleado no existe en table_12: crear registro else: actualizar monto return éxito + registros modificados

Solicitud de Adelanto(Estado solicitud (1,2,3,4) - Adelante de sueldo) - [show]

🧾 Descripción

Este servicio permite obtener el estado actual de distintos procesos vinculados a un trabajador, tales como:

El servicio analiza dinámicamente el tipo de proceso solicitado.
Si se envía un tipo de proceso específico, consulta su última solicitud pendiente.
Si no se envía proceso, valida automáticamente si el trabajador tiene adelanto salarial en el mes actual y devuelve su estado.

📌 Es un servicio que depende totalmente de la API del ERP para obtener la información.


🚀 Endpoint

POST /estado-solicitud


📥 Request Body

{ "empleado": "EMP-0001", "proceso": "licencia" }

Parámetros

Campo Tipo Obligatorio Descripción
empleado string ✔️ Código del empleado en ERP
proceso string opcional Tipo de solicitud a consultar (“cambio de cuenta”, “licencia”, “asignación familiar”). Si no se envía, se valida “adelanto salarial”.

🔐 Seguridad

Requiere autenticación interna y comunicación con el ERP vía dbErp() y ServiceErp().


🧠 Flujo del Servicio (resumen real)

🔸 1. Validación Inicial

Obtiene:

Define tablas ERP según el proceso solicitado.


🔸 2. Cuando se envía un proceso específico

Los procesos admitidos son:

Proceso enviado Tabla consultada Campo de relación
"cambio de cuenta" tabCambio de Cuenta Bancaria empleado
"licencia" tabSolicitud de Licencias id_empleado
"asignación familiar" tabSolicitud Asignacion Familiar id_empleado

El servicio:

  1. Construye los filtros del ERP.

  2. Busca la última solicitud activa (docstatus < 2).

  3. Si no encuentra registros → devuelve un mensaje indicando que no existe solicitud.

  4. Si existe:

    • Lee motivo

    • Lee validacion_solicitud

    • Lee docstatus

    • Devuelve estado traducido a texto.

Estados interpretados:

docstatus Estado
0 En proceso
1 Aprobado
2 Pagado
3 Rechazado

🔸 3. Cuando NO se envía proceso: Validación de adelanto salarial

  1. Obtiene el adelanto salarial del mes (tabSolicitud de Adelanto Mensual + tabla interna hija).

  2. Si no existe solicitud → devuelve mensaje correspondiente.

  3. Si existe, continúa:

    • Revisa si existe Solicitud de Pagos pagada relacionada al mes.

    • Si se encuentra, asigna estado "Pagado".

    • Si docstatus = 0 y el día es >= 17, se marca como "Rechazado".

    • Caso contrario usa el estado según docstatus.


📤 Response 200 – Ejemplo de solicitud por proceso

{ "valor": true, "msn": "Estado de la solicitud encontrado", "data": { "motivo": "Actualización de datos", "validacion_solicitud": "Pendiente", "fecha": "2025-01-22 12:30:00", "estado": "En proceso" } }


📤 Response 200 – Ejemplo para adelanto salarial

{ "valor": true, "msn": "Estado de la solicitud encontrado", "data": { "monto": 300, "fecha": "2025-01-18 15:04:22", "estado": "Pagado" } }


❗ Posibles Errores

1. Proceso enviado no existe

{ "valor": false, "msn": "Usted no cuenta con una solicitud" }

2. No existen solicitudes del tipo indicado

{ "valor": false, "msn": "Usted no cuenta con una solicitud de licencia" }

3. No existe adelanto salarial para el mes

{ "valor": false, "msn": "Usted no ha solicitado un adelanto salarial para este mes" }

4. Falla consultando al ERP

{ "valor": false, "msn": "Hubo un inconveniente al consultar los datos." }


📚 Schemas (Estructuras utilizadas)

Solicitud de Licencias

{ "name": "string", "modified": "datetime", "docstatus": 0, "motivo": "string", "validacion_solicitud": "string" }

Solicitud Adelanto Mensual

{ "mes": "string", "anio": "string", "docstatus": 0, "modified": "datetime", "monto": 0 }


🗃 Lógica en pseudo-código simplificada

if request.proceso exists: tabla, where = procesos_config[proceso] data = dbErp(tabla, where) if empty(data): return sin solicitud estado = traducir_docstatus(data.docstatus) return estado, motivo, fecha else: adelanto = dbErp(Solicitud Adelanto Mensual) if no adelanto: return "no ha solicitado" if solicitud_pagos_pagada AND adelanto.docstatus == 1: estado = Pagado else if docstatus==0 AND día >=17: estado = Rechazado else: estado = según tabla return monto, fecha, estado

Cambio de cuenta bancaria(Solicitar cambio de cuenta (1)) - [store]

🧾 Descripción

Registra una nueva solicitud de cambio de cuenta bancaria para un empleado, validando previamente:

Si todo es correcto, crea un nuevo documento en el ERP: Cambio de Cuenta Bancaria


🚀 Endpoint

POST /cambio-cuenta-bancaria/store


📥 Request Body

{ "empleado": "EMP-0001", "nuevo_banco": "Banco de Crédito del Perú", "nueva_cuenta_bancaria": "12345678901234", "documento_cuenta": "/files/archivo.pdf" }

Campos requeridos

Campo Tipo Obligatorio Descripción
empleado string ✔️ ID del empleado
nuevo_banco string ✔️ Nuevo banco elegido
nueva_cuenta_bancaria string ✔️ Número de cuenta del nuevo banco
documento_cuenta string ✔️ Archivo previamente cargado en ERP

🔐 Seguridad

Requiere autenticación interna mediante ServiceErp() y dbErp() hacia el ERP corporativo.


🧠 Flujo del Servicio (resumen real)

1. Validaciones iniciales

Banco Longitudes válidas
BCP 14 o 20
BBVA 16, 18 o 20
Interbank 18 o 20
Otros 20

Si no cumple → devuelve error.


2. Verifica si el empleado ya tiene una solicitud en estado Borrador

Se consulta en el ERP:

GET Cambio de Cuenta Bancaria filters = [["empleado","=", empleado],["docstatus","=",0]]

Si ya existe un documento en borrador → error.


3. Registrar la nueva solicitud

Si no existe borrador, crea el documento:

POST resource/Cambio de Cuenta Bancaria { "empleado": empleado, "nombre_de_banco_nuevo": nuevo_banco, "nuevo_num_de_cuenta_bancaria": nueva_cuenta_bancaria, "documento_cuenta": documento_cuenta }

📤 Response 200 – Éxitoso

{ "valor": true, "msn": "Registrado con éxito", "response": { "name": "CCB-000123", "empleado": "EMP-0001", "nombre_de_banco_nuevo": "Banco de Crédito del Perú", "nuevo_num_de_cuenta_bancaria": "12345678901234" } }

❗ Posibles Errores

1. Falta un dato obligatorio

{ "valor": false, "msn": "Debe adjuntar un documento de acreditación de cuenta bancaria" }

2. Número de cuenta inválido

{ "valor": false, "msn": "Cantidad de dígitos de número de cuenta incorrecto" }

3. Ya existe solicitud en borrador

{ "valor": false, "msn": "Ya cuenta con una solicitud en Borrador pendiente de validar" }

4. Error al registrar en ERP

{ "valor": false, "msn": "Ocurrió un error al registrar el cambio de cuenta bancaria", "error": { ... } }

📚 Schemas utilizados

Cambio de Cuenta Bancaria (POST)

{ "empleado": "string", "nombre_de_banco_nuevo": "string", "nuevo_num_de_cuenta_bancaria": "string", "documento_cuenta": "string" }

Consulta de solicitudes

{ "name": "string" }

🗃 Lógica en pseudo-código

if faltan_datos: return error validar_longitud_segun_banco() buscar_borrador = GET CambioCuentaBancaria where empleado and docstatus=0 if existe_borrador: return error "Ya cuenta con una solicitud" crear_documento = POST CambioCuentaBancaria { empleado, banco, cuenta, documento } return éxito

Solicitud de Licencias(Combo tipos de licencias (1)) - [combos]

🧾 Descripción

Servicio que devuelve los valores preconfigurados para el combo tipos_licencias, utilizado por el frontend o aplicación móvil para poblar listas desplegables relacionadas a licencias.

Este servicio no realiza operaciones en base de datos, no consume ERP ni APIs externas.
Simplemente retorna valores estáticos cargados en la propiedad $this->tipos_licencias.


🚀 Endpoint

POST /combos

No requiere parámetros.


🔐 Seguridad

No requiere validación adicional.
El servicio solo retorna data estática, sin acceso a información sensible del ERP.


🧠 Flujo del Servicio (resumen real)

  1. Obtiene el array interno $this->tipos_licencias, previamente definido en el controlador.

  2. Construye un arreglo combos con la estructura:

$combos["tipos_licencias"] = $this->tipos_licencias;
  1. Retorna una respuesta JSON estándar:

{ "valor": true, "data": { "tipos_licencias": [...] } }

📥 Request Body

No requiere parámetros.
Ejemplo:


{}

📤 Response 200 – Ejemplo

{ "valor": true, "data": { "tipos_licencias": [ "LICENCIA A1", "LICENCIA A2A", "LICENCIA A2B", "LICENCIA A3A", "LICENCIA A3B", "LICENCIA A3C" ] } }

(La estructura real depende del contenido de $this->tipos_licencias.)


❗ Posibles Errores

Este servicio no genera errores internos, pues no consulta APIs externas.
Solo pueden ocurrir fallas del servidor:

1. Error por variable no definida

{ "valor": false, "msn": "Error interno: tipos_licencias no declarado", "data": [] }

2. Error inesperado del servidor

{ "valor": false, "msn": "Error del servidor: <mensaje>", "data": [] }

📚 Schemas (estructuras usadas)

Response

{ "valor": true|false, "data": { "tipos_licencias": "array" } }

🗃 Lógica en pseudo-código

function combos(request): combos = {} combos["tipos_licencias"] = this.tipos_licencias return { valor: true, data: combos }

Solicitud de Licencias(Solicitar solicitud de licencia (1)) - [store]

🧾 Descripción

Crea una Solicitud de Licencias para un empleado, validando previamente:

El servicio registra en el ERP un nuevo documento "Solicitud de Licencias" si cumple todas las reglas definidas.


🚀 Endpoint

POST /solicitud-licencias/store


📥 Request Body – Parámetros

Campo Tipo Obligatorio Descripción
empleado string ID del empleado
tip_licencia string Tipo de licencia (validado contra $this->tipos_licencias)
fecha_ini date Fecha de inicio de la licencia
fecha_fin date Fecha fin de la licencia
declaracion_jurada file/url depende Obligatorio si tip_licencia = "Familiar Enfermo"
hoja_hospitalizacion file/url depende Obligatorio si tip_licencia = "Familiar Enfermo"
uci file/url depende Obligatorio si tip_licencia = "Familiar Enfermo"
acta_nacimiento file/url depende Obligatorio si tip_licencia = "Paternidad"
acta_defuncion file/url depende Obligatorio si tip_licencia = "Licencia Por Luto"

🧠 Flujo del Servicio (resumen real)

  1. Validación de campos obligatorios

    • Verifica empleado, tipo de licencia válido, fecha_ini y fecha_fin.

  2. Cálculo de días de licencia


    $dias = (new DateTime(fecha_ini))->diff(new DateTime(fecha_fin))->days;
  3. Validaciones específicas por tipo de licencia

    Tipo de licencia Requisitos Máximo días
    Familiar Enfermo declaracion_jurada, hoja_hospitalizacion, uci 7
    Paternidad acta_nacimiento 10
    Licencia Por Luto acta_defuncion 5
    Licencia sin goce 30
  4. Validación: El empleado no debe tener una solicitud en borrador

    GET Solicitud de Licencias filters: [["id_empleado","=",empleado],["docstatus","=",0]]
  5. Construcción del body para enviar al ERP

    • Incluye campos adicionales dependiendo del tipo de licencia.

  6. Creación de la solicitud

    POST resource/Solicitud de Licencias
  7. Retorno de respuesta estándar


📤 Response 200 – Ejemplo exitoso

{ "valor": true, "msn": "Solicitud de licencias enviada", "data": [] }

(El campo data retorna el borrador encontrado, si existía.)


⚠️ Posibles Errores

1. Falta de parámetros

{ "valor": false, "msn": "Envie el empleado" }

2. Tipo de licencia inválido

{ "valor": false, "msn": "Envie el tipo de licencia válido" }

3. Fechas incompletas

{ "valor": false, "msn": "Envie la fecha de inicio" }

4. Exceso de días permitidos

{ "valor": false, "msn": "El rango de fecha no debe sobrepasar los 7 dias" }

5. Documentación obligatoria faltante

{ "valor": false, "msn": "Suba su hoja de hospitalizacion" }

6. Solicitud duplicada en borrador

{ "valor": true, "msn": "No se puede crear, Ya tiene una solicitud en borrador" }

7. Error al registrar en ERP

{ "valor": false, "msn": "Ocurrió un error al crear la Solicitud de Licencias", "error": { ... } }

🗃 Lógica en Pseudocódigo

if empleado vacío → error if tipo no permitido → error if fechas vacías → error dias = fecha_fin - fecha_ini switch tipo_licencia: Familiar Enfermo: validar documentos validar dias <= 7 Paternidad: validar acta_nacimiento validar dias <= 10 Luto: validar acta_defuncion validar dias <= 5 Licencia sin goce: validar dias <= 30 buscar borradores: GET Solicitud de Licencias where empleado & docstatus=0 si existe → error body = { empleado, tipo, fechas, documentos } crear solicitud: POST Solicitud de Licencias si ERP responde error → retornar error retornar éxito


📚 Estructuras usadas

Solicitud de Licencias (POST)

Campos enviados:

{ "id_empleado": "string", "tip_licencia": "string", "fecha_ini": "YYYY-mm-dd", "fecha_fin": "YYYY-mm-dd", "declaracion_jurada": "url (opcional)", "hoja_hospitalizacion": "url (opcional)", "uci": "url (optional)", "acta_nacimiento": "url (optional)", "acta_defuncion": "url (optional)" }

Asignación Familiar(Buscar dni empleado (1)) - [searchJobApplicant]

🧾 Descripción

Este servicio consulta información de un postulante (Job Applicant) enviando su número de documento a un endpoint externo.
El servicio actúa como un proxy directo: recibe un documento, llama por cURL al endpoint de EMPRESARIAL y retorna la respuesta tal cual viene de la API.

No realiza validaciones ni transformaciones adicionales.


🚀 Endpoint interno

POST /search-job-applicant


📥 Parámetros de entrada (Request Body)

{ "document": "string" }

Campo | Tipo | Obligatorio | Descripción

---|---|---|---
document | string | Sí | Número de documento del postulante a buscar.


🔐 Seguridad

No usa autenticación interna ni tokens propios.
El servicio simplemente reenvía el dato al endpoint: POST {EMPRESARIAL}/api/search_job_applicant


🧠 Flujo del Servicio (Resumen Real)

  1. Recibe el campo document desde la solicitud.

  2. Prepara una petición cURL hacia:


    {EMPRESARIAL}/api/search_job_applicant
  3. Envía el documento como parámetro form-data:


    document = <valor recibido>
  4. Ejecuta la llamada.

  5. Decodifica la respuesta JSON.

  6. Retorna la data al cliente sin modificaciones.


📤 Respuesta 200 – Ejemplo

Respuesta depende totalmente del servicio externo.
Un ejemplo típico puede ser:

{ "valor": true, "data": { "name": "JOB-00045", "first_name": "Carlos", "last_name": "Rojas", "status": "Open", "document": "74581236" } }

❗ Posibles Errores

1. No se puede conectar con EMPRESARIAL

{ "valor": false, "msn": "No se pudo conectar con el servicio externo", "data": [] }

2. EMPRESARIAL devuelve error interno

{ "valor": false, "msn": "Error desde API Empresarial", "data": { ...detalle del error... } }

3. Respuesta no válida o JSON corrupto

{ "valor": false, "msn": "Respuesta inesperada del servidor externo", "data": "<response>" }

📚 Esquema esperado desde el API externo (referencial)

El API no está documentado en tu código, pero normalmente una estructura de Job Applicant incluye:

{ "name": "string", "first_name": "string", "last_name": "string", "status": "string", "document": "string" }

La estructura real depende 100% del sistema EMPRESARIAL.


🗃 Lógica en pseudo-código

document = request.document curl = init() curl.url = EMPRESARIAL + "api/search_job_applicant" curl.method = POST curl.postfields = { document: document } response = curl.execute() return json_decode(response)


🧩 Código documentado

/** * Servicio: searchJobApplicant * * Descripción: * Busca información de un postulante enviando su documento al API externo EMPRESARIAL. * Este servicio actúa como un puente: manda el documento vía cURL y retorna la respuesta * sin transformaciones adicionales. * * Endpoint interno: * POST /search-job-applicant * * Parámetros: * - document (string): Documento de identidad del postulante. * * Flujo: * 1. Recibe el documento del request. * 2. Ejecuta cURL hacia EMPRESARIAL/api/search_job_applicant enviando el documento. * 3. Obtiene y decodifica la respuesta JSON. * 4. Retorna directamente la respuesta del servicio externo. * * Posibles errores: * - Fallo en la conexión cURL * - Respuesta inválida del servidor externo */ public function searchJobApplicant(Request $request) { $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => EMPRESARIAL.'api/search_job_applicant', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => array('document' => $request->document), )); $response = curl_exec($curl); curl_close($curl); return json_decode($response,true); }

Asignación Familiar(Solicitar asignacion familiar (1)) - [store]

🧾 Descripción

Este servicio registra una Solicitud de Asignación Familiar para un empleado, validando previamente que:

  1. Se hayan enviado las dos imágenes del DNI (anverso y reverso).

  2. El empleado tenga un género válido y registrado.

  3. No exista ya una asignación familiar duplicada para el mismo hijo (DNI del menor).

  4. No existan más de dos solicitudes asociadas al mismo DNI de hijo (límite máximo permitido).

El registro se almacena directamente en el ERP mediante el recurso Solicitud Asignacion Familiar.


🚀 Endpoint

POST /solicitud-asignacion-familiar


📥 Request Body

{ "dni": "string", "fecha_hijo": "YYYY-MM-DD", "edad": 10, "empleado": "EMP-0001", "img_dni": "ruta/archivo1.png", "reverso": "ruta/archivo2.png", "nombre": "Nombre del hijo", "afiliacion_al_essalud": "SI" }

🔐 Seguridad

✔ Requiere autenticación interna vía ServiceErp() del ERP.
✔ Se validan datos del empleado antes de crear la solicitud.


🧠 Flujo del Servicio (Resumen)

  1. Validación de archivos obligatorios
    Verifica que se envíen img_dni y reverso.
    Si falta uno → retorna error.

  2. Obtiene datos del empleado
    Usa el método verifyEmployeeGender($empleado) para traer:

    • género

    • fecha de ingreso real

  3. Revisa si ya existe una solicitud similar
    Busca solicitudes para:

    • el mismo DNI del hijo

    • la misma fecha de ingreso del empleado


    GET Solicitud Asignacion Familiar filters: dni_hijo, fecha_ingreso
  4. Valida duplicidades según reglas

    • Si existe 1 solicitud previa, compara géneros:

      • Si el género coincide → ❌ ya tiene asignación familiar.

    • Si existen 2 solicitudes previas → ❌ no puede registrar más.

  5. Crea la nueva solicitud
    Realiza un POST hacia: POST /resource/Solicitud Asignacion Familiar

    Con los campos:

    { "id_empleado": "...", "nombre_hijo": "...", "dni_hijo": "...", "edad_hijo": "...", "fecha_hijo": "...", "dni_doc": "...", "reverso": "...", "afiliacion_al_essalud": "..." }
  6. Retorna respuesta final


📤 Response 200 – Ejemplos

✔ Registro exitoso

{ "valor": true, "msn": "Asignacion familiar registrada con exito" }

❌ Faltan imágenes del DNI

{ "valor": false, "msn": "Debe de enviar la 2 imagenes del DNI" }

❌ Asignación ya existente para el DNI del menor

{ "valor": false, "msn": "Este dni ya cuenta con una asignacion familiar" }

❌ DNI ya usado en dos asignaciones previas

{ "valor": false, "msn": "Este dni ya cuenta con dos asignaciones familiares" }

❌ Error al registrar en el ERP

{ "valor": false, "msn": "Ocurrió un error al registrar la solicitud de asignacion familiar" }

📚 Schemas utilizados

🔹 Solicitud Asignacion Familiar (POST)

{ "id_empleado": "string", "nombre_hijo": "string", "dni_hijo": "string", "edad_hijo": number, "fecha_hijo": "YYYY-MM-DD", "dni_doc": "string", "reverso": "string", "afiliacion_al_essalud": "SI/NO" }

🔹 Solicitud Asignacion Familiar (GET/FILTER)

{ "name": "string", "id_empleado": "string", "dni_hijo": "string", "fecha_ingreso": "YYYY-MM-DD" }

🔹 Datos del empleado (verifyEmployeeGender)

{ "gender": "M/F", "fecha_de_ingreso_real": "YYYY-MM-DD" }

🗃 Lógica en pseudocódigo

if falta img_dni o reverso: return error genderEmployee = verifyEmployeeGender(empleado) solicitudesPrevias = Buscar solicitudes por dni_hijo y fecha_ingreso if count == 1: otherGender = verifyEmployeeGender(solicitudesPrevias.id_empleado) if same gender: return error: ya tiene asignación if count >= 2: return error: límite alcanzado body = datos de asignación familiar guardar = POST Solicitud Asignacion Familiar if error: return error return éxito

Solicitudes de Pagos(Obtener Lista de Solicitudes (1)) - [paymentRequestList]

🧾 Descripción

Este servicio obtiene la lista de solicitudes de pago realizadas en el ERP, aplicando restricciones dependientes del usuario, su departamento y reglas de validación definidas por el área de Gerencia.

El módulo:

Si el usuario no está autorizado, el módulo devuelve un mensaje de bloqueo.


🚀 Endpoint

POST /payment-request-list


📥 Request Body

Ejemplo:

{ "department": "LOGISTICA", "concepto": "Compras abastecimiento interno", "usuario": "usuario@empresa.com", "status": "Validado" }

Campos:

Campo Tipo Descripción
department string Departamento del usuario
concepto string Concepto filtrado (opcional)
usuario string User ID
status string Estado de validación (opcional). Si es vacío, se excluyen "No requiere" y "Rechazado".

🔐 Seguridad

Requiere conexión válida con el ERP vía dbErp() y ServiceErp().


🧠 Flujo del Servicio (resumen funcional)

1️⃣ Validación de permisos del usuario

Se consulta: tabValidacion de Pagos Gerencia

Si no existe configuración para ese usuario:

{ "valor": false, "msn": "El modulo esta inhabilitado para su departamento", "data": [] }

2️⃣ Construcción de filtros principales

Si existen reglas personalizadas:

3️⃣ Filtrado por estado

4️⃣ Filtrado por concepto

Si el body incluye un concepto → se agrega un WHERE concepto = X.

5️⃣ Consulta principal

Se obtiene:

name, fecha, estado_de_validación, moneda, departamento, proveedor, ruc, concepto, monto, number_factura, voucher

Desde: tabSolicitud de Pagos

6️⃣ Obtención de archivos transados

Por cada solicitud encontrada se consultan los archivos: tabArchivos Transados

Clasifica:

Y asigna nombres:

Imagen 1 Documento 1 Archivo 1

7️⃣ Construcción de la respuesta final

Cada solicitud incluye:

{ "archivos_transados": [...], "documento_factura": "url o vacío", ... }

📤 Response 200 – Ejemplo exitoso

{ "valor": true, "msn": "Lista de Solicitudes generada correctamente", "data": [ { "name": "SP-0001", "fecha": "2025-01-10", "estado": "Validado", "moneda": "PEN", "departamento": "LOGISTICA", "proveedor": "Proveedor SAC", "ruc": "20123456789", "concepto": "Transacción / Compensaciones", "monto": 1500, "numero": "F001-12345", "documento_factura": "/files/factura.pdf", "archivos_transados": [ { "name": "ARCH-001", "parent": "SP-0001", "url": "/file-download/123.jpg", "nombre_archivo": "Imagen 1" } ] } ] }

❌ Posibles Errores

1️⃣ Usuario sin permisos para usar el módulo

{ "valor": false, "msn": "El modulo esta inhabilitado para su departamento", "data": [] }

2️⃣ Error al cargar solicitudes

{ "valor": false, "msn": "Surgió un error al cargar la lista de solicitudes, intente nuevamente", "data": { ... } }

3️⃣ No existen solicitudes dentro de los filtros

{ "valor": true, "msn": "No existen solicitudes", "data": [] }

📚 Tablas / Recursos Usados

tabValidacion de Pagos Gerencia

Campos usados:

tabSolicitud de Pagos

Campos:

tabArchivos Transados

Campos:


🗃 Lógica en pseudo-código

usuario_rules = GET ValidacionPagos where usuario = X if empty(usuario_rules): return módulo inhabilitado build base filters: estado_documento NOT IN ('Pago Rechazado') fecha >= hoy - 6 meses if usuario_rules exist: for each rule: add OR (concepto = rule.concepto AND monto > rule.monto) if status enviado: add estado_de_validación = X else: exclude ['No requiere', 'Rechazado'] if concepto enviado: add concepto = X requests = query SolicitudPagos with filters if no requests: return lista vacía get archivos_transados for all requests group and classify archivos by type return lista final con archivos agrupados

Solicitudes de Pagos(Obtener Combos Conceptos (1)) - [getComboSolicitudPago]

🧾 Descripción

Obtiene la lista de conceptos permitidos para un usuario específico, basándose en la tabla del ERP "Validación de Pagos Gerencia".

El servicio filtra los registros por el usuario ingresado y retorna un array único de conceptos asociados a dicho usuario.
Se utiliza para validar qué tipos de pagos puede solicitar un trabajador.


🚀 Endpoint

POST /get-combo-solicitud-pago


📥 Request Body

Debe incluir el campo:

{ "usuario": "correo_o_user_id" }

❗ Validación

Si no se envía usuario, responde:

{ "valor": true, "msn": "Debe de ingresar el usuario correctamente", "data": [] }


🔐 Seguridad

El servicio usa el método interno dbErp() que requiere autenticación interna vía ERPNext.
Por ello, se asume que el cliente ya cuenta con token/credenciales válidas.


🧠 Flujo del Servicio (Explicación Real)

  1. Validar parámetro usuario

    • Si está vacío → responde error de validación.

  2. Construir filtros para ERP


    WHERE usuario = <usuario>
  3. Consultar al ERP
    Usando:


    tabValidacion de Pagos Gerencia

    con el SQL:

    • SELECT concepto

    • FROM tabValidacion de Pagos Gerencia

    • WHERE usuario = %(usuario)s

  4. Obtener resultados

    • Se extrae la columna concepto de la respuesta.

    • Se eliminan duplicados mediante array_unique.

  5. Retornar los conceptos permitidos.


📤 Response 200 – Ejemplo

{ "valor": true, "msn": "Se encontró los conceptos", "data": [ "Bonificación", "Viáticos", "Movilidad", "Pago Extraordinario" ] }


❗ Posibles Errores

1. Usuario no enviado

{ "valor": true, "msn": "Debe de ingresar el usuario correctamente", "data": [] }

2. Usuario sin conceptos asignados

{ "valor": true, "msn": "Se encontró los conceptos", "data": [] }

(El servicio no devuelve error — solo retorna lista vacía.)

3. Error del ERP

Si dbErp() falla internamente, el servicio responderá una lista vacía debido a su estructura actual.


📚 Tablas y Estructuras Usadas

Tabla: tabValidacion de Pagos Gerencia

Campos utilizados:

{ "usuario": "string", "concepto": "string" }


🗃 Lógica en Pseudocódigo

IF usuario está vacío: return error filtros = { usuario: usuario } data = ERP.dbErp( table = "Validacion de Pagos Gerencia", select = "concepto", where usuario = usuario ) conceptos = extraer columna "concepto" conceptos = eliminar duplicados return { valor: true, data: conceptos }

Solicitudes de Pagos(Validar Solicitud (1)) - [validatePaymentRequest]

🧾 Descripción

Servicio encargado de validar o rechazar una Solicitud de Pagos en el ERP.
Actualiza el campo estado_de_validación del documento Solicitud de Pagos y devuelve una respuesta indicando si la operación fue exitosa.

El servicio no procesa lógica adicional más allá de actualizar el estado del documento y devolver el resultado.


🚀 Endpoint

PUT /validate-payment-request

📩 Recibe parámetros mediante el body del Request (Laravel Request):

{ "name": "SP-00012", "status": "Validado" }

🔐 Seguridad

Requiere autenticación contra el ERP, manejada internamente mediante: $this->general->ServiceErp()

No requiere headers adicionales desde el lado del cliente.


🧠 Flujo del Servicio (explicación real)

  1. Recibe:

    • name → ID del documento (Solicitud de Pagos)

    • status → Puede ser "Validado" o "Rechazado"

  2. Determina internamente mensajes para usuario según status:

    • "Validado" → aprobar

    • "Rechazado" → rechazar

  3. Construye el body con el nuevo estado:


    ["estado_de_validación" => $request->status]
  4. Envía:


    PUT /resource/Solicitud de Pagos/{name}
  5. Si el ERP responde con error → devuelve mensaje indicando fallo al aprobar o rechazar.

  6. Si la operación es correcta → responde con:

    • valor = true

    • mensaje: "Solicitud de Pago Aprobado/Rechazado correctamente"

    • data → respuesta del ERP


📥 Request Body (Laravel)

{ "name": "string (ID del documento)", "status": "Validado | Rechazado" }

📤 Response 200 – Ejemplo (Aprobado)

{ "valor": true, "msn": "Solicitud de Pago Aprobado correctamente", "data": { "name": "SP-00012", "estado_de_validación": "Validado" } }

Ejemplo (Rechazado)

{ "valor": true, "msn": "Solicitud de Pago Rechazado correctamente", "data": { "name": "SP-00012", "estado_de_validación": "Rechazado" } }

❗ Posibles Errores

1. Error durante el PUT

{ "valor": false, "msn": "Surgió un error al aprobar la Solicitud de Pago", "data": {} }

2. El ERP responde con "valor = false"

{ "valor": false, "msn": "Surgió un error al rechazar la Solicitud de Pago", "data": { ...respuesta del ERP... } }

3. Excepción inesperada

{ "valor": false, "msn": "Surgió un error al aprobar la Solicitud de Pago", "data": "ErrorException detail" }

📚 Schema del documento afectado

Solicitud de Pagos (PUT)

Campos utilizados: { "estado_de_validación": "string" }


🗃 Lógica en pseudo-código

name = request.name status = request.status body = { estado_de_validación: status } try: response = PUT "Solicitud de Pagos/{name}" with body except: return error message if response.valor == false: return error message return success response with custom message

Cambio Salarial Administrativo(Empleados Activos (1)) - [getEmployeeActive]

🧾 Descripción

Servicio que obtiene el listado completo de empleados activos desde el ERP.
Solo devuelve empleados cuyo status = "active" y expone información básica:

Este servicio se utiliza para obtener la lista de empleados habilitados dentro del sistema.


🚀 Endpoint

POST /get-employee-active

📌 El método es POST, pero internamente realiza una consulta GET al ERP.


📥 Request Body

El servicio no requiere parámetros en el body.


{}

Todo se obtiene directamente del ERP mediante ServiceErp().


🔐 Seguridad

Requiere conexión autorizada al ERP.
La autenticación se maneja internamente mediante: $this->general->ServiceErp(...)


🧠 Flujo del Servicio (Resumen Real)

  1. Construye la solicitud hacia el ERP:

GET Employee ?limit=None &fields=["nombre_completo","passport_number","name"] &filters=[["status","=","active"]]
  1. Envía la solicitud al ERP mediante: 

$this->general->ServiceErp('GET', null, $body, APICAPACITACION . 'resource/Employee');


  1. Verifica:

    • Si el ERP respondió con error.

    • Si no existen registros de empleados activos.

  2. En caso de éxito:

    • Devuelve la lista completa de empleados encontrados.


📤 Response 200 – Ejemplo

✅ Caso exitoso

{ "valor": true, "msn": "Busqueda Existosa", "data": [ { "nombre_completo": "Juan Pérez López", "passport_number": "45382910", "name": "HR-EMP-00231" }, { "nombre_completo": "Ana Torres", "passport_number": "72839201", "name": "HR-EMP-00412" } ] }

❗ Error interno del ERP

{ "valor": false, "msn": "Error interno, cominique con soporte", "data": [] }

❗ Sin registros encontrados

{ "valor": false, "msn": "No se encontraron Registros", "data": [] }

❗ Posibles Errores

1. Error en la llamada al ERP

Ocurre cuando ServiceErp() devuelve valor = false.

{ "valor": false, "msn": "Error interno, cominique con soporte", "data": [] }

2. No existen empleados activos

{ "valor": false, "msn": "No se encontraron Registros", "data": [] }

3. Error inesperado del servidor

(si se implementara un try/catch)

{ "valor": false, "msn": "Error del servidor: <detalle>", "data": [] }

📚 Schemas utilizados

Employee (GET)

Campos usados:

{ "name": "string", "nombre_completo": "string", "passport_number": "string" }


🗃 Lógica en Pseudo-Código

body = { limit = none fields = ["nombre_completo","passport_number","name"] filters = [["status","=","active"]] } response = GET ERP Employee with body if response.valor == false: return error if response.data.count == 0: return "No se encontraron registros" return { valor: true, msn: "Busqueda Existosa", data: response.data }

Cambio Salarial Administrativo(Obtener Salario (1)) - [getEmployeeActive]

🧾 Descripción

Este servicio obtiene todos los empleados activos desde el ERP, retornando únicamente la información básica necesaria para listarlos:

Es un servicio de consulta que solo consume los datos de la API del ERP usando ServiceErp().


🚀 Endpoint

GET /get-employee-active

No recibe parámetros en el body; todo se obtiene del ERP.


🔐 Seguridad

Requiere autenticación válida hacia el ERP (manejada internamente por ServiceErp()).


🧠 Flujo del Servicio (Resumen Real)

  1. Construye el body de consulta para el ERP:

    { "limit": "none", "fields": ["nombre_completo", "passport_number", "name"], "filters": [["status", "=", "active"]] }
  2. Realiza el request: GET Employee

  3. Valida:

    • Si hubo error en el ERP → retorna error.

    • Si la respuesta está vacía → retorna mensaje "No se encontraron registros".

  4. Si hay resultados, retorna:

    • valor = true

    • msn = "Busqueda Exitosa"

    • data = lista de empleados activos


📥 Request Body

Este endpoint no recibe body.


{}

📤 Response 200 – Ejemplo

✔️ Con empleados encontrados

{ "valor": true, "msn": "Busqueda Existosa", "data": [ { "nombre_completo": "Juan Pérez", "passport_number": "12345678", "name": "EMP-0001" }, { "nombre_completo": "Ana Torres", "passport_number": "87654321", "name": "EMP-0002" } ] }

❗ Sin registros

{ "valor": false, "msn": "No se encontraron Registros", "data": [] }

❌ Error interno

{ "valor": false, "msn": "Error interno, cominique con soporte", "data": [] }

❗ Posibles Errores

1️⃣ Error del ERP

Ocurre cuando ServiceErp() retorna "valor" => false

{ "valor": false, "msn": "Error interno, cominique con soporte", "data": [] }

2️⃣ No hay registros activos

{ "valor": false, "msn": "No se encontraron Registros", "data": [] }

3️⃣ Error inesperado en servidor

{ "valor": false, "msn": "Error del servidor", "data": [] }

📚 Schemas Usados

📄 Employee (GET)

Campos utilizados:

{ "name": "string", "nombre_completo": "string", "passport_number": "string" }

🗃 Lógica en Pseudo-código

body = { limit: none fields: ["nombre_completo", "passport_number", "name"] filters: [["status","=","active"]] } response = GET ERP Employee if response.valor == false: return error if response.data is empty: return no registros return { valor: true msn: "Busqueda Exitosa" data: response.data }

Cambio Salarial Administrativo(Actualizar Salario (1)) - [updateSalarialbyEmployee]

🧾 Descripción

Este servicio registra una solicitud de actualización salarial para un empleado.
Envía al ERP los nuevos valores de:

El servicio solo valida la estructura y los datos requeridos, mientras que el proceso interno de aprobación o registro es manejado por el ERP a través del recurso Cambio Salarial Administrativo.


🚀 Endpoint

POST /update-salarial-by-employee


📥 Request Body (JSON)

Todos los campos son obligatorios.

Campo Tipo Descripción
empleado string ID del empleado
sueldo number Nuevo sueldo propuesto
movilidad number Nuevo monto de movilidad
bono_nocturno number Monto de bono nocturno
fecha string (YYYY-MM-DD) Fecha de aplicación del cambio salarial

Ejemplo de entrada

{ "empleado": "EMP-00123", "sueldo": "1500", "movilidad": "200", "bono_nocturno": "150", "fecha": "2025-01-15" }

🔐 Seguridad

Requiere token válido del ERP (interno), administrado desde:

$this->general->ServiceErp()

🧠 Flujo del Servicio (resumen real)

  1. Valida que se hayan enviado todos los campos requeridos.
    Si falta alguno, retorna error.

  2. Valida formato de fecha usando validateDate().

  3. Construye el body que será enviado al ERP:

{ "empleado": "<id>", "nuevo_sueldo": "<sueldo>", "nueva_movilidad": "<movilidad>", "nuevo_bono_nocturno": "<bono nocturno>", "fecha_de_actualizacion_date": "<fecha>" }
  1. Envía la solicitud al ERPPOST resource/Cambio Salarial Administrativo

  1. Devuelve al cliente el resultado, incluyendo la respuesta del ERP.


📤 Response 200 – Ejemplo exitoso

{ "valor": true, "msn": "¡Excelente! Se ha registrado exitosamente tu solicitud.", "data": { "name": "CSA-00045", "empleado": "EMP-00123", "nuevo_sueldo": "1500", "nueva_movilidad": "200", "nuevo_bono_nocturno": "150", "fecha_de_actualizacion_date": "2025-01-15" } }

❗ Posibles Errores

1. Campos faltantes

{ "valor": false, "msn": "Ingrese los campos requeridos" }

2. Empleado vacío

{ "valor": false, "msn": "Ingrese el empleado" }

3. Sueldo vacío

{ "valor": false, "msn": "Ingrese el sueldo" }

4. Movilidad vacío

{ "valor": false, "msn": "Ingrese la movilidad" }

5. Bono nocturno vacío

{ "valor": false, "msn": "Ingrese el Bono Nocturno" }

6. Fecha inválida

{ "valor": false, "msn": "Ingrese la fecha de actualizacion" }

📚 Schemas

Cambio Salarial Administrativo (ERP)

Body enviado:

{ "empleado": "string", "nuevo_sueldo": "number", "nueva_movilidad": "number", "nuevo_bono_nocturno": "number", "fecha_de_actualizacion_date": "YYYY-MM-DD" }

🗃 Lógica en Pseudocódigo

required = [empleado, sueldo, movilidad, bono_nocturno, fecha] if falta alguno: return error if fecha no válida: return error body = { empleado, nuevo_sueldo: sueldo, nueva_movilidad: movilidad, nuevo_bono_nocturno: bono_nocturno, fecha_de_actualizacion_date: fecha } response = POST ERP Cambio Salarial Administrativo return success with response

Cambio de Sistema Pensionario(Sistema de Pension Combos (1)) - [combos]

🧾 Descripción

Este servicio retorna un conjunto de listas predefinidas utilizadas en la aplicación móvil, específicamente los tipos de AFP disponibles para selección en formularios o procesos del sistema.

No realiza consultas a base de datos ni al ERP; solo devuelve información estática utilizada para poblar combos (selects) en la interfaz.

Es un servicio simple y de uso general dentro del módulo de onboarding o actualización de datos personales.


🚀 Endpoint

POST /combos

Este servicio no requiere parámetros en el body ni en la URL.


🔐 Seguridad

Utiliza el flujo regular del controlador.
No solicita autenticación directa dentro de la función, pero su acceso depende de la configuración del backend (middleware del módulo).

No realiza llamadas externas al ERP.


🧠 Flujo del Servicio (resumen real)

  1. Define internamente una lista fija con los tipos de AFP:

    • AFP Habitat

    • AFP Profuturo

    • AFP Prima

    • AFP Integra

  2. Organiza los datos dentro de un arreglo asociado a la clave "tipos_afp".

  3. Retorna un JSON con:

    • valor: true

    • data: { "tipos_afp": [...] }


📥 Request Body

Este servicio no recibe parámetros.


{}

📤 Response 200 – Ejemplo

{ "valor": true, "data": { "tipos_afp": [ "AFP Habitat", "AFP Profuturo", "AFP Prima", "AFP Integra" ] } }

❗ Posibles Errores

Este servicio no genera errores, dado que devuelve datos estáticos.
Sin embargo, errores genéricos podrían producirse por:

  1. Error interno del servidor

    { "valor": false, "msn": "Error interno del servidor", "data": [] }

📚 Schemas usados

Respuesta del servicio

{ "valor": "boolean", "data": { "tipos_afp": ["string", ...] } }

🗃 Lógica en pseudo-código

combos = { "tipos_afp": [ "AFP Habitat", "AFP Profuturo", "AFP Prima", "AFP Integra" ] } return { valor: true, data: combos }

Cambio de Sistema Pensionario(Enviar solicitud cambio AFP (1)) - [store]

🧾 Descripción

Este servicio registra una solicitud de cambio de sistema pensionario para un empleado, validando previamente:

El servicio crea un nuevo documento en el ERP: Solicitud de Cambio de Sistema Pensionario


🚀 Endpoint

POST /cambio-sistema-pensionario/store


🔐 Seguridad


🧠 Flujo del Servicio (resumen real)

1. Validación de parámetros

El servicio valida:

2. Trae los datos del empleado


GET Employee/{empleado}

Si el empleado no existe → error.

3. Determina si el cambio es permitido

Reglas del negocio:

4. Verifica si ya existe una solicitud "Borrador"

Consulta a la base ERP:

SELECT name FROM `tabSolicitud de Cambio de Sistema Pensionario` WHERE id_empleado = <empleado> AND docstatus = 0

Si existe una, retorna error.

5. Crea la solicitud de cambio

POST resource/Solicitud de Cambio de Sistema Pensionario { "id_empleado": <empleado>, "sistema_pensionario": "AFP"|"ONP", "tipo_de_afp": "...", "tipo_cambio": "...", "cuspp": "..." // cuando aplica }


📥 Request Body (ejemplo)

{ "empleado": "EMP-0001", "sistema_pensionario": "AFP", "tipo_afp": "AFP Integra", "cuspp": "123456789012", "tipo_cambio": "DE ONP A AFP" }


📤 Response 200 – Ejemplo

✔ Cambio enviado correctamente

{ "valor": true, "msn": "Solicitud de cambio de sistema pensionario enviada" }

❌ Tipo de cambio inválido

{ "valor": false, "msn": "La opción del tipo de cambio no es una opción valida (\"ENTRE AFP\",\"DE ONP A AFP\",\"DE AFP A ONP\")" }

❌ Ya existe solicitud en borrador

{ "valor": false, "msn": "Ya cuenta con una solicitud en Borrador pendiente de validar" }

❌ No puede cambiar al mismo sistema

{ "valor": false, "msn": "No puede hacer el cambio al mismo sistema pensionario" }

❌ Error al crear solicitud

{ "valor": false, "msn": "Ocurrió un error al crear la solicitud de cambio de sistema pensionario", "error": { ... } }


📚 Validaciones importantes del servicio

✔ Validación de CUSPP

✔ Validación de sistema pensionario

✔ Regla especial ONP → AFP

Si el empleado está en ONP, solo puede migrar a AFP Integra:

if($employee["response"]["fondo_de_pensiones"] == "ONP" && $sistema_pensionario == "AFP" && $tipo_afp != "AFP Integra")


🗃 Lógica en pseudo-código

validar parámetros employee = GET Employee/{empleado} si no existe -> error si cambio no permitido -> error buscar solicitudes en Borrador para el empleado si existe -> error validar CUSPP si aplica crear documento: POST Solicitud de Cambio de Sistema Pensionario retornar éxito