nexusflex-mcp 3.73.0 → 3.74.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.
- package/.claude-plugin/plugin.json +1 -1
- package/api.mjs +2 -1
- package/docs.mjs +6 -4
- package/package.json +1 -1
- package/server.mjs +29 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexusflex",
|
|
3
3
|
"description": "Nexus Flex en Claude: el MCP (altas, consultas, control por foto; nunca mueve dinero) y las skills (control por foto) en un solo instalable.",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.74.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Nexus Flex",
|
|
7
7
|
"url": "https://nexusflex.com.ar"
|
package/api.mjs
CHANGED
|
@@ -52,7 +52,8 @@ if (EMAIL && PASSWORD && !/^https:\/\//i.test(API_URL)) {
|
|
|
52
52
|
// Ninguna paga, cobra ni transfiere: excluir/reincluir un envío de una liquidación (con
|
|
53
53
|
// motivo) y ver/preparar los datos de facturación de un cliente (no emite comprobantes).
|
|
54
54
|
const OPERACIONES_OK = [
|
|
55
|
-
{ metodo: "POST", ruta: /^\/liquidaciones\/anteriores\/\d+\/(excluir|reincluir)\/?$/i },
|
|
55
|
+
{ metodo: "POST", ruta: /^\/liquidaciones\/anteriores\/\d+\/(excluir|reincluir|cobro-parcial)\/?$/i },
|
|
56
|
+
{ metodo: "PUT", ruta: /^\/liquidaciones\/observaciones\/\d+\/?$/i },
|
|
56
57
|
{ metodo: "GET", ruta: /^\/afip\/estado\/?$/i },
|
|
57
58
|
{ metodo: "POST", ruta: /^\/afip\/preparar-cliente\/?$/i },
|
|
58
59
|
];
|
package/docs.mjs
CHANGED
|
@@ -152,14 +152,14 @@ const GROUPS = [
|
|
|
152
152
|
{ titulo: "Control por foto (staff)", tools: ["control_foto_preparar", "control_foto_estructura", "control_foto_carpeta", "control_foto_foto"] },
|
|
153
153
|
{ titulo: "Env\xEDos (staff)", tools: ["envio_cargar", "envio_desde_etiqueta_ml", "envio_procesar", "envio_entregar", "envio_estado", "envios_trabados", "planilla_reporte", "envio_asignar_grupo", "nodo_provisorio_crear", "provisorio_conciliar", "envio_reasignar_cliente", "envio_mensajero_externo", "envio_editar_zona", "envio_editar_fecha", "cobro_corregir", "sin_vendedor", "asignar_sin_vendedor", "envio_completar_ciclo", "envio_pago_mensajero", "envio_corregir_estado", "envio_asignar_mensajero"] },
|
|
154
154
|
{ titulo: "Colecta y zonas (staff)", tools: ["colecta_ver", "colecta_pendientes", "colecta_historial", "colecta_configurar", "colecta_fija", "colecta_asignar", "colecta_desasignar", "zonas_reparto", "zona_barrios", "zonas_simetria", "asignar_mensajero_zona", "asignar_nodo_zona", "envios_por_zona", "procesar_zona", "rechazar_zona", "grupos_tarifas", "nodo_alias_poner", "zona_dejar", "nodo_link_confirmacion", "zonas_grupo", "zona_mover_metazona", "zona_componer_grupo", "grupo_tarifa_set", "retiros_cargar"] },
|
|
155
|
-
{ titulo: "Rendiciones y reclamos", tools: ["rendiciones", "rendicion_revertir", "reclamos_listar"] },
|
|
155
|
+
{ titulo: "Rendiciones y reclamos", tools: ["rendiciones", "rendicion_revertir", "reclamos_listar", "reclamo_responder"] },
|
|
156
156
|
{ titulo: "Marketplace de rutas", tools: ["rutas_publicas", "mis_rutas", "ruta_ofertas", "ruta_publicar", "ruta_ofertar", "ruta_adjudicar"] },
|
|
157
157
|
{ titulo: "Afiliados", tools: ["afiliacion_listar", "comisiones_afiliado_ver", "afiliado_crear", "afiliacion_crear", "afiliacion_editar", "comision_liquidar"] },
|
|
158
158
|
{ titulo: "M\xE9tricas / KPIs", tools: ["kpi_nodo", "kpi_red", "metricas_por_tipo", "top_productos"] },
|
|
159
159
|
{ titulo: "WMS del nodo", tools: ["stock_nodo", "productos_nodo", "producto_crear"] },
|
|
160
160
|
{ titulo: "Gesti\xF3n del nodo", tools: ["clientes_del_nodo", "cliente_crear", "cliente_editar", "sucursales_cliente", "sucursal_perfil", "precios_ver", "precio_actualizar", "cuentas_vinculadas", "generar_enlace_vinculacion", "facturacion_estado", "facturacion_preparar_cliente"] },
|
|
161
161
|
{ titulo: "Marketing / atribuci\xF3n", tools: ["marketing_config_ver", "marketing_config_guardar"] },
|
|
162
|
-
{ titulo: "Liquidaciones", tools: ["liquidacion_buscar", "liquidacion_detalle", "liquidaciones_sin_recibir", "liquidacion_excluir_envio", "liquidacion_reincluir_envio", "cuenta_semanal_nodos"] },
|
|
162
|
+
{ titulo: "Liquidaciones", tools: ["liquidacion_buscar", "liquidacion_detalle", "liquidaciones_sin_recibir", "liquidacion_excluir_envio", "liquidacion_reincluir_envio", "liquidacion_cobro_parcial", "cuenta_semanal_nodos"] },
|
|
163
163
|
{ titulo: "Usuarios / choferes", tools: ["chofer_listar", "chofer_crear", "chofer_editar", "usuario_editar", "operador_crear", "cliente_generar_usuario", "cliente_resetear_clave", "usuario_habilitar_reparto"] },
|
|
164
164
|
{ titulo: "Administraci\xF3n (red)", tools: ["nodos_listar", "nodo_crear", "usuario_habilitar_rol", "grupo_crear", "logo_subir", "sugerencias_listar", "cierre_semanal_links", "nodo_renombrar", "grupo_miembros", "grupo_sumar_nodo", "grupo_expulsar_nodo", "grupo_admin_permiso"] }
|
|
165
165
|
];
|
|
@@ -170,7 +170,7 @@ const TOOL_DOCS = {
|
|
|
170
170
|
liquidacion_excluir_envio: { "que": "Saca un env\xEDo del cobro de una liquidaci\xF3n YA emitida y re-suma el total.", "uso": "id (liquidaci\xF3n), tracking (del env\xEDo a excluir), motivo (obligatorio, m\xEDnimo 10 caracteres, lo ve el vendedor). Requiere permiso finanzas. Si esa liquidaci\xF3n ya est\xE1 en una factura ARCA emitida, la rechaza (har\xEDa falta nota de cr\xE9dito).", "ej": "liquidacion_excluir_envio id:1234 tracking:'NFABC123' motivo:'el nodo no lo entreg\xF3, qued\xF3 en el centro'.", "no": "No emite nota de cr\xE9dito: si la liquidaci\xF3n ya est\xE1 en una factura de ARCA emitida, lo rechaza. Re-suma la liquidaci\xF3n y ajusta la cuenta corriente del vendedor (no es un pago ni un cobro)." },
|
|
171
171
|
liquidacion_reincluir_envio: { "que": "Lo inverso de liquidacion_excluir_envio: devuelve al cobro un env\xEDo que se hab\xEDa excluido.", "uso": "id (liquidaci\xF3n), tracking (del env\xEDo a reincluir), motivo (obligatorio, m\xEDnimo 10 caracteres, ej. 'el nodo s\xED lo entreg\xF3, hay foto'). Requiere permiso finanzas. Mismo guard de factura emitida.", "ej": "liquidacion_reincluir_envio id:1234 tracking:'NFABC123' motivo:'verif con el nodo, s\xED lo entreg\xF3'.", "no": "Mismo cuidado que excluir: si la liquidaci\xF3n ya est\xE1 facturada en ARCA, lo rechaza. Re-suma y ajusta la cuenta corriente; no es un pago ni un cobro." },
|
|
172
172
|
cuenta_semanal_nodos: { "que": "La cuenta de TU nodo con cada nodo con el que se pasaron paquetes por un grupo (de lunes a s\xE1bado que se congela el mi\xE9rcoles siguiente).", "uso": "Sin par\xE1metros lista lo que est\xE1 EN VIVO, a\xFAn no cerrado. Con `cierre` (id): ese cierre congelado. Con `lista:true`: tus cierres semanales con su neto. Admin global: `nodo` para elegir/acotar el nodo.", "ej": "cuenta_semanal_nodos lista:true \u2192 ves tus cierres; cuenta_semanal_nodos cierre:100 \u2192 ese cierre congelado con el detalle por nodo.", "no": "No cierra semanas (se cierran solas); no mueve dinero." },
|
|
173
|
-
cierre_semanal_links: { "que": "Para cada nodo de un cierre semanal, el link
|
|
173
|
+
cierre_semanal_links: { "que": "Para cada nodo de un cierre semanal, el link de su cuenta: si el nodo no tiene usuario lo da de alta (mail, contrase\xF1a, nombre, apellido; una sola vez por nodo) y si ya tiene, lo manda a entrar. La cuenta se ve adentro, en Saldos con otros nodos.", "uso": "Opcional cierre (id del cierre; default: el \xFAltimo). Devuelve primero los nodos SIN usuario: a esos pas\xE1selo por WhatsApp. Solo admin global.", "ej": "cierre_semanal_links cierre:100 \u2192 recib\xEDs los links de todos los nodos para mandarles por WhatsApp.", "no": "No env\xEDa por WhatsApp (solo genera el link); el link ya no muestra la cuenta sin login." },
|
|
174
174
|
nodo_renombrar: { "que": "Cambia la raz\xF3n social (nombre real) de un nodo \u2014 lo ve TODO el mundo.", "uso": "nodo (nombre actual o tu apodo), nombreNuevo (nombre nuevo). Solo admin global. No toca dinero.", "ej": "nodo_renombrar nodo:'FastCorreo' nombreNuevo:'FastCorreo Log\xEDstica'.", "no": "No es un apodo personal (para eso us\xE1 nodo_alias_poner); la cambio es global." },
|
|
175
175
|
grupos_tarifas: { "que": "Los grupos log\xEDsticos de tu nodo (admin global: todos) con los nodos que los integran y la TARIFA de clearing por zona de cada uno.", "uso": "Sin par\xE1metros. Admin global: cualquier nodo; operador: sus grupos. Es lo que mir\xE1s para auditar por qu\xE9 un traspaso entre nodos se cobr\xF3 lo que se cobr\xF3.", "ej": "grupos_tarifas \u2192 ves Bonorino, Portela, etc. con sus nodos y cu\xE1nto cobra cada zona.", "no": "No modifica tarifas (para eso us\xE1 grupo_tarifa_set); solo lectura." },
|
|
176
176
|
nodo_alias_poner: { "que": "Le pon\xE9s TU propio apodo a un nodo para reconocerlo m\xE1s f\xE1cil \u2014 es personal.", "uso": "nodo (nombre actual o tu apodo), alias (el apodo nuevo; vac\xEDo para sacarlo). Pod\xE9s usar ese apodo en cualquier herramienta que pida un nodo.", "ej": `nodo_alias_poner nodo:'Log\xEDstica Portela' alias:'RL Zona Sur' \u2192 de ah\xED en m\xE1s pod\xE9s decir 'asignar_nodo_zona nodo:"RL Zona Sur"'.`, "no": "No es un cambio global (nodo_renombrar s\xED); solo te lo ve a vos." },
|
|
@@ -244,7 +244,9 @@ const TOOL_DOCS = {
|
|
|
244
244
|
rechazar_zona: { que: "RECHAZA env\xEDos ruteados por zona: dejan de aparecerte y quedan para origen u otros nodos de la zona.", uso: "envioIds (de envios_por_zona); motivo opcional. Admin global: `nodo` para elegir/acotar el nodo.", ej: "rechazar_zona envioIds:[103] motivo:'fuera de mi cobertura'.", no: "No cambia el estado del env\xEDo." },
|
|
245
245
|
rendiciones: { que: "Estado de rendiciones: cobros/cambios/devoluciones a recuperar o rendir, con totales y qui\xE9n tiene cada uno.", uso: "Sin par\xE1metros. Scopeado a tu alcance (vendedor: lo tuyo; nodo: tu nodo; mensajero: lo suyo).", ej: "rendiciones \u2192 cu\xE1nto falta que rinda cada cadete.", no: "No confirma ni revierte (rendicion_revertir); NO incluye rutas de marketplace adjudicadas (ver ayuda tema:facturacion_marketplace)." },
|
|
246
246
|
rendicion_revertir: { que: "Revierte un cobro/cambio marcado como 'rendido' por error \u2192 vuelve a 'a rendir'.", uso: "envioId + tipo (cobro|cambio); motivo opcional. Deja registro.", ej: "rendicion_revertir envioId:987 tipo:cobro motivo:'se marc\xF3 sin recibir'.", no: "No mueve dinero en cuentas; corrige el estado de la rendici\xF3n." },
|
|
247
|
-
reclamos_listar: { que: "Reclamos abiertos de clientes ligados a liquidaciones/rendiciones (tipo, estado, trackings en disputa).", uso: "estado opcional (abierto|resuelto). Vendedor: lo suyo; operador: su nodo.", ej: "reclamos_listar estado:abierto \u2192 qu\xE9 cobros est\xE1n en disputa.", no: "No
|
|
247
|
+
reclamos_listar: { que: "Reclamos abiertos de clientes ligados a liquidaciones/rendiciones (tipo, estado, trackings en disputa).", uso: "estado opcional (abierto|resuelto). Vendedor: lo suyo; operador: su nodo.", ej: "reclamos_listar estado:abierto \u2192 qu\xE9 cobros est\xE1n en disputa.", no: "No responde ni cierra: para eso `reclamo_responder`." },
|
|
248
|
+
liquidacion_cobro_parcial: { que: "Cobro en destino PARCIAL: lo que el comprador pag\xF3 en destino se da por cobrado y el env\xEDo sigue en la liquidaci\xF3n por la diferencia (flete \u2212 cobrado).", uso: "id (liquidaci\xF3n), tracking, montoCobrado (lo cobrado en destino, ARS; 0 quita el ajuste), motivo (obligatorio, m\xEDnimo 10 caracteres, lo lee el vendedor). Rechaza si ya hay factura de ARCA emitida y los viajes especiales.", ej: 'liquidacion_cobro_parcial id:4278 tracking:NFxxxx montoCobrado:4611 motivo:"Zona media cobrada como cercana" \u2192 el env\xEDo pasa de $7.371 a $2.760.', no: "No sirve si lo cobrado cubre todo el flete (us\xE1 liquidacion_excluir_envio) ni mueve dinero." },
|
|
249
|
+
reclamo_responder: { que: "Responde (y opcionalmente cierra o reabre) el reclamo que un vendedor dej\xF3 sobre su liquidaci\xF3n; la respuesta la lee en su portal.", uso: "id (del reclamo, de reclamos_listar), respuesta (texto para el vendedor), cerrar:true para dejarlo resuelto o reabrir:true para volverlo a abierto. Requiere permiso finanzas; solo reclamos de tu nodo.", ej: 'Primero liquidacion_excluir_envio con motivo, despu\xE9s reclamo_responder id:18 respuesta:"Se descontaron 4 env\xEDos, nuevo total $68.420" cerrar:true.', no: "No corrige montos (eso es excluir/reincluir) ni mueve dinero." },
|
|
248
250
|
rutas_publicas: { que: "Publicaciones ABIERTAS de toda la red que tu nodo puede tomar (con cu\xE1ntas ofertas tiene cada una). Marca las tuyas con esMia.", uso: "Sin par\xE1metros.", ej: "rutas_publicas \u2192 ver qu\xE9 rutas hay para ofertar.", no: "No oferta (ruta_ofertar)." },
|
|
249
251
|
mis_rutas: { que: "Tus publicaciones (con estado/adjudicaci\xF3n: nodoToma y precioAcordado) y las ofertas que hiciste a otros.", uso: "Sin par\xE1metros.", ej: "mis_rutas \u2192 ver si tu ruta se adjudic\xF3 y a qui\xE9n.", no: "El precioAcordado es la obligaci\xF3n registrada, NO un asiento de facturaci\xF3n (ver ayuda tema:facturacion_marketplace)." },
|
|
250
252
|
ruta_ofertas: { que: "Ofertas recibidas en una publicaci\xF3n TUYA, de la m\xE1s barata a la m\xE1s cara. Solo el que public\xF3.", uso: "publicacionId. Los ids de oferta sirven para adjudicar.", ej: "ruta_ofertas publicacionId:12 \u2192 eleg\xEDs la mejor y su ofertaId.", no: "No adjudica (ruta_adjudicar)." },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexusflex-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.74.0",
|
|
4
4
|
"description": "MCP de Nexus Flex: operá tu nodo/cuenta desde un asistente de IA (altas de clientes, stock, KPIs). Login por autorización web (device-flow). NO toca dinero.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/server.mjs
CHANGED
|
@@ -56,8 +56,9 @@ const ALLOW_PRECIOS = truthy(process.env.NEXUSFLEX_MCP_ALLOW_PRECIOS);
|
|
|
56
56
|
|
|
57
57
|
// ATADO CON: backend/src/services/mcp-remote.ts (MCP_VERSION + NOVEDADES + mismos tools, salvo SOLO_REMOTO)
|
|
58
58
|
// y mcp/package.json. Lo verifica backend/src/coherencia.test.ts. Ver CLAUDE.md → "Cosas que van juntas".
|
|
59
|
-
const MCP_VERSION = "3.
|
|
59
|
+
const MCP_VERSION = "3.74.0"; // bumpear junto con package.json + backend/services/mcp-remote.ts
|
|
60
60
|
const NOVEDADES = [
|
|
61
|
+
"3.74.0 — RECLAMOS DE VENDEDORES: nuevo `reclamo_responder` (responder, cerrar o reabrir el reclamo que un vendedor dejó sobre su liquidación; la respuesta la lee en su portal). Se usa junto con `liquidacion_excluir_envio` / `liquidacion_reincluir_envio`: primero corregís el cobro, después contestás con el nuevo total. Es lo mismo que la pantalla Reclamos de vendedores. Además `liquidacion_cobro_parcial`: cuando el comprador pagó en destino MENOS que el flete (ej. zona media cobrada como cercana), lo cobrado se da por pagado y el envío sigue en la liquidación por la diferencia; con `montoCobrado` 0 se quita el ajuste. Y el cierre automático de un reclamo ya no responde con un solo envío y un total viejo: espera a que estén atendidos todos los envíos del reclamo. Además la app y el MCP validan que el reclamo sea de un cliente de TU nodo. Solo texto y estado: no mueve dinero. Requiere permiso finanzas.",
|
|
61
62
|
"3.73.0 — CONTROL POR FOTO MÁS SEGURO: el MCP de la PC solo puede leer y crear adentro de UNA carpeta, la que elegís al instalar el plugin de Nexus Flex (si no elegís ninguna: Documentos\\Control por foto, que se crea sola). `control_foto_preparar`, `control_foto_carpeta` y `control_foto_foto` toman las rutas desde ahí (podés pasar solo 'Lunes 14-9-2026') y rechazan cualquier ruta de afuera o un acceso directo que apunte afuera. `control_foto_estructura` te dice cuál es la carpeta. No mueve dinero.",
|
|
62
63
|
"3.72.0 — CONTROL POR FOTO POR CARPETAS, para cualquier nodo y cualquiera de sus grupos. `control_foto_preparar` (MCP local) te crea las carpetas del día (o de varios) con los nombres exactos de tus grupos y cadetes. Armás una carpeta por día con DADOS/<grupo> (lo que pasaste a un grupo), DADOS/<cadete> (lo repartió un cadete tuyo), RECIBIDOS/…/<cadete> (te lo dio otro nodo y lo repartió tu cadete) y RECIBIDOS/<grupo> (te lo dieron y lo derivaste por ese grupo). `control_foto_carpeta` (MCP local) recorre la carpeta, lee el QR de cada foto (o la IA de etiquetas), busca o da de alta el envío SIN duplicar, lo asigna al responsable de zona / cadete / grupo, lo lleva a Entregado en el día real y le cuelga la foto (la que ven los nodos en su cuenta semanal). Primero simula y te devuelve las preguntas (cuentas de ML desconocidas, zonas con varios responsables, duplicados); se contestan con `control_foto_foto` o, más cómodo, en la app: Logística → 📷 Control por foto (ahí también quedan los envíos SIN VENDEDOR para asignarles el cliente o el nodo que te los dio; «recordar» asocia la cuenta de ML para la próxima, salvo que sea compartida entre logísticas). `control_foto_estructura` te dice qué nombres de carpeta valen. Nada sale de tu red (tu nodo + los de tus grupos). No mueve dinero.",
|
|
63
64
|
"3.71.0 — Habilitadas por el dueño: `liquidacion_excluir_envio` / `liquidacion_reincluir_envio` (sacar o devolver UN envío del cobro de una liquidación emitida, con motivo obligatorio) y `facturacion_estado` / `facturacion_preparar_cliente` (qué falta para facturar y cargar los datos fiscales de un cliente) ya funcionan por MCP: el filtro de dinero las deja pasar con su método exacto. Siguen sin pagar, cobrar ni emitir comprobantes, y piden permiso finanzas. Además `mis_envios` ahora sí filtra por `estado`.",
|
|
@@ -658,8 +659,8 @@ if (isStaff && puede("finanzas")) {
|
|
|
658
659
|
// ============================================================================
|
|
659
660
|
if (esGlobal) {
|
|
660
661
|
tool("cierre_semanal_links", {
|
|
661
|
-
title: "Links
|
|
662
|
-
description: "Para cada nodo de un cierre semanal (el último si no pasás `cierre`), el link
|
|
662
|
+
title: "Links del cierre semanal para cada nodo",
|
|
663
|
+
description: "Para cada nodo de un cierre semanal (el último si no pasás `cierre`), el link de su cuenta de esa semana. El link NO muestra la cuenta sin login: si el nodo todavía no tiene usuario, le pide mail, contraseña, nombre y apellido y lo da de alta (una sola vez por nodo, con el primer link que abra); si ya tiene, lo manda a entrar y ve la cuenta con todos los nodos adentro. Primero los que NO tienen usuario: a esos pasáselo vos por WhatsApp. Solo admin global. Solo lectura.",
|
|
663
664
|
inputSchema: { cierre: z.number().int().positive().optional().describe("id del cierre (default: el último)") },
|
|
664
665
|
}, async ({ cierre }) => run(() => api("GET", `/logisticas/cierres-semanales/links${q({ cierre })}`)));
|
|
665
666
|
|
|
@@ -1455,6 +1456,31 @@ if (ALLOW_WRITE) {
|
|
|
1455
1456
|
motivo: z.string().min(10).describe("Por qué sí se le cobra."),
|
|
1456
1457
|
},
|
|
1457
1458
|
}, async ({ id, tracking, motivo }) => run(() => api("POST", `/liquidaciones/anteriores/${id}/reincluir`, { tracking, motivo })));
|
|
1459
|
+
tool("liquidacion_cobro_parcial", {
|
|
1460
|
+
title: "Cobro en destino parcial de un envío",
|
|
1461
|
+
description: "Cuando el comprador le pagó al cadete MENOS que el flete (ej. el envío era zona media y se cobró como cercana): lo cobrado se da por pagado y el envío sigue en la liquidación YA emitida por la diferencia (flete − cobrado). `montoCobrado` 0 quita el ajuste y vuelve a cobrar el flete entero. Si lo cobrado cubre todo el flete usá `liquidacion_excluir_envio`. El `motivo` es OBLIGATORIO: queda en el historial del envío y el vendedor lo ve en su portal. Rechaza si la liquidación ya está en una factura de ARCA emitida y los viajes especiales. Ajusta el total y la cuenta corriente. No mueve dinero. Scopeada a tu nodo. Requiere permiso finanzas.",
|
|
1462
|
+
inputSchema: {
|
|
1463
|
+
id: z.number().int().positive().describe("id de la liquidación"),
|
|
1464
|
+
tracking: z.string().min(1),
|
|
1465
|
+
montoCobrado: z.number().min(0).describe("Lo que se cobró en destino, en pesos (ARS). 0 = quitar el ajuste."),
|
|
1466
|
+
motivo: z.string().min(10).describe("Por qué (ej. 'zona media cobrada como cercana'). Lo lee el vendedor."),
|
|
1467
|
+
},
|
|
1468
|
+
}, async ({ id, tracking, montoCobrado, motivo }) => run(() => api("POST", `/liquidaciones/anteriores/${id}/cobro-parcial`, { tracking, montoCobrado, motivo })));
|
|
1469
|
+
tool("reclamo_responder", {
|
|
1470
|
+
title: "Responder o cerrar un reclamo de un vendedor",
|
|
1471
|
+
description:
|
|
1472
|
+
"Responde el reclamo que un vendedor dejó sobre su liquidación (el `id` sale de `reclamos_listar`). La respuesta la lee el vendedor en su portal (Mi Cuenta). `cerrar:true` además lo pasa a resuelto; `reabrir:true` lo vuelve a abierto. Es lo mismo que Reclamos de vendedores en la app. Para corregir lo cobrado primero usá `liquidacion_excluir_envio` / `liquidacion_reincluir_envio` y contale el resultado en la respuesta. Solo texto y estado: no mueve dinero. Scopeado a tu nodo. Requiere permiso finanzas.",
|
|
1473
|
+
inputSchema: {
|
|
1474
|
+
id: z.number().int().positive().describe("id del reclamo (de `reclamos_listar`)"),
|
|
1475
|
+
respuesta: z.string().min(5).optional().describe("Texto para el vendedor (obligatorio salvo que solo reabras)"),
|
|
1476
|
+
cerrar: z.boolean().optional().describe("true = dejarlo resuelto"),
|
|
1477
|
+
reabrir: z.boolean().optional().describe("true = volver a abierto"),
|
|
1478
|
+
},
|
|
1479
|
+
}, async ({ id, respuesta, cerrar, reabrir }) => run(async () => {
|
|
1480
|
+
if (!respuesta && !reabrir) throw new Error("Falta la respuesta para el vendedor.");
|
|
1481
|
+
if (cerrar && reabrir) throw new Error("No podés cerrar y reabrir a la vez.");
|
|
1482
|
+
return api("PUT", `/liquidaciones/observaciones/${id}`, { ...(respuesta ? { respuesta } : {}), ...(cerrar ? { estado: "resuelto" } : reabrir ? { estado: "abierto" } : {}) });
|
|
1483
|
+
}));
|
|
1458
1484
|
tool("facturacion_preparar_cliente", {
|
|
1459
1485
|
title: "Dejar un cliente listo para facturar",
|
|
1460
1486
|
description:
|