paperclip-plugin-autopilot-ops 0.1.35 → 0.1.37

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.37";
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.37";
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.37";
39936
39936
  var DB_NAMESPACE_SLUG = "autopilot_ops";
39937
39937
  var PAGE_ROUTE = "autopilot";
39938
39938
  var TOOL_NAMES = {
@@ -41057,6 +41057,23 @@ 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, periodo) {
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
+ const p = periodo && typeof periodo === "object" ? periodo : {};
41074
+ const fecha5 = (x) => typeof x === "string" && /^\d{4}-\d{2}-\d{2}$/.test(x) ? x : void 0;
41075
+ return { porCodigo, dias: d, ...fecha5(p.desde) ? { desde: fecha5(p.desde) } : {}, ...fecha5(p.hasta) ? { hasta: fecha5(p.hasta) } : {} };
41076
+ }
41060
41077
  var redondear2 = (n, dec = 2) => Math.round(n * 10 ** dec) / 10 ** dec;
41061
41078
  var periodoValido = (p) => typeof p === "string" && /^\d{4}-(0[1-9]|1[0-2])$/.test(p);
41062
41079
  var porcentajeValido = (n) => typeof n === "number" && Number.isFinite(n) && n > LIMITES_PORCENTAJE[0] && n <= LIMITES_PORCENTAJE[1];
@@ -41148,7 +41165,7 @@ function armarAjuste(actual, porcentaje3) {
41148
41165
  if (items.length === 0) return { ok: false, error: "el convenio no tiene pr\xE1cticas con valor" };
41149
41166
  return { ok: true, items, actual: lectura.practicas };
41150
41167
  }
41151
- function resumenAjuste(items, excluir, porcentaje3, porcentajeCalculado, tope) {
41168
+ function resumenAjuste(items, excluir, porcentaje3, porcentajeCalculado, tope, volumenes = null) {
41152
41169
  const fuera = new Set(Array.isArray(excluir) ? excluir.map(normalizarCodigo) : []);
41153
41170
  const dentro = items.filter((i) => !fuera.has(i.codigo));
41154
41171
  const cargan = dentro.filter((i) => i.estado === "propuesta");
@@ -41161,7 +41178,9 @@ function resumenAjuste(items, excluir, porcentaje3, porcentajeCalculado, tope) {
41161
41178
  total_actual: redondear2(cargan.reduce((a, i) => a + (i.valor_actual ?? 0), 0)),
41162
41179
  total_nuevo: redondear2(cargan.reduce((a, i) => a + (i.valor_nuevo ?? 0), 0)),
41163
41180
  tope,
41164
- supera_tope: Math.abs(porcentaje3) > tope
41181
+ supera_tope: Math.abs(porcentaje3) > tope,
41182
+ // Sin nada facturado de estas prácticas en el período no hay con qué estimar: null, no 0.
41183
+ impacto_mensual: volumenes && cargan.some((i) => (volumenes.porCodigo[i.codigo] ?? 0) > 0) ? 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
41184
  };
41166
41185
  }
41167
41186
  function textoIndices(detalle, desde, hasta) {
@@ -42832,7 +42851,11 @@ var ajusteConvenio = {
42832
42851
  return [
42833
42852
  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
42853
  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)
42854
+ c.ok ? ok("calculo_ajuste", `${c.porcentaje} % sobre ${c.items.length} pr\xE1cticas`) : falla("calculo_ajuste", c.error),
42855
+ ...(() => {
42856
+ const v = leerVolumenes(datos.volumenes, datos.dias_volumen);
42857
+ 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")];
42858
+ })()
42836
42859
  ];
42837
42860
  }
42838
42861
  },
@@ -44861,6 +44884,11 @@ async function cambiarPolitica(ctx, input2) {
44861
44884
  if ("error" in f) throw new OpsError("validacion", `formula: ${f.error}`);
44862
44885
  opciones.formula = f;
44863
44886
  }
44887
+ if (opciones.dias_respuesta !== void 0) {
44888
+ const v = enteroEntre(opciones.dias_respuesta, 1, 60);
44889
+ if (v === null) throw new OpsError("validacion", "dias_respuesta: tiene que ser un n\xFAmero entero entre 1 y 60");
44890
+ opciones.dias_respuesta = v;
44891
+ }
44864
44892
  if (opciones.tope_ajuste !== void 0) {
44865
44893
  const v = enteroEntre(opciones.tope_ajuste, LIMITES_TOPE_AJUSTE[0], LIMITES_TOPE_AJUSTE[1]);
44866
44894
  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 +45385,13 @@ async function transicionar(ctx, input2) {
45357
45385
  const tope = contexto.topeAjuste ?? leerTopeAjuste(void 0);
45358
45386
  const porcentajeAntes = typeof caso.datos.porcentaje === "number" ? caso.datos.porcentaje : 0;
45359
45387
  const calculado = typeof caso.datos.porcentaje_calculado === "number" ? caso.datos.porcentaje_calculado : porcentajeAntes;
45388
+ const volGuardado = caso.datos.volumenes && typeof caso.datos.volumenes === "object" ? caso.datos.volumenes : null;
45360
45389
  const recalcular = (porcentaje3, excluir) => {
45361
45390
  const a = armarAjuste(caso.datos.actual, porcentaje3);
45362
45391
  if (!a.ok) return;
45363
45392
  datos.porcentaje = porcentaje3;
45364
45393
  datos.items = a.items;
45365
- datos.resumen = resumenAjuste(a.items, excluir, porcentaje3, calculado, tope);
45394
+ datos.resumen = resumenAjuste(a.items, excluir, porcentaje3, calculado, tope, volGuardado);
45366
45395
  };
45367
45396
  const pedido = typeof datos.porcentaje === "number" ? datos.porcentaje : typeof datos.porcentaje === "string" && datos.porcentaje.trim() ? Number(datos.porcentaje) : null;
45368
45397
  delete datos.porcentaje;
@@ -45370,6 +45399,10 @@ async function transicionar(ctx, input2) {
45370
45399
  delete datos.excluir;
45371
45400
  const c = calcularAjuste(caso, datos, contexto);
45372
45401
  const act = leerActual(datos.actual);
45402
+ const vl = leerVolumenes(datos.volumenes, datos.dias_volumen, datos.periodo_volumen);
45403
+ delete datos.periodo_volumen;
45404
+ const vol = vl && !("error" in vl) ? vl : null;
45405
+ delete datos.dias_volumen;
45373
45406
  if (c.ok && "practicas" in act) {
45374
45407
  Object.assign(datos, {
45375
45408
  porcentaje: c.porcentaje,
@@ -45378,16 +45411,20 @@ async function transicionar(ctx, input2) {
45378
45411
  periodo_hasta: c.hasta,
45379
45412
  items: c.items,
45380
45413
  excluir: [],
45381
- resumen: resumenAjuste(c.items, [], c.porcentaje, c.porcentaje, tope),
45414
+ resumen: resumenAjuste(c.items, [], c.porcentaje, c.porcentaje, tope, vol),
45415
+ volumenes: vol,
45382
45416
  // Lo que tenía el convenio antes del ajuste queda guardado en el caso: es el respaldo para volver atrás.
45383
45417
  actual: act.practicas,
45384
45418
  indices_usados: Array.isArray(datos.indices) ? datos.indices : []
45385
45419
  });
45386
- }
45420
+ } else delete datos.volumenes;
45387
45421
  delete datos.indices;
45388
45422
  } else {
45389
45423
  delete datos.actual;
45390
45424
  delete datos.indices;
45425
+ delete datos.volumenes;
45426
+ delete datos.dias_volumen;
45427
+ delete datos.periodo_volumen;
45391
45428
  }
45392
45429
  if (resultado.via === "ajustar") {
45393
45430
  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.37",
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": [