Commit Graph

11 Commits

Author SHA1 Message Date
Efrain (Helgen)
d56dd38e02 Carga rápida, sincronización sin recargar, requisiciones en cualquier proyecto y clave de proyecto
- bootstrap(): una sola llamada al entrar con roles y listas según el rol; las pestañas se dibujan
  al instante con los roles de la última sesión (localStorage, solo interfaz). getDatosIniciales
  queda como alias.
- CacheService por versión de colección (proyectos, contratos, cotizaciones, catálogo,
  requisiciones, oc, pagosCobranza, pagosProveedores): doPost sube la versión tras cada escritura
  (con candado); las hojas que se editan a mano se revisan por huella cada pocos minutos desde
  la consulta de fondo. Memoria por petición para propiedades y cachés.
- sincronizar(versiones, contexto): devuelve solo lo que cambió y respeta roles; la interfaz
  consulta cada 20 s con la pestaña visible, al cambiar de pestaña y al abrir un buscador de
  proyectos; si alguien está capturando, avisa en vez de repintar. Los cambios de rol se aplican
  sin recargar.
- Requisiciones, OC y pago a proveedores en proyectos Activos y Cerrados con o sin contrato
  (moneda de la aceptada o MXN); Cancelados no. Cobranza sin aceptada muestra costo de OC y
  "Sin contrato". Pagos de clientes siguen exigiendo contrato firmado.
- Clave de proyecto (columna L): folio visible PRY-AAAA-NNNN-XXX, sugerida con el nombre y
  editable al crear; la llave interna sigue siendo PRY-AAAA-NNNN. asignarClavesProyectos()
  (vista previa) y asignarClavesProyectosAplicar() asignan clave a los existentes y renombran
  su carpeta principal. Buscadores por clave.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 13:47:04 -06:00
Efrain (Helgen)
fdb273793f Compras: requisiciones de materiales y pago a proveedores
- Requisiciones (ROL_REQUISICION): el trabajador pide materiales sin precios para un proyecto
  activo con contrato firmado, adjunta la cotización del proveedor (PDF/JPG/PNG/HEIC, 10 MB) y
  solo ve las suyas (el servidor filtra por el correo del token), sin montos, cliente, OC ni pagos.
- SOLO_REQUISICION: cuentas que solo ven la pestaña Requisiciones; doPost les niega lo demás.
- Estados: Solicitada → Autorizada (genera la OC) → Pagada → Cerrada; Rechazada, Devuelta
  (corregir y reenviar con el mismo folio) y Cancelada. Historial visible para el solicitante.
- Toda OC sale de una requisición autorizada: se quitan la emisión directa y el botón "Recibida".
  La OC guarda req_folio y su PDF lleva "Requisición: REQ-…". Cancelar la OC regresa la
  requisición a Solicitada.
- Pago a proveedor (PGP-AAAA-NNNN, hoja PagosProveedores en el libro de Compras): comprobante
  obligatorio, monto = total de la OC ±1.00, tipo de cambio si es otra moneda. OC y requisición
  a Pagada; cancelar el pago las regresa (no si ya está cerrada). Una OC pagada no se cancela.
- Cierre: "Recibí el material" (solicitante) o compras con motivo; la OC queda Recibida.
- Pruebas: tests/requisiciones.test.js nueva; compras, interfaz, cobranza y sesión actualizadas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 11:56:20 -06:00
Efrain (Helgen)
1a02e2df3f Compras: órdenes de compra por proyecto, proveedores y margen (fase 3)
- Rol nuevo ROL_COMPRAS (Script Properties): solo ese rol crea, ve, recibe y
  cancela órdenes; el servidor lo revisa en cada llamada y los demás reciben
  codigo PERMISO. getDatosIniciales agrega permisos.compras.
- Órdenes OC-AAAA-NNNN con el mismo candado e idempotencia, solo en proyectos
  Activos con contrato firmado. Estados Emitida / Recibida / Cancelada (con
  motivo; nunca se borran). La línea de negocio sale del contrato.
- Libro y carpeta "Cotizador Helgen — Compras" aparte y restringidos con
  privado_(): ni en la Base de datos ni en la carpeta del proyecto ni en
  cobranza. Pestañas OrdenesCompra, Proveedores (se llena sola) y Bitacora.
- PDF de la orden siempre con la razón social de Helgen y los términos
  TERMINOS_OC (se agregan solos a Config). Sin tipo de cambio ni línea.
- Costo siempre capturado, nunca el precio de venta. Orden en otra moneda que
  el proyecto: tipo de cambio obligatorio y costo convertido.
- Margen (contratado sin IVA − órdenes vigentes sin IVA) solo en la vista de
  cobranza; preparado para sumar nómina y horas. Con órdenes vigentes la
  aceptada no puede cambiar de moneda.
- Cobranza y compras comparten la mecánica de área privada (carpetaArea_,
  libroArea_, enRol_). Los proyectos nuevos ya no crean "Órdenes de compra".
- Interfaz: pestaña Compras y tarjeta de margen en Cobranza.
- Pruebas: tests/compras.test.js nuevo; interfaz, cobranza, sesión, proyectos
  y cotización actualizadas (oc.html de ejemplo). Las ocho pasan.

Sin publicar: falta respaldo, prueba en PRUEBAS, clasp y wrangler (CLAUDE.md §9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:49:07 -06:00
Efrain (Helgen)
decddbb973 Cotizaciones: columna V con el tipo de cambio usado en cotizaciones USD
La interfaz manda el tipo de cambio con que convirtió los precios del catálogo;
el servidor lo valida (1–1000, 4 decimales) y lo guarda solo en cotizaciones en
USD. En MXN, en filas viejas o con precios capturados sin tipo de cambio queda
vacía. El encabezado se agrega solo (patrón de ENCABEZADOS_COTIZACIONES).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:11:56 -06:00
Efrain (Helgen)
745c9e3a66 Fase 2: cobranza por proyecto y cotizaciones en USD
- Cobranza en un libro y una carpeta aparte ("Cotizador Helgen — Cobranza"),
  fuera de la carpeta maestra, porque la Base de datos la lee todo el dominio.
- Cotización aceptada (una por proyecto; línea y moneda salen de ella),
  esquema de pagos (Energy fijo 60/30/10; Helgen editable, suma 100%),
  contrato firmado que bloquea todo, desbloqueo solo del administrador con
  motivo, pagos PAG-AAAA-NNNN con comprobante obligatorio (PDF/imagen,
  revisado por contenido), excedente a la siguiente etapa, tolerancia de 1.00,
  tipo de cambio cuando la moneda del pago es otra, cancelación con motivo y
  bitácora.
- Permisos en el servidor: ROL_COBRANZA y ADMIN_DESBLOQUEO en Script
  Properties; sin rol, codigo PERMISO y ningún dato de cobranza.
- Un proyecto con contrato firmado no admite cotizaciones nuevas y sale del
  buscador de cotizaciones.
- Cotizaciones en MXN o USD (columna U, PDF e importe con letra en dólares);
  en USD el catálogo no pone el precio.
- Proyectos nuevos sin subcarpeta "Pagos".
- Pruebas: nueva cobranza.test.js; interfaz, cotización, sesión y proyectos
  ampliadas. CLAUDE.md actualizado (§4.5.2, §5, §6.10, §6.11, regla 12, §9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 14:54:23 -06:00
Efrain (Helgen)
18e305a36f Revert "Historial: nombre del vendedor desde el directorio de Google de helgen.tech"
Se decidió no publicar la búsqueda en el directorio (servicio People): el nombre de un vendedor viejo
(p. ej. leo@helgen.tech) se corrige solo cuando guarde una cotización con sesión. appsscript.json vuelve a
quedar sin servicios avanzados y Code.js igual a lo publicado en @5. Nunca se hizo clasp push de c6c4b93.

This reverts commit c6c4b93.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 13:45:30 -06:00
Efrain (Helgen)
c6c4b93da3 Historial: nombre del vendedor desde el directorio de Google de helgen.tech
Las cotizaciones de vendedores que nunca guardaron con sesión (p. ej. leo@helgen.tech) seguían mostrando el
correo. Ahora, para correos @helgen.tech sin nombre en la hoja, listarCotizaciones busca el nombre y apellido
en el directorio de la organización (servicio avanzado People, searchDirectoryPeople con perfiles del
dominio), solo acepta la persona con el correo exacto y guarda el resultado 6 h en caché. Si el directorio
falla o no hay permiso, se muestra el correo como antes. No escribe en la hoja.

probarDirectorio() autoriza el permiso desde el editor. Pruebas en sesion.test.js. CLAUDE.md §3, §4.4,
§4.6 y §6.8 (orden: push, autorizar, deploy).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 13:34:27 -06:00
Efrain (Helgen)
3c410b46ad Historial: nombre del vendedor también en cotizaciones viejas
Las filas anteriores a la sesión con Google no tienen vendedor_nombre/apellido y mostraban el correo.
listarCotizaciones ahora arma un mapa correo → "Nombre Apellido" con las filas que sí lo tienen
(nombresDeVendedores, gana la más reciente) y lo usa para las viejas (vendedorDeFila); si el correo no
se conoce, sigue mostrando el correo. Solo cambia la respuesta: la hoja no se modifica.

Pruebas en sesion.test.js. CLAUDE.md: §4.4, §4.6 y registros de prueba en la hoja real
(HLG-2026-0005, HLG-2026-0006, PRY-2026-0001) para excluirlos de reportes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 12:58:24 -06:00
Efrain (Helgen)
c04f878168 Proyecto rechazado al guardar: la interfaz limpia el campo y refresca la lista
Si el servidor rechaza la cotización porque el proyecto se canceló, se cerró o no existe, la etiqueta seguía
diciendo "Proyecto activo". Ahora el error lleva codigo PROYECTO (errorProyecto_ en Code.js, doPost lo
pasa a la respuesta, la capa api-web lo pone en err.codigo) y errorAlGuardar limpia el campo Proyecto,
refresca la lista de proyectos y muestra el aviso. Otros errores no tocan el campo.

Pruebas: tests/interfaz.test.js (nueva: DOM y fetch simulados), codigo PROYECTO en proyectos.test.js y
sesion.test.js. CLAUDE.md §8 y §10.2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 12:29:56 -06:00
Efrain (Helgen)
aae01d6918 Proyectos: folio PRY-AAAA-NNNN, carpeta en Drive y cotizaciones ligadas por proyecto_folio
- Pestaña "Proyectos" (se crea sola) con cliente_id (RFC o SIN-RFC:nombre|empresa), estado con lista
  desplegable y vendedor del token. Folio con contador propio CONSECUTIVO_PROY_AAAA bajo el mismo candado.
- Carpeta Cotizador Helgen/Proyectos/AAAA/<folio> — <cliente> — <nombre>/ con Cotizaciones,
  Órdenes de compra y Pagos; las subcarpetas borradas o renombradas se vuelven a crear.
- Cotizaciones: columna T proyecto_folio (las viejas quedan vacías = "Sin proyecto"); con proyecto, el PDF
  va a su carpeta Cotizaciones. Proyecto inexistente o no Activo se rechaza sin gastar folio.
- Interfaz: campo Proyecto opcional con buscador y "Nuevo proyecto" en el módulo 1; columna en Historial.
- Pruebas: tests/proyectos.test.js (Drive simulado con árbol de carpetas) y sesion.test.js ampliada.
- CLAUDE.md: §6.9 Proyectos y §6.10 modelo futuro (OC, Pagos, Gastos, cotización "Aceptada").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 10:59:37 -06:00
Efrain (Helgen)
bbb34768b4 Respaldo inicial del Cotizador Helgen (19/10/2026)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:14:08 -06:00