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"