- 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>
- resumenCobranzaGeneral() (solo ROL_COBRANZA; solo lee): una lectura de
Contratos, Esquemas, Pagos, Proyectos y órdenes de compra. Usa
resumenCobranza por proyecto: mismas cifras que la vista de cada proyecto.
- Totales por moneda (nunca MXN + USD), solo de contratos firmados. Los
"Por firmar" se muestran sin sumar; los proyectos cancelados no aparecen.
- Por proyecto: contratado, cobrado, saldo, avance, siguiente etapa, último
pago, costo de órdenes y margen (costosDeOrdenes, compartida con la vista).
- Interfaz: el resumen es la pantalla inicial de Cobranza; filtros, clic
para abrir el proyecto, "← Resumen" y Descargar CSV (UTF-8 con BOM, texto
con = + - @ neutralizado).
- Pruebas: cobranza, compras e interfaz ampliadas; las ocho pasan.
Sin publicar (CLAUDE.md §9).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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>
vistaCobranza_ manda puedeAceptar y puedeFirmar (falsos si el proyecto está
Cancelado o, en el caso de aceptar, si ya está firmado); la interfaz oculta esos
botones y muestra un aviso con cómo reactivarlo. El servidor ya rechazaba ambas
acciones. Pruebas de cobranza e interfaz ampliadas. Publicar la API antes que la
interfaz.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
El libro hereda de la carpeta el acceso del dominio y Drive no deja quitar un permiso
heredado en el hijo (403 cannotDeletePermission). El simulacro de la API de Drive
ahora reproduce la herencia; la raíz de Mi unidad simulada ya no está compartida.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
En helgen.tech DriveApp.setSharing falla con "Access denied: DriveApp." aunque el
script es dueño, con Permission.NONE y con VIEW. privado_() ahora lista los permisos
con la API REST de Drive y borra los de tipo domain/anyone, con el token del script
(sin permisos nuevos). Si no puede, lanza error. Simulacro de la API en las pruebas.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
prepararCobranza() falló en la API real con "Access denied: DriveApp." en setSharing.
Con Access.PRIVATE el permiso se ignora. El simulacro ahora rechaza NONE como Google.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workspace de helgen.tech comparte como lector con todo el dominio lo que se crea:
la carpeta y el libro de cobranza nacieron visibles para cualquier vendedor.
privado_() los deja en Restringido (conserva a tania@ y leo@) y prepararCobranza()
repara los que ya existen. Prueba: el simulacro de Drive comparte lo nuevo con el dominio.
CLAUDE.md: IDs de la carpeta y el libro de cobranza reales.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
En la prueba de punta a punta la fecha del pago se mostraba como
"Tue Oct 20 2026 00:00:00 GMT-0600…": appendRow convierte "AAAA-MM-DD" en fecha
aunque la columna tenga formato de texto. Ahora fecha_pago y fecha_firma se
escriben con apóstrofo (texto, sin depender de la zona horaria de la hoja) y al
leer se normalizan las filas ya guardadas como fecha. Firmar y desbloquear ya no
reescriben aceptada_por / fecha_aceptacion. La prueba simula ese comportamiento
de Sheets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Esquema de Helgen Energy: solo ADMIN_DESBLOQUEO lo edita (antes de firmar),
con motivo obligatorio que queda en la Bitacora junto con el esquema anterior.
Al cambiar entre cotizaciones de Energy se conserva el esquema; al pasar de
Helgen a Energy se pone el 60/30/10 (con confirmación si reemplaza otro).
- PDF en USD: columnas "P. Unitario (USD)" e "Importe (USD)"; en MXN sin cambios.
- Prueba de que la cotización USD imprime el mismo bloque de términos que MXN.
- Pruebas de cobranza e interfaz ampliadas; CLAUDE.md actualizado.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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>