paperclip-plugin-autopilot-ops 0.1.37 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/manifest.js +9 -1
- package/dist/ui/index.js +9 -1
- package/dist/worker.js +74 -14
- package/package.json +1 -1
package/dist/manifest.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/manifest.ts
|
|
2
2
|
var PLUGIN_ID = "alephoo.autopilot-ops";
|
|
3
|
-
var PLUGIN_VERSION = "0.1.
|
|
3
|
+
var PLUGIN_VERSION = "0.1.39";
|
|
4
4
|
var DB_NAMESPACE_SLUG = "autopilot_ops";
|
|
5
5
|
var PAGE_ROUTE = "autopilot";
|
|
6
6
|
var TOOL_NAMES = {
|
|
@@ -458,6 +458,14 @@ var manifest = {
|
|
|
458
458
|
capability: "api.routes.register",
|
|
459
459
|
companyResolution: { from: "body", key: "companyId" }
|
|
460
460
|
},
|
|
461
|
+
{
|
|
462
|
+
routeKey: "respuesta-equipo",
|
|
463
|
+
method: "POST",
|
|
464
|
+
path: "/casos/:casoId/respuesta-equipo",
|
|
465
|
+
auth: "board",
|
|
466
|
+
capability: "api.routes.register",
|
|
467
|
+
companyResolution: { from: "body", key: "companyId" }
|
|
468
|
+
},
|
|
461
469
|
{
|
|
462
470
|
routeKey: "envio-nota",
|
|
463
471
|
method: "POST",
|
package/dist/ui/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
|
|
9
9
|
// src/manifest.ts
|
|
10
10
|
var PLUGIN_ID = "alephoo.autopilot-ops";
|
|
11
|
-
var PLUGIN_VERSION = "0.1.
|
|
11
|
+
var PLUGIN_VERSION = "0.1.39";
|
|
12
12
|
var DB_NAMESPACE_SLUG = "autopilot_ops";
|
|
13
13
|
var PAGE_ROUTE = "autopilot";
|
|
14
14
|
var TOOL_NAMES = {
|
|
@@ -466,6 +466,14 @@ var manifest = {
|
|
|
466
466
|
capability: "api.routes.register",
|
|
467
467
|
companyResolution: { from: "body", key: "companyId" }
|
|
468
468
|
},
|
|
469
|
+
{
|
|
470
|
+
routeKey: "respuesta-equipo",
|
|
471
|
+
method: "POST",
|
|
472
|
+
path: "/casos/:casoId/respuesta-equipo",
|
|
473
|
+
auth: "board",
|
|
474
|
+
capability: "api.routes.register",
|
|
475
|
+
companyResolution: { from: "body", key: "companyId" }
|
|
476
|
+
},
|
|
469
477
|
{
|
|
470
478
|
routeKey: "envio-nota",
|
|
471
479
|
method: "POST",
|
package/dist/worker.js
CHANGED
|
@@ -39932,7 +39932,7 @@ function startWorkerRpcHost(options) {
|
|
|
39932
39932
|
|
|
39933
39933
|
// src/manifest.ts
|
|
39934
39934
|
var PLUGIN_ID = "alephoo.autopilot-ops";
|
|
39935
|
-
var PLUGIN_VERSION = "0.1.
|
|
39935
|
+
var PLUGIN_VERSION = "0.1.39";
|
|
39936
39936
|
var DB_NAMESPACE_SLUG = "autopilot_ops";
|
|
39937
39937
|
var PAGE_ROUTE = "autopilot";
|
|
39938
39938
|
var TOOL_NAMES = {
|
|
@@ -40390,6 +40390,14 @@ var manifest = {
|
|
|
40390
40390
|
capability: "api.routes.register",
|
|
40391
40391
|
companyResolution: { from: "body", key: "companyId" }
|
|
40392
40392
|
},
|
|
40393
|
+
{
|
|
40394
|
+
routeKey: "respuesta-equipo",
|
|
40395
|
+
method: "POST",
|
|
40396
|
+
path: "/casos/:casoId/respuesta-equipo",
|
|
40397
|
+
auth: "board",
|
|
40398
|
+
capability: "api.routes.register",
|
|
40399
|
+
companyResolution: { from: "body", key: "companyId" }
|
|
40400
|
+
},
|
|
40393
40401
|
{
|
|
40394
40402
|
routeKey: "envio-nota",
|
|
40395
40403
|
method: "POST",
|
|
@@ -41194,7 +41202,7 @@ function textoIndices(detalle, desde, hasta) {
|
|
|
41194
41202
|
}
|
|
41195
41203
|
var NOTA_POR_DEFECTO = {
|
|
41196
41204
|
asunto: "Actualizaci\xF3n de aranceles \xB7 {convenio} \xB7 {institucion}",
|
|
41197
|
-
texto: "Estimados de {financiador}:\n\
|
|
41205
|
+
texto: "Estimados de {financiador}:\n\n{fundamento}, proponemos actualizar los aranceles del convenio {convenio} en un {porcentaje}, con vigencia desde el {vigencia}.\n\nAdjuntamos el detalle de las {practicas} pr\xE1cticas con sus valores actuales y los propuestos.\n\nQuedamos a la espera de su conformidad.\n\nSaludos cordiales,\n{firma}\n{institucion}"
|
|
41198
41206
|
};
|
|
41199
41207
|
function armarNota(plantilla, d) {
|
|
41200
41208
|
const p = plantilla && typeof plantilla === "object" ? plantilla : {};
|
|
@@ -41205,6 +41213,8 @@ function armarNota(plantilla, d) {
|
|
|
41205
41213
|
convenio: d.convenio,
|
|
41206
41214
|
porcentaje: `${d.porcentaje.toLocaleString("es-AR", { maximumFractionDigits: 2 })} %`,
|
|
41207
41215
|
indices: d.indices,
|
|
41216
|
+
// «De acuerdo con la variación de …» si se propone lo que da la fórmula; si no, el índice queda como referencia.
|
|
41217
|
+
fundamento: d.calculado == null || Math.abs(d.calculado - d.porcentaje) < 5e-3 ? `De acuerdo con la variaci\xF3n de ${d.indices}` : `Teniendo en cuenta la variaci\xF3n de ${d.indices}, que da un ${d.calculado.toLocaleString("es-AR", { maximumFractionDigits: 2 })} %`,
|
|
41208
41218
|
vigencia: dia5 ? `${dia5}/${m}/${a}` : d.vigencia,
|
|
41209
41219
|
firma: d.firma,
|
|
41210
41220
|
practicas: String(d.practicas)
|
|
@@ -42797,7 +42807,8 @@ var circularAranceles = {
|
|
|
42797
42807
|
}
|
|
42798
42808
|
]
|
|
42799
42809
|
};
|
|
42800
|
-
var RESPUESTAS_AJUSTE = ["aprobado", "aprobado_otro", "rechazado"];
|
|
42810
|
+
var RESPUESTAS_AJUSTE = ["aprobado", "aprobado_otro", "rechazado", "insistir", "contraoferta"];
|
|
42811
|
+
var RESPUESTAS_DEL_FINANCIADOR = ["aprobado", "otro", "rechazado"];
|
|
42801
42812
|
var CANALES_NOTA = ["correo", "portal_del_financiador", "nota", "otro"];
|
|
42802
42813
|
function calcularAjuste(caso, datos, contexto) {
|
|
42803
42814
|
const formula = contexto.formulaAjuste ?? FORMULA_POR_DEFECTO;
|
|
@@ -42831,7 +42842,7 @@ var ajusteConvenio = {
|
|
|
42831
42842
|
puesto: "Convenios y facturaci\xF3n",
|
|
42832
42843
|
descripcion: "Calcula el aumento de un convenio con los \xEDndices publicados (IPC de INDEC) y la f\xF3rmula de la instituci\xF3n, arma los valores nuevos de cada pr\xE1ctica y la nota al financiador; la direcci\xF3n revisa y aprueba, se registra la respuesta del financiador, se carga con el archivo que genera el plugin y el puesto comprueba releyendo cada valor.",
|
|
42833
42844
|
inicial: "abierto",
|
|
42834
|
-
estados: ["abierto", "calculado", "pendiente_aprobacion", "por_enviar", "enviado", "acordado", "aplicado", "verificado", "con_diferencias", "rechazado", "rechazado_financiador", "cancelado"],
|
|
42845
|
+
estados: ["abierto", "calculado", "pendiente_aprobacion", "por_enviar", "enviado", "respuesta_recibida", "acordado", "aplicado", "verificado", "con_diferencias", "rechazado", "rechazado_financiador", "cancelado"],
|
|
42835
42846
|
finalesOk: ["verificado"],
|
|
42836
42847
|
finalesNoOk: ["rechazado", "rechazado_financiador", "cancelado"],
|
|
42837
42848
|
minutosAbsorbidos: 40,
|
|
@@ -42932,15 +42943,39 @@ var ajusteConvenio = {
|
|
|
42932
42943
|
]
|
|
42933
42944
|
},
|
|
42934
42945
|
{
|
|
42935
|
-
via: "
|
|
42946
|
+
via: "informar_respuesta",
|
|
42936
42947
|
de: ["enviado"],
|
|
42937
|
-
|
|
42948
|
+
// Si aceptó lo propuesto no hay nada que decidir: queda el archivo. Otro porcentaje o un rechazo los decide la dirección.
|
|
42949
|
+
a: (_caso, datos) => datos.respuesta === "aprobado" ? "acordado" : "respuesta_recibida",
|
|
42938
42950
|
actor: ["humano"],
|
|
42939
|
-
descripcion: "
|
|
42951
|
+
descripcion: "El equipo registra lo que contest\xF3 el financiador: acept\xF3 lo propuesto, pidi\xF3 otro porcentaje (porcentaje) o no lo acept\xF3 (motivo).",
|
|
42952
|
+
validar: (_caso, datos) => {
|
|
42953
|
+
const r = datos.respuesta;
|
|
42954
|
+
if (!RESPUESTAS_DEL_FINANCIADOR.includes(r)) return [falla("respuesta_valida", `respuesta: ${RESPUESTAS_DEL_FINANCIADOR.join(", ")}`)];
|
|
42955
|
+
if (r === "otro") return [ok("respuesta_valida"), validarPorcentajeHumano(datos.porcentaje, "porcentaje_valido")];
|
|
42956
|
+
if (r === "rechazado") return [ok("respuesta_valida"), texto4(datos.motivo) ? ok("motivo_presente") : falla("motivo_presente", "anotar qu\xE9 respondi\xF3 el financiador")];
|
|
42957
|
+
return [ok("respuesta_valida")];
|
|
42958
|
+
}
|
|
42959
|
+
},
|
|
42960
|
+
{
|
|
42961
|
+
via: "reenviar",
|
|
42962
|
+
de: ["enviado"],
|
|
42963
|
+
a: "enviado",
|
|
42964
|
+
actor: ["humano", "agente"],
|
|
42965
|
+
nivelRequerido: "ejecuta",
|
|
42966
|
+
descripcion: "Registrar que se volvi\xF3 a mandar la nota (el financiador no respondi\xF3 en el plazo).",
|
|
42967
|
+
validar: (_caso, datos) => [texto4(datos.destinatario) ? ok("destinatario_presente") : falla("destinatario_presente", "destinatario (a qui\xE9n se reenvi\xF3) es obligatorio")]
|
|
42968
|
+
},
|
|
42969
|
+
{
|
|
42970
|
+
via: "responder",
|
|
42971
|
+
de: ["enviado", "respuesta_recibida"],
|
|
42972
|
+
a: (_caso, datos) => datos.respuesta === "rechazado" ? "rechazado_financiador" : datos.respuesta === "insistir" || datos.respuesta === "contraoferta" ? "por_enviar" : "acordado",
|
|
42973
|
+
actor: ["humano"],
|
|
42974
|
+
descripcion: "La direcci\xF3n decide sobre la respuesta del financiador: aceptar lo propuesto, aceptar otro porcentaje (porcentaje), contraofertar (porcentaje: vuelve a salir una nota), insistir (se reenv\xEDa la nota) o darlo por rechazado (motivo).",
|
|
42940
42975
|
validar: (_caso, datos) => {
|
|
42941
42976
|
const r = datos.respuesta;
|
|
42942
42977
|
if (!RESPUESTAS_AJUSTE.includes(r)) return [falla("respuesta_valida", `respuesta: ${RESPUESTAS_AJUSTE.join(", ")}`)];
|
|
42943
|
-
if (r === "aprobado_otro") return [ok("respuesta_valida"), validarPorcentajeHumano(datos.porcentaje, "porcentaje_valido")];
|
|
42978
|
+
if (r === "aprobado_otro" || r === "contraoferta") return [ok("respuesta_valida"), validarPorcentajeHumano(datos.porcentaje, "porcentaje_valido")];
|
|
42944
42979
|
if (r === "rechazado") return [ok("respuesta_valida"), texto4(datos.motivo) ? ok("motivo_presente") : falla("motivo_presente", "anotar qu\xE9 respondi\xF3 el financiador")];
|
|
42945
42980
|
return [ok("respuesta_valida")];
|
|
42946
42981
|
}
|
|
@@ -42991,7 +43026,7 @@ var ajusteConvenio = {
|
|
|
42991
43026
|
},
|
|
42992
43027
|
{
|
|
42993
43028
|
via: "cancelar",
|
|
42994
|
-
de: ["abierto", "calculado", "pendiente_aprobacion", "por_enviar", "enviado", "acordado", "con_diferencias"],
|
|
43029
|
+
de: ["abierto", "calculado", "pendiente_aprobacion", "por_enviar", "enviado", "respuesta_recibida", "acordado", "con_diferencias"],
|
|
42995
43030
|
a: "cancelado",
|
|
42996
43031
|
actor: ["humano", "agente"],
|
|
42997
43032
|
nivelRequerido: "observa",
|
|
@@ -45431,20 +45466,26 @@ async function transicionar(ctx, input2) {
|
|
|
45431
45466
|
datos.excluir = excluir;
|
|
45432
45467
|
recalcular(pedido ?? porcentajeAntes, excluir);
|
|
45433
45468
|
} else if (resultado.via !== "calcular") delete datos.excluir;
|
|
45434
|
-
if (resultado.via === "
|
|
45435
|
-
datos.
|
|
45469
|
+
if (resultado.via === "informar_respuesta") {
|
|
45470
|
+
datos.respuesta_financiador = { respuesta: datos.respuesta, porcentaje: pedido, detalle: str2(datos.motivo) ?? str2(datos.detalle) };
|
|
45471
|
+
if (datos.respuesta === "aprobado") datos.porcentaje_acordado = porcentajeAntes;
|
|
45472
|
+
}
|
|
45473
|
+
if (resultado.via === "responder" && (datos.respuesta === "aprobado_otro" || datos.respuesta === "contraoferta") && pedido !== null) {
|
|
45474
|
+
if (datos.respuesta === "aprobado_otro") datos.porcentaje_acordado = pedido;
|
|
45436
45475
|
recalcular(pedido, caso.datos.excluir);
|
|
45437
45476
|
}
|
|
45438
45477
|
if (resultado.via === "responder" && datos.respuesta === "aprobado") datos.porcentaje_acordado = porcentajeAntes;
|
|
45439
45478
|
if (resultado.a === "por_enviar") {
|
|
45440
45479
|
const op = await obtenerOpciones(ctx, input2.companyId, caso.workflow);
|
|
45441
|
-
const
|
|
45480
|
+
const porcentajeNota = typeof datos.porcentaje === "number" ? datos.porcentaje : porcentajeAntes;
|
|
45481
|
+
const r = datos.resumen ?? caso.datos.resumen;
|
|
45442
45482
|
datos.nota = armarNota(op.nota, {
|
|
45443
45483
|
institucion: str2(op.institucion) ?? str2(caso.datos.institucion) ?? "",
|
|
45444
45484
|
financiador: str2(caso.datos.financiador) ?? "",
|
|
45445
45485
|
convenio: str2(caso.datos.convenio) ?? "",
|
|
45446
|
-
porcentaje:
|
|
45447
|
-
|
|
45486
|
+
porcentaje: porcentajeNota,
|
|
45487
|
+
calculado: typeof caso.datos.porcentaje_calculado === "number" ? caso.datos.porcentaje_calculado : null,
|
|
45488
|
+
indices: textoIndices(caso.datos.detalle ?? { fijo: porcentajeNota }, str2(caso.datos.ultimo_ajuste), str2(caso.datos.periodo_hasta)),
|
|
45448
45489
|
vigencia: str2(caso.datos.vigencia_desde) ?? "",
|
|
45449
45490
|
firma: str2(op.firma) ?? "",
|
|
45450
45491
|
practicas: r?.practicas ?? 0
|
|
@@ -46348,6 +46389,20 @@ async function registrarEnvioLiquidacion(ctx, input2) {
|
|
|
46348
46389
|
});
|
|
46349
46390
|
return transicionar(ctx, { companyId: input2.companyId, casoId: caso.id, via: "enviar", datos: { aviso_id: accion.id, canal, ...destinatario ? { destinatario } : {}, ...persona ? { registrado_por: persona } : {} }, actor: input2.actor });
|
|
46350
46391
|
}
|
|
46392
|
+
async function registrarRespuestaEquipo(ctx, input2) {
|
|
46393
|
+
const caso = await leerCaso(ctx, input2.companyId, input2.casoId);
|
|
46394
|
+
if (!caso) throw new OpsError("caso_inexistente", `no existe el caso ${input2.casoId} en esta instituci\xF3n`);
|
|
46395
|
+
if (caso.workflow !== "ajuste_convenio") throw new OpsError("workflow_invalido", "solo los ajustes de convenio esperan una respuesta del financiador");
|
|
46396
|
+
if (input2.actor.tipo !== "humano") throw new OpsError("actor_no_permitido", "la respuesta la registra una persona");
|
|
46397
|
+
const persona = str2(input2.persona);
|
|
46398
|
+
if (input2.reenvio) {
|
|
46399
|
+
const canal = typeof input2.reenvio.canal === "string" && CANALES_NOTA.includes(input2.reenvio.canal) ? input2.reenvio.canal : "otro";
|
|
46400
|
+
const accion = await registrarAccion(ctx, { companyId: input2.companyId, casoId: caso.id, tipo: "aviso", conector: canal === "correo" ? "mail" : "manual", objetivo: `Nota de ajuste reenviada a ${str2(caso.datos.financiador) ?? "el financiador"}`, resultado: "ok", evidencia: { canal, destinatario: input2.reenvio.destinatario, ...persona ? { registrado_por: persona } : {} }, actor: input2.actor });
|
|
46401
|
+
return transicionar(ctx, { companyId: input2.companyId, casoId: caso.id, via: "reenviar", datos: { aviso_id: accion.id, canal, destinatario: input2.reenvio.destinatario, ...persona ? { registrado_por: persona } : {} }, actor: input2.actor });
|
|
46402
|
+
}
|
|
46403
|
+
const n = typeof input2.porcentaje === "number" ? input2.porcentaje : typeof input2.porcentaje === "string" && input2.porcentaje.trim() ? Number(input2.porcentaje) : void 0;
|
|
46404
|
+
return transicionar(ctx, { companyId: input2.companyId, casoId: caso.id, via: "informar_respuesta", motivo: str2(input2.detalle), datos: { respuesta: input2.respuesta, ...n !== void 0 ? { porcentaje: n } : {}, ...str2(input2.detalle) ? { motivo: str2(input2.detalle) } : {}, ...persona ? { registrado_por: persona } : {} }, actor: input2.actor });
|
|
46405
|
+
}
|
|
46351
46406
|
async function registrarEnvioNota(ctx, input2) {
|
|
46352
46407
|
const caso = await leerCaso(ctx, input2.companyId, input2.casoId);
|
|
46353
46408
|
if (!caso) throw new OpsError("caso_inexistente", `no existe el caso ${input2.casoId} en esta instituci\xF3n`);
|
|
@@ -47403,6 +47458,11 @@ async function manejarApi(ctx, input2) {
|
|
|
47403
47458
|
const datosA = { ...body.porcentaje !== void 0 ? { porcentaje: body.porcentaje } : {}, ...Array.isArray(body.excluir) ? { excluir: body.excluir } : {} };
|
|
47404
47459
|
return respuesta(200, await transicionar(ctx, { companyId, casoId: input2.params.casoId ?? "", via: "ajustar", motivo: motivoConPersona(str3(body.motivo)), datos: conPersona({ ...datosA, ...str3(body.motivo) ? { motivo: str3(body.motivo) } : {} }), idempotencyKey: str3(body.idempotencyKey), actor }));
|
|
47405
47460
|
}
|
|
47461
|
+
case "respuesta-equipo": {
|
|
47462
|
+
if (actor.tipo !== "humano") return respuesta(403, { error: "actor_no_permitido", motivo: "la respuesta la registra una persona" });
|
|
47463
|
+
const reenvio = body.reenvio && typeof body.reenvio === "object" ? body.reenvio : null;
|
|
47464
|
+
return respuesta(200, await registrarRespuestaEquipo(ctx, { companyId, casoId: input2.params.casoId ?? "", respuesta: body.respuesta, porcentaje: body.porcentaje, detalle: str3(body.detalle), reenvio: reenvio ? { canal: reenvio.canal, destinatario: str3(reenvio.destinatario) } : null, persona: decididoPor, actor }));
|
|
47465
|
+
}
|
|
47406
47466
|
case "envio-nota": {
|
|
47407
47467
|
if (actor.tipo !== "humano") return respuesta(403, { error: "actor_no_permitido", motivo: "el env\xEDo lo registra una persona" });
|
|
47408
47468
|
return respuesta(200, await registrarEnvioNota(ctx, { companyId, casoId: input2.params.casoId ?? "", canal: body.canal, destinatario: str3(body.destinatario), persona: decididoPor, actor }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paperclip-plugin-autopilot-ops",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Autopilot Care · operación autónoma gobernada para instituciones de salud: workflows determinísticos, validaciones, registro de negocio, políticas (observa/propone/ejecuta/corte) y tablero del director, como plugin de Paperclip.",
|
|
6
6
|
"files": [
|