@nubiia/mcp-freematica 0.7.0 → 0.9.0

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.
Files changed (56) hide show
  1. package/README.md +20 -7
  2. package/dist/clients/fiql-builder.d.ts +32 -8
  3. package/dist/clients/fiql-builder.js +42 -14
  4. package/dist/clients/fiql-builder.js.map +1 -1
  5. package/dist/clients/freematica-client.d.ts +165 -34
  6. package/dist/clients/freematica-client.js +355 -96
  7. package/dist/clients/freematica-client.js.map +1 -1
  8. package/dist/schemas/cartera.d.ts +7 -5
  9. package/dist/schemas/cartera.js +13 -11
  10. package/dist/schemas/cartera.js.map +1 -1
  11. package/dist/schemas/clientes.d.ts +164 -0
  12. package/dist/schemas/clientes.js +205 -0
  13. package/dist/schemas/clientes.js.map +1 -0
  14. package/dist/schemas/facturas-ventas.d.ts +20 -16
  15. package/dist/schemas/facturas-ventas.js +36 -32
  16. package/dist/schemas/facturas-ventas.js.map +1 -1
  17. package/dist/schemas/localizaciones.d.ts +90 -0
  18. package/dist/schemas/localizaciones.js +145 -0
  19. package/dist/schemas/localizaciones.js.map +1 -0
  20. package/dist/schemas/pedidos-compras.d.ts +8 -6
  21. package/dist/schemas/pedidos-compras.js +8 -6
  22. package/dist/schemas/pedidos-compras.js.map +1 -1
  23. package/dist/server-instructions.js +43 -0
  24. package/dist/server-instructions.js.map +1 -1
  25. package/dist/server.js +5 -3
  26. package/dist/server.js.map +1 -1
  27. package/dist/tools/articulos.d.ts +14 -0
  28. package/dist/tools/articulos.js +183 -0
  29. package/dist/tools/articulos.js.map +1 -0
  30. package/dist/tools/cartera.js +2 -2
  31. package/dist/tools/cartera.js.map +1 -1
  32. package/dist/tools/clientes.d.ts +2 -1
  33. package/dist/tools/clientes.js +63 -2
  34. package/dist/tools/clientes.js.map +1 -1
  35. package/dist/tools/contabilidad.js +7 -7
  36. package/dist/tools/contabilidad.js.map +1 -1
  37. package/dist/tools/contactos-clientes.d.ts +2 -1
  38. package/dist/tools/contactos-clientes.js +58 -4
  39. package/dist/tools/contactos-clientes.js.map +1 -1
  40. package/dist/tools/contratos/cabecera.d.ts +2 -3
  41. package/dist/tools/contratos/cabecera.js.map +1 -1
  42. package/dist/tools/facturas-ventas.js +12 -12
  43. package/dist/tools/facturas-ventas.js.map +1 -1
  44. package/dist/tools/helpers.d.ts +4 -0
  45. package/dist/tools/helpers.js.map +1 -1
  46. package/dist/tools/localizaciones.d.ts +3 -2
  47. package/dist/tools/localizaciones.js +151 -13
  48. package/dist/tools/localizaciones.js.map +1 -1
  49. package/dist/tools/personal.js +13 -17
  50. package/dist/tools/personal.js.map +1 -1
  51. package/dist/tools/prl.js +15 -49
  52. package/dist/tools/prl.js.map +1 -1
  53. package/dist/tools/proveedores.d.ts +2 -2
  54. package/dist/tools/proveedores.js +8 -6
  55. package/dist/tools/proveedores.js.map +1 -1
  56. package/package.json +1 -1
package/README.md CHANGED
@@ -20,6 +20,9 @@ MCP server que expone operaciones del API REST de Freemática (ERP: facturación
20
20
 
21
21
  | Tool | Endpoint Freemática | Descripción |
22
22
  | ---------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
23
+ | `freematica_list_articulos` | `GET /part/v1/articulos` | Catálogo de artículos/materiales/consumibles (referencias, familias, proveedores) |
24
+ | `freematica_get_articulo` | `GET /part/v1/articulos/{idreg}` | Detalle de un artículo |
25
+ | `freematica_get_precio_articulo` | `GET /pgrl/v1/precio-articulo/{idreg}` | Precios de venta de un artículo (PRECIO_VENTA, DESCUENTO, FACTURABLE) |
23
26
  | `freematica_list_materiales_asignados_servicios` | `GET /pvss/v2/contratos-servicios-material` | Lista de material asignado a servicios |
24
27
  | `freematica_get_master_data` | (24 endpoints según `catalog`) | Devuelve un catálogo de datos maestros (tipos, geográficos, organizativos, inventario, financiero) |
25
28
  | `freematica_list_clientes` | `GET /pgrl/v2/clientes` | Lista paginada de clientes |
@@ -31,7 +34,7 @@ MCP server que expone operaciones del API REST de Freemática (ERP: facturación
31
34
  | `freematica_get_ficha_prev_cliente` | `GET /pprl/v2/ficha-prev-cliente` | Ficha PRL de un cliente |
32
35
  | `freematica_list_vigilancia_salud` | `GET /pprl/v1/vigilancia-salud` | Lista paginada de registros de Vigilancia de la Salud |
33
36
  | `freematica_get_vigilancia_salud` | `GET /pprl/v1/vigilancia-salud/{idreg}` | Detalle de un registro de Vigilancia de la Salud |
34
- | `freematica_list_personal` | `GET /pers/v2/personal` | Lista paginada de personas (RRHH) |
37
+ | `freematica_list_personal` | `GET /pers/v1/personal` | Lista paginada de personas (RRHH) |
35
38
  | `freematica_get_persona` | `GET /pers/v2/personal/{idreg}` | Detalle de una persona |
36
39
  | `freematica_list_calendarios` | `GET /pgrl/v1/calendarios` | Lista paginada de calendarios laborales |
37
40
  | `freematica_list_calendario_periodos` | `GET /pgrl/v1/calendarios/{idreg}/periodos` | Periodos de un calendario laboral |
@@ -65,6 +68,8 @@ MCP server que expone operaciones del API REST de Freemática (ERP: facturación
65
68
  | `freematica_get_servicio_contrato` | `GET /pvss/v2/contratos-servicios/{idReg}` | Detalle de un servicio de contrato |
66
69
  | `freematica_list_contratos_opcionales` | `GET /ppre/v2/contratos/opcionales` | Lista paginada de opcionales de contratos |
67
70
  | `freematica_get_contrato_opcionales` | `GET /ppre/v2/contratos/opcionales/{idReg}` | Detalle de un registro de opcionales |
71
+ | `freematica_list_localizaciones_envio_clientes` | `GET /pgrl/v2/localizaciones-envio-clientes` | Localizaciones de envío de clientes |
72
+ | `freematica_list_localizaciones_factura_clientes` | `GET /pgrl/v2/localizaciones-factura-clientes` | Localizaciones de factura de clientes |
68
73
 
69
74
  ### Tools de escritura (requieren `FREEMATICA_ENABLE_WRITES=true`)
70
75
 
@@ -82,6 +87,12 @@ Por defecto el servidor es de **solo lectura**. Con `FREEMATICA_ENABLE_WRITES=tr
82
87
  | `freematica_update_servicio_facturacion` | `PUT /pvss/v2/contratos/{id}/servicios-facturacion/{id}` | Datos de facturación del servicio (precios hora, forma de pago…) |
83
88
  | `freematica_create_contrato_opcionales` | `POST /ppre/v2/contratos/opcionales` | Alta de opcionales de contrato |
84
89
  | `freematica_update_contrato_opcionales` | `PUT /ppre/v2/contratos/opcionales/{idReg}` | Actualización de opcionales de contrato |
90
+ | `freematica_create_cliente` | `POST /pgrl/v2/clientes` | Alta de cliente (idReg derivado de grupo+código) |
91
+ | `freematica_update_cliente` | `PUT /pgrl/v2/clientes/{idReg}` | Actualización parcial de cliente (fetch+merge) |
92
+ | `freematica_create_contacto_cliente` | `POST /pgrl/v2/contactos-clientes` | Alta de contacto de cliente |
93
+ | `freematica_update_contacto_cliente` | `PUT /pgrl/v2/contactos-clientes/{idReg}` | Actualización parcial de contacto (fetch+merge) |
94
+ | `freematica_create_localizacion_cliente` | `POST /pgrl/v2/localizaciones-{tipo}-clientes` | Alta de localización (tipo: cobro/envio/factura/servicio) |
95
+ | `freematica_update_localizacion_cliente` | `PUT /pgrl/v2/localizaciones-{tipo}-clientes/{idReg}` | Actualización parcial de localización (fetch+merge) |
85
96
 
86
97
  ## Filtros tipados (FIQL interno)
87
98
 
@@ -97,8 +108,8 @@ freematica_list_cartera_clientes({
97
108
  estado: 'pendiente',
98
109
  });
99
110
 
100
- // El MCP construye internamente:
101
- // rquery=CARCL_EMP==0001;CARCL_FECDOC=ge=2026-01-01;CARCL_SITCAR==1
111
+ // El MCP construye internamente (valores siempre entre comillas simples):
112
+ // rquery=CARCL_EMP=='0001';CARCL_FECDOC=ge='2026-01-01';CARCL_SITCAR=='1'
102
113
  ```
103
114
 
104
115
  ### Ventajas del patrón
@@ -116,14 +127,16 @@ freematica_list_facturas_cabecera({
116
127
  empresa: '0001',
117
128
  traspasadoContabilidad: false,
118
129
  });
119
- // → rquery=FAC_CODEMP==0001;FAC_TRASP_CONTAB==0
130
+ // → rquery=FVC_CODEMP=='0001';FVC_TRASP_CONTAB=='0'
120
131
 
121
- // Proveedores activos que contienen "GARCIA" en el nombre:
132
+ // Proveedor por nombre EXACTO (el API no soporta búsqueda parcial: =lk=
133
+ // responde 400 y los wildcards % devuelven 0 resultados). El filtro activo
134
+ // de proveedores post-filtra las bajas en cliente (FIQL no tiene IS NULL):
122
135
  freematica_list_proveedores({
123
- nombre: 'GARCIA',
136
+ nombre: 'LEJIAS PONS S.A.',
124
137
  activo: true,
125
138
  });
126
- // → rquery=NOMBRE_PRO=lk=GARCIA;FECHA_BAJA==null
139
+ // → rquery=NOMBRE_PRO=='LEJIAS PONS S.A.'
127
140
  ```
128
141
 
129
142
  ## Modos de transporte
@@ -15,11 +15,29 @@
15
15
  * - `;` AND (combina expresiones)
16
16
  * - `,` OR (combina expresiones)
17
17
  *
18
+ * Quoting de valores: TODOS los valores escalares se emiten entre comillas
19
+ * simples (`CAMPO=='valor'`). El API de Freemática lo exige para columnas de
20
+ * texto y fecha (sin comillas responde 400 "Error al ejecutar sentencia" o
21
+ * ignora el filtro silenciosamente) y lo acepta también en columnas
22
+ * numéricas. Verificado empíricamente contra /pers/v1/personal,
23
+ * /part/v1/articulos, /pcon/v2/cuentas, /pven/v1/facturas-cabecera,
24
+ * /pcar/v1/cartera-clientes y /pgrl/v2/proveedores.
25
+ *
18
26
  * Caracteres que requieren escape en valores FIQL:
19
- * `;` `,` `(` `)` `"` `'` espacios → percent-encoding (%3B, %2C, %28, %29, %22, %27, %20)
27
+ * `;` `,` `(` `)` `"` `'` → percent-encoding (%3B, %2C, %28, %29, %22, %27)
20
28
  * `=` → %3D (evita ambigüedad con operadores FIQL del tipo `=op=`)
21
29
  * `!` → %21 (evita ambigüedad con el operador `!=`)
22
30
  * El `==` en un valor se convierte en `%3D%3D` automáticamente.
31
+ * El espacio NO se escapea: dentro de comillas simples el API lo acepta
32
+ * tal cual, y percent-encodearlo rompe el match (doble encoding al pasar
33
+ * la FIQL por URLSearchParams).
34
+ *
35
+ * LIMITACIÓN CONOCIDA: los valores que contienen caracteres reservados
36
+ * (comas, apóstrofes, paréntesis…) viajan percent-encoded dentro del quoting
37
+ * y el servidor los compara literalmente, así que un filtro por un valor con
38
+ * esos caracteres puede devolver 0 resultados (verificado con comas en
39
+ * DESC_ART; sin datos con apóstrofes para verificar alternativas). El escape
40
+ * se mantiene porque no escaparlos rompería la gramática FIQL (inyección).
23
41
  */
24
42
  /**
25
43
  * Operadores escalares soportados.
@@ -62,19 +80,19 @@ export type FiqlFilters = FiqlGroup | {
62
80
  * **Grupo plano** (se unen con AND):
63
81
  * ```ts
64
82
  * buildFiql({ COD_CLI: '123', ESTADO: 'activo' })
65
- * // → 'COD_CLI==123;ESTADO==activo'
83
+ * // → "COD_CLI=='123';ESTADO=='activo'"
66
84
  * ```
67
85
  *
68
86
  * **Operador explícito**:
69
87
  * ```ts
70
88
  * buildFiql({ IMPORTE: { op: 'gt', value: 1000 } })
71
- * // → 'IMPORTE=gt=1000'
89
+ * // → "IMPORTE=gt='1000'"
72
90
  * ```
73
91
  *
74
92
  * **Operador IN con array**:
75
93
  * ```ts
76
94
  * buildFiql({ COD_CLI: { op: 'in', value: ['A1', 'A2'] } })
77
- * // → 'COD_CLI=in=(A1,A2)'
95
+ * // → "COD_CLI=in=('A1','A2')"
78
96
  * ```
79
97
  *
80
98
  * **Composición AND/OR**:
@@ -82,19 +100,25 @@ export type FiqlFilters = FiqlGroup | {
82
100
  * buildFiql({
83
101
  * and: [{ EMPRESA: '1' }, { DELEGACION: 'MAD' }],
84
102
  * })
85
- * // → 'EMPRESA==1;DELEGACION==MAD'
103
+ * // → "EMPRESA=='1';DELEGACION=='MAD'"
86
104
  *
87
105
  * buildFiql({
88
106
  * or: [{ ESTADO: 'activo' }, { ESTADO: 'pendiente' }],
89
107
  * })
90
- * // → 'ESTADO==activo,ESTADO==pendiente'
108
+ * // → "ESTADO=='activo',ESTADO=='pendiente'"
91
109
  * ```
92
110
  *
111
+ * AVISO: la composición OR (`,`) responde 400 en los endpoints probados del
112
+ * API real (pers, part); para expresar "uno de varios valores" usar el
113
+ * operador `in`, que sí está soportado.
114
+ *
93
115
  * ### Reglas
116
+ * - Todos los valores escalares se emiten entre comillas simples.
94
117
  * - Los valores `undefined` se omiten silenciosamente.
95
118
  * - Si todos los filtros son `undefined` o el objeto está vacío → retorna `""`.
96
- * - Los caracteres reservados FIQL (`;`, `,`, `(`, `)`, `"`, `'`, espacio, `=`, `!`)
97
- * en los valores se percent-encodean automáticamente.
119
+ * - Los caracteres reservados FIQL (`;`, `,`, `(`, `)`, `"`, `'`, `=`, `!`)
120
+ * en los valores se percent-encodean automáticamente. El espacio va tal
121
+ * cual (protegido por el quoting).
98
122
  * - Las claves `and`/`or` sólo activan composición si su valor es un `Array`.
99
123
  * Si el valor es un string, number u otro tipo primitivo, se tratan como
100
124
  * nombres de campo ordinarios (ej. `{ and: 'val' }` → `AND==val`).
@@ -15,11 +15,29 @@
15
15
  * - `;` AND (combina expresiones)
16
16
  * - `,` OR (combina expresiones)
17
17
  *
18
+ * Quoting de valores: TODOS los valores escalares se emiten entre comillas
19
+ * simples (`CAMPO=='valor'`). El API de Freemática lo exige para columnas de
20
+ * texto y fecha (sin comillas responde 400 "Error al ejecutar sentencia" o
21
+ * ignora el filtro silenciosamente) y lo acepta también en columnas
22
+ * numéricas. Verificado empíricamente contra /pers/v1/personal,
23
+ * /part/v1/articulos, /pcon/v2/cuentas, /pven/v1/facturas-cabecera,
24
+ * /pcar/v1/cartera-clientes y /pgrl/v2/proveedores.
25
+ *
18
26
  * Caracteres que requieren escape en valores FIQL:
19
- * `;` `,` `(` `)` `"` `'` espacios → percent-encoding (%3B, %2C, %28, %29, %22, %27, %20)
27
+ * `;` `,` `(` `)` `"` `'` → percent-encoding (%3B, %2C, %28, %29, %22, %27)
20
28
  * `=` → %3D (evita ambigüedad con operadores FIQL del tipo `=op=`)
21
29
  * `!` → %21 (evita ambigüedad con el operador `!=`)
22
30
  * El `==` en un valor se convierte en `%3D%3D` automáticamente.
31
+ * El espacio NO se escapea: dentro de comillas simples el API lo acepta
32
+ * tal cual, y percent-encodearlo rompe el match (doble encoding al pasar
33
+ * la FIQL por URLSearchParams).
34
+ *
35
+ * LIMITACIÓN CONOCIDA: los valores que contienen caracteres reservados
36
+ * (comas, apóstrofes, paréntesis…) viajan percent-encoded dentro del quoting
37
+ * y el servidor los compara literalmente, así que un filtro por un valor con
38
+ * esos caracteres puede devolver 0 resultados (verificado con comas en
39
+ * DESC_ART; sin datos con apóstrofes para verificar alternativas). El escape
40
+ * se mantiene porque no escaparlos rompería la gramática FIQL (inyección).
23
41
  */
24
42
  // ---------------------------------------------------------------------------
25
43
  // Internals
@@ -47,7 +65,7 @@ const OP_MAP = {
47
65
  * `CAMPO==x=gt=0` → parser puede interpretar `x=gt=0` como sub-operador
48
66
  * `CAMPO==123==EVIL` → parser puede ver un doble operador
49
67
  */
50
- const FIQL_RESERVED_RE = /[;,()"' =!]/g;
68
+ const FIQL_RESERVED_RE = /[;,()"'=!]/g;
51
69
  const RESERVED_ENCODE_MAP = {
52
70
  ';': '%3B',
53
71
  ',': '%2C',
@@ -55,7 +73,6 @@ const RESERVED_ENCODE_MAP = {
55
73
  ')': '%29',
56
74
  '"': '%22',
57
75
  "'": '%27',
58
- ' ': '%20',
59
76
  '=': '%3D',
60
77
  '!': '%21',
61
78
  };
@@ -73,13 +90,18 @@ function escapeFiqlValue(raw) {
73
90
  return raw.replace(FIQL_RESERVED_RE, (ch) => RESERVED_ENCODE_MAP[ch] ?? ch);
74
91
  }
75
92
  /**
76
- * Convierte un valor primitivo a string FIQL escapado.
93
+ * Convierte un valor primitivo a string FIQL escapado y quoted.
94
+ *
95
+ * El valor SIEMPRE va entre comillas simples: es el formato que exige el
96
+ * API de Freemática para columnas de texto/fecha y que acepta también en
97
+ * columnas numéricas. Las comillas simples internas van percent-encoded
98
+ * (%27) para que no puedan cerrar el quoting.
77
99
  *
78
100
  * @param val - Primitivo (`string | number | boolean`).
79
- * @returns Representación FIQL del valor.
101
+ * @returns Representación FIQL del valor (ej. `'123'`).
80
102
  */
81
103
  function primitiveToFiql(val) {
82
- return escapeFiqlValue(String(val));
104
+ return `'${escapeFiqlValue(String(val))}'`;
83
105
  }
84
106
  /**
85
107
  * Genera una expresión FIQL simple para `campo operador valor`.
@@ -97,7 +119,7 @@ function buildExpression(key, fiqlValue) {
97
119
  const arr = Array.isArray(value) ? value : [value];
98
120
  if (arr.length === 0)
99
121
  return '';
100
- const encoded = arr.map((v) => escapeFiqlValue(String(v))).join(',');
122
+ const encoded = arr.map((v) => primitiveToFiql(v)).join(',');
101
123
  return `${key}${fiqlOp}(${encoded})`;
102
124
  }
103
125
  const scalar = Array.isArray(value) ? value[0] : value;
@@ -167,19 +189,19 @@ function isComposition(filters) {
167
189
  * **Grupo plano** (se unen con AND):
168
190
  * ```ts
169
191
  * buildFiql({ COD_CLI: '123', ESTADO: 'activo' })
170
- * // → 'COD_CLI==123;ESTADO==activo'
192
+ * // → "COD_CLI=='123';ESTADO=='activo'"
171
193
  * ```
172
194
  *
173
195
  * **Operador explícito**:
174
196
  * ```ts
175
197
  * buildFiql({ IMPORTE: { op: 'gt', value: 1000 } })
176
- * // → 'IMPORTE=gt=1000'
198
+ * // → "IMPORTE=gt='1000'"
177
199
  * ```
178
200
  *
179
201
  * **Operador IN con array**:
180
202
  * ```ts
181
203
  * buildFiql({ COD_CLI: { op: 'in', value: ['A1', 'A2'] } })
182
- * // → 'COD_CLI=in=(A1,A2)'
204
+ * // → "COD_CLI=in=('A1','A2')"
183
205
  * ```
184
206
  *
185
207
  * **Composición AND/OR**:
@@ -187,19 +209,25 @@ function isComposition(filters) {
187
209
  * buildFiql({
188
210
  * and: [{ EMPRESA: '1' }, { DELEGACION: 'MAD' }],
189
211
  * })
190
- * // → 'EMPRESA==1;DELEGACION==MAD'
212
+ * // → "EMPRESA=='1';DELEGACION=='MAD'"
191
213
  *
192
214
  * buildFiql({
193
215
  * or: [{ ESTADO: 'activo' }, { ESTADO: 'pendiente' }],
194
216
  * })
195
- * // → 'ESTADO==activo,ESTADO==pendiente'
217
+ * // → "ESTADO=='activo',ESTADO=='pendiente'"
196
218
  * ```
197
219
  *
220
+ * AVISO: la composición OR (`,`) responde 400 en los endpoints probados del
221
+ * API real (pers, part); para expresar "uno de varios valores" usar el
222
+ * operador `in`, que sí está soportado.
223
+ *
198
224
  * ### Reglas
225
+ * - Todos los valores escalares se emiten entre comillas simples.
199
226
  * - Los valores `undefined` se omiten silenciosamente.
200
227
  * - Si todos los filtros son `undefined` o el objeto está vacío → retorna `""`.
201
- * - Los caracteres reservados FIQL (`;`, `,`, `(`, `)`, `"`, `'`, espacio, `=`, `!`)
202
- * en los valores se percent-encodean automáticamente.
228
+ * - Los caracteres reservados FIQL (`;`, `,`, `(`, `)`, `"`, `'`, `=`, `!`)
229
+ * en los valores se percent-encodean automáticamente. El espacio va tal
230
+ * cual (protegido por el quoting).
203
231
  * - Las claves `and`/`or` sólo activan composición si su valor es un `Array`.
204
232
  * Si el valor es un string, number u otro tipo primitivo, se tratan como
205
233
  * nombres de campo ordinarios (ej. `{ and: 'val' }` → `AND==val`).
@@ -1 +1 @@
1
- {"version":3,"file":"fiql-builder.js","sourceRoot":"","sources":["../../src/clients/fiql-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fiql-builder.js","sourceRoot":"","sources":["../../src/clients/fiql-builder.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { type MasterDataCatalog } from '../schemas/master-data.js';
3
3
  import { type ListCarteraFilters } from '../schemas/cartera.js';
4
4
  import type { ListFacturasCabeceraFilters, ListFacturaLineasFilters, ListFacturaIvaFilters, ListFacturaVencimientosFilters } from '../schemas/facturas-ventas.js';
5
5
  import { type ListPedidosCompraFilters } from '../schemas/pedidos-compras.js';
6
+ import { type LocalizacionTipo } from '../schemas/localizaciones.js';
6
7
  import type { Cliente } from '../types/clientes.js';
7
8
  import type { ContactoCliente } from '../types/contactos-clientes.js';
8
9
  import type { MasterDataItem } from '../types/master-data.js';
@@ -36,6 +37,64 @@ export declare class FreematicaClient extends BaseClient {
36
37
  * Endpoint: GET /pvss/v2/contratos-servicios-material
37
38
  */
38
39
  getMaterialesAsignadosServicios(): Promise<ListResult<VoContratosServMatAsignado>>;
40
+ /**
41
+ * Lista paginada de artículos del catálogo de inventario.
42
+ *
43
+ * Endpoint: GET /part/v1/articulos
44
+ *
45
+ * Todos los filtros son de coincidencia EXACTA (el endpoint no soporta
46
+ * búsqueda parcial: =lk= responde 400 y los wildcards % devuelven 0
47
+ * resultados — verificado contra el API real). OJO: COD_ARTICULO puede
48
+ * llevar espacios iniciales en Freemática (ej. " QQ10615") que forman
49
+ * parte del código.
50
+ *
51
+ * El filtro `activo` mapea a MOTIVO_BAJA (columna de texto — las columnas
52
+ * de fecha no permiten comparar con vacío):
53
+ * - `true` → MOTIVO_BAJA=='' (sin motivo de baja).
54
+ * - `false` → MOTIVO_BAJA!='' (con motivo de baja).
55
+ * Los artículos con MOTIVO_BAJA nulo (≈36 de 6304 en producción) no
56
+ * matchean ninguno de los dos valores.
57
+ *
58
+ * @param opts - Paginación y filtros opcionales.
59
+ * @returns Lista paginada de artículos (cada item incluye `idReg`).
60
+ */
61
+ listArticulos(opts: {
62
+ page?: number;
63
+ items?: number;
64
+ codArticulo?: string;
65
+ tipoCodigo?: string;
66
+ codProveedor?: string;
67
+ linea?: string;
68
+ familia?: string;
69
+ subfamilia?: string;
70
+ descripcion?: string;
71
+ codigoBarras?: string;
72
+ activo?: boolean;
73
+ }): Promise<ListResult<Record<string, unknown>>>;
74
+ /**
75
+ * Detalle de un artículo por `idReg` opaco.
76
+ *
77
+ * Endpoint: GET /part/v1/articulos/{idreg}
78
+ *
79
+ * El API devuelve un envelope de LISTA con un único item (verificado contra
80
+ * el API real), no un objeto detalle; este método lo desenvuelve.
81
+ *
82
+ * @param idReg - Identificador opaco (base64) del artículo.
83
+ * @returns Objeto con todos los campos del artículo.
84
+ */
85
+ getArticulo(idReg: string): Promise<Record<string, unknown>>;
86
+ /**
87
+ * Precios de venta de un artículo por `idReg` opaco.
88
+ *
89
+ * Endpoint: GET /pgrl/v1/precio-articulo/{idreg}
90
+ *
91
+ * Devuelve un objeto con PRECIO_VENTA, DESCUENTO y FACTURABLE.
92
+ *
93
+ * @param idReg - Identificador opaco (base64) del artículo (el mismo que
94
+ * devuelve freematica_list_articulos).
95
+ * @returns Objeto de precios del artículo.
96
+ */
97
+ getPrecioArticulo(idReg: string): Promise<Record<string, unknown>>;
39
98
  /**
40
99
  * Obtener un catálogo de datos maestros.
41
100
  */
@@ -101,23 +160,13 @@ export declare class FreematicaClient extends BaseClient {
101
160
  *
102
161
  * Endpoint: GET /pprl/v1/vigilancia-salud
103
162
  *
104
- * `idRegPersona` se envía como query param nativo. El resto de filtros se
105
- * codifican en FIQL y se envían como `rquery`.
106
- *
107
- * @param opts - Opciones de paginación y filtrado.
163
+ * @param opts - Paginación y filtro opcional idRegPersona.
108
164
  * @returns Lista paginada de registros VS.
109
165
  */
110
166
  listVigilanciaSalud(opts: {
111
167
  page?: number;
112
168
  items?: number;
113
169
  idRegPersona?: string;
114
- empresa?: string;
115
- delegacion?: string;
116
- codPersona?: string;
117
- tipoRevision?: string;
118
- resultado?: string;
119
- fechaCitaDesde?: string;
120
- fechaCitaHasta?: string;
121
170
  }): Promise<ListResult<Record<string, unknown>>>;
122
171
  /**
123
172
  * Lista de cuentas analíticas.
@@ -139,12 +188,11 @@ export declare class FreematicaClient extends BaseClient {
139
188
  /**
140
189
  * Lista paginada de personas (empleados) con filtros FIQL opcionales.
141
190
  *
142
- * Endpoint: GET /pers/v2/personal
191
+ * Endpoint: GET /pers/v1/personal
143
192
  *
144
- * El filtro `activo` (boolean) se traduce a `VSSPER_ACTIVO==S` (true) o
145
- * `VSSPER_ACTIVO==N` (false). Las búsquedas por `nombre` y `apellido` usan
146
- * el operador de igualdad estándar FIQL (el servidor aplica LIKE internamente
147
- * para estos campos).
193
+ * Todos los filtros son de coincidencia EXACTA: el endpoint no soporta
194
+ * búsqueda parcial (=lk= responde 400 y los wildcards % / * devuelven 0
195
+ * resultados verificado contra el API real).
148
196
  *
149
197
  * @param opts - Opciones de paginación y filtrado.
150
198
  * @returns Lista paginada de personas.
@@ -161,14 +209,18 @@ export declare class FreematicaClient extends BaseClient {
161
209
  situacion?: string;
162
210
  departamento?: string;
163
211
  seccion?: string;
164
- activo?: boolean;
165
212
  }): Promise<ListResult<Record<string, unknown>>>;
166
213
  /**
167
- * Detalle de una persona por `idReg` opaco.
214
+ * Detalle de una persona por su `idReg` opaco.
168
215
  *
169
- * Endpoint: GET /pers/v2/personal/{idreg}
216
+ * Endpoint: GET /pers/v1/personal/{idreg}
170
217
  *
171
- * @param idReg - Identificador opaco de la persona.
218
+ * v1, igual que el listado: garantiza que todo idReg devuelto por
219
+ * freematica_list_personal funciona aquí (la vista v2 es un subconjunto
220
+ * de sincronización incremental). El API devuelve un envelope de LISTA
221
+ * con un único item (verificado contra el API real); se desenvuelve.
222
+ *
223
+ * @param idReg - Identificador opaco (base64) de la persona.
172
224
  * @returns Objeto con todos los campos de la persona.
173
225
  */
174
226
  getPersona(idReg: string): Promise<Record<string, unknown>>;
@@ -237,12 +289,11 @@ export declare class FreematicaClient extends BaseClient {
237
289
  * Construye la FIQL a partir de los filtros tipados y la añade como `rquery`
238
290
  * usando `appendRquery()` (patrón canónico del foundation TD-117).
239
291
  *
240
- * El filtro `soloImpagados=true` genera `CARCL_FECIMPAG!=null`, donde el
241
- * valor `'null'` es la convención centinela de Freemática para indicar "sin
242
- * valor" en campos de fecha opcionales (assumption empírica: observado en
243
- * datos reales de la API; documentado para futuras implementaciones).
244
- * El operador `ne` se pasa vía `buildFiql` para garantizar escaping
245
- * consistente con el resto de filtros.
292
+ * El filtro `soloImpagados=true` genera `CARCL_FECIMPAG=ge='1900-01-01'`
293
+ * (cualquier fecha de impago con valor). El FIQL de Freemática no tiene
294
+ * IS NOT NULL: `!=null` devuelve 0 resultados silenciosamente y `!='null'`
295
+ * responde 500 (verificado contra el API real; con este rango devuelve
296
+ * 382 impagados de 72054 documentos).
246
297
  *
247
298
  * El filtro `estado` mapea a los valores numéricos de `CARCL_SITCAR`
248
299
  * (1=pendiente, 2=cancelado, 3=derivado).
@@ -314,13 +365,16 @@ export declare class FreematicaClient extends BaseClient {
314
365
  /**
315
366
  * Lista paginada de proveedores con filtros FIQL.
316
367
  *
317
- * El filtro `activo` mapea a FECHA_BAJA:
318
- * - `true` → FECHA_BAJA es nula (proveedor activo). Se usa el operador `=is-null=true` si el
319
- * API lo soporta; como fallback se omite el filtro y se filtra post-process.
320
- * En Freemática el convenio estándar es: activo=true → `FECHA_BAJA==null` (FIQL `==null`).
321
- * - `false` FECHA_BAJA tiene valor (proveedor de baja).
368
+ * El filtro `activo` mapea a FECHA_BAJA. El API no soporta IS NULL en FIQL
369
+ * (`==null` devuelve 0 resultados y `=='null'` responde 500 verificado
370
+ * contra el API real), así que:
371
+ * - `false` → `FECHA_BAJA=ge='1900-01-01'` (cualquier fecha de baja).
372
+ * - `true` sin filtro server-side; las bajas se descartan post-process
373
+ * sobre la página recibida (FECHA_BAJA con valor). El `total`
374
+ * devuelto es el del dataset sin filtrar.
322
375
  *
323
- * El filtro `nombre` usa operador FIQL `=lk=` para búsqueda parcial (LIKE).
376
+ * El filtro `nombre` es coincidencia EXACTA: el operador `=lk=` responde
377
+ * 400 en este endpoint y los wildcards % devuelven 0 resultados.
324
378
  *
325
379
  * Endpoint: GET /pgrl/v2/proveedores
326
380
  */
@@ -377,7 +431,11 @@ export declare class FreematicaClient extends BaseClient {
377
431
  * Lista paginada de localizaciones de servicio de clientes.
378
432
  *
379
433
  * Filtros soportados: codCliente (COD_CLI), grupoCliente (GRUPO_CLI), codPais (COD_PAIS),
380
- * codProvincia (COD_PROVINCIA), representante (COD_REPRES), activo (FECHA_BAJA nulo/no nulo).
434
+ * codProvincia (COD_PROVINCIA), representante (COD_REPRES).
435
+ *
436
+ * La vista NO tiene columna FECHA_BAJA (filtrar por ella responde 400
437
+ * "Error en rquery" — verificado contra el API real), así que no existe
438
+ * filtro activo/baja en este recurso.
381
439
  *
382
440
  * Endpoint: GET /pgrl/v2/localizaciones-servicio-clientes
383
441
  */
@@ -387,7 +445,6 @@ export declare class FreematicaClient extends BaseClient {
387
445
  codPais?: string;
388
446
  codProvincia?: string;
389
447
  representante?: string;
390
- activo?: boolean;
391
448
  }): Promise<ListResult<Record<string, unknown>>>;
392
449
  /**
393
450
  * Detalle de una factura de ventas (cabecera) por `idReg` opaco.
@@ -790,6 +847,80 @@ export declare class FreematicaClient extends BaseClient {
790
847
  * Nivel debug: body completo, para poder reconstruir la operación.
791
848
  */
792
849
  private logWrite;
850
+ /**
851
+ * Alta de cliente.
852
+ *
853
+ * Endpoint: POST /pgrl/v2/clientes — body VoClientes.
854
+ * Requeridos por el API: idReg, COD_GRUPO_CLI, COD_CLI, NOMBRE_CLI, NIF,
855
+ * TIPO_IMPTO, COD_DIVISA, TIPO_FACT.
856
+ */
857
+ createCliente(body: Record<string, unknown>): Promise<Record<string, unknown>>;
858
+ /**
859
+ * Actualización de cliente.
860
+ *
861
+ * Endpoint: PUT /pgrl/v2/clientes/{idReg} — body VoClientes completo
862
+ * (el caller hace fetch+merge antes de llamar).
863
+ */
864
+ updateCliente(idReg: string, body: Record<string, unknown>): Promise<Record<string, unknown>>;
865
+ /**
866
+ * Detalle de un contacto de cliente por `idReg` opaco.
867
+ *
868
+ * Endpoint: GET /pgrl/v1/contactos-clientes/{idreg}
869
+ * (v2 solo expone el listado; el singular es v1 pero devuelve las mismas
870
+ * columnas CC_*). Se usa en el fetch+merge del update.
871
+ */
872
+ getContactoCliente(idReg: string): Promise<Record<string, unknown>>;
873
+ /**
874
+ * Alta de contacto de cliente.
875
+ *
876
+ * Endpoint: POST /pgrl/v2/contactos-clientes — body VoContactosClientes.
877
+ * Requeridos por el API: CC_GRUPO_CLI, CC_CLI.
878
+ */
879
+ createContactoCliente(body: Record<string, unknown>): Promise<Record<string, unknown>>;
880
+ /**
881
+ * Actualización de contacto de cliente.
882
+ *
883
+ * Endpoint: PUT /pgrl/v2/contactos-clientes/{idReg}.
884
+ */
885
+ updateContactoCliente(idReg: string, body: Record<string, unknown>): Promise<Record<string, unknown>>;
886
+ /**
887
+ * Detalle de una localización de cliente por tipo e `idReg` opaco.
888
+ *
889
+ * Usa el GET singular v2 del tipo (v1 para factura, que no tiene v2; las
890
+ * columnas son las mismas). Se emplea en el fetch+merge de los updates.
891
+ */
892
+ getLocalizacionCliente(tipo: LocalizacionTipo, idReg: string): Promise<Record<string, unknown>>;
893
+ /**
894
+ * Lista paginada de localizaciones de envío de clientes.
895
+ *
896
+ * Endpoint: GET /pgrl/v2/localizaciones-envio-clientes
897
+ */
898
+ listLocalizacionesEnvioClientes(opts?: ListOptions & {
899
+ codCliente?: string;
900
+ grupoCliente?: string;
901
+ }): Promise<ListResult<Record<string, unknown>>>;
902
+ /**
903
+ * Lista paginada de localizaciones de factura de clientes.
904
+ *
905
+ * Endpoint: GET /pgrl/v1/localizaciones-factura-clientes
906
+ * (la lista solo existe en v1; el v2 de este recurso es solo POST/PUT).
907
+ */
908
+ listLocalizacionesFacturaClientes(opts?: ListOptions & {
909
+ codCliente?: string;
910
+ grupoCliente?: string;
911
+ }): Promise<ListResult<Record<string, unknown>>>;
912
+ /**
913
+ * Alta de localización de cliente (cobro, envío, factura o servicio).
914
+ *
915
+ * Endpoint: POST /pgrl/v2/localizaciones-{tipo}-clientes — body Vo del tipo.
916
+ */
917
+ createLocalizacionCliente(tipo: LocalizacionTipo, body: Record<string, unknown>): Promise<Record<string, unknown>>;
918
+ /**
919
+ * Actualización de localización de cliente (cobro, envío, factura o servicio).
920
+ *
921
+ * Endpoint: PUT /pgrl/v2/localizaciones-{tipo}-clientes/{idReg}.
922
+ */
923
+ updateLocalizacionCliente(tipo: LocalizacionTipo, idReg: string, body: Record<string, unknown>): Promise<Record<string, unknown>>;
793
924
  private listResource;
794
925
  /**
795
926
  * Helper genérico para endpoints de lista que soportan paginación + filtros FIQL