Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' # Genera un DOCX válido (Office Open XML) como ZIP de XMLs. # Uso: # powershell -ExecutionPolicy Bypass -File tools\generate_propuesta_docx.ps1 $baseDir = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path $outFile = Join-Path $baseDir 'Propuesta_ERP_para_cliente.docx' function Escape-Xml([string]$text) { if ($null -eq $text) { return '' } return [System.Security.SecurityElement]::Escape($text) } function W-Paragraph([string]$text, [bool]$Bold = $false, [int]$Size = 22, [int]$After = 120) { $rPr = '' if ($Bold) { $rPr += '' } $rPr += "" $lines = $text -split "\r\n|\r|\n" $runs = New-Object System.Text.StringBuilder for ($i = 0; $i -lt $lines.Length; $i++) { if ($i -gt 0) { [void]$runs.Append('') } $escaped = Escape-Xml $lines[$i] [void]$runs.Append('') [void]$runs.Append($escaped) [void]$runs.Append('') } return "$rPr$($runs.ToString())" } function Section-Title([string]$text) { W-Paragraph -text $text -Bold $true -Size 34 -After 160 } function Subsection-Title([string]$text) { W-Paragraph -text $text -Bold $true -Size 28 -After 120 } function Bullet([string]$text) { W-Paragraph -text ("• " + $text) -Bold $false -Size 22 -After 60 } # Basado en menu.php (módulos visibles y pantallas principales) $modulos = [ordered]@{ 'Dashboard' = @( 'Resumen general y acceso rápido a la operación.' ) 'Facturación' = @( 'Facturas (emisión, consulta y control de ventas).' 'Clientes (registro, actualización y consulta).' 'Reporte de facturas (filtros, exportación e impresión).' ) 'Gastos' = @( 'Registro de gastos (clasificación y control operativo).' 'Reporte de gastos (análisis por periodos y categorías).' ) 'Compras' = @( 'Cotizaciones (solicitud/registro de ofertas de proveedores).' 'Órdenes de compra (aprobación y seguimiento).' 'Compras de mercancías (ingreso y control).' 'Proveedores (catálogo y datos comerciales).' 'Reporte de compras (consulta por fechas/proveedor).' ) 'Inventario' = @( 'Artículos (catálogo, precios, clasificación).' 'Categorías (organización del catálogo).' 'Unidades de medida (configuración y estandarización).' 'Almacenes (control multi-almacén).' 'Movimientos de inventario (entradas/salidas/ajustes).' 'Reporte general de artículos (existencias y listados).' 'Categorías / Cuentas (asignación contable por categoría; solo administrador).' ) 'Clientes y Cuentas por Cobrar (CXC)' = @( 'Cargos a clientes (facturación diferida y documentos por cobrar).' 'Pago de clientes (registro de cobros).' 'Estado de cuenta de clientes (movimientos, saldo y detalle).' 'Notas de crédito (ajustes, devoluciones y descuentos).' 'Reportes de pagos y cargos (control interno y auditoría).' 'Antigüedad de saldos (gestión de mora y cartera).' ) 'Proveedores y Cuentas por Pagar (CXP)' = @( 'Cargos a proveedores (cuentas por pagar y documentos).' 'Pagos a proveedores (control de desembolsos).' 'Estado de cuenta de proveedores (saldos y movimientos).' 'Notas de crédito a proveedores (ajustes y devoluciones).' 'Reportes de pagos y cargos (seguimiento y control).' 'Antigüedad de saldos (planeación de pagos).' ) 'Activos Fijos' = @( 'Registro de activos fijos (altas, bajas, control).' 'Depreciación de activos (cálculo y control).' ) 'Nómina y Recursos Humanos' = @( 'Administración de empleados y procesos de nómina (según configuración).' ) 'Contabilidad' = @( 'Contabilidad general (asientos, integración, reportes financieros).' ) 'Bancos' = @( 'Disponibilidad bancaria (saldos por banco).' 'Cuentas bancarias (registro y control).' 'Movimientos bancarios (entradas/salidas).' 'Conciliación bancaria (comparación vs extractos).' 'Extractos (listado e importación).' 'Importar extracto del banco (carga de movimientos desde archivo).' 'Reporte de conciliación bancaria (evidencias y control).' 'Cheques (emisión y seguimiento).' ) 'Reportes' = @( 'Módulo central de reportes con exportación a Excel e impresión.' ) 'Administración' = @( 'Usuarios (gestión de acceso y roles).' 'Empresa (parámetros por empresa).' 'Configuración (ajustes generales).' 'Impuestos (parametrización de tasas y reglas).' ) } $today = Get-Date -Format 'yyyy-MM-dd' $docParts = New-Object System.Collections.Generic.List[string] $docParts.Add((Section-Title 'Propuesta Comercial – Sistema ERP')) | Out-Null $docParts.Add((W-Paragraph -text ("Fecha: $today") -Size 20 -After 120)) | Out-Null $docParts.Add((W-Paragraph -text 'Este documento describe los módulos y funcionalidades principales del sistema ERP disponible en el directorio /agua. El objetivo es presentar, de forma clara y comercial, el alcance del software para apoyar la decisión de compra.' -Size 22 -After 180)) | Out-Null $docParts.Add((Section-Title '1. Resumen Ejecutivo')) | Out-Null $docParts.Add((W-Paragraph -text 'El ERP integra los procesos críticos de la empresa (ventas, compras, inventario, cartera, proveedores, bancos, contabilidad, activos y RRHH) en una sola plataforma. Esto permite centralizar la información, mejorar el control, reducir errores y acelerar la toma de decisiones mediante reportes y trazabilidad.' -Size 22 -After 180)) | Out-Null $docParts.Add((Section-Title '2. Funcionalidades por Módulo')) | Out-Null foreach ($k in $modulos.Keys) { $docParts.Add((Subsection-Title $k)) | Out-Null foreach ($f in $modulos[$k]) { $docParts.Add((Bullet $f)) | Out-Null } $docParts.Add((W-Paragraph -text '' -After 60)) | Out-Null } $docParts.Add((Section-Title '3. Procesos Clave (Flujos)')) | Out-Null $docParts.Add((Subsection-Title '3.1 Proceso de Facturación y Cobranza')) | Out-Null $docParts.Add((Bullet 'Registro/actualización del cliente y condiciones de crédito.')) | Out-Null $docParts.Add((Bullet 'Emisión de facturas y consulta de documentos.')) | Out-Null $docParts.Add((Bullet 'Gestión de cobros, aplicación de pagos y notas de crédito.')) | Out-Null $docParts.Add((Bullet 'Seguimiento mediante estado de cuenta y antigüedad de saldos.')) | Out-Null $docParts.Add((Subsection-Title '3.2 Proceso de Compras y Pagos')) | Out-Null $docParts.Add((Bullet 'Registro de proveedor y condiciones de pago.')) | Out-Null $docParts.Add((Bullet 'Cotizaciones y generación de órdenes de compra.')) | Out-Null $docParts.Add((Bullet 'Registro de compras y cargos a proveedores.')) | Out-Null $docParts.Add((Bullet 'Programación/registro de pagos y notas de crédito.')) | Out-Null $docParts.Add((Bullet 'Control mediante estado de cuenta y antigüedad de saldos.')) | Out-Null $docParts.Add((Subsection-Title '3.3 Proceso de Inventario')) | Out-Null $docParts.Add((Bullet 'Configuración de artículos, categorías, unidades y almacenes.')) | Out-Null $docParts.Add((Bullet 'Registro de movimientos (entradas, salidas, ajustes).')) | Out-Null $docParts.Add((Bullet 'Consulta de existencias y reportes generales.')) | Out-Null $docParts.Add((Subsection-Title '3.4 Proceso Bancario y Conciliación')) | Out-Null $docParts.Add((Bullet 'Registro de movimientos bancarios y control de cuentas.')) | Out-Null $docParts.Add((Bullet 'Importación y gestión de extractos bancarios.')) | Out-Null $docParts.Add((Bullet 'Conciliación bancaria para validar movimientos.')) | Out-Null $docParts.Add((Bullet 'Soporte de cheques y reportes de conciliación.')) | Out-Null $docParts.Add((Subsection-Title '3.5 Contabilidad y Reportes')) | Out-Null $docParts.Add((Bullet 'Integración contable con módulos operativos (según configuración).')) | Out-Null $docParts.Add((Bullet 'Registro de asientos y generación de reportes financieros.')) | Out-Null $docParts.Add((Bullet 'Exportación a Excel e impresión en reportes para auditoría y control.')) | Out-Null $docParts.Add((Section-Title '4. Beneficios para el Cliente')) | Out-Null $docParts.Add((Bullet 'Visibilidad total: información centralizada por cliente, proveedor, producto y periodo.')) | Out-Null $docParts.Add((Bullet 'Control y trazabilidad: reportes, estados de cuenta y conciliación bancaria.')) | Out-Null $docParts.Add((Bullet 'Productividad: reducción de reprocesos y estandarización de operaciones.')) | Out-Null $docParts.Add((Bullet 'Escalabilidad: crecimiento por módulos y parametrización por empresa.')) | Out-Null $docParts.Add((Section-Title '5. Siguiente Paso')) | Out-Null $docParts.Add((W-Paragraph -text 'Se propone realizar una demostración guiada enfocada en los procesos del cliente (ventas, compras, inventario y contabilidad). Posteriormente, se valida alcance, parametrización inicial y plan de implementación.' -Size 22 -After 200)) | Out-Null $documentXml = @" $($docParts -join "") "@ $contentTypes = @" "@ $rels = @" "@ $docRels = @" "@ $created = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") $core = @" Propuesta Comercial – Sistema ERP ERP ERP $created $created "@ $app = @" ERP "@ $tmpRoot = Join-Path $baseDir 'tools\._tmp_docx_build_ps' if (Test-Path $tmpRoot) { Remove-Item -Recurse -Force $tmpRoot } New-Item -ItemType Directory -Force -Path (Join-Path $tmpRoot '_rels') | Out-Null New-Item -ItemType Directory -Force -Path (Join-Path $tmpRoot 'word\_rels') | Out-Null New-Item -ItemType Directory -Force -Path (Join-Path $tmpRoot 'docProps') | Out-Null # Escribir archivos (UTF-8 sin BOM) $utf8NoBom = New-Object System.Text.UTF8Encoding($false) [System.IO.File]::WriteAllText((Join-Path $tmpRoot '[Content_Types].xml'), $contentTypes, $utf8NoBom) [System.IO.File]::WriteAllText((Join-Path $tmpRoot '_rels\.rels'), $rels, $utf8NoBom) [System.IO.File]::WriteAllText((Join-Path $tmpRoot 'word\document.xml'), $documentXml, $utf8NoBom) [System.IO.File]::WriteAllText((Join-Path $tmpRoot 'word\_rels\document.xml.rels'), $docRels, $utf8NoBom) [System.IO.File]::WriteAllText((Join-Path $tmpRoot 'docProps\core.xml'), $core, $utf8NoBom) [System.IO.File]::WriteAllText((Join-Path $tmpRoot 'docProps\app.xml'), $app, $utf8NoBom) # Crear ZIP (DOCX) Add-Type -AssemblyName System.IO.Compression.FileSystem if (Test-Path $outFile) { Remove-Item -Force $outFile } [System.IO.Compression.ZipFile]::CreateFromDirectory($tmpRoot, $outFile) # Limpieza Remove-Item -Recurse -Force $tmpRoot Write-Host "OK: DOCX generado en: $outFile"