paperclip-plugin-autopilot-ops 0.1.35 → 0.1.36

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/manifest.ts
2
2
  var PLUGIN_ID = "alephoo.autopilot-ops";
3
- var PLUGIN_VERSION = "0.1.35";
3
+ var PLUGIN_VERSION = "0.1.36";
4
4
  var DB_NAMESPACE_SLUG = "autopilot_ops";
5
5
  var PAGE_ROUTE = "autopilot";
6
6
  var TOOL_NAMES = {
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.35";
11
+ var PLUGIN_VERSION = "0.1.36";
12
12
  var DB_NAMESPACE_SLUG = "autopilot_ops";
13
13
  var PAGE_ROUTE = "autopilot";
14
14
  var TOOL_NAMES = {
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.35";
39935
+ var PLUGIN_VERSION = "0.1.36";
39936
39936
  var DB_NAMESPACE_SLUG = "autopilot_ops";
39937
39937
  var PAGE_ROUTE = "autopilot";
39938
39938
  var TOOL_NAMES = {
@@ -41057,6 +41057,21 @@ var FORMULA_POR_DEFECTO = { componentes: [{ serie: "ipc_general", peso: 100 }] }
41057
41057
  var TOPE_AJUSTE_POR_DEFECTO = 15;
41058
41058
  var LIMITES_TOPE_AJUSTE = [1, 100];
41059
41059
  var LIMITES_PORCENTAJE = [-50, 100];
41060
+ function leerVolumenes(v, dias) {
41061
+ if (v === void 0 || v === null) return null;
41062
+ if (!Array.isArray(v)) return { error: "volumenes tiene que ser una lista [{codigo, cantidad}]" };
41063
+ const d = typeof dias === "number" && Number.isInteger(dias) && dias >= 7 && dias <= 999 ? dias : null;
41064
+ if (d === null) return { error: "volumenes necesita dias (el per\xEDodo le\xEDdo, de 7 a 999)" };
41065
+ const porCodigo = {};
41066
+ for (const [i, e] of v.entries()) {
41067
+ const r = e ?? {};
41068
+ const codigo = normalizarCodigo(r.codigo);
41069
+ const cantidad2 = typeof r.cantidad === "number" ? r.cantidad : Number(r.cantidad);
41070
+ if (!codigo || !Number.isFinite(cantidad2) || cantidad2 < 0) return { error: `volumenes[${i}]: c\xF3digo y cantidad mayor o igual a 0` };
41071
+ porCodigo[codigo] = (porCodigo[codigo] ?? 0) + cantidad2;
41072
+ }
41073
+ return { porCodigo, dias: d };
41074
+ }
41060
41075
  var redondear2 = (n, dec = 2) => Math.round(n * 10 ** dec) / 10 ** dec;
41061
41076
  var periodoValido = (p) => typeof p === "string" && /^\d{4}-(0[1-9]|1[0-2])$/.test(p);
41062
41077
  var porcentajeValido = (n) => typeof n === "number" && Number.isFinite(n) && n > LIMITES_PORCENTAJE[0] && n <= LIMITES_PORCENTAJE[1];
@@ -41148,7 +41163,7 @@ function armarAjuste(actual, porcentaje3) {
41148
41163
  if (items.length === 0) return { ok: false, error: "el convenio no tiene pr\xE1cticas con valor" };
41149
41164
  return { ok: true, items, actual: lectura.practicas };
41150
41165
  }
41151
- function resumenAjuste(items, excluir, porcentaje3, porcentajeCalculado, tope) {
41166
+ function resumenAjuste(items, excluir, porcentaje3, porcentajeCalculado, tope, volumenes = null) {
41152
41167
  const fuera = new Set(Array.isArray(excluir) ? excluir.map(normalizarCodigo) : []);
41153
41168
  const dentro = items.filter((i) => !fuera.has(i.codigo));
41154
41169
  const cargan = dentro.filter((i) => i.estado === "propuesta");
@@ -41161,7 +41176,8 @@ function resumenAjuste(items, excluir, porcentaje3, porcentajeCalculado, tope) {
41161
41176
  total_actual: redondear2(cargan.reduce((a, i) => a + (i.valor_actual ?? 0), 0)),
41162
41177
  total_nuevo: redondear2(cargan.reduce((a, i) => a + (i.valor_nuevo ?? 0), 0)),
41163
41178
  tope,
41164
- supera_tope: Math.abs(porcentaje3) > tope
41179
+ supera_tope: Math.abs(porcentaje3) > tope,
41180
+ impacto_mensual: volumenes ? redondear2(cargan.reduce((a, i) => a + ((i.valor_nuevo ?? 0) - (i.valor_actual ?? 0)) * (volumenes.porCodigo[i.codigo] ?? 0), 0) * 30 / volumenes.dias, 0) : null
41165
41181
  };
41166
41182
  }
41167
41183
  function textoIndices(detalle, desde, hasta) {
@@ -42832,7 +42848,11 @@ var ajusteConvenio = {
42832
42848
  return [
42833
42849
  texto4(datos.lectura_id) ? ok("lectura_registrada") : falla("lectura_registrada", "calcular requiere lectura_id: la lectura del convenio en el HIS registrada con ops_registrar_accion"),
42834
42850
  fijo || texto4(datos.lectura_indices_id) ? ok("indices_registrados") : falla("indices_registrados", "calcular requiere lectura_indices_id: la consulta de los \xEDndices (conector api) registrada con ops_registrar_accion"),
42835
- c.ok ? ok("calculo_ajuste", `${c.porcentaje} % sobre ${c.items.length} pr\xE1cticas`) : falla("calculo_ajuste", c.error)
42851
+ c.ok ? ok("calculo_ajuste", `${c.porcentaje} % sobre ${c.items.length} pr\xE1cticas`) : falla("calculo_ajuste", c.error),
42852
+ ...(() => {
42853
+ const v = leerVolumenes(datos.volumenes, datos.dias_volumen);
42854
+ return v && "error" in v ? [falla("volumenes_validos", v.error)] : [ok("volumenes_validos", v ? "con lo facturado" : "sin vol\xFAmenes: no se estima el impacto en pesos")];
42855
+ })()
42836
42856
  ];
42837
42857
  }
42838
42858
  },
@@ -44861,6 +44881,11 @@ async function cambiarPolitica(ctx, input2) {
44861
44881
  if ("error" in f) throw new OpsError("validacion", `formula: ${f.error}`);
44862
44882
  opciones.formula = f;
44863
44883
  }
44884
+ if (opciones.dias_respuesta !== void 0) {
44885
+ const v = enteroEntre(opciones.dias_respuesta, 1, 60);
44886
+ if (v === null) throw new OpsError("validacion", "dias_respuesta: tiene que ser un n\xFAmero entero entre 1 y 60");
44887
+ opciones.dias_respuesta = v;
44888
+ }
44864
44889
  if (opciones.tope_ajuste !== void 0) {
44865
44890
  const v = enteroEntre(opciones.tope_ajuste, LIMITES_TOPE_AJUSTE[0], LIMITES_TOPE_AJUSTE[1]);
44866
44891
  if (v === null) throw new OpsError("validacion", `tope_ajuste: tiene que ser un n\xFAmero entero entre ${LIMITES_TOPE_AJUSTE[0]} y ${LIMITES_TOPE_AJUSTE[1]}`);
@@ -45357,12 +45382,13 @@ async function transicionar(ctx, input2) {
45357
45382
  const tope = contexto.topeAjuste ?? leerTopeAjuste(void 0);
45358
45383
  const porcentajeAntes = typeof caso.datos.porcentaje === "number" ? caso.datos.porcentaje : 0;
45359
45384
  const calculado = typeof caso.datos.porcentaje_calculado === "number" ? caso.datos.porcentaje_calculado : porcentajeAntes;
45385
+ const volGuardado = caso.datos.volumenes && typeof caso.datos.volumenes === "object" ? caso.datos.volumenes : null;
45360
45386
  const recalcular = (porcentaje3, excluir) => {
45361
45387
  const a = armarAjuste(caso.datos.actual, porcentaje3);
45362
45388
  if (!a.ok) return;
45363
45389
  datos.porcentaje = porcentaje3;
45364
45390
  datos.items = a.items;
45365
- datos.resumen = resumenAjuste(a.items, excluir, porcentaje3, calculado, tope);
45391
+ datos.resumen = resumenAjuste(a.items, excluir, porcentaje3, calculado, tope, volGuardado);
45366
45392
  };
45367
45393
  const pedido = typeof datos.porcentaje === "number" ? datos.porcentaje : typeof datos.porcentaje === "string" && datos.porcentaje.trim() ? Number(datos.porcentaje) : null;
45368
45394
  delete datos.porcentaje;
@@ -45370,6 +45396,9 @@ async function transicionar(ctx, input2) {
45370
45396
  delete datos.excluir;
45371
45397
  const c = calcularAjuste(caso, datos, contexto);
45372
45398
  const act = leerActual(datos.actual);
45399
+ const vl = leerVolumenes(datos.volumenes, datos.dias_volumen);
45400
+ const vol = vl && !("error" in vl) ? vl : null;
45401
+ delete datos.dias_volumen;
45373
45402
  if (c.ok && "practicas" in act) {
45374
45403
  Object.assign(datos, {
45375
45404
  porcentaje: c.porcentaje,
@@ -45378,16 +45407,19 @@ async function transicionar(ctx, input2) {
45378
45407
  periodo_hasta: c.hasta,
45379
45408
  items: c.items,
45380
45409
  excluir: [],
45381
- resumen: resumenAjuste(c.items, [], c.porcentaje, c.porcentaje, tope),
45410
+ resumen: resumenAjuste(c.items, [], c.porcentaje, c.porcentaje, tope, vol),
45411
+ volumenes: vol,
45382
45412
  // Lo que tenía el convenio antes del ajuste queda guardado en el caso: es el respaldo para volver atrás.
45383
45413
  actual: act.practicas,
45384
45414
  indices_usados: Array.isArray(datos.indices) ? datos.indices : []
45385
45415
  });
45386
- }
45416
+ } else delete datos.volumenes;
45387
45417
  delete datos.indices;
45388
45418
  } else {
45389
45419
  delete datos.actual;
45390
45420
  delete datos.indices;
45421
+ delete datos.volumenes;
45422
+ delete datos.dias_volumen;
45391
45423
  }
45392
45424
  if (resultado.via === "ajustar") {
45393
45425
  const excluir = Array.isArray(datos.excluir) ? datos.excluir.map(normalizarCodigo) : caso.datos.excluir ?? [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paperclip-plugin-autopilot-ops",
3
- "version": "0.1.35",
3
+ "version": "0.1.36",
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": [