Necesarios solo si vas a exportar el LRE a la DT. Si los dejas vacíos, se usan valores por defecto (Región Metropolitana, jornada ordinaria) y el AFP/salud se mapean automáticamente.
| Trabaja | Entrada | Salida |
|---|
Si tienes cargas, la liquidación calcula sola el monto = cargas × valor del tramo (tabla en Configuración → Asignación Familiar). Oficialmente el tramo se fija una vez al año según el promedio de renta enero–junio; si ya lo sabes, elígelo manualmente en vez de "Automático".
Detalle de cuotas del préstamo (opcional, se calcula solo con "Generar desde liquidaciones")
Esta liquidación se eliminará y quedará disponible para volver a generarla. Debes indicar el motivo; queda guardado para auditoría.
Este período ya está cerrado (pasó el mes). Se necesita la clave superadmin separada, configurada en Configuración → Remuneraciones.
Descuenta automático sueldo_base/30 × N días (criterio DT), incluido en la base de la gratificación legal.
Ajuste puntual solo para esta liquidación, sin cambiar la configuración fija del trabajador.
Valor que se aplica al agregarse (editable en cada liquidación)
Asignación automática
Se sugiere en liquidaciones de ese mes
Si está marcado, se agrega automáticamente al crear liquidaciones del mes indicado
Desmárcalo si este haber es imponible para AFP/salud/IUSC pero no debe sumarse al calcular el 25% de gratificación (ej. bono de escolaridad, según definición con tu asesor).
Para descuentos como "Ausencias / Inasistencias", ingresa el monto en negativo (ej: -30000): se resta de los haberes imponibles y de la base de la gratificación legal.
Desmárcalo si este haber (ej. bono de escolaridad) es imponible para AFP/salud/IUSC pero no debe sumarse al calcular el 25% de gratificación.
Sugerido: autorizar entre los días 10 y 18 del mes. Hasta 4 anticipos por trabajador y período (idealmente 1 por semana, los días viernes).
Útil para casos como el seguro complementario de salud: si lo paga la empresa, el monto no reduce el líquido del trabajador y queda registrado como costo del empleador (columna "Costo Total Empleador" en el Libro de Remuneraciones).
Útil para seguro complementario o seguro de vida: se descuenta todos los meses sin fecha de término, hasta que lo desactives. El monto de cada mes igual se puede ajustar puntualmente al crear la liquidación.
Primera cuota descontada
Se generará la liquidación de todos los trabajadores activos para . Revisa/ajusta estos valores antes de calcular la vista previa.
Prellenado desde Configuración. Déjalo en 0 para no aplicar.
Útil para bonos puntuales del mes (ej. bono producción, aguinaldo extraordinario) que quieras dar a todos de una vez. Se suma además de la colación/movilización y de los haberes automáticos ya configurados por trabajador.
Revisa el resultado antes de generar. Desmarca a quien quieras excluir de esta tanda.
De acuerdo a la Ley N° 21.719 puede solicitar acceso, rectificación, supresión, oposición, portabilidad o bloqueo de sus datos personales.
Ingrese sus credenciales para continuar
| Código | Nombre | Rol | Permisos | Vendedor | Correo | Estado | Creado | Acciones | |
|---|---|---|---|---|---|---|---|---|---|
|
Cargando... |
|||||||||
Marcar = restringir. 🙈 ocultan el
dato al vendedor. 🔒 limitan las cifras a su vendedor asignado. Sin marcar nada, el vendedor ve todo.
🤖 El asistente está desactivado por defecto — actívalo por usuario.
🌐 Leads Web: permite ver el menú y solo los leads asignados al email del vendedor.
🏛️ Licitaciones MP: permite ver el módulo (admin siempre lo ve; vendedor solo si está marcado).
📜 Certificados: permite buscar y enviar certificados de calidad (admin siempre lo ve).
Si se asigna un vendedor, el usuario solo verá cotizaciones y facturas de ese código al ingresar.
Código con el que este usuario figura como bodeguero en el ERP (columna COBODUSER de gecot_enc). No necesariamente coincide con su código de acceso a Kognit — se usa solo al autorizar notas de venta pendientes.
| N° | Fecha | Cliente | Total | Vence | |
|---|---|---|---|---|---|
| Cargando… | |||||
| # | Código | Descripción | U.M. | Cantidad | Stock | P. Unitario | Dto.1% | Dto.2% | P. Neto | Subtotal | 📍 | ✕ |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Busque y agregue productos a la cotización |
||||||||||||
| Subtotal Neto: | $0 | |||||||||||
Solo se muestran cotizaciones del sistema web que no tienen una factura o boleta emitida ni se traspasaron al ERP — nunca aparece aquí una que tenga un documento tributario real detrás. Se borran por completo, sin poder deshacerlo.
Cargando…
| N° Cotización ▼ | Fecha | Hora | RUT | Cliente | Comuna | Vendedor | Total | Estado | Despacho | Origen | Admin-V | Acciones |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Cargando... |
||||||||||||
Anota o corrige de una vez los haberes y descuentos que cambian mes a mes para varios trabajadores, en vez de entrar a cada ficha. Los descuentos aquí son solo los mensuales/indefinidos (ej. seguro complementario) — los préstamos por cuotas se manejan solos y no aparecen aquí.
Sube la planilla (.xls) del reloj control de asistencia. El sistema calcula los atrasos de la mañana (según Configuración → Hora de entrada + Tolerancia), los atrasos del regreso de almuerzo (jornada partida, según Regreso de almuerzo + su tolerancia) y las horas extra (según Hora de salida) de cada trabajador, y los deja listos para revisar antes de aplicarlos — no reemplaza la carga manual, sigue disponible igual que antes.
Las horas extra y los atrasos/ausencias son dos conceptos independientes que nunca se compensan entre sí. No existe la figura de "llegó tarde el lunes pero se quedó más tiempo el miércoles, se cancelan" — cada uno se rige por su propia norma y se calcula por separado (por eso este sistema nunca resta horas extra menos ausencias, ni al revés).
En Chile la hora extra se define por jornada DIARIA pactada, no por un umbral semanal de 40 horas (a diferencia de otros países). Si la jornada es de 8 horas diarias y un día se trabajan 9, esa hora extra corresponde a ese día, sin importar cuántas horas lleva acumuladas la semana. Por eso el cálculo se hace sumando minuto a minuto por día — no hace falta agrupar por semana ni verificar si se completaron las 40 horas semanales.
La jornada semanal pactada sí se usa, pero solo como dato para calcular el valor de la hora (fórmula del Dictamen 5308/230: sueldo diario × 28 ÷ (horas semanales × 4)) — no cambia que el conteo de minutos sea diario.
Se combinan los días de ambos archivos y solo se cuentan los que caigan entre "Desde" y "Hasta" (evita duplicar si algún archivo trae más días de la cuenta). Las fechas se sugieren solas al elegir el mes, pero puedes ajustarlas al día exacto de corte que uses (20, 19, etc.).
Imposiciones a pagar por institución, préstamos, etc. Puedes generarlo desde las liquidaciones y luego agregar, modificar o eliminar filas libremente.
El certificado toma la fecha de contrato del trabajador y calcula su antigüedad. Se muestra una vista previa antes de descargar el PDF.
Este módulo administra el ciclo completo de remuneraciones de tus trabajadores: desde su ficha previsional hasta el cálculo mensual, los libros contables/legales y la documentación laboral. Está organizado en 7 pestañas:
Ficha de cada trabajador: datos personales, sueldo base, AFP, previsión de salud, cuenta bancaria, datos LRE (región/comuna/jornada) y estado previsional (pensionado).
Calcula y guarda la liquidación mensual de cada trabajador (o de todos a la vez con "⚡ Generar todas"). Vista previa antes de guardar, PDF en 2 formatos, envío por email.
Planilla mensual resumen: una fila por trabajador con sus totales de haberes, descuentos y líquido, exportable a Excel.
Libro de remuneraciones legal (imprimible/Excel) con el desglose completo por concepto, más el resumen contable editable y la exportación del LRE para la Dirección del Trabajo.
Genera contratos de trabajo y finiquitos en PDF con los datos ya cargados del trabajador, calculando automáticamente el feriado proporcional.
Certificado de antigüedad laboral y Certificado de Sueldos y Retenciones anual (formato SII), ambos con vista previa antes de descargar.
Todo el cálculo se apoya en esta pestaña ⚙️ Configuración: aquí defines el IMM/UTM vigentes, la UTM histórica por mes (para recalcular meses anteriores), las tasas de AFP, la tabla del IUSC, los tipos de descuento y de haberes, la asignación de colación/movilización automáticas, la firma del empleador para los PDF, y puedes auditar las liquidaciones eliminadas.
❓ Preguntas frecuentes
1) Verifica que todos los trabajadores activos tengan su ficha al día en Empleados (sueldo, AFP, salud). 2) Ve a Liquidaciones, elige año/mes y usa "⚡ Generar todas" para calcular a todo el mundo de una vez (o "+ Nueva liquidación" para uno en particular). 3) Revisa la vista previa de cada una antes de confirmar. 4) Descarga los PDF o envíalos por email. 5) Consulta el Libro de Remuneraciones y exporta el LRE para la DT.
En Liquidaciones, en la fila correspondiente usa el botón 🗑 Eliminar. El sistema te pedirá el motivo (queda guardado en una auditoría, visible más abajo en esta misma pestaña de Configuración) y luego podrás generarla de nuevo con los datos correctos desde "+ Nueva liquidación".
Al calcular una liquidación, despliega el panel "➕ Más conceptos": ahí están todos los conceptos habituales del Libro Electrónico (comisiones, aguinaldo, bonos, viático, APV, cuota sindical, anticipos, etc.). Cada campo solo se aplica si le pones un monto — si lo dejas vacío, simplemente no aparece.
En Configuración → Descuentos activos por empleado usa "+ Asignar" (o desde la liquidación misma con "+ Agregar" en la sección de descuentos). Define monto total, N° de cuotas y, si aplica, meses libres de pago. El sistema calcula la cuota mensual y la va descontando automáticamente cada vez que generes la liquidación de ese trabajador, hasta completar las cuotas.
En Configuración → Tipos de haberes, crea o edita el tipo y marca "Aplicar a todos los empleados" con el mes automático correspondiente. Ese haber se agregará solo a las liquidaciones de ese mes para todos los trabajadores activos. Si es solo para algunos, en cambio, asígnalo individualmente desde "Haberes activos por empleado".
El sistema usa la UTM histórica del mes que estás calculando (no la actual), para que las reliquidaciones de meses pasados sean exactas. Ve a Configuración → UTM histórica por mes y usa "Completar año" para descargar los 12 valores; si alguno no corresponde, puedes corregirlo manualmente. También puedes forzar un valor de IUSC específico con el campo "IUSC manual" al calcular la liquidación.
Es el Libro de Remuneraciones Electrónico que exige la Dirección del Trabajo mensualmente. Ve a 📖 Libro Remun., elige el período y presiona "📤 Exportar LRE (DT)": descarga un CSV en el formato exacto que exige el portal Mi DT (delimitador ";", nombre de archivo, códigos de concepto). Antes de exportar, revisa que los trabajadores tengan cargados sus datos de región/comuna/jornada en su ficha (sección "📘 Datos para Libro Electrónico").
En Configuración → Firma del empleador, sube una imagen (PNG con fondo transparente, idealmente). Se incrusta automáticamente sobre la línea "Firma Empleador" en las liquidaciones, contratos, finiquitos y certificados que generes desde entonces.
Calcula normalmente su última liquidación (con los días trabajados hasta la fecha de término). Luego ve a 📄 Contratos / Finiquitos, selecciona al trabajador y completa el formulario de Finiquito: causal legal, indemnizaciones si corresponden, y usa el botón "Calcular" junto a Feriado Proporcional para que el sistema lo calcule automáticamente según la fórmula de la DT. Después, si ya no seguirá en la empresa, puedes desactivarlo o eliminarlo desde Empleados.
Se multiplica por los días hábiles del mes (lunes a viernes), descontando los feriados legales/de empresa cargados en "🗓 Feriados".
Se agrega automáticamente a cada liquidación. Art. 41 inc. 2 CT. Se puede corregir a mano para un trabajador puntual editando su liquidación.
Se agrega automáticamente a cada liquidación. Art. 41 inc. 2 CT.
Por defecto no (sin obligación legal, salvo pacto/convenio colectivo — SUSESO). Si lo activas, esos 3 días se pagan como sueldo normal y solo se descuenta el resto de la licencia.
Minutos de gracia diarios antes de descontar por atraso (ej. llegada 8:30, tolerancia 10 → recién descuenta después de las 8:40). Se aplica día por día al registrar los atrasos en la liquidación, no sobre el total del mes.
Horario esperado, usado solo al importar una planilla de asistencia (⏱ Asistencia) para calcular atrasos (con la tolerancia de arriba) y horas extra.
Solo afecta a los trabajadores con "Descontar salida anticipada" activado en su ficha — minutos de gracia antes de empezar a descontar por retirarse antes de la hora de salida.
Para jornada partida (ej. 13:30, con 30 min de tolerancia → recién se considera atraso después de las 14:00). Puede ser distinta a la tolerancia de la mañana.
Determina cómo se calcula el valor de la hora usado tanto para pagar horas extra como para descontar atrasos/ausencias, en la liquidación real y en la vista previa de Asistencia. Por defecto "Estándar" (no cambia montos existentes).
Los valores UF de fin de mes quedan guardados y se usan al emitir liquidaciones retroactivas.
Las tasas cambian mensualmente. Fuente: spensiones.cl
Se aplica sobre la base tributable = Total Imponible − AFP − Salud. La tabla es progresiva por tramos en UTM.
Impuesto = base × factor − rebaja. UTM vigente:
—.
| Tramo (renta mensual) | Desde (UTM / $) | Hasta (UTM / $) | Factor | Rebaja ($) |
|---|---|---|---|---|
| Cargando… | ||||
Tabla mensual del SII. Los montos en $ se calculan con la UTM vigente configurada arriba.
El monto por carga depende del tramo, que oficialmente se determina por el promedio de renta imponible de enero a junio del año anterior (rige de julio a junio siguiente). Para cada trabajador puedes fijar el tramo manualmente en su ficha (recomendado, según ese promedio real) o dejarlo en "Automático", en cuyo caso el sistema estima el tramo usando el imponible del mes que se está liquidando.
| Tramo | Renta imponible hasta ($) | Monto por carga ($) |
|---|---|---|
| Cargando… | ||
Valores vigentes desde el 01-05-2026 (Ley N°21.830, D.O. 22-06-2026). Si la ley reajusta los montos, edítalos aquí. Fuente: ¿Cuál es el valor de la asignación familiar? — DT
Un trabajador que ya está pensionado (por vejez o invalidez) y sigue trabajando como dependiente tiene un tratamiento previsional distinto al de un trabajador normal. La razón, según la DT, es que "el riesgo para el cual se otorgó el beneficio ya está suficientemente cubierto".
| Situación del trabajador | AFP | SIS (empleador) | Seg. Cesantía (AFC) | Salud (7%) |
|---|---|---|---|---|
| No pensionado | Obligatoria | Obligatorio | Obligatoria (si indefinido) | Obligatoria |
| Pensionado por vejez | Exento | Exento | Exento | Obligatoria |
| Pensionado por invalidez total | Exento | Exento | Exento | Obligatoria |
| Pensionado por invalidez parcial | Obligatoria | Obligatorio | Obligatoria (si indefinido) | Obligatoria |
| Pensionado (cualquiera) + "sigue cotizando AFP voluntariamente" | Se calcula igual que un trabajador no pensionado (según su tipo de pensión para el AFC) | Obligatoria | ||
Fuentes: Trabajador pensionado y cotización AFP — DT · Obligados a cotizar seguro de cesantía — DT · Cotizaciones del seguro de cesantía — DT
❓ Preguntas frecuentes — cómo se ingresan estos datos
En Empleados → ✏️ Editar (o al crear uno nuevo), en el bloque junto al selector de AFP encontrarás "¿Trabajador pensionado?". Elige No, Vejez, Invalidez total o Invalidez parcial y guarda. No necesitas hacer nada más: el cálculo de AFP/SIS/AFC se ajusta automáticamente la próxima vez que calcules una liquidación de ese trabajador.
Solo aparece si el trabajador está marcado como pensionado. Actívalo si, pese a estar pensionado, decidió por escrito seguir cotizando en su AFP (situación poco común pero permitida). En ese caso el sistema calcula la cotización AFP normalmente, como si no estuviera pensionado.
No. Debes volver a calcular la liquidación de ese período para que tome el nuevo estado previsional (el botón "Calcular y previsualizar" siempre recalcula todo de nuevo con los datos actuales del trabajador). Si la liquidación ya estaba guardada, primero elimínala (indicando el motivo) y vuelve a generarla.
En la vista previa de la liquidación (al calcular) revisa la columna de Descuentos Legales: si el trabajador está exento, verás la línea "AFP [nombre] (exento — trabajador pensionado)" con monto $0, en vez de que la línea simplemente no aparezca. Así queda claro que no es un error, sino la exención aplicada.
En la misma ficha del empleado, dentro de la sección plegable "📘 Datos para Libro Electrónico (LRE)", está el campo "Seguro cesantía (AFC)" (Sí/No). Si el trabajador está pensionado por vejez o invalidez total, el sistema lo exime automáticamente aunque el campo diga "Sí" — no necesitas cambiarlo manualmente.
Sí, automáticamente. En el Libro de Remuneraciones (pestaña 📖) verás $0 en la columna AFP para el trabajador exento. En el archivo LRE exportado (botón "📤 Exportar LRE" en el mismo tab) se marcan los códigos oficiales 1108 y 1109 según corresponda, sin que tengas que hacer nada adicional.
Cuando el trabajador llega tarde o se ausenta parte de la jornada (no un día completo), la Dirección del Trabajo establece una fórmula distinta a la del día completo (sueldo/30). Se basa en el Dictamen N°5308/230 (29-09-1996).
Ejemplo: sueldo $1.500.000, jornada 45 h/semana, 2 horas de atraso → diario $50.000 → 4 semanas $1.400.000 → valor hora $7.777,78 → descuento = $15.555,56.
Fuentes: ¿Las horas de atraso dan derecho a descontar? — DT · Base de cálculo del descuento — DT · Remuneración diaria para descontar ausencias — DT
❓ Cómo se usa en el sistema
En "Nueva liquidación", sección "Atrasos / ausencias parciales": agrega una fila por cada día con atraso (fecha + minutos). El sistema descuenta la tolerancia configurada y suma las horas netas resultantes automáticamente al calcular.
Se guarda una tabla con la UTM de cada mes para poder recalcular liquidaciones de meses anteriores con el valor correcto de ese período (no el actual). Fuente: mindicador.cl, que replica los valores oficiales publicados por el SII.
| Mes | UTM | Fecha valor | |
|---|---|---|---|
| Selecciona un año y presiona "Completar año". | |||
UF del último día de cada mes. Al calcular una liquidación de un mes anterior con plan Isapre en UF, el sistema busca automáticamente esta UF histórica (no la actual) para descontar el monto correcto. Fuente: mindicador.cl (Banco Central).
| Mes | UF (último día) | Fecha valor | |
|---|---|---|---|
| Selecciona un año y presiona "Completar año". | |||
Precargado con los valores oficiales del Ingreso Mínimo Mensual desde julio 2024 (Ley N°21.751 y decretos del Ministerio del Trabajo). Si un trabajador gana exactamente el sueldo mínimo actual, al calcular la liquidación de un período anterior el sistema usa automáticamente el IMM histórico de ese mes en vez del actual — sin necesidad de editar su ficha. No aplica a trabajadores con otro sueldo.
| Mes | IMM | |
|---|---|---|
| Cargando… | ||
Fuentes: Ley 21.751 — Ministerio del Trabajo · Valor vigente — DT
Se usan para calcular con precisión el feriado (vacaciones) proporcional de un finiquito (días hábiles → días corridos, considerando fines de semana y feriados reales, en vez de una aproximación). No afecta el descuento por licencia médica, que por ley se calcula en días corridos, no hábiles. Cada fecha muestra el día de la semana para poder ver de un vistazo si conviene revisar un posible "feriado puente" (ej. viernes 19 si Fiestas Patrias cae jueves-viernes) — estos se decretan aparte cada año y hay que agregarlos manualmente cuando se confirmen.
| Fecha | Nombre | Tipo | |
|---|---|---|---|
| Cargando… | |||
Imagen (PNG con fondo transparente, idealmente) que se incrusta sobre la línea "Firma Empleador" en el PDF de la liquidación. Se aplica a ambos formatos.
Categorías reutilizables al asignar descuentos (préstamos, seguros, etc.)
| Nombre | Categoría | Estado | |
|---|---|---|---|
| Cargando... | |||
"Leyes sociales" de cargo del empleador (no descuentan al trabajador): Mutual/Ley 16.744, AFC empleador y la nueva cotización adicional Ley 21.735 (Reforma de Pensiones, gradual desde ago-2025). Los trabajadores pensionados por vejez o invalidez total quedan exentos de todas estas leyes sociales, igual que del AFP/SIS.
Base 0,95% + tasa adicional según riesgo/organismo
1% desde ago-2025; sube gradual — verificar en spensiones.cl
⚠️ La CCAF no es un cargo del empleador: es la entidad que administra parte del 7% de salud que ya paga el trabajador (Previred reparte 4,2% CCAF / 2,8% Fonasa cuando la empresa está afiliada — no es un descuento ni costo adicional). Por eso no se calcula aquí ni se descuenta en la liquidación. El dato de CCAF (para dejarlo anotado en el Libro de Remuneraciones, "por si las moscas") se configura más abajo, en "📖 CCAF — dato informativo para el Libro".
Fuentes: Cotización adicional Ley 21.735 — Subsecretaría Previsión Social · Tope imponible y accidentes del trabajo — DT · Indicadores Previsionales Previred (tasas AFC, SIS, Ley 21.735, Asignación Familiar)
Es del trabajador (parte de su 7% de salud), no un costo del empleador. Este valor no se descuenta ni se suma en ninguna liquidación — solo se anota como nota informativa en el Libro de Remuneraciones → Resumen contable (categoría "CCAF") al usar "Generar desde liquidaciones", por si necesitas dejar registro del monto administrado por tu caja.
Déjalo en 0 si no quieres registrar este dato. El % o monto exacto varía según tu caja (Los Andes, La Araucana, Los Héroes, 18 de Septiembre) — confírmalo con tu CCAF.
Catálogo de bonos y asignaciones (aguinaldos, bonos, etc.)
| Nombre | Tipo | Mes auto | ¿A todos? | |
|---|---|---|---|---|
| Cargando... | ||||
Bonos/asignaciones fijos por trabajador que se agregan solos a su liquidación. "Todos los meses" o un mes específico (ej. aguinaldo).
Documentos de esta semana sin pago registrado. Para ver el estado de cuenta completo de un cliente, búscalo arriba.
Cargando…
Cheques ingresados como pago que aún no se confirman como cobrados, de todos los clientes, ordenados por fecha de vencimiento.
Cargando…
Cargando…
Cheques que se marcaron como cobrados últimamente. Si alguno se confirmó por error —por ejemplo, un cheque a fecha que todavía no se cobra— devuélvelo a la cartera. El pago no se elimina: sigue ligado a su factura, solo vuelve a contarse como pendiente de cobro.
Cargando…
Filas del monedero de Kognit que ya están duplicadas en el ERP, o que se repiten (mismo cliente y monto) dentro del propio monedero. Revisa y elimina las que correspondan — no se borra nada automáticamente.
Cargando…
Pagos ya conciliados en Kognit que todavía no están en el ERP. Marca los que quieres generar (se crean como pago cobrado en la cuenta del cliente). Documentos que ya tienen pago en el ERP no aparecen.
Cargando…
Documentos emitidos en el rango elegido que a la fecha de corte (hoy) todavía no tienen ningún pago asignado. Incluye tanto lo emitido por el ERP como lo declarado al SII (para empresas sin ese documento cargado en el ERP).
Elige el rango y presiona Ver.
Elige el período y presiona Ver.
| Documento | Pendiente | A pagar |
|---|
Para cuando varios documentos se pagan con varios instrumentos que no calzan uno a uno. Carga cada instrumento, marca los documentos abajo y presiona "Repartir".
Se aplican después de los pagos, sobre lo que cada documento todavía deba. En "Automático" se reparten entre los documentos marcados, del más antiguo al más nuevo.
El cupón general se usa solo en las líneas que no tengan su propio cupón cargado (cada instrumento/detalle puede traer el suyo).
| Documento | Fecha | Saldo pendiente | Monto a pagar | Pago | |
|---|---|---|---|---|---|
Cargando… | |||||
Entraste con una clave temporal que el administrador conoce. Elige una tuya para continuar.
Usuarios que dijeron haber olvidado su clave. Al aprobar, el sistema genera una clave temporal: anótala y entrégasela (también se le envía por correo si tiene uno registrado). Al entrar con ella, el sistema le exige definir una propia.
Libro Diario, Libro Mayor, Balance y Estado de Resultados, leídos directamente del libro
contable del ERP (gediario) — todos los informes son de solo lectura. El único
botón que escribe algo es "Nuevo Comprobante", más abajo.
Balance de PERÍODO: el saldo de cada cuenta se calcula solo con lo posteado entre "Desde" y "Hasta" (por defecto, el año calendario completo) — no arrastra nada de antes. El cuadre (Debe = Haber del período) se muestra al pie del resultado.
Reporte clásico de período (por defecto, desde el 1 de enero del año de "Hasta"). Sumas Debe/Haber → Saldos Deudor/Acreedor → según si la cuenta es de Balance o de Resultado, el saldo cae en Activo/Pasivo o en Pérdida/Ganancia. La Utilidad o Pérdida del Ejercicio es la diferencia entre Activo y Pasivo, y debe coincidir con la diferencia entre Ganancia y Pérdida — ese cuadre se muestra al pie.
⚠️ El plan de cuentas del ERP no separa Costo de Venta / Gastos de Administración y Ventas / Gastos Financieros en ramas distintas — la clasificación por sección de este informe es una propuesta armada a mano (criterio estándar de PyME chilena), a validar con el contador de la empresa antes de usarla como definitiva.
"Gastos de Administración y Ventas" es el costo fijo/operacional de mantener la empresa funcionando (sueldos, arriendos, gastos generales, etc.) — no incluye Costo de Venta, que depende de cuánto se vende, no de mantener la operación abierta. Mismo criterio de clasificación que Estado de Resultados (ver aviso ahí).
Calculado con el Libro Diario (asientos contables), por mes de la fecha del asiento, con la misma clasificación del Estado de Resultados. La contabilidad se carga en cierres mensuales: el mes en curso aparece cuando el contador lo cierra, y el último cierre puede cambiar si lo ajusta.
Método indirecto: parte de la Utilidad del Ejercicio y ajusta por lo que no es caja hasta reconciliar exacto con el movimiento real de Caja y Bancos del período (el cuadre se muestra al pie). Excluye los asientos "Saldo Inicial" de apertura anual del contador — no son movimiento de caja real, solo reafirman/corrigen saldos.
A diferencia de los demás reportes (que son de período), este es a una fecha — la foto del negocio en ese instante, acumulando todo el historial del libro. "Utilidad Acumulada" se reclasifica de Pasivo a Patrimonio (así vive en el plan de cuentas del ERP, pero económicamente es patrimonio). "Resultado Acumulado No Distribuido" es el histórico completo de Ganancias−Pérdidas, porque esas cuentas nunca se cierran en este libro — es lo que hace que el balance cuadre exacto en cualquier fecha. Activa "Comparar con otra fecha" para verlo lado a lado con un cierre anterior (ej. 31-dic del año pasado), como se presenta normalmente un balance general.
Plan de cuentas del ERP. El número de una cuenta no se puede cambiar; el nombre sí (los comprobantes guardan el número, así que renombrar no altera ningún asiento). Una cuenta solo se puede eliminar si no tiene subcuentas y nada la usa: comprobantes, saldos del ERP, órdenes, productos, formas de pago o la configuración de Kognit.
gediario), el mismo que
usa el ERP de escritorio. No hay forma de deshacerlo desde Kognit una vez guardado —
si te equivocas, hay que corregirlo desde el ERP o con un asiento de reverso.
Control de boletas de honorarios recibidas (pagos a profesionales independientes) para cuadrar la retención declarada en el Formulario 29. No es un registro oficial del SII — es un control interno propio de Kognit. Retención vigente 2026: 15,25% (Ley 21.133, sube gradualmente hasta 17% en 2028).
Elige un módulo para ver los pasos. El de cotizaciones abre además el tour interactivo real.
| N° OC | Fecha | Mes | Estado | Proveedor | Ítems | Neto | Total OC | |
|---|---|---|---|---|---|---|---|---|
| Cargando... | ||||||||
Documentos de compra que el SII ya registró para esta empresa (Registro de Compras y Ventas) — mismo dato que ya usa Libro de Compras, sin necesidad de sincronizar de nuevo acá. ⚠️ No todo lo que aparece acá es una compra de productos — el Libro de Compras también junta facturas de gastos (servicios, arriendo, internet, etc.) que no van a Inventario. Usa "👁 Ver detalle" para revisar qué trae realmente el documento antes de decidir; "→ Ingresar a inventario" precarga proveedor y fecha en Ingreso Orden de Importación — úsalo solo para compras de productos reales; las líneas se cargan desde la planilla del proveedor o con «Traer el detalle de una compra» (al final de esta pantalla), que las lee del XML del SII o de facturacion.cl. Para facturas de gastos o servicios usa «🧾 Ingresar al ERP»: eliges la cuenta contable (de toda la factura o de cada línea) y, con el interruptor «Compras al ERP» encendido, queda grabada en el registro de compras del ERP.
| Fecha | Tipo | Folio | Proveedor | RUT | Neto | IVA | Total | En el ERP | Acciones |
|---|---|---|---|---|---|---|---|---|---|
| Cargando... | |||||||||
Para una compra de productos: lee el detalle línea por línea del documento (XML del SII o facturacion.cl) y te lleva a Ingreso Orden de Importación con las líneas ya cargadas, para revisarlas y confirmar el ingreso al inventario.
Lee el XML real del documento recibido (con el detalle línea por línea) — mismo dato que el DTE que tu proveedor le mandó al SII. Dos formas de conseguirlo:
Lista los documentos recibidos en facturacion.cl (panel «DTE Recibidos», con guías de despacho, y Libro de Compras, sin repetir folios) para un rango de fechas, y trae el detalle real (línea por línea) del que elijas — a diferencia del SII, esta vía no pide captcha. Necesita el nombre de la empresa configurado en Conexiones → DTE (Facturación electrónica).
Junta los tres registros que Kognit ya sincroniza del SII por separado (Documentos → Ventas SII, Libro de Compras y Boletas SII), para ver el panorama fiscal completo sin entrar a cada uno. Si alguno no se ha actualizado nunca desde el SII, su columna sale en $0 — no es un error, es que falta bajarlo desde su propia pestaña.
Cargando…
Se calcula en vivo con las líneas de facturas, boletas y notas de crédito del ERP (sin documentos anulados). El costo es el que quedó registrado en cada línea de venta; si ese costo está mal en el ERP, el margen también — por eso la pestaña Alertas lista las líneas sospechosas. Las notas de crédito restan venta (casi nunca traen costo).
Cargando…
Compara, mes a mes, lo que el sistema habría proyectado con lo que finalmente se vendió. La proyección se recalcula con el mismo criterio del panel de Proyección (venta al corte ÷ días hábiles transcurridos × días hábiles del mes) y siempre al mismo día del mes, para que los meses se puedan comparar entre sí. La meta es el promedio de los tres meses cerrados anteriores.
| Mes | Meta | Llevaba al día | Proyección | Vendido | % Meta | Desvío | Acierto |
|---|
| Cliente | Total | Fact. | Monto |
|---|---|---|---|
|
Cargando... |
|||
| Vendedor | Cot. | Fact. | % Fact. | Neto fact. | Total fact. | Pendiente x facturar |
|---|---|---|---|---|---|---|
|
Cargando... |
||||||
FADSUBTOT facturas + BOLDSUBT
boletas) sin aplicar ningún descuento.FADDESC, FADDESC2) y luego un
ajuste proporcional por el descuento de cabecera: cada línea se escala por FANETO / suma_netos
para que el total cuadre con el neto real del documento.FANETO/BOLNETO del documento distribuido proporcionalmente por línea.Neto Final × %; si es $ fijo por unidad →
Cantidad vendida × $/u.Clientes cuya primera compra (factura o boleta) cayó dentro del rango — nunca habían comprado antes. Si un cliente volvió a comprar en meses siguientes, se muestran todos esos meses y qué compró en cada uno.
Clientes que compraron dentro de la ventana elegida antes de la fecha de corte, pero no tienen
ninguna compra registrada desde esa fecha hasta hoy. Ordenados por monto histórico (a quién conviene recontactar primero).
💡 Cómo leer el resultado: la "fecha de corte" y los "meses atrás" solo definen la ventana en la que se busca
si el cliente estaba activo (debe haber comprado al menos una vez entre corte−X meses y el corte, y nada después).
La columna "Última compra" es su fecha real de compra dentro de esa ventana — puede caer al principio, al medio
o justo antes del corte — y "Días sin comprar" siempre se cuenta desde esa fecha real hasta hoy, no desde el corte.
Por eso puede ser mayor que "corte − hoy".
| N° Factura | Fecha | RUT | D | Nombre | CxC | Vendedor | Cond. Pago | Neto | IVA | Total | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Seleccione un período y haga clic en Actualizar | |||||||||||
El costo de factorizar una factura casi nunca es "un solo %" — normalmente son 3 componentes que se descuentan del valor de la factura antes de recibir el dinero:
Qué mueve la tasa hacia arriba o abajo: a mayor plazo hasta el vencimiento, mayor descuento; clientes (pagadores) con buen historial de pago bajan la tasa; montos grandes o relación de largo plazo con la factoring suelen negociar mejor condición.
Ojo con el IVA: la comisión y los gastos van con factura y su IVA correspondiente — el "costo total" real es más alto que solo la tasa de descuento publicitada.
Cuánto anticipan de la factura: normalmente entre 95% y 98% del total al momento; el resto (el "retenido") se paga cuando el cliente final efectivamente cancela.
Estos son rangos de referencia del mercado chileno, no una cotización — cada factoring fija sus condiciones según el riesgo del cliente y el volumen de operación. Al ingresar un pago con Factoring en Kognit, usa el % o monto real que te informó tu factoring, no estos rangos.
| Código | Descripción ▲ | U.M. | Precio 1 | Precio 2 | Costo | Stock | Bod.1 | Bod.2 | Bod.3 | Estado | Vend.hasta hoy |
|---|---|---|---|---|---|---|---|---|---|---|---|
|
Cargando... |
|||||||||||
| Código | Descripción ▲ | Stock | Vta/mes | Cobertura | A comprar | Estado | Último mov. | |
|---|---|---|---|---|---|---|---|---|
|
Presiona "Calcular" para generar el informe de reposición |
||||||||
Sube tu planilla de productos a cotizar (columna B = código del sistema, columna G = cantidad a cotizar). Se devuelve la misma planilla con tres columnas agregadas: lo vendido realmente en los últimos 12 meses (hasta hoy) de cada código, la diferencia contra lo que se piensa cotizar, y una cantidad recomendada (si se pide más de lo vendido en el año, sugiere no pasarse de esa demanda real; sin ventas en el período, pide revisar con el cliente en vez de arriesgar un número) — resaltado en rojo si el producto no tuvo ventas en el período, y en amarillo si se cotiza más de lo vendido.
Presiona "Analizar" para generar el análisis
Todos los productos activos con su precio en la lista elegida, agrupados por serie y ordenados de menor a mayor medida. Escriba el precio nuevo directamente en la columna Precio (también en los que dicen «sin precio»): si deja una medida más chica más cara que una mayor (o al revés), la fila se marca en rojo y lo dice en Escalera de medidas al instante. Nada se guarda hasta que use Guardar cambios. Con Fijar un margen objetivo se calculan de una vez los precios de lo filtrado.
Compara cada producto con su equivalente en la otra calidad y revisa que, dentro de una serie, ninguna medida menor cueste más que una mayor. El emparejado sale de la descripción: se toma la calidad y la medida, y lo que queda identifica la serie.
Pulse Actualizar
Mismo agrupado de "Paridad de precios" (por serie y medida, 304 en una columna y 316 en la de al lado) pero mostrando todas las listas de precios de cada lado a la vez — solo lectura, para comparar de un vistazo. Para corregir un precio, hazlo desde la ficha del producto en Productos (o desde Paridad si es una sola lista).
Pulse Actualizar
No se ha guardado nada todavía. Puede haber motivos legítimos para dejarlo así, por eso no se bloquea — pero conviene mirarlo. Lo que confirmes queda registrado.
| Código | Descripción | Lista | Precio actual | Precio nuevo | Diferencia | Margen antes → después | Aviso |
|---|
| Fecha | Tipo | N° Doc. | Cliente / Proveedor | Bodega | Cantidad | Costo | Stock tras mov. | |
|---|---|---|---|---|---|---|---|---|
|
Busca un producto para ver su kardex |
||||||||
Sin movimientos en el período
geitems_man/mand/mov):
Déjalo en 0 si salen bien. Si desde la 2.ª etiqueta se van corriendo (ej. Xprinter), pon aquí el espacio entre etiqueta y etiqueta del rollo (ej. 3) y prueba con «Etiqueta de prueba». Se recuerda en este navegador.
| N° Excel | Código | Descripción | Stock actual | Costo actual | Qty ingreso | Costo nuevo | Stock final | Costo promedio | PV actual | PV nuevo | Actualizar PV | Cajas | Piezas/Caja | Etiquetas |
|---|
Esto escribe de verdad en el ERP: 1 encabezado + 0 línea(s) de detalle
(geitems_man/geitems_mand), los movimientos de stock (geitems_mov) y
actualiza el costo promedio (y el precio de venta donde lo marcaste). No se puede deshacer desde acá.
El packing list no trae el código del producto, así que asigna a mano cada bloque (material/medida/descripción tal como viene en el archivo) al producto correspondiente de la orden. Al asignar, se copian las Cajas y Piezas/Caja a esa fila de la tabla.
Cargando importaciones…
| Código ERP | Descripción Español | Descripción Inglés | Cantidad | Costo Unit. | Total |
|---|
Muestra cómo llegará cada producto a los próximos meses con el stock de hoy, lo que viene en las órdenes de importación y la venta promedio. Así ves qué se agota antes de que llegue lo próximo y qué hay que pedir, a quién y hasta qué fecha. Todo se guarda en Kognit: no modifica el ERP.
Cómo se usa: 1) descarga la plantilla; 2) llena arriba los datos de la orden (código, proveedor, fecha de llegada, dólar) y debajo una línea por producto con su código del ERP, cantidad y precio en USD; 3) súbela aquí. Si la fecha de llegada cambia, la editas y queda el historial. Al ingresar la importación de verdad con la misma referencia (por ejemplo C-1003) la orden pasa sola a «llegó».
Se sugiere el proveedor de menor último costo entre los que ya te vendieron cada producto; tú decides. El costo de las órdenes cargadas aquí usa el dólar final de hoy; el de compras anteriores es el valor en pesos con que se ingresaron.
Lo que hay que pagar cada mes. Supone que el anticipo de las órdenes que ya vienen en camino ya se pagó al hacer el pedido y que el saldo se paga el día que llegan; para la orden nueva, el anticipo se paga en su fecha límite de pedido y el saldo al llegar. El anticipo se supone de 50%. Los dólares son aproximados (pesos ÷ dólar final).
Una vez al día Kognit revisa la proyección con los parámetros que guardaste y avisa a los administradores cuando entran productos NUEVOS cuya fecha límite para pedir cae dentro de ese plazo: aviso en pantalla, mensaje del sistema en el chat (queda guardado) y correo si no están conectados. Si cambias los parámetros, vuelve a guardar. Si la fecha de llegada planeada pasa, hay que actualizarla.
Se calcula con las órdenes que ya llegaron: la fecha real es la del ingreso en «Ingreso Orden Imp.» (o la que indiques en «Ya llegó»). Para medir la demora real de una importación hace falta la fecha del pedido, que se pide al cargar cada orden.
«Guardar esta proyección» deja una foto de hoy (stock, venta mensual y llegadas de cada producto). Pasadas al menos dos semanas, «Ver acierto» la compara con lo que pasó de verdad: ventas reales vs. proyectadas y stock real vs. proyectado. Sirve para saber cuánto confiar en el cálculo y ajustar la cobertura o el escenario.
El dólar final = dólar inicial + gastos. Se usa para convertir a pesos los precios en USD de las órdenes (costo puesto en bodega). Si sube el flete, cambias el gasto y recalculas el costo de las órdenes.
| Código | Descripción | Copias | |
|---|---|---|---|
| Cargando productos… | |||
Déjalo en 0 salvo que la térmica saque las etiquetas pegadas.
| Código | Descripción | |
|---|---|---|
| Cargando productos… | ||
| # | Código | Texto en el letrero |
|---|
Ej. pon "1" si un pasillo tiene un solo producto: la letra y el QR crecen para llenar toda la hoja.
Cargando productos...
Cargando...
Busca, previsualiza y envía certificados PDF a tus clientes
Cargando…
Selecciona un certificado para previsualizarlo aquí
En vivo desde buscador.mercadopublico.cl — COTs ordenadas por cierre próximo, igual que el portal.
Descarga el Excel desde mercadopublico.cl → "Ver listado completo" → "Descargar resultado en Excel" y súbelo aquí para ver todas las licitaciones sin filtro por rubros.
| Nombre / Organismo | Tipo | Presupuesto | Publicación | Cierre | Estado | Ofertas | Participar | ⭐ |
|---|---|---|---|---|---|---|---|---|
Cargando… | ||||||||
| ID ↕ | Nombre ↕ | Organismo ↕ | Fecha Cierre ↕ | Monto ↕ | Estado | Tipo | ⭐ |
|---|---|---|---|---|---|---|---|
| Cargando… | |||||||
Cotizaciones emitidas que aún no se facturan (activas y parciales): agenda la llamada o el recordatorio, registra lo que pasó y mide cuánto se cierra.
| N° / tipo | Cliente | Vendedor | Neto pendiente | Emitida · validez | Seguimiento | Última gestión | Próxima acción |
|---|
| Vendedor | Emitidas | Facturadas | Abiertas | Perdidas | Tasa de cierre | De las resueltas | Con gestión | Monto emitido | Monto facturado |
|---|
Vendedor = quien emitió la cotización (su usuario del ERP o de Kognit), no el vendedor asignado al cliente; si la emitió alguien que no es vendedor (caja, administración), cuenta para el asignado. Por fecha de emisión. Facturadas = estado COMPLETA en el ERP. Perdidas = cerradas o anuladas en el ERP, más las marcadas perdidas aquí. De las resueltas = facturadas ÷ (facturadas + perdidas), sin contar las que siguen abiertas. Para una tasa realista deja fuera los tickets (TI) con el filtro de tipos.
Cotizaciones recibidas desde el portal web. Revísalas y conviértelas a cotización formal.
Quién está ahora en allen.cl, qué mira y qué buscó. Si escribe en el chat del sitio, le llega a todos; el primero que responde se queda con la conversación (los demás la ven, pero no responden salvo que la libere). 👋 Saludar manda un solo saludo por visita. Se activa y se le pone horario en Parámetros → Sitio Web.
Compras de la tienda en que el cliente eligió pagar por transferencia. Revisa la cartola y, cuando el dinero haya llegado, presiona Confirmar pago: en ese momento se crean el cliente y la cotización en el ERP, y se envían los correos, igual que con un pago Webpay. Lo que no se confirma en 48 horas hábiles se anula solo.
RELOAD, LOCK TABLES, REPLICATION CLIENT..zip con todas las configuraciones de esta empresa (conexiones, SMTP, SII, empresa, logos…)
y la llave de cifrado .secret.key. Es lo que hace falta para levantar esta empresa
en otro servidor — junto con un respaldo de la base de datos (el botón de arriba).
Busca por número, revisa el estado actual y cámbialo. Todo cambio queda registrado (usuario, fecha/hora, IP y equipo).
El ERP solo guarda el código y el nombre de cada transporte. Aquí se anota dónde está su terminal para armar la «Ruta de transportes» del día (Despachos → 🗺️ Ruta del día → 🚛 Transportes): una parada por terminal, con los despachos facturados que hay que llevar. La hora de cierre es opcional: si el camión llegaría después, la ruta lo marca. No se modifica nada del ERP.
Reconstruye los pasos que siguió un usuario al crear una cotización o nota de venta. Sirve para diagnosticar un problema cuando no se sabe cómo ocurrió.
Usa los filtros y pulsa Buscar
Texto de la política que el usuario debe aceptar al ingresar al sistema. Al cambiar la versión, todos los usuarios deberán volver a aceptarla.
La Ley 21.719 exige no conservar datos más tiempo del necesario. Configura cuántos días se guardan los registros y ejecuta la limpieza cuando quieras.
Solicitudes recibidas de titulares que ejercen sus derechos de acceso, rectificación, cancelación/supresión, oposición, portabilidad o bloqueo de datos.
Cargando solicitudes...
Clasifica los productos para filtrar la reposición por Tipo (según la familia) y por Calidad / Espesor / Largo (detectados en la descripción). No modifica el ERP.
Configuración exclusiva del sitio web público de esta empresa — no afecta nada del ERP ni de Kognit.
Es la clave que se pide al hacer clic en "🔒 Intranet" dentro de catalogo.html en el sitio web, para desbloquear el modo administrador (ver stock/precio real, editar imágenes, marcar ofertas, etc.). No tiene relación con las cuentas de usuario de Kognit.
Cómo aparece la empresa en los correos a los clientes del sitio (confirmar cuenta, cambiar clave). Si queda vacío se usa el nombre del ERP, que a veces viene abreviado.
Cómo se llama en el menú y en el título de la pantalla donde llegan las cotizaciones y compras del sitio (ej. «Solicitudes web», «Pedidos del sitio»). Si queda vacío se llama «Leads Web». También se puede cambiar en Parámetros → Módulos del menú.
Protege el formulario de cotización del sitio contra robots. Google entrega dos claves para el dominio del sitio: la pública va en las páginas del sitio y la secreta va aquí. Si no coinciden, las solicitudes de cotización se rechazan.
La clave de Intranet siempre puede ver precio y stock exacto, sin importar esta opción.
Es un solo interruptor de 3 posiciones (no se pueden combinar entre sí) — elige la que corresponda para el público en general.
Productos marcados aquí muestran su precio real en el catálogo público (según el modo elegido arriba) y son los únicos que se pueden agregar al carrito de pago online. Propia de esta empresa — no se comparte con otras instalaciones de Kognit.
Todas las familias del inventario aparecen aquí. Apaga las que no quieras mostrar en el catálogo público (por ejemplo insumos internos o líneas que aún no quieres publicar). Por defecto se muestran todas.
?externo=1 al final de la dirección (ej. allen.cl/?externo=1): esa visita sí cuenta.Cuando alguien abre un producto en el catálogo, el sitio puede mostrar una descripción corta. La IA la escribe una sola vez por producto y queda guardada: las visitas siguientes no gastan nada, y tú puedes corregirla. Solo ve el nombre, la familia y la unidad (nunca precios, stock ni clientes). Usa la clave de Anthropic de Conexiones → Módulos; cuesta del orden de 1 a 2 USD por todo un catálogo de 2.400 productos.
El sitio intenta adivinar la foto de cada producto probando el código como nombre de archivo
(ej: código 110367 → images/110367.jpg). Si un producto no tiene una foto
que coincida así, asócialo aquí escribiendo el nombre exacto del archivo que ya subiste a la carpeta
images/ del hosting del sitio (ej: C1-06.jpg).
Permite pagar directo en el sitio (carrito 🛒 → checkout → Webpay) los productos marcados como oferta — no toda la lista de precios. Distinto de "Parámetros → WebPay" (esa es solo lectura de correos para conciliación bancaria; esto es el cobro real).
Con los dos activos, el cliente elige antes de pagar. Con transferencia el pedido queda esperando pago y no se crea nada en el ERP hasta que lo confirmes en Leads Web → 🏦 Transferencias. Si no se confirma en 48 horas hábiles, se anula solo y se avisa al cliente.
KOGNIT_URL
en el sitio (ej. https://kognit.ddns.net:8001), sin barra al final.
Agrega al checkout la elección de retiro/despacho/transporte, aviso de tubos largos, recargo de despacho en Santiago y etiqueta automática cuando la dirección de despacho es distinta a la de facturación. Apagado por defecto — actívalo recién cuando lo hayas probado.
Solo informa — no cambia el cobro real de despacho (eso lo controla "Cobrar recargo de despacho" arriba).
Los mensajes se escriben abajo. Los datos entre llaves se completan solos con lo configurado en esta página, así el aviso nunca queda desactualizado.
{zona} las comunas de despacho (ej. «Santiago y sus comunas vecinas») ·
{monto_gratis} el monto desde el que el despacho es gratis ·
{costo} el costo del despacho bajo ese monto ·
{gratis} la etiqueta verde «GRATIS» ·
{mapa} el enlace «Ver mapa de comunas».
Para negrita, escribe entre asteriscos: *así*. Un mensaje con {monto_gratis} o {costo} no se muestra si el cobro de despacho está apagado.
El stock del ERP no siempre calza con la bodega, y el ERP lo descuenta recién al facturar. Por eso el sitio ofrece para compra en línea: stock del ERP − lo apartado − un margen de seguridad. El cliente nunca ve la cantidad: ve «Disponible», «Pocas unidades» o «Sin stock» / «A pedido».
El correo de confirmación de compra online se envía al vendedor asignado del cliente (con copia a la empresa). Si un vendedor no tiene email cargado aquí, la confirmación llega solo a la empresa.
Visitas del sitio web que vieron precios: el cliente (si inició sesión), desde dónde entró (ciudad aproximada, según su conexión a internet), con qué aparato y qué productos abrió. Los anónimos aparecen cuando pulsan «Ver precio». Las visitas de la red de la empresa no cuentan. El primer ingreso del día de un cliente registrado se avisa por mensaje interno a los superadmin.
Cuando está activo, al recibir un lead desde allen.cl se crea automáticamente la cotización en el ERP y se envía el PDF al cliente por email.
Cuentas creadas en el sitio (registro + verificación por email) — ver quién se registró, su estado, y verificar/bloquear a mano si hace falta.
El RUT no se puede duplicar (una sola cuenta por RUT). El ícono ⚠️ marca cuando el mismo email, teléfono o nombre aparece en OTRO RUT distinto — no se bloquea (hay casos legítimos), pero conviene revisarlo a mano.
| RUT | Nombre | Teléfono | Estado | Creado | Verificado | Último login | |||
|---|---|---|---|---|---|---|---|---|---|
| Cargando… | |||||||||
| Código | Descripción ▲ | U.M. | Precio 1 | Precio 2 | Costo | Stock | Vendidos | Bod.1 | Bod.2 | Bod.3 | Familia | Estado |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Cargando... |
||||||||||||
Texto que los usuarios deberán aceptar al conectarse.
Aplica a todos los usuarios. Al desmarcarlo desaparece el botón verde de
WhatsApp en la fila del Historial y también dentro de «Ver cotización»
—son el mismo flujo, así que esconder solo uno no serviría de nada—.
No afecta al modal que sale justo después de guardar una cotización nueva: ahí
el envío es lo que acabas de pedir, no un atajo. Tampoco toca el aviso de despachos
por WhatsApp, que tiene su propio permiso por usuario.
Hoy el PDF se copia al hosting y el WhatsApp apunta a esa copia. Al ser una
copia, se queda vieja: si modificas la cotización, el cliente sigue viendo los
precios anteriores.
Con el enlace directo el PDF se genera al momento desde este servidor, así que
siempre está al día y no hace falta subir nada. A cambio, el enlace solo abre si
este servidor está accesible desde internet — y eso vale también para los enlaces
que ya enviaste. Los PDF ya subidos al hosting no se tocan y siguen funcionando.
Cambia cómo se denomina el documento en el menú, historial, PDF y correos.
Cómo se muestra el número en el Historial y demás listas de pantalla. No cambia el número real: el PDF, el ticket de picking, los correos y el WhatsApp siguen usando el completo, y la búsqueda sigue aceptándolo entero.
Nombre de la pestaña "Impacto Ventas" en Informes (antes "Importancia de vendedores").
Si una cotización supera este plazo sin cambio de estado, recibirás un aviso para cerrarla.
Define qué fecha se usa para clasificar facturas, boletas y notas de crédito en todos los informes (Ventas, Comisiones, Estadísticas, Facturas, Despachos).
Define de dónde se toman las notas de crédito del cliente al Registrar un pago en el Libro de Ventas.
genc_enc; se ocultan los saldos NCR de gepagos_ant. Úsalo si ya no trabajas con gepagos_ant.| RUT | Nombre | Giro | Ciudad | Saldo | Contacto | Acciones |
|---|---|---|---|---|---|---|
Cargando... | ||||||
| RUT | Nombre | Ciudad | Lista P. | Vendedor | Acciones | |
|---|---|---|---|---|---|---|
|
Cargando... |
||||||
| Código | Nombre | Celular | Teléfono | Estado | Acciones |
|---|---|---|---|---|---|
|
Cargando... |
|||||
Árbol jerárquico — 5 niveles según código. La columna Comisión se usa para calcular el sueldo de vendedores.
Los datos de la empresa se leen del ERP
(tabla geparam) según la base activa. Aquí solo se administra el logo.
Al guardar una cotización en el ERP, su PDF se sube automáticamente al hosting (por base de datos). El nombre del archivo es el N° de la cotización.
cotclientes de tu hosting (vía cPanel → Administrador de archivos).| Código | Nombre | Rol | Permisos | Vendedor | Correo | 🔒 Política | Estado | Creado | Acciones | |
|---|---|---|---|---|---|---|---|---|---|---|
|
Cargando... |
||||||||||
Cargando…
Descarga el Registro de Compras y Ventas del SII (año completo) a Excel.
Usa login automático con la clave guardada, o ingresa la cookie manualmente.
El Registro de Compras y Ventas (RCV) es el libro tributario electrónico que el SII mantiene con todos los documentos tributarios emitidos y recibidos por la empresa durante el año.
Al descargar el RCV obtienes un Excel con las compras (facturas de proveedores) y ventas (facturas emitidas) del año seleccionado, directamente desde el portal del SII.
⚠️ Este Excel es solo para tu respaldo/uso externo — descargarlo acá NO carga nada en Kognit. Para que las compras/ventas/boletas del SII aparezcan en el Libro de Compras, Ventas SII, Boletas SII y en Informes → Resumen SII, usa el botón "🔄 Actualizar desde SII" que tiene cada una de esas pantallas (en Documentos Emitidos) — ese sí guarda los datos en Kognit.
💡 Tip: guarda la clave del SII en ⚙ Configurar para que el login sea automático (sirve tanto para este Excel como para los botones "Actualizar desde SII" de las otras pantallas).
stock-modo y validez).paquete_kognit_vX.zip (lo arma herramientas/paquete.py), revisa cada archivo ANTES de escribir (un app.py con error, un JSON con BOM o un archivo de configuración de una empresa se rechazan y no se sube nada), respalda lo que reemplaza, reinicia y muestra la versión que quedó corriendo en cada empresa. Nuevo botón «Volver a la versión anterior».compra.css y compra.js; el funcionamiento no cambia. Respaldo de las páginas anteriores en Sitio web allen/respaldo-antes-rediseno-compra-2026-09-29. Subir al hosting: compra.css, compra.js, checkout.html, cuenta.html, pago-resultado.html y mi-cuenta.html./despachos) con mapa de las comunas de despacho, costo, horarios y formas de entrega. Todo se lee de Kognit (Parámetros → Sitio Web): si cambias la lista de comunas, el mapa se acerca solo a esa zona. Límites comunales oficiales en comunas-rm.json. Enlace «Despachos» en el menú de la portada y del catálogo, «Ver comunas» en el checkout ; la página de ingreso quedó solo con «Iniciar sesión» y «Crear cuenta». En las páginas de compra, el logo oficial reemplaza al texto del encabezado, y la página de ingreso dice «¡Bienvenido!» y muestra solo el formulario.banner-despacho.js, cargado en index.html y catalogo.html: lee /api/publico/tienda-config y muestra la barra azul arriba de la página según el modo (No mostrar / Solo clientes registrados / Todo el sitio). Tiene "×" para cerrarlo (no vuelve a aparecer mientras la pestaña siga abierta). Si Kognit no responde, el sitio se ve igual que siempre, sin banner. No requirió cambios en la CSP del .htaccess. Hay que subir al hosting: banner-despacho.js, index.html, catalogo.html._es_region_metropolitana) y rechaza el pedido aunque alguien se salte la pantalla./api/tienda/pedido) ya no rechaza productos sin oferta — cobra lista 1 sin descuento; sin sesión de cliente nada cambia (el pedido la exige desde antes). Probado en vivo: sin sesión 0 comprables; con la sesión del cliente de prueba, 1.956.sesion-cliente.js).vendedor/forma_pago/modalidad_entrega/privacidad_aceptada_en. Mi Cuenta permite cambiar esas preferencias. Probado en vivo con un RUT temporal (rechaza sin tipo, Factura sin giro y sin aceptar privacidad; guarda todo lo demás) — borrado al terminar.sii_actividades.json, por código o texto), dirección, ciudad, comuna, región (obligatorias, validado también en el servidor), contacto, email, teléfono y celular — ordenados en grilla. Nuevas columnas contacto/celular en web_clientes. Si un cliente del ERP no tiene algún dato en su ficha (ej. giro), ese campo queda editable para completarlo.mi_cuenta_despachos_modo).sesion-cliente.js, campo boton_cuenta_modo.)cot_web_pedidos.notas_entrega), en la observación de la cotización del ERP y de la solicitud web, y aparecen 📝 en la Ruta del día para el chofer.gecli se crea su ficha con los datos del registro (razón social, giro, dirección, comuna/ciudad/región con sus códigos del ERP, email, teléfono, celular, contacto, vendedor, forma de pago), categoría GENERAL, lista de precio 1 y activo — con la misma función del mantenedor de clientes. Se crea al PAGAR, no al registrarse, para no llenar el ERP de gente que solo mira precios. Si el RUT ya es cliente no se toca. Probado en vivo con un RUT temporal (ficha completa con comuna Providencia y región 13; una segunda compra no la duplica) — borrado al terminar.https://www.allen.cl/catalogo.html, así que Kognit mandaba al cliente a /catalogo.html/pago-resultado.html, que no existe. Ahora Kognit se queda solo con el dominio (https://www.allen.cl) aunque se escriba una página o carpeta al final, al guardar y al usarlo.cot_geocache_dir). Configurable en Modalidad de entrega: dirección de salida (vacío = la de la empresa), velocidad, minutos por parada y aviso a clientes. Tabla cot_despacho_rutas; endpoints GET/DELETE /api/despachos/ruta, POST /api/despachos/ruta/generar.cot_web_pedidos_agenda_log) y se avisa por correo al cliente y a la casilla de avisos de la tienda. La tarjeta de Despachos en Kognit muestra siempre la fecha vigente. Endpoints GET /api/tienda/mi-cuenta/entregas, …/entregas/{id}/agenda y POST …/entregas/{id}/reagendar. Probado en vivo: pedido a 3 días se reagendó; pedido de mañana bloqueado ("menos de 24 horas"); otro RUT no puede tocarlo (404). Pedidos de prueba borrados.GET /api/publico/agenda-despacho?modo= entrega los días y bloques con cupo; /api/tienda/pedido revalida la fecha elegida (si otro cliente tomó el último cupo mientras pagaba, responde 409 y el checkout recarga el calendario). Un pedido pendiente de pago reserva el cupo 30 minutos. Nuevas columnas agenda_modo/agenda_fecha/agenda_bloque en cot_web_pedidos.kognit.html, sin tocar el endpoint.hon_boletas, módulo aún en revisión) — no tenía sentido usar el mapeo Categoría→Cuenta del Libro de Compras para esa cuenta puntual.
rut_profesional+nombre_profesional) sumando el monto BRUTO de cada boleta — es el gasto real que se reconoce (Debe "Honorarios"); la retención es un pasivo aparte (Haber "Retención por pagar"), nunca reduce el gasto.3010003) es la única excepción, resuelta en el mismo endpoint GET /api/contabilidad/estado-resultados/detalle-cuenta (nueva rama por fuente, sin tocar la rama de compras existente).gediario — este desglose asume que lo anotado ahí coincide con lo que después se contabiliza a mano en el ERP, algo que todavía no se ha terminado de revisar con datos reales completos.GET /api/tienda/mi-cuenta/{cotizaciones,facturas,despachos}) aceptan desde/hasta; mandar ambos vacíos explícitos pide el historial completo sin filtro.gecot_det + geitems_mae (nunca un JOIN con TRIM() sobre toda la tabla — mismo criterio preventivo de siempre, eso colgó Gamspa una vez) para traer los productos reales de TODAS las cotizaciones visibles en un solo viaje. Probado en vivo: una cotización real ahora muestra sus 4 productos con nombre y cantidad, en vez de "0 producto(s)".window.open() DESPUÉS de esperar la respuesta del servidor (await) — Safari y varios bloqueadores de ventanas emergentes solo confían en una ventana abierta directo por el clic del usuario, y una abierta después de un await pierde ese permiso y queda bloqueada en silencio. Corregido: la pestaña se abre vacía en el mismo clic, y se le asigna el PDF apenas llega.gecot_enc.COREG (texto libre en esta base — cubre "Metropolitana", "Metropolitana de Santiago" y hasta "METRPOLITANA" con error de tipeo, buscando "METR"); si la región es desconocida, avisa igual que en RM (nunca se suprime por duda). Probado con una cotización real de Biobío.analisis_cat, con su propio botón 📌 y su propia tabla de predeterminado por proveedor (cot_rcv_prov_analisis_cat), totalmente independiente del 📌 de "Cuenta" — fijar una nunca toca la otra. Lista editable en el mismo modal de configuración que ya tenía "Cuentas".analisis que ya existía — nunca se fija por proveedor, siempre en blanco hasta que se escribe a mano en cada documento, con las direcciones/detalles ya usados antes apareciendo como sugerencia (datalist) para no re-tipearlos.detalle_por_mes), así que hacer clic en cualquier barra cambia el detalle al instante, sin otro viaje al servidor.gecuentas) a la que pertenece — varias categorías pueden compartir la misma cuenta (ej. Agua y Luz → "Gastos Generales"). En Contabilidad → Estado de Resultados, hacer clic en cualquier línea de cuenta abre un desglose por categoría de ese período (como ya hace el CRD con los meses).
GET /api/documentos/rcv-config/cuentas-gasto (solo admin) para poblar ese selector con las cuentas de gasto reales.GET /api/contabilidad/estado-resultados/detalle-cuenta: para una cuenta y un rango de fechas, agrupa el Libro de Compras por categoría (heredando la categoría predeterminada del proveedor cuando el documento no la tiene marcada), sin IVA (crédito fiscal aparte, mismo criterio que la centralización por cuenta), y lo compara contra el monto real de esa cuenta en gediario.<optgroup>), por si alguna categoría necesita asociarse a una cuenta que no sea de gasto. Endpoint renombrado a GET /api/documentos/rcv-config/cuentas-contables.gediario: 46.000+ líneas desde 2009, con Debe/Haber por asiento) y un plan de cuentas (gecuentas, 173 cuentas) — este módulo nuevo es de solo lectura: nunca crea ni modifica un asiento, solo lee y suma lo que el contador ya registró en el ERP de escritorio.
gecuentas.CTNIVEL nunca se usó en esta base) — mismo patrón de árbol por prefijo que ya usa el sistema para familias de productos.GET /api/contabilidad/plan-cuentas, /diario, /mayor, /balance (archivo nuevo contabilidad_router.py, mismo patrón que Remuneraciones/Bodega).GET /api/contabilidad/balance-8-columnas._ER_SECCION) para poder ajustarlo en un solo lugar si el contador clasifica distinto alguna cuenta. Cualquier cuenta con movimiento que no esté en el mapeo cae en "Sin clasificar" (nunca se pierde en silencio) y se avisa en pantalla. La utilidad final se verifica cruzada contra el mismo Ingresos−Gastos calculado sin pasar por ninguna sección — probado en vivo (ene-abr 2026): calza exacto con el Balance 8 Columnas, $82.119.725. Nuevo endpoint GET /api/contabilidad/estado-resultados.gediario (el mismo libro que usa el ERP de escritorio).
gediario no tiene ninguna restricción única en la base de datos — se avisó este riesgo al usuario antes de construirlo, y se decidió aceptar el riesgo residual de choque con el ERP de escritorio en vez de reservar un rango propio (alternativa también evaluada). Si se detecta un posible choque justo después de guardar, se avisa en pantalla para revisar el número en el ERP.cot_contabilidad_asientos_log, no toca el esquema del ERP) para saber después quién creó cada comprobante desde acá — gediario no tiene columna de usuario/origen.CREATE TABLE IF NOT EXISTS hace un COMMIT implícito en MySQL — al crear la tabla de auditoría DESPUÉS de insertar las líneas del asiento, un rollback posterior ya no alcanzaba a deshacer el insert en gediario. Se detectó con la prueba (quedaron 2 filas reales de prueba, borradas de inmediato) y se corrigió moviendo el CREATE TABLE al principio, antes de tocar cualquier dato contable real. Nuevo endpoint POST /api/contabilidad/asiento.honorarios_router.py, tabla propia hon_boletas), permiso propio "Honorarios", 100% ingreso manual por ahora — queda pendiente investigar si el SII tiene una consulta programable de boletas recibidas (como ya existe para el Registro de Compras y Ventas) para traerlas automáticas más adelante.GET /api/contabilidad/dashboard-gastos?meses=.GET /api/contabilidad/flujo-de-caja.GET /api/contabilidad/balance-general.fecha_comparacion opcional; sin él se comporta exactamente igual que antes (una sola fecha). Probado en vivo: 24-sep-2026 ($34.276.675.129) vs. 31-dic-2025 ($30.731.947.962), cuadrado en ambas fechas.cot_web_leads, pendientes y convertidas), sus facturas con descarga de PDF (mismo mecanismo ya probado de Facturas Emitidas, con doble chequeo de que esa factura sea realmente suya antes de servir el PDF) y el estado de despacho de sus pedidos (misma información que hoy ve un vendedor en la pantalla de Despachos, pero filtrada a lo suyo).web_cliente_router.py, tabla web_clientes. Nuevos endpoints POST /api/tienda/registro, GET /api/tienda/verificar, POST /api/tienda/reenviar-verificacion, POST /api/tienda/login, GET /api/tienda/mi-cuenta/{perfil,cotizaciones,facturas,despachos} — todos bajo el prefijo público /api/tienda/ que ya existía para el carrito, con autenticación propia del cliente adentro de cada uno.web_clientes./api/tienda/pedido ahora exige _cliente_guard() (401 sin sesión de cliente) y que el RUT del pedido coincida con el RUT de la cuenta logueada (403 si no calza, para que nadie compre a nombre de otra empresa con solo escribir otro RUT). El gate del checkout en pantalla ya mandaba el token; esto lo hace exigible de verdad — el mismo criterio que ya se usaba para "tienda activa" ("no basta con ocultar el botón"). Probado: rechaza sin sesión, rechaza token de personal (no sirve para comprar), rechaza RUT distinto al de la cuenta.gecli.CLIMAIL) → email del lead web de origen si el pedido vino del sitio. Si no hay ningún correo, no se envía nada pero igual queda registrado el intento.gecot_enc.COREG (texto libre en esta base — se vio "Metropolitana", "Metropolitana de Santiago" y hasta "METRPOLITANA" con error de tipeo, cubiertas las tres buscando "METR"); si la región viene vacía o desconocida, se prefiere avisar igual que en RM, nunca suprimir por duda. Probado con una cotización real de región (Biobío): no avisó en "preparado", sí intentó avisar en "entregado_transporte" (llegó a buscar el correo, quedó registrado que ese cliente no tenía ninguno cargado — no es un fallo del filtro).cot_despacho_avisos (log, nunca se borra) y endpoint GET /api/ventas-gefac/despacho-avisos?conros=, traído en un solo request por cada carga del tablero (no uno por tarjeta).boucher pero NO el estado si el despacho ya tenía una fila previa con otro estado — quedaba con la foto de entrega pero sin pasar a "Entregado al transporte". Corregido para que suba el voucher SIEMPRE marque ese estado, sin importar el que tuviera antes.gecli, registró el intento, y el endpoint de consulta lo devolvió bien — datos de prueba borrados de cot_despacho_avisos al terminar.gecli.CLIEMAIL no existe (es CLIMAIL). Encontrado revisando el código al construir el aviso de arriba. Dos lugares reales afectados: GET /api/cliente-info estaba roto al 100% (pedía también CLICIUDAD, que tampoco existe — es CLICIU, un código) y siempre tiraba 500, así que el panel de cliente del Kardex nunca mostró ciudad/email/dirección de nadie; corregido con el mismo patrón robusto que ya usa /api/cliente/{rut} (JOIN a geciu para el nombre real de la ciudad). El segundo, en GET /api/cotizaciones/{cot_id} (sistema nuevo), fallaba en silencio dentro de un except desnudo. Probado en vivo: /api/cliente-info ahora devuelve ciudad, email y teléfono reales.cuenta.html → POST /api/tienda/olvide-clave (respuesta siempre genérica, no revela si la cuenta existe) → correo con enlace de un solo uso, vence en 2 horas (más corto que el de verificación, por ser un cambio de clave) → página nueva restablecer-clave.html → POST /api/tienda/restablecer-clave.token_verificacion/token_expira de web_clientes (en una cuenta ya verificada quedan libres) — no hizo falta agregar columnas nuevas.ver_precision_proyeccion y ver_resumen_sii (grupo "Informes", mismo mecanismo de Grupos de Permisos que los demás) — el admin puede otorgarlos puntualmente a un vendedor sin darle el rol completo.
_vendedor_permitido()/_faven_permitido(), así que un vendedor sin permiso de admin solo puede ver SUS propios datos aunque manipule el selector de vendedor o la URL. No hizo falta tocar nada ahí, solo se confirmó.web_precio_clientes_registrados (booleano, independiente de web_mostrar_precio). mostrar_precio_item ahora es true si el modo del público lo permite O si este interruptor está activo y hay una sesión de cliente verificada — se combinan con "o", nunca se pisan._cliente_web_opcional(request) — como _cliente_guard pero NUNCA lanza 401 (un visitante sin cuenta en el catálogo público es normal, no un error), reutiliza el mismo JWT/secreto que ya firma las sesiones de "Mi Cuenta" y de personal (solo cambia el claim tipo), así que un token de un vendedor logueado en Kognit NO cuenta como cliente para esto.catalogo.html) manda el token del cliente en el header Authorization junto con la clave de Intranet si la hay — ambos pueden convivir.gecli): se le muestran sus datos reales (razón social, giro, dirección, comuna/ciudad/región — resolviendo los códigos a nombre real, mismo patrón que /api/cliente/{rut}) para que solo los confirme, en vez de volver a tipearlos.cot_web_leads, como antes) MÁS las cotizaciones reales ya creadas en el ERP por ese RUT (gecot_enc) — sin duplicar las que ya se convirtieron desde un lead web. Antes un cliente antiguo que nunca pidió nada por el sitio veía la pestaña vacía pese a tener historial real.web_clientes (tipo_documento, giro, direccion, comuna, ciudad, region, datos_fact_confirmados_en), nuevos endpoints GET/POST /api/tienda/mi-cuenta/facturacion.gecli y sus cotizaciones reales combinadas correctamente; probado también que Factura sin giro se rechaza y Boleta sin giro se acepta — datos de prueba borrados al terminar.GET /api/mantenedor/clientes-web y PUT /api/mantenedor/clientes-web/{id}/estado — a propósito NO viven bajo /api/tienda/ (ese prefijo es público, sin sesión de personal): esto es información interna, protegida igual que cualquier otra pantalla de Kognit. Nunca expone la clave del cliente ni el token de verificación.
/api/tienda/ solo permitía las cabeceras Content-Type, X-Admin-Key — nunca Authorization, que es justo la que usa "Mi Cuenta" para identificarse. Por eso el login (que no manda esa cabecera) funcionaba, pero cualquier pantalla de "Mi Cuenta" (cotizaciones/facturas/despachos) fallaba en el navegador con "Failed to fetch" antes de llegar al servidor. Corregido agregando Authorization a Access-Control-Allow-Headers. De paso, mi-cuenta.html ahora distingue un error de conexión real ("No se pudo conectar con el servidor") de una lista vacía, en vez de mostrar el texto crudo del navegador.allen.cl y kognit.ddns.net esa cookie sería de terceros y Safari (y parte de Chrome) la bloquean por defecto sin aviso — se habría roto el login para una parte real de los visitantes a cambio de una protección parcial. Se optó por reforzar la causa en vez del síntoma: Content-Security-Policy en .htaccess (con mod_headers), cuyo connect-src es lo más importante — aunque un script ajeno lograra ejecutarse en la página, solo puede mandar datos a los dominios de la lista (Kognit, Google Analytics/Tag Manager), nunca a un servidor de un atacante. Se armó revisando los dominios externos reales que usa cada página (fuentes, Google Tag Manager/Ads, mapa embebido, formulario de pago a Transbank) para no romper nada. Más X-Content-Type-Options, X-Frame-Options, Referrer-Policy — mismo criterio que ya tiene el backend de Kognit.cuenta.html no mostraba nada. El CSS tenía #panel-registro { display:none } y el JS lo "mostraba" con style.display='' — pero un style.display vacío no le gana a una regla CSS por ID, así que el panel quedaba oculto para siempre sin importar la pestaña activa. "Iniciar sesión" sí se veía porque no tenía esa regla. Corregido usando 'block'/'none' explícitos en vez de ''/'none'. Encontrado por el usuario probando el flujo real.allen.cl/api/tienda/verificar), pero /api/ vive en el backend de Kognit, no en el hosting de Apache — nunca iba a existir esa ruta ahí. Corregido: el enlace ahora usa la URL real de Kognit (reutiliza el campo "URL de Kognit" ya configurado en Parámetros → Sitio Web → Transbank). La página de resultado (cuenta-verificada.html) sí queda en el sitio estático, sin cambios. Encontrado por el usuario probando el flujo real, corregido y verificado el mismo enlace armado.Sitio web allen\nuevo\ que consumen los endpoints de web_cliente_router.py.
cuenta.html (rutas limpias /cuenta): login + registro con pestañas, guarda el token del cliente en localStorage (separado del carrito y de cualquier sesión de personal).mi-cuenta.html (/mi-cuenta): panel con 3 pestañas — Mis cotizaciones, Mis facturas (con botón para ver el PDF, traído por fetch con el token en el header, nunca en la URL) y Estado de despacho — todo lo que trae el backend, filtrado a lo del cliente.cuenta-verificada.html (/cuenta-verificada): pantalla de resultado del enlace de confirmación por correo (éxito o enlace vencido/ya usado).catalogo.html, checkout.html, pago-resultado.html) YA estaban construidos completos desde antes (v1.0.736) — casi no habían quedado documentados. checkout.html se modificó para exigir sesión de cliente antes de mostrar el formulario de pago (a pedido del usuario: "obligatorio para comprar") — si no hay sesión, muestra un aviso con enlace a /cuenta?next=comprar y, al volver logueado, el carrito sigue intacto (vive en localStorage, nunca se pierde) y el formulario se precarga con los datos de la cuenta.POST /api/cxc/evaluar-credito-ia, protegido por el mismo permiso cxc de siempre.GET/POST /api/config/ia-credito. Importante: requiere una cuenta de API de Anthropic propia (console.anthropic.com), separada de cualquier suscripción de Claude/Claude Code — se cobra aparte por uso, aunque para este caso puntual el costo real es de centavos al mes.GET /api/informes/clientes-nuevos, filtrado por vendedor del lado del servidor (un vendedor no-admin solo ve sus propios clientes nuevos, no puede forzar el parámetro de la URL).GET /api/informes/clientes-nuevos acepta desde/hasta (o mes, por compatibilidad) y devuelve el detalle mes a mes por cliente más el bloque dashboard.display:flex sin dirección de columna) y un estilo puesto directo en el HTML le gana a cualquier regla externa — se corrigió forzando la dirección vertical con !important.GET /api/informes/clientes-inactivos.table-layout:fixed y ajuste de margenes/tamaño de letra pensado para hoja carta (@page{size:letter}), para que las columnas se acomoden al ancho de la página en vez de desbordarse..xlsx con el mismo listado que se ve en pantalla — en "Clientes Nuevos" con una segunda hoja "Compras por mes" (una fila por cada mes en que un cliente volvió a comprar, con el detalle de productos). Nuevos endpoints GET /api/informes/clientes-nuevos/excel y GET /api/informes/clientes-inactivos/excel, mismos filtros y misma seguridad por vendedor que sus versiones en pantalla.gecli.CLIVEN), que puede haber cambiado desde entonces. Ahora muestra el vendedor que quedó registrado en la factura/boleta de esa última compra (cae al vendedor asignado en la ficha solo si el documento no tiene uno registrado).gecli.CLIREG) — para saber si el problema de clientes que dejan de comprar está concentrado en una zona o vendedor puntual. Se agregó también al Excel (columna "Zona" y una hoja "Por vendedor y zona" con los mismos totales).1”X3", la comilla curva de un autocorrector) en vez de la comilla recta que se usa para medir. Según el caso, el producto desaparecía del informe sin aviso, o —peor— tomaba por error un número de más adelante en la descripción (el largo) como si fuera el diámetro.3/8X1/4"), pasaba algo parecido al bug de Bushings del día anterior pero más grave: un Niple de 3/8" se leía como si fuera de 8", un número completamente distinto y sin ningún aviso.X3", X 3" con espacio de más, X3 sin la comilla de cierre) — como Kognit dejaba ese texto tal cual para armar la tarjeta, cada forma quedaba en su propio grupo. Ahora se reconocen las 3 formas como la misma medida.UC-1"304). El código se veía bien en el modal, pero al guardar el modal decía que no existía.
1") cortaba el valor a la mitad antes de mandarlo al servidor, así que buscaba un código que no existía. Corregido.1X3", 2X4" — la única comilla de la descripción es la del largo, al final), el informe no reconocía NINGUNA medida en ese producto y lo dejaba completamente afuera, no solo mal agrupado.
gefac_enc.FANROCOT, el mismo que ya se usaba para saber si la cotización de origen tenía despacho) pero se descartaba antes de armar la respuesta — ahora se expone y se muestra chico, debajo del N° de factura ("Cot./NV 12345"), solo cuando la factura quedó enlazada a una.0, no vacío — sin el chequeo explícito se habría mostrado un falso "Cot./NV 0" en cada una de esas filas. Encontrado por el checker antes de llegar a producción..secret.key. Ahora un botón arma un .zip con eso (configs de conexiones, SMTP, SII, empresa, logos… + un instructivo de restauración). No incluye los dumps .sql.gz (van con el otro botón), los logs, ni las carpetas de documentos subidos. Solo superadmin, con aviso de que el zip contiene la llave que descifra las contraseñas guardadas.DATE(), que en MySQL 5.5 impide usar el índice. También se agregó un registro del tiempo de cada consulta, para diagnosticar de una si vuelve a fallar.ocultar_reposicion, ocultar_importaciones, ocultar_kardex, ocultar_analisiscv), visibles en la matriz de Grupos de Permisos desde antes — no se tocó nada ahí, para no duplicar.ver_inv_productos, ver_inv_paridad, ver_inv_listasprecios), todos nacen ocultos por defecto (hay que activarlos a propósito, a pedido explícito del usuario) y aparecen automáticamente en Grupos de Permisos — la matriz ya se arma sola a partir de la lista de permisos, no hizo falta tocar esa pantalla.ocultar_costo_paridad) que, cuando está marcado para un usuario sin rol admin, deja esa casilla SIEMPRE marcada y bloqueada — no se puede destildar. Solo tiene efecto real una vez que ese mismo usuario también tenga acceso a ver esas pantallas (con los permisos nuevos de arriba).(precio-costo)/costo) y una nueva tomando el costo, dividiéndolo por el precio de venta y sacando la diferencia contra 1 (margen sobre el precio de venta: 1-(costo/precio)), ambas en porcentaje.
precio × (1-0,58)) no daba el costo real, daba 1.430 en vez de 1.434.
precio = costo / (1 − margen/100) — para ver cómo quedan antes de decidir si se guardan.
_lp_data) el cálculo que ya usaba el endpoint de pantalla, para que el PDF nunca pueda mostrar un número distinto del que ya se ve en la pantalla.gecot_enc) traía como máximo 2.000 filas, ordenadas por fecha, antes de que el usuario eligiera cómo ordenar la pantalla — con el rango de un mes completo, una empresa con actividad normal supera fácil esa cantidad entre ambos sistemas, y las cotizaciones más antiguas del rango quedaban fuera del conteo total sin ningún aviso.cot_cabecera, nunca tuvo ningún tope) en vez de sacarlo del todo, para seguir protegido si alguna vez se elige un rango de fechas verdaderamente enorme por error.gepagos.PACLI) contra la ficha de clientes, en vez de por el documento que realmente se estaba cobrando — y ese mismo RUT tiene en gecli una fila de Cliente ("SPA") y una de Proveedor ("COM. E INDUSTRIAL") con razón social distinta cada una (confirmado por el usuario: no es un error de datos, es real que existen ambas fichas para ese RUT).geitems_cod, la tabla que ya existe justo para el caso de que cada proveedor use su propio código); y en "Ingreso Orden de Importación", junto al Excel de siempre, dos formas nuevas de cargar el detalle: subir a mano el XML descargado del SII, o intentar traerlo directo reutilizando la misma sesión del SII que ya usa Libro de Compras (sin pedir usuario/clave de nuevo).PUT nuevo con el mismo criterio de ciudad/comuna/región ya corregido para clientes, y que solo toca fichas de tipo proveedor — nunca un cliente con el mismo RUT.id y el folio del documento — se leen todos de una pasada. Por cada documento, dos peticiones más (un token de seguridad que se genera al momento + el XML real) devuelven el mismo formato estándar del SII, así que se reutilizó tal cual el mismo lector construido ayer.cxc_asignar_nc_erp, cxc_asignar_saldo_erp, _aplicar_saldo_ant_a_doc) guardaban el medio de pago como "nc" — un valor que nunca existió en los diccionarios que usan tanto la Planilla de Caja como el Libro de Ventas (solo tenían "saldo_favor"), así que ambos caían en silencio al valor por defecto ("Transferencia"). Se agregó "nc" como alias reconocido en los dos lados (backend y frontend) — corrige también los pagos ya guardados así antes, sin necesidad de tocar datos viejos.except: pass mudo — si esa escritura fallaba por cualquier motivo, el pago real quedaba perfecto en el ERP (por eso "el registro en el ERP está OK") pero la Planilla de Caja no se enteraba nunca y mostraba la factura pendiente para siempre, sin dejar ningún rastro del motivo. Ahora ese error, si vuelve a pasar, queda registrado en el log del servidor en vez de desaparecer en silencio.conciliacion_guardar escribía el NCR en gepagos con el monto de la NC tal cual llegaba del navegador, sin topar contra lo que el documento realmente debía (_doc_pendiente_erp). Una factura de $138.664 pagada con NC por $257.587 quedaba en gepagos con los $257.587 completos aplicados a ese único documento, y el sobrante de $118.923 desaparecía sin convertirse nunca en saldo a favor. Se extrajo el núcleo real (tope + excedente a gepagos_ant, con auditoría y cierre de la NC) que ya usaba /api/cxc/asignar-nc-erp a una función compartida (_aplicar_nc_a_doc), reutilizada ahora también por "Registrar pago" del Libro de Ventas — el bookkeeping propio de Kognit (cot_nc_aplicada) también pasó a guardar lo realmente aplicado, no lo pedido.gepagos pero con PATIPODOC='FAC' (la clase genérica del Libro de Ventas) en vez del tipo real del documento (FEL/FEC/etc.) — un valor que el ERP nunca usa. Eso lo volvía invisible para todo lo que cruza por tipo exacto: el Estado de Cuenta de CxC mostraba "$0 abonos" aunque el pago existiera en gepagos, y al eliminar el pago, _anular_pago_erp_kognit (que busca por el tipo real) tampoco lo encontraba — la NC quedaba "CERRADA" para siempre en vez de volver a estar disponible. Corregido resolviendo el PATIPODOC real (_resolver_patipodoc) antes de aplicar la NC, en vez de pasarle la clase genérica.INSERT principal de conciliacion_guardar ya fijaba cot_concil_banco.nc_aplicada con el total pedido por el navegador, y el propio _aplicar_nc_a_doc volvía a sumar el monto real aplicado sobre ese mismo valor. Se separó en dos campos: nc_previa (lo ya aplicado por una operación anterior, que sí se preserva) y lo que aplica esta operación, que ahora solo lo suma el propio _aplicar_nc_a_doc — nunca el INSERT principal.gepagos, la marca PAESTADO='EL' (eliminado) — y dos consultas de la Planilla de Caja leían gepagos sin filtrar ese estado, a diferencia de todas las demás consultas del sistema (Libro de Ventas, CxC, etc.), que sí lo hacen. Corregido agregando el filtro que faltaba en ambas._anular_pago_erp_kognit (la función que anula el pago en gepagos al eliminarlo) tenía todos sus pasos bajo un solo except: pass mudo, y el paso que libera la NC asociada corría antes que el paso que anula el pago principal — si ese primer paso fallaba por cualquier motivo, la función se detenía ahí en silencio y ni siquiera llegaba a anular el pago. Se separó cada paso en su propio try/except con log, con el paso crítico (anular el pago real) primero e independiente de los pasos secundarios (liberar NC, anular anticipos).VMSMS19-316L, 20020-25, VM11/4"316LSS, VMSMS101-316LS, etc.).
20020-XX, VMSMS101-316LS) habían quedado clasificados en una familia distinta a la de su gemelo — calidad, medida y serie calzaban perfecto, pero la familia no, así que nunca se juntaban. Se corrigió agrupando solo por serie, sin exigir la misma familia (el ITFAM que se muestra en el encabezado de cada serie ahora es solo informativo, tomado del primer producto del grupo).geitems_mov, salidas por venta) — para acotar la comparación a lo que de verdad se está moviendo, o al revés, a lo que dejó de venderse.colspan) no coincidía con las columnas que la tabla realmente pintaba fila por fila, y el navegador corría todo lo que venía después para acomodarse. Corregido contando también Stock (y la nueva columna Vendido, ver abajo).fetch aparte que se quedaron sin el filtro (_vQS) al agregarse — un vendedor sin permiso de admin veía ahí el total de toda la empresa. Corregido, y de paso el backend de /api/informes/facturas-erp-vendedor ganó el parámetro vendedor que nunca tuvo.ver_etiquetas_letreros (Parámetros → Usuarios), por defecto solo admin/superadmin — antes esa pestaña se veía igual para cualquiera con acceso a Inventario.CONTEXTO_SISTEMA_COTIZACIONES.md (la que lee en vivo Conexiones → Documentación técnica) estaba con fecha de la v1.0.743 y le faltaba todo lo hecho desde entonces — puesta al día con la versión, la ficha real de gecli, los permisos granulares nuevos y el resto de los cambios de esta sesión._solo_admin), pero el frontend los mostraba a cualquiera con acceso a Inventario — un vendedor sin permiso los veía, los llenaba, y recién al guardar recibía un 403 sin ninguna pista antes de intentarlo.cxc o bodega_ubicaciones. Los botones ahora arrancan ocultos y el backend también revalida (no solo se esconde el botón)._exigir_permiso(request, clave, etiqueta), genérico, en vez de seguir copiando el mismo bloque de 15 líneas por cada permiso nuevo (como ya pasaba con _exigir_permiso_bodega, _exigir_permiso_aviso_despacho, etc.).gecli), solo cambia CLITIPO='P'. Editar un proveedor existente sigue sin estar disponible (no se pidió).Access denied for user 'root'@'...' (using password: YES) — la clave guardada para el backup programado había quedado desactualizada, y solo se descubrió días después, cuando ya habían fallado varios respaldos de madrugada.
_toast() que no existe en ningún lado del archivo — guardar la config no mostraba nada, ni éxito ni error. Se corrigió para usar el aviso real del sistema.gecli.CLITEXTO (a pedido del usuario; ese campo del ERP no tenía otro uso).--gris-claro se usaba en 2 lugares pero nunca se había definido como variable CSS.historial_unificado() ya estaba bien hecho — el checker comparaba contra el límite equivocado (se colaba una función distinta, _eliminar_cotizacion_nueva, que tiene su propio except sin los mismos parámetros).import normal y dos comentarios que por casualidad terminaban en una sigla en mayúsculas.title, value) armados con datos sin escapar — mismo riesgo real que ya había mordido antes con una descripción de producto con comillas ("CODO 90 2\" SS304"). Se envolvieron todos con el escape ya usado en el resto del proyecto (_lvEsc).chk_auth.py encontró 26 endpoints sensibles (usuarios, permisos, config, SMTP, superadmin, PIN, claves) que escriben sin comprobar el rol de quien llama — arreglar eso bien requiere revisar caso por caso qué nivel de acceso corresponde a cada uno, no un cambio mecánico.
parametros que no existe (la página real es mantenedor). Estaba así desde que se armó ese listado de accesos.giros_ciiu4.json.GET /api/giros?q=...: busca por texto o código. El campo Giro del mantenedor de clientes ahora sugiere coincidencias mientras se escribe (con un pequeño retraso para no golpear el servidor en cada tecla) — sigue aceptando texto libre si no calza con el catálogo.CLINOTAS) resultó guardar RTF, no texto plano — el ERP la edita con un control RichEdit (toolbar Negrita/Cursiva/fuente). Kognit guardaba el texto tal cual, que el ERP mostraría como código crudo en vez de la nota. Ahora se envuelve en el RTF mínimo que el ERP sabe abrir al guardar, y se decodifica de vuelta a texto plano al leerla (compatible con notas de antes de este cambio, que quedan intactas).CLIDV (dígito verificador) ahora se calcula y se guarda junto al RUT — antes quedaba sin dato pese a que el ERP lo guarda separado de CLIRUT.CLINOTAS1/2/3 quedan en '' explícito (una pantalla vieja del ERP que este mantenedor no usa, pero no debían quedar en blanco por omisión).CLIBALANCE y CLICREDIS quedan en 0 — un cliente recién creado no debe nada ni tiene crédito usado todavía.CLITEXTO queda en ''.gecat en vez de asumir un rango fijo: se comprobó con datos reales que los códigos no son 1/2 secuenciales como parecía en la captura — en esta base son 1=DISTRIBUIDOR y 99=GENERAL.'1'/'0' (texto), confirmado con los valores reales que ya usa el ERP en esa columna.gecom.COMPRO es una FK real hacia geciu.CIUCOD (Putre→Parinacota, Iquique→Iquique, calzan exacto) — la conclusión anterior (que no había relación) se basó solo en los nombres de columna, no en los datos.
geciu, pese al nombre, es en realidad la tabla de provincias chilenas (CIUDES trae "Arica", "Parinacota"...) — este ERP la llama "Ciudad". La cadena real es Comuna → Ciudad → Región.geciu/gecom en el servidor, sin mostrar qué nombres existen — se podía escribir algo razonable que no calzara con nada y quedar sin guardar en silencio.
GET /api/ciudades y GET /api/comunas; los campos Ciudad/Comuna del mantenedor completo y de "Nuevo cliente" ahora sugieren esas listas reales al escribir (autocompletado, sigue aceptando texto libre).gecom no tiene ninguna columna hacia ciudad ni región — son dos listas independientes, cada una con su propio autocompletado.gecli.CLICIU/CLICOM/CLIREG son códigos (apuntan a geciu/gecom/gereg), no texto libre — pero crear/editar cliente guardaba lo escrito en pantalla tal cual.
gecom no tiene relación con región ni ciudad, pero geciu.CIUREG sí apunta directo a gereg — así que la región se deriva sola desde la ciudad ya resuelta.gecli_suc) — la factura sigue yendo al RUT de siempre./api/sync/paquete) ya traía las condiciones de pago y los tipos de cotización desde hace tiempo, pero cargarCondicionesPago() y cargarTiposCotizacion() solo sabían pedirlos en vivo — sin conexión, el fetch fallaba en silencio y el <select> quedaba completamente vacío, ni siquiera con la opción "— Seleccione —".
cargarTransportistas(): si no hay conexión, o si el fetch en vivo falla, ambas funciones caen a los datos ya guardados en el paquete offline. Cotizar sin internet ahora tiene disponibles todas las opciones del formulario, no solo clientes y productos.🔌 conectadas/máximo — cuántas conexiones tiene asignadas el motor MySQL/MariaDB para esa base y cuántas están en uso ahora mismo.
SHOW FULL PROCESSLIST. Si el usuario de la base no tiene el privilegio PROCESS, se cae al texto genérico en vez de romper el badge./api/cxc/asignar-nc-erp) ya aceptaba un campo fecha opcional —decide en qué Planilla de Caja cae el movimiento, validado para que nunca sea futura—, pero el modal "Aplicar NC al ERP" nunca mostraba el campo, así que siempre se aplicaba con la fecha de hoy. Se agregó el campo al modal, con hoy como valor por defecto.TRE / FEL-144918 — el código de 3 letras de gepagos.PATIPOPAG, sin traducir. Ahora muestra el nombre legible (usando la tabla _CXC_MEDIO_LBL que ya existía para otras partes de la pantalla), en los tres lugares donde se arma ese texto.
TRE), así que dejaba el título genérico. El usuario mostró con evidencia que el Libro de Ventas SÍ lo distingue ("Tarjeta débito / Redcompra") para el mismo pago — usa cot_concil_banco.medio (la palabra completa), no el código de 3 letras. El kardex de CxC ya tenía esa tabla cargada pero no la consultaba. Ahora sí: prioriza cot_concil_banco.medio y solo cae al código genérico del ERP cuando no hay fila conciliada (pago ingresado directo en el ERP de escritorio).table-layout:fixed con un <colgroup> de anchos fijos (misma técnica que ya funciona en el Libro de Ventas), en varias rondas de ajuste según el ancho real de pantalla del usuario. Cada ronda resolvía un síntoma y creaba otro nuevo — Cliente aplastado letra por letra, Vendedor/Fecha/Origen truncados, un hueco lateral que parecía un error —, y comparado contra la tabla original, el usuario prefirió dejarla como estaba. Se quitó todo: el colgroup, los anchos fijos, el min-width, los quiebres responsive nuevos. El Historial vuelve a su comportamiento de siempre, con scroll horizontal disponible cuando la pantalla no alcanza.fecha de gebloqueo ya traía la hora completa — solo faltaba pedirla. Ahora el tooltip de cada día lista las horas (ej. "3 conexiones: 08:15, 12:40, 17:02") en vez de solo el número.upload.php, dejándolo responder "OK" sin guardar nunca el archivo — el enlace que WhatsApp mandaba con confianza apuntaba a la nada, en silencio. El usuario prefirió que WhatsApp deje de depender por completo del hosting de cada empresa: ahora adjunta/descarga el PDF directo siempre, sin importar si hay enlace público configurado. La subida al hosting sigue existiendo (la necesita el Portal de Clientes), solo que WhatsApp ya no confía en su resultado.alert() que bloquea hasta confirmarlo.abrirWhatsApp() ya reemplazaba por "va adjunto" antes de enviar — el usuario veía un mensaje al escribir que no era el que realmente se mandaba. Ahora el mensaje por defecto ya dice "va adjunto" desde el principio, y solo si el PDF falla al momento de enviar se cambia por un enlace firmado real como respaldo. Se retiró también _waSubirFtp (código muerto, siempre en false).upload.php. El panel "Últimas subidas" mostraba todo en verde, pero los PDF nunca llegaban a allen.cl/cotcli/. Al comparar el upload.php real de Allen contra la plantilla apareció este comentario agregado por una herramienta externa: "This file may contain artifacts of previous malicious infection. However, the dangerous code has been removed..." — la firma de un escáner de malware del hosting (tipo Imunify360) que le quitó justo el bloque que guarda el archivo, dejando intacto el resto: el script sigue validando bien y respondiendo "OK", pero nunca vuelve a escribir nada. Se regeneró el upload.php correcto desde Mi Empresa → FTP (ya trae el token real embebido) para volver a subirlo; se recomendó pedirle al hosting que excluya esa carpeta de sus escaneos, porque puede repetirse.#dc2626) — la misma asociación que ya usa el botón "PDF comisiones" — en los botones de solo-ícono (fila del Historial, "Ver Cotización", notas legado).CHE, TRA, EFE) y palabra completa para el Libro de Ventas (cheque, transferencia) — pero usaba la misma variable para las dos cosas, así que el Libro se quedaba con el código de 3 letras.
UPDATE puntual sobre cot_concil_banco. Al revisar en producción apareció otro par de facturas con el mismo patrón, del día anterior — 4 en total corregidas.cot_concil_banco tiene columnas para ese detalle, pero _concil_marcar_pagado() nunca las escribía — el otro endpoint de pagos que ya funcionaba bien sí las arma. El frontend ya sabía leerlas; solo faltaba que este camino se las diera.
gepagos — el dato ya estaba ahí, solo faltaba propagarlo.COALESCE para no borrar el detalle de un cheque ya registrado si después se le aplica una NC al mismo documento.'list' object has no attribute 'split'. Una configuración interna (cotizacion_pendiente_dbs) es una lista, y así se trata bien en otros dos lugares del código — pero aquí alguien le hizo .split(",") como si fuera texto, y revienta apenas se ejecuta. No era un problema de una empresa en particular: el botón nunca pudo haber funcionado desde que se escribió así. Arreglado en una línea, copiando el patrón correcto.
COTRANSPORTE, que es un indicador numérico (0/1) y no el código del transportista — eso va aparte en COENVIO. Quedó en "" por descuido en la misma línea que sus dos vecinos, que ya mandaban 0 bien. Corregido con el mismo 0, sin inventar un valor.except que capturaba el error en una variable que no se usa en ningún otro lugar del archivo — ni se registraba, ni se devolvía. Lo único que quedaba después era el error, más genérico, del db.close() siguiente intentando cerrar una conexión ya muerta. Ahora se registra la excepción real con traza completa antes de que se pierda; no corrige la causa de fondo, pero la próxima vez el log dirá exactamente qué consulta falló.BUSH-2-1/2X2 y las medidas mayores (3", 3½", 4") no aparecían.
/api/productos, que ahora sí avisa si se llega a él en vez de parecer una lista completa._pc_productos() son los mismos objetos del caché de inventario, no una copia. Mutarlos directamente habría dejado «precios fantasma» ahí con solo pedir una vista previa sin guardar. El lote ahora trabaja sobre su propia copia.PENDIENTE, ACTIVA, RECHAZADA o VENCIDA. Nunca una FACTURADA ni una ya MIGRADO_ERP — el servidor revalida el estado de cada una en el momento de borrar, no confía en lo que mostraba la pantalla.SHOW INDEX/SHOW COLUMNS en Allen): Allen sí tiene COCREAFEC (no hace el JOIN extra a gecot_est) y COFEC sí tiene índice. La causa real: gecot_enc en Allen tiene ~452.000 filas y CONROMOD no tiene índice — el chequeo de «cotizaciones con versiones anteriores» hacía dos escaneos completos de esa tabla cada vez que expiraba su caché de 60s. En Gamspa (~24.000 filas) pasa casi inadvertido; en Allen, 20 veces más grande, pesa mucho más.
gecot_enc.CONROMOD, pero esa tabla la usa también el ERP de escritorio — un ALTER TABLE la bloquea mientras se crea. Se deja para cuando se pueda hacer con Allen sin nadie facturando.gecli (agregada completa, sin filtro, para sacar el nombre del cliente) se reutilizaba también en la consulta de KPIs del período — que solo cuenta y suma, nunca usa el nombre. Sin texto de búsqueda esa agregación se pagaba dos veces por carga, una de ellas sin ningún uso. Ahora el KPI arma su propio FROM sin ese JOIN salvo que el buscador esté filtrando por nombre de cliente; el listado paginado no cambia.C:\caddy —la carpeta del proxy HTTPS, no código de Kognit— se colaba como destino de subida: el servicio del proxy se llama Kognit_Caddy, y _deploy_code_dirs() nunca tuvo la misma exclusión que deploy_reiniciar() ya aplicaba correctamente al reiniciar.
Kognit_Caddy queda excluido de los destinos de subida; y cada carpeta se escribe aislada — las que sí se pueden guardar quedan guardadas, y las que fallen se reportan con el motivo real en vez de tumbar todo.mysqldump ni la conexión Python de respaldo tenían un timeout de conexión explícito — con un host que no responde en absoluto, cada intento podía colgarse el timeout del sistema operativo, uno detrás del otro, mientras el navegador ya mostraba el error por su propio timeout de proxy.
--connect-timeout=10 a mysqldump (dos lugares) y connect_timeout=10 a la conexión Python. ⚠️ El flag de mysqldump se tuvo que revertir: al probarlo en producción, ese binario lo rechazó (unknown variable 'connect-timeout=10'), rompiendo el respaldo por completo — peor que el problema original. mysqldump sigue acotado solo por el timeout=300 de subprocess.run() que ya existía; el connect_timeout de la conexión Python (parámetro propio de pymysql, sin ese riesgo) sí se mantiene.margin-left:auto. Un primer intento los agrupó en un solo contenedor pero mantuvo el margin-left:auto compartido — insuficiente, el hueco solo cambiaba de lugar (reaparecía junto al filtro de Vendedor). Se quitó el margin-left:auto del todo: ahora quedan pegados, en fila compacta, sin ningún empuje hacia el borde. Con el filtro de Vendedor visible seguía faltando un poco de espacio para que todo cupiera en una sola línea, así que el botón "🧹 Limpiar" quedó solo con el ícono (sin el texto) — el título con la explicación completa se sigue mostrando al pasar el mouse.30206-SMS51, VB3VTL-51 y VB3V-2"—. Se le quitan la calidad y la medida, y lo que queda identifica la serie. La medida se convierte a número (1-1/2" → 1,5): alfabéticamente 1" iría después de 1-1/2" y la comprobación del orden no valdría nada.0,9843", 1.9685"). Se corrigió con una tabla de equivalencias, pero se pasó de frenada: una UNION CLAMP DIN 25 pasó a mostrarse como UNION CLAMP 1", y son productos distintos — el informe comparaba precios de cosas diferentes. Ahora la equivalencia solo ordena: cada sistema mantiene su fila y su etiqueta (DN 25, 50 mm, 1"), el emparejado 304↔316 se hace dentro del mismo sistema y el orden de precios se revisa por escalera separada.ITUTIL1: se comprobó con un antes/después real que de 98 columnas el ERP cambia exactamente una. Las otras listas que tengan precio se mueven manteniendo su proporción, no con un porcentaje fijo que aplastaría relaciones puestas a mano.ITPREC (la lista 1), pero cada cliente lleva asignada su lista: un 304 puede estar correcto en la 1 y salir más caro que el 316 en la 3, y a ese cliente se le cotiza con esa. Ahora eliges la lista, y mientras miras una el informe revisa las demás y te avisa en cuáles hay desfases, con enlace para saltar. El selector solo ofrece las listas que existen de verdad en el catálogo. De paso se corrigió que el snapshot leía solo hasta ITPREC5 cuando la tabla llega a ITPREC15.
/pdf, que no cifra — la descarga interna y el correo nunca han ido con clave. La línea se añadía mirando solo el ajuste proteger_pdf, sin comprobar qué se enviaba de verdad. El cliente buscaba un candado inexistente y creía haberse equivocado, y de paso el mensaje publicaba 4 dígitos de su RUT sin necesidad. Ahora solo aparece cuando el archivo va cifrado de verdad; donde sí lleva clave, se sigue anunciando.?k= llevaban tiempo ahí, como respaldo para empresas sin hosting. Faltaba que durase —eran 30 días, y metido en un WhatsApp eso significaba que a los dos meses el cliente veía un error y el vendedor no se enteraba; ahora son 3 años— y que fuese absoluto, porque uno relativo dentro de un WhatsApp no lleva a ninguna parte. Por eso no se deja encender sin la URL pública..json que va junto al PDF —la que escribe el descargador de facturas—, y las cotizaciones subían sin ella.
upload.php del hosting rechazaba todo lo que no fuera .pdf, así que había que ampliarlo. Hay que volver a subirlo (Mi Empresa → Subir PDF al hosting → descargar upload.php). Sigue siendo una lista cerrada: solo .pdf y .pdf.json, nunca un .php.upload.php contestaba «token inválido» o «no se pudo escribir en la carpeta», ese texto se descartaba.• FAC 144773 — $30.719 a • FAC 144773 — WENGAN INDUSTRIAL LTDA. — $30.719: quien despacha necesita saber a quién va cada factura sin ir a buscarlo. El nombre se recorta a 30 caracteres (el mensaje se lee en un teléfono y con 15 facturas los nombres largos lo vuelven ilegible) pero el número y el monto van completos. Se limpian los espacios dobles que trae el ERP. El nombre sale de la propia factura, no de la ficha del cliente: si cambió de razón social después, el mensaje debe decir lo que dice el documento.> ya son cinco caracteres y el código cortaba seis. Además cada línea de una misma cita se dibujaba en su propia caja; ahora se juntan en una.C:\Kognit_Instalador como «una copia de instalador desactualizada». No lo es: es la carpeta de código de dos empresas en producción, y esa nota invitaba justo a ignorarla al desplegar.COFEC) junto a la hora de creación real (COCREAFEC), y el ERP mueve la fecha del documento al procesarlo o facturarlo. Resultado: fecha de hoy con la hora de hace tres días. Verificado sobre 11 cotizaciones reales: las 5 descuadradas se habían creado el 28, 29 y 30.HH:MM y se tiraba la fecha, así que la pantalla no tenía cómo saberlo./api/diagnostico/hora). Compara de una vez los tres relojes que usa Kognit: el del servidor, el de la base —que en varias empresas está en otra máquina— y la hora de Chile calculada, con un resumen en una línea. Y un fallo mudo menos: si no se puede cargar la zona horaria de Chile (en Windows hace falta el paquete tzdata), antes se usaba la hora del servidor sin avisar; ahora queda registrado el motivo.gecli), separados por CLITIPO. Una empresa a la que se le compra y se le vende tiene dos fichas legítimas, cada una con su giro, su dirección y su saldo. Kognit las mostraba juntas.gecli_suc, no del campo CLISUC de la ficha, que no es una cuenta fiable (en Villacor vale 0 en una ficha y vacío en otra). Es una consulta más por página, no una por cliente.Kognit_* incluido el suyo propio. Al llegar a su propio «stop», el proceso moría ahí mismo, así que el «start» de cuatro segundos después no se ejecutaba nunca. Un proceso que se va a matar a sí mismo no puede ser quien lo resucite: ahora el trabajo lo hace un PowerShell aparte, despegado, que sobrevive a la muerte del padre.Kognit_Caddy — el proxy que da HTTPS a todas las empresas, y que no tiene nada que ver con el código que se acaba de subir.%TEMP%\kognit_reinicio.log.C:\Kognit_licencias\, en <carpeta de código>\licencias\ y en la carpeta de datos de la empresa, con cualquiera de los dos nombres de archivo. Donde no está el archivo, la tarjeta no aparece — y esa es toda la protección: sin clave no se puede firmar nada.gebol_enc/gebol_det, mueve stock y deja el TXT.
DTE-39-32692 emitida y subida a facturacion.cl, y el archivo que genera Kognit sale idéntico. La boleta no es la factura con otro número: los bloques se llaman distinto (->Boleta<-, ->BoletaTotales<-, ->BoletaDetalle<-), el encabezado lleva 16 campos en vez de 12, los totales 8 en vez de 9 y sin descuento, y el detalle 12 en vez de 14.BEL se reintenta, igual que en facturas y notas de crédito. Los inserts usan detección de columnas: gebol_det no se llama igual en todas las bases.↩ de una fila del Libro de Ventas, así que un folio de otro período quedaba fuera de alcance. Nuevo botón «↩ NC por número» en la barra: se elige Factura o Boleta, se escribe el folio y se abre la misma ventana de siempre. El código de tipo no hay que adivinarlo (FEL o FAC, BEL o BOL, según la empresa): el servidor prueba los candidatos y usa el que existe. No es una «NC libre» — el formato exige que la nota apunte a un documento real; lo único que cambia es de dónde sale el número.CODO 90 ACERO INOX 2") y esa comilla cerraba el atributo antes de tiempo: el tooltip salía cortado en «CODO 90 2». Corregido en siete tablas y en dos más con nombres de cliente.144584 de UNIFLEX SPA por $54.128, pendiente en CxC y con ✔ en el Libro).
") en el nombre rompía la fila de la tabla.nssm.exe no funcionaba y que «lo más probable es que lo borró el antivirus». Era falso: el archivo estaba sano y el propio registro se contradecía dos líneas más arriba.
nssm.exe. Corregido, junto con dos casos parecidos que podían abortar la instalación de las librerías.INSTALAR_KOGNIT.bat) en vez de una consola.
nssm.exe (ahora se agrega la exclusión de Defender primero), se tomaba el Python de la Microsoft Store —que un servicio no puede ejecutar— (ahora se descarta y, si no hay otro, se instala uno real solo), y cuando un paso fallaba el instalador seguía igual.servicio.log en vez de decir «instalación completada»..bat antiguos siguen disponibles.SOPORTE TUBO DN 85-89 MM no genera nada.cot_concil_banco, una tabla propia de Kognit — y solo cuatro flujos (aplicar NC, asignar saldo a favor, eliminar anticipo) hacían el puente. Los que registran un pago de verdad, no.
ITBO1+ITBO3…) o en una sola columna (ITSTOCK). Esa detección corría una sola vez y, si en ese momento la base no estaba disponible —pasa seguido, porque vive en otra ubicación y se llega por internet—, fallaba en silencio y el servicio quedaba usando ITSTOCK hasta el próximo reinicio.
! y un subrayado. Ahora la línea lleva tres marcas a la vez: un aro alrededor de la cantidad, una barra negra al costado para ubicarla sin leerla, y «FALTAN 42» en negativo — que dice cuánto falta, en vez de obligar a restarlo de cabeza mirando stk 8→-42. El aviso de cabecera también pasa a fondo negro, que es lo más visible que imprime una térmica.CODSUBTOT, que no significa lo mismo en todas las filas: las cotizaciones creadas por Kognit guardan ahí el neto, las creadas por el ERP de escritorio guardan el bruto, sin descuento. Comprobado sobre 3.663 documentos. Esos informes —productos más cotizados, monto pendiente de clientes que no compraron, cotizaciones no facturadas y la búsqueda— venían sobrestimando entre un 25% y un 34%. Ahora calculan el neto real, así que sus totales van a bajar: no es un error nuevo, es el que se corrigió.50,5 a 50 (al par más cercano); el ERP y MySQL lo suben a 51. En los precios que caen justo en el medio, Kognit y el ERP daban números distintos. Ahora Kognit redondea igual que el ERP, también al grabar.CODPOS) y se respeta al reabrir la cotización, en el PDF y en el ticket de picking. De paso se corrigió una consulta que leía las líneas sin ordenar, así que ahí el orden salía al azar.X-Forwarded-For, que la escribe quien se conecta: cualquiera con acceso al puerto interno podía mandar X-Forwarded-For: 127.0.0.1 y llevarse un permiso de entrada válido por 30 días.
_ip_cliente). De paso, cuatro pantallas que registraban la IP —solicitudes ARCO, leads web, pedidos web y la verificación anti-robot— guardaban la del proxy en vez de la del visitante.overflow:auto pero, por ser un elemento flexible, no podía encogerse por debajo de su contenido y el scroll nunca se activaba.⋮ y se abre con un clic (abrir una cierra la anterior). El botón "⋮ Controles" de la barra permite volver al modo anterior si prefieres verlos todos, y la preferencia se recuerda. El nombre de la estantería sigue siempre visible, porque va arriba y no compite por espacio.stk 39→34 en #333 y el pie de página en #555. Eran justo los dos textos más pálidos. Ahora todo va en negro puro.9.5px) que caen entre dos puntos de la cabeza térmica y salen con el borde a medio quemar. Ahora todos son enteros.76.221.499-7) hacía que el sistema lo rechazara diciendo que faltaba, con el campo lleno a la vista. La causa: el campo era numérico, y cuando uno de esos recibe algo que no es un número el navegador devuelve cadena vacía — el valor se ve pero el código lee "". Ahora es de texto y acepta con puntos o sin ellos, con guion o sin él, con dígito verificador o sin él; debajo muestra cómo quedará guardado y avisa si el DV no calza (sin bloquear, porque hay RUT especiales cargados así en el ERP). Probado con nueve formas de escribirlo.PAFECING (cuándo se ingresó el pago). Cuando esas dos fechas no coinciden —justo el caso del contador que ingresa hoy los cobros de ayer— el mismo pago salía en la caja de ayer y en la de hoy. Ahora hay una sola definición de a qué día pertenece un pago, usada por todas las consultas de la planilla: 1) la corrección manual hecha desde Kognit, si la hay; 2) la fecha del abono en el banco de la conciliación — cuándo entró la plata de verdad; 3) PAFECING, lo único que hay si el pago no está conciliado. Al ser una expresión compartida, dos cajas ya no pueden discrepar. En la práctica: un cobro que entró ayer queda en la caja de ayer aunque se ingrese hoy, y desaparece de la de hoy. (Con esto Conexiones → 📅 Fechas de pagos queda casi sin uso: lo que corregía a mano ahora se resuelve solo.)GET /api/cotizaciones/verificar-numero (comprobar que el correlativo no cambió mientras se llenaba el formulario) estaba declarada después de GET /api/cotizaciones/{cot_id}, y FastAPI resuelve por orden: la petición entraba por la de arriba con cot_id="verificar-numero" y devolvía un error de validación. Nadie lo notó porque se llama dentro de un try y, al fallar, no verificaba nada. Ambas rutas pasaron a un prefijo propio y se revisó todo app.py con un detector escrito para esto: no queda ninguna otra tapada.[ ] y cantidad en grande abajo— y las descripciones largas se parten en vez de truncarse. Ordenado de mayor a menor cantidad, con cliente, destino, transportista, vendedor, totales y espacio de firma. Botón en Despachos y en el Historial de cotizaciones.cot_despacho_factura, con quién y cuándo) y no modifica nada en el ERP. Desde ahí ese despacho muestra su estado de pago como cualquier otro.FANROCOT vacío, lo habitual al facturar desde el ERP de escritorio), no hay forma de saber cuál es su factura ni si está pagada. Antes eso se mostraba como "SIN PAGO AÚN", que es falso; ahora dice "— SIN FACTURA VINCULADA" con la explicación al posar el mouse. Se evaluó adivinar la factura desde gecot_det.CODFACT y se descartó: ahí esa columna es una marca (vale 1), no un folio, y habría enlazado una factura ajena mostrando el pago de otro cliente.PATIPODOC fuera idéntico al tipo del documento; un pago grabado como FAC sobre una factura FEL no se contaba y el documento aparecía impago. Ahora, si no encuentra nada con el tipo exacto, amplía la búsqueda a la familia (FEL/FAC/FEC/FEX o BEL/BOL), pero solo tras comprobar que ese número no está repetido entre dos documentos distintos. Además los dos except mudos de esa pantalla ahora dejan el error real en el log.gevend; se rechaza un código que no exista ahí, porque dejaría el documento fuera de todos los informes por vendedor). Escribe gecot_enc.COVEN —el ERP, que es de donde salen las comisiones— y en el sistema nuevo actualiza cot_cabecera. Motivo obligatorio, historial propio y auditoría completa (quién, cuándo, IP y equipo). Al confirmar avisa que el documento pasa a contar para las comisiones del nuevo vendedor.req.usuario_codigo) heredada de la función de la que se separó ese código, que lanzaba error siempre y quedaba tapada por un except: pass; todos los certificados salían con el correo global. Corregido, y ese except ahora deja el motivo en el log. (b) El respaldo de base de datos en modo Python (el que se usa si no está mysqldump) fallaba en la primera columna de texto o fecha porque usaba date sin importarlo. Se revisó todo app.py con un analizador de ámbitos y no queda ningún otro nombre sin definir.PAFECING con la fecha del momento, sin opción, así que una NC aplicada días después caía en la Planilla de Caja equivocada — el mismo problema ya corregido en los pagos con plata. Ahora los tres reciben la fecha del pago que ya se elige en el modal, validada en el servidor (formato correcto y nunca futura). No hay campo nuevo que llenar, y también aplica cuando la factura se salda solo con una NC.gepagos.PANROBAN y se traduce con el maestro gebancos (con el respaldo del texto Bco: de los cheques antiguos): "Cheque N° 1234 · Banco BCI".WHERE. Eso dejaba de poder usar el índice de PAFECING y obligaba a recorrer gepagos entero ejecutando la subconsulta por cada fila: la consulta se eternizaba y la conexión se cortaba sola (HTTP 500 … (0, '')). El criterio no cambió en nada — cambió dónde se calcula: ahora se resuelve en memoria, aprovechando que la conciliación ya está cargada, y los candidatos se buscan con dos consultas baratas que sí usan índice (los pagos ingresados ese día, y los de documentos cuyo abono bancario es de ese día). Mismo resultado, sin la espera.CO-4 NPT y CNPT4 son productos distintos) es fácil asignar el equivocado y que el buscador no encuentre nada.B01-…, B02-…) encontrar la que se busca es inmediato. Orden natural y sin distinguir mayúsculas, así B10 va después de B2 y un nombre en minúsculas no se va al final.ITBOxx, que es el de creación en el ERP), con orden natural para que "Bodega 2" quede antes que "Bodega 10".ITBO01, ITBO02…), muestra además cuánto hay en cada local con su nombre de gebodegas —por ejemplo B01: 786 · B02 Stgo Concha: 120—, omitiendo las que están en cero. El pie aclara que el TOTAL es la suma de todas las bodegas, no el stock de ese estante: el ERP lleva stock por bodega, no por estantería.geitems_mae.ITUBI1-4, los mismos campos que ya usan el escáner de bodega y Crear Producto — en vez de una tabla paralela de ubicaciones que tarde o temprano diría algo distinto al ERP. Muestra antes qué cambiará y omite los códigos inexistentes informándolos, en vez de fallar a medias. Esos campos son de 5 caracteres, así que la ubicación se arma: Bodega = el código del plano, que ahora se define a mano con el botón "Código ERP" (FITT, VNPT…) en vez de un correlativo P2/P3 que no le dice nada a nadie; Estante = el nombre de la estantería si cabe en 5 (E1, A4a) y solo si no cabe su id interno — antes escribía siempre el id, así que el plano mostraba "E1" y el ERP decía "X1"; Pasillo = el pasillo de la estantería, que se pone con el botón P en modo edición (hay bodegas con dos o tres) y se deja vacío cuando la bodega tiene uno solo. El pasillo tiene nombre y código: se escribe el nombre visible ("Pasillo 1", "Pasillo Fittings") y el sistema propone el código de 5 caracteres para el ERP (P1), corregible. El nombre se guarda una sola vez por pasillo y lo comparten todas sus estanterías; en el plano se ve el código y el nombre completo sale en el tooltip del nivel; Nivel = N1, N2… El botón ℹ Información explica esto dentro de la propia pantalla.grupo), y el desplegable se abre buscando ese identificador: con dos grupos propios, el segundo botón terminaba abriendo el menú del primero (por ejemplo, "Administración" mostrando Inventario y Compras). Ahora cada grupo nuevo nace con un id único y los grupos ya guardados con ids repetidos se desempatan solos al dibujar el menú — no hay que rehacer la configuración a mano.getipo_pag), no el código; si no hay descripción registrada cae al código. Solo aplica a facturas — boletas y notas de crédito no llevan condición, así que van en blanco. Es la vista Pro; el Excel y la vista Clásico (SII) mantienen el formato legal del libro, sin la columna.PAFECING) con la fecha del momento, sin opción. Como el contador ingresa al día siguiente los cobros del día anterior, esos pagos caían en la Planilla de Caja del día equivocado y aparecían como "cobro de documento de otra fecha". Ahora: al conciliar la cartola se usa la fecha del abono en el banco (cuando la plata entró de verdad, no cuando se alcanzó a conciliar); "Registrar pago" tiene campo "Fecha del pago" con aviso en ámbar si no es hoy y sin fechas futuras; y el reintento de pagos pendientes usa la fecha guardada, no la del reintento. Validado también en el servidor.gepagos.PANROBAN). Kognit usaba una lista fija de bancos de Chile que no calzaba con el maestro del ERP, así que PANROBAN quedaba en 0 y el nombre se guardaba como texto dentro de la observación (Bco:...) — legible en Kognit, pero invisible para cualquier reporte del ERP que lea esa columna. Ahora los selectores se llenan con los bancos reales de gebancos y al grabar se traduce el nombre a su código BACOD. La Cartera de Cheques traduce el código de vuelta a nombre, y sigue leyendo el texto antiguo para los cheques ya cargados así. Si la empresa no tiene la tabla, todo funciona como antes. Además, si falta un banco, el propio selector trae "➕ Agregar banco…": pide el nombre y lo crea en gebancos con el siguiente código disponible (si ya existía lo reutiliza, no lo duplica). Solo admin/superadmin.Revisión completa del proceso de pagos masivos ("Pagar varios documentos" en Cuentas x Cobrar) y de cómo llegan a la Planilla de Caja. Se encontraron y corrigieron tres problemas:
PACOBRA vacío en el ERP y por eso no aparecían en el Reporte de Pagos al filtrar por cobrador. Se agregó el selector de cobrador al modal de pago masivo, con "Oficina" precargado igual que en el individual.grupo + excepciones propias. Eliminar un grupo deja a sus usuarios con permisos 100% individuales (nunca se quedan sin acceso). Retrocompatible: un usuario sin grupo asignado (todos los existentes al desplegar esto) funciona exactamente igual que antes. Nuevos endpoints GET/POST/PUT/DELETE /api/admin/grupos-permisos.descargador_facturacion.py (contador vs. total del mes, historial de descargas, folios ya en disco), así que repetir el rango es rápido y seguro. Nuevo marcador "📍 Última descarga automática" con fecha y resumen. La descarga manual (año/mes a elección) sigue funcionando igual que siempre, aparte.autorizar_notas_pendientes) sin quedar registro de quién de verdad autorizó — el sistema solo "adivinaba" contra la clave de cada usuario elegible. Ahora el modal "Autorizar" pide elegir explícitamente el usuario (los mismos elegibles de siempre: admin/superadmin, o quien tenga el permiso "Autorizar notas pendientes" vía su Grupo de Permisos o como excepción individual — ej. bodega) y valida la clave de esa persona puntual. El registro de auditoría (cot_estado_log) deja constancia real de quién autorizó, en vez de solo registrar a quien estaba logueado en el navegador. Nuevo endpoint GET /api/usuarios/autorizadores.cot_permisos_grupos tenía tres problemas de definición que se fueron destapando uno tras otro — columnas DATETIME ... ON UPDATE CURRENT_TIMESTAMP (solo válido en TIMESTAMP, y en 5.5 además solo se permite una columna TIMESTAMP automática por tabla), y la columna permisos TEXT DEFAULT '{}' (MySQL nunca permite DEFAULT en columnas TEXT/BLOB, en ninguna versión — este era el error real de fondo). Como GET /api/admin/usuarios también toca esta tabla (para el badge de grupo), la pantalla de Usuarios completa quedaba en blanco ("No hay usuarios"), no solo Grupos de Permisos.gecot_enc.COBODUSER (código de bodeguero) y COBODFEC (fecha/hora) — mismo momento de la autorización, no de la impresión. No bloquea la autorización si esas columnas no existen en alguna empresa puntual. Ojo: el código de login en Kognit no siempre es el mismo que el código de bodeguero real en el ERP (ej. Miriam Lastra = "01" en Kognit pero "B01" en el ERP) — se agregó un campo nuevo y editable "Código de bodeguero (ERP)" en la ficha de cada usuario (Parámetros → Usuarios) para mapearlo explícitamente; si se deja vacío, se sigue usando el código de Kognit como respaldo.GET /api/notaventa/impresion/historial y GET /api/notaventa/impresion/avisos.NameError (_re sin importar) dentro de cxc_kardex hacía fallar en silencio TODO el cruce de pagos del cliente apenas encontraba uno con datos de tarjeta en la observación — quedaba tapado por un except: pass que no dejaba rastro. Corregido el import faltante, y el log del servidor ahora registra el error real si este bloque vuelve a fallar por otra causa (antes quedaba mudo).gecot_det.CODOBS ya no se llena al crear/modificar cotizaciones (antes guardaba ahí la descripción del producto de esa línea) — estaba generando problemas al facturar desde el ERP de escritorio. Kognit nunca dependía de ese dato para mostrar nada (siempre re-obtiene la descripción vía geitems_mae), así que no afecta ninguna pantalla.sansunstainless.com: lo extraído queda siempre como borrador editable y se suma a lo ya escrito sin pisarlo — nunca se publica solo. Nueva tabla cot_fichas_tecnicas y endpoints /api/fichas-tec/*.gecot_det.CODOBS ahora se graba en blanco en vez de NULL.certificados.html, accesible desde el ícono 🔖 en Historial → Facturas.bodega_router.py) nunca estaba registrado en app.py, no solo lo nuevo de hoy: le faltaban el import y el app.include_router(...), así que todas sus rutas devolvían 404 en silencio desde siempre. Corregido.POST /api/bodega/certificados/confirmar-lote.GET /api/bodega/certificados/confirmadas y POST /api/bodega/certificados/revertir.certificados.html) — cambió de tema oscuro propio a la misma paleta e identidad visual de Kognit (azules, tipografía Inter, topbar), para que se sienta parte del mismo sistema en vez de una herramienta aparte.cantidad>0 — ocultando en silencio cualquier certificado recién confirmado. Corregido para mostrar el lote si tiene heat_no, tenga o no stock físico contado./api/productos, usado en Cotizar/Certificados 3.1/etc.) ordenaba los resultados solo alfabéticamente, no por relevancia. Buscar "FERRULE" traía primero cualquier producto que mencionara esa palabra en cualquier parte de la descripción (ej. un conector que empezaba con "C..." y solo la nombraba al final) por delante de los productos que de verdad son "Ferrule Clamp ...". Ahora prioriza: coincidencia exacta → empieza con lo buscado → la frase completa aparece seguida → cada palabra suelta en cualquier lugar (como antes), y dentro de cada grupo mantiene el orden alfabético natural de siempre.POST /api/bodega/certificados/asociar-heat-manual.POST /api/bodega/certificados/confirmar-por-planilla.bodega_lotes, porque la restricción de la tabla no contemplaba el heat no. como parte de la identidad del lote. Corregido para que cada colada distinta quede en su propia fila, sin afectar el conteo de stock físico normal (ingreso/ajuste), que sigue funcionando igual que siempre.GET /api/bodega/certificados/facturas-estado.geitems_man/geitems_mand). Es informativo — Kognit no descuenta stock por lote FIFO al vender, así que no indica de qué orden salió específicamente esa venta, solo dónde buscar el certificado; además, si el producto tiene varias órdenes, se resalta cuál de ellas en particular tiene la colada confirmada. Nuevo endpoint GET /api/bodega/certificados/ordenes-producto.certificados (bien escrita) para el archivo temporal; como el sistema busca esa carpeta ANTES que la real (que tiene un typo en el nombre real en disco), empezaba a encontrar la nueva —casi vacía— en vez de la que tiene todos los PDF. Corregido para que los archivos temporales usen siempre la carpeta real ya detectada, nunca creen una nueva.50003-1/2): iba como parte de la URL en vez de parámetro de búsqueda, mismo problema ya conocido en otras partes del sistema con códigos que llevan "/". Corregido.DCLAMP1-1/2"): el código se armaba sin escapar dentro de un atributo HTML, y la comilla cortaba el valor a la mitad antes de llegar al servidor. Corregido.certificados.html abre un modal con el flujo completo de 6 pasos (desde escribir el código al hacer el pedido hasta enviarle el certificado al cliente) + casos especiales, sin salir de la pantalla.GET /api/usuarios-login ahora excluye a quien tenga rol='superadmin' (por rol, no por nombre) — para entrar con ese código hay que escribirlo directo en "Código de Usuario" (el campo ya existía debajo del selector), sin que aparezca a la vista de cualquiera que abra la lista.CONTEXTO_SISTEMA_COTIZACIONES.md leído en vivo desde el servidor (arquitectura, tablas de BD, endpoints) — siempre al día, sin mantener una copia aparte. Nuevo endpoint GET /api/config/contexto-tecnico (solo superadmin).GET /api/facturas/{fanro}/resumen (respeta el mismo permiso por vendedor que el resto de Facturas).GET /api/bodega/certificados/archivos?subcarpeta=; POST /api/bodega/certificados/escanear acepta ahora archivos (rutas puntuales, con prioridad sobre subcarpetas).imagenes.json de un sitio en particular), así que cualquier otra instalación de Kognit con su propio sitio web quedaba sin ofertas funcionando. Ahora cada empresa administra sus propias ofertas en su propia tabla (cot_web_ofertas), desde Parámetros → Sitio Web → "🏷️ Ofertas del sitio web" (código, % descuento, cantidad mínima, vencimiento opcional). El mecanismo viejo se mantiene intacto como respaldo automático solo para quien ya lo estaba usando, así nadie pierde lo que tenía funcionando.GET/PUT/DELETE /api/config/web-imagenes.GET /api/config/web-imagenes/detectar.0 (falsy en JavaScript, la condición lo trataba como "sin dato")./api/cxc/pagar-varios, reutilizando exactamente el mismo camino que un pago individual.clave; funcionaba solo para claves aún no migradas al hash — para cualquier usuario con clave ya hasheada (PBKDF2+salt), la comparación siempre fallaba. Corregido para usar _verificar_clave() (la misma función del login) en todos los puntos.PATCH con el estado por query string, pero el frontend mandaba PUT con el estado en el body — nunca coincidían, el cambio de estado fallaba en silencio. Corregido, y protegido con el nuevo permiso "Cambiar estado del documento en Historial" (antes cualquier vendedor podía cambiarlo sin restricción, incluso llamando la API directo).geserver_print (igual que si la hubiera impreso el ERP de escritorio), resolviendo dinámicamente el usuario ERP a través de geroles/geperfiles (rol "Servidor de impresión remota", código 50102)._faven_permitido.cot_web_pedidos, endpoints POST /api/tienda/pedido, POST /api/tienda/pedido/retorno, GET /api/tienda/pedido/{id}/estado, GET/PUT /api/config/transbank (solo superadmin, credenciales cifradas). Nueva sección en Parámetros → Sitio Web para configurar ambiente/credenciales/email de aviso./api/web-leads fallaba en cada llamada: cot_web_leads.fecha DATETIME DEFAULT CURRENT_TIMESTAMP es incompatible con MySQL 5.5 (error 1067 repetido en el log); se quitó el DEFAULT y el INSERT pasa NOW() explícito. También se subió el timeout de los informes pesados (Patrón estacional, etc.) de 120s a 280s.GET /api/informes/impacto-ventas-evolucion.GET /api/informes/fidelidad-clientes, permiso ver_fidelidad_clientes.pip install playwright && playwright install chromium). Queda marcado como experimental: el login automático contra Clave Única nunca se había probado en código, así que los selectores del formulario pueden necesitar ajuste según el resultado real. Nuevos endpoints POST /api/mp/robot/credenciales, GET /api/mp/robot/estado, POST /api/mp/robot/probar-ahora.web_admin_key) y el interruptor "mostrar precio/stock reales al público" (web_mostrar_precio) solo se podían cambiar editando app_config.json a mano en el servidor. Ahora hay un campo con la clave en texto plano (para poder recuperarla si se olvida) + botón "🎲 Generar" (clave aleatoria de 16 caracteres) y "📋 Copiar", más el checkbox de precios/stock — todo se guarda al instante sin reiniciar Kognit. Nuevos endpoints GET/PUT /api/config/web-allen. De paso se cambió la clave de Intranet por defecto ("allen", demasiado simple) por una generada al azar.web_mostrar_precio pasó de booleano a texto ('no'|'ofertas'|'todos').imagenes.json desde una ruta local del disco (allen_imagenes_json_path), pero Kognit y el hosting de allen.cl no son el mismo servidor, así que ese archivo no existía ahí. Ahora, si no encuentra el archivo local, lo descarga directo desde https://www.allen.cl/imagenes.json (con caché de 60s para no recargar el sitio en cada visita al catálogo).gecli_suc) solo se podían ver; ahora el botón 🏢 permite "+ Agregar sucursal" y editar/eliminar las existentes, sin depender del ERP de escritorio. Pensado para clientes que trabajan solo con Kognit — el cliente en sí ya se creaba directo en gecli con "+ Nuevo cliente", ahora también se le pueden cargar sus sucursales. Nuevos endpoints POST/PUT/DELETE /api/clientes/{rut}/sucursales.toISOString()), que le suma horas y la empuja al día siguiente — una COT que cierra hoy en la tarde quedaba clasificada como si cerrara mañana y el filtro la descartaba. Ahora compara por fecha calendario local, igual que "Publicado" (desde/hasta).POST /api/sii/importar-xml, GET /api/sii/cliente-datos-xml?rut=....vouchers/. Compatible hacia atrás; nuevo endpoint de mantenimiento para migrar los que ya quedaron sueltos.@match exigía un subdominio y el dominio raíz de MP nunca calzaba; (2) el script modificaba window.fetch/XMLHttpRequest en vez de unsafeWindow, así que corría pero nunca veía peticiones reales; (3) la que realmente bloqueaba todo: llamar a GM_xmlhttprequest desde una función pegada al XHR de la página real fallaba con "is not a function" — corregido capturando esa API en una variable al cargar el script. Hay que reinstalar el script (Conexiones → Config MP) para tomar el cambio.gecli.CLICIU es numérico (ej. Alas): se intentaba guardar el nombre de la ciudad como texto en una columna que ahí es un código numérico — mismo problema ya visto en Reasignar clientes de vendedor. Ahora esa columna se deja sin tocar; además, si un cliente puntual falla, ya no tumba al resto de la selección.geciu/gecom/gereg) antes de guardar; si no hay coincidencia exacta, se avisa cuál no se pudo guardar.gecli (completa giro/dirección si ya se subió el XML de respaldo). GET /api/clientes/sii-pendientes, POST /api/clientes/sii-importar.Date.getTime()), igual para "Publicación"..user.js. Se agregó GET /api/mp/tampermonkey-script.user.js y el botón apunta ahí. Sigue requiriendo tener la extensión Tampermonkey ya instalada antes.href="#" hasta terminar de cargar el detalle interno — un clic antes abría "#" (Kognit mismo). Ahora se arma con el código apenas se abre el modal.textoBusqueda de MP busca dentro del título de la licitación, no del organismo comprador, y los títulos casi nunca mencionan la comuna. Ahora se trae un bloque grande sin filtro de texto (solo estado) y se compara el organismo en el navegador (tope 1.000 registros).mp_rubro_keywords en GET/POST /api/mp/config.openpyxl (exclusivo para .xlsx) — al subir el Excel real que exporta MP (formato 97-2003), fallaba en silencio y la pantalla quedaba en 0, sin aviso claro. Ahora detecta el formato real por los primeros bytes del archivo y lee los .xls viejos con xlrd (con conversión correcta de fechas), además de los .xlsx de siempre.fecha_publicacion descendente antes de mostrarlo, en vez de confiar en un valor no verificado.GET /api/mp/buscar-codigo/{codigo}.javascript: pegados en marcadores (CSP del sitio) — el bookmarklet nunca llegaba a correr, sin error visible. Nueva alternativa: script para la extensión gratuita Tampermonkey (botón "📥 Instalar script en Tampermonkey" en Conexiones → Config MP) que intercepta silenciosamente las llamadas que la propia página de MP hace a servicios-compra-agil/servicios-escritorio y envía el token a Kognit solo, sin clics — basta con tener esa pestaña abierta con sesión iniciada. Instalación de una sola vez. Nuevo endpoint GET /api/mp/tampermonkey-script. El bookmarklet queda como alternativa secundaria.POST /api/mp/jwt-externo (al que llama el bookmarklet desde mercadopublico.cl) no estaba en la lista de rutas públicas del middleware de autenticación — la petición llega sin el JWT de sesión de Kognit (viene de otro sitio, sin login), así que el middleware la rechazaba con 401 antes de que el endpoint alcanzara a revisar su propia api_key de seguridad. Esa respuesta 401 no traía encabezados CORS, el navegador bloqueaba la respuesta, y el bookmarklet siempre terminaba en "Error de conexión" sin guardar nunca el token. Se agregó a las rutas públicas (sigue protegido por su propia api_key).escritorio.mercadopublico.cl, así que siempre se guardaba como "Token Escritorio" en vez de "Token Compra Ágil". El bookmarklet avisaba "Token actualizado" pero Licitaciones MP seguía sin funcionar. Ahora decide primero por la URL (si contiene "compra-agil"), no solo por el dominio./compra-agil, la ruta real del buscador./api/informes/productos-cotizados y las llamadas a /api/informes/cotiza-no-compra que ya no se usaban (los endpoints backend no se tocaron)._naturalCompare) al armar esas listas./api/catalogo, usado también por el sitio web). Fix del mismo día: las medidas mixtas escritas con espacio en vez de guion (ej. "2 1/2\"", el formato real usado en el ERP) quedaban mal igual — el detector solo reconocía "2-1/2\""; ahora reconoce ambos formatos.KOGNIT_CONRO_PISO, v1.0.730) queda ahora como una opción, no forzado para todas las empresas — interruptor por empresa entre "Numeración independiente" (rango alto de siempre, recomendado) y "Correlativo normal del ERP" (numeración consecutiva de toda la vida, para empresas como GAMSPA que lo prefieren así). Nuevo endpoint GET/POST /api/config/conro-numeracion. En "Correlativo normal", a pedido de GAMSPA, Kognit salta 3 números hacia adelante (MAX+3, dejando 2 libres de colchón) en vez de tomar exactamente el siguiente — reduce el riesgo del mismo choque sin el salto grande del rango reservado, aunque no lo elimina del todo._auto_crear_cot_lead buscaba el precio del producto en una tabla geitems que no existe — la real es geitems_mae (única línea del código con este error). El producto se agregaba igual, pero siempre en $0.errors.log, a diferencia del resto de la misma función. Ahora ambos casos quedan registrados con el detalle exacto.max-height:calc(100vh - 280px)) y scroll propio, en cualquier tamaño de pantalla — en celular eso se sentía como pantalla "partida" (filtros fijos arriba, tabla scrolleando encerrada abajo). En mobile ahora se saca ese límite y la tabla fluye con el scroll natural de la página; en desktop se mantiene igual que antes.ver_resumen_diario y dejó de sembrarse la tabla sys_resumen_diario (no se borra lo ya guardado, solo deja de usarse). El Historial de versiones queda como única fuente de "qué se hizo cada día".SELECT DISTINCT sobre gecot_enc (para excluir "versiones anteriores" vía CONROMOD) se ejecutaban completos y sin filtro de fecha en cada carga y auto-refresco — un recorrido de años de historial repetido sin necesidad. Ahora se cachean en memoria 60 segundos, sin cambiar el resultado que ve el usuario.gecli.CLICIU guarda un código numérico (INT), no texto, y el .strip() fallaba sobre ese valor. Corregido usando el mismo helper de normalización (_str) que ya se usa en otros lugares para este mismo problema.gedescriptores.contador (el correlativo que usa el ERP de escritorio para calcular su próximo número) con su propio CONRO reservado (5.000.00X). Eso empujaba el contador del escritorio hasta el rango de millones de Kognit — se confirmó con una captura real del listado del escritorio mostrando N° 5000000-5000006 mezclados con números normales. Se eliminó esa actualización en los dos lugares donde ocurría; Kognit sigue calculando su propio número (solo lee el contador, nunca lo escribe), y el escritorio queda siempre con su numeración real disponible./api/publico/condiciones-pago (catálogo getipo_pag) para que el sitio ofrezca Contado/Crédito 30-60-90 días, en vez de solo el método de pago (Efectivo/Transferencia/etc). Se guarda en cot_web_leads.condicion_pago_cod/des y, al crear la cotización desde un Lead Web, se preselecciona por código exacto (antes se intentaba adivinar comparando texto contra "forma de pago" y casi nunca acertaba, por ser conceptos distintos)./api/publico/cliente-sucursales (lee gecli_suc); si el cliente encontrado por RUT tiene sucursales, el sitio muestra un selector "¿A qué sucursal quiere que se cotice?" que autocompleta dirección/ciudad/comuna/región de esa sucursal. Se guarda en cot_web_leads.sucursal_nro/nombre y, al convertir el lead en cotización desde Leads Web, se preselecciona automáticamente la misma sucursal.plataforma) — visible como subtexto bajo la fecha en la lista y en el detalle de la solicitud./api/publico/cliente (evita extraer datos de clientes en masa recorriendo RUTs) y en /api/web-leads (evita spam automatizado), honeypot invisible en el formulario de cotización, y la clave de Intranet ahora viaja por cabecera (X-Admin-Key) en la carga principal del catálogo en vez de ir en la URL.D/T (Despacho por Transporte) en vez de CO/TI, siempre que ese código exista en el catálogo getipos de la empresa (si no existe, sigue cayendo en CO/TI como antes).gecli.CLIVEN; no modifica cotizaciones ya emitidas.gecot_enc) podían chocar de número con el programa de escritorio del ERP: caso real — un vendedor tenía abierta una cotización nueva en el ERP de escritorio (que muestra el próximo N° apenas se abre la pantalla, pero recién lo confirma al guardar, minutos después); mientras tanto Kognit creó una cotización desde un Lead Web y calculó ese mismo número — el guardado del vendedor llegó después y pisó la fila que Kognit acababa de crear, y además quedó escondida del Historial (el guardado del vendedor generó una cadena de versionado que la marcó como "versión anterior"). Kognit ahora reserva un rango de numeración bien por delante de donde crece el ERP de escritorio (que sigue usando números bajos consecutivos como siempre), así el número calculado en el escritorio nunca coincide con uno ya usado por Kognit, sin importar cuánto tiempo quede esa pantalla abierta antes de guardar.abono_id) que vincula esas filas de forma exacta — antes no había ninguna relación registrada entre ellas, solo coincidencia de fecha/monto. Aplica a los repartos hechos desde ahora en adelante; los históricos anteriores a este cambio no se reconstruyeron (para no adivinar agrupaciones).cot_nc_aplicada. Se ve tanto en el Libro de Ventas como en la Planilla de Caja..btn-ghost trae background:#fff fijo; el estilo del botón solo cambiaba el texto y el borde a blanco (pensado para verse sobre el header café de ese modal) sin tocar el fondo, dejando texto blanco sobre fondo blanco. Se le agregó background:transparent./bodega. Se agregó el mismo selector (Única/Bodega 1/2/3) también aquí.cot_cabecera (el sistema web) y nunca gecot_enc (el ERP legado) — que es donde vive la enorme mayoría de las cotizaciones reales de estas empresas; (2) el selector de vendedor manda el CÓDIGO (gevend.VENCOD), pero la consulta lo comparaba contra cot_cabecera.vendedor, un campo de NOMBRE — nunca podía coincidir. Ahora se resuelve el nombre real del vendedor para cot_cabecera y se agrega una consulta a gecot_enc (por código de vendedor COVEN), combinando ambas fuentes; las cotizaciones del ERP se geolocalizan por dirección igual que las del sistema web sin GPS (nunca capturan GPS en vivo, se crean desde el propio ERP).actualizar_cotizacion_legado nunca actualizaba CODIR/cociu/cocom/coreg (dirección/ciudad/comuna/región) — esos campos ni siquiera estaban en el UPDATE. Se agregaron al modelo y al UPDATE; el frontend ahora manda el valor final de esos campos del formulario (que ya se actualizan solos al elegir una sucursal).guardarCambiosCotizacion() mandaba siempre cotipo: '' en el payload (el comentario decía "preserva tipo", era a propósito, pero dejaba de tener sentido) — el backend interpreta '' como "no cambiar", así que quedaba igual sin importar lo elegido. Ahora manda el valor real del selector. También se corrigió que el selector de Tipo no se dejaba con el valor actual de la cotización al abrirla para modificar.tipo_cotizacion_cod/des o COTIPO según el origen), solo faltaba mostrarlo.gecli_suc), al modificar no aparecía forma de elegir ni cambiar entre ellas. Además, al elegir una sucursal solo se cargaban dirección y contacto; ahora también carga ciudad, comuna, región, email, teléfono y celular — comuna/región/ciudad de la sucursal venían como código numérico crudo (CLISCOM/CLISREG/CLISCIU) y no se mostraban; ahora se resuelven a su nombre real (mismo cruce contra geciu/gecom/gereg que ya usa la ficha principal del cliente).abrirEmailHistLegado asumía que "legado no tiene email guardado" y siempre abría el modal con el campo en blanco — pero el ERP sí lo tiene (gecli.CLIMAIL), y la propia pantalla "Ver cotización" ya lo mostraba. Ahora busca el email del cliente antes de abrir el modal (mismo criterio que ya usaba el botón de WhatsApp con el celular) y lo prellena; si de verdad no hay email guardado, el modal se abre igual para ingresarlo a mano.gecli_suc, cruzada por el código de sucursal del documento — no confundir con la "oficina" interna del vendedor), y arriba de la tabla aparece un resumen "Ventas por sucursal (solo facturas)" con el total de cada sucursal más el total general — a propósito solo cuenta Facturas (ventas reales), no boletas ni cotizaciones; la tabla de abajo sigue mostrando los 3 tipos igual que antes.geitems_man + una línea por producto en geitems_mand (MADTIPO='E') + una fila espejo por línea en geitems_mov (ITMTIPO='ME', ITMDOC=el N° de esa entrada) para el saldo corrido y el costeo — el Kardex ya sabía leer este patrón sin cambios adicionales. El ⚖ de una sola fila en la tabla de Productos sigue igual, para ajustes rápidos de un solo producto.geserver_print (tabla externa que escribe la propia impresora de despacho, no Kognit) probando tanto el N° de la cotización como el de sus facturas asociadas (FANROCOT), por si el envío a imprimir queda registrado con uno u otro número. Al pasar el mouse sobre el pill muestra quién lo envió, la fecha y la hora.ws.append([]) (la fila en blanco antes del encabezado) no crea una fila real en openpyxl, así que el cálculo de en qué fila pintar el encabezado quedaba corrido en uno — el fondo azul se pintaba en una fila fantasma vacía y el texto de los títulos caía en la fila siguiente sin ningún estilo. Corregido con una fila en blanco real (ws.append([None])), quedando el fondo azul y el texto blanco en la misma fila, igual que se ve en pantalla.ITMIN/ITMINGRESO/ITMQIN, pero el Ajuste de Stock escribe en ITMINT — no la encontraba y mostraba "–" aunque el dato sí estaba guardado en la base. El stock nunca estuvo mal, solo esa columna en pantalla.geserver_print.usuario es el código del usuario del ERP de escritorio (tabla usuarios, CCODIGO/CNOMBRE — la app de despacho corre ahí, no en Kognit), distinto de cot_usuarios o gevend aunque coincidan números por casualidad. Ahora se resuelve a nombre real (ej. "18" → "PEDRO HILARRAZA"); si esa tabla no existe en alguna instalación, muestra el código tal cual (como antes).cot_cabecera) el dato ya venía correcto (comuna). En las del ERP legado (gecot_enc) se leía COCIU, que en este ERP es la provincia (ej. "Chacabuco", que ni siquiera es una ciudad — es la provincia de Colina), no la comuna. Ahora se lee COCOM (comuna real: "Colina", "Providencia", "Viña Del Mar"), con reversa automática a COCIU si esa columna no existe en alguna instalación.ITBO1/ITBO2/ITBO3) — ITSTOCK no se suma a nada ahí. Si se dejaba el selector de bodega en "Única/no aplica", el ajuste se guardaba igual (con su cantidad correcta, visible en el Kardex) pero en ITSTOCK, que nunca aparece en ningún total visible — parecía que el ingreso "no se registró". Ahora, si la empresa es multibodega, el sistema exige elegir una bodega antes de guardar el ajuste (tanto desde Inventario → Productos/Kardex como desde /bodega).geitems_mae y que la reversa no deje esa bodega en negativo (por ejemplo si hubo ventas después que ya consumieron ese stock); si pasaría, avisa y pide confirmar de nuevo para forzarlo.cxc_pagos_manual) sumándole un campo nuevo origen_doc_key que evita aplicar de más la misma NC dos veces./bodega (y de Inventario → 📍 Ubicaciones) no leía nada: la librería de escaneo (ZXing) se cargaba desde un CDN externo (unpkg.com) directo en la página; si esa tablet o celular no tenía salida a internet (común en redes de bodega restringidas), la librería nunca llegaba a cargar y la cámara escaneaba sin detectar absolutamente nada, sin ningún error visible — parecía simplemente "no leer" los códigos. Ahora se sirve local (nueva ruta /zxing.min.js, archivo vendorizado en el servidor, mismo criterio que ya se usaba con html5-qrcode.js), con el CDN externo solo como respaldo si el archivo local llegara a faltar, y un aviso visible en pantalla si de verdad no se puede cargar (en vez de fallar en silencio).rep-con-importaciones) que no correspondía al del checkbox real (rep-con-imp), y además Excel/PDF/Email volvían a leer todos los filtros directo del DOM en vez de reusar los mismos de la última vez que se presionó "Calcular" — cualquier cambio de estado de esos controles (categorías, tipos, proveedores) entre calcular y exportar podía dejar el archivo vacío o con datos distintos a los que se veían en pantalla. Ahora Excel y PDF reutilizan exactamente la misma consulta que generó los resultados ya visibles..etq-code img) forzaba el código de barras a un ancho FIJO de 3.4cm, pensado originalmente como un mínimo pero que en la práctica también actuaba como máximo — si el código del producto tenía más caracteres, el código de barras generado (naturalmente más ancho) quedaba comprimido para caber en esos 3.4cm, adelgazando las barras hasta volverlas ilegibles para cualquier lector físico o de celular, aunque en pantalla se viera "normal". Ahora solo se fuerza el ancho mínimo (min-width), dejando que el ancho natural del código de barras (según cuántos caracteres tenga) se respete siempre./api/documentos/conciliacion/guardar calculaban el excedente por separado y cada uno insertaba su propia fila en gepagos_ant — una como "anticipo por pago mayor" (dentro de _ingresar_pago_erp_core, calculada sobre el pendiente real del ERP) y otra como "excedente de pago mayor" (calculada aparte con el total del documento que manda el navegador) — el mismo sobrepago quedaba contado dos o más veces como saldo a favor del cliente, visible en Cuentas x Cobrar → Créditos disponibles. Eliminado el bloque redundante; el excedente ahora se escribe una sola vez. Los duplicados que ya quedaron guardados de antes de este fix hay que eliminarlos a mano (botón 🗑 junto a cada saldo en "Créditos disponibles", pide motivo y queda auditado).image-rendering: pixelated/crisp-edges) en esa imagen.MAPRO=0 en geitems_man, y después el Kardex mostraba "Cliente: 0 — 0" al no encontrar ningún proveedor con ese RUT. Ahora se exige elegir un proveedor real de la lista de sugerencias antes de poder confirmar (validado también en el servidor, por si llega por otra vía)._lblBarcodeSvg) que ya generaba los códigos de las etiquetas de producto, con ancho natural (no forzado) y renderizado nítido para que se pueda escanear. Va debajo de la descripción del producto, no al costado (a diferencia del QR).MIN(FANRO) — la más antigua — y las demás quedaban invisibles en la tarjeta, aunque sí existieran en el ERP. Ahora se traen y muestran TODAS las facturas asociadas a ese ticket (FANROCOT), cada una con su propio botón "🏷️ Etiqueta" y marca de pago. Además, "pagado" ahora se calcula con el mismo criterio real de Cuentas por Cobrar (saldo pendiente = 0, vía _doc_pendiente_erp) en vez de solo verificar que existiera alguna fila en gepagos — y el ticket queda "✓ PAGADO" solo si todas sus facturas están pagadas (antes bastaba con que una tuviera algún pago, aunque fuera parcial)./bodega, junto al de ubicación — permite hacer un ingreso o rebaje manual de stock desde el celular, visible solo para admin/superadmin (mismo permiso que ya exigía el escritorio). Reutiliza el endpoint que ya existía (POST /api/inventario/ajuste): inserta en geitems_mov y actualiza el stock en geitems_mae — ningún dato ni tabla nueva, solo se expuso también en la app móvil. Incluye selector de Bodega (1/2/3) para instalaciones multibodega como Allen. Sesiones que ya estaban abiertas antes de este cambio se re-loguean solas automáticamente la primera vez (faltaba guardar el rol para poder mostrar el botón). Nuevo modo por defecto "🔢 Cantidad contada": se escribe el stock que se contó físicamente y el sistema calcula solo la diferencia (ingreso o rebaje) contra el stock actual, incluso si ese stock actual está en negativo — el modo anterior de elegir Ingreso/Rebaje y la cantidad a mano sigue disponible como "➕➖ Por diferencia".geitems_mov: el movimiento se grababa con ITMTIPO='AJU', un código que el Kardex no reconoce en su filtro de tipos — ahora usa ITMTIPO='ME' (ingreso) o ITMTIPO='MS' (rebaje), el código real de "Entrada/Salida Manual". El Kardex excluía TODO ME/MS a propósito (para no duplicar lo que trae Ingreso de Importación); se afinó esa exclusión para que solo tape los ME/MS que de verdad vienen de un encabezado de Ingreso de Importación (ITMDOC con un N° real en geitems_man) — el ajuste de stock usa ITMDOC=0, así que ahora sí queda visible en el Kardex. Además ITMSAL quedaba fijo en 0 (rompía el saldo corrido de los movimientos siguientes) y ITMCOSTO se llenaba con lo que se escribiera en el formulario en vez del costo real — ahora ITMSAL es el saldo corrido real (anterior + ingreso − rebaje) y ITMCOSTO es siempre el costo promedio actual del producto.image-rendering: pixelated a la imagen del código en las etiquetas térmicas chicas (antes solo estaba en la etiqueta horizontal grande) — cualquier escalado (no solo rotación) puede difuminar los bordes del código si el navegador la suaviza al achicarla.gepagos; para SII: sin fila en cxc_pagos_manual con doc_key SII), de todos los clientes a la vez, no uno por uno. Muestra días de atraso (en rojo si superan 30) y avisa si faltan períodos del SII por descargar para ese rango. Botón "🖨 Imprimir / PDF" para verlo/guardarlo.getUserMedia no logra capturar la foto (permiso de cámara denegado, sin cámara, cámara ocupada por otra app, navegador sin soporte, o falta HTTPS/localhost), la tarjeta de la solicitud ahora muestra el motivo exacto (ej. "🚫 Permiso de cámara denegado") en vez de quedar en blanco sin ninguna pista._row_solicitud(), que no incluía el campo foto_path en la respuesta — la miniatura nunca se dibujaba ahí aunque la foto sí estuviera guardada en el servidor (sí se veía en Conexiones → 🔐 Accesos al sitio, que lee la tabla directo). Ahora ambas vistas muestran la foto por igual.genc_enc.NCDOC/NCTIPODOC.cot_etiqueta_notas), así que la próxima vez que se abra o reimprima su etiqueta ya viene cargada.cot_etiqueta_cola con reclamo atómico para evitar imprimir la misma etiqueta dos veces si hay más de una estación abierta.PAESTADO='CO' (cobrado) aunque tuviera la fecha del documento a futuro. Ahora todo pago con cheque queda Pendiente (PE) con la fecha del cheque, hasta que el usuario lo confirme manualmente cuando el banco lo cobre de verdad — igual que ya funcionaba para otros pagos pendientes.gepagos_ant pero el pago real desaparecía, dejando la factura como si nunca se hubiera pagado. Se reordenó para que la limpieza corra primero y la aplicación del combo (saldo/NC/monedero) después, así queda escrita y firme.CERRADA en el ERP; los cerrados quedan en una lista aparte debajo del tablero ("🗑 Cerrados (N)"), oculta por defecto con un botón para mostrarla/ocultarla. Con el mismo formato, los despachos "retira cliente" ahora siempre se sacan del tablero activo (ya no depende de un checkbox) y quedan en su propia lista colapsable ("🚶 Retira cliente (N)") debajo de la de Cerrados — nunca se eliminan ni se toca la cotización en el ERP, solo se mueven de lista.geitems_man/geitems_mand (igual que "Mov. Manuales → Ingreso Art." del ERP de escritorio), los movimientos en geitems_mov (ITMTIPO='ME') y llama a recalcular_stock por producto para dejar el stock al día. El costo promedio ponderado ya calculado en la vista previa queda como el nuevo ITCOSTO (no toca el historial de movimientos anteriores), y actualiza ITPREC donde se marcó "Actualizar PV". Pide proveedor (buscador por nombre/RUT contra gecli), bodega, observación y fecha antes de confirmar. Solo superadmin.geitems_mae con sus columnas reales de datos generales/precio/stock/ubicación, geitems_cod para códigos alternativos, geitems_pro para proveedores) — queda idéntico a uno creado desde el ERP. Pestañas Datos Generales / Precio de Ventas / Stocks / Proveedores / Adiciones (Ficha Técnica y Kit quedan para una siguiente etapa). Solo admin/superadmin.recalcular_stock) fallaba siempre en esta instalación (su UPDATE final concatena el saldo pegado a "WHERE" sin espacio, ej. 750.00WHERE — error de sintaxis) y el respaldo que ya existía para ese caso usaba STOCK_CONFIG["columna"], que puede ser el literal "multibodega" (una etiqueta interna, no una columna real) en instalaciones con más de una bodega — de ahí el error "Unknown column 'multibodega'" al confirmar un ingreso. Corregido en Ingreso Orden de Importación y en Ajuste de Inventario: ahora el stock siempre se corrige con un UPDATE propio a la columna real (ITBOn o ITSTOCK), sin depender de que el SP haya funcionado.geitems_man/geitems_mand/geitems_mov. Guarda el estado anterior en una tabla propia de Kognit al momento de confirmar, para poder revertir con precisión.version.json: el endpoint /api/version parseaba HISTORIAL_ACTUALIZACIONES.md con una regex propia (con sus propios valores por defecto "1.0.1"/"Desconocida"), en vez de leer version.json como indica el propio comentario "fuente de verdad" del sistema de auto-actualización. Ahora lee version.json directamente, igual que el resto del sistema.version.json con BOM rompía la lectura en silencio: al guardarlo con PowerShell (Out-File -Encoding utf8) queda con un BOM invisible al inicio; json.load(..., encoding="utf-8") fallaba por ese BOM y el backend caía siempre a sus valores por defecto ("v1.0.0", "Versión inicial automática"), aunque el archivo real tuviera la versión correcta. Ahora se lee con utf-8-sig (tolera el BOM si existe) en /api/version, _version_actual() y el panel de Deploy.gecot_enc.COENVIO), excluyendo "retira cliente" — para poder estar atento a la asignación de pagos de facturas que corresponden a despacho.cot_concil_banco), ahora se muestra bajo el documento del pago en las tres vistas del kardex de CxC (agrupada por documento, pendientes de confirmar y cronológica).FANROCOT y CONRO como texto (str()), pero si MySQL devuelve uno como entero y el otro como Decimal (ej. columna DECIMAL), los textos nunca calzan ("12345" vs "12345.00") aunque sean el mismo número. Corregido con un normalizador numérico.FROM ("...fanrocot, FROM..."), rompiendo la sintaxis SQL y devolviendo error 500 en ambas pantallas. Corregido.ITUBI1-4) y su stock actual del sistema; incluye asignar/editar la ubicación de productos que ya existían. Disponible de dos formas: la pestaña Inventario → 📍 Ubicaciones dentro de Kognit, y una página aparte en /bodega (login propio, sin el menú de Kognit alrededor) pensada para dejar fija en una tablet o celular de bodega. Requiere el nuevo permiso "Ubicaciones de bodega" (admin/superadmin lo tienen por defecto).gevend, WhatsApp), correo de la empresa con info@allen.cl como respaldo. QR opcional (url editable, por defecto el catálogo). Vista previa editable en pantalla antes de imprimir, tamaño etiqueta térmica 10×15cm.gepagos_ant. Causa: en esa tabla PATIPODOC es varchar(1) (guarda F/B) y PAID es autoincremental, distinto de gepagos. Ahora el excedente queda correctamente como anticipo del cliente (PAESTADO='PE'), disponible para asignar a otra factura.gevend) en el modal de asignación de abonos; queda registrado en PACOBRA del pago. Preselecciona el vendedor del usuario logueado.CA_ID=0 (antes quedaba nulo).NEL) se contaba como si ya estuviera aplicada. Ahora solo cuentan las aplicaciones reales (NCR).gepagos, gepagos_ant, genc_enc). Nace desactivado (modo revisión): registrar pago, conciliar banco, WebPay, Transbank y asignar NC siguen funcionando en Kognit, pero no tocan el ERP. Cubre todos los flujos.gecli.CLICREMAX), pendientes de la semana con Despacho/Local, pagos manuales y vista previa imprimible.gepagos con las convenciones del ERP (PAESTADO CO/PE/EL, PATIPO='A', PANROBAN=0, PAID = MAX+1, cobrador desde gevend), desde CxC y desde todos los flujos del Libro de Ventas.gepagos_ant (PE), asignable después a otra factura. Se avisa el monto en pantalla.NCESTADO='CERRADA' y la fila muestra "✔ NC aplicada"; al eliminar el pago vuelve a GENERADA y queda disponible de nuevo.PANROCH, PANROBAN, PAFECCH). Cheque a fecha futura → CHF.PATIPODOC exacto. Elimina los falsos "⚠ Saldo negativo" y "posible folio duplicado".EL (eliminados) y los NEL (marca de origen NC, no un pago), y los PE se muestran aparte sin descontar.geciu multiplicaba las filas y el mismo cliente aparecía dos veces.PAFECCH es la fecha del cheque, no la del pago; para el resto de los medios se usa PAFECING (fecha real de ingreso).genc_det), y las NC de boletas con RUT genérico (1-9) ya muestran el cliente correcto (prioriza NCNOM).gevend); se muestran los datos del cliente (giro/email/teléfono) al editar; y el detalle indica el origen del documento (Web/ERP/Offline/Lead/Kognit).DATETIME DEFAULT CURRENT_TIMESTAMP y el error se perdía en silencio.sueldo/30/8) y Dictamen 5308/230 ((sueldo/30×28)/(jornada×4)), aplicada tanto a la liquidación como a la vista de Asistencia.gebodegas.gebodegas. Nuevo tipo Traspaso entre Bodegas (T). Tarjetas reordenadas y columnas duplicadas quitadas. Bodega de ME/MS se cruza con geitems_mov.ITMBOD. Cantidad de NEL se suma desde genc_det. Fix columna bodega destino (nombre real detectado automáticamente) que hacía desaparecer todos los movimientos manuales/traspasos.POST /api/rem/liquidaciones/pdf-preview.rem_excedentes_isapre y endpoint GET /api/rem/excedentes-isapre.rem_descuento_tipos.remuneraciones./api/indicadores es ahora público (no requiere sesión activa), eliminando posibles errores de autenticación al cargar el dashboard.CODFACT vacío o '0'). Los ítems ya facturados no aparecen.backup_ultimo_error en vez de capturarlo silenciosamente. El panel de Respaldo BD muestra el último error junto al último backup exitoso para facilitar el diagnóstico.geord_enc/geord_det usaban CAST(ORCLI AS CHAR) dentro de COALESCE en el GROUP BY, lo que falla silenciosamente en algunas versiones de MariaDB/MySQL. Simplificadas las 3 queries para eliminar el CAST del SQL. Los proveedores 🏭 de órdenes de compra ahora aparecen en el dropdown y en las filas de productos.allen.cl/bodega/index.html — app standalone con login propio (campo codigo), token guardado por servidor en localStorage, escáner nativo (BarcodeDetector + getUserMedia) sin librerías externas. Fix error "[object Object]" al iniciar sesión."SIN-ORDEN" por defecto. El campo se muestra como "(opcional)" con hint que explica el comportamiento FIFO para retiros.Authorization manuales en guardarNotifAcceso — el wrapper global window.fetch los inyecta automáticamente. Corregidas referencias gw_token → _jwt.BarcodeDetector nativo con loop requestAnimationFrame y fallback a html5-qrcode solo si el API nativo no está disponible..sql.gz con mysqldump o fallback Python puro. Archivos en GW_DATA_DIR/backups/. Lista descargable desde el panel.geitems_mov con tipo AJU y llama a recalcular_stock. Solo admin/superadmin._repProdRendered (siempre sincronizado con el DOM) como fuente de datos, eliminando mismatch entre BDs..xlsx real con SheetJS.const formato causaba SyntaxError que dejaba el login atascado en "Verificando conexión…".periodo (YYYYMM) desde la fecha de inicio del filtro activo.cot_arco_solicitudes). Nuevos endpoints: /api/privacidad/config, /api/privacidad/aceptar, /api/privacidad/admin-config, /api/privacidad/guardar-config, /api/privacidad/purgar, /api/privacidad/solicitudes-arco./api/privacidad/aceptar-link?token=XXX).GET /api/mp/buscar-live.textoBusqueda a la API de MP, filtrando sobre todas las COTs del portal. Debounce de 500ms.Z (UTC) para que el browser las convierta a hora local Chile correctamente.estado=2 — la API devuelve el mismo universo que el portal./api/admin/tipos-doc (tipos reales de getipos). Endpoint ahora acepta permiso cambiar_tipo_doc, no solo admin.CodigoOC no está vacío y RUTProveedor coincide con el RUT propio) y la suma de MontoTotal de esas adjudicaciones. Se recalcula automáticamente al aplicar filtros de mes/región/texto.cambiar_tipo_doc en Parámetros → Usuarios. Cuando está activado, el vendedor ve la sección "Cambiar tipo de documento" dentro de su modal de perfil (clic en avatar). Permite buscar una cotización por número, ver el tipo actual y cambiarlo con un motivo obligatorio — igual que la herramienta de admin pero accesible desde el avatar. El historial de cambios queda registrado en cot_estado_log con usuario, IP y equipo. Los admins siempre ven la sección.GET /api/mp/config regenera la mp_api_key automáticamente si no existe, evitando que el bookmarklet quede en "Cargando…". Banner de expiración mejorado: muestra botón "🌐 Abrir MP" directo y cambia a polling cada 30s cuando hay token expirado para detectar la renovación automáticamente tras usar el bookmarklet.desde/hasta en GET /api/mp/licitaciones.orderBy=1, estado=2 (sin filtro de fecha) — idéntico al buscador.mercadopublico.cl — descargando hasta 2 000 COTs ordenadas por cierre próximo. Siempre arranca desde la página 1 para no saltarse novedades. Las 3 tarjetas explicativas se reemplazaron por un banner único descriptivo.es_invitacion TINYINT en cot_mp_licitaciones. Las COTs descargadas desde el endpoint autenticado (donde el proveedor fue invitado directamente) se marcan con es_invitacion=1 y muestran el badge azul 🔔 INVITADO en la tabla. El campo es sticky (si una COT ya está marcada como invitada, un re-sync no la desmarca).GET /api/mp/oc-pendientes (servicios-escritorio.mercadopublico.cl). Clic abre panel con lista de OC: número, organismo, fecha y link "Ver en MP →". Nuevo JWT Escritorio en ⚙️ Configuración MP (token Keycloak/heimdall, distinto del COT). Endpoints: POST /api/mp/escritorio-jwt, GET /api/mp/oc-pendientes.ver_certificados por usuario (admin siempre lo ve). Endpoints: GET /api/certificados, /api/certificados/archivo, POST /api/certificados/enviar. Carpeta: GW_DATA_DIR/certificados/.mp_activo). Los vendedores lo ven si tienen el nuevo permiso 🏛️ Ver Licitaciones MP activado en Parámetros → Usuarios (igual que ver_leads).origen en cot_cabecera (migración automática). El badge muestra: Web para cotizaciones del formulario Kognit; 📱 Offline para notas de venta sin red (detectado por cot_notas_offline); 🌐 Lead para conversiones de lead web (detectado por cot_web_leads.erp_conro); Leg para entradas directas del ERP.mpPollSyncStatus ahora llama cargarLicitacionesMP() fuera del bloque if/else — tanto si el sync termina con éxito como si falla, la tabla y todos los KPIs se recargan siempre.mp-filtro-cierre (ya oculto y sin opciones). Ahora llaman mpSortBy('cierre') / mpSortBy('publicacion') para ordenar la tabla directamente.mpRenderDashboard() ahora se invoca desde mpRenderTabla() con la lista ya filtrada — al filtrar por región, estado, tipo o texto, todos los contadores (Total, Publicadas hoy, Cierran hoy/mañana/semana, En seguimiento) se recalculan sobre el subconjunto visible.opacity: 0.55 y fondo gris — indicando visualmente que ya fueron revisadas sin sacarlas del flujo. El botón 👁 sigue funcionando para marcar/desmarcar.PATCH /api/mp/licitaciones/{codigo}/revisada ahora verifica con SHOW COLUMNS si existe la columna revisada y la crea con ALTER TABLE si no — en lugar de asumir que la migración ya corrió.cot_api_id en SELECT: mp_ofertas_refresh ahora verifica con SHOW COLUMNS antes de incluir cot_api_id en el SELECT; si no existe usa NULL AS cot_api_id.cot_api_id en INSERT: _mp_guardar_licitaciones construye dinámicamente _cols/_vals/_upd con SHOW COLUMNS, incluyendo solo las columnas que existen. El CREATE TABLE ya incluye todas las columnas nuevas para instalaciones limpias.GET /api/mp/licitaciones/{codigo}/ofertas ahora usa la API COT JWT como fuente primaria (escanea ventana ±45 días por publicación, extrae ofertasRecibidas); el scraping HTML era el fallback pero buscador.mercadopublico.cl es una SPA renderizada por JS. El toast indica la fuente: "(API MP)" o "(portal)".revisada se persiste en BD (TINYINT DEFAULT 0) y sobrevive re-sync. Endpoint PATCH /api/mp/licitaciones/{codigo}/revisada.ofertas_recibidas y mis_ofertas en BD con migración automática.organismo.compra-agil.mercadopublico.cl/resumen-cotizacion/{codigo} directamente (URL descubierta en portal). Fix modal "Ir a Licitar" también actualizado. Fix onclick roto por comillas dobles en template literal.pin_warning_ok en localStorage para silenciar permanentemente. Login devuelve pin_archivo para diagnóstico.GET /api/admin/usuarios ahora requiere token y filtra usuarios con rol=superadmin si el caller no es superadmin. PUT y DELETE bloquean con 403 si el target es superadmin y el caller no lo es. Todos los fetches del panel de usuarios pasan Authorization: Bearer.ultima_sync en timer: el auto-sync ahora espera al worker COT antes de actualizar la hora mostrada.adjudicacion_json coincide con el RUT proveedor configurado en Parámetros → MP Config, se muestra un badge dorado 🏆 ADJUDICADO A MÍ en la vista lista, fichas y Excel del módulo Mercado Público. El cálculo se realiza en el backend al listar, también aparece en el CSV exportado.GET /api/mp/licitaciones ahora devuelve fecha_publicacion y el nuevo campo booleano adjudicado_a_mi.fecha_adj; para el resto, sobre fecha_cierre. Permite buscar historial de adjudicaciones pasadas.adjudicado_a_mi=true, útil para ver el historial completo de adjudicaciones propias.POST /api/mp/guardar-cot). Filtros: texto, estado, monto mínimo, "solo no guardadas". Endpoints: POST /api/mp/preview-excel (parsea y devuelve JSON sin guardar, incluye flag ya_guardada) y POST /api/mp/guardar-cot (upsert individual en cot_mp_licitaciones con en_seguimiento=1)./v1/compra-agil-busqueda/buscar con parámetros desde/hasta/orderBy/size/page. Pagina automáticamente hasta 100 páginas (hasta 2000 registros), mapea los nuevos campos (idEstado, estadoConvocatoria, misOfertas, ofertasRecibidas, montoDisponible, organismo/unidad concatenados). El toast muestra cuántas se trajeron, páginas recorridas y nuevas vs actualizadas. Rango configurable: dias_atras=180, max_paginas=100.Z para que el navegador las convierta a hora local (Chile) automáticamente.page_inicio=1 fuerza desde el principio.#inp-rut), llama buscarCliente() para autocompletar datos del cliente, descuento y condición de pago desde el perfil ERP, mapea forma de pago y modo de entrega/api/publico/vendedorescot_web_leads y traspasada al formulario al crear cotizaciónGET/POST /api/config/leads, GET /api/publico/vendedores/api/cliente/{rut}: fallback sin JOINs cuando las tablas gereg/gecom/geciu no existen (ERP MySQL antiguo); columnas CLICIU/CLICOM/CLIREG toleran int o varchar/, ,, %, |): backend usa {itcod:path}, frontend _encProd() deja la barra literal y codifica el restoinp-obs); l.items con fallback JSON.parse si viene como stringinp-observaciones en lugar de inp-obs) y no se vaciaba al crear nueva cotización; además el badge de vendedor del lead tampoco se ocultaba al limpiarshowPage('nueva') antes de limpiar, garantizando que el formulario de cotización quede visible y activonavigator.geolocation) guarda lat/lng en cot_cabecera. Para el historial sin GPS, geocodifica con Nominatim (OpenStreetMap, gratis, sin API key) y cachea en cot_geocache. Mapa interactivo Leaflet: pins numerados (azul=GPS exacto / naranja=geocodificado), línea de ruta, popup con datos de cotización y lista de visitas. Admin ve cualquier vendedor; el vendedor solo la suya.gefac_enc (facturas) o gebol_enc (boletas), independientemente del estado de sus cotizaciones. Además se excluyen cotizaciones ANULADAS del conteo.lat/lng aún no existen en la BD (servidor recién instalado); la ruta funciona aunque el servidor no se haya reiniciado después de la actualización.isolation:isolate para confinar los z-indexes internos de Leaflet (markers/popups) — al abrir cualquier modal estando en la pestaña Ruta, el backdrop oscuro cubre el mapa correctamente.cliente_email al endpoint del historial (GET /api/cotizaciones) y se actualiza el onclick del botón Email tanto en la vista de detalle como en la lista del historial.guardarCotizacion() nunca reseteaba el botón "Guardar" en el path de éxito — quedaba deshabilitado si el usuario cerraba el modal sin hacer clic en "Nueva". (2) Ambos botones (web y ERP) ahora llaman a limpiarFormulario() automáticamente tras guardar con éxito, antes de mostrar el modal de acciones (el modal no depende del formulario sino de parámetros propios).gecot_enc + gecot_det (ERP) en vez de cot_cabecera. Dos secciones: Sin facturar (cotizaciones donde ningún ítem tiene CODFACT asignado) y Parcialmente facturadas (algunos ítems facturados, otros pendientes) con cantidad de ítems pendientes y monto; filtra el año en curso; si no hay parciales muestra "No hay facturas parciales pendientes".cot_mp_licitaciones. Filtros por texto/estado/monto mínimo, tab Listado / En seguimiento, tabla con código/nombre/organismo/monto/cierre/días restantes, modal de detalle con ítems y link a mercadopublico.cl, botón seguimiento por licitación. Config por empresa (token, RUT proveedor, monto mínimo, activar/desactivar). Configurado para empresa Alas.↩ 3 NC · -$245.000) con el neto real de facturas. KPI "Notas de Crédito" en rojo aparece en el encabezado cuando hay NC en el período. En la tabla comparativa, sub-fila roja por año con el detalle de NC. Endpoints devuelven ahora nc_cant, nc_neto, nc_total, v_cant_bruto como campos separados.GET /api/documentos/ventas-boletas/resumen-mensual-erp.geparam) de la base activa. Solo para administrador o superadmin; para el resto siguen siendo de solo lectura. Botón "Guardar datos del ERP" separado del de logo.window.print()./api/version/* como ruta pública (sin autenticación), impidiendo
que el token llegara al endpoint de guardado. Corregido a solo /api/version (exacto).Kognit_*, clave de BD cifrada al vuelo, accesos directos por empresa).CODFACT=1).gecot_enc.COFECDESP.crear_empresas.bat crea de una vez las carpetas de
datos de varias empresas y copia en cada una .secret.key y conexiones.json.
Luego solo se instala el servicio de cada empresa.GW_DATA_DIR
(conexiones, claves, configs y logos separados). Incluye servicio_instalar_empresa.bat y
ejemplo de Caddy para una URL por empresa. Sin cambios si se usa una sola empresa.tzdata) y reiniciar el servidor.geparam.cf_tipo_bodega: Si vale 0, el stock mostrado es
geitems_mae.ITSTOCK; si vale 1, es la suma de las bodegas (como antes). Si la
columna no existe, se mantiene la detección automática. Se aplica por base de datos.gecot_det.CODTIPO) se ajusta junto a la cabecera para no romper el ERP. Cada cambio queda
auditado (usuario, fecha/hora, IP y equipo).upload.php con el token secreto ya incluido, se sube al hosting una vez y listo. Token guardado cifrado.https://www.gamspa.cl/cotclientes/C-2026-00001.pdf, en vez de una dirección interna. Se
configura en Parámetros → Mi Empresa → FTP (campo "URL pública del PDF", por base).cotclientes por defecto). Se configura en Parámetros → Mi Empresa →
FTP (solo superadmin), por base de datos, con botones Probar conexión y Crear carpeta. Si el FTP
falla, la cotización igual se graba. Requiere reiniciar el servidor.geparam de la BD activa
(solo lectura); el logo sigue de carga manual. Los PDF y correos usan la empresa de cada BD.app_config.json).cot_estado_log. Se auditan también
autorizar/rechazar y los cambios del sistema nuevo.geitems_cod), con buscador y exportación a PDF y
Excel (hojas "Por producto" y "Por código").COTIPO.CREATE TABLE) y ahora todos los dispositivos nuevos piden
autorización (se desactivó la auto-aprobación de la red local; localhost sigue como
salida de seguridad). Configurable en app_config.json (sitio_auto_aprobar_lan).gecot_enc / gecot_det). La numeración usa
el último CONRO real con bloqueo y reintento anti-duplicado, para no chocar con el ERP en
marcha. El botón "Guardar Cotización" original sigue funcionando igual.getipos), que llenan
CODESPACHO/CORETIRA/COTRANSPORTE y COENVIO. El tipo de
documento (COTIPO) toma el valor del select "Tipo Cotización".gecot).PENDIENTE. Los administradores ven todas; los vendedores solo las suyas.gebol_enc.Bearer token en todas las APIs. Frontend inyecta token automáticamente en cada
fetch. Logout en 401.localhost por defecto; configurable con
ALLOWED_ORIGINS en .env.gecot_det.CODFACT como fuente
autoritativa (vacío/0 = pendiente; con valor = facturado). Fallback a COESTADO si no existe
la columna.COESTADO. Default = solo facturadas.nc_por_dia[].ITFA_COM_TIPO e
ITFA_COM_FIJO.POST /api/mantenedor/familias/comision-masiva.neto × % (tipo pct)
o cant × $fijo (tipo fijo). Afecta KPIs, totales, subfamilias, vendedores y detalle de
líneas. Badges muestran X.X% (verde) o $Y/u (azul).vgd-spin/vgd-contenido. Renombrados a
vgds-spin/vgds-contenido para Despachos._vgDespachoData para forzar recarga.
id="lbl-condiciones-doc".geitems_mae.ITCOSTO × cant.; ítems sin maestro se valorizan con costo 0.gecli.CLIREG → gereg y
gecli.CLICOM → gecom. Incluye KPIs (regiones/comunas activas, % sin georeferencia),
ranking top regiones y top 15 comunas, y acordeón expandible región → comunas con barra proporcional,
neto, docs, ticket promedio y % sobre región y total. Neto bruto (sin NC). Fallback automático a
geciu si gereg/gecom no existen.cot_detalle con
gecot_det + gecot_enc via UNION ALL, con nombres desde
geitems_mae. El filtro de período aplica a ambos sistemas./api/ventas-gefac/vendedores reescrito con dos
consultas separadas (códigos primero, nombres después), eliminando el JOIN problemático. El frontend
solo carga el dropdown cuando está vacío.gefac_enc.FAVEN / gebol_enc.BOLVEN → gevend. Aparece solo
cuando hay datos de vendedor.cot_usuarios.cod_vendedor para filtrar el sistema nuevo, y filtra
gecot_enc.COVEN para el sistema legado.CLISUC=1), aparece un selector 🏢 con todas sus sucursales. Al elegir una, se
rellenan automáticamente Dirección, Ciudad, Contacto, Email y Teléfonos con los datos de esa
sucursal.cot_cabecera.vendedor guarda el nombre del usuario, no el código gefac. Ahora se envían
dos parámetros separados: usuario (nombre del usuario → sistema nuevo) y
vendedor (código gefac → sistema legado). El badge muestra "Nombre (cód:
XXX)".geven fue reemplazado por consulta separada y segura contra gevend (tabla
correcta de vendedores).genc_enc), igual que el "Neto Real" del informe de ventas.codfact = 0 se marcan PENDIENTE; los ya facturados se muestran atenuados.GET /api/producto/{itcod} que estaba
ausente.cargarInformes() que causaba
SyntaxError y dejaba el login atascado en "Verificando conexión…".showPage()) y los botones no las encontraban. Movidas al scope global.mail.allen.cl:587 que usan SSL implícito en lugar de STARTTLS.SMTP_CONFIG global (desde smtp_config.json) con fallback
a configuración personal del usuario en cot_usuarios. El código anterior buscaba en
tablas de base de datos que no existen.httpx, Request) dentro
del endpoint de email que causaban "Internal Server Error". Se agregó usuario_codigo al
fetch del modal para usar SMTP personal del usuario si está configurado._generar_pdf_ventas_bytes()
retornando bytes directamente, eliminando el uso frágil de body_iterator async. El JS del
modal ahora muestra el mensaje específico del error (SMTP, autenticación, etc.) en lugar del texto
crudo.data-desde/data-hasta y escapa correctamente comillas en el código del
producto.ITMCLI ahora se reconoce como campo de RUT (no
nombre), permitiendo que el Kardex resuelva el nombre del cliente desde gecli.
ACL-1 1/2"304) ya no
generan atributos HTML rotos.ITMCLI almacena el RUT como entero, no el nombre. Corregida
la clasificación para permitir el JOIN con gecli y obtener nombre, email, teléfono y
contacto del cliente.geitems_mov (misma fuente que el contador
de vendidos), garantizando consistencia con el número mostrado en la tabla.TRIM() en todas las consultas a geitems_mov para
tolerar espacios en el código almacenado.Desc.% y
muestra el P. Neto real.1.5,
el oninput
llamaba renderItemRow
que destruía y recreaba el input con parseFloat("1.") = 1,
borrando el punto. Corregido: renderItemRow
ya no destruye los inputs dto1/dto2 si tienen el foco — solo actualiza el monto.ITFAM IN (cod, subcod1, subcod2...).
La tabla muestra la columna Familia para identificar a qué subfamilia pertenece cada producto. El pie
indica cuántas subfamilias se incluyeron./api/mantenedor/inventario
ahora incluye "itfam"
en cada producto (código de familia de geitems_mae.ITFAM).
Antes solo existía "familia" con el nombre descriptivo.filter(p => p.itfam === famCod)
sobre el resultado, pero p.itfam
no existía en el response → siempre devolvía 0 productos. El API ya filtra con ITFAM IN (...),
se usa directamente data.productos.
activo: int(VENEST)
y el PUT espera activo.
Eliminado el campo venest
del frontend que era incorrecto y confundía el flujo.v.venest
(campo real de gevend.VENEST)
con fallback a v.activo.
El PUT envía ambos campos para compatibilidad.geitems_mae.ITFAM.
El botón muestra el conteo al cargar y actúa como toggle para ocultar/mostrar.activo
como parseInt
para evitar que llegue como string. La comparación de cod
ahora usa String()
en ambos lados. Se usa encodeURIComponent
en la URL del PUT.p.precio1
y p.estado
que no existen en el API. Corregido a p.precios['1']
y p.activo,
que son los nombres reales que devuelve /api/mantenedor/inventario.
JSON.stringify
en onclick. Ahora usa caché _acCache
+ data-*.
Funciona con cualquier descripción sin importar comillas o caracteres especiales.cargarValidez()
y guardarValidez()
que faltaban.limpiarFormulario()
que reinicia cliente, ítems y caché (localStorage)./api/productos
y /api/mantenedor/inventario.
Búsqueda desordenada: "CABLE BLANCO" encuentra "CABLE 2MM BLANCO".kognit.html) y backend (app.py).
Solo para vendedores que cobran distinto al valor por defecto de la familia. Los no listados usan el valor de arriba.
Marca los vendedores y define la comisión a aplicarles. Luego podrás editar cada uno.
CODIGO, Code, SKU).Item, Description).Item, Description).| Código ERP | Descripción Inglés | Descripción Español | Stock | Vta/Mes | A Pedir |
|---|---|---|---|---|---|
| Cargando datos… | |||||
| Código | Descripción inglés | Descripción español (ERP) |
|---|
Historial de lo encolado hacia la estación de impresión al autorizar cotizaciones. "Impresa" significa que se le mandó la orden al sistema operativo — no hay confirmación de que salió el papel (atasco, sin tinta, etc.).
| N° Cotización | Cliente | Autorizó | Encolada | Impresa | Estado |
|---|---|---|---|---|---|
Cargando… | |||||
Especificaciones (material, medidas, norma, presión…) que se muestran junto a cada producto en el catálogo. Se pueden escribir a mano o extraer desde una ficha de sansunstainless.com — la extracción siempre queda como borrador editable, nunca se guarda sola.
El catálogo de allen.cl lee las especificaciones desde el archivo fichas-tec.json.
Descárgalo con este botón y súbelo a la carpeta del sitio, junto a imagenes.json.
Cargando…
Para activar la cotización se requiere clave de administrador.
Ingresa un número de cotización
Datos que usa el descargador: acceso a facturación.cl y cómo subir al hosting (FTP o PHP). Se guardan en empresas_facturacion.json en el servidor — no hace falta editar el archivo a mano.
Cargando descargas…
gecli a partir de los datos del SII, sin depender de ninguna sesión web del SII.
Cargando…
{
"version": "1.0.540",
"url": "https://tudominio.cl/updates/kognit_1.0.540.zip",
"sha256": "<hash sha256 del zip>",
"notas": "Que cambió",
"obligatoria": false
}
Por seguridad: la descarga se verifica con el SHA256 antes de aplicar. Solo el superadmin puede actualizar.
paquete_kognit_vX.zip trae todo lo necesario. También puedes elegir archivos sueltos. Antes de escribir se revisa que ninguno esté dañado; si uno falla, no se sube nada.Tú administras y vas cambiando la empresa activa. Cada empresa trae sus datos desde su base (geparam) y su logo por base de datos.
logo_<base>).Mismo código, pero cada empresa corre en su propio puerto con su carpeta de datos (logo, conexiones, SMTP, todo separado) y su URL.
.secret.key (el mismo, para descifrar) y un conexiones.json apuntando a la base de esa empresa.instalacion\, como administrador). Puedes
pasar los datos o dejar que te pregunte el puerto:
GestionWeb_EmpresaA (puerto que elijas) con su GW_DATA_DIR. Avisa si el puerto ya está en uso.servicio_desinstalar_empresa.bat EmpresaA. Plantillas en
instalacion\Caddyfile.ejemplo y guía completa en instalacion\LEEME_MULTIEMPRESA.txt.
GW_DATA_DIR):
conexiones.json, .secret.key, smtp_config.json,
logos_bd.json / logo_*.*, app_config.json,
ftp_config.json, sii_config.json, etc. Se comparte el código
(kognit.html, íconos). Si no defines GW_DATA_DIR, funciona como siempre
(mono-empresa).
dte_plano con archivos TXT) o
LibreDTE (por API). Al emitir, Kognit usa el motor elegido y actualiza el ERP
(gefac_enc/gefac_det/geitems_mov y el stock).
facturacion.cl/allen/..., el nombre es allen.
gebloqueo), no las de Kognit
(para eso está "Conexiones activas"). El nombre se cruza con la tabla usuarios del ERP.
https://app.graficanet.cl con candado verde,
para que funcione la cámara/foto de seguridad y la PWA desde celulares. El sistema sigue
corriendo en este equipo (puerto 8000); Caddy solo le pone el HTTPS por delante. No se toca tu correo
ni tu hosting actual.
| IP pública | Detectando… |
| IP del cliente | Detectando… |
| Puerto de Kognit | Detectando… |
| Host / Subdominio | Detectando… |
192.168.0.1) → sección DHCP → fija que este PC sea
siempre 192.168.0.160 (DHCP reservation). Si no, el Wi-Fi puede darle otra IP mañana y se rompe el reenvío.
192.168.0.160:
CNAME app.graficanet.cl → tu-ddns-actual.ddns.net
kognit-casa.duckdns.org).CNAME app.graficanet.cl → kognit-casa.duckdns.org
winget install --id CaddyServer.Caddy
caddy version.Caddyfile (sin extensión) con esto:app.graficanet.cl {
reverse_proxy http://localhost:8000
}
caddy run
app.graficanet.cl con candado verde. Para dejarlo siempre activo (servicio):caddy start
https://app.graficanet.clhttp://192.168.0.160:8000
Hasta esta versión, los pagos registrados desde el Libro de Ventas quedaban con la fecha
del día en que se digitaron, no del día en que entró el dinero. Acá se comparan contra la
fecha del abono en el banco que quedó guardada en la conciliación, y se pueden dejar
en la Planilla de Caja que les corresponde.
No se modifica nada del ERP. La corrección se guarda solo en Kognit y la Planilla de
Caja la aplica por encima: el pago en el ERP queda exactamente igual (mismo monto, mismo
estado, mismo documento) y esto se puede deshacer. Los pagos ingresados directamente en el
ERP de escritorio no aparecen acá.
Para los cobros que no pasaron por la conciliación bancaria (por ejemplo, ingresados
desde Cuentas por Cobrar): no hay ninguna fecha de banco con qué compararlos, así que el
sistema no puede deducir solo cuál es la fecha correcta — la indicas tú.
Elige la caja donde están hoy, marca los pagos que en realidad son de otro día y muévelos.
Tampoco modifica el ERP.
Un mismo RUT puede tener ficha de Cliente y de Proveedor (CLITIPO='P')
con razón social distinta cada una — no es necesariamente un error (es el patrón normal
del ERP cuando alguien es cliente y proveedor a la vez, a veces bajo un nombre comercial
distinto para cada rol). Pero si una pantalla busca el nombre "por RUT" sin distinguir el
tipo, puede mostrar el nombre equivocado — caso real: la Planilla de Caja mostraba el nombre
del proveedor en vez del cliente para una factura (ya corregido). Esta lista es solo para
revisar y decidir caso a caso si de verdad hace falta corregir algo en gecli
— no borra ni cambia nada por sí sola.
Cargando…
El ERP de escritorio no avisa de ninguna forma cuando alguien cambia un precio ahí directo — Kognit compara el precio de todo el catálogo (las 15 listas) cada 1 hora contra el último que vio, y registra acá cualquier diferencia. Los cambios hechos desde Paridad de precios o "Fijar margen objetivo" también quedan, con el usuario real que los hizo; los detectados fuera de Kognit aparecen marcados ⚙ Detectado.
Cargando…
Una liquidación de Remuneraciones queda bloqueada apenas termina el mes que liquida (no se puede editar/recalcular). Si hay un error, hay que eliminarla para volver a generarla — y eso exige esta clave, separada de la clave de acceso de cualquier usuario. Vive aquí (Conexiones, solo superadmin) para que un usuario Administrador no pueda verla ni cambiarla por su cuenta, aunque tenga acceso al módulo Remuneraciones. Se puede eximir a un usuario de que se la pidan desde su ficha (Usuarios → permisos → "exigir clave superadmin para eliminar liquidaciones de meses cerrados").
Cómo se conectan las piezas: quién usa qué pantalla, a qué backend le habla, dónde vive el dato, y con qué servicios externos conversa. Abajo, el ciclo de vida de un documento de venta de punta a punta.
Un vendedor arma la cotización en kognit.html; el backend (app.py) la guarda en gecot_enc/det del ERP. Un admin la autoriza y la emite: Kognit genera él mismo la factura (gefac_enc/det, DTE 33), la boleta (gebol_enc/det, DTE 39) o la nota de crédito (genc_enc/det, DTE 61), toma folio con reintento, mueve stock y deja el TXT para facturacion.cl — ya no depende del ERP de escritorio para esto. Si lleva transporte, aparece en Pantalla de Despachos. Si trae certificado 3.1, bodega_router.py liga el Heat No. al lote. El pago queda en Cuentas x Cobrar (gepagos). El mismo backend también sirve al Portal de Clientes, al Sitio Web público y a la app de Bodega — cuatro puertas de entrada al mismo sistema.
Arquitectura, tablas de BD, endpoints y convenciones del sistema. Se lee en vivo desde CONTEXTO_SISTEMA_COTIZACIONES.md en el servidor — siempre al día, sin copiar nada acá.
| Área | Mecanismo | Estado |
|---|---|---|
| Contraseñas de usuarios | PBKDF2-HMAC-SHA256 con sal aleatoria. Las contraseñas antiguas en texto plano se migran automáticamente al primer login exitoso. | ✅ Activo |
| Autenticación | JWT firmado con HMAC-SHA256. Sin JWT válido, ningún endpoint del API responde con datos. | ✅ Activo |
| Credenciales de BD | Cifradas con Fernet en conexiones.json. La clave de cifrado está en .secret.key separada del archivo de datos. |
✅ Activo |
| Contraseñas SMTP | Cifradas con Fernet en smtp_config.json. Nunca se almacenan en texto plano. |
✅ Activo |
| Rate limiting en login | Máximo 10 intentos por IP en 5 minutos. Al superar el límite, la IP queda bloqueada automáticamente. | ✅ Activo |
| Separación de roles | Todos los endpoints sensibles verifican el rol (vendedor / admin / superadmin) antes de responder. Los endpoints públicos solo exponen datos no sensibles. | ✅ Activo |
| Información de BD oculta | /api/db-status no expone host, usuario ni versión del servidor de base de datos. |
✅ Activo |
| Protección de datos personales | Política de privacidad con aceptación obligatoria (Ley 21.719). Portal ARCO+ para ejercer derechos. Retención configurable de logs y sesiones. | ✅ Activo |
| Auditoría de cambios | Todos los cambios de estado, tipo de documento y accesos quedan registrados en cot_estado_log y cot_actividad_log con usuario, IP, equipo y fecha. |
✅ Activo |
| Riesgo | Detalle | Impacto |
|---|---|---|
| Rate limiting en memoria | El contador de intentos fallidos se reinicia al reiniciar el servidor. Un atacante podría reiniciar el proceso para saltarlo. Mitigado por el acceso físico/red requerido para reiniciar. | BAJO |
| HTTPS depende de Caddy | El sistema confía en que el proxy Caddy maneje el cifrado SSL/TLS. Sin Caddy, la comunicación va en HTTP (solo recomendado en red local cerrada). | MEDIO |
| JWT sin revocación inmediata | Un token válido sigue funcionando hasta que expira, aunque el usuario cambie su contraseña. Los tokens duran pocas horas y las sesiones online se rastrean por latido. | BAJO |
Cargando conexiones...
-----KOGNIT LICENCIA-----. Se comprueba la firma antes de guardarla: si no
es válida o es de otra empresa, no se guarda nada.
AAAA-MM-DD.
Para cuando una factura se emitió por fuera del flujo normal (ej. desde el ERP de escritorio sin quedar
enlazada) y la pantalla de Despachos sigue mostrando "SIN FACTURAR" aunque la factura sí exista.
Esto marca la bandera CODFACT a mano — no crea ninguna factura real ni cambia el Estado de
la cotización. Todo cambio queda registrado (usuario, fecha/hora, IP y equipo).
Busca por número y cambia el tipo de documento (Nota de Venta, Ticket, Cotización, etc.). El detalle se ajusta automáticamente para no romper el ERP. Todo cambio queda registrado (usuario, fecha/hora, IP y equipo).
Busca por número y reasigna el vendedor sin
tener que abrir el documento y regrabarlo entero. Escribe gecot_enc.COVEN en el ERP, que es de
donde salen las comisiones. Todo cambio queda registrado (usuario, fecha/hora, IP y equipo).
Elige el vendedor origen, marca los clientes que quieres traspasar y elige el vendedor destino. Cambia gecli.CLIVEN — afecta a qué vendedor queda asignado el cliente en el ERP hacia adelante (no modifica cotizaciones ya emitidas).
| Cliente | RUT | Ciudad |
|---|
Cuando Kognit crea una cotización directo en el ERP (ej. al convertir un Lead Web), calcula el próximo N° (CONRO). Elige cómo lo calcula en esta empresa:
Estas opciones son propias de esta empresa (esta instancia de Kognit) — no afectan a otras empresas.
Elige qué tipos de documento aparecen en el listado de pendientes por aprobar (dashboard de Inicio e Historial filtrado por PENDIENTE). Si no marcas ninguno, se muestran todos los tipos (comportamiento actual).
Elige qué tipos de documento cuentan en la tarjeta "Pendientes Facturar" del dashboard de Inicio (del mes en curso). Si no marcas ninguno, cuentan todos los tipos (comportamiento actual). Ej. GAMSPA: marcar solo TI.
Agrega un botón en Cuentas por Cobrar → Estado de Cuenta que le pide a la IA una sugerencia de riesgo de crédito a 30 días para un cliente, usando su historial real de pagos (nunca aprueba ni bloquea nada por sí sola — la decisión la sigue tomando una persona). Requiere una clave de API de Anthropic propia (console.anthropic.com), separada de cualquier suscripción de Claude/Claude Code — se cobra aparte, por uso, aunque para este caso el costo real es de centavos al mes.
En «Clientes del mes» (Inicio) y en Leads Web → Búsquedas del sitio, cruza por RUT lo que un cliente hace en el sitio (cuenta, búsquedas, precios vistos, pedidos) con lo que compra en local, para saber si prefiere comprar directo. Solo se ve a quien inició sesión en «Mi Cuenta»: el visitante anónimo no se identifica. Son datos de comportamiento de clientes con nombre: define quién puede verlos.
Solo el superadmin puede cambiar esta opción.
Si el servidor de correo rechaza la conexión, ¿qué debe hacer el sistema?
| Estado | Usuario | Equipo / IP | Conexión | Última actividad | Desconexión | Acción |
|---|---|---|---|---|---|---|
Cargando… | ||||||
| Fecha / Hora | Usuario | 🖥️ Equipo origen | IP origen | 🗄️ Servidor BD | Base de datos |
|---|---|---|---|---|---|
|
Cargando sesiones... |
|||||
| Código ↕ | Descripción ↕ | U.M. | Stock ↕ | Precio ↕ | Agregar |
|---|---|---|---|---|---|
|
Cargando productos... |
|||||
Ingrese al menos 2 caracteres para buscar
Cargando...
Cargando…
Cargando…
Cargando...
Nueva versión disponible
Verificando...
| Código ERP | Descripción Inglés (Proveedor) | Descripción Español (ERP) | Stock | Vta/Mes | A Pedir |
|---|
| Año | Neto | Docs | vs Ant. * |
|---|---|---|---|
| Cargando... | |||
| Fecha | Hora | Tipo | N° | Cliente | RUT | Vendedor | Neto | Total | Utilidad | Productos |
|---|---|---|---|---|---|---|---|---|---|---|
|
Cargando... |
||||||||||
| Código | Descripción | Cant. | P. Unit. | Subtotal |
|---|
Se perdió el acceso a internet, pero puedes seguir trabajando con los datos descargados en este equipo:
Consejo: antes de salir a terreno, abre la app con wifi y pulsa "⬇️ Actualizar datos" en la bandeja para tener todo al día.
Notas guardadas en este equipo. Al haber conexión se envían al ERP; cada una lleva un identificador único para no duplicarse aunque se reintente.
CODIGO, Code, SKU).Item, Description).Item, Description).| Código ERP | Descripción Inglés | Descripción Español | Stock | Vta/Mes | A Pedir |
|---|---|---|---|---|---|
| Cargando datos… | |||||
| Código | Descripción inglés | Descripción español (ERP) |
|---|