Compare commits

..
241 Commits
Author SHA1 Message Date
jpegueroandClaude Sonnet 5.5 83fffcd31f ccprmt002: no crear un segundo contador PG por vendedor (rompia ccprmt001)
ccprmt001/003/005 leen cctb00003 por tipo_doc esperando una sola fila. En SQL
Server un SELECT INTO que devuelve varias filas da -284 (en Informix tomaba la
primera). Al dar de alta un rango, ccprmt002 insertaba una fila PG por vendedor
y, con ella, nadie podia registrar recibos. Ahora solo crea la fila si no existe
ninguna PG.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 17:10:29 -04:00
jpegueroandClaude Sonnet 5.5 1e64839bf2 veprmt025: Nuevo abre un grupo vacio y los botones Activar/Desactivar se ven
- El bloque AFTER DISPLAY de la lista recargaba el grupo seleccionado (y sus
  clientes) al pulsar Nuevo; ahora solo lo hace si operacion <> "N".
- vefmwd022.4fd: los botones Desactivar y Activar solo tenian icono y quedaban
  invisibles cuando el icono no carga; se les agrega texto.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 16:08:43 -04:00
jpegueroandClaude Sonnet 5.5 539af7f912 CxC: ccprrp018/003/001 con reporte Genero, ccprrp052 y ccprmt002 corregidos
- ccprrp018: agrega MAIN, GROUP BY por nombre, y reemplaza la salida Excel/DDE
  (G:\ESTADO.XLS, DEL G:\ESTADOS) por un reporte Genero (ccprrp018.4rp); carga con
  un solo INSERT...SELECT en tabla temporal.
- ccprrp003: reemplaza el REPORT de texto con codigos de impresora por
  ccprrp003.4rp; agrega por cliente en una consulta (DATEDIFF, mismas reglas).
- ccprrp001: agrega MAIN, GROUP BY por nombre, reporte Genero (ccprrp001.4rp) y
  registra el formulario ccfmrp001 en FORMULARIOS_CC (faltaba, -1110).
- ccprrp052: la validacion del campo Orden estaba al reves.
- ccprmt002: cctb00002.fecha es datetime en SQL Server; el formulario, la variable
  global relacion (ccprgb000) y el CONSTRUCT la manejan como DATE; corrige que
  eLiminar mostrara exito sin actualizar filas.
- mbsERP.4pw: registra los .4rp, libgre y ccfmrp001 (sin credenciales).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 15:23:22 -04:00
Abel López b52ccfae7f Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-27 16:07:27 -04:00
jpegueroandClaude Sonnet 5.5 b09ba2374f prprmt003.4rp: separa los titulos cantidad y medida
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 15:38:57 -04:00
jpegueroandClaude Sonnet 5.5 7f069af336 prprmt003: combo Equipo mas ancho (se cortaba el texto) y el reporte ahora imprime la Cantidad
- prfmmt003pr.4fd: Equipo 30 -> 48 columnas y las columnas siguientes se corren 18.
- prprmt003.4rp: hoja horizontal y nueva columna cantidad entre espesor y medida
  (el cambio de cantidad al modificar un documento no se veia al imprimir).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 15:33:59 -04:00
jpegueroandClaude Sonnet 5.5 c6bcf1b743 gitignore: quita la regla de bin duplicada (ya la agrego Abel)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 13:14:25 -04:00
jpeguero 1829bd1bc7 Merge origin/main (cambios de Abel) en main local 2026-10-27 13:14:06 -04:00
jpegueroandClaude Sonnet 5.5 16bff226c5 alprmt006 (Reporte de Entrada): conexion explicita, SCHEMA, contador por bodega, CURRENT/USER de SQL Server e INSERT con columnas
- DATABASE -> SCHEMA y CONNECT TO smarmotech con usuario/clave (args 1 y 2).
- iptb00007 (contador) es por movimiento y bodega: consulta, update e insert lo usan.
- Verificacion de documento duplicado en iptb00006 considera la bodega.
- user,current (Informix) -> SUSER_SNAME(),getdate().
- INSERT INTO iptb00006 con lista explicita de columnas (la tabla ya tiene 50).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 12:35:51 -04:00
jpegueroandClaude Sonnet 5.5 91a1a4ef96 alprmt006: registra la aplicacion (otrodir/alprmt006.4gl y alfmmt006.per) en el grupo Reportes de Entradas
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 12:17:27 -04:00
jpegueroandClaude Sonnet 5.5 931a814278 prprmt008: registra FUNCIONESREPORT (defecto/seleccionarsalida), libgre y los formularios prfmwd003/prfmwd004
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 12:10:56 -04:00
Abel LópezandClaude Opus 5.5 5b53d994ac noprrp009: salida con cuadro de formato y conteo por movimiento
- La salida pasa del archivo de texto en FGLSPOOL a
  seleccionarsalida()/configureoutput() (Excel/PDF/pantalla); antes se
  dejo en texto porque configureOutput() era un stub que devolvia NULL.
- RIGHT MARGIN 86 (el reporte usa hasta la columna 84).
- NO. REGISTROS se reinicia en cada codigo de movimiento (se acumulaba).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 11:48:43 -04:00
Abel LópezandClaude Opus 5.5 05d5adf8c9 noprrp008: desbloqueado, registrado en el proyecto y con cuadro de formato
- mbsERP.4pw: se registra noprrp008 (Volantes de Nomina) en NOMINA. El
  build ya pasa con la JVM configurada en el grupo COMUNES.
- noprrp008.4gl: seleccionarSalida() en lugar del 'SVG' fijo; el usuario
  elige Excel/PDF/pantalla (modo IMPRESORA y la parte impresa de EMAIL).
- noprrp008.4rp: formato del acumulado ###,###,###.## (con #,###,###.##
  los montos de 10 millones o mas salian como 2.64775E7).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 10:59:44 -04:00
Abel LópezandClaude Opus 5.5 a8c4ab1f78 coprmt025: desbloqueado (JVM en COMUNES, formulario .4fd e impresion)
- mbsERP.4pw: el grupo COMUNES (libreria FUNCIONESEMAIL, que usa
  IMPORT JAVA javax.mail) recibe FGLJVMPATH/JAVA_HOME/PATH como el grupo
  MODULOS; sin eso el build fallaba con -8301 "Can not create java VM".
- mbsERP.4pw: se registra codir/cofmmt025.4fd en lugar del .per (el .per
  no tiene el combo formonly.depto: error -8083 al consultar).
- coprmt025.4gl: la impresion vuelve a configureoutput(salida) como en
  3.20 (escribia un XML suelto en FGLSPOOL); el boton imprimir muestra el
  cuadro de formato (PDF si se cancela).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 10:41:30 -04:00
Abel López 6a72dad748 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-26 16:44:23 -04:00
Abel LópezandClaude Opus 5.5 afc4fd5f04 cpprrp001: exportacion a PDF/Excel con el cuadro de formato
- defecto()/START REPORT TO archivo reemplazado por
  seleccionarsalida()/configureoutput() (salida XML HANDLER).
- Se quita RUN imprime (era para la impresora matricial).
- Codigos de impresora en NULL (salian como basura en PDF/Excel).
- RIGHT MARGIN 138 para que no se recorten las columnas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:43:22 -04:00
Abel LópezandClaude Opus 5.5 4762e8c10d coprrp007: exportacion a Excel/PDF con el cuadro de formato
- La salida escribia un XML directo en FGLSPOOL; se vuelve a
  seleccionarsalida()/configureoutput() como en la version 3.20.
- RIGHT MARGIN 148 para que no se recorten las columnas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:42:33 -04:00
jpegueroandClaude Sonnet 5.5 c744b6fd61 prprmt003: imprimir fallaba (-1260): el arreglo del reporte no tenia el campo num_oc
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 16:36:53 -04:00
jpegueroandClaude Sonnet 5.5 282c4ce7fa prprmt003: usa su propio formulario prfmmt003pr (el prfmmt003 de ctdir no tiene el screen record s_docs)
El formulario viejo de ctdir lo sigue usando ctprmt029; prprmt003 usa una copia del .4fd
nuevo de PRDIR con otro nombre para que no choquen en bin.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 16:33:34 -04:00
jpeguero 313482be68 Limpieza: PROYECTO/bin fuera del repo, excepto los .4rp (indicacion de Johnny Soto) 2026-10-26 16:27:22 -04:00
jpeguero ff2a3df470 Merge origin/main en main local 2026-10-26 16:27:21 -04:00
jpegueroandClaude Sonnet 5.5 48192eb211 prprmt003: usa PRDIR/prprmt003.4gl (version completa) y registra sus modulos y formularios
El proyecto apuntaba a ctdir/prprmt003.4gl (631 lineas, version vieja). Se cambia a
PRDIR (2398 lineas) y se agregan prtraza, coperacion, cturno, prod_report,
prverificar, los formularios prfmordenped/pendientes/prfmwd010/prfmwd011, la
dependencia FUNCIONES_IR (maquinas) y libgre.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 16:27:07 -04:00
jpegueroandClaude Sonnet 5.5 f8e97fd09e ipprmt021: consulta el nombre del usuario una sola vez por usuario (antes una consulta por fila)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 15:56:18 -04:00
Abel LópezandClaude Opus 5.5 316496520b coprrp019: exportacion a PDF/Excel sin codigos de impresora
- Codigos de impresora matricial en NULL (salian como basura en PDF/Excel).
- PRINT antes de la raya de cierre: la ultima linea de detalle termina en ";"
  y la raya se pegaba a ella, saliendose de la pagina.
- nom_pt CLIPPED para que Flete/Gastos queden en sus columnas.
- RIGHT MARGIN 165 (el reporte usa hasta la columna 163).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:37:23 -04:00
Abel LópezandClaude Opus 5.5 f48618a23c coprrp004 (Cronologico de Ordenes): exportacion a PDF/Excel/pantalla
- La salida escribia un XML crudo en FGLSPOOL (no era PDF ni Excel); vuelve
  a configureOutput() (modo compatibilidad de GRE, como en 3.20) con la
  ventana comun seleccionarsalida() (EXCEL / PDF / SCREEN).
- Se quitan dos ESC P (ASCII 27, ASCII 80) de impresora matricial que el
  reporte imprimia directo y salian como basura en PDF/Excel.
Verificado contra la BD .250 (tipo 01, 01/08/2026 al 15/08/2026): PDF y Excel
generados; 4 ordenes, monto = productos + flete + otros gastos, total
1,515,154.88 = SQL. Build OK con gsmake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 11:36:31 -04:00
Abel LópezandClaude Opus 5.5 1d6a2556e5 coprrp001 (Catalogo de Suplidores): exportacion a PDF/Excel/pantalla
- La salida escribia un XML crudo en FGLSPOOL (no era PDF ni Excel); se
  restaura el codigo de 3.20: ventana seleccionarSalida() (EXCEL / PDF /
  SCREEN) con el diseno bin/coprrp001.4rp (fgl_report_loadCurrentSettings).
Verificado contra la BD .250 (22-1 a 22-10, orden numerico): PDF y Excel
generados; 9 suplidores = SQL (22-7 anulado). Build OK con gsmake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 11:31:33 -04:00
LuisandClaude Opus 5.5 465205efc6 Pruebas migracion 6.0: correo de prueba, PDF y esquema DECIMAL(38)
- otrodir/enviacorreo.4gl: TRY/CATCH al ejecutar el procedimiento de correo
  (si falla avisa y no se pierde la grabacion; antes una cotizacion con
  reserva se perdia completa) y desvio opcional MBS_CORREO_PRUEBA para
  ambientes de prueba (en produccion no existe la variable).
- ccprmt001, ccprmt003, ccprrp049, ccprrp054: salida SVG fija -> PDF.
- bin/ccprrp054.4rp: era de otro reporte (reporte54); se usa el de
  ccprrp049 (mismo REPORT r_email).
- *.sch: columnas DECIMAL/MONEY con precision > 32 (vistas como
  ventas_facturas, analisiscotizaciones, rotacioniventario) bajadas a 32
  con la misma escala; Genero daba -6634 y no compilaban veprrp058/059/060.
- mbsERP.4pw: agregado vefmrp060.4fd a FORMULARIOS_VE (-1110).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 10:54:27 -04:00
Abel LópezandClaude Opus 5.5 5841de1da3 Repo: PROYECTO/bin deja de versionarse, salvo los disenos .4rp
- .gitignore: se ignora todo PROYECTO/bin (compilados, imagenes, estilos,
  xml/js de ejecucion, ejecutables, certificados) excepto *.4rp, que son
  fuentes registradas en mbsERP.4pw. Reemplaza las reglas anteriores de
  bin/IMAGENES y bin/*.TXT.
- Se quitan del repositorio (git rm --cached) los 459 archivos de bin que no
  son .4rp; siguen en el disco de cada PC. Se conservan los 205 .4rp.
Nota: bin/cert/*.pem quedan en el historial de git; si son llaves reales
deben cambiarse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 09:58:12 -04:00
jpegueroandClaude Sonnet 5.5 f6f1c9b8c7 ipprmt021: limita la busqueda a las 500 requisiciones mas recientes (CERRADA traia 35,812 y fallaba con -1326)
Ordena por fecha desc y avisa al usuario cuando hay mas para que use los filtros.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 16:04:57 -04:00
jpegueroandClaude Sonnet 5.5 4a8d31d9d0 ipprmt020: aviso de item repetido a prueba de valores nulos (el texto salia en blanco)
Arma el mensaje por partes, omitiendo las vacias, y usa ASCII 10 para los saltos.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 17:01:47 -04:00
jpegueroandClaude Sonnet 5.5 6dac9550c1 ipprmt020: avisa del item repetido al escribirlo/buscarlo (al dar Tab) y aviso mas compacto
Si el item ya esta en otra linea, muestra un aviso corto, limpia la fila y
regresa a Clase. Se mantiene el chequeo al guardar como respaldo.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 16:51:42 -04:00
jpegueroandClaude Sonnet 5.5 75d81bdfc7 ipprmt020: no permite repetir un item en la requisicion y arregla la fecha del reporte
- Guardar: si un item (clase/grupo/tipo/medida) aparece en mas de una linea,
  aunque cambie el area, muestra error y no guarda (antes solo avisaba y solo
  si coincidia el area). Evita que el impreso muestre solo la primera linea.
- Reporte: la fecha/hora sale como dd/mm/yyyy hh:mm y el titulo deja espacio
  para que no se corte en el encabezado.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 16:44:46 -04:00
jpegueroandClaude Sonnet 5.5 b5bf9e2b26 ipprmt020: avisa (sin bloquear) cuando un item se repite en el detalle al guardar
Nueva funcion itemRepetido(): misma area, clase, grupo, tipo y medida entre las
lineas con cantidad. Si hay repetido pregunta si desea continuar; NO vuelve a
la edicion (CONTINUE DIALOG), YES guarda como antes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 16:04:21 -04:00
jpegueroandClaude Sonnet 5.5 fa54d93651 PROYECTO/bin fuera del repo, excepto los .4rp (indicacion de Johnny Soto)
- .gitignore: PROYECTO/bin/** ignorado salvo *.4rp (incluye subcarpetas).
- Se sacan del indice 459 archivos de bin (cert/*.pem, filesXML, fotos,
  node_modules, estilos, etc.) con git rm --cached; siguen en cada PC.
- Se conservan los 205 disenos de reporte .4rp.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 14:43:06 -04:00
Abel López 4bfaea0a47 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-21 16:58:41 -04:00
jpegueroandClaude Sonnet 5.5 96c461d4b6 prprmt020: la orden se guardaba en prtb09.num_oc pero se consultaba prtb08.num_oc (REGISTRO NO EXISTE siempre)
INPUT BY NAME y el SELECT INTO ahora usan prtb08, igual que el resto del programa.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 16:43:18 -04:00
Abel LópezandClaude Opus 5.5 3422acc241 cpprrp017 (Validacion de Facturas): exportacion a PDF/Excel y filtro que se cortaba
- La salida escribia un .txt en FGLSPOOL (no era PDF ni Excel); vuelve a
  configureOutput() con la ventana comun seleccionarsalida() (EXCEL / PDF /
  SCREEN), RIGHT MARGIN 142 y sin codigos de impresora matricial.
- BUG de la migracion: la consulta se armaba en selec CHAR(500); al cambiar
  rowid por ROW_NUMBER() el texto fijo paso a 463 caracteres y cualquier
  filtro de factura+suplidor o de fechas se cortaba (-4145). Ahora se arma
  en un STRING local.
Verificado contra la BD .250: factura 068-1AK05 de 22-770 (Debe = Haber =
1,253,019.91) y grupo 22 del 01/08/2026 al 15/08/2026 (4 facturas, total
3,834,979.72) cuadran con SQL; PDF y Excel generados. Build OK con gsmake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 16:07:13 -04:00
jpegueroandClaude Sonnet 5.5 a226f65b00 ipprmt064: registra el formulario ipfmwd003.4fd (faltaba en el proyecto, error -1110/-8083 con combo almacen)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 12:50:19 -04:00
Abel LópezandClaude Opus 5.5 65ad3fd68c cpprrp011 (Validacion Cuentas Afectadas en Facturacion): exportacion a PDF/Excel/pantalla
- La salida escribia un XML crudo en FGLSPOOL (no era PDF ni Excel); vuelve
  a configureOutput() (modo compatibilidad de GRE, como en 3.20) con la
  ventana comun seleccionarsalida() (EXCEL / PDF / SCREEN).
- RIGHT MARGIN 142: la linea llega a la columna 139 y con el ancho por
  defecto (132) se cortaba.
Verificado contra la BD .250 (grupo 22, 01/08/2026 al 15/08/2026, Afectar
Mayor = N): PDF y Excel generados; 4 facturas, valor 62,868.52, Debe = Haber
= 3,834,979.72 y totales por cuenta cuadran con SQL. Build OK con gsmake.
No probado: Afectar Mayor = S (graba en cgtb00004).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:43:25 -04:00
jpegueroandClaude Sonnet 5.5 2d3d2c4fbc ipprrp010: centra el titulo y lo separa del encabezado del grupo
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 12:35:35 -04:00
Abel LópezandClaude Opus 5.5 8ced6a5498 cpprrp004 (Estado de Cuenta): exportacion a PDF/Excel/pantalla
- La salida escribia un XML crudo en FGLSPOOL (no era PDF ni Excel); vuelve
  a configureOutput() (modo compatibilidad de GRE, como en 3.20) con la
  ventana comun seleccionarsalida() (EXCEL / PDF / SCREEN).
- Se quita defecto(): solo cargaba codigos de impresora matricial que, si
  el menu pasa una impresora, salian como basura en PDF/Excel.
Verificado contra la BD .250 (22-770, 01/08/2026 al 15/08/2026): PDF y Excel
generados; documentos y creditos (38,910.46) cuadran con SQL. Build OK con
gsmake. Sin cambios (igual que 3.20): 'Balance Al' sale .00 porque usa
cptb00001.tipo_doc_cp, vacia en todas las filas; hoja final vacia.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:34:10 -04:00
jpegueroandClaude Sonnet 5.5 bf73616f5c ipprrp010: corrige diseno del .4rp (filas length=max, columnas mas anchas, hoja horizontal)
El reporte se veia con los campos apilados y encimados: las filas
estaban declaradas con length=12 en vez de max y las columnas eran
demasiado angostas.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 12:29:06 -04:00
jpegueroandClaude Sonnet 5.5 dead250cf9 ipprmt002: el combo Grupo No. 1 se llenaba con el cursor equivocado (Bienes/Servicio)
grupo_producto() declaraba bgrupos (iptb00071) pero recorria btipoproductos.
Ahora recorre bgrupos y usa el nombre del grupo como valor, que es lo que
guarda iptb00002.grupo1 (CORALINA, TRAVERTINO, CARIBBEAN BLOND, PORTORRO).
Verificado en la .250: alta del producto 209-1819-9-391 con grupo1=TRAVERTINO.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 10:28:19 -04:00
Abel LópezandClaude Opus 5.5 c8743d85c8 cpprrp003 (Mayor Auxiliar): exportacion a PDF/Excel/pantalla
- La salida escribia un XML crudo en FGLSPOOL (no era PDF ni Excel); vuelve
  a configureOutput() (modo compatibilidad de GRE, como en 3.20) con la
  ventana comun seleccionarsalida() (EXCEL / PDF / SCREEN).
- Se dejan vacios los codigos de impresora matricial (ASCII 14/15/20,
  ESC E/F/M/P) del encabezado, que salian como basura en PDF/Excel.
Verificado contra la BD .250 (grupo 22, del 01/08/2026 al 15/08/2026):
PDF, Excel y pantalla generados; balance inicial, debitos, creditos, balance
y total general (credito 62,868.52, balance 105,394.28) cuadran con SQL.
Build OK con gsmake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 10:00:54 -04:00
jpegueroandClaude Sonnet 5.5 4059dc92e6 ipprmt002: recalcula nombre_representante antes de grabar (Escoger lo dejaba en blanco)
En la pantalla nueva se puede aceptar con OK sin pasar por el campo num_emp, y
nombre_representante solo se calculaba en AFTER FIELD num_emp. Al modificar un
producto, el UPDATE lo grababa vacio. Se recalcula antes de los 5 INSERT/UPDATE
de iptb00002. Verificado en la .250: tras Escoger+OK sin cambios solo cambian
us_mod y fech_mod.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 09:40:43 -04:00
jpegueroandClaude Sonnet 5.5 ef6980358e ipprmt002: registra ipfmmt002 e ipfmwd006
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 09:31:27 -04:00
jpegueroandClaude Sonnet 5.5 5e5da7a926 ipprmt002: compila y enlaza (esquema de ipdir con iptb00002 de 49 columnas, funciones faltantes)
- ipdir/smarmotech.sch: copia del esquema raiz con solo iptb00002 actualizada a
  las 49 columnas reales (grupo2, bookmatch, tipos, tipo_material, imp_aduanal,
  categoria, es_produccion). Verificado: los 33 programas ip* que compilaban
  siguen compilando.
- otrodir/gerentesmarcas.4gl copiado de PROYECTOS; categoria_conteo registrada;
  busca_departamento local en ipprmt002 (irdepartamento esta en FUNCIONES_IR).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 09:12:09 -04:00
jpegueroandClaude Sonnet 5.5 7dfed7798c Repara mbsERP.4pw: resuelve conflicto sin resolver del commit 93a4eb4
El merge 93a4eb4 subio el .4pw con marcadores de conflicto (ambas versiones
pegadas). Se rehizo el merge de 16ef058 y 9bc9170 normalizando los saltos de
linea (16ef058 estaba en LF, el resto en CRLF). Resultado: XML valido, 233
aplicaciones sin duplicados, conserva registros de ipprmt044/045 y los de
adprmt001/017/027 y cpprrp002.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 08:37:05 -04:00
Luis 93a4eb40f5 lsoto prueba de programas 2026-10-20 21:53:39 -04:00
Luis 16ef05828e lsoto prueba de programas 2026-10-20 21:52:20 -04:00
Abel López 9bc9170788 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-20 17:05:47 -04:00
jpegueroandClaude Sonnet 5.5 9e4b66497c Merge origin/main en main local (ipprmt044, lqprrp009)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 17:05:19 -04:00
Abel López 7aa4734658 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-20 17:03:29 -04:00
Abel LópezandClaude Opus 5.5 3bb4b58216 cpprrp002 (Saldos por Antiguedad): exportacion a PDF/Excel/pantalla
- Vuelve a configureOutput() (modo compatibilidad de GRE, como en 3.20) en
  lugar del XML crudo en FGLSPOOL, que no era ni PDF ni Excel.
- El formato se elige en la ventana comun seleccionarsalida() (EXCEL / PDF /
  SCREEN); se quita del formulario cpfmrp002 el grupo 'Opciones Salidas',
  al que no se llegaba con Enter. La opcion MATRICIAL deja de ofrecerse.
- RIGHT MARGIN 145: la linea llega a la columna 143 y con el ancho por
  defecto (132) la columna Total salia cortada.
Verificado contra la BD .250 (grupo 25, corte 20/10/2026): PDF de 12 paginas
con totales completos. Excel generado en prueba local; falta confirmarlo en
el GDC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:02:56 -04:00
jsoto 073c284449 Merge remote-tracking branch 'origin/main' 2026-10-20 16:05:23 -04:00
jpegueroandClaude Sonnet 5.5 0c3e16d08c ipprmt044: registra ipfmmt045, ipfmwd012/013/013a y vefmwd100 en FUNCIONES_IP
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 16:05:00 -04:00
jsotoandClaude Opus 5.5 9eb74bbea7 JSOTO veconvierteorden/ccprmt003: evita ordenes duplicadas por cotizacion
Dos usuarios convirtiendo la misma cotizacion a la vez creaban dos ordenes
(cot 340001 -> 262237 y 262238, ticket 12234). La validacion "cotizacion
tiene orden" corria antes del BEGIN WORK; el segundo usuario la pasaba,
esperaba el bloqueo de prtb00020 y al liberarse insertaba otra orden.

- vedir/veconvierteorden: re-valida dentro de la transaccion, ya con el
  bloqueo de prtb00020.
- WEBSERVICES/veconvierteorden: misma re-validacion (no tenia ninguna).
- ccdir/ccprmt003 verifica_orden(): COUNT(*) en vez de SELECT num_oc,
  que daba -284 con ordenes duplicadas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 16:04:59 -04:00
jpegueroandClaude Sonnet 5.5 1be68d9313 ipprmt044: registra formularios faltantes (ipfmmt044, ipfmwd001/004/009/010/011) y ipautorizareq.4fd en FUNCIONES_IP
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:34:20 -04:00
jpegueroandClaude Sonnet 5.5 97b9c16bf1 lqprrp009: inicia el reporte con la primera fila y avisa cuando no hay registros
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 11:09:06 -04:00
Abel LópezandClaude Sonnet 5.5 4e3993daf8 Registra adprmt027 (Formulario de Vacaciones) y corrige bugs
- Registra adfmmt027.per (FORMULARIOS_AD) y la aplicacion adprmt027 en
  ADMINISTRACION PERSONAL.
- MAIN: se quitan el usuario y la clave escritos en el fuente (kpolanco);
  vuelve a usar los argumentos de la linea de comandos.
- adpcmf027: CONVERT(CHAR(10),fecha,103) hacia variables DATE -> columna
  directa (-1205).
- La tabla vacaciones no existia en marmotech (.250); se creo con
  adprmt027_vacaciones.sql (14 columnas del esquema viejo).
Verificado contra la BD .250: Nuevo, Buscar, Escoger y eLiminar con la
ficha 110 (el registro de prueba se elimino).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 10:20:42 -04:00
Luis 4c9a841473 modificacion factura lsoto 2026-10-19 18:21:13 -04:00
Abel López 9c520ec3ad Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-19 17:24:20 -04:00
Abel LópezandClaude Sonnet 5.5 548dc62d4a Registra adprmt017 (Accion de Personal) y corrige bugs de Genero 6
- Registra adprmt017 y sus formularios (adfmmt017, adfmwd007/008/017/018/019)
  en ADMINISTRACION PERSONAL. adfmwd009.per no se registra: solo lo abre
  busca_movi(), que nadie llama.
- adfunciones.4gl pasa a la libreria FUNCIONES_ADF (el mismo archivo no puede
  estar en dos aplicaciones); noprcs004 y adprmt017 dependen de ella.
- adfmwd008.per: DATABASE rayovac -> smarmotech (-6601).
- adprmt017.4gl: CONVERT(CHAR(10),fecha,103/101) hacia variables DATE -> se
  lee la columna fecha directa (-1205); sexo del titular con
  ISNULL(cod_par,0)=0 (adtb00021 tiene cod_par/sec_par NULL); un tipo_mov
  vacio (AUMENTO SALARIAL, CONTRATACION) ya no se atora en cod_sol.
Verificado contra la BD .250: Nuevo de AUMENTO SALARIAL (accion 5387, empleado
110) graba adtb00020 sin cambiar adtb00003. Capacitacion/Desvinculacion no
probadas: las tablas adtb00059-62 no existen en la .250.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 17:22:34 -04:00
jpegueroandClaude Sonnet 5.5 0f48fc5afc Bloqueados: enlazan prprmt006, ipprmt044 y lqprrp009 (licencia Genero activa)
- lqprrp009: se quita la copia local de defecto(); msgrp000 (restaurado por
  Johnny el 16/10) ya la trae y duplicaba (-6203).
- prprmt006: se anulan las dos llamadas a pantalla() (encabezado de la
  pantalla de texto antigua, no existe en el proyecto y los demas programas
  de PRODUCCION no la usan) y se pone titulo de ventana.
- ipprmt044: fotos.4gl ahora incluye ctramo() y cseccion() (copiadas de
  otrodir/tramos.4gl y secciones.4gl) porque importar FUNCIONES_IR completa
  mete modulos de Repuestos que chocan.
- ipdir/ipautorizareq.4gl: IMPORT FGL greruntime. msgrp000 importa ese
  paquete y libgre.42m tambien define fgl_report_*, por lo que cualquier
  modulo de libreria que los llamara sin importar quedaba ambiguo (-8401)
  cuando el programa lo usaba (solo ipprmt044). Verificado: las 34
  aplicaciones que usan FUNCIONES_IP enlazan, salvo ipprmt002 e ipprrp052
  que siguen con el problema conocido de columnas de iptb00002 en el
  esquema.

Pendiente: probar funcionalmente estos programas.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 13:11:45 -04:00
jpegueroandClaude Sonnet 5.5 604f9339ed Bloqueados: lqprrp009, prprmt006 e ipprmt044 (pendiente enlazar y probar)
lqprrp009 (Liquidacion Repuestos):
- Dependencia FUNCIONESREPORT (msgrp000, seleccionarsalida).
- defecto() copiada al programa (vive en indir/defecto.4gl junto con
  msgrp000 duplicado, importarla chocaba -6203); configureOutput ya la
  aporta msgrp000.
- Quita Convert(...,103) que llenaba variables DATE (fecha_inicial/final).
- Titulo de ventana "Liquidacion Repuestos".

prprmt006 (Orden Produccion):
- El programa usa prtb08[idx].cod_n_c... como arreglo, pero el global
  prtb08 es RECORD LIKE prtb00012.* y el arreglo arrprtb08 se quito de
  prprgb000.4gl el 24/08 (68b73cf): 52 errores "Subscripting cannot be
  applied". Se define arrprtb08 dentro del propio programa (mismos 7
  campos que el form prfmmt006 s_orden) y se renombran 54 referencias.
  Nadie mas usa arrprtb08, no hay choque con globales.

ipprmt044 (Transacciones Inventario):
- Faltaba la funcion fotos() de 12 parametros: existe en el respaldo
  PROYECTOS/otrodir/fotos.4gl (version de 2017) y la llamada del programa
  coincide exactamente. Se agrega a la aplicacion junto con el form
  ipfmwd015.4fd. Las llamadas de ipprcs004/_1 a fotos() estan comentadas,
  no se afectan. cc_avisadespacho es un procedimiento almacenado, no una
  funcion 4GL.

Los tres compilan con fglcomp (esquema smarmotech); falta enlazar y
probar cuando se active la licencia de Genero (FLM-51 vencida).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 13:00:27 -04:00
jsotoandClaude Opus 5.5 7e166ca852 JSOTO MainMenu: lanza cada programa desde su ruta de seg0005 y con el runtime del menu
- Cada programa arranca parado en su ruta de seg0005 (cd /d), como en 3.20: ahi estan
  cert\, filesXML\, net6.0\, tmp\... que la factura electronica busca con rutas relativas,
  y sus .42m. Antes heredaba como directorio de trabajo la carpeta del despliegue del GAR,
  que cambia en cada deploy y llego a tener .42m de 3.20 (-6201 Bad version).
- Usa %FGLDIR%\bin\fglrun (el runtime del menu) en vez del primer fglrun del PATH.
- Ya no imprime usuario y clave en la consola/log del GAS.

Probado en .251 (despliegue mbs-20261019-121056): cgprmt001 y cgprmt004 OK.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:19:21 -04:00
jsoto fcaa47948b Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-19 12:09:59 -04:00
Abel LópezandClaude Sonnet 5.5 31daca8636 Registra adprmt001 (Departamentos) en ADMINISTRACION PERSONAL y corrige bugs
- Registra adfmmt001.4fd (FORMULARIOS_AD), adprgb000.4gl (FUNCIONES_AD) y
  la aplicacion adprmt001 en el subgrupo ADMINISTRACION PERSONAL.
- INSERT en adtb00001 (14 cols) y adtb00029 (10 cols) con lista de
  columnas (error 213 por columnas nuevas en el esquema).
- INPUT/DISPLAY BY NAME limitados a los 7 campos del formulario (-1102
  tipo_departamento no existe en el form).
- Escoger ya no actualiza estado_a/estado_m con variables nunca cargadas
  (los dejaba en NULL); se quitan del INPUT BY NAME (no estan en el form).
- SELECT UNIQUE -> SELECT DISTINCT (SQL Server).
Verificado contra la BD .250 con el depto 9990: Nuevo, Escoger y eLiminar
en adtb00001/00029/00033.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 11:24:54 -04:00
jsotoandClaude Opus 5.5 7831e33c28 JSOTO .gitignore: llaves y certificados fuera del repo
Se ignoran *.jks, *.keystore, *.p12, *.pfx, *.pem, *.key, *.crt y *.cer, y se sacan del
repo los 38 que estaban versionados (keystores de Android, certificados de firma, llave
TLS de WEBSERVICES, llaves APNs, etc.). Los archivos siguen en disco.

OJO: al hacer pull, git borra esos archivos de la copia de cada desarrollador; quien los
necesite (firma e-CF, WEBSERVICES, build del APK) debe recibirlos por un medio seguro.
Siguen en el historial de git: se recomienda renovar las llaves expuestas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:35:51 -04:00
jsotoandClaude Opus 5.5 c7325cc87d JSOTO .gitignore: GAR e imagenes de ejecucion fuera del repo
- *.gar: los paquetes se generan en el build (gsmake -t mbs mbsERP.4pw); se sacan del
  repo PROYECTO/distbin/mbs.gar y PROYECTO/seguridad2.0/distbin/Application_GAR.gar.
- PROYECTO/bin/IMAGENES: solo se versionan las imagenes que usan programas y reportes
  (Logo.png, Logo_DCM.png, genero_logo.png, LOGO.JPG, logo1.png y EMPLEADOS/.gitkeep).
  Se sacan del repo fotos personales, temporales (tmpfile.jpg) y archivos subidos en
  ejecucion (imagenessistema/, p.ej. comprobantes de cobro). Los archivos siguen en disco.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:32:04 -04:00
jsotoandClaude Opus 5.5 3a021932f3 JSOTO mbsERP.4pw: cgprmt005 fuera del proyecto y GAR solo con logos de reportes
- Se quita la aplicacion cgprmt005 (Cheques Administrativos RD$) y sus formularios
  cgfmmt005/cgfmwd007: pertenece al proyecto EXTERIOR (conecta a la BD exterior, usa
  funciones de sus librerias y los cheques solo estan vivos en exterior; en marmotech
  el ultimo es de 2018). Las fuentes quedan en cgdir.
- Paquete mbs: el directorio IMAGENES solo incluye los logos que usan los .4rp
  (Logo.png, Logo_DCM.png, genero_logo.png, LOGO.JPG). Con *.png/*.jpg se empaquetaban
  fotos personales, temporales y comprobantes de cobro de bin/IMAGENES.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:27:45 -04:00
Luis 1d3906bcc3 Merge branch 'main' of https://git.fulldetord.com/jsoto/MBS
# Conflicts:
#	PROYECTO/cgdir/edprrp118b.4gl.bak-20261008
#	PROYECTO/irdir/desglose_conteo.4gl
#	PROYECTO/irdir/imprequisicion.4gl
#	PROYECTO/irdir/irautorizareq.4gl
#	PROYECTO/irdir/irbuscaprod.4gl
#	PROYECTO/irdir/irfmmt004.per
#	PROYECTO/irdir/irprcs006.4gl
#	PROYECTO/irdir/irprgb000.4gl
#	PROYECTO/irdir/irprmt002.4gl
#	PROYECTO/irdir/irprmt004.4gl
#	PROYECTO/irdir/irprmt006.4gl
#	PROYECTO/irdir/irprmt009.4gl
#	PROYECTO/irdir/irprmt020.4gl
#	PROYECTO/irdir/irprmt021.4gl
#	PROYECTO/irdir/irprmt036.4gl
#	PROYECTO/irdir/irprmt066.4gl
#	PROYECTO/irdir/irprrp002.4gl
#	PROYECTO/irdir/irprrp003.4gl
#	PROYECTO/irdir/irprrp005.4gl
#	PROYECTO/irdir/irprrp006.4gl
#	PROYECTO/irdir/irprrp009.4gl
#	PROYECTO/irdir/irprrp043.4gl
#	PROYECTO/irdir/irprrp045.4gl
#	PROYECTO/lqdir/lqprrp009.4gl.bak_20261012
#	PROYECTO/lqdir/lqprrp009.rdd.bak_20261012
#	PROYECTO/otrodir/apiclient.4gl.bak_20261014
#	PROYECTO/otrodir/cuentas.4gl
#	PROYECTO/otrodir/irdepartamento.4gl
#	PROYECTO/otrodir/maquinas.4gl
#	PROYECTO/otrodir/productos_incluye.4gl
#	PROYECTO/otrodir/secciones.4gl
#	PROYECTO/otrodir/tramos.4gl
#	WEBSERVICES/productosconteo.4gl.bak_20261012
2026-10-19 10:17:14 -04:00
Luis a67f97271a lsoto 2026-10-19 10:11:40 -04:00
Luis e0722b2e2a lsoto 2026-10-19 10:07:36 -04:00
jsotoandClaude Opus 5.5 a1c15d43f3 JSOTO acprmt001: ALTER de actb00001 y arreglos de MaintainX y lista
- acprmt001_alter_actb00001.sql: crea en actb00001 las columnas cod_sp, cod_sp_sec,
  tipo_activo y activo_padre (NULL). Las usa la version ene-2025 del programa
  (integracion MaintainX) y nunca se habian creado en ninguna base. Aplicado en la .250;
  pendiente en produccion.
- Si MaintainX falla (Adicionar/Modificar con la casilla marcada, Eliminar con
  id_maintainx) se cancela la operacion; antes hacia ROLLBACK y seguia grabando fuera de
  la transaccion (COMMIT -255).
- Eliminar: parametros de ApiMaintainX en el orden de la firma (infoArray, maquinaria).
- Lista: se quita la fila vacia final; getdata usa el codigo como parametro (antes
  "WHERE a.codigo = " sin valor daba -201) y filtra la maquina inactiva en el ON del
  LEFT JOIN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 09:54:32 -04:00
jpegueroandClaude Opus 5.5 f6e41932b1 prprmt011 (Administracion Ordenes): formularios faltantes y fechas -1205
- Registra en FORMULARIOS_PR los formularios que el programa y sus
  librerias abren y no estaban en el proyecto: prfmmt011b, prfmmt011c,
  prfmwd015, prfmcs002, prfmmt021b/c/d, prfmwd002, prfmwd012, prfmwd013.
- prfmmt012 registrado era el de ccdir (otro formulario con el mismo
  nombre); se reemplaza por PRDIR/prfmmt012.4fd (campos iguales al 42f de
  produccion).
- Rescata otrodir/existenciaalmacenes.4fd del respaldo PROYECTOS y lo
  registra en FUNCIONES_PR junto a existenciaalmacenes.4gl.
- prfmwd014.per: s_llegada[9] -> [5]; la pantalla dibuja 5 filas y el
  formulario no compilaba (-2029). Tampoco existia compilado en produccion.
- Quita CONVERT(...,103) en 8 lecturas que llenan campos DATE (consulta
  principal, fecha_llegada, parciales y datos de cotizacion); con dias >12
  el programa terminaba con error al buscar. Se dejan los CONVERT que
  llenan campos CHAR(10).
- Titulo de ventana "Administracion Ordenes".

Verificado: busqueda 01/07/2026-02/07/2026 trae 189 lineas con colores;
botones transacciones y Requisicion funcionan. Pendiente probar
Existencia, flujo, Documentos, fllegada, parciales, visualiza_log,
Reporte Data e Informe. Nota: un mes completo (3,105 lineas) tarda
varios minutos por las consultas por linea (diseno original).
Pendiente Johnny: FORMULARIOS_PR no compila completo por prfmmt006
(columna prtb00007.orden_pedido inexistente) y msgfmwd001 (msgrp000) no
tiene fuente en ningun lado.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:05:43 -04:00
jpeguero cb8363561a Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-17 09:31:17 -04:00
jsoto adbbaaee8e Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-16 17:07:28 -04:00
jsotoandClaude Opus 5.5 f363390589 JSOTO cgprmt022 adaptado a MARMOTECH y cgprmt037 fuera del proyecto MBS
cgprmt022 (actualizacion de tasa mensual, cgtb00084; la usa edprrp116):
- La fuente era la version de EXTERIOR, donde vetb00060/vetb00061 estan invertidas
  respecto a marmotech: el combo de moneda ahora sale de vetb00061 y los tipos de
  cliente de vetb00060.
- SELECT INTO tenia 5 columnas para 4 variables.
- Se quita la segunda escritura a marmotech.dbo.cgtb00084 (en marmotech es la misma tabla).
- cgfmmt022.4fd: formulario de EXTERIOR (campo Replicar y tabla de tipos de cliente);
  el de MARMOTECH (2022) no tenia esos campos (-1102).

mbsERP.4pw: se quita la aplicacion cgprmt037 y sus formularios cgfmmt037/cgfmwd006
(solo los usaba ese programa). Pertenece al proyecto EXTERIOR (sistema de tablas de la
BD exterior, aun no iniciado); las fuentes quedan en cgdir.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 17:05:01 -04:00
jpegueroandClaude Opus 5.5 a52b16b8b2 ipprmt005 (Clase): graba Inventario y oculta clases eliminadas
- Alta y modificacion ahora graban cod_inv (Inventario); antes se leia en
  la consulta pero nunca se guardaba (igual en el 42m de produccion 3.20).
- La consulta excluye las clases con status_t = 'E' (eliminadas) y lee
  status_t, para que al consultar una eliminada salga REGISTRO NO EXISTE y
  funcione el control de Escoger sobre registros anulados.
- Impresora se deja sin tocar, como en 3.20: el combo no tiene opciones
  (tampoco en produccion) y guardarlo borraria valores existentes (80-83)
  que usa veconvierteorden para rutear impresion de ordenes.
- Configuracion de ejecucion con el usuario de la responsable (antes usaba
  el de jsoto, por eso grababa ese usuario como creador/modificador).

Verificado: consulta de clase eliminada (211) da REGISTRO NO EXISTE; alta
(212) graba Inventario y usuario jpeguero. Pendiente: probar Escoger y
eLiminar con la nueva version y confirmar en produccion que cod_inv solo
usa los valores del combo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 17:00:54 -04:00
Abel LópezandClaude Sonnet 5.5 b8f403c2e4 Proyecto: elimina el grupo NOMINA vacio de MODULOS
El grupo estaba vacio (despues de MATERIA PRIMA) y no se usara; los
programas de nomina viven en RECURSOS HUMANOS > NOMINA.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 16:53:41 -04:00
Abel López 8a87ebbc10 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-16 16:50:16 -04:00
jsotoandClaude Opus 5.5 0991743a80 JSOTO QA G6 (.250): arreglos en reportes de Repuestos y Contabilidad
Repuestos (irdir):
- irprrp002: cod_sec USING '&&&&' (con '&&&' salia *** en sec >= 1000); encabezado
  con companias.nombre (estaba fijo "EUROSTONE").
- irprrp003: filtro de fecha real con parametros (antes CONVERT(...,103) BETWEEN texto:
  traia movimientos de cualquier ano); codigo CHAR(8)/'&&&&' (los sec >= 1000 se
  mezclaban en un mismo grupo y saldo); RIGHT MARGIN 170 (saldo y balance cortados).
- irprrp004: CONSTRUCT sobre irtb00005.cod_mov (antes intb00005: fallaba con filtro).
- irprrp006: JOIN b.cod_n = c.cod_n (antes c.cod_n = c.cod_n).
- irprrp009: CONSTRUCT calificado con b. (columnas ambiguas en el JOIN).
- irprrp045: sin departamento solo muestra los departamentos del usuario (adtb00056).

Contabilidad (cgdir):
- cgprrp014: saldo de apertura acreedor va positivo a la columna CR (restaba en totales).
- cgprrp009: ya no modifica cgtb00004 (UPDATE departamento=0 y reversion); el NULL se
  trata como 0 en las consultas; corrige idx1 (START REPORT se repetia por fila).
- cgprcs024: el acumulado anterior termina el dia antes de "desde" (se contaba doble).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 16:50:08 -04:00
Abel LópezandClaude Sonnet 5.5 70c3131e9c Registra noprmt026 (Pago TSS) y migra la salida de DDE a CSV
- Registra nofmmt026.4fd y la aplicacion noprmt026 (con FGLSPOOL) en el
  subgrupo NOMINA.
- GDC 6.00 ya no incluye el modulo WINDDE (error -6331): enviaDDE() guarda
  las celdas en memoria y escribeCSV() genera FGLSPOOL/noprmt026_<tipo>_
  <periodo>.csv con las mismas filas/columnas de la plantilla TSS.
- SQL: se quitan los CONVERT(...,103) sobre variables DATE (-1205), la
  comparacion de fechas como texto (101) y el date+int dentro del SQL
  (-206); rango con fecha_sig = fecha_final+1. FOREACH con THRU (10 cols).
Verificado contra la BD .250: Normal 2026/7 = 636 filas / 33,933,711.43;
Bonificacion cancelados 2026/4 = 229 filas / 1,596,887.98.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 16:47:15 -04:00
Abel LópezandClaude Sonnet 5.5 fc5a23132d Registra noprrp041 (Reporte de Horas Extras) y corrige bugs
- Registra nofmrp041.4fd y la aplicacion noprrp041 en el subgrupo NOMINA.
- nofmrp041.4fd: el del repo no era el de este programa; se usa el de 3.20
  (fecha_inicial, fecha_final, cod_sup, num_emp) con format dd/mm/yyyy.
- noprrp041.4gl: el JOIN comparaba notb00028.supervisor (texto
  '(cod) NOMBRE') con adtb00003.num_emp -> error 245; ahora une por
  notb00028.num_emp. El filtro Empleado filtra b.num_emp. Fechas del SQL
  en yyyymmdd con fecha_final+1 (sin BETWEEN).
Verificado contra la BD .250 (dic-2019: 3,552 horas / 544,076.97).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 15:39:35 -04:00
Luis 54c77ca23e para hacer el pull lsoto 2026-10-16 15:33:34 -04:00
jsotoandClaude Opus 5.5 705fadfdb4 JSOTO QA G6 (.250): arreglos CG/Activos/Repuestos/Informatica, DBDATE, imagenes de reportes y cgprrp008
Programas (bugs encontrados en las pruebas funcionales en la .250):
- acprmt004/acprmt005: MIN/MAX sobre la fecha real (no sobre texto CONVERT 103); acprmt004 alinea rowid.
- cgprrp008: lee cgtb00004 (no la copia cgtb00004_tmp del 14-mar-2026) y solo regenera
  cgtb00016 cuando se corre sin filtro de cuenta.
- cgprrp014: CONSTRUCT con los nombres de campo del form (cod_sp_sc).
- cgfmrp013: defaultValue del combo = cgprrp012.4rp.
- cgprrp022/edprrp029: salida getPreviewDevice() en lugar de SVG fijo.
- edprrp080: no consume numero ED con afecta = NO.
- cgprmt004/022/037, segprmt0001: sin CONNECT "IFMX" (-6366); EXTERIOR via cross-DB.
- irprcs001: agrega CONNECT; irprmt021: columna idestado; irprmt066: la anulacion sin
  MaintainX ya no se deshace (-255); otrodir/bodegas: rama '2' llena origen y destino.
- teprmt001: ajustes G6.

Despliegue G6:
- DBDATE=dmy4 en config/Application.xcf, config/Main_prg.xcf, resources/Application.xcf
  y en el grupo MODULOS del .4pw (los programas lanzados por el menu heredan el entorno).
- 31 .4rp: IMAGEBOX con rutas absolutas file:///E:|F:|C: -> relativas IMAGENES/...;
  se agregan IMAGENES/LOGO.JPG y genero_logo.png.
- Paquete mbs: incluye bin/*.4rp y bin/IMAGENES (antes el GAR no llevaba los reportes).
- resources/TopMenu.4st (irprcs008 daba -8014); bin/cgprcs024.4rp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:30:24 -04:00
Luis c190582481 para hacer un pull lsoto 2026-10-16 15:28:58 -04:00
jpegueroandClaude Sonnet 5.5 aa7fe013c0 lqprrp004: mensaje de 'sin datos' igual al de Genero 3.20
Con Tipo Reporte Local (sin liquidaciones con liquidada='L' en cgtb00017,
ni en pruebas ni en produccion) el programa se cerraba sin avisar. En 3.20
muestra INFO "NO ENCONTRE INFORMACION CON ESOS PARAMETROS" y vuelve al
menu; se replica el mismo texto.

Verificado contra Genero 3.20 y 6.00.03 con Productos Terminados, 03/2024,
Local.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 11:35:04 -04:00
jpegueroandClaude Sonnet 5.5 e051b498f6 lqprrp004: reemplaza .4rp danado por el de produccion y avisa si no hay datos
- bin/lqprrp004.4rp del repo era un archivo binario ilegible (motor de
  reportes: "Content is not allowed in prolog"). Se reemplaza por el XML de
  produccion (\192.168.40.4\MARMOTECHC$\BIN320, report name liquida1,
  formato 6.00).
- Si la consulta no devuelve filas ahora muestra "NO EXISTEN REGISTROS PARA
  ESTOS PARAMETROS" en vez de cerrarse sin avisar.

Verificado: Productos Terminados, 03/2024, tipo Importacion: 2 paginas en
pantalla y PDF con totales por orden. Tipo Local sin datos en el periodo.
Excel no probado.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 11:11:42 -04:00
jpegueroandClaude Sonnet 5.5 5dcc4adf2c Corrige compilacion de lqprrp004 y prprmt011 (modulos LIQUIDACION y PRODUCCION)
lqprrp004:
- El .4gl tenia saltos de linea CR (Mac antiguo): en Genero 6 el comentario
  '######' de la linea 2 se tragaba todo el programa (modulo de 181 bytes,
  "main not defined"). Convertido a CRLF (el diff grande es solo eso).
- numero_ent se usaba en REPORT entrada271 sin definirse (solo existia en
  edprrp0271); definida y asignada = 27 como en la funcion hermana.
- Agrega dependencia FUNCIONESREPORT.

prprmt011 / prprmt021:
- primpresion.impresion(pnumoc) chocaba con impresion(...) de 5 parametros
  de FUNCIONESREPORT (veprrp049_1.4gl). Renombrada a impresion_oc y su unico
  llamador (prprmt021) actualizado. prprmt011 recibe FUNCIONESREPORT.

Verificado con gsmake: lqprrp004, lqprmt002, ipprmt005, prprmt011 y
prprmt021 compilan y enlazan. lqprrp004 consulta datos de 03/2024 pero el
reporte no se genera: bin/lqprrp004.4rp es un archivo binario (no XML) y no
existe version XML en el repo. Pendiente que Johnny lo entregue.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 10:15:59 -04:00
jsotoandClaude Opus 5.5 95aa24c029 JSOTO Restaura configureOutput() de 3.20 en msgrp000 (reportes GRE)
El stub RETURN NULL dejaba sin handler a los ~90 programas que usan
configureOutput(): todos caian con -8083 en START REPORT ... TO XML HANDLER.
Se vuelve a la version de 3.20 y se agrega IMPORT FGL greruntime para que
las funciones fgl_report_* resuelvan aunque la app no declare libgre.42x.

Verificado con gsmake (fgl602) sobre las 79 apps que dependen de
FUNCIONESREPORT: ninguna empeora; las de CxP, Compras y Nomina siguen
compilando y 8 reportes de Ventas pasan a compilar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 17:37:36 -04:00
jsotoandClaude Opus 5.5 d8764b3bda JSOTO Alta y compilacion G6 de programas CG, Cheques, Activos, Tesoreria, Repuestos e Informatica
Merge de main (ipprrp013/014/046/053) con conflictos resueltos:
- mbsERP.4pw: ipprrp014 conserva ambos 4rp y su 4fd.
- bin/ipprrp014.4rp: columnas MARGEN/CLASIF. + titulo IPPRRP014.

Programas agregados a mbsERP.4pw (53 compilan y enlazan con fgl602):
- CONTABILIDAD GENERAL, ACTIVOS FIJOS, REPUESTOS; grupos nuevos TESORERIA,
  CHEQUES e INFORMATICA (segprmt001 = seguridad2.0/segprmt0001.4gl).
- irdir copiado de 3.20 PROYECTOS/irdir a PROYECTO/irdir; helpers de
  PROYECTOS/otrodir en FUNCIONES_IR (departamento -> irdepartamento.4gl).
- Fuentes mas nuevos de 3.20: edprrp118, edprrp080, acprrp010, cgprmt022.
- FUNCIONES: GeneraEntradaDiario.4gl a la version 3.20 + costoLiquidacion.4gl.
- Ajustes G6: existe duplicado en irprgb000, fakeData de 22 campos y
  answer2 en irprmt036/020 (ApiMaintainC), selectOutputSimple en irprcs008,
  schemas de forms a smarmotech, referencia declarada en cgprmt005.
- cgprmt005 sigue sin enlazar: requiere funciones de EXTERIOR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:22:14 -04:00
jpegueroandClaude Sonnet 5.5 ea88c93da3 Corrige ctprrp014 (Reporte Produccion Mensual)
- Titulo de ventana corregido
- START REPORT se ejecuta con la primera fila; si la consulta no devuelve
  datos avisa "NO EXISTEN REGISTROS PARA ESTOS PARAMETROS" en vez de
  generar un reporte en blanco

Verificado con ano 2024 (la BD de pruebas no tiene produccion posterior a
agosto de 2025): 1 pagina con 9 semielaborados por mes y total, en pantalla,
PDF y Excel.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 16:07:11 -04:00
jpegueroandClaude Sonnet 5.5 7d5a853351 Corrige ctprrp004 (Reporte Produccion Diaria)
- Titulo de ventana corregido (mostraba "screen")
- START REPORT se ejecuta con la primera fila; si la consulta no devuelve
  datos avisa "NO EXISTEN REGISTROS PARA ESTOS PARAMETROS" en vez de
  generar un reporte en blanco

Verificado con 01/01/2024 a 12/31/2024: detallado 166 paginas en pantalla,
resumen 57 paginas en PDF. En la BD de pruebas (.40.250) cttb00003 no tiene
produccion posterior a agosto de 2025, por eso rangos de 2026 salen vacios.
Excel no probado.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 15:49:06 -04:00
jpegueroandClaude Sonnet 5.5 fc2fa7acac Corrige ipprrp054 (Revision de Conduces con y sin Archivo)
- Registra ipfmrp054.4fd y la dependencia FUNCIONESREPORT en mbsERP.4pw
- seleccionarsalida() -> selectOutputSimple()
- Rescata ipprrp054.4rp del respaldo PROYECTOS/bin (ipdir/ y bin/)
- El reporte arrancaba aunque la consulta no devolviera filas y el motor
  fallaba (Failed to find value for the look ahead input-variables);
  ahora START REPORT se ejecuta con la primera fila y, si no hay datos,
  muestra "NO EXISTEN REGISTROS"
- Titulo de ventana corregido

Verificado: 05/01/2026 a 10/15/2026 genera 100 paginas en pantalla y PDF.
Nota: las fechas de este formulario se capturan en formato mm/dd/yyyy
(campo Edit sin selector), comportamiento original del programa.
Excel no probado.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 13:16:11 -04:00
jpegueroandClaude Sonnet 5.5 47942191ee Corrige ipprrp051 (Transacciones de Inventario con ubicacion)
- Registra ipfmrp051.4fd y la dependencia FUNCIONESREPORT en mbsERP.4pw
  (resuelve msgrp000 y seleccionarSalida)
- busca_departamento() definida localmente (igual que ipprrp047/048)
- seleccionarsalida() -> selectOutputSimple()
- Rescata ipprrp051.4rp del respaldo PROYECTOS/bin (ipdir/ y bin/)
- Titulo de ventana corregido

Verificado: 01/08/2026 a hoy, movimiento 30, 8 paginas en pantalla y PDF.
Excel no probado.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 13:04:06 -04:00
jpegueroandClaude Sonnet 5.5 43f9d16e62 Corrige ipprrp048 (Transacciones de Inventario por Departamento)
- Registra ipfmrp048.4fd y la dependencia FUNCIONESREPORT en mbsERP.4pw
  (resuelve msgrp000 y seleccionarSalida)
- busca_departamento() definida localmente (igual que ipprrp035/036/047)
- seleccionarsalida() -> selectOutputSimple()
- Rescata ipprrp048.4rp del respaldo PROYECTOS/bin (ipdir/ y bin/)
- Titulo de ventana corregido

Verificado: 01/08/2026 a hoy, movimiento 30, 4 paginas en pantalla y PDF.
Excel no probado.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 12:51:54 -04:00
jsoto 659e690af3 JSOTO adicione los 4rp del ipprrp014 2026-10-14 18:30:22 -04:00
jpegueroandClaude Sonnet 5.5 d805fa3164 Corrige ipprrp047 (Operacion por Movimiento Detallado y Valorizado)
- Registra ipfmrp047.4fd y la dependencia FUNCIONESREPORT en mbsERP.4pw
  (resuelve msgrp000 y seleccionarSalida)
- busca_departamento() definida localmente (igual que ipprrp035/036)
- seleccionarsalida() -> selectOutputSimple()
- Rescata ipprrp047.4rp del respaldo PROYECTOS/bin (ipdir/ y bin/)
- Titulo de ventana corregido

Verificado en pantalla: 01/05/2026 a hoy, 113+ paginas agrupadas por
movimiento y departamento con totales. PDF y Excel no probados.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 17:00:45 -04:00
jpegueroandClaude Sonnet 5.5 3903f11a92 Corrige ipprrp046 (Relacion de Documentos)
- Registra ipfmrp046.per y la dependencia FUNCIONESREPORT en mbsERP.4pw
- seleccionarsalida()/configureoutput() -> selectOutputSimple() y funcion
  local configurarSalidaClasica(): el configureOutput de msgrp000 es un stub
  que devuelve NULL; el reporte clasico PRINT COLUMN necesita el modo
  compatibilidad (monoespaciado) como el de indir/defecto.4gl
- Titulo de ventana corregido

Verificado: 01/05/2026 a hoy genera 299 paginas en pantalla y PDF.
Excel no probado por el volumen de datos.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 16:29:54 -04:00
jpegueroandClaude Sonnet 5.5 d76e6d7035 Corrige ipprrp014 (Dias de Inventarios Gerente Marcas): Detallado funcional
- Registra ipfmrp014.4fd y la dependencia FUNCIONESREPORT en mbsERP.4pw
- Quita convert(char(10),...,103) de fecha_v y fecha_oc (el campo es DATE)
- Titulo de ventana corregido
- Rescata ipprrp014.4rp del respaldo PROYECTOS/bin; el encabezado decia
  IPPRRP013 (texto fijo copiado del otro diseno), corregido a IPPRRP014

Verificado: pantalla, PDF y Excel con el gerente Adolfo Santelises (prueba
con usuario temporal, no incluido en este commit). Pendiente: Resumen por
clase, ipprrp014r.4rp no existe en el repo ni en el respaldo.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:47:26 -04:00
Abel LópezandClaude Sonnet 5.5 79a4a4530c Proyecto: reorganiza grupos de RECURSOS HUMANOS
- Programas y librerias de nomina (FORMULARIOS_NO, FUNCIONES_NO y las
  aplicaciones noprmt/noprcs/noprrp) pasan al subgrupo NOMINA.
- FORMULARIOS_AD y FUNCIONES_AD pasan al subgrupo ADMINISTRACION PERSONAL.
Solo cambia la ubicacion en mbsERP.4pw; ids, dependencias y fuentes sin
cambios.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 16:48:11 -04:00
Abel López 0ed9fb6d98 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs
# Conflicts:
#	PROYECTO/mbsERP.4pw
2026-10-08 10:28:43 -04:00
jpegueroandClaude Sonnet 5.5 b6ae121e22 Corrige ipprrp053 (Informe Transacciones Inventarios)
- Registra ipfmrp053.4fd y la dependencia FUNCIONESREPORT en mbsERP.4pw
- selectoutput() inexistente -> selectOutputSimple()
- Rescata ipprrp053.4rp del respaldo PROYECTOS/bin (ipdir/ y bin/)
- Titulo de ventana corregido (mostraba "form")

Verificado: rango 05/01/2026 a hoy genera 911 paginas; pantalla, PDF y Excel OK.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 13:15:20 -04:00
Abel LópezandClaude Sonnet 5.5 ad1a97dd9a noprrp045: corrige expresiones del diseno (.4rp)
Quita espacios dentro de las expresiones RTL de bgColor/fontBold, que el
parser rechazaba al cargar el reporte. Datos verificados contra la BD
(monto y cantidad por mes y sexo, ano 2025).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 13:06:20 -04:00
jpegueroandClaude Sonnet 5.5 f8df43d126 Corrige ipprrp013 (Dias de Inventario): Detallado y Resumen funcionales
- Registra ipfmrp013.4fd y la libreria FUNCIONESREPORT en mbsERP.4pw
- Quita CONVERT(...,103) en fecha_factura y fech_oc (error -1205)
- Titulo de ventana corregido
- ipprrp013.4rp: formato 7.00, diseno plano con rtl:input-variable
  (los grupos anidados no coincidian con el flujo del REPORT), encabezado
  con compania/fecha/hora y FECHA VENTA enlazada a fecha_v
- Resumen usa ipprrp013r.4rp (agregado por Johnny)

Verificado: Detallado sin filtros (3 paginas) y Resumen clase 124.
Pendiente: alineacion visual de columnas del Detallado.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 12:56:29 -04:00
Abel LópezandClaude Sonnet 5.5 61818beb31 Registra noprrp045 (Formulario Ministerio de Trabajo)
- Registra nofmrp045.per y la aplicacion noprrp045 en mbsERP.4pw.
- Mueve noprrp045.4rp a bin/ (igual que los demas reportes).
- Diseno: el gris/negrita de columnas aplica solo a filas mensuales
  (A/M/C); las secciones 4-8 se ven planas. Declara x.tipo como
  input-variable.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 12:54:04 -04:00
Abel LópezandClaude Sonnet 5.5 4b2d63007b Proyecto: mover librerias y programas del grupo NOMINA a RECURSOS HUMANOS
Solo cambia la ubicacion en mbsERP.4pw (ids, dependencias y fuentes
sin cambios). El grupo NOMINA queda vacio.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 12:53:51 -04:00
jsoto 9366fc90e4 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-07 12:12:20 -04:00
jsoto a5ccd3083f JSOTO Adicion grupos ADMINISTRACION PERSONAL Y NOMINA 2026-10-07 12:11:28 -04:00
Luis f574991f0d Merge branch 'main' of https://git.fulldetord.com/jsoto/MBS
# Conflicts:
#	PROYECTO/MBSVG240-marmodesarrollador.4pw
#	PROYECTO/MBSVG240-marmotecnologia.4pw
2026-10-05 23:23:05 -04:00
Luis 2498c785d3 agregue varias funciones para poder ejecutar el programa de facturas lsoto 2026-10-05 23:11:14 -04:00
jsoto ccf12198ba JSOTO ELIMINE LOS NOMBRES DEL PROYECTO DUPLICADOS 2026-10-05 15:03:14 -04:00
jsoto f414a150d9 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs
# Conflicts:
#	PROYECTO/mbsERP.4pw
2026-10-01 17:53:35 -04:00
jsoto 67a5190309 JSOTO ADICIONE EL IPPRRP013R.4RP 2026-10-01 17:48:44 -04:00
Abel López 9ba79096c4 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-10-01 17:03:15 -04:00
Abel LópezandClaude Sonnet 5 80bd203be6 Registra noprrp015 (Prestamos Cooperativa) con reporte moderno
Se agrega noprrp015 al proyecto usando nofmrp015.per.

A diferencia de noprrp009 (donde se opto por salida de archivo de
texto), aqui se reescribio REPORT prestamo de PRINT COLUMN clasico a
PRINTX, y se creo nodir/../bin/noprrp015.4rp (diseno Report Writer
2.0) para soportar pantalla/PDF/Excel, igual que noprrp002/003/039/
043/044. configureOutput() en msgrp000.4gl sigue siendo un stub NULL
(ver noprrp009), asi que se usa fgl_report_loadCurrentSettings +
fgl_report_selectDevice/selectPreview/commitCurrentSettings
directamente.

Se corrige tambien el mismo problema de signo oculto en los montos
(mascaras sin caracter de signo) que se encontro en noprrp009.

Probado con empleado especifico y con varios empleados del mismo
movimiento, verificado contra BD (valor, interes y balance).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-01 17:02:41 -04:00
Abel LópezandClaude Sonnet 5 8ac18135e5 Registra noprrp009 (Movimientos de Empleados) y corrige varios bugs
Se agrega noprrp009 al proyecto usando nofmrp009.per.

Se corrige conversion CONVERT(CHAR,fecha,103) hacia variables DATE en
3 consultas (mismo patron de error -1205 "Invalid month in date" visto
en otros programas).

Se corrige salida del reporte: REPORT list_cooper usa el estilo
clasico PRINT COLUMN (no PRINTX/.4rp), incompatible con el motor de
reportes moderno (fgl_report_*); configureOutput() en msgrp000.4gl es
un stub que siempre retorna NULL para este caso (documentado en su
propio comentario). Se cambia a escribir un archivo de texto plano en
FGLSPOOL, igual que noprrp038.

Se corrige comparacion de fechas como texto (CONVERT a CHAR en formato
dd/mm/yyyy comparado alfabeticamente) en el modo "Vacaciones Pagadas",
que fallaba al usar un rango de fechas que cruza meses/anos distintos;
se cambia a comparacion real de fechas (>= y < dia_siguiente).

Se corrige formato de fecha faltante en los campos de rango de fecha
del formulario (.per), causando "Invalid month in date" al capturar
un dia mayor a 12 como mes.

Se corrige perdida del valor de fecha final en el encabezado del modo
"Vacaciones Pagadas" (el campo se reutilizaba en el record de fetch y
se sobreescribia con un valor en blanco); se guarda en una variable
separada antes del ciclo.

Se corrige formato de impresion de montos y totales sin signo
(mascaras "#,###,###.##" sin caracter de signo), que ocultaba
silenciosamente los valores negativos mostrandolos como positivos.

Probado en ambos modos (por nomina/movimiento, y por vacaciones
pagadas con rango de fechas cruzando meses), verificado contra BD.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-01 12:53:49 -04:00
jpeguero 65515b14c2 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-30 17:03:17 -04:00
jpegueroandClaude Sonnet 5 4bdcf34a7d Registrar form y dependencia de ipprrp013 (Dias de Inventario), agregar titulo
- Registrar ipfmrp013.4fd en el proyecto (form not found al abrir).
- Agregar dependencia faltante FUNCIONESREPORT (msgrp000,
  seleccionarSalida), no linkeaba.
- Agregar titulo a la ventana (usaba el generico "screen").

El .4rp ya existia en el repo y no necesito cambios. Pendiente probar
funcionalmente (filtros/fechas, totales, exportar) - queda para la
proxima sesion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 16:56:02 -04:00
Abel LópezandClaude Sonnet 5 a7431ef94a Registra noprrp043 (Informe Registro Entrada/Salidas) y corrige bugs
Se agrega noprrp043 al proyecto usando nofmrp043.4fd, reutilizando
FUNCIONESREPORT y libgre.42x.

Se corrige validacion residual de otro programa: comprobaba
"fecha_inicial IS NULL" (variable nunca asignada aqui) y hacia
NEXT FIELD fecha_inicial, campo que no existe en este formulario
(solo existen xfecha1/xfecha2). Esto hacia que el boton "Imprimir"
fallara siempre con "Field not found". Se elimina esa validacion,
ya que la validacion real de xfecha1 esta justo despues.

Se corrige rango de fechas: WHERE checktime BETWEEN fecha1 AND fecha2
(sin hora) excluye registros del ultimo dia con hora posterior a
medianoche. Se cambia a >= fecha1 AND < fecha2+1.

Probado con empleado 5001, rango 14/10/2024-16/10/2024, verificado
contra BD (2 registros de entrada, fecha/hora correctas).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 10:58:35 -04:00
jpegueroandClaude Sonnet 5 c795294090 Renombrar selectOutput() a selectOutputSimple() para evitar choque
otrodir/selectoutput_simple.4gl definia FUNCTION selectOutput(), mismo
nombre que otrodir/vesalidaimpresora.4gl (ya usado por Abel en
noprcs006, ipprrp002, ipprrp003, ipprrp039, ipprrp044). Al mezclar
ambos commits, cualquier programa que dependiera de FUNCIONESREPORT
mas la libreria de Abel rompia por simbolo duplicado.

Se renombra la funcion (y se actualizan sus 4 unicos llamados: ipprrp005,
ipprrp009, ipprrp035, ipprrp036) sin tocar vesalidaimpresora.4gl, para
no afectar los programas que Abel ya tiene funcionando con esa version.

Recompilados y verificados los 4 programas tras el cambio.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 10:48:03 -04:00
Abel López 5eedb6b174 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-29 16:48:14 -04:00
Abel LópezandClaude Sonnet 5 f9a7bb91dc Registra noprrp038 (Generacion File para Bancos)
Se agrega noprrp038 al proyecto reutilizando el formulario nofmrp008
(no tiene formulario propio). Sin bugs de codigo encontrados.

Probado con nomina 2320/Q filtrando al empleado 110 (con cuenta
bancaria real): archivo H/N generado correctamente, RNC de la
empresa y monto neto verificados contra BD. El archivo de retiro en
efectivo (RetMarmo.txt) quedo vacio correctamente ya que el empleado
de prueba si tiene cuenta bancaria.

Nota: el relleno de lineas en blanco al final del archivo de prueba
es un artefacto de filtrar a un solo empleado (PAGE LENGTH usa el
conteo total de la nomina, no el del filtro); en una corrida real sin
filtro de empleado no ocurre.

Se genero el archivo real de prueba en una carpeta temporal fuera del
repositorio (contenia datos bancarios/cedula reales del empleado de
prueba), se verifico y se elimino del disco tras la confirmacion del
usuario.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 16:44:17 -04:00
jpegueroandClaude Sonnet 5 60a4119326 Corregir ipprrp036 (Costos de Calidad con Ventas): form, dependencia,
.4rp faltantes y titulo incorrecto

- Registrar ipfmrp036.4fd en el proyecto.
- Agregar dependencia faltante FUNCIONESREPORT para selectOutput().
- Rescatar ipprrp036.4rp de un backup viejo (PROYECTOS/bin), no existia
  en el repo. El nombre de reporte (inv1) coincidia bien.
- El titulo del reporte decia "ipprrp035" (texto quemado copiado del
  diseño anterior, nunca actualizado) - corregido a "ipprrp036", y el
  subtitulo aclarado a "Reporte costos de calidad (con ventas)".

Verificado con rango de fechas 2026-hoy: abre limpio, muestra
"Facturado ventas a la fecha" en el encabezado, exporta correctamente
en PDF, pantalla y Excel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 15:26:41 -04:00
jpegueroandClaude Sonnet 5 895499a8a8 Corregir ipprrp035 (Costos de Calidad): form, dependencia y .4rp faltantes
- Registrar ipfmrp035.4fd en el proyecto.
- Agregar dependencia faltante FUNCIONESREPORT para selectOutput().
- Rescatar ipprrp035.4rp de un backup viejo (PROYECTOS/bin), no existia
  en el repo. El nombre de reporte (inv1) coincidia bien.

Verificado con rango de fechas 2024-hoy, vista detallada y resumida
(por producto y por departamento): abre limpio, exporta correctamente
en PDF, pantalla y Excel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 15:07:14 -04:00
jpegueroandClaude Sonnet 5 6c20f62de9 Corregir ipprrp009 (Existencia a Diferentes Fechas) y limpiar debug
- Registrar ipfmrp009.4fd y agregar dependencias faltantes
  (FUNCIONESREPORT, FUNCIONES_IN) para msgrp000/selectOutput/defecto/
  fgl_report_*.
- Rescatar ipprrp009.4rp de un backup viejo (PROYECTOS/bin), no existia
  en el repo. El nombre de reporte (existencia_grafica) coincidia bien,
  a diferencia del caso de ipprrp010.
- Quitar dos DISPLAY de depuracion olvidados (mostraban el SQL completo
  y el texto "imprime" en cada fila).

Verificado con producto 29-668-1403-6952, rango 01/01/2026-29/09/2026,
grafico=SI: Existencia 360.00, Costo 3,512.41/3,512.42, Total
1,264,469.40 (cuadra: 360 x costo). Subtotal por origen y total general
correctos. Exportado en PDF, pantalla y Excel sin problemas. Cierre
limpio.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 12:44:34 -04:00
jpegueroandClaude Sonnet 5 3923c9dc01 Corregir ipprrp005 (Maestra Costo Standard): dependencias, logo y titulo
- Registrar ipfmrp005.4fd en el proyecto (form not found al abrir).
- Agregar dependencias faltantes FUNCIONESREPORT (msgrp000) para el
  papel/preview del reporte.
- selectOutput() no estaba definida en ningun modulo enlazable sin
  conflicto: la version de otrodir/vesalidaimpresora.4gl tiene una
  firma distinta (devuelve 3 valores) y la de otrodir/msgrp000.4gl
  choca con indir/defecto.4gl al traer ambas. Se extrajo a un archivo
  propio (otrodir/selectoutput_simple.4gl) la version de un solo
  valor de retorno que ya coincidia con lo que espera este programa,
  reutilizando el formulario "Configuration" ya existente.
- ipprrp005.4rp: la ruta del logo era absoluta a la maquina de
  produccion (E:\MARMOTECHC\IMAGENES\logo.png), no existia aqui -
  cambiada a ruta relativa (logo.png, ya esta en PROYECTO/bin).
- Se agrego titulo a la ventana (usaba el generico "screen").

Verificado con producto 29-668-1403-6952, año 2026: Material 3,512.42,
Labor 0.00, Gasto 0.00, Costo STD 3,512.42 - reporte bien formateado
(usa el .4rp original del programa, no uno reescrito). Cierre limpio.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 12:22:37 -04:00
jpegueroandClaude Sonnet 5 d1b29437c9 Reescribir ipprrp010 (Operacion Movimientos Detallado): .4rp equivocado
El .4rp que traia el repo (y su copia en el backup viejo) era en
realidad el reporte de "activos" de otro programa (RWFglReportName y
todo el cuerpo no correspondian a REPORT detalle(x)) - por eso nunca
pudo generar nada, ni siquiera despues de arreglar el crash original
de configureOutput().

- Se convirtio el REPORT detalle(x) de PRINT COLUMN clasico a PRINTX
  (siguiendo el patron de ipprrp005, que si funciona), y se escribio un
  .4rp nuevo desde cero con las variables correctas.
- Se quito el subtotal por "Orden" que la migracion habia agregado sin
  incluirlo en el ORDER BY (nunca funciono bien, no existia en 3.20).
- Se agrego titulo a la ventana (usaba el generico "screen").

Pendiente: el acomodo visual de columnas del reporte sale apilado en
vertical en vez de en fila - los datos y subtotales son correctos, pero
falta pulir el layout en el Report Designer (consultado con Johnny).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 12:22:25 -04:00
Abel LópezandClaude Sonnet 5 6ec15cfb3d Registra noprrp044 (Carnet Empleados) y corrige ruta de logo
Se agrega noprrp044 al proyecto usando nofmrp044.4fd, reutilizando
FUNCIONESREPORT y libgre.42x.

Se corrige ruta absoluta hardcodeada en noprrp044.4rp
(file:///F:/MARMOTECHC/BIN320/IMAGENES/marmotech.png, inexistente en
este equipo) por una ruta relativa a IMAGENES/Logo.png, ya presente
en el proyecto.

Probada impresion de carnet (frente y reverso) para un empleado con
foto, verificado contra BD.

Pendiente: la opcion "NO EMPLEADOS" (generacardnet, etiquetas
genericas) usa noprrp044_1.4rp, que no existe en el proyecto (solo
una version renombrada noprrp044_1_otros_ant.4rp de origen incierto).
Se deja sin resolver hasta confirmar con el usuario cual version usar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 16:39:15 -04:00
Abel LópezandClaude Sonnet 5 aeab10ce0d Registra noprrp039 (Reporte Empleados) y corrige bugs de SQL y fecha
Se agrega noprrp039 al proyecto usando nofmrp039.4fd, reutilizando
FUNCIONESREPORT y libgre.42x.

Se corrige "AND  and" duplicado (typo) en las 3 consultas dinamicas
del bloque tipoEmpleados=9 (TODOS los empleados), que producia un
error de sintaxis SQL y bloqueaba completamente esa opcion.

Se corrige CONVERT(CHAR,fech_efec,103) hacia variable DATE en las 5
consultas del programa, mismo patron de error -1205 "Invalid month
in date" ya visto en otros programas.

Se crea PROYECTO/bin/IMAGENES/EMPLEADOS (con .gitkeep), carpeta
faltante donde el programa exporta las fotos de empleados
(foto_empleado.writeFile); sin ella el reporte fallaba con error
-8087 al procesar cualquier empleado con foto guardada.

Probado con empleado especifico y con "TODOS" (activos+inactivos con
foto), verificado contra BD sobre departamento 1000.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 13:11:32 -04:00
Abel LópezandClaude Sonnet 5 0641c6b2be Registra noprrp003 (Herramientas de Empleados) y corrige bugs
Se agrega noprrp003 al proyecto usando nofmrp003.4fd, reutilizando
FUNCIONESREPORT y libgre.42x ya configurados para noprrp002.

Se corrige bug donde el combo "Departamento=TODOS" (valor NULL)
generaba via CONSTRUCT la condicion "e.departamento is null" en vez
de no filtrar, excluyendo a todos los empleados con departamento
asignado (confirmado con debug logging: solo empleados sin
departamento pasaban el filtro). Se agrega neutraliza_depto_null()
para neutralizar esa condicion especifica tras el CONSTRUCT.

Se corrige fila vacia sobrante al final del reporte (el FOREACH deja
un elemento extra en el arreglo dinamico; se agrega
inv.deleteElement(idx), igual que en noprrp002).

Probado con empleado especifico, todos los empleados y filtro por
departamento, verificado contra BD (94 registros totales, 12 para
CONTABILIDAD).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 12:09:57 -04:00
Abel LópezandClaude Sonnet 5 c7442a777b Corrige ancho insuficiente del campo Numero de Nomina en noprrp002
El campo num_nomi en nofmrp002.4fd solo permitia 6 caracteres, pero
existen numeros de nomina de 8 digitos en notb00010 (periodos
codificados como fecha, ej. 27032021). Se amplia a 9 caracteres.

Probado reporte con nomina 2118/Q (14 empleados en notb00008, de los
cuales 12 pertenecen realmente al periodo segun el rango de fechas;
los otros 2 son registros historicos de 2008/2015 con el mismo
numero de nomina por coincidencia de datos antiguos, correctamente
excluidos por el filtro de fecha del reporte).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 10:48:04 -04:00
Abel LópezandClaude Sonnet 5 7e2f99b50e Registra noprrp002 (Nomina de Pago) y corrige bugs de reporte PDF
Se agrega noprrp002 al proyecto usando nofmrp002.4fd, mas
vesalidaimpresora.4gl (selectOutput2) en la libreria compartida
FUNCIONESREPORT, y externalDependencies libgre.42x para el motor de
reportes.

Se corrige databaseName="marmotech" invalido en nofmrp002.4fd (schema
no registrado en el proyecto) por "smarmotech".

Se corrige bug de tipo de dato: r_output estaba declarado SMALLINT en
noprrp002.4gl, pero selectOutput2() devuelve un STRING ("PDF","SVG",
"XLSX"). Ese desajuste impedia que fgl_report_selectDevice recibiera
el dispositivo correcto, asi que elegir PDF no generaba un PDF real.
Se cambia r_output a STRING.

Probado reporte agrupado de nomina (vista previa en pantalla y
exportacion a PDF real), verificado contra BD sobre empleado 110,
periodo 2320/Q.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 10:09:33 -04:00
Abel LópezandClaude Sonnet 5 c1719d4b6e Registra noprcs006 (Consulta Balance Por Empleado)
Se agrega noprcs006 al proyecto usando nofmcs006.4fd, mas
FUNCIONESREPORT (seleccionarsalida.4gl) y externalDependencies
libgre.42x, requeridos para las funciones del motor de reportes
(fgl_report_loadCurrentSettings, etc) que usa la opcion Imprimir.

Probada consulta inicial, Ver (balance acumulado por movimiento) e
Imprimir (vista previa de reporte), verificado contra BD sobre
empleado 110, cod_mov=12 (PRESTAMO COOPMAR).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 10:36:47 -04:00
Abel LópezandClaude Sonnet 5 c296da0151 Registra noprcs004 (Consulta Acumulado por Empleado)
Se agrega noprcs004 al proyecto usando nofmcs004.4fd. Se agrega
addir/adfunciones.4gl al Application ya que el programa llama a
calcula_salarios() definida ahi (no en noprrp037.4gl, que tiene una
funcion del mismo nombre pero con firma incompatible/uso de
variables de otro programa).

Se corrige conversion CONVERT(CHAR,fech_efec,103) hacia variable DATE
en la consulta principal, mismo patron de error -1205 "Invalid month
in date" ya visto en otros programas.

Probada consulta principal (datos del empleado, fecha de entrada,
salario promedio diario) y Ver (acumulado por movimiento), verificado
contra BD sobre empleado 110.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 09:45:52 -04:00
Abel López 66a57b4b3c Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-25 16:46:21 -04:00
Abel LópezandClaude Sonnet 5 c141af53f2 Registra noprcs002 (Consulta Movimiento por Nomina)
Se agrega noprcs002 al proyecto usando nofmcs002.per. Es un programa
de solo consulta (sin INSERT/UPDATE/DELETE).

Probada busqueda inicial, Ver (detalle de movimientos de un periodo,
incluyendo scroll por teclado para ver mas de 4 filas) y navegacion
Siguiente sobre empleado 110, periodo 2320/Q. Monto Pagado verificado
contra SUM(valor) en BD.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 16:33:40 -04:00
Abel LópezandClaude Sonnet 5 750b9a6bcf Registra noprmt025 (Parametros ISR) y corrige tres bugs bloqueantes
Se agrega noprmt025 al proyecto usando nofmmt025.4fd (tiene los
campos monto_ars/monto_afp que faltan en el .per).

Se corrigen tres bugs que impedian usar el programa:
1. nopcmf023(): CONVERT(varchar,fecha,101) hacia variable DATE,
   mismo patron de error -1205 "Invalid month in date" ya visto en
   otros programas.
2. nopcad023(): la validacion de tipo_emp contra notb00010 usaba un
   SELECT sin INTO/cursor (singleton select), que exige exactamente
   una fila. notb00010 es la tabla de periodos de nomina (un registro
   por periodo), con cientos de filas por tipo_emp, asi que esta
   validacion fallaba siempre con error -284 "A subquery has returned
   not exactly one row", bloqueando por completo la opcion Nuevo. Se
   cambia a SELECT COUNT(*) INTO existe_tipo.
3. nofmmt025.4fd: el campo fecha (Edit widget, formonly) no tenia
   format="dd/mm/yyyy", causando que Genero interpretara la fecha
   tecleada con el formato de fecha por defecto del sistema en vez
   del formato dominicano, dando "Invalid month in date" al capturar
   un dia mayor a 12 como mes.

Probado ciclo completo: Nuevo, Buscar, Escoger y eLiminar sobre
parametro de prueba (numero_nomina=26).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 12:30:28 -04:00
Abel LópezandClaude Sonnet 5 303a722875 Registra noprmt024 (Maestra de Puestos) y corrige duplicado en Nuevo
Se agrega noprmt024 al proyecto usando nofmmt024.per.

Se corrige adpcad023(): tras un INSERT exitoso el codigo hacia NEXT
FIELD nom_puesto para permitir capturar otro puesto, pero sin limpiar
los campos del registro anterior. Combinado con el orden real de
tabulacion del formulario (nivel_sal/salario_min/salario_max quedan
antes que cod_puesto_sirla en el orden de atributos, aunque
visualmente aparecen despues), esto permitia disparar un segundo
INSERT accidental con datos incompletos/residuales del registro
previo. Se agrega CLEAR FORM y reset de los campos tras cada insercion
exitosa, igual que en los demas programas de Nuevo ya corregidos.

Probado ciclo completo: Nuevo (confirmado que ya no duplica),
Buscar, Escoger y eLiminar sobre puesto de prueba.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 11:48:21 -04:00
Abel LópezandClaude Sonnet 5 58909014ab Registra noprmt023 (Maestra de Departamentos) y corrige bug de MaintainX
Se agrega noprmt023 al proyecto usando nofmmt023.4fd. Este programa
conecta a dos bases (smarmotech y marmotech/EXTERIOR via Informix
legado) para sincronizar departamentos en ambas.

Se agrega environment FGLPROFILE al Application para que resuelva la
conexion dual via PROYECTO/config/fglprofile. Se corrige ese archivo:
dbi.database.smarmotech.source apuntaba a un DSN "marmotech250s" que
nunca se creo; se cambia al DSN real existente "marmotech18".

Se corrige eLiminar: llamaba a la API real de MaintainX (DELETE) con
solo validar que id_maintainx no fuera null, ignorando el checkbox
"Enviar a MaintainX" (apicheck). Ahora requiere ambas condiciones.

Probado ciclo completo (Adicionar, Buscar, Escoger, eLiminar,
Departamentos Relacionados) verificando sincronizacion entre
smarmotech y EXTERIOR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 10:11:49 -04:00
jpegueroandClaude Sonnet 5 3d43efa82f Revertir actualizacion de meta-esquema de smarmotech.sch/4db
La regeneracion via 'Update Meta-schema' del commit anterior perdio 239
tablas que si existian en el esquema anterior (algunas reales, como
departamentos y dgii_rnc, no solo staging temporal), probablemente por
la opcion 'Ignore errors' de la extraccion o por permisos/timeout contra
la base real. Riesgo de romper la compilacion de otros programas del
equipo sin necesidad, y de todas formas no resolvio el bloqueo de
ipprrp052 (columna iptb00002.categoria). Se revierte para no arriesgar
el trabajo de otros mientras se investiga la causa real con Johnny.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 16:21:54 -04:00
jpegueroandClaude Sonnet 5 ecf819671d Corregir ipprrp050 (Conteo Fisico) y actualizar meta-esquema de smarmotech
- Registrar ipfmrp050.4fd en el proyecto (form not found al abrir).
- Agregar dependencia faltante FUNCIONESREPORT a ipprrp050 (no linkeaba,
  llamaba seleccionarSalida() sin tener el modulo).
- Rescatar ipprrp050.4rp de un backup viejo (PROYECTOS/bin), no existia
  en el repo.

Verificado con producto 29-668-1403-6952, bodega ALMACEN PUNTA CANA:
existencia 308.00, coincide con la BD. Cierre limpio con Cancel (usa el
mismo patron DIALOG/ON ACTION que ipprrp052, sin el bug de cierre
colgado de ipprrp002/ipprrp002_1).

Nota aparte (sin corregir, igual que ipprrp052): cuentaitems() nunca se
llama (comentado), variable cuenta sin inicializar para la barra de
progreso - inofensivo pero es codigo muerto.

Ademas: actualizar DATABASE/smarmotech.4db, smarmotech.sch y
PROYECTO/smarmotech.sch desde la BD real (.40.250) via Update Meta-schema
de Genero Studio. Se hizo intentando resolver el bloqueo de ipprrp052
(columna iptb00002.categoria no reconocida por el compilador) - el
esquema ya trae la columna correcta pero el compilador sigue sin
reconocerla incluso tras Rebuild All completo; ipprrp052 sigue
bloqueado, pendiente que Johnny revise el paso de regeneracion del
diccionario que nos falta.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 16:21:16 -04:00
jpegueroandClaude Sonnet 5 1ea7f53344 Corregir ipprrp002_1 (Catalogo Productos Con Costos): cierre colgado y titulo
- ipprrp002_1.4gl: envolver el flujo de captura/reporte en un WHILE,
  mismo bug que ipprrp002 (el programa quedaba colgado tras generar el
  reporte y habia que forzar el cierre; ahora Cancelar cierra limpio y
  se puede volver a buscar sin cerrar el programa).
- ipfmrp002_1.4fd: agregar texto al <Form> ("CATALOGO PRODUCTOS CON
  COSTOS"), la ventana no tenia titulo y mostraba "screen" por defecto.

Verificado con producto 29-668-1403-6952 (1 pagina, existencia 360.00,
costo 3,512.42, precio 7,379.02, coincide con la BD) y con el catalogo
completo sin filtro (mismo volumen que ipprrp002, generacion correcta
aunque lenta por las consultas adicionales que hace por fila).

Nota aparte (sin corregir): los campos "Origen" y "Lista Precios" en
pantalla no estan en el INPUT BY NAME ni se usan en el query (que trae
siempre ventas='1' y cod_lista=1 hardcodeados) - no seleccionables,
funcionalidad a medio conectar igual que "Anio" en ipprcs042.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 12:10:43 -04:00
Abel López 899f4ee138 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-22 16:50:12 -04:00
Abel LópezandClaude Sonnet 5 37209b5009 Registra noprmt019 (Cambio de Departamento)
Se agrega noprmt019 al proyecto usando nofmmt019.per. Probado cambio
de departamento sobre empleado 110 (1000 -> 2100 -> 1000), verificado
que se propaga a adtb00003 y a los movimientos fijos en notb00003.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 13:38:15 -04:00
jpegueroandClaude Sonnet 5 c00ba4b920 Corregir ipprrp002 (Catalogo Productos Terminados) y registrar assets de ipprrp002_1/ipprrp052
- Rescatar de un backup viejo (PROYECTOS/bin) los .4rp que faltaban en el
  repo: ipprrp002.4rp, ipprrp002_1.4rp, ipprrp002_2.4rp e ipprrp052.4rp.
  Sin ellos el reporte nunca podia generarse (fgl_report_loadCurrentSettings
  fallaba y el programa hacia EXIT PROGRAM).
- Registrar en mbsERP.4pw los formularios ipfmrp002.4fd, ipfmrp002_1.4fd
  e ipfmrp052.4fd, y los .4rp anteriores: existian en el repo pero nunca
  se habian agregado al proyecto.
- ipprrp002.4gl: cambiar `cuenta` de SMALLINT a INTEGER, causaba
  "Value too large to fit in a SMALLINT" al generar el catalogo completo
  (43,796 productos sin filtro).
- ipprrp002.4gl: envolver el flujo de captura/reporte en un WHILE para
  permitir buscar de nuevo sin cerrar el programa, y para que Cancelar
  termine limpio (antes, al terminar de generar el reporte el programa
  quedaba colgado y habia que forzar el cierre).

Verificado con producto 29-668-1403-6952 (1 pagina, ciclo buscar-reporte-
cerrar limpio) y catalogo completo sin filtro (43,796 productos, 1093
paginas, generacion correcta).

Nota aparte (sin corregir): sin filtro de codigo el programa genera el
catalogo completo (43,796 productos) sin ninguna advertencia; evaluar si
deberia exigir un filtro minimo. Campo "Anio" en pantalla sin uso en el
codigo. ipprrp002_1 e ipprrp052 tienen sus assets registrados pero aun
no se han probado funcionalmente.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 12:58:06 -04:00
Abel LópezandClaude Sonnet 5 31fbc9a3b9 Registra noprmt018 (Pago Prest. en Efectivo) y corrige bug de fecha
Se agrega noprmt018 al proyecto usando nofmmt018.per.

Se corrige conversion CONVERT(CHAR,fecha,103) hacia variable DATE en
nopcmf018(), mismo patron de error -1205 "Invalid month in date"
encontrado en otros programas de nomina.

Probado ciclo completo: Adicionar, Consultar-modificar/Buscar,
Escoger y eLiminar sobre empleado 4124 (cod_mov=12).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 12:44:22 -04:00
jpeguero 7bda7659a6 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-21 17:03:01 -04:00
jpegueroandClaude Sonnet 5 e33dad06b8 Registrar formularios de ipprrp002/ipprrp002_1 (Catalogo Productos Terminados)
ipfmrp002.4fd e ipfmrp002_1.4fd existian en el repo pero nunca se habian
agregado a mbsERP.4pw, mismo patron visto en ipprcs004_1/ipprcs042.

Pendiente aparte: los reportes ipprrp002.4rp e ipprrp002_2.4rp (usados
por fgl_report_loadCurrentSettings) no existen en el repo ni en su
historial, el programa no puede completar la generacion del reporte
hasta que se consigan o se rehagan en Report Studio. Consultado con
Johnny, sin respuesta aun.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 17:01:21 -04:00
Abel López 12bb4e837b Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-21 16:56:47 -04:00
Abel LópezandClaude Sonnet 5 fc49b30714 Registra noprmt016 (Act./Desact. Empleado)
Se agrega noprmt016 al proyecto usando nofmmt016.per. Probado
Activar/Desactivar sobre empleado 110, verificado status_t en
adtb00003 en ambos sentidos.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 16:55:33 -04:00
jpegueroandClaude Sonnet 5 1647848fec Corregir ipprcs042 (Hoja Vida Producto): form no registrado y crash de fecha
- Registrar ipfmcs042.4fd en el proyecto, no estaba agregado a mbsERP.4pw
  y el runtime daba "Form file not found" al abrir el programa.
- Quitar CONVERT(CHAR(10),b.fech_oc,103) en la busqueda de ordenes de
  compra a proveedores, causaba "Invalid month in date" (-1205) igual
  que en mercancia_transito.4gl/funciones_ip.4gl.

Verificado con producto 1-119-2-56 (272 ordenes de compra 2008-2026):
grilla de proveedores, inventarios y precios cargan correctamente.

Nota aparte (sin corregir): los campos "Almacen" y "Rank" del formulario
existen mas nunca se usan en el codigo, no filtran nada.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 15:15:37 -04:00
jpegueroandClaude Sonnet 5 5f1c3b6e3b Corregir ipprcs004/ipprcs004_1 (Consulta Existencias): crashes al probar botones migrados
- mercancia_transito.4gl y funciones_ip.4gl: quitar CONVERT(...,103) al
  traer fechas de SQL Server, causaba "Invalid month in date" (-1205) en
  ambiente de pruebas por ambiguedad de formato dd/mm/yyyy vs mm/dd/yyyy.
- ipprcs004_1: agregar dependencia faltante FUNCIONES_PR (no linkeaba,
  llamaba mercancia_transito/fechas_llegadas sin tener el modulo).
- Registrar en el proyecto tres formularios que existian en el repo pero
  nunca se agregaron a mbsERP.4pw (ipfmwd017.4fd, almacenes.4fd,
  cofmfu009.4fd), causaban "Form file not found" en los botones
  Ordenes/Almacenes/Fecha Llegada.

Verificado botón por botón contra produccion (Genero 3.20, .40.8) con el
mismo codigo de producto: Foto, Ordenes, Reservados, Ubicacion, Almacenes
y Reporte (PDF/pantalla/Excel) dan resultados consistentes.

Pendiente aparte: el patron CONVERT(...,103) aparece en ~132 archivos del
proyecto, riesgo sistemico a evaluar por separado.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 12:56:39 -04:00
Abel LópezandClaude Sonnet 5 5baf191a88 Registra noprmt011 y corrige bugs de fecha y borrado de cuota compartida
Se agrega noprmt011 (Control Prestamos y Facturas) al proyecto usando
nofmmt011.4fd (nofmmt011.per no tenia el campo valor_cuota requerido).

Se corrige conversion CONVERT(CHAR,fecha,103) hacia variable DATE en
nopcmf011(), que causaba error -1205 "Invalid month in date" al
navegar con Siguiente/Anterior cuando el dia del mes era mayor a 12.

Se corrige eLiminar: el DELETE FROM notb00003 era incondicional y
borraba la cuota compartida del empleado+movimiento aunque quedaran
otros documentos activos en notb00011 dependiendo de ella. Ahora solo
se borra si no quedan documentos activos para ese empleado+movimiento.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 11:45:55 -04:00
Abel López 64f5e612d9 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-16 16:49:29 -04:00
Abel LópezandClaude Sonnet 5 7638c1046b Corregir noprmt008 (Generacion de Nomina): checkbox no aplicaba su
valor por defecto

El checkbox "GENERO NOMINA ACTIVOS" (opt1) y los demas checkboxes de
la pantalla inicial no entregaban su defaultValue a la variable si el
usuario no los tocaba explicitamente, quedando en "N". Como el codigo
hace "IF opt1 != 'S' THEN RETURN" sin ningun mensaje, el programa
generaba 0 registros y se cerraba en silencio pareciendo exitoso.

Se inicializan opt1/opt2/opt3/regalia/vacaciones explicitamente antes
del INPUT BY NAME para que coincidan con los defaults del formulario,
sin depender de esa interaccion.

Se retiro tambien la funcion debuglog() (y su entrada FGLSPOOL) usada
solo para diagnosticar este problema.

Verificado generando la nomina 2701/Q completa: 4798 registros para
628 empleados, con calculo correcto de sueldo quincenal (50% primera
quincena) y descuentos de TSS/ARS.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 12:16:53 -04:00
jsoto c52fce4cb8 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-15 12:15:37 -04:00
jpegueroandClaude Sonnet 5 5667c1e508 Registrar formularios y libreria nueva para ipprcs004
- Registrar ipfmcs004.4fd, coloca_ubicacion.4fd, ipfmcs004b.per e
  ipfmcs004_1.4fd (faltaban)
- Crear libreria UBICACIONDH_IP para ubicacionDH.4gl (funcion
  InsertaUbicacionDH), separada de FUNCIONES_IP porque su otra funcion
  buscardata() choca con la ya existente en ipprmt020.4gl
- Agregar dependencia de FUNCIONESREPORT a ipprcs004 (para
  seleccionarSalida, ya registrada ahi para ipprmt044)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 12:17:35 -04:00
jsoto 61195adc75 JSOTO Arreglo programa ipprmt005, quitando la conexion IFMX 2026-09-15 12:14:15 -04:00
jpegueroandClaude Sonnet 5 3d293561d2 Registrar formulario ipfmcs006.4fd para ipprcs006 (Consulta Balances)
Probado: filtros de busqueda (producto, bodega, rango de fechas) con
opcion "Actual" - resultados correctos comparados contra la BD.

Opcion "Historico" (consulta base separada historicomtech) confirmada
como bug preexistente: falla con "Invalid column name num_oc" tanto en
el ambiente de pruebas (se restauro un backup fresco de produccion del
40.8 para poder probar) como en produccion Genero 3.20 - la tabla
historicomtech.dbo.iptb00006 nunca tuvo la columna num_oc que si tiene
la tabla en vivo. No es un bug de la migracion, no se toca.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 16:15:26 -04:00
jpegueroandClaude Sonnet 5 d4eb103454 Registrar y corregir ipprcs002 (Consulta Maestra de Productos)
- Registrar formulario ipfmcs002.per (faltaba)
- Extraer la funcion pantalla() de ipmn00000.4gl (programa de menu con su
  propio MAIN) a un archivo compartido nuevo (otrodir/pantalla_ip.4gl)
  para poder reutilizarla sin conflicto de MAIN duplicado
- Bug corregido: el programa nunca tenia CONNECT TO, dependia de heredar
  una conexion de otro programa que nunca lo invoca en este contexto de
  prueba - se agrego ARG_VAL + CONNECT TO "smarmotech" como en el resto
  de los programas
- Bug corregido: el arreglo global "prod" (usado solo por este programa)
  era de tamaño fijo ARRAY[200], causaba error -1326 con mas de 200
  resultados - convertido a DYNAMIC ARRAY, y se agrego prod.clear() antes
  de repoblarlo
- Agregado titulo a la ventana (usaba "screen size" clasico sin TITLE)

Pendiente de decision de Johnny: la pantalla no exige ningun filtro de
busqueda y hace una consulta SQL adicional por cada producto encontrado
(calculo de existencia) - sin filtro intenta traer todo el catalogo y
tarda mas de una hora antes de fallar. Se probo exitosamente usando
siempre un codigo de producto completo (clase-grupo-tipo-secuencia).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 15:03:03 -04:00
jpegueroandClaude Sonnet 5 bb9d9a05a1 Corregir ipprmt017: columnas sin titulo, toolbar incompleto y checkbox Elimina
- Agregar titulo a columnas Unidad y Moneda, ocultar campo interno idrow
- Agregar a ToolBar1 los botones Busca Informacion, Limpia Screen,
  Conversion Moneda y Cancela operacion (estaban definidos como
  ActionDefault pero nunca agregados a la barra, por eso no se veian)
- Capturar el idrow generado al insertar un precio nuevo (antes quedaba
  NULL en memoria, rompiendo el eliminar de esa misma fila en la misma
  sesion)
- Corregir el checkbox "Elimina": el clic con mouse marcaba la casilla
  visualmente pero no actualizaba el valor real hasta perder el foco con
  Tab (bug de renderizado de GST). Se cambio el trigger de AFTER FIELD a
  ON CHANGE, que si sincroniza el valor de inmediato con clic de mouse

Pendiente: falta la prueba final completa del flujo eliminar en
ipprmt017 (se hizo hasta confirmar que ON CHANGE captura el valor
correctamente, falta probar el guardado + verificacion en BD)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 17:00:17 -04:00
jpegueroandClaude Sonnet 5 866778edfe Avanzar en registro y correccion de ipprmt017 (Precio por Cliente)
- Registrar ipfmmt017.4fd e ipfmwd008.per (faltaban)
- Corregir esquema viejo "marmotech" -> "smarmotech" en ipfmwd008.per
- Copiar vefmwd002.4fd a ipdir (renombrado vefmwd002_ip.4fd) para evitar
  depender de la libreria FORMULARIOS_PR (de Compras), que tiene errores
  propios sin relacion (prfmmt006.4fd con columna inexistente,
  prfmwd014.per con problema estructural) que bloqueaban la compilacion
- Corregir 3 columnas de la lista de precios sin titulo (idrow, unidadmed,
  moneda): idrow se oculta (es un campo interno), unidadmed y moneda
  reciben titulo visible

Pendiente: falta recompilar y probar el flujo completo (alta, consulta,
eliminacion) de ipprmt017.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 13:23:21 -04:00
jpegueroandClaude Sonnet 5 4ce1e7a03d Registrar y corregir ipprmt014 (Administracion Medidas)
- Registrar formulario ipfmmt014.per (faltaba)
- Corregir refresco de pantalla al eliminar (no mostraba estado 'E' hasta
  volver a consultar), confirmado por Johnny que debe verse al instante
- Agregar validacion para no permitir eliminar un registro ya eliminado
  (mostraba "REGISTRO ELIMINADO" de nuevo sin avisar)

Nota: el aviso de "ya eliminado" no sale centrado en pantalla - limitacion
del cliente grafico de Genero para dialogos lanzados desde pantallas tipo
MENU clasico (no aplica en pantallas DIALOG modernas). Aceptado por la
usuaria, no es bloqueante.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 12:28:56 -04:00
jpeguero f163516115 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-11 11:55:22 -04:00
jpegueroandClaude Sonnet 5 1ed4e0e691 Corregir ipprmt010: campos de usuario/fecha/estado enlazados a tabla equivocada
- El formulario ipfmmt010.per tenia los campos Usuario Creador/Modificador,
  Fecha Creacion/Modificacion y el indicador de estado enlazados a
  iptb00020 (tabla de Grupos, ajena a este programa) en vez de iptb00024
  (Tipos de Productos) - copiado por error del formulario de otro programa
- La consulta en ipprmt010.4gl tampoco seleccionaba esas columnas
- Al eliminar, el registro en memoria y la pantalla no se actualizaban con
  el nuevo estado, solo la base de datos

Confirmado por Johnny que el estado 'E' debe reflejarse en pantalla al
eliminar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 11:48:59 -04:00
jpegueroandClaude Sonnet 5 189c582eee Registrar formulario ipfmmt010.per para ipprmt010 (Tipos de Productos)
Probado completo: alta, consulta-modificacion y eliminacion (confirmado
en BD que status_t queda en 'E') - todo funciona correctamente.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 11:38:45 -04:00
jpegueroandClaude Sonnet 5 ecdd770632 Registrar formulario ipfmmt012.per para ipprmt012 (Administracion Grupos)
Probado completo: alta, consulta-modificacion y eliminacion - todo
funciona correctamente.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 10:29:39 -04:00
jpegueroandClaude Sonnet 5 7915a27efe Agregar mapeo de conexion marmotech -> EXTERIOR en fglprofile
Autorizado por Johnny Soto: crear DSN ODBC apuntando a la base EXTERIOR
para la segunda conexion legada de Informix usada en ipprmt064/ipprmt005.

Investigacion: la conexion aislada a EXTERIOR funciona correctamente,
pero abrir esta segunda conexion junto con la conexion activa a
smarmotech falla con error -6366 "Changed database context" del driver
dbmsnc de Genero. Se descarto: colision de nombre de DSN, pooling de
conexiones ODBC, y version del driver (probados ODBC Driver 18 y el
driver "SQL Server" legado) - mismo resultado en todos los casos.
Parece ser una limitacion del driver de Genero al manejar dos conexiones
simultaneas al mismo servidor SQL Server. Escalado a Johnny para abrir
caso con soporte de Four Js.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 10:05:22 -04:00
Abel López 79eff57d70 Merge branch 'main' of https://git.fulldetord.com/jsoto/mbs 2026-09-10 17:02:44 -04:00
Abel LópezandClaude Sonnet 5 9ac3f70a13 WIP: Agregar noprmt008 (Generacion de Nomina) - en diagnostico
- Registrar noprmt008 en mbsERP.4pw junto con sus 3 formularios
  (nofmmt008.4fd, nofmmt108.per, nofmmt208.per)
- Corregir bug en nofmmt008.4fd: el checkbox opt3 tenia colName="opt2"
  duplicado por error de copiar/pegar, causando "Field (opt3) not
  found in form"
- Quitar CONVERT(CHAR(10),...,103) en 5 SELECTs que alimentaban
  variables DATE (mismo patron de bug ya visto en noprmt003):
  causaba "-1205 Invalid month in date" de forma intermitente
- Agregar funcion debuglog() (escribe a archivo en FGLSPOOL) para
  diagnosticar por que la generacion terminaba sin insertar ningun
  registro; diagnostico aun en curso

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 17:02:39 -04:00
jpeguero 972f2f1f47 Registrar formularios y funciones faltantes para ipprmt005 y ipprmt013
- Registrar ipfmmt019.4fd (formulario real que usa ipprmt005.4gl)
- Migrar categorias.4gl desde PROYECTOS y registrarlo (usaba
  formonly.cod_cat, coincide con ipprmt005; la copia existente en
  PUNTO VENTAS VER2 usaba un nombre de campo distinto)

Pendiente: ipprmt005 (como ipprmt064) requiere una segunda conexion a una
base "marmotech" (alias IFMX) no mapeada en el ambiente, resto de la
epoca Informix. Consultado con Johnny como patron general.
2026-09-10 16:52:45 -04:00
jpeguero d43f2729bd Registrar y corregir ipprmt013 (Costos Estandares Producto Terminado)
- Registrar formulario ipfmmt013.4fd en el proyecto (faltaba)
- Corregir databaseName del formulario (marmotech -> smarmotech, esquema
  viejo que impedia resolver la tabla iptb00004)
- Agregar titulo de ventana (formulario no tenia atributo text, mostraba
  "screen" generico)
2026-09-10 16:42:48 -04:00
jpeguero 987c2c1122 Avanzar en registro y correccion de ipprmt044 (Productos Terminados)
- Registrar 8 archivos faltantes en FUNCIONES_IP (ipautorizareq, codigoModificacion,
  piking, conduces, ubicacionH, ipactualizareqtrx, loadDespiece, LlenarUbicaciones)
- Agregar dependencias FUNCIONESREPORT y FUNCIONESEMAIL a ipprmt044 (defecto,
  configureOutput, enviaemail ya existian en el proyecto)
- Resolver colision de nombres: renombrar REPORT/FUNCTION duplicados en
  ipautorizareq.4gl (requiere->requiereAutoriza, buscadoc->buscadocAutoriza,
  impdocumento->impdocumentoAutoriza) que chocaban con imprequisiciones.4gl
  y buscarequisicion.4gl
- Sincronizar registros locales desactualizados: x RECORD en ipautorizareq.4gl
  (faltaba us_crea) y x/z RECORD del REPORT formu4 en ipprgb000.4gl (faltaban
  bodega_destino, factura, area, descripcion_area, existencia, disponible,
  codigo_bloque, id_kit) respecto a los registros globales reales
- Migrar ipprmt020_1.4rp desde PROYECTOS y corregir su RWFglReportName

Pendiente: funcion 'fotos' (12 parametros) no existe en ningun archivo del
proyecto, consultado con Johnny
2026-09-10 14:15:49 -04:00
jpeguero e414e52523 Registrar y corregir ipprmt021 (Autorizaciones Requisiciones Almacenes)
- Registrar estadosprocesos.4gl y formulario ipfmmt021.4fd en el proyecto
- Corregir columna estado_proceso inexistente por idestado (error SQL -6372)
- Corregir desfase de columnas en SELECT/INTO de buscadoc() que dejaba
  usuario, bodega origen y tipo de movimiento vacios en el reporte impreso,
  y filtraba la descripcion del estado hacia el campo de observacion
2026-09-10 13:03:01 -04:00
jpeguero a3e88776a9 Registrar y corregir ipprmt020 (Requisiciones Productos Almacenes)
- Registrar funciones compartidas faltantes (buscarequisicion, imprequisiciones, funciones_ip) y formularios ipfmmt003/ipfmmt020 en el proyecto
- Agregar usuarioSistema a seg000.4gl
- Ampliar combos Codigo Mov/Bodega/Bodega Destino en ipfmmt020.4fd (texto ilegible)
- Refrescar lista de requisiciones al anular (buscarData + clear del arreglo)
2026-09-09 16:30:34 -04:00
jpeguero 9e70c46451 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-09-05 12:03:31 -04:00
jpegueroandClaude Sonnet 5 adf5224440 Agrega ipprmt003 (Productos Terminados) y actualiza esquema de BD
- Registra formulario ipfmmt003 en FORMULARIOS_IP con dependencia a
  Database
- Corrige dos bugs reales en ipprmt003.4gl: campo
  control_ubicacion_almacen duplicado en INPUT BY NAME (error -8090),
  y columnas control_produccion/control_ubicacion_almacen duplicadas
  en el INSERT INTO (error SQL -6372). Probado completo: alta,
  consulta, eliminacion, validacion de duplicados
- Actualiza DATABASE/smarmotech.4db con el esquema actual de SQL
  Server (agrega columnas nuevas de iptb00002 y otras tablas)
- ipprmt002 queda pendiente: 5 columnas de iptb00002 no son
  reconocidas por el compilador pese a existir en la BD real,
  requiere revision en vivo con Johnny

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 12:03:13 -04:00
Abel López 888a36553e Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-09-04 16:48:33 -04:00
Abel López 97ef961e13 Revert "Agregar noprmt020 al proyecto (identidad real pendiente de confirmar)"
This reverts commit 77e844390e.
2026-09-04 16:46:09 -04:00
Abel LópezandClaude Sonnet 5 77e844390e Agregar noprmt020 al proyecto (identidad real pendiente de confirmar)
- Registrar noprmt020 en mbsERP.4pw
- Agregar MAIN (faltaba, el archivo era solo funciones para ser
  llamadas desde el menu nomnmt000.4gl) y una funcion pantalla()
  local para el encabezado
- Corregir typo "database marmotech" -> "smarmotech" en nofmmt021.per

NOTA: el usuario identifico este programa como "Calcular Horas
Extras", pero tanto el contenido del .4gl como su propio menu
(nomnmt000.4gl: "19-Porc. Accidente Trabajo noprmt020") indican que
en realidad es la maestra de % de Accidente de Trabajo. Build y
compilacion verificados, prueba funcional pendiente hasta confirmar
el programa correcto para "Calcular Horas Extras" (candidatos:
noprmt030.4gl, noprmt038.4gl, o los reportes noprrp007/011/018/026/034/035).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 16:22:45 -04:00
Abel LópezandClaude Sonnet 5 81182e5ded Agregar noprmt007 (Novedades de la Nomina) al modulo NOMINA
Registrar noprmt007 en mbsERP.4pw usando nofmmt007.4fd (el .per
carece de departamento_afecta, num_trx, sueldo_act y los campos
titulo_dep_act/titulo_dep_afecta que usa el programa). El .4gl
compilo limpio sin cambios de codigo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 13:45:56 -04:00
Abel LópezandClaude Sonnet 5 60e392c033 Agregar noprmt001 (Codigos de Movimientos) al modulo NOMINA
- Registrar noprmt001 en mbsERP.4pw (usa cofmmt001... nofmmt001.4fd,
  el .per carece del grid smovimientos y los campos modifica/vacaciones)
- Reemplazar smarmotech.sch/.42d de nodir por la copia canonica ya
  generada en MBS/DATABASE (orden de columnas correcto, incluye
  telefonoCorporativo/numeroOficina/extension) en vez de regenerar

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 12:12:24 -04:00
jpegueroandClaude Sonnet 5 367f0c4340 Agrega los 34 programas de Productos Terminados al proyecto
Registra las Applications de Productos Terminados (ipprmt/ipprcs/ipprrp)
con dependencias a FUNCIONES_IP, Database y FUNCIONES, y agrega
ipprgb000.4gl como archivo compartido de FUNCIONES_IP. Listo para
compilar/probar programa por programa, igual que se hizo con Materia
Prima.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 09:39:19 -04:00
jpeguero 43aa1c809d Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-09-04 09:31:18 -04:00
jpegueroandClaude Sonnet 5 b6085d4140 Mueve ipdir (Productos Terminados) de PROYECTOS a PROYECTO
Instruccion de Johnny: todos los directorios de fuentes de inventario
deben migrarse de la carpeta temporal PROYECTOS a la carpeta real
PROYECTO, ya que PROYECTOS sera eliminada.

Se elimino tambien un archivo suelto sin relacion llamado "ipdir"
que existia en PROYECTO (del commit inicial) y bloqueaba el nombre
de la carpeta.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 09:29:01 -04:00
Abel López affc09c3e8 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-09-03 16:57:12 -04:00
jpegueroandClaude Sonnet 5 4532d51e4b Prueba inprrp011 (completo) e inprrp028 (matricial completo, PDF pendiente)
- Corrige selectOutput()/seleccionarSalida()/configureOutput() en
  defecto.4gl para usar la API real fgl_report_* (Report Writer 2.0),
  reemplazando los stubs previos. Reutiliza el formulario Configuration
  ya existente en el proyecto (FUNCIONESREPORT)
- inprrp011: quita el START REPORT forzado a XML roto (media migracion
  abandonada), probado completo: filtros, totales/subtotales vs
  produccion, exportacion PDF/Excel/Pantalla funcionando
- inprrp028: mismo patron, restaura Sietesalida) - No/matricial
  como respaldo. Crea bin/inprrp028.4rp (diseno de reporte, no existia)
  para la salida grafica; carga sin error de formato pero la
  generacion no completa en este entorno - pendiente de revisar
  rendimiento/recursos

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 16:52:39 -04:00
Abel LópezandClaude Sonnet 5 ee27da0669 Agregar noprmt003 (Maestra de Empleados) al modulo NOMINA
- Registrar noprmt003 en mbsERP.4pw (FUNCIONES_NO: noprfu000.4gl,
  nocarnet.4gl; FORMULARIOS_NO: nofmmt003.4fd); reutiliza
  otrodir/departamentos.4gl ya presente en FUNCIONES
- Actualizar el diccionario de esquema smarmotech.sch: faltaban las
  columnas telefonoCorporativo/numeroOficina/extension de adtb00003
  (existen en la BD real pero no estaban en el diccionario, .42d se
  regenera solo al recompilar); propagado a todos los directorios
- Desactivar el CONNECT TO "marmotech" AS "IFMX" (Informix ya no
  existe, todo migro a SQL Server) y el INSERT duplicado hacia esa
  conexion en el alta de empleados; sin esto el programa se colgaba
  al iniciar
- Quitar CONVERT(...,103) de fechas en el SELECT/FETCH de empleados:
  se convertian a texto dd/mm/yyyy y luego se reasignaban a variables
  DATE, causando "-1205 Invalid month in date" con dias > 12
- Agregar BEFORE CONSTRUCT/END CONSTRUCT para poblar el combo de
  Departamento en la busqueda (faltaba, quedaba vacio)
- Corregir foto de empleado que no se limpiaba al navegar
  Siguiente/Anterior hacia un empleado sin foto
- nocarnet.4gl: sustituir fgl_report_* (API no disponible) por
  om.XmlWriter.createFileWriter() hacia FGLSPOOL

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 16:51:11 -04:00
Abel LópezandClaude Sonnet 5 b27b20d42d Agregar noprmt002 (Movimientos Fijos Emp.) al modulo NOMINA
- Registrar noprmt002 en mbsERP.4pw junto con noprgb000.4gl
  (FUNCIONES_NO), nofmmt002.per/nofmwd001.per (FORMULARIOS_NO) y
  adfmwd004.per (FORMULARIOS_AD, compartido con ADMINISTRACION)
- Copiar el diccionario de esquema smarmotech.sch a nodir/addir
  (faltaba, igual que en otros directorios ya corregidos)
- Corregir typo "database marmotech" -> "smarmotech" en nofmwd001.per

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 12:12:06 -04:00
jsoto 382ec5cd35 JSOTO Se adiciono programa adprmt017 2026-09-03 10:12:37 -04:00
Abel López 4cb8d4c71b Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-09-01 16:48:54 -04:00
Abel LópezandClaude Sonnet 5 f216a7acfa Agregar coprrp007 (Cronologico de Requisiciones) al proyecto
- Registrar coprrp007 en mbsERP.4pw, usando cofmrp007.4fd (el .per
  no define el combo de departamento que requiere busca_departamento())
- Enlazar la libreria FUNCIONES_IN (ya contiene departamento.4gl) en
  vez de duplicar el archivo, evitando conflicto de salida .42m
- Agregar guarda NULL en departamento.4gl: ui.combobox.forname()
  puede no encontrar el combo durante el CONSTRUCT y causaba
  "Null pointer exception" al llamar .clear()
- Sustituir seleccionarsalida()/configureoutput() (no definidas,
  API fgl_report_* no disponible) por om.XmlWriter.createFileWriter()
  hacia FGLSPOOL

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 16:48:46 -04:00
jpegueroandClaude Sonnet 5 f140ab917e Agrega y corrige inprrp008, inprrp028, inprrp009 e inprrp011 (Materia Prima)
- inprrp008: agrega CONNECT faltante en MAIN, corrige ruta de impresion
  hardcodeada (C:\archivo -> FGLSPOOL) y comando RUN sin comillas,
  reconstruye infmrp008 como .4fd (el campo Ordenamiento se compilaba
  como checkbox en vez de texto)
- inprrp028: restaura la rama matricial (Si/No Reporte Grafico) que
  habia quedado comentada, dejando el programa forzado a la via XML
  rota; agrega funcion compartida seleccionarSalida() a defecto.4gl
- inprrp009: agrega notNull al combo de Bodega para quitar los items
  <blank>/<not blank>, agrega titulo a la ventana
- Registra formularios infmrp008, infmrp028 e infmrp011 en el proyecto
- Todos probados: corren completos sin error de FGL (Exit code: 0) via
  matricial; la salida grafica/PDF sigue siendo la limitacion conocida
  de entorno (Report Writer 2.0 no disponible)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-01 16:48:20 -04:00
jpeguero cda8053d90 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-31 16:46:34 -04:00
jpegueroandClaude Sonnet 5 7f789181cf Agrega inprrp003 e inprrp005 (reportes de Materia Prima) al proyecto
- Registra formularios infmrp003.per e infmrp005.per en FORMULARIOS_IN
- Agrega funciones compartidas msgrp000() y selectOutput() a defecto.4gl
  (selectOutput como stub, mismo limite conocido de Report Writer 2.0
  que configureOutput)
- inprrp003 probado: reporte de movimientos corre completo sin error
  de FGL (impresion fisica no disponible en entorno de desarrollo)
- inprrp005 pendiente: error SQL -1262 "Non-numeric character in
  datetime" al filtrar por Fecha del Dia, en investigacion

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 16:44:13 -04:00
Abel López 26961ddd81 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-31 16:43:06 -04:00
Abel LópezandClaude Sonnet 5 3284ae0de9 Agregar coprrp019 (Validacion Ordenes) al proyecto
- Registrar coprrp019 en mbsERP.4pw
- Agregar CONNECT TO/ARG_VAL faltante en MAIN (el programa hacia
  consultas SQL sin haberse conectado nunca a la base de datos)
- Sustituir seleccionarsalida()/configureoutput() (no definidas,
  API fgl_report_* no disponible) por om.XmlWriter.createFileWriter()
  hacia FGLSPOOL
- Corregir typo "database marmotech" -> "database smarmotech" en
  cofmrp019.per

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 16:42:59 -04:00
jpegueroandClaude Sonnet 5 ea1493db43 Prueba y corrige inprcs006 (Movimiento Materia Prima)
- Proyecto ahora referencia infmcs006.4fd en vez de .per (el .per
  clasico no puede declarar las columnas del Tree de filas hijas)
- Corrige conflicto de campo "bodega" entre INPUT y CONSTRUCT dentro
  del mismo DIALOG (error -8090), moviendo la busqueda a ON ACTION
- Corrige binding de ComboBox Bodega y campo mensaje_ini (faltaba
  colName/sqlTabName, causaba Null pointer exception)
- Agrega titulo "MOVIMIENTO MATERIA PRIMA" y ensancha combo de bodega
- Corrige tabIndex del combo de bodega para navegacion con teclado

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 12:21:46 -04:00
jpeguero 7b1b414629 Agrega formulario infmcs006 para inprcs006
Compilo correctamente; pendiente probar por caida del servidor
de base de datos (192.168.40.250).
2026-08-28 19:39:54 -04:00
jpeguero 0d17478789 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-28 19:22:35 -04:00
jpeguero 6f50812bb1 Completa Buscar Documentos en inprmt036 y agrega inprmt066
- inprfu000.4gl: corrige reimprime()/busca_info() para que branchen
  correctamente segun el programa llamante (inprmt046 vs otros).
  Antes usaban siempre las variables de inprmt046 (otros_mov),
  causando errores en inprmt036. Se activa y corrige la logica que
  estaba comentada para el caso generico (Johnny autorizo completarla,
  confirmado que tampoco funcionaba en produccion).
- inprmt066 (Anular Documentos): agrega formulario faltante y el
  campo Bodega (combo) que no existia. Ensancha el combo para
  legibilidad. Probado: anulacion de documento real, funciona.
2026-08-28 19:21:13 -04:00
Abel LópezandClaude Sonnet 5 052b80de34 Configurar FGLSPOOL en coprmt009 para que Imprime genere el reporte
El Application node de coprmt009 no tenia la variable de entorno
FGLSPOOL configurada (a diferencia de coprrp001/coprrp004/coprmt025).
FGL_GETENV("FGLSPOOL") devolvia NULL, el handler de XmlWriter en
orden() (coprorden.4gl) nunca se creaba, y "Imprime" fallaba
silenciosamente sin generar el reporte ni mostrar error.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 16:56:29 -04:00
Abel LópezandClaude Sonnet 5 cc4964af5e Merge remote-tracking branch 'origin/main'
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 16:48:38 -04:00
Abel LópezandClaude Sonnet 5 3df53ba483 Agregar coprrp004 (Cronologico de Ordenes) al proyecto
- Registrar coprrp004 (usando cofmrp004.4fd, el .per carece del
  campo estado) en mbsERP.4pw
- Sustituir seleccionarsalida()/configureoutput() (no definidas en
  este programa, misma API fgl_report_* no disponible) por
  om.XmlWriter.createFileWriter() hacia FGLSPOOL

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 16:48:04 -04:00
Abel LópezandClaude Sonnet 5 91eeef199e Corregir campo bodega oculto en busqueda de coprmt009
El CONSTRUCT del criterio de busqueda y un DISPLAY BY NAME en escoge()
referenciaban cotb00014.bodega/ordenes.bodega, que no existe como campo
visible en cofmmt009 (combo oculto, ya excluido en el INPUT BY NAME de
copcad009). Causaba "FORMS statement error -1102: Field (bodega) not
found in form" al usar Buscar Ordenes de Compras.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 16:06:50 -04:00
jpeguero f230a3002d Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-28 15:06:25 -04:00
jpeguero 817720127e Merge remote-tracking branch 'origin/main' 2026-08-28 14:21:56 -04:00
Abel LópezandClaude Sonnet 5 a37d0336b5 Agregar coprrp001 (Catalogo Suplidores) y corregir bugs en coprcs009
- Registrar coprrp001/cofmrp001 en mbsERP.4pw
- Sustituir API fgl_report_* no disponible por XmlWriter en coprrp001.4gl
- Ampliar cs_ordena.codigo a CHAR(20) en coprgb000.4gl
- Corregir mascaras PICTURE de codigo en coprcs009.4gl
- Ampliar campo c1 en cofmcs009.per para igualar el ancho de codigo
- Corregir typo de base de datos en cofmwd016.per

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 11:38:43 -04:00
jsoto c4169453ce Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-28 08:48:12 -04:00
jsoto 7f975157a5 JSOTO adicione --build-rdd al coprmt004 y el libgre.42x al programa coprmt009 2026-08-28 08:46:49 -04:00
jpeguero 69b4500eed Corrige inprmt046, agrega inprmt036 y arreglos de fecha/impresion
- inprmt046: agrega columnas Maquina/Clasf.Bloque faltantes en la
  tabla, ensancha combos para legibilidad, corrige formato de fecha
  (CONVERT 103 requiere DBDATE=DMY4/ configurado). Saca la funcion
  maquinaria() de un archivo local a una compartida (maquinaria.4gl)
  para evitar duplicado.
- inprmt036 (Requisicion de Materiales): agrega formulario, campo
  Impresion (MATRICIAL/PDF), corrige nombre_d y agrega columna
  Existencia faltante en la tabla.
- Agrega funcion compartida configureOutput (stub, Report Writer 2.0
  no disponible en FGL 6.00.01).
- Requiere variables de entorno DBDATE=DMY4/ y FGLSPOOL (carpeta
  PROYECTO/spool) al abrir Genero Studio para reportes/fechas.
2026-08-27 16:57:10 -04:00
Abel López b7877d7c07 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-27 16:19:01 -04:00
Abel LópezandClaude Sonnet 5 b05e858ac6 Añadir coprmt010, coprmt015, coprmt016, coprmt025 y coprcs005 (modulo COMPRAS)
- coprmt010 (Paises): corregir condicion invertida en "Escoger" que
  bloqueaba editar registros activos y solo permitia editar los ya
  eliminados (status_t != "E" -> = "E").
- coprmt016 (Terminos de Pago): usar el formulario .4fd (el .per no tenia
  el grid "Tabla" que el codigo espera); agregar columna "dias" faltante
  al INSERT (la tabla real tiene 9 columnas, el INSERT solo daba 8 valores
  sin lista de columnas explicita).
- coprmt025 (Requisicion Compras): agregar funciones faltantes
  (busca_departamento2 en depto.4gl, enviaemail en FUNCIONESEMAIL);
  sincronizar el RECORD "data" y la aridad de RETURNING de ApiMaintainC
  con el fix de api_test.4gl; reemplazar fgl_report_* (no disponible) por
  om.XmlWriter en las 3 rutas de impresion.
- coprmt015 y coprcs005: sin cambios de codigo, solo registro en el
  proyecto.
- mbsERP.4pw: registrar los 5 programas; investigar/configurar Java para
  coprmt025 (FGLJVMPATH/JAVA_HOME/CLASSPATH apuntando a un JRE Temurin
  8u504 local). Pendiente: el puente Java de esta instalacion de Genero
  sigue fallando ("Can not create java VM") incluso con el ejemplo oficial
  de FGL: parece un problema de la instalacion misma, no de version de
  Java. Se sugirio reparar via MsiExec /f {3B1E10F3-FBCC-4737-8BDF-284359029D70}
  (Four Js Genero BDL with Web Services 6.00.02), pendiente de ejecutar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 16:18:51 -04:00
jsoto 33f477778e Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-27 16:05:45 -04:00
jsoto c0f6b23e19 JSOTO adicione la CLASSPATH java al grupo COMUNES 2026-08-27 16:04:05 -04:00
jpeguero 7b6cb1e111 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-26 13:35:09 -04:00
jpeguero efdf8953dd Reorganiza MATERIA PRIMA a PROYECTO y avanza inprmt002/005/013/046
- Mueve todo el contenido de PROYECTOS/indir y varias funciones
  compartidas de PROYECTOS/otrodir hacia PROYECTO, siguiendo
  instruccion de Johnny (PROYECTOS se va a eliminar).
- inprmt002: agrega campo Desglose faltante, corrige typo "eLiminar".
- inprmt005: agrega formulario y 3 campos faltantes (Consumo,
  Requiere Autorizacion, Requisiciones), corrige typo "eLiminar".
- inprmt013: agrega formulario, titulo, corrige typo "eLiminar".
- inprmt046: agrega formulario y varias funciones/dependencias
  faltantes (cincodmov, clasf_bloque, medidas, defecto,
  buscaEmp, consultaTransportista, busca_departamento);
  corrige nombres de campo desalineados con el codigo
  (depto_a, bodega) y los convierte a ComboBox donde el
  codigo lo requiere.
- Corrige dependencia faltante de FORMULARIOS_IN a la libreria
  Database (bloqueaba todo el modulo de MATERIA PRIMA).
2026-08-26 13:31:09 -04:00
jsoto 9a8c922af3 JSOTO adicion del folder Dashboard 2026-08-26 08:45:20 -04:00
jsoto 45e559c05c JSOTO removi un smarmotech.sch que estaba en otrodir 2026-08-26 08:43:15 -04:00
Abel López 43d5a218e7 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-25 16:59:08 -04:00
Abel LópezandClaude Sonnet 5 acacf34eea Añadir modulo COMPRAS (coprmt001, coprmt009, coprmt016)
- coprmt001 (Suplidores): agregar campos faltantes (tipo_doc,rnc,cuenta_no)
  al RECORD interno de ApiMaintainC() en api_test.4gl, y unificar la
  aridad de RETURNING en las 3 llamadas (POST/PATCH/DELETE) - el
  enlazador exige el mismo numero de valores de retorno en todo el modulo.
- coprmt009 (Ordenes de Compra): reemplazar fgl_report_loadCurrentSettings/
  selectDevice/selectPreview/commitCurrentSettings (no disponibles en este
  FGL) por om.XmlWriter.createFileWriter en coprorden.4gl; agregar
  verificacion defensiva en lugarentrega.4gl (ui.combobox.forname puede
  devolver NULL si el formulario actual no tiene el combo "bodega"); quitar
  "ordenes.bodega" de los INPUT BY NAME (campo oculto, no se puede enlazar).
  Pendiente: probar el flujo completo de creacion de orden (se corto por
  una caida de conexion transitoria durante la prueba).
- coprmt016 (Terminos de Pago): CRUD simple, sin cambios de codigo.
- mbsERP.4pw: crear modulo COMPRAS (estaba vacio) con librerias
  FUNCIONES_CO y FORMULARIOS_CO, y registrar los 3 programas.
- otrodir/smarmotech.sch: diccionario de esquema completo (antes faltaba
  en este directorio, causaba fallos de link en api_test.4gl).
- .gitignore: excluir logs de STARTLOG() (bin/*.TXT) y archivos .err de
  compilacion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 16:58:59 -04:00
jsoto 5fa61ead23 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-25 16:48:40 -04:00
jsoto ca75ed204c Sync cambios recientes 3.20 -> migracion (10 programas) 2026-08-25 16:35:02 -04:00
jpeguero 4bb2df1630 Agrega los 13 programas de MATERIA PRIMA al proyecto
Todos quedan bloqueados por un error de diccionario de base de datos
(Can not open Database dictionary 'smarmotech' / tabla no encontrada
entre las especificadas), confirmado en inprmt002 e inprmt005 pese a
actualizar el diccionario (Update from database). Reportado a Johnny.
2026-08-25 13:32:55 -04:00
jpeguero 8e9619ae77 Merge remote-tracking branch 'origin/main' 2026-08-25 12:27:20 -04:00
jpeguero 18cf673753 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2026-08-25 12:26:42 -04:00
jpeguero 9ce99926e1 Corrige prprrp116 (reporte STATUS ORDENES PEDIDOS) y agrega modulo MATERIA PRIMA
- prprrp116: agrega form faltante, corrige encabezado del reporte
  (p_compania.nombre), evita crash cuando no hay registros, agrega
  opcion EXCEL en Visualizacion, quita filtros <blank>/<not blank>
  del combo Status Orden.
- prprcs001: corrige CONSTRUCT con columna inexistente (fecha_oc).
- prprmt022: quita filtros <blank>/<not blank> del combo Estado.
- Agrega los 13 programas de MATERIA PRIMA al proyecto (mbsERP.4pw).
2026-08-25 12:21:24 -04:00
Abel López 347e8139fc Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-25 11:49:06 -04:00
Abel LópezandClaude Sonnet 5 46d9dd4f5d Añadir cpprrp011 y cpprrp017; corregir bugs de migracion Informix->SQL Server
- cpprrp011: agregar INTO explicito a SELECT de validacion de referencia
  duplicada, y lineas de diagnostico temporales (pendiente: el campo ref
  sigue llegando NULL al INSERT en cgtb00004, falta investigar mas).
- cpprrp017: agregar bloque MAIN faltante, quitar CALL PANTALLA() redundante,
  cambiar rutas hardcodeadas C:\archivo y %USPRINT% (sin permisos/no
  definida) por FGLSPOOL, y reemplazar a.rowid (pseudo-columna de Informix
  inexistente en SQL Server) por ROW_NUMBER() OVER(...).
- cpfmrp017.per: corregir typo "database marmotech" -> "database smarmotech"
  que rompia la resolucion del esquema.
- mbsERP.4pw: registrar cpprrp011 y cpprrp017 con sus dependencias y
  configuracion de prueba.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 11:48:57 -04:00
jsoto 30c19630e9 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-25 11:33:31 -04:00
jsoto 88b994fa17 JSOTO ADICIONE EL GRUPO COMPRAS 2026-08-25 11:33:18 -04:00
Luis f13b57e592 probe los programas veprmt102 y veprmt025 ,Luis Soto 2026-08-25 07:15:50 -04:00
jsoto a7a8b9010d JSOTO GAR 2026-08-24 19:45:31 -04:00
jsoto 10e4565b8d Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-24 19:35:46 -04:00
jsoto 8c49a9a9de JSOTO Adicione el GAR para poder generar el file y desplegarlo en el server 2026-08-24 19:34:04 -04:00
Abel LópezandClaude Sonnet 5 fa1b51c33e Añadir cpprrp002, cpprrp003 y cpprrp004; corregir reportes XML y formulario cpfmrp002
- cpprgb000/msgrp000: restaurar getPreviewDevice con case correcto
  (ui.Interface.frontCall) y dejar configureOutput como stub, ya que la
  API fgl_report_* no existe en este FGL 6.00.01.
- cpprrp002/003/004: sustituir configureoutput()/handler roto por
  om.XmlWriter.createFileWriter escribiendo a FGLSPOOL, usando STRING
  para la ruta (CHAR(80) truncaba la ruta larga del proyecto).
- cpfmrp002.per: agregar campo faltante "Salida" (r_output) que el
  programa ya esperaba.
- mbsERP.4pw: registrar cpprrp002/003/004 con sus dependencias,
  entorno FGLSPOOL y configuracion de prueba.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 17:04:18 -04:00
jpeguero fd01d27119 Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS 2026-08-24 17:00:07 -04:00
jpeguero 68b73cfd54 Jeilyn Peguero: desbloquea y agrega programas de PRODUCCION 2026-08-24 16:56:59 -04:00
1538 changed files with 137312 additions and 271804 deletions
+20
View File
@@ -33,6 +33,7 @@ mydatabase.db
# ── Logs de ejecución ──
*.log
*.err
# ── Spool de reportes (salida temporal de impresión) ──
PROYECTO/spool/
@@ -47,3 +48,22 @@ desktop.ini
# NOTA: se CONSERVAN en el repo -> *.4gl *.per *.4fd *.4pw *.4st *.4ad
# *.sch *.4db (esquema), imagenes (*.png *.jpg), README, docs.
# -- Paquetes GAR: se generan en el build (gsmake -t mbs mbsERP.4pw), no van al repo --
*.gar
# -- PROYECTO/bin: no se versiona (compilados, imagenes, ejecutables, datos de ejecucion) --
# salvo los disenos de reporte .4rp, que son fuentes registradas en mbsERP.4pw.
PROYECTO/bin/**
!PROYECTO/bin/**/
!PROYECTO/bin/**/*.4rp
# -- Llaves y certificados: NUNCA en el repo (se entregan aparte a quien los necesite) --
*.jks
*.keystore
*.p12
*.pfx
*.pem
*.key
*.crt
*.cer
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,561 @@
<title>Radiografía Marmotech</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap">
<style>
:root{
--bg:#f2efe9; --surface:#fbfaf7; --surface-2:#f5f2ea;
--ink:#231f18; --muted:#726c60; --faint:#9a9284;
--line:#e4dfd4; --line-2:#efe9dd;
--accent:#9a6a2b; --accent-soft:#e9dcc4;
--pos:#2f7d57; --neg:#b3402a; --warn:#b1832a;
--grid:#eae4d8;
--shadow:0 1px 2px rgba(40,33,20,.05),0 8px 24px -12px rgba(40,33,20,.14);
--radius:14px;
}
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
--bg:#17150f; --surface:#211e16; --surface-2:#26221a;
--ink:#ece6da; --muted:#a69d8c; --faint:#7c7361;
--line:#332e24; --line-2:#2b271e;
--accent:#cd9c56; --accent-soft:#3a3020;
--pos:#4fb07f; --neg:#e0674e; --warn:#d5a34a;
--grid:#2a261d;
--shadow:0 1px 2px rgba(0,0,0,.4),0 10px 30px -14px rgba(0,0,0,.6);
}
}
:root[data-theme="dark"]{
--bg:#17150f; --surface:#211e16; --surface-2:#26221a;
--ink:#ece6da; --muted:#a69d8c; --faint:#7c7361;
--line:#332e24; --line-2:#2b271e;
--accent:#cd9c56; --accent-soft:#3a3020;
--pos:#4fb07f; --neg:#e0674e; --warn:#d5a34a;
--grid:#2a261d;
--shadow:0 1px 2px rgba(0,0,0,.4),0 10px 30px -14px rgba(0,0,0,.6);
}
*{box-sizing:border-box}
html,body{margin:0}
body{
background:var(--bg); color:var(--ink);
font-family:"IBM Plex Sans",system-ui,sans-serif;
font-size:15px; line-height:1.5;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1220px; margin:0 auto; padding:22px 20px 60px}
.num{font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1}
/* Header */
header.top{display:flex; align-items:flex-end; justify-content:space-between; gap:20px; flex-wrap:wrap; margin-bottom:6px}
.brand{display:flex; align-items:center; gap:14px}
.mark{width:44px; height:44px; flex:0 0 auto}
.brand h1{font-family:"Fraunces",serif; font-weight:600; font-size:26px; letter-spacing:-.01em; margin:0; line-height:1.05}
.brand .sub{color:var(--muted); font-size:12.5px; letter-spacing:.14em; text-transform:uppercase; margin-top:3px}
.period{text-align:right}
.period .lbl{font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--faint)}
.period .val{font-family:"Fraunces",serif; font-size:19px; font-weight:500}
.period .note{font-size:11.5px; color:var(--muted)}
.rule{height:1px; background:linear-gradient(90deg,var(--accent),var(--line) 60%,transparent); margin:16px 0 18px; opacity:.7}
/* Tabs */
nav.tabs{display:flex; gap:4px; margin-bottom:20px; border-bottom:1px solid var(--line); flex-wrap:wrap}
nav.tabs button{
appearance:none; border:0; background:none; cursor:pointer; color:var(--muted);
font-family:inherit; font-size:14px; font-weight:500; padding:10px 15px; border-radius:8px 8px 0 0;
border-bottom:2px solid transparent; margin-bottom:-1px; display:flex; align-items:center; gap:8px;
}
nav.tabs button .idx{font-family:"IBM Plex Mono",monospace; font-size:11px; color:var(--faint)}
nav.tabs button:hover{color:var(--ink); background:var(--surface-2)}
nav.tabs button[aria-selected="true"]{color:var(--ink); border-bottom-color:var(--accent)}
nav.tabs button[aria-selected="true"] .idx{color:var(--accent)}
:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.page{display:none; animation:fade .35s ease}
.page.active{display:block}
@keyframes fade{from{opacity:0; transform:translateY(4px)}to{opacity:1; transform:none}}
@media (prefers-reduced-motion:reduce){.page,.page.active{animation:none}}
/* Cards & grid */
.grid{display:grid; gap:14px}
.kpis{grid-template-columns:repeat(4,1fr)}
.card{background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow); padding:16px 17px}
.card h3{margin:0 0 2px; font-size:11.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--muted); font-weight:600}
.card .cap{font-size:11.5px; color:var(--faint); margin:0 0 12px}
.kpi .k-val{font-family:"Fraunces",serif; font-weight:600; font-size:29px; letter-spacing:-.01em; line-height:1.05; margin-top:6px}
.kpi .k-val small{font-size:14px; color:var(--muted); font-weight:500; font-family:"IBM Plex Sans"}
.kpi .k-sub{display:flex; align-items:center; gap:8px; margin-top:9px; font-size:12.5px; color:var(--muted)}
.delta{display:inline-flex; align-items:center; gap:4px; font-weight:600; font-variant-numeric:tabular-nums; padding:2px 7px; border-radius:20px; font-size:12px}
.delta.up{color:var(--pos); background:color-mix(in srgb,var(--pos) 12%,transparent)}
.delta.down{color:var(--neg); background:color-mix(in srgb,var(--neg) 12%,transparent)}
.delta.flat{color:var(--warn); background:color-mix(in srgb,var(--warn) 12%,transparent)}
.accent-bar{height:3px; border-radius:3px; background:var(--accent); opacity:.9; margin:-16px -17px 14px; border-radius:var(--radius) var(--radius) 0 0}
.row{display:grid; gap:14px; margin-top:14px}
.r-8-4{grid-template-columns:1.9fr 1.1fr}
.r-6-6{grid-template-columns:1fr 1fr}
.r-7-5{grid-template-columns:1.4fr 1fr}
/* Chart bits */
svg{display:block; width:100%; height:auto; overflow:visible}
.lgd{display:flex; gap:16px; flex-wrap:wrap; font-size:12px; color:var(--muted); margin-top:10px}
.lgd span{display:inline-flex; align-items:center; gap:6px}
.dot{width:10px; height:10px; border-radius:3px; display:inline-block}
table.tbl{width:100%; border-collapse:collapse; font-size:13px}
table.tbl th{text-align:left; font-size:11px; letter-spacing:.08em; text-transform:uppercase; color:var(--faint); font-weight:600; padding:7px 8px; border-bottom:1px solid var(--line)}
table.tbl td{padding:8px; border-bottom:1px solid var(--line-2); font-variant-numeric:tabular-nums}
table.tbl td.r,table.tbl th.r{text-align:right}
table.tbl tr:last-child td{border-bottom:0}
.barcell{position:relative}
.barcell .fill{position:absolute; left:0; top:50%; transform:translateY(-50%); height:60%; border-radius:3px; background:var(--accent-soft)}
.barcell span{position:relative}
.ratio{display:flex; align-items:baseline; gap:10px}
.ratio .big{font-family:"Fraunces",serif; font-weight:600; font-size:34px; letter-spacing:-.02em}
.foot{color:var(--muted); font-size:12px; margin-top:26px; border-top:1px solid var(--line); padding-top:14px}
.foot code{font-family:"IBM Plex Mono",monospace; font-size:11.5px; background:var(--surface-2); padding:1px 5px; border-radius:4px}
.pill{font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--accent); background:var(--accent-soft); padding:3px 8px; border-radius:20px; font-weight:600}
@media(max-width:880px){
.kpis{grid-template-columns:repeat(2,1fr)}
.r-8-4,.r-6-6,.r-7-5{grid-template-columns:1fr}
}
</style>
<div class="wrap">
<header class="top">
<div class="brand">
<svg class="mark" viewBox="0 0 44 44" aria-hidden="true">
<rect x="1" y="1" width="42" height="42" rx="9" fill="none" stroke="var(--accent)" stroke-width="1.5"/>
<path d="M8 30 L17 15 L23 24 L29 12 L36 30 Z" fill="none" stroke="var(--accent)" stroke-width="1.6" stroke-linejoin="round"/>
<path d="M8 33 L36 33" stroke="var(--accent)" stroke-width="1.6"/>
<circle cx="29" cy="12" r="1.8" fill="var(--accent)"/>
</svg>
<div>
<h1>Radiografía de la Empresa</h1>
<div class="sub">Marmotech, S.A. &middot; Cuadro de Mando de Presidencia</div>
</div>
</div>
<div class="period">
<div class="lbl">Periodo</div>
<div class="val num">Enero – Julio 2026</div>
<div class="note">acumulado del año · comparado vs. 2025</div>
</div>
</header>
<div class="rule"></div>
<nav class="tabs" role="tablist">
<button role="tab" aria-selected="true" data-p="p1"><span class="idx">01</span> Radiografía</button>
<button role="tab" aria-selected="false" data-p="p2"><span class="idx">02</span> Análisis de Gastos</button>
<button role="tab" aria-selected="false" data-p="p3"><span class="idx">03</span> Estructura Financiera</button>
</nav>
<!-- ============ PÁGINA 1 ============ -->
<section class="page active" id="p1" role="tabpanel">
<div class="grid kpis">
<div class="card kpi"><div class="accent-bar"></div>
<h3>Ventas Netas</h3>
<div class="k-val num">RD$ 1,375.3<small> M</small></div>
<div class="k-sub"><span class="delta down">▼ 1.3%</span> vs. 1,393.1 M (2025)</div>
</div>
<div class="card kpi">
<h3>Utilidad Bruta</h3>
<div class="k-val num">RD$ 706.9<small> M</small></div>
<div class="k-sub"><span class="delta down">▼ 1.4 pp</span> margen 51.4% <span style="color:var(--faint)">(52.8%)</span></div>
</div>
<div class="card kpi">
<h3>Utilidad Operativa</h3>
<div class="k-val num">RD$ 292.1<small> M</small></div>
<div class="k-sub"><span class="delta flat">21.2%</span> margen operativo</div>
</div>
<div class="card kpi"><div class="accent-bar"></div>
<h3>Utilidad Neta</h3>
<div class="k-val num">RD$ 219.6<small> M</small></div>
<div class="k-sub"><span class="delta down">▼ 21.4%</span> margen 16.0% <span style="color:var(--faint)">(20.1%)</span></div>
</div>
</div>
<div class="row r-7-5">
<div class="card">
<h3>Estado de Resultados — Cascada</h3>
<p class="cap">De ventas a utilidad neta · acumulado 2026 (RD$ millones)</p>
<svg id="waterfall" viewBox="0 0 720 300" role="img" aria-label="Cascada del estado de resultados"></svg>
</div>
<div class="card">
<h3>Composición de cada RD$ vendido</h3>
<p class="cap">Estructura del peso de ventas · 2026</p>
<svg id="composition" viewBox="0 0 360 300" role="img" aria-label="Composición de ventas"></svg>
</div>
</div>
<div class="row r-7-5">
<div class="card">
<h3>Comportamiento del periodo actual</h3>
<p class="cap">Ventas netas (barras) y utilidad neta (línea) por mes · 2026</p>
<svg id="trend" viewBox="0 0 720 280" role="img" aria-label="Tendencia mensual 2026"></svg>
<div class="lgd">
<span><i class="dot" style="background:var(--accent-soft)"></i> Ventas netas</span>
<span><i class="dot" style="background:var(--accent)"></i> Utilidad neta</span>
<span><i class="dot" style="background:var(--pos)"></i> Margen neto %</span>
</div>
</div>
<div class="card">
<h3>Trayectoria anual</h3>
<p class="cap">Ventas y utilidad neta por año (RD$ M) · 2026 parcial</p>
<svg id="annual" viewBox="0 0 360 280" role="img" aria-label="Comparativo anual"></svg>
</div>
</div>
</section>
<!-- ============ PÁGINA 2 ============ -->
<section class="page" id="p2" role="tabpanel">
<div class="grid kpis">
<div class="card kpi"><div class="accent-bar"></div>
<h3>Gastos Operativos</h3>
<div class="k-val num">RD$ 414.7<small> M</small></div>
<div class="k-sub"><span class="delta down">▲ 7.1%</span> vs. 387.2 M (2025)</div>
</div>
<div class="card kpi">
<h3>Gasto / Ventas</h3>
<div class="k-val num">30.2<small> %</small></div>
<div class="k-sub"><span class="delta down">▲ 2.4 pp</span> vs. 27.8% (2025)</div>
</div>
<div class="card kpi">
<h3>Gerencia mayor peso</h3>
<div class="k-val" style="font-size:22px">Ventas y Mercadeo</div>
<div class="k-sub num">RD$ 184.5 M · 44% del gasto</div>
</div>
<div class="card kpi">
<h3>Mayor alza YoY</h3>
<div class="k-val" style="font-size:22px">Admin. y Materiales</div>
<div class="k-sub num"><span class="delta down">▲ 13.3%</span> +12.3 M</div>
</div>
</div>
<div class="row r-6-6">
<div class="card">
<h3>Gasto por gerencia</h3>
<p class="cap">2026 vs. 2025 · acumulado ene–jul (RD$ M)</p>
<svg id="ger" viewBox="0 0 380 300" role="img" aria-label="Gasto por gerencia"></svg>
<div class="lgd">
<span><i class="dot" style="background:var(--accent)"></i> 2026</span>
<span><i class="dot" style="background:var(--accent-soft)"></i> 2025</span>
</div>
</div>
<div class="card">
<h3>Naturaleza del gasto</h3>
<p class="cap">Por subgrupo contable · 2026 (RD$ M)</p>
<table class="tbl">
<thead><tr><th>Subgrupo</th><th class="r">Monto</th><th class="r">% ventas</th></tr></thead>
<tbody id="subg"></tbody>
</table>
<p class="cap" style="margin-top:12px">El subgrupo <b>76 Cierre de gastos de fabricación</b> (−325.7 M) es una absorción a costo; reduce el gasto neto operativo.</p>
</div>
</div>
<div class="row">
<div class="card">
<h3>Gasto mensual — control de eficiencia</h3>
<p class="cap">Gasto operativo por mes y su relación con las ventas · 2026</p>
<svg id="gtrend" viewBox="0 0 720 250" role="img" aria-label="Gasto mensual"></svg>
</div>
</div>
</section>
<!-- ============ PÁGINA 3 ============ -->
<section class="page" id="p3" role="tabpanel">
<div class="grid kpis">
<div class="card kpi"><div class="accent-bar"></div>
<h3>Activos Totales</h3>
<div class="k-val num">RD$ 6,435<small> M</small></div>
<div class="k-sub">al 31-jul-2026</div>
</div>
<div class="card kpi">
<h3>Razón Corriente</h3>
<div class="k-val num">2.29<small> ×</small></div>
<div class="k-sub"><span class="delta up">sólida</span> activo cte. 3,250 / pasivo cte. 1,420</div>
</div>
<div class="card kpi">
<h3>Capital de Trabajo</h3>
<div class="k-val num">RD$ 1,830<small> M</small></div>
<div class="k-sub">holgura de liquidez operativa</div>
</div>
<div class="card kpi">
<h3>Endeudamiento</h3>
<div class="k-val num">36<small> %</small></div>
<div class="k-sub"><span class="delta up">conservador</span> pasivo / activo</div>
</div>
</div>
<div class="row r-6-6">
<div class="card">
<h3>De dónde viene y dónde está el capital</h3>
<p class="cap">Activos = Pasivos + Patrimonio + resultado del ejercicio (RD$ M)</p>
<svg id="bal" viewBox="0 0 380 300" role="img" aria-label="Estructura del balance"></svg>
</div>
<div class="card">
<h3>Composición del activo</h3>
<p class="cap">al 31-jul-2026 (RD$ M)</p>
<table class="tbl">
<thead><tr><th>Rubro</th><th class="r">Saldo</th></tr></thead>
<tbody id="act"></tbody>
</table>
<h3 style="margin-top:18px">Composición del pasivo</h3>
<table class="tbl">
<thead><tr><th>Rubro</th><th class="r">Saldo</th></tr></thead>
<tbody id="pas"></tbody>
</table>
</div>
</div>
</section>
<div class="foot">
<span class="pill">Prototipo de diseño</span>
&nbsp; Vista previa del tablero de Power BI. Fuente: <code>MarmotechBI.presidencia.vwPLMensual</code>, <code>vwGastosDepto</code>, <code>vwBalanceMensual</code> —
reproduce el Mayor General Analítico (cgprrp008) y el Análisis de Gastos (cgprrp009). Cifras validadas contra el sistema al 31-jul-2026.
</div>
</div>
<script>
(function(){
var css=getComputedStyle(document.documentElement);
var C=function(n){return css.getPropertyValue(n).trim()};
function col(n){return C(n)}
var money=function(v){return v.toLocaleString('en-US',{minimumFractionDigits:1,maximumFractionDigits:1})};
/* tabs */
var btns=document.querySelectorAll('nav.tabs button');
btns.forEach(function(b){
b.addEventListener('click',function(){
btns.forEach(function(x){x.setAttribute('aria-selected','false')});
b.setAttribute('aria-selected','true');
document.querySelectorAll('.page').forEach(function(p){p.classList.remove('active')});
document.getElementById(b.dataset.p).classList.add('active');
});
});
var NS='http://www.w3.org/2000/svg';
function el(t,a){var e=document.createElementNS(NS,t);for(var k in a)e.setAttribute(k,a[k]);return e;}
function txt(x,y,s,o){o=o||{};var t=el('text',{x:x,y:y});t.textContent=s;
t.setAttribute('fill',o.fill||col('--muted'));
t.setAttribute('font-size',o.fs||11);
t.setAttribute('font-family',o.mono?'"IBM Plex Mono",monospace':'"IBM Plex Sans",sans-serif');
t.setAttribute('font-weight',o.fw||400);
if(o.anchor)t.setAttribute('text-anchor',o.anchor);
t.setAttribute('font-variant-numeric','tabular-nums');
return t;}
/* ---------- WATERFALL ---------- */
(function(){
var svg=document.getElementById('waterfall'); if(!svg)return;
var W=720,H=300,padL=8,padR=8,base=250,top=20;
var steps=[
{l:'Ventas',v:1375.3,type:'start'},
{l:'Costo',v:-668.4,type:'neg'},
{l:'Ut. Bruta',v:706.9,type:'sub'},
{l:'Gastos',v:-414.7,type:'neg'},
{l:'Ut. Operat.',v:292.1,type:'sub'},
{l:'Otros/ISR',v:-72.5,type:'neg'},
{l:'Ut. Neta',v:219.6,type:'end'}
];
var max=1375.3, sc=(base-top)/max;
var n=steps.length, gap=14, bw=(W-padL-padR-gap*(n-1))/n;
var run=0;
steps.forEach(function(s,i){
var x=padL+i*(bw+gap), h, y, fill;
if(s.type==='start'||s.type==='sub'||s.type==='end'){
h=s.v*sc; y=base-h; run=s.v;
fill = s.type==='end'?col('--accent') : (s.type==='start'?col('--accent'):col('--ink'));
if(s.type==='sub')fill=col('--faint');
}else{
h=Math.abs(s.v)*sc; y=base-(run*sc); run=run+s.v;
fill=col('--neg');
}
svg.appendChild(el('rect',{x:x,y:y,width:bw,height:Math.max(2,h),rx:3,fill:fill,opacity:s.type==='sub'?0.5:0.92}));
svg.appendChild(txt(x+bw/2,base+16,s.l,{anchor:'middle',fs:10.5,fill:col('--muted')}));
svg.appendChild(txt(x+bw/2,y-6,(s.v>0?'':'−')+money(Math.abs(s.v)),{anchor:'middle',fs:11,mono:true,fw:600,fill:col('--ink')}));
});
})();
/* ---------- COMPOSITION (stacked bar of one peso) ---------- */
(function(){
var svg=document.getElementById('composition'); if(!svg)return;
var parts=[
{l:'Costo de ventas',p:48.6,c:col('--neg')},
{l:'Gastos operativos',p:30.2,c:col('--warn')},
{l:'Otros / ISR',p:5.3,c:col('--faint')},
{l:'Utilidad neta',p:16.0,c:col('--pos')}
];
var x=90,y=24,w=54,H=250,total=100,sc=H/total,cy=y;
parts.forEach(function(p){
var h=p.p*sc;
svg.appendChild(el('rect',{x:x,y:cy,width:w,height:h,fill:p.c,opacity:.9}));
svg.appendChild(txt(x-10,cy+h/2+4,p.p.toFixed(1)+'%',{anchor:'end',mono:true,fs:12,fw:600,fill:col('--ink')}));
svg.appendChild(txt(x+w+10,cy+h/2+4,p.l,{fs:11.5,fill:col('--muted')}));
cy+=h;
});
svg.appendChild(txt(x+w/2,y-8,'RD$ 1.00',{anchor:'middle',fs:10,fill:col('--faint')}));
})();
/* ---------- TREND (bars + line) ---------- */
(function(){
var svg=document.getElementById('trend'); if(!svg)return;
var data=[
{m:'Ene',v:132.4,u:2.5},{m:'Feb',v:169.9,u:7.2},{m:'Mar',v:224.8,u:56.3},
{m:'Abr',v:224.3,u:52.6},{m:'May',v:190.8,u:33.0},{m:'Jun',v:225.0,u:37.8},
{m:'Jul',v:208.1,u:30.2}
];
var W=720,base=230,top=18,padL=34,padR=12;
var max=240, sc=(base-top)/max;
[0,60,120,180,240].forEach(function(g){
var y=base-g*sc;
svg.appendChild(el('line',{x1:padL,y1:y,x2:W-padR,y2:y,stroke:col('--grid'),'stroke-width':1}));
svg.appendChild(txt(padL-6,y+3,g,{anchor:'end',fs:9.5,fill:col('--faint'),mono:true}));
});
var n=data.length, gap=18, bw=(W-padL-padR-gap*(n-1))/n;
var pts=[];
data.forEach(function(d,i){
var x=padL+i*(bw+gap);
var h=d.v*sc;
svg.appendChild(el('rect',{x:x,y:base-h,width:bw,height:h,rx:3,fill:col('--accent-soft')}));
svg.appendChild(txt(x+bw/2,base+15,d.m,{anchor:'middle',fs:10.5}));
svg.appendChild(txt(x+bw/2,base-h-6,d.v.toFixed(0),{anchor:'middle',fs:10,mono:true,fill:col('--muted')}));
pts.push([x+bw/2, base-d.u*sc]);
});
var dpath='M'+pts.map(function(p){return p[0]+','+p[1]}).join(' L');
svg.appendChild(el('path',{d:dpath,fill:'none',stroke:col('--accent'),'stroke-width':2.4,'stroke-linejoin':'round'}));
pts.forEach(function(p){svg.appendChild(el('circle',{cx:p[0],cy:p[1],r:3.4,fill:col('--surface'),stroke:col('--accent'),'stroke-width':2}));});
})();
/* ---------- ANNUAL ---------- */
(function(){
var svg=document.getElementById('annual'); if(!svg)return;
var data=[{y:'2024',v:2401,u:462},{y:'2025',v:2401,u:457},{y:"2026*",v:1375,u:220}];
var W=360,base=230,top=18,padL=30,padR=10;
var max=2500,sc=(base-top)/max;
var n=data.length,gap=40,grp=(W-padL-padR-gap*(n-1))/n, bw=grp/2-3;
data.forEach(function(d,i){
var x=padL+i*(grp+gap);
var h1=d.v*sc,h2=d.u*sc;
svg.appendChild(el('rect',{x:x,y:base-h1,width:bw,height:h1,rx:3,fill:col('--accent-soft')}));
svg.appendChild(el('rect',{x:x+bw+6,y:base-h2,width:bw,height:h2,rx:3,fill:col('--accent')}));
svg.appendChild(txt(x+grp/2,base+15,d.y,{anchor:'middle',fs:11}));
svg.appendChild(txt(x+bw/2,base-h1-5,(d.v/1000).toFixed(2)+'k',{anchor:'middle',fs:9.5,mono:true,fill:col('--muted')}));
svg.appendChild(txt(x+bw+6+bw/2,base-h2-5,d.u,{anchor:'middle',fs:9.5,mono:true,fill:col('--muted')}));
});
svg.appendChild(txt(padL,top-4,'RD$ M',{fs:9.5,fill:col('--faint')}));
})();
/* ---------- GERENCIA (grouped horizontal) ---------- */
(function(){
var svg=document.getElementById('ger'); if(!svg)return;
var data=[
{l:'Ventas y Mercadeo',a:184.5,b:178.3},
{l:'Admin. y Materiales',a:104.8,b:92.5},
{l:'Planta / Producción',a:78.1,b:79.9},
{l:'Gerencia General',a:41.3,b:36.4},
{l:'Planta Agregados',a:4.4,b:0},
{l:'Caribbean',a:1.6,b:0}
];
var W=380,padL=8,padR=44,top=6,rowH=46,x0=padL, maxW=W-padL-padR, max=190, sc=maxW/max;
data.forEach(function(d,i){
var y=top+i*rowH;
svg.appendChild(txt(x0,y+11,d.l,{fs:11,fw:500,fill:col('--ink')}));
svg.appendChild(el('rect',{x:x0,y:y+16,width:Math.max(2,d.a*sc),height:9,rx:2,fill:col('--accent')}));
svg.appendChild(el('rect',{x:x0,y:y+27,width:Math.max(2,d.b*sc),height:9,rx:2,fill:col('--accent-soft')}));
svg.appendChild(txt(x0+d.a*sc+6,y+24,money(d.a),{fs:10,mono:true,fill:col('--muted')}));
});
})();
/* ---------- SUBGRUPO table ---------- */
(function(){
var tb=document.getElementById('subg'); if(!tb)return;
var rows=[
['74 · Otros gastos y servicios',304.1,22.1],
['71 · Compensación empleados',293.8,21.4],
['73 · Gastos fijos',114.7,8.3],
['72 · Otros rel. a empleados',27.8,2.0],
['76 · Cierre fabricación (absorción)',-325.7,-23.7]
];
var max=310;
rows.forEach(function(r){
var tr=document.createElement('tr');
var w=Math.abs(r[1])/max*100;
tr.innerHTML='<td class="barcell"><div class="fill" style="width:'+w+'%;background:'+(r[1]<0?'color-mix(in srgb,var(--neg) 20%,transparent)':'var(--accent-soft)')+'"></div><span>'+r[0]+'</span></td>'+
'<td class="r num" style="font-weight:600;color:'+(r[1]<0?'var(--neg)':'var(--ink)')+'">'+(r[1]<0?'−':'')+money(Math.abs(r[1]))+'</td>'+
'<td class="r num" style="color:var(--muted)">'+r[2].toFixed(1)+'%</td>';
tb.appendChild(tr);
});
})();
/* ---------- GASTO TREND ---------- */
(function(){
var svg=document.getElementById('gtrend'); if(!svg)return;
var data=[
{m:'Ene',g:55.1,r:41.6},{m:'Feb',g:54.8,r:32.2},{m:'Mar',g:59.2,r:26.3},
{m:'Abr',g:59.9,r:26.7},{m:'May',g:57.7,r:30.3},{m:'Jun',g:61.5,r:27.3},{m:'Jul',g:66.6,r:32.0}
];
var W=720,base=200,top=16,padL=34,padR=40;
var max=80,sc=(base-top)/max;
[0,20,40,60,80].forEach(function(g){var y=base-g*sc;
svg.appendChild(el('line',{x1:padL,y1:y,x2:W-padR,y2:y,stroke:col('--grid')}));
svg.appendChild(txt(padL-6,y+3,g,{anchor:'end',fs:9.5,mono:true,fill:col('--faint')}));});
var n=data.length,gap=20,bw=(W-padL-padR-gap*(n-1))/n, rpts=[];
data.forEach(function(d,i){
var x=padL+i*(bw+gap),h=d.g*sc;
svg.appendChild(el('rect',{x:x,y:base-h,width:bw,height:h,rx:3,fill:col('--accent')}));
svg.appendChild(txt(x+bw/2,base+15,d.m,{anchor:'middle',fs:10.5}));
svg.appendChild(txt(x+bw/2,base-h-5,d.g.toFixed(0),{anchor:'middle',fs:9.5,mono:true,fill:col('--muted')}));
rpts.push([x+bw/2, base-(d.r/ (80/60) )*sc]); // scale % on right (0-60 mapped)
});
// right axis % (gasto/ventas), scale 0-60 across same height
var rsc=(base-top)/60;
rpts=[];data.forEach(function(d,i){var x=padL+i*(bw+gap);rpts.push([x+bw/2, base-d.r*rsc]);});
var dp='M'+rpts.map(function(p){return p[0]+','+p[1]}).join(' L');
svg.appendChild(el('path',{d:dp,fill:'none',stroke:col('--pos'),'stroke-width':2.2,'stroke-dasharray':'1 0'}));
rpts.forEach(function(p,i){svg.appendChild(el('circle',{cx:p[0],cy:p[1],r:3,fill:col('--surface'),stroke:col('--pos'),'stroke-width':2}));
svg.appendChild(txt(p[0],p[1]-8,data[i].r.toFixed(0)+'%',{anchor:'middle',fs:9,mono:true,fill:col('--pos')}));});
svg.appendChild(txt(padL,top-4,'RD$ M',{fs:9.5,fill:col('--faint')}));
svg.appendChild(txt(W-padR+4,top+4,'% ventas',{fs:9.5,fill:col('--pos')}));
})();
/* ---------- BALANCE stacked ---------- */
(function(){
var svg=document.getElementById('bal'); if(!svg)return;
var W=380,base=250,top=20,bw=88;
var max=6435, sc=(base-top)/max;
// col 1 activos
var xA=60;
svg.appendChild(el('rect',{x:xA,y:base-6435*sc,width:bw,height:6435*sc,rx:4,fill:col('--accent'),opacity:.9}));
svg.appendChild(txt(xA+bw/2,base-6435*sc-8,'6,435',{anchor:'middle',fs:12,mono:true,fw:600,fill:col('--ink')}));
svg.appendChild(txt(xA+bw/2,base+16,'Activos',{anchor:'middle',fs:11}));
// col 2 pasivo+patrimonio+result
var xB=xA+bw+70, parts=[{l:'Pasivos',v:2322,c:col('--neg')},{l:'Patrimonio',v:3894,c:col('--pos')},{l:'Result. ejerc.',v:219,c:col('--warn')}];
var cy=base;
parts.forEach(function(p){var h=p.v*sc;cy-=h;
svg.appendChild(el('rect',{x:xB,y:cy,width:bw,height:h,fill:p.c,opacity:.85}));
svg.appendChild(txt(xB+bw+8,cy+h/2+4,p.l+' '+p.v.toLocaleString('en-US'),{fs:10.5,fill:col('--muted')}));
});
svg.appendChild(txt(xB+bw/2,base+16,'Pas. + Patrim.',{anchor:'middle',fs:11}));
})();
/* ---------- ACTIVO / PASIVO tables ---------- */
(function(){
function fill(id,rows,max){
var tb=document.getElementById(id); if(!tb)return;
rows.forEach(function(r){
var tr=document.createElement('tr');
var neg=r[1]<0;
tr.innerHTML='<td>'+r[0]+'</td><td class="r num" style="color:'+(neg?'var(--neg)':'var(--ink)')+'">'+(neg?'−':'')+Math.abs(r[1]).toLocaleString('en-US')+'</td>';
tb.appendChild(tr);
});
}
fill('act',[['Activos corrientes',3250],['Activos fijos',4140],['Depreciación acum.',-1136],['Otros activos',181],['Total activos',6435]]);
fill('pas',[['Pasivos corrientes',1420],['Préstamos largo plazo',902],['Total pasivos',2322],['Patrimonio',3894]]);
// bold totals
['act','pas'].forEach(function(id){var t=document.getElementById(id);var rs=t.querySelectorAll('tr');
rs.forEach(function(tr){if(/Total/.test(tr.textContent)){tr.style.fontWeight='700';tr.querySelectorAll('td').forEach(function(td){td.style.borderTop='1px solid var(--line)';});}});});
})();
})();
</script>
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,328 @@
# Documentación de la base de datos **MarmotechBI**
### Guía para el desarrollo de dashboards en Power BI
| | |
|---|---|
| **Servidor** | `192.168.40.8` (SQL Server 2016) |
| **Base de datos** | `MarmotechBI` |
| **Origen de los datos** | Se actualiza en vivo desde los sistemas operativos de la empresa |
| **Naturaleza** | Capa semántica de **vistas** (54 vistas + 2 tablas). No almacena datos propios salvo 2 tablas de carga manual |
| **Propósito** | Esquema estrella para que usuarios de negocio armen sus propios dashboards con nombres de negocio |
| **Fecha de este documento** | 2026-08-25 |
> **Idea clave:** casi todo en `MarmotechBI` es una **vista** que presenta la información con nombres de negocio (`vwFactVentas`, `vwDimProducto`, etc.). Como son vistas, **no existen llaves foráneas físicas**: las relaciones son *lógicas* y hay que **crearlas manualmente en Power BI** (ver la sección [Relaciones para Power BI](#relaciones-recomendadas-en-power-bi)).
---
## 1. Cómo conectarse desde Power BI
1. **Obtener datos → SQL Server**.
2. Servidor: `192.168.40.8` &nbsp;·&nbsp; Base de datos: `MarmotechBI`.
3. Modo: **Import** (recomendado para tableros publicados) o **DirectQuery** si se necesita tiempo real.
4. Seleccionar las vistas del área que se va a analizar (ej. `vwFactVentas` + sus dimensiones `vwDim*`).
5. En la vista **Modelo**, crear las relaciones según la sección 6.
> **Permisos:** el acceso es por login de Windows con rol de lectura (`db_datareader`) sobre `MarmotechBI`. Solicitarlo a Tecnología con el usuario de dominio.
---
## 2. Convenciones de nombres
| Prefijo | Significado | Rol en el modelo |
|---|---|---|
| `vwDim…` | **Dimensión** — describe (quién, qué, dónde, cuándo) | Tabla de "look up" |
| `vwFact…` / `VWFACT…` | **Hecho** — mide (cuánto, cuántos) | Tabla central de valores |
| `vwBridge…` | **Puente** — resuelve relaciones muchos-a-muchos | Entre dimensiones |
| `VW_DIM_…` / `VW_HECHOS_…` | Esquema del **Balanced Scorecard / Indicadores** (área independiente) | Dim / Hecho de gestión |
| Sin prefijo (`ventas_facturas`, `estadoResultado`, `item_conteo_ciclico`…) | **Vistas planas de reporte** — ya vienen denormalizadas | Se usan solas, no requieren relaciones |
| `…_usuario` (`_cdelacruz`, `_jisa`, `_mpuig`…) | **Copias personales** filtradas por vendedor/supervisor | Uso individual, no para el modelo general |
**Claves compuestas** — se repiten en casi todo el modelo:
- **Producto** = `cod_n` + `cod_grupo` + `cod_tipo` + `cod_sec` (4 columnas). En `vwDimProducto` existe también `producto_id` que las concatena como texto (`cod_n-cod_grupo-cod_tipo-cod_sec`).
- **Cliente** = `tipo_cliente` + `sec_cliente` (2 columnas).
---
## 3. Áreas temáticas (subject areas)
| # | Área | Hecho(s) principal(es) | Dimensiones que usa |
|---|---|---|---|
| A | **Comercial / Ventas** | `vwFactVentas`, `VWFACTCOTIZACIONES`, `vwfactPipeline`, `vwFactPresupuesto` | Fecha, Cliente, Vendedor, EquipoVentas, Producto, Categoría, Provincia, Zona, TipoVenta |
| B | **Cuentas por Cobrar** | `vwFactCxC_Base`, `vwFactCxC_Real` | Cliente, Vendedor, TipoVenta |
| C | **Despacho / Pendientes** | `vwOrdenesPendientesDespacho`, `vwReqCotizaciones`, `vwProductoDisponible` | Cliente, Vendedor, Producto |
| D | **Producción** | `vwProduccion_pub` | DepartamentoProducción, Producto |
| E | **Contabilidad / Finanzas** | `vwFactContabilidad`, `estadoResultado` | (Departamento, Cuenta — internas) |
| F | **Inventario** | `vwRotacionInventario_pub`, `vwRotacionInventarioPorBodega_pub`, `item_conteo_ciclico` | (planas, autocontenidas) |
| G | **Indicadores / Balanced Scorecard** | `VW_HECHOS_INDICADORES`, `VW_HECHOS_DOWNTIME`, `VW_HECHOS_TICKETS` | Calendario, Departamentos, Indicadores, Perspectivas, Procesos |
| H | **Datos externos** (tabla física) | `FactMercadoEdificaciones` | (independiente) |
---
## 4. Diccionario de dimensiones (área comercial)
### `vwDimFecha` — Calendario (grano mensual)
Grano = mes.
| Columna | Tipo | Descripción |
|---|---|---|
| `ano` | smallint | Año |
| `numeroMes` | smallint | Número de mes (1-12) — **llave para ordenar** |
| `mes` | char(10) | Nombre del mes |
| `AnoMes` | varchar(7) | `AAAA-MM` |
### `vwDimCliente` — Clientes &nbsp;· PK = `tipo_cliente` + `sec_cliente`
| Columna | Tipo | Descripción |
|---|---|---|
| `tipo_cliente` | smallint | Tipo/segmento de cliente (parte 1 de la llave) |
| `sec_cliente` | int | Secuencia del cliente (parte 2 de la llave) |
| `nombre` | char(100) | Razón social |
| `num_rnc` | char(25) | RNC/Cédula |
| `direccion` | varchar(173) | Dirección |
### `vwDimVendedor` — Vendedores &nbsp;· PK = `vendedor_id`
| Columna | Tipo | Descripción |
|---|---|---|
| `vendedor_id` | smallint | Código de vendedor (corresponde al nº de empleado) |
| `vendedor` | varchar(31) | Nombre y apellido |
| `equipo_id` | smallint | **FK → `vwDimEquipoVentas.equipo_id`** |
### `vwDimEquipoVentas` — Equipos de venta &nbsp;· PK = `equipo_id`
| Columna | Tipo | Descripción |
|---|---|---|
| `equipo_id` | smallint | Código del equipo/departamento comercial |
| `equipoVentas` | nchar(200) | Nombre del equipo |
### `vwDimProducto` — Productos &nbsp;· PK = `cod_n`+`cod_grupo`+`cod_tipo`+`cod_sec`
**Es la dimensión central de producto de todo el modelo.**
| Columna | Tipo | Descripción |
|---|---|---|
| `cod_n`, `cod_grupo`, `cod_tipo`, `cod_sec` | int | Llave compuesta del producto |
| `producto_id` | varchar(43) | Llave concatenada (`cod_n-cod_grupo-cod_tipo-cod_sec`) — **usar esta para relacionar en Power BI** |
| `descripcion_producto` | varchar(180) | Nombre del producto |
| `unidad_med` | char(4) | Unidad de medida |
| `clase` / `grupo` / `tipo` | char/nvarchar | Jerarquía de clasificación |
| `origen` | char(20) | Origen (nacional/importado/producción) |
| `categoria_titulo` | varchar(100) | Categoría comercial |
| `GerenteMarcas` | varchar(31) | Gerente de marca responsable |
### `vwDimCategoria` — Categorías comerciales &nbsp;· PK = `cod_categoria`
| Columna | Tipo | Descripción |
|---|---|---|
| `cod_categoria` | smallint | Código de categoría |
| `categoria` | varchar(100) | Nombre de la categoría |
### `vwBridgeProductoCategoria` — Puente Producto ↔ Categoría
Resuelve que un producto (por `cod_n`+`cod_grupo`+`cod_tipo`) pertenece a una categoría.
| Columna | Tipo | Descripción |
|---|---|---|
| `cod_n`, `cod_grupo`, `cod_tipo` | smallint | Parte de la llave del producto |
| `cod_categoria` | smallint | **FK → `vwDimCategoria.cod_categoria`** |
### `vwDimProvincia` — Provincias &nbsp;· PK = `cod_provincia`
| Columna | Tipo | Descripción |
|---|---|---|
| `cod_provincia` | smallint | Código de provincia |
| `nombre_provincia` | char(30) | Nombre |
| `pais` | nchar(20) | País |
| `idZona` | smallint | **FK → `vwDimZona.cod_zona`** |
### `vwDimZona` — Zonas geográficas &nbsp;· PK = `cod_zona`
| Columna | Tipo | Descripción |
|---|---|---|
| `cod_zona` | smallint | Código de zona |
| `zonaGeografica` | char(30) | Nombre de la zona |
### `vwDimTipoVenta` — Tipo de venta / Moneda &nbsp;· PK = `ventas`
Contiene la **tasa de cambio** usada para convertir a RD$.
| Columna | Tipo | Descripción |
|---|---|---|
| `ventas` | smallint | Código de tipo de venta |
| `descripcion` | nvarchar(80) | Descripción |
| `simbolo` | nvarchar(40) | Símbolo de moneda |
| `descripcion_moneda` | nchar(40) | Moneda |
| `tasa` | decimal | Tasa de cambio a RD$ |
| `tipo_operacion` | varchar(11) | `LOCAL_RD` / `LOCAL_USD` / `EXPORTACION` / `EURO` / `OTRO` |
### `vwDimDepartamentoProduccion` — Departamentos de producción &nbsp;· PK = `codigodepto`
| Columna | Tipo | Descripción |
|---|---|---|
| `codigodepto` | smallint | Código de departamento |
| `nombre_depto` | char(30) | Nombre |
| `tipo_departamento` | nchar(40) | Tipo |
| `proceso_agrupado` | varchar(13) | Agrupación de proceso |
---
## 5. Diccionario de hechos (measures)
### `vwFactVentas` — Ventas facturadas &nbsp;· grano: **línea de factura**
Una fila por cada línea de factura. Solo incluye documentos activos (no anulados).
| Columna | Tipo | Rol | Descripción |
|---|---|---|---|
| `factura`, `sucid` | int | Grano | Nº de factura + sucursal |
| `fecha`, `ano`, `mes` | date/int | → Fecha | Fecha de factura |
| `tipo_cliente`, `sec_cliente` | — | → Cliente | Llave del cliente |
| `vendedor` | smallint | → Vendedor | `sec_vend` (código del vendedor) |
| `ventas` | — | → TipoVenta | Código de moneda/tipo venta |
| `tipoVenta`, `simbolo`, `tasa` | — | Atributo | Descripción de moneda y tasa |
| `cod_provincia` | — | → Provincia | Provincia del cliente |
| `cotizacion_no` | int | → Cotización | Cotización que originó la venta |
| `cod_n`,`cod_grupo`,`cod_tipo`,`cod_sec` | — | → Producto | Llave del producto |
| `cantidad` | numeric | Medida | Cantidad vendida |
| `precio` | numeric | Medida | Precio unitario |
| `porc_desc` | numeric | Medida | % de descuento |
| `valor_bruto` | numeric | Medida | cantidad × precio |
| `valor_descuento` | numeric | Medida | Monto del descuento |
| `neto` | numeric | Medida | Neto en moneda original |
| **`neto_rd`** | numeric | Medida | **Neto convertido a RD$ (neto × tasa)** — usar para totales |
### `VWFACTCOTIZACIONES` — Cotizaciones &nbsp;· grano: línea de cotización
Llaves: `cotizacion_no`, `tipo_cliente`+`sec_cliente`, `vendedor_id`, `cod_zona`, `cod_provincia`, `cod_n…cod_sec`.
Medidas: `cantidad`, `precio`, `porc_desc`, `neto_rd`, `monto_bruto`, `monto_descuento`, `estado`.
### `vwfactPipeline` — Embudo comercial (cotizado → vendido → despachado) · grano: cotización
Medidas: `cotizado_rd`, `vendido_rd`, `pendiente_venta_rd`, `conversion_pct`, `despachado_rd`, `pendiente_despacho_rd`.
Llaves: `cotizacion_no`, `tipo_cliente`+`sec_cliente`, `vendedor`, `cod_zona`, `cod_provincia`, `ventas`.
### `vwFactPresupuesto` — Presupuesto/meta de ventas
Llaves: `ano`,`mes`, `vendedor`, `ventas`, `cod_n…cod_sec`, `cod_categoria`.
Medidas: `cantidad`, `valor`, `valor_rd`.
### `vwFactCxC_Base` — Movimientos de Cuentas por Cobrar
Llaves: `tipo_cliente`+`sec_cliente`, `vendedor`, `num_doc`, `tipo_doc`, `ventas`.
Medidas: `monto`, `monto_rd`, `monto_signado`, `monto_signado_rd`, `dias_vencimiento`, `tipo_movimiento`.
### `vwFactCxC_Real` — Balance vigente de CxC por factura
Llaves: `tipo_cliente`+`sec_cliente`, `vendedor`, `factura`, `ventas`.
Medidas: `balance_rd`, `dias_vencimiento`.
### `vwProductoDisponible` — Disponibilidad de inventario (snapshot)
Disponibilidad calculada con la misma lógica del sistema operativo de inventario. Llave: `producto_id` / `cod_n…cod_sec`.
Medidas: `existencia`, `ordenes_abiertas`, `despachado`, `reservado`, `transito`, **`disponible`** (= existencia − (ordenes_abiertas − despachado) − reservado).
### `vwOrdenesPendientesDespacho` — Órdenes pendientes de despacho
Llaves: `cotizacion_no`, `tipo_cliente`+`sec_cliente`, `vendedor_id`, `cod_n…cod_sec`.
Medidas: `cantidadCotizada`, `cantidadDespachada`, `cantidadPendiente`, `valorCotizadoLinea`.
### `vwReqCotizaciones` — Requisiciones vs. cotizaciones
Medidas: `cantidadCotizada`, `cantidadDespachada`, `cantidadPendiente`, `valorRequisicion`, `valorPendienteDespachar`.
### `vwProduccion_pub` — Producción diaria &nbsp;· grano: producto/día
Llaves: `codigodepto` → DepartamentoProducción, `cod_n…cod_sec` → Producto.
Medidas: `unidades`, `cantidad`, `existencia`, `cantidadVendida`.
### `vwFactContabilidad` — Movimientos contables
Llaves: `cuenta`, `codigodepartamento`, `ano`, `mes`, `tipo`, `banco`.
Medidas: `debito`, `credito`, `balance`, `presupuesto`. Incluye auditoría (`usuariocreador`, `fechacreacion`…).
---
## 6. Relaciones recomendadas en Power BI
> Como son vistas, **Power BI no detecta relaciones automáticamente**. Créalas a mano en la vista *Modelo*, con cardinalidad **Dimensión (1) → Hecho (\*)** y filtro en **dirección única**.
### 6.1 Área comercial (estrella)
| Dimensión (lado 1) | Columna | Hecho (lado \*) | Columna |
|---|---|---|---|
| `vwDimFecha` | `AnoMes` | `vwFactVentas` / cotizaciones / pipeline | `AnoMes` derivado de `ano`+`mes` |
| `vwDimCliente` | *clave compuesta* | `vwFactVentas`, `VWFACTCOTIZACIONES`, CxC | `tipo_cliente` + `sec_cliente` |
| `vwDimVendedor` | `vendedor_id` | `vwFactVentas` (`vendedor`), cotizaciones (`vendedor_id`) | vendedor |
| `vwDimEquipoVentas` | `equipo_id` | `vwDimVendedor` | `equipo_id` |
| `vwDimProducto` | `producto_id` | hechos con `cod_n…cod_sec` | *clave compuesta* |
| `vwDimCategoria` | `cod_categoria` | `vwBridgeProductoCategoria` | `cod_categoria` |
| `vwBridgeProductoCategoria` | `cod_n`+`cod_grupo`+`cod_tipo` | `vwDimProducto` | mismas columnas |
| `vwDimProvincia` | `cod_provincia` | `vwFactVentas`, cotizaciones, pipeline | `cod_provincia` |
| `vwDimZona` | `cod_zona` | `vwDimProvincia` | `idZona` |
| `vwDimTipoVenta` | `ventas` | hechos con `ventas` | `ventas` |
### 6.2 Claves compuestas — cómo resolverlas
Power BI **solo permite relaciones por UNA columna**. Para `Cliente` y `Producto` (llaves de 2 y 4 columnas) crea una **columna llave concatenada** con la misma fórmula en la dimensión y en el hecho:
```
// Cliente — en vwDimCliente y en cada hecho:
ClienteKey = FORMAT([tipo_cliente],"00") & "-" & FORMAT([sec_cliente],"0000000")
// Producto — usar el producto_id que ya trae vwDimProducto; en los hechos:
ProductoKey = FORMAT([cod_n],"0") & "-" & FORMAT([cod_grupo],"0") & "-" & FORMAT([cod_tipo],"0") & "-" & FORMAT([cod_sec],"0")
```
Luego relaciona por `ClienteKey` / `ProductoKey`.
### 6.3 Fechas
Los hechos traen `ano` + `mes`/`numeroMes` (grano mensual). Recomendado:
- Crear una **tabla de calendario** en Power BI (`CALENDAR`/`CALENDARAUTO`) y una columna `AnoMes` en cada hecho para relacionar; **o**
- Reutilizar `VW_DIM_CALENDARIO` (grano diario) como calendario compartido cuando se cruce con Indicadores.
### 6.4 Moneda
Los valores `*_rd` **ya vienen convertidos a RD$** usando la `tasa` de `vwDimTipoVenta`. Para totales monetarios usar siempre las columnas `neto_rd`, `monto_rd`, `valor_rd`, `balance_rd`.
---
## 7. Área de Indicadores / Balanced Scorecard (esquema `VW_*`)
Modelo estrella independiente para el tablero de gestión (indicadores, tiempos de caída, tickets de soporte).
**Dimensiones**
| Vista | PK | Descripción |
|---|---|---|
| `VW_DIM_CALENDARIO` | `Fecha` | Calendario diario (Año, Mes, Trimestre, Semana, EsFinDeSemana) |
| `VW_DIM_DEPARTAMENTOS` | `IdDepartamento` | Departamentos (Nombre, Tipo, Responsable, Activo) |
| `VW_DIM_INDICADORES` | `IdIndicador` | Indicadores (Meta, Peso, Frecuencia, UnidadMedida; FK `IdDepartamento`) |
| `VW_DIM_PERSPECTIVAS` | `IdPerspectiva` | Perspectivas del BSC (Financiera, Cliente, Procesos, Aprendizaje) |
| `VW_DIM_PROCESOS` | `IdProceso` | Procesos (Área, Criticidad, Tipo; FK `IdDepartamento`) |
**Hechos**
| Vista | Llaves | Medidas |
|---|---|---|
| `VW_HECHOS_INDICADORES` | `IdIndicador`, `Fecha`, `IdPerspectiva` | `ValorReal`, `ValorMeta`, `Cumplimiento`, `Score` |
| `VW_HECHOS_DOWNTIME` | `Fecha`, `IdDepartamento`, `IdProceso` | `HorasCaidas`, `ImpactoEstimado` |
| `VW_HECHOS_TICKETS` | `Fecha`, `IdProceso`, `IdDepartamento` | `HorasResolucion`, conteos por `status`/`priority`/`category` |
| `VW_SCORE_DEPARTAMENTO` | (derivada) | `ScorePromedio` por Departamento/Año/Mes |
**Relaciones**
- `VW_DIM_INDICADORES[IdIndicador]` → `VW_HECHOS_INDICADORES[IdIndicador]`
- `VW_DIM_PERSPECTIVAS[IdPerspectiva]` → `VW_HECHOS_INDICADORES[IdPerspectiva]`
- `VW_DIM_CALENDARIO[Fecha]` → `VW_HECHOS_INDICADORES / DOWNTIME / TICKETS[Fecha]`
- `VW_DIM_DEPARTAMENTOS[IdDepartamento]` → `VW_DIM_INDICADORES / VW_DIM_PROCESOS / hechos[IdDepartamento]`
- `VW_DIM_PROCESOS[IdProceso]` → `VW_HECHOS_DOWNTIME / VW_HECHOS_TICKETS[IdProceso]`
---
## 8. Tablas físicas (carga manual)
| Tabla | Contenido | Notas |
|---|---|---|
| `FactMercadoEdificaciones` | Datos de mercado de la construcción (municipio, barrio, tipo de destino, m² construidos, unidades, precio/m², situación del mercado, fuente) | Se carga con datos externos (ej. estadísticas de edificaciones) |
---
## 9. Vistas planas y personales (uso directo, fuera del modelo estrella)
Estas vistas **ya vienen denormalizadas** (traen las descripciones incorporadas): se conectan solas, sin relaciones.
| Vista | Uso |
|---|---|
| `ventas_facturas` | Vista completa de ventas con cliente, vendedor, producto, zona, moneda ya resueltos — ideal para una tabla dinámica rápida |
| `vwRotacionInventario_pub` / `vwRotacionInventarioPorBodega_pub` | Rotación de inventario (global / por bodega): cantidad vendida, valor ventas, `rotacion` |
| `item_conteo_ciclico` | Programación de conteo cíclico por clase ABC |
| `estadoResultado` | Estado de resultados por mes (`aplica_a`, `Balance`) |
| `vwProduccion_pub` | Producción diaria en formato plano |
| `analisisCotizaciones`, `analisisRequisiciones` | Análisis de cotizaciones y requisiciones (unidades/valores cotizados vs. despachados) |
**Copias personales (filtradas por vendedor/supervisor)** — *no usar para el modelo corporativo*:
`analisisCotizaciones_cdelacruz`, `_jefrancisco`, `_jisa`, `_mhurtado`, `_mpuig`, `_mvargas`;
`analisisRequisiciones_cdelacruz`, `_jefrancisco`, `_JISA`, `_mhurtado`, `_mpuig`;
`vwreportesfactura_cdelacruz`, `_jisa`, `_mpuig`;
`vwDimProductoMariaAna` (copia de `vwDimProducto`).
---
## 10. Buenas prácticas para el equipo de dashboards
1. **Un modelo por área** — no mezclar el esquema comercial con el de Indicadores en un mismo reporte salvo que se comparta el calendario.
2. **Usar siempre las columnas `*_rd`** para importes; la conversión de moneda ya está hecha.
3. **Dimensión en el lado 1, hecho en el lado \*** y filtro cruzado **unidireccional** (evita ambigüedad).
4. **Crear medidas DAX** (SUM, DISTINCTCOUNT…) en lugar de arrastrar columnas numéricas directamente.
5. **No apuntar a las vistas `_usuario`** para tableros compartidos; usar la vista base y filtrar con seguridad a nivel de fila (RLS) si se requiere segmentar por vendedor.
6. Ante dudas sobre el significado de una columna, consultar a Tecnología.
@@ -0,0 +1,192 @@
# Dashboard Ejecutivo de Presidencia — Guía de armado en Power BI
> Radiografía financiera para el Presidente, basada en el **Mayor General Analítico** (`cgprrp008.4gl`) y el **Análisis de Gastos por Departamento** (`cgprrp009.4gl`).
> Datos servidos por la capa BI: **`192.168.40.8 / MarmotechBI`**, esquema **`presidencia`** (vistas creadas por el script `SQL_Vistas_Presidencia.sql`).
> Fecha: 2026-08-26 · Autor: jsoto.
---
## 0. Lo que ya está hecho (capa de datos)
Se crearon 3 vistas en `MarmotechBI` — restringidas a `jsoto` (`DENY SELECT` a `public` + `GRANT` explícito a `MARMOTECH\jsoto` y `jsoto`; el resto del equipo `db_datareader` **no** las ve):
| Vista | Grano | Para qué | Columnas clave |
|---|---|---|---|
| `presidencia.vwPLMensual` | año × mes × cuenta | Estado de Resultados (cgprrp008) | `ano, numero_mes, mes, AnoMes, fecha_mes, grupo, linea, orden_linea, subgrupo_cod, subgrupo_desc, cuenta, cuenta_desc, debito, credito, resultado, costo_gasto` |
| `presidencia.vwGastosDepto` | año × mes × depto × cuenta | Análisis de gastos (cgprrp009) | `…, gerencia_cod, gerencia, departamento, depto_nombre, subgrupo_cod, subgrupo_desc, cuenta, cuenta_desc, debito, credito, gasto` |
| `presidencia.vwBalanceMensual` | año × mes × cuenta | Balance / liquidez | `…, grupo, grupo_desc, subgrupo_cod, subgrupo_desc, cuenta, cuenta_desc, movimiento_mes, saldo_natural, saldo_presentacion` |
**Reglas de negocio ya aplicadas dentro de las vistas** (no hay que replicarlas en DAX):
- Estado de Resultados por **primer dígito** de la cuenta: `4` Ventas · `5` Costo · `7` Gastos · `8` Otros (incl. `88` = ISR).
- **`resultado = credito − debito`** → la suma de todas las líneas del P&L = **Utilidad Neta**. Ventas suma positivo; costo, gastos e ISR restan.
- Solo transacciones activas (`status_t IS NULL`).
- Se **excluye el asiento de cierre anual** (`ref` tipo `ED.99-001/12AA`); sin esto, todo año cerrado neteaba a cero.
Validado contra el sistema: julio-2026 reproduce exactamente la imagen del `cgprrp008`.
---
## 1. Conexión y consultas (Power Query / M)
**Obtener datos → SQL Server** · Servidor `192.168.40.8` · Base `MarmotechBI` · Modo **Import** (o DirectQuery si se quiere en vivo).
Traer las 3 vistas del esquema `presidencia`. Ejemplo de la consulta base (las otras dos son idénticas cambiando el nombre):
```m
let
Origen = Sql.Database("192.168.40.8", "MarmotechBI"),
PL = Origen{[Schema="presidencia", Item="vwPLMensual"]}[Data]
in
PL
```
### Tabla de calendario (necesaria para YoY / YTD)
Crear una tabla calculada **DimCalendario** (grano día, contigua) y marcarla como *Tabla de fechas*:
```DAX
DimCalendario =
VAR MinD = DATE(2015,1,1) -- ajustar si se quiere histórico más largo
VAR MaxD = DATE(2028,12,31)
RETURN
ADDCOLUMNS(
CALENDAR(MinD, MaxD),
"Año", YEAR([Date]),
"MesNo", MONTH([Date]),
"Mes", FORMAT([Date],"MMM","es-DO"),
"AñoMes", FORMAT([Date],"yyyy-MM"),
"PrimerDiaMes", DATE(YEAR([Date]),MONTH([Date]),1),
"Trimestre", "T" & FORMAT([Date],"Q")
)
```
> Modelado → seleccionar DimCalendario → **Marcar como tabla de fechas** (columna `Date`).
---
## 2. Relaciones (vista *Modelo*)
Las vistas traen `fecha_mes` = **primer día del mes**. Relacionar **una sola** dirección, Dimensión (1) → Hecho (\*):
| Desde (1) | Columna | Hacia (\*) | Columna |
|---|---|---|---|
| `DimCalendario` | `Date` | `vwPLMensual` | `fecha_mes` |
| `DimCalendario` | `Date` | `vwGastosDepto` | `fecha_mes` |
| `DimCalendario` | `Date` | `vwBalanceMensual` | `fecha_mes` |
Como cada mes tiene un solo `fecha_mes` (día 1), la relación con el calendario diario funciona perfecto para `TOTALYTD` y `SAMEPERIODLASTYEAR`.
Los *slicers* de Año / Mes se ponen sobre **DimCalendario** (`Año`, `Mes`).
---
## 3. Medidas DAX
Crear una tabla de medidas vacía (`_Medidas`) o alojarlas en `vwPLMensual`.
### 3.1 Estado de Resultados (base)
```DAX
Ventas Netas = CALCULATE( SUM(vwPLMensual[resultado]), vwPLMensual[grupo] = "4" )
Costo de Ventas = CALCULATE( SUM(vwPLMensual[costo_gasto]), vwPLMensual[grupo] = "5" )
Gastos Operativos = CALCULATE( SUM(vwPLMensual[costo_gasto]), vwPLMensual[grupo] = "7" )
Otros Ing. y Gastos = CALCULATE( SUM(vwPLMensual[costo_gasto]), vwPLMensual[linea] = "Otros Ingresos y Gastos" )
ISR = CALCULATE( SUM(vwPLMensual[costo_gasto]), vwPLMensual[linea] = "Impuesto sobre la Renta" )
Utilidad Bruta = [Ventas Netas] - [Costo de Ventas]
Utilidad Operativa = [Utilidad Bruta] - [Gastos Operativos]
Utilidad antes ISR = [Utilidad Operativa] - [Otros Ing. y Gastos]
Utilidad Neta = SUM( vwPLMensual[resultado] ) -- suma de todas las líneas
```
### 3.2 Márgenes
```DAX
Margen Bruto % = DIVIDE( [Utilidad Bruta], [Ventas Netas] )
Margen Operativo % = DIVIDE( [Utilidad Operativa], [Ventas Netas] )
Margen Neto % = DIVIDE( [Utilidad Neta], [Ventas Netas] )
Costo % Ventas = DIVIDE( [Costo de Ventas], [Ventas Netas] )
Gastos % Ventas = DIVIDE( [Gastos Operativos], [Ventas Netas] )
```
### 3.3 Comparativos (YoY y YTD)
```DAX
Ventas AA = CALCULATE( [Ventas Netas], SAMEPERIODLASTYEAR(DimCalendario[Date]) )
Utilidad Neta AA = CALCULATE( [Utilidad Neta], SAMEPERIODLASTYEAR(DimCalendario[Date]) )
Gastos AA = CALCULATE( [Gastos Operativos], SAMEPERIODLASTYEAR(DimCalendario[Date]) )
Ventas YoY % = DIVIDE( [Ventas Netas] - [Ventas AA], [Ventas AA] )
Utilidad YoY % = DIVIDE( [Utilidad Neta] - [Utilidad Neta AA], [Utilidad Neta AA] )
Gastos YoY % = DIVIDE( [Gastos Operativos] - [Gastos AA], [Gastos AA] )
Ventas YTD = TOTALYTD( [Ventas Netas], DimCalendario[Date] )
Utilidad Neta YTD = TOTALYTD( [Utilidad Neta], DimCalendario[Date] )
```
### 3.4 Gastos (vwGastosDepto)
```DAX
Gasto Total = SUM( vwGastosDepto[gasto] )
Gasto AA = CALCULATE( [Gasto Total], SAMEPERIODLASTYEAR(DimCalendario[Date]) )
Gasto YoY % = DIVIDE( [Gasto Total] - [Gasto AA], [Gasto AA] )
Gasto % de Ventas = DIVIDE( [Gasto Total], [Ventas Netas] )
```
### 3.5 Balance / liquidez (vwBalanceMensual)
El saldo del balance es el **saldo acumulado al último mes del contexto**. Medidas:
```DAX
Saldo (fin periodo) =
VAR ultima = MAX( vwBalanceMensual[fecha_mes] )
RETURN CALCULATE( SUM(vwBalanceMensual[saldo_presentacion]),
vwBalanceMensual[fecha_mes] = ultima )
Activos = CALCULATE( [Saldo (fin periodo)], vwBalanceMensual[grupo]="1" )
Pasivos = CALCULATE( [Saldo (fin periodo)], vwBalanceMensual[grupo]="2" )
Patrimonio = CALCULATE( [Saldo (fin periodo)], vwBalanceMensual[grupo]="3" )
Activo Corriente = CALCULATE( [Saldo (fin periodo)], vwBalanceMensual[subgrupo_cod]="11" )
Pasivo Corriente = CALCULATE( [Saldo (fin periodo)],
vwBalanceMensual[subgrupo_cod] IN {"20","21"} )
Razón Corriente = DIVIDE( [Activo Corriente], [Pasivo Corriente] )
Capital de Trabajo= [Activo Corriente] - [Pasivo Corriente]
Endeudamiento % = DIVIDE( [Pasivos], [Activos] )
```
---
## 4. Formato de medidas
- Importes: moneda RD$, 0 decimales (o en millones con formato personalizado `#,##0.0,, " M"`).
- Porcentajes: 1 decimal.
- Activar **tabular-nums** implícito (Power BI ya alinea) y usar la fuente del tema corporativo.
---
## 5. Páginas y visuales (ver prototipo `Dashboard_Presidencia_Mockup.html`)
### Página 1 — **Radiografía** (resumen ejecutivo)
- **Fila de KPIs (tarjetas):** Ventas Netas + `Ventas YoY %` · Utilidad Bruta + Margen Bruto % · Utilidad Operativa + Margen Operativo % · Utilidad Neta + `Utilidad YoY %` + Margen Neto %.
- **Cascada (Waterfall):** eje = campo `linea` de `vwPLMensual` (orden por `orden_linea`), valor = `[Utilidad Neta]` con desglose por línea → arranca en Ventas y aterriza en Utilidad Neta. (El visual *Waterfall* nativo suma correctamente porque `resultado` ya trae el signo).
- **Comportamiento del periodo actual (columnas + línea):** eje `DimCalendario[Mes]`; columnas = `[Ventas Netas]`; línea = `[Utilidad Neta]`; línea secundaria opcional = `[Margen Neto %]`.
- **Trayectoria anual (barras agrupadas):** eje `DimCalendario[Año]`; valores `[Ventas Netas]` y `[Utilidad Neta]`.
- Slicers: Año, Mes.
### Página 2 — **Análisis de Gastos** (cgprrp009)
- KPIs: Gasto Total + `Gasto YoY %` · `Gasto % de Ventas` · gerencia de mayor peso · mayor alza YoY.
- **Barras por gerencia:** eje `vwGastosDepto[gerencia]`; valores `[Gasto Total]` y `[Gasto AA]`. *Drill-down* a `depto_nombre` y luego `cuenta_desc`.
- **Naturaleza del gasto:** tabla o *treemap* por `subgrupo_desc` con `[Gasto Total]` y `[Gasto % de Ventas]`. (Nota: subgrupo `76 Cierre gtos fabricación` es una absorción negativa a costo).
- **Gasto mensual + % de ventas:** columnas `[Gasto Total]` por `Mes` con línea `[Gasto % de Ventas]` (control de eficiencia).
### Página 3 — **Estructura Financiera** (balance / liquidez)
- KPIs: Activos · Razón Corriente · Capital de Trabajo · Endeudamiento %.
- **Activos = Pasivos + Patrimonio + resultado del ejercicio** (columnas apiladas): la diferencia contra Activos es la utilidad del año en curso aún no cerrada — es normal y se puede rotular como *"Resultado del ejercicio"*.
- **Composición del activo / pasivo:** tabla por `subgrupo_desc` con `[Saldo (fin periodo)]`.
- **Tendencia del patrimonio:** línea `[Patrimonio]` por `Año`.
---
## 6. Suscripción del Presidente
Publicar en el workspace corporativo → **Suscribir** al Presidente (envío por correo con captura del reporte, p. ej. cada lunes). Requiere que el dataset tenga **actualización programada** (gateway sobre `192.168.40.8`).
---
## 7. Ideas de ampliación (opcional, reutilizando vistas existentes)
Para una radiografía "de un vistazo" también semanal, se puede añadir una página **Panorama** que combine, con las vistas ya publicadas en `MarmotechBI` (sin crear nada nuevo):
- Ventas vs. presupuesto del mes (`vwFactVentas` + `vwFactPresupuesto`).
- Cuentas por cobrar y vencido (`vwFactCxC_Real`).
- Backlog / órdenes pendientes de despacho (`vwOrdenesPendientesDespacho`).
- Producción del periodo (`vwProduccion_pub`).
> Se maneja como **modelo aparte** (área comercial) para no mezclar granos; ver `Documentacion_MarmotechBI.md`.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,32 @@
PROYECTO POWER BI — RADIOGRAFÍA MARMOTECH (Dashboard de Presidencia)
====================================================================
QUÉ ES ESTO
-----------
Un Proyecto de Power BI (.pbip) en formato de texto:
- Radiografia_Marmotech.SemanticModel -> modelo de datos + TODAS las medidas DAX
- Radiografia_Marmotech.Report -> 3 páginas (Radiografía / Gastos / Estructura)
Se conecta en vivo a las vistas del esquema "presidencia" en 192.168.40.8 / MarmotechBI.
CÓMO ABRIRLO Y CONVERTIRLO A .PBIX
----------------------------------
1. Abrir Power BI Desktop (v2.157 o superior).
2. Archivo -> Abrir -> seleccionar Radiografia_Marmotech.pbip
(o doble clic al .pbip).
3. Si pide credenciales de la base: usar autenticación de Windows (tu usuario jsoto).
4. Actualizar / cargar datos.
5. Archivo -> Guardar como -> elegir tipo ".pbix" -> listo, ya tienes el .pbix.
REQUISITO (una sola vez, si no abre el reporte)
-----------------------------------------------
Archivo -> Opciones -> Características de vista previa ->
activar "Almacenar informes con el formato de informe mejorado (PBIR)".
Reiniciar Power BI Desktop y volver a abrir el .pbip.
NOTA
----
El MODELO (tablas, relaciones y medidas DAX) está completo y es la parte reutilizable.
Si algún visual del reporte necesitara reacomodo, guíate por el prototipo
"Dashboard_Presidencia_Mockup.html" y la "Guia_Dashboard_Presidencia_PowerBI.md":
tienen la disposición exacta y las medidas ya existen en el modelo.
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
"metadata": { "type": "Report", "displayName": "Radiografia_Marmotech" },
"config": { "version": "2.0", "logicalId": "554add93-b301-4779-a780-de4189e02962" }
}
@@ -0,0 +1,4 @@
{
"version": "4.0",
"datasetReference": { "byPath": { "path": "../Radiografia_Marmotech.SemanticModel" } }
}
@@ -0,0 +1,8 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/page/1.0.0/schema.json",
"name": "8b8f836c-adf6-4122-94af-ca83a95f1186",
"displayName": "Estructura Financiera",
"displayOption": "FitToPage",
"height": 720,
"width": 1280
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "44ff5e53-b511-41e3-bdd8-48225cf9736d",
"position": { "x": 648, "y": 16, "z": 0, "width": 300, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Capital de Trabajo" } }, "queryRef": "vwPLMensual.Capital de Trabajo", "nativeQueryRef": "Capital de Trabajo" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Capital de Trabajo'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "a03966b2-7a2b-4724-9b6f-9d2a82dfbf1a",
"position": { "x": 16, "y": 16, "z": 0, "width": 300, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Activos" } }, "queryRef": "vwPLMensual.Activos", "nativeQueryRef": "Activos" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Activos Totales'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "aebdc78d-a3c5-45bd-a5a1-33956b52c2af",
"position": { "x": 964, "y": 16, "z": 0, "width": 300, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Endeudamiento %" } }, "queryRef": "vwPLMensual.Endeudamiento %", "nativeQueryRef": "Endeudamiento %" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Endeudamiento'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,14 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "b45f71ca-ef58-4807-9ec8-b326c6cef118",
"position": { "x": 16, "y": 170, "z": 0, "width": 620, "height": 300, "tabOrder": 0 },
"visual": {
"visualType": "clusteredColumnChart",
"query": { "queryState": { "Category": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "vwBalanceMensual" } }, "Property": "grupo_desc" } }, "queryRef": "vwBalanceMensual.grupo_desc", "nativeQueryRef": "grupo_desc" } ] },
"Y": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Saldo (fin periodo)" } }, "queryRef": "vwPLMensual.Saldo (fin periodo)", "nativeQueryRef": "Saldo (fin periodo)" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Activos / Pasivos / Patrimonio'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,14 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "b536c95a-a634-4891-9041-14d33dba3e31",
"position": { "x": 652, "y": 170, "z": 0, "width": 612, "height": 300, "tabOrder": 0 },
"visual": {
"visualType": "tableEx",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "vwBalanceMensual" } }, "Property": "subgrupo_desc" } }, "queryRef": "vwBalanceMensual.subgrupo_desc", "nativeQueryRef": "subgrupo_desc" },
{ "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Saldo (fin periodo)" } }, "queryRef": "vwPLMensual.Saldo (fin periodo)", "nativeQueryRef": "Saldo (fin periodo)" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Composicion'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "dfc8665b-ed52-4a78-ad7a-ceec1bd415d6",
"position": { "x": 332, "y": 16, "z": 0, "width": 300, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Razon Corriente" } }, "queryRef": "vwPLMensual.Razon Corriente", "nativeQueryRef": "Razon Corriente" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Razon Corriente'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,8 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/page/1.0.0/schema.json",
"name": "b1d7c3f7-19f4-4e53-9f46-39c24299735d",
"displayName": "Radiografia",
"displayOption": "FitToPage",
"height": 720,
"width": 1280
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "0001fb8c-bfd0-48b4-8c87-ca2e91ded77e",
"position": { "x": 16, "y": 16, "z": 0, "width": 280, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Ventas Netas" } }, "queryRef": "vwPLMensual.Ventas Netas", "nativeQueryRef": "Ventas Netas" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Ventas Netas'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "1c8b8064-507f-4d74-aafe-996d0e78abcc",
"position": { "x": 652, "y": 484, "z": 0, "width": 300, "height": 120, "tabOrder": 0 },
"visual": {
"visualType": "slicer",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "DimCalendario" } }, "Property": "Anio" } }, "queryRef": "DimCalendario.Anio", "nativeQueryRef": "Anio" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Ano'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,14 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "41b6bf4e-59e7-43d8-bed5-00903f07cf14",
"position": { "x": 16, "y": 170, "z": 0, "width": 620, "height": 300, "tabOrder": 0 },
"visual": {
"visualType": "waterfallChart",
"query": { "queryState": { "Category": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "linea" } }, "queryRef": "vwPLMensual.linea", "nativeQueryRef": "linea" } ] },
"Y": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Utilidad Neta" } }, "queryRef": "vwPLMensual.Utilidad Neta", "nativeQueryRef": "Utilidad Neta" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Estado de Resultados (cascada)'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "7bc4f47e-ea03-4a86-85bc-7b0589403ff3",
"position": { "x": 984, "y": 16, "z": 0, "width": 280, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Utilidad Neta" } }, "queryRef": "vwPLMensual.Utilidad Neta", "nativeQueryRef": "Utilidad Neta" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Utilidad Neta'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "86346a78-aca0-4130-8fcc-df275187d223",
"position": { "x": 688, "y": 16, "z": 0, "width": 280, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Utilidad Operativa" } }, "queryRef": "vwPLMensual.Utilidad Operativa", "nativeQueryRef": "Utilidad Operativa" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Utilidad Operativa'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,15 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "bf867728-d557-4369-a08f-96be202ea340",
"position": { "x": 652, "y": 170, "z": 0, "width": 612, "height": 300, "tabOrder": 0 },
"visual": {
"visualType": "lineClusteredColumnComboChart",
"query": { "queryState": { "Y": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Ventas Netas" } }, "queryRef": "vwPLMensual.Ventas Netas", "nativeQueryRef": "Ventas Netas" } ] },
"Category": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "DimCalendario" } }, "Property": "Mes" } }, "queryRef": "DimCalendario.Mes", "nativeQueryRef": "Mes" } ] },
"Y2": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Utilidad Neta" } }, "queryRef": "vwPLMensual.Utilidad Neta", "nativeQueryRef": "Utilidad Neta" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Comportamiento del periodo (Ventas vs Utilidad)'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,15 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "c16df67e-416b-4acb-8169-fbd21a916682",
"position": { "x": 16, "y": 484, "z": 0, "width": 620, "height": 220, "tabOrder": 0 },
"visual": {
"visualType": "clusteredColumnChart",
"query": { "queryState": { "Category": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "DimCalendario" } }, "Property": "Anio" } }, "queryRef": "DimCalendario.Anio", "nativeQueryRef": "Anio" } ] },
"Y": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Ventas Netas" } }, "queryRef": "vwPLMensual.Ventas Netas", "nativeQueryRef": "Ventas Netas" },
{ "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Utilidad Neta" } }, "queryRef": "vwPLMensual.Utilidad Neta", "nativeQueryRef": "Utilidad Neta" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Trayectoria anual'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "ea44fc7d-26fd-4269-a605-7a460f6078bd",
"position": { "x": 312, "y": 16, "z": 0, "width": 280, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Utilidad Bruta" } }, "queryRef": "vwPLMensual.Utilidad Bruta", "nativeQueryRef": "Utilidad Bruta" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Utilidad Bruta'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,8 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/page/1.0.0/schema.json",
"name": "e77fc1b2-6848-4091-910e-ab9079a10ae3",
"displayName": "Analisis de Gastos",
"displayOption": "FitToPage",
"height": 720,
"width": 1280
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "2970078c-5cf9-40ff-ad03-436e7f9d90c1",
"position": { "x": 16, "y": 16, "z": 0, "width": 300, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Gasto Total" } }, "queryRef": "vwPLMensual.Gasto Total", "nativeQueryRef": "Gasto Total" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Gastos Operativos'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,14 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "55c25809-9340-4b4f-ab44-ea947df2aa20",
"position": { "x": 16, "y": 484, "z": 0, "width": 1248, "height": 220, "tabOrder": 0 },
"visual": {
"visualType": "columnChart",
"query": { "queryState": { "Category": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "DimCalendario" } }, "Property": "Mes" } }, "queryRef": "DimCalendario.Mes", "nativeQueryRef": "Mes" } ] },
"Y": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Gasto Total" } }, "queryRef": "vwPLMensual.Gasto Total", "nativeQueryRef": "Gasto Total" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Gasto mensual'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,14 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "c5d3dccf-c735-4552-97e3-3409f290ae2c",
"position": { "x": 16, "y": 170, "z": 0, "width": 620, "height": 300, "tabOrder": 0 },
"visual": {
"visualType": "barChart",
"query": { "queryState": { "Category": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "vwGastosDepto" } }, "Property": "gerencia" } }, "queryRef": "vwGastosDepto.gerencia", "nativeQueryRef": "gerencia" } ] },
"Y": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Gasto Total" } }, "queryRef": "vwPLMensual.Gasto Total", "nativeQueryRef": "Gasto Total" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Gasto por gerencia'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,15 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "d56cf84c-d5d9-4d14-a4a5-c20b98f0aab6",
"position": { "x": 652, "y": 170, "z": 0, "width": 612, "height": 300, "tabOrder": 0 },
"visual": {
"visualType": "tableEx",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Column": { "Expression": { "SourceRef": { "Entity": "vwGastosDepto" } }, "Property": "subgrupo_desc" } }, "queryRef": "vwGastosDepto.subgrupo_desc", "nativeQueryRef": "subgrupo_desc" },
{ "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Gasto Total" } }, "queryRef": "vwPLMensual.Gasto Total", "nativeQueryRef": "Gasto Total" },
{ "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Gasto % de Ventas" } }, "queryRef": "vwPLMensual.Gasto % de Ventas", "nativeQueryRef": "Gasto % de Ventas" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Naturaleza del gasto'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "f2193414-6ebe-4c68-bb63-1badcb5ffd09",
"position": { "x": 332, "y": 16, "z": 0, "width": 300, "height": 140, "tabOrder": 0 },
"visual": {
"visualType": "card",
"query": { "queryState": { "Values": { "projections": [ { "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "vwPLMensual" } }, "Property": "Gasto % de Ventas" } }, "queryRef": "vwPLMensual.Gasto % de Ventas", "nativeQueryRef": "Gasto % de Ventas" } ] } } },
"drillFilterOtherVisuals": true,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'Gasto / Ventas'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
}
}
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/pagesMetadata/1.0.0/schema.json",
"pageOrder": [ "b1d7c3f7-19f4-4e53-9f46-39c24299735d", "e77fc1b2-6848-4091-910e-ab9079a10ae3", "8b8f836c-adf6-4122-94af-ca83a95f1186" ],
"activePageName": "b1d7c3f7-19f4-4e53-9f46-39c24299735d"
}
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/report/1.0.0/schema.json",
"themeCollection": { "baseTheme": { "name": "CY24SU10" } },
"layoutOptimization": "None"
}
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
"metadata": { "type": "SemanticModel", "displayName": "Radiografia_Marmotech" },
"config": { "version": "2.0", "logicalId": "9189c214-f719-4b14-9985-284d1156b518" }
}
@@ -0,0 +1,4 @@
{
"version": "4.0",
"settings": {}
}
@@ -0,0 +1,2 @@
database
compatibilityLevel: 1550
@@ -0,0 +1,7 @@
model Model
culture: es-ES
defaultPowerBIDataSourceVersion: powerBI_V3
sourceQueryCulture: es-ES
annotation PBI_QueryOrder = ["vwPLMensual","vwGastosDepto","vwBalanceMensual","DimCalendario"]
@@ -0,0 +1,12 @@
relationship a1bca91e-c68e-40d9-903e-6c0b3084d97e
fromColumn: vwPLMensual.fecha_mes
toColumn: DimCalendario.Date
relationship b8a2999c-fc54-47de-8f0b-85af0263c75b
fromColumn: vwGastosDepto.fecha_mes
toColumn: DimCalendario.Date
relationship ea96c86f-8345-4913-b1e6-6823b9a100f4
fromColumn: vwBalanceMensual.fecha_mes
toColumn: DimCalendario.Date
@@ -0,0 +1,42 @@
table DimCalendario
column Date
dataType: dateTime
sourceColumn: [Date]
formatString: General Date
summarizeBy: none
column Anio
dataType: int64
sourceColumn: [Anio]
summarizeBy: none
column MesNo
dataType: int64
sourceColumn: [MesNo]
summarizeBy: none
column Mes
dataType: string
sourceColumn: [Mes]
summarizeBy: none
column AnioMes
dataType: string
sourceColumn: [AnioMes]
summarizeBy: none
column PrimerDiaMes
dataType: dateTime
sourceColumn: [PrimerDiaMes]
formatString: General Date
summarizeBy: none
column Trimestre
dataType: string
sourceColumn: [Trimestre]
summarizeBy: none
partition DimCalendario = calculated
mode: import
source = ADDCOLUMNS ( CALENDAR ( DATE ( 2015, 1, 1 ), DATE ( 2028, 12, 31 ) ), "Anio", YEAR ( [Date] ), "MesNo", MONTH ( [Date] ), "Mes", FORMAT ( [Date], "MMM" ), "AnioMes", FORMAT ( [Date], "yyyy-MM" ), "PrimerDiaMes", DATE ( YEAR ( [Date] ), MONTH ( [Date] ), 1 ), "Trimestre", "T" & FORMAT ( [Date], "Q" ) )
@@ -0,0 +1,81 @@
table vwBalanceMensual
column 'ano'
dataType: int64
sourceColumn: ano
summarizeBy: none
column 'numero_mes'
dataType: int64
sourceColumn: numero_mes
summarizeBy: none
column 'mes'
dataType: string
sourceColumn: mes
summarizeBy: none
column 'AnoMes'
dataType: string
sourceColumn: AnoMes
summarizeBy: none
column 'fecha_mes'
dataType: dateTime
sourceColumn: fecha_mes
formatString: General Date
summarizeBy: none
column 'grupo'
dataType: string
sourceColumn: grupo
summarizeBy: none
column 'grupo_desc'
dataType: string
sourceColumn: grupo_desc
summarizeBy: none
column 'subgrupo_cod'
dataType: string
sourceColumn: subgrupo_cod
summarizeBy: none
column 'subgrupo_desc'
dataType: string
sourceColumn: subgrupo_desc
summarizeBy: none
column 'cuenta'
dataType: string
sourceColumn: cuenta
summarizeBy: none
column 'cuenta_desc'
dataType: string
sourceColumn: cuenta_desc
summarizeBy: none
column 'movimiento_mes'
dataType: decimal
sourceColumn: movimiento_mes
summarizeBy: none
column 'saldo_natural'
dataType: decimal
sourceColumn: saldo_natural
summarizeBy: none
column 'saldo_presentacion'
dataType: decimal
sourceColumn: saldo_presentacion
summarizeBy: none
partition vwBalanceMensual = m
mode: import
source =
let
Origen = Sql.Database("192.168.40.8", "MarmotechBI"),
Datos = Origen{[Schema="presidencia", Item="vwBalanceMensual"]}[Data]
in
Datos
@@ -0,0 +1,91 @@
table vwGastosDepto
column 'ano'
dataType: int64
sourceColumn: ano
summarizeBy: none
column 'numero_mes'
dataType: int64
sourceColumn: numero_mes
summarizeBy: none
column 'mes'
dataType: string
sourceColumn: mes
summarizeBy: none
column 'AnoMes'
dataType: string
sourceColumn: AnoMes
summarizeBy: none
column 'fecha_mes'
dataType: dateTime
sourceColumn: fecha_mes
formatString: General Date
summarizeBy: none
column 'gerencia_cod'
dataType: string
sourceColumn: gerencia_cod
summarizeBy: none
column 'gerencia'
dataType: string
sourceColumn: gerencia
summarizeBy: none
column 'departamento'
dataType: int64
sourceColumn: departamento
summarizeBy: none
column 'depto_nombre'
dataType: string
sourceColumn: depto_nombre
summarizeBy: none
column 'subgrupo_cod'
dataType: string
sourceColumn: subgrupo_cod
summarizeBy: none
column 'subgrupo_desc'
dataType: string
sourceColumn: subgrupo_desc
summarizeBy: none
column 'cuenta'
dataType: string
sourceColumn: cuenta
summarizeBy: none
column 'cuenta_desc'
dataType: string
sourceColumn: cuenta_desc
summarizeBy: none
column 'debito'
dataType: decimal
sourceColumn: debito
summarizeBy: none
column 'credito'
dataType: decimal
sourceColumn: credito
summarizeBy: none
column 'gasto'
dataType: decimal
sourceColumn: gasto
summarizeBy: none
partition vwGastosDepto = m
mode: import
source =
let
Origen = Sql.Database("192.168.40.8", "MarmotechBI"),
Datos = Origen{[Schema="presidencia", Item="vwGastosDepto"]}[Data]
in
Datos
@@ -0,0 +1,163 @@
table vwPLMensual
column 'ano'
dataType: int64
sourceColumn: ano
summarizeBy: none
column 'numero_mes'
dataType: int64
sourceColumn: numero_mes
summarizeBy: none
column 'mes'
dataType: string
sourceColumn: mes
summarizeBy: none
column 'AnoMes'
dataType: string
sourceColumn: AnoMes
summarizeBy: none
column 'fecha_mes'
dataType: dateTime
sourceColumn: fecha_mes
formatString: General Date
summarizeBy: none
column 'grupo'
dataType: string
sourceColumn: grupo
summarizeBy: none
column 'orden_linea'
dataType: int64
sourceColumn: orden_linea
summarizeBy: none
column 'linea'
dataType: string
sourceColumn: linea
summarizeBy: none
column 'subgrupo_cod'
dataType: string
sourceColumn: subgrupo_cod
summarizeBy: none
column 'subgrupo_desc'
dataType: string
sourceColumn: subgrupo_desc
summarizeBy: none
column 'cuenta'
dataType: string
sourceColumn: cuenta
summarizeBy: none
column 'cuenta_desc'
dataType: string
sourceColumn: cuenta_desc
summarizeBy: none
column 'nivel'
dataType: int64
sourceColumn: nivel
summarizeBy: none
column 'debito'
dataType: decimal
sourceColumn: debito
summarizeBy: none
column 'credito'
dataType: decimal
sourceColumn: credito
summarizeBy: none
column 'resultado'
dataType: decimal
sourceColumn: resultado
summarizeBy: none
column 'costo_gasto'
dataType: decimal
sourceColumn: costo_gasto
summarizeBy: none
measure 'Ventas Netas' = CALCULATE ( SUM ( vwPLMensual[resultado] ), vwPLMensual[grupo] = "4" )
formatString: \$ #,0,," M";\$ -#,0,," M";\$ 0
measure 'Costo de Ventas' = CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[grupo] = "5" )
formatString: \$ #,0,," M"
measure 'Gastos Operativos' = CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[grupo] = "7" )
formatString: \$ #,0,," M"
measure 'Otros Ing. y Gastos' = CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[linea] = "Otros Ingresos y Gastos" )
formatString: \$ #,0,," M"
measure 'ISR' = CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[linea] = "Impuesto sobre la Renta" )
formatString: \$ #,0,," M"
measure 'Utilidad Bruta' = [Ventas Netas] - [Costo de Ventas]
formatString: \$ #,0,," M"
measure 'Utilidad Operativa' = [Utilidad Bruta] - [Gastos Operativos]
formatString: \$ #,0,," M"
measure 'Utilidad antes ISR' = [Utilidad Operativa] - [Otros Ing. y Gastos]
formatString: \$ #,0,," M"
measure 'Utilidad Neta' = SUM ( vwPLMensual[resultado] )
formatString: \$ #,0,," M"
measure 'Margen Bruto %' = DIVIDE ( [Utilidad Bruta], [Ventas Netas] )
formatString: 0.0%
measure 'Margen Operativo %' = DIVIDE ( [Utilidad Operativa], [Ventas Netas] )
formatString: 0.0%
measure 'Margen Neto %' = DIVIDE ( [Utilidad Neta], [Ventas Netas] )
formatString: 0.0%
measure 'Costo % Ventas' = DIVIDE ( [Costo de Ventas], [Ventas Netas] )
formatString: 0.0%
measure 'Gastos % Ventas' = DIVIDE ( [Gastos Operativos], [Ventas Netas] )
formatString: 0.0%
measure 'Ventas AA' = CALCULATE ( [Ventas Netas], SAMEPERIODLASTYEAR ( DimCalendario[Date] ) )
formatString: \$ #,0,," M"
measure 'Utilidad Neta AA' = CALCULATE ( [Utilidad Neta], SAMEPERIODLASTYEAR ( DimCalendario[Date] ) )
formatString: \$ #,0,," M"
measure 'Ventas YoY %' = DIVIDE ( [Ventas Netas] - [Ventas AA], [Ventas AA] )
formatString: 0.0%
measure 'Utilidad YoY %' = DIVIDE ( [Utilidad Neta] - [Utilidad Neta AA], [Utilidad Neta AA] )
formatString: 0.0%
measure 'Ventas YTD' = TOTALYTD ( [Ventas Netas], DimCalendario[Date] )
formatString: \$ #,0,," M"
measure 'Utilidad Neta YTD' = TOTALYTD ( [Utilidad Neta], DimCalendario[Date] )
formatString: \$ #,0,," M"
measure 'Gasto Total' = SUM ( vwGastosDepto[gasto] )
formatString: \$ #,0,," M"
measure 'Gasto AA' = CALCULATE ( [Gasto Total], SAMEPERIODLASTYEAR ( DimCalendario[Date] ) )
formatString: \$ #,0,," M"
measure 'Gasto YoY %' = DIVIDE ( [Gasto Total] - [Gasto AA], [Gasto AA] )
formatString: 0.0%
measure 'Gasto % de Ventas' = DIVIDE ( [Gasto Total], [Ventas Netas] )
formatString: 0.0%
measure 'Saldo (fin periodo)' = VAR u = MAX ( vwBalanceMensual[fecha_mes] ) RETURN CALCULATE ( SUM ( vwBalanceMensual[saldo_presentacion] ), vwBalanceMensual[fecha_mes] = u )
formatString: \$ #,0,," M"
measure 'Activos' = CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[grupo] = "1" )
formatString: \$ #,0,," M"
measure 'Pasivos' = CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[grupo] = "2" )
formatString: \$ #,0,," M"
measure 'Patrimonio' = CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[grupo] = "3" )
formatString: \$ #,0,," M"
measure 'Activo Corriente' = CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[subgrupo_cod] = "11" )
formatString: \$ #,0,," M"
measure 'Pasivo Corriente' = CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[subgrupo_cod] IN {"20","21"} )
formatString: \$ #,0,," M"
measure 'Razon Corriente' = DIVIDE ( [Activo Corriente], [Pasivo Corriente] )
formatString: 0.00
measure 'Capital de Trabajo' = [Activo Corriente] - [Pasivo Corriente]
formatString: \$ #,0,," M"
measure 'Endeudamiento %' = DIVIDE ( [Pasivos], [Activos] )
formatString: 0.0%
partition vwPLMensual = m
mode: import
source =
let
Origen = Sql.Database("192.168.40.8", "MarmotechBI"),
Datos = Origen{[Schema="presidencia", Item="vwPLMensual"]}[Data]
in
Datos
@@ -0,0 +1,7 @@
{
"version": "1.0",
"artifacts": [
{ "report": { "path": "Radiografia_Marmotech.Report" } }
],
"settings": { "enableAutoRecovery": true }
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,226 @@
/* ============================================================================
MarmotechBI — Vistas para el Dashboard Ejecutivo de Presidencia
----------------------------------------------------------------------------
Autor : Juan F. Soto (jsoto)
Fecha : 2026-08-26
Servidor : 192.168.40.8 (SQL Server 2016)
Base : MarmotechBI (capa semantica; los datos viven en marmotech.dbo.*)
Objetivo : Radiografia financiera para el Presidente, a partir del
Mayor General Analitico (cgprrp008) y el Analisis de Gastos
por Departamento (cgprrp009).
Fuente de datos:
marmotech.dbo.cgtb00004 = transacciones contables (debito/credito por cuenta/fecha)
marmotech.dbo.cgtb00001 = catalogo de cuentas (nivel, descripcion)
marmotech.dbo.prdtable = periodos contables (ano, mes -> rango de fechas)
marmotech.dbo.mestable = nombres de meses
marmotech.dbo.adtb00001 = departamentos (nom_dpto)
Reglas de negocio (validadas contra cgprrp008 / cgprrp009):
* Estado de Resultados por PRIMER DIGITO de la cuenta:
4 = VENTAS NETA (naturaleza credito)
5 = COSTO DE VENTAS (naturaleza debito)
7 = GASTOS (naturaleza debito)
8 = OTROS INGRESOS Y GASTOS (incluye 88 = IMPUESTO S/RENTA)
* resultado (aporte a la utilidad) = credito - debito
-> Ventas suma positivo; Costo/Gastos/ISR restan; la suma de todas
las lineas = Utilidad Neta del periodo.
* Solo transacciones activas: status_t IS NULL.
* Se EXCLUYE el asiento de cierre anual (ref 'ED.99-001/12YY' y
'ED.99-002/12YY'); de lo contrario cada ano cerrado netearia a 0 porque
el cierre revierte las cuentas de resultado contra Utilidades Retenidas.
(2026 aun no tiene cierre, por eso muestra saldo operativo real.)
Seguridad (requisito): estas vistas solo deben ser legibles por jsoto.
Se crean en el esquema [presidencia] y se hace DENY SELECT a [public].
jsoto (MARMOTECH\jsoto y login SQL jsoto) es sysadmin/db_owner, por lo que
ignora el DENY y conserva acceso; el resto del equipo (db_datareader) queda
bloqueado a nivel de esquema.
============================================================================ */
USE MarmotechBI;
GO
/* ---- 1. Esquema dedicado ------------------------------------------------- */
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'presidencia')
EXEC('CREATE SCHEMA presidencia AUTHORIZATION dbo;');
GO
/* ---- 2. Estado de Resultados mensual (cgprrp008) ------------------------- */
/* Grano: ano x mes x cuenta. Un renglon por cuenta contable de resultado. */
IF OBJECT_ID('presidencia.vwPLMensual','V') IS NOT NULL
DROP VIEW presidencia.vwPLMensual;
GO
CREATE VIEW presidencia.vwPLMensual
AS
WITH mov AS (
SELECT p.ano,
p.mes AS numero_mes,
b.cuenta_no,
SUM(b.debito) AS debito,
SUM(b.credito) AS credito
FROM marmotech.dbo.cgtb00004 b
INNER JOIN marmotech.dbo.prdtable p
ON b.fecha BETWEEN p.fecha_inicio AND p.fecha_corte
WHERE b.status_t IS NULL
AND LEFT(b.cuenta_no,1) IN ('4','5','7','8')
AND b.ref NOT LIKE 'ED.99-001/12%' -- asiento de cierre anual
AND b.ref NOT LIKE 'ED.99-002/12%' -- asiento de cierre anual (variante)
GROUP BY p.ano, p.mes, b.cuenta_no
)
SELECT
m.ano,
m.numero_mes,
ms.descrip AS mes,
RIGHT('0000'+CONVERT(varchar(4),m.ano),4) + '-' +
RIGHT('00'+CONVERT(varchar(2),m.numero_mes),2) AS AnoMes,
DATEFROMPARTS(m.ano, m.numero_mes, 1) AS fecha_mes,
LEFT(m.cuenta_no,1) AS grupo,
CASE LEFT(m.cuenta_no,1)
WHEN '4' THEN 1 WHEN '5' THEN 2 WHEN '7' THEN 3
WHEN '8' THEN CASE WHEN m.cuenta_no LIKE '88%' THEN 5 ELSE 4 END
END AS orden_linea,
CASE LEFT(m.cuenta_no,1)
WHEN '4' THEN 'Ventas Netas'
WHEN '5' THEN 'Costo de Ventas'
WHEN '7' THEN 'Gastos Operativos'
WHEN '8' THEN CASE WHEN m.cuenta_no LIKE '88%'
THEN 'Impuesto sobre la Renta'
ELSE 'Otros Ingresos y Gastos' END
END AS linea,
LEFT(m.cuenta_no,2) AS subgrupo_cod,
sg.descripcion AS subgrupo_desc,
m.cuenta_no AS cuenta,
ct.descripcion AS cuenta_desc,
ct.nivel,
m.debito,
m.credito,
CAST(m.credito - m.debito AS decimal(19,2)) AS resultado, -- + = aporta utilidad
CAST(m.debito - m.credito AS decimal(19,2)) AS costo_gasto -- + = costo/gasto
FROM mov m
LEFT JOIN marmotech.dbo.cgtb00001 ct ON ct.cuenta_no = m.cuenta_no
LEFT JOIN marmotech.dbo.cgtb00001 sg ON sg.cuenta_no = LEFT(m.cuenta_no,2)
LEFT JOIN marmotech.dbo.mestable ms ON ms.mes = m.numero_mes;
GO
/* ---- 3. Analisis de Gastos por Departamento (cgprrp009) ------------------ */
/* Grano: ano x mes x departamento x cuenta. Solo grupo 7 (GASTOS). */
IF OBJECT_ID('presidencia.vwGastosDepto','V') IS NOT NULL
DROP VIEW presidencia.vwGastosDepto;
GO
CREATE VIEW presidencia.vwGastosDepto
AS
WITH mov AS (
SELECT p.ano,
p.mes AS numero_mes,
ISNULL(b.departamento,0) AS departamento,
b.cuenta_no,
SUM(b.debito) AS debito,
SUM(b.credito) AS credito
FROM marmotech.dbo.cgtb00004 b
INNER JOIN marmotech.dbo.prdtable p
ON b.fecha BETWEEN p.fecha_inicio AND p.fecha_corte
WHERE b.status_t IS NULL
AND LEFT(b.cuenta_no,1) = '7'
AND b.ref NOT LIKE 'ED.99-001/12%'
AND b.ref NOT LIKE 'ED.99-002/12%'
GROUP BY p.ano, p.mes, ISNULL(b.departamento,0), b.cuenta_no
)
SELECT
m.ano,
m.numero_mes,
ms.descrip AS mes,
RIGHT('0000'+CONVERT(varchar(4),m.ano),4) + '-' +
RIGHT('00'+CONVERT(varchar(2),m.numero_mes),2) AS AnoMes,
DATEFROMPARTS(m.ano, m.numero_mes, 1) AS fecha_mes,
LEFT(CONVERT(varchar(4),m.departamento),1) AS gerencia_cod,
CASE LEFT(CONVERT(varchar(4),m.departamento),1)
WHEN '1' THEN 'Gerencia General'
WHEN '2' THEN 'Administracion y Materiales'
WHEN '3' THEN 'Gestion Humana'
WHEN '4' THEN 'Ventas y Mercadeo'
WHEN '5' THEN 'Canteras'
WHEN '6' THEN 'Planta / Produccion'
WHEN '7' THEN 'Planta Agregados'
WHEN '8' THEN 'Marmotech en Caribbean'
ELSE 'Sin Departamento'
END AS gerencia,
m.departamento,
ISNULL(ad.nom_dpto,'SIN DEPARTAMENTO') AS depto_nombre,
LEFT(m.cuenta_no,2) AS subgrupo_cod,
sg.descripcion AS subgrupo_desc,
m.cuenta_no AS cuenta,
ct.descripcion AS cuenta_desc,
m.debito,
m.credito,
CAST(m.debito - m.credito AS decimal(19,2)) AS gasto -- + = gasto neto
FROM mov m
LEFT JOIN marmotech.dbo.cgtb00001 ct ON ct.cuenta_no = m.cuenta_no
LEFT JOIN marmotech.dbo.cgtb00001 sg ON sg.cuenta_no = LEFT(m.cuenta_no,2)
LEFT JOIN marmotech.dbo.adtb00001 ad ON ad.departamento = m.departamento
LEFT JOIN marmotech.dbo.mestable ms ON ms.mes = m.numero_mes;
GO
/* ---- 4. Balance General / Estructura financiera (saldo acumulado) -------- */
/* Grano: ano x mes x cuenta, grupos 1 (Activos) 2 (Pasivos) 3 (Capital). */
/* saldo_acumulado = saldo contable al cierre del mes (deb-cred acumulado). */
IF OBJECT_ID('presidencia.vwBalanceMensual','V') IS NOT NULL
DROP VIEW presidencia.vwBalanceMensual;
GO
CREATE VIEW presidencia.vwBalanceMensual
AS
WITH mov AS (
SELECT p.ano,
p.mes AS numero_mes,
b.cuenta_no,
SUM(b.debito - b.credito) AS movimiento
FROM marmotech.dbo.cgtb00004 b
INNER JOIN marmotech.dbo.prdtable p
ON b.fecha BETWEEN p.fecha_inicio AND p.fecha_corte
WHERE b.status_t IS NULL
AND LEFT(b.cuenta_no,1) IN ('1','2','3')
GROUP BY p.ano, p.mes, b.cuenta_no
),
acum AS (
SELECT m.*,
SUM(m.movimiento) OVER (PARTITION BY m.cuenta_no
ORDER BY m.ano, m.numero_mes
ROWS UNBOUNDED PRECEDING) AS saldo_acumulado
FROM mov m
)
SELECT
a.ano,
a.numero_mes,
ms.descrip AS mes,
RIGHT('0000'+CONVERT(varchar(4),a.ano),4) + '-' +
RIGHT('00'+CONVERT(varchar(2),a.numero_mes),2) AS AnoMes,
DATEFROMPARTS(a.ano, a.numero_mes, 1) AS fecha_mes,
LEFT(a.cuenta_no,1) AS grupo,
CASE LEFT(a.cuenta_no,1) WHEN '1' THEN 'Activos'
WHEN '2' THEN 'Pasivos'
WHEN '3' THEN 'Capital' END AS grupo_desc,
LEFT(a.cuenta_no,2) AS subgrupo_cod,
sg.descripcion AS subgrupo_desc,
a.cuenta_no AS cuenta,
ct.descripcion AS cuenta_desc,
CAST(a.movimiento AS decimal(19,2)) AS movimiento_mes,
CAST(a.saldo_acumulado AS decimal(19,2)) AS saldo_natural, -- deb-cred
/* Presentacion: Activos positivos por debito; Pasivos/Capital por credito */
CAST(CASE WHEN LEFT(a.cuenta_no,1) = '1' THEN a.saldo_acumulado
ELSE -a.saldo_acumulado END AS decimal(19,2)) AS saldo_presentacion
FROM acum a
LEFT JOIN marmotech.dbo.cgtb00001 ct ON ct.cuenta_no = a.cuenta_no
LEFT JOIN marmotech.dbo.cgtb00001 sg ON sg.cuenta_no = LEFT(a.cuenta_no,2)
LEFT JOIN marmotech.dbo.mestable ms ON ms.mes = a.numero_mes;
GO
/* ---- 5. Seguridad: solo jsoto ------------------------------------------- */
DENY SELECT ON SCHEMA::presidencia TO [public];
GO
/* Concesion explicita (documenta la intencion; jsoto ya es db_owner/sysadmin) */
IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = 'MARMOTECH\jsoto')
GRANT SELECT ON SCHEMA::presidencia TO [MARMOTECH\jsoto];
GO
IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = 'jsoto')
GRANT SELECT ON SCHEMA::presidencia TO [jsoto];
GO
@@ -0,0 +1,342 @@
<# Genera el proyecto Power BI (.pbip) "Radiografia_Marmotech"
Modelo (TMDL) con las 3 vistas de presidencia + DimCalendario + medidas DAX,
y un reporte (PBIR) con 3 paginas. Abrir el .pbip en Power BI Desktop y
Guardar como .pbix.
Autor: jsoto · 2026-08-26
#>
param(
[string]$Root = "C:\Users\jsoto\Documents\NACE\proyectos\Fuentes\MARMOTECH\Dashboards MARMOTECH\Radiografia_Marmotech"
)
$ErrorActionPreference = "Stop"
$Name = "Radiografia_Marmotech"
$SM = Join-Path $Root "$Name.SemanticModel"
$RP = Join-Path $Root "$Name.Report"
if(Test-Path $Root){ Remove-Item $Root -Recurse -Force }
New-Item -ItemType Directory -Force -Path $Root,$SM,(Join-Path $SM "definition"),(Join-Path $SM "definition\tables"),$RP,(Join-Path $RP "definition"),(Join-Path $RP "definition\pages") | Out-Null
function W($path,$content){
$dir = Split-Path $path -Parent
if(!(Test-Path $dir)){ New-Item -ItemType Directory -Force -Path $dir | Out-Null }
# UTF-8 sin BOM
[System.IO.File]::WriteAllText($path, $content, (New-Object System.Text.UTF8Encoding($false)))
}
function G(){ [guid]::NewGuid().ToString() }
$TAB = [char]9
# ---------------- .pbip ----------------
W (Join-Path $Root "$Name.pbip") @"
{
"version": "1.0",
"artifacts": [
{ "report": { "path": "$Name.Report" } }
],
"settings": { "enableAutoRecovery": true }
}
"@
# ---------------- SemanticModel/.platform ----------------
W (Join-Path $SM ".platform") @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
"metadata": { "type": "SemanticModel", "displayName": "$Name" },
"config": { "version": "2.0", "logicalId": "$(G)" }
}
"@
# ---------------- SemanticModel/definition.pbism ----------------
W (Join-Path $SM "definition.pbism") @"
{
"version": "4.0",
"settings": {}
}
"@
# ---------------- database.tmdl ----------------
W (Join-Path $SM "definition\database.tmdl") ("database`n${TAB}compatibilityLevel: 1550`n")
# ---------------- model.tmdl ----------------
$model = @()
$model += "model Model"
$model += "${TAB}culture: es-ES"
$model += "${TAB}defaultPowerBIDataSourceVersion: powerBI_V3"
$model += "${TAB}sourceQueryCulture: es-ES"
$model += ""
$model += "annotation PBI_QueryOrder = [`"vwPLMensual`",`"vwGastosDepto`",`"vwBalanceMensual`",`"DimCalendario`"]"
$model += ""
W (Join-Path $SM "definition\model.tmdl") (($model -join "`n") + "`n")
# ---------------- helper: tabla desde vista SQL ----------------
function Table-Sql($tname,$cols){
# cols: array de "nombre|tipo"
$l = @()
$l += "table $tname"
foreach($c in $cols){
$p = $c.Split("|"); $cn=$p[0]; $ct=$p[1]
$l += "${TAB}column '$cn'"
$l += "${TAB}${TAB}dataType: $ct"
$l += "${TAB}${TAB}sourceColumn: $cn"
if($ct -eq "dateTime"){ $l += "${TAB}${TAB}formatString: General Date" }
$l += "${TAB}${TAB}summarizeBy: none"
$l += ""
}
$l += "${TAB}partition $tname = m"
$l += "${TAB}${TAB}mode: import"
$l += "${TAB}${TAB}source ="
$l += "${TAB}${TAB}${TAB}${TAB}let"
$l += "${TAB}${TAB}${TAB}${TAB} Origen = Sql.Database(`"192.168.40.8`", `"MarmotechBI`"),"
$l += "${TAB}${TAB}${TAB}${TAB} Datos = Origen{[Schema=`"presidencia`", Item=`"$tname`"]}[Data]"
$l += "${TAB}${TAB}${TAB}${TAB}in"
$l += "${TAB}${TAB}${TAB}${TAB} Datos"
$l += ""
return ($l -join "`n") + "`n"
}
$plCols = @("ano|int64","numero_mes|int64","mes|string","AnoMes|string","fecha_mes|dateTime","grupo|string","orden_linea|int64","linea|string","subgrupo_cod|string","subgrupo_desc|string","cuenta|string","cuenta_desc|string","nivel|int64","debito|decimal","credito|decimal","resultado|decimal","costo_gasto|decimal")
$gsCols = @("ano|int64","numero_mes|int64","mes|string","AnoMes|string","fecha_mes|dateTime","gerencia_cod|string","gerencia|string","departamento|int64","depto_nombre|string","subgrupo_cod|string","subgrupo_desc|string","cuenta|string","cuenta_desc|string","debito|decimal","credito|decimal","gasto|decimal")
$blCols = @("ano|int64","numero_mes|int64","mes|string","AnoMes|string","fecha_mes|dateTime","grupo|string","grupo_desc|string","subgrupo_cod|string","subgrupo_desc|string","cuenta|string","cuenta_desc|string","movimiento_mes|decimal","saldo_natural|decimal","saldo_presentacion|decimal")
# --- vwPLMensual (aloja las medidas) ---
$pl = Table-Sql "vwPLMensual" $plCols
# medidas
$M = @()
function Meas($n,$expr,$fmt){
$s = @()
$s += "${TAB}measure '$n' = $expr"
if($fmt){ $s += "${TAB}${TAB}formatString: $fmt" }
$s += ""
return ($s -join "`n")
}
$m0 = "`n"
$m0 += Meas "Ventas Netas" "CALCULATE ( SUM ( vwPLMensual[resultado] ), vwPLMensual[grupo] = `"4`" )" "\`$ #,0,,`" M`";\`$ -#,0,,`" M`";\`$ 0"
$m0 += Meas "Costo de Ventas" "CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[grupo] = `"5`" )" "\`$ #,0,,`" M`""
$m0 += Meas "Gastos Operativos" "CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[grupo] = `"7`" )" "\`$ #,0,,`" M`""
$m0 += Meas "Otros Ing. y Gastos" "CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[linea] = `"Otros Ingresos y Gastos`" )" "\`$ #,0,,`" M`""
$m0 += Meas "ISR" "CALCULATE ( SUM ( vwPLMensual[costo_gasto] ), vwPLMensual[linea] = `"Impuesto sobre la Renta`" )" "\`$ #,0,,`" M`""
$m0 += Meas "Utilidad Bruta" "[Ventas Netas] - [Costo de Ventas]" "\`$ #,0,,`" M`""
$m0 += Meas "Utilidad Operativa" "[Utilidad Bruta] - [Gastos Operativos]" "\`$ #,0,,`" M`""
$m0 += Meas "Utilidad antes ISR" "[Utilidad Operativa] - [Otros Ing. y Gastos]" "\`$ #,0,,`" M`""
$m0 += Meas "Utilidad Neta" "SUM ( vwPLMensual[resultado] )" "\`$ #,0,,`" M`""
$m0 += Meas "Margen Bruto %" "DIVIDE ( [Utilidad Bruta], [Ventas Netas] )" "0.0%"
$m0 += Meas "Margen Operativo %" "DIVIDE ( [Utilidad Operativa], [Ventas Netas] )" "0.0%"
$m0 += Meas "Margen Neto %" "DIVIDE ( [Utilidad Neta], [Ventas Netas] )" "0.0%"
$m0 += Meas "Costo % Ventas" "DIVIDE ( [Costo de Ventas], [Ventas Netas] )" "0.0%"
$m0 += Meas "Gastos % Ventas" "DIVIDE ( [Gastos Operativos], [Ventas Netas] )" "0.0%"
$m0 += Meas "Ventas AA" "CALCULATE ( [Ventas Netas], SAMEPERIODLASTYEAR ( DimCalendario[Date] ) )" "\`$ #,0,,`" M`""
$m0 += Meas "Utilidad Neta AA" "CALCULATE ( [Utilidad Neta], SAMEPERIODLASTYEAR ( DimCalendario[Date] ) )" "\`$ #,0,,`" M`""
$m0 += Meas "Ventas YoY %" "DIVIDE ( [Ventas Netas] - [Ventas AA], [Ventas AA] )" "0.0%"
$m0 += Meas "Utilidad YoY %" "DIVIDE ( [Utilidad Neta] - [Utilidad Neta AA], [Utilidad Neta AA] )" "0.0%"
$m0 += Meas "Ventas YTD" "TOTALYTD ( [Ventas Netas], DimCalendario[Date] )" "\`$ #,0,,`" M`""
$m0 += Meas "Utilidad Neta YTD" "TOTALYTD ( [Utilidad Neta], DimCalendario[Date] )" "\`$ #,0,,`" M`""
# medidas de gastos
$m0 += Meas "Gasto Total" "SUM ( vwGastosDepto[gasto] )" "\`$ #,0,,`" M`""
$m0 += Meas "Gasto AA" "CALCULATE ( [Gasto Total], SAMEPERIODLASTYEAR ( DimCalendario[Date] ) )" "\`$ #,0,,`" M`""
$m0 += Meas "Gasto YoY %" "DIVIDE ( [Gasto Total] - [Gasto AA], [Gasto AA] )" "0.0%"
$m0 += Meas "Gasto % de Ventas" "DIVIDE ( [Gasto Total], [Ventas Netas] )" "0.0%"
# medidas de balance
$m0 += Meas "Saldo (fin periodo)" "VAR u = MAX ( vwBalanceMensual[fecha_mes] ) RETURN CALCULATE ( SUM ( vwBalanceMensual[saldo_presentacion] ), vwBalanceMensual[fecha_mes] = u )" "\`$ #,0,,`" M`""
$m0 += Meas "Activos" "CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[grupo] = `"1`" )" "\`$ #,0,,`" M`""
$m0 += Meas "Pasivos" "CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[grupo] = `"2`" )" "\`$ #,0,,`" M`""
$m0 += Meas "Patrimonio" "CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[grupo] = `"3`" )" "\`$ #,0,,`" M`""
$m0 += Meas "Activo Corriente" "CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[subgrupo_cod] = `"11`" )" "\`$ #,0,,`" M`""
$m0 += Meas "Pasivo Corriente" "CALCULATE ( [Saldo (fin periodo)], vwBalanceMensual[subgrupo_cod] IN {`"20`",`"21`"} )" "\`$ #,0,,`" M`""
$m0 += Meas "Razon Corriente" "DIVIDE ( [Activo Corriente], [Pasivo Corriente] )" "0.00"
$m0 += Meas "Capital de Trabajo" "[Activo Corriente] - [Pasivo Corriente]" "\`$ #,0,,`" M`""
$m0 += Meas "Endeudamiento %" "DIVIDE ( [Pasivos], [Activos] )" "0.0%"
# insertar medidas antes de la particion (deben ir dentro de la tabla, antes de 'partition')
$pl = $pl -replace "(?s)(${TAB}partition vwPLMensual = m)", ($m0 + "`$1")
W (Join-Path $SM "definition\tables\vwPLMensual.tmdl") $pl
W (Join-Path $SM "definition\tables\vwGastosDepto.tmdl") (Table-Sql "vwGastosDepto" $gsCols)
W (Join-Path $SM "definition\tables\vwBalanceMensual.tmdl") (Table-Sql "vwBalanceMensual" $blCols)
# ---------------- DimCalendario (tabla calculada) ----------------
$dc = @()
$dc += "table DimCalendario"
foreach($c in @("Date|dateTime","Anio|int64","MesNo|int64","Mes|string","AnioMes|string","PrimerDiaMes|dateTime","Trimestre|string")){
$p=$c.Split("|");$cn=$p[0];$ct=$p[1]
$dc += "${TAB}column $cn"
$dc += "${TAB}${TAB}dataType: $ct"
$dc += "${TAB}${TAB}sourceColumn: [$cn]"
if($ct -eq "dateTime"){ $dc += "${TAB}${TAB}formatString: General Date" }
$dc += "${TAB}${TAB}summarizeBy: none"
$dc += ""
}
$dax = 'ADDCOLUMNS ( CALENDAR ( DATE ( 2015, 1, 1 ), DATE ( 2028, 12, 31 ) ), "Anio", YEAR ( [Date] ), "MesNo", MONTH ( [Date] ), "Mes", FORMAT ( [Date], "MMM" ), "AnioMes", FORMAT ( [Date], "yyyy-MM" ), "PrimerDiaMes", DATE ( YEAR ( [Date] ), MONTH ( [Date] ), 1 ), "Trimestre", "T" & FORMAT ( [Date], "Q" ) )'
$dc += "${TAB}partition DimCalendario = calculated"
$dc += "${TAB}${TAB}mode: import"
$dc += "${TAB}${TAB}source = $dax"
$dc += ""
W (Join-Path $SM "definition\tables\DimCalendario.tmdl") (($dc -join "`n") + "`n")
# ---------------- relationships.tmdl ----------------
$rel = @()
foreach($t in @("vwPLMensual","vwGastosDepto","vwBalanceMensual")){
$rel += "relationship $(G)"
$rel += "${TAB}fromColumn: $t.fecha_mes"
$rel += "${TAB}toColumn: DimCalendario.Date"
$rel += ""
}
W (Join-Path $SM "definition\relationships.tmdl") (($rel -join "`n") + "`n")
Write-Output "SemanticModel escrito."
# =====================================================================
# REPORTE (PBIR)
# =====================================================================
W (Join-Path $RP ".platform") @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
"metadata": { "type": "Report", "displayName": "$Name" },
"config": { "version": "2.0", "logicalId": "$(G)" }
}
"@
W (Join-Path $RP "definition.pbir") @"
{
"version": "4.0",
"datasetReference": { "byPath": { "path": "../$Name.SemanticModel" } }
}
"@
# PBIR exige version.json dentro de definition/
W (Join-Path $RP "definition\version.json") @"
{
"version": "2.0.0"
}
"@
W (Join-Path $RP "definition\report.json") @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/report/1.0.0/schema.json",
"themeCollection": { "baseTheme": { "name": "CY24SU10" } },
"layoutOptimization": "None"
}
"@
# ---- helpers de visuales PBIR ----
function Field-Measure($entity,$prop){
return @"
{ "field": { "Measure": { "Expression": { "SourceRef": { "Entity": "$entity" } }, "Property": "$prop" } }, "queryRef": "$entity.$prop", "nativeQueryRef": "$prop" }
"@
}
function Field-Column($entity,$prop){
return @"
{ "field": { "Column": { "Expression": { "SourceRef": { "Entity": "$entity" } }, "Property": "$prop" } }, "queryRef": "$entity.$prop", "nativeQueryRef": "$prop" }
"@
}
# roles: hashtable rol -> array de proyecciones json
function Visual($pageDir,$vtype,$x,$y,$w,$h,$roles,$title){
$vid = G
$vdir = Join-Path $pageDir "visuals\$vid"
New-Item -ItemType Directory -Force -Path $vdir | Out-Null
$projBlocks = @()
foreach($r in $roles.Keys){
$items = ($roles[$r] -join ",`n")
$projBlocks += "`"$r`": { `"projections`": [ $items ] }"
}
$queryState = ($projBlocks -join ",`n")
$titleObj = ""
if($title){
$titleObj = @"
,
"objects": {
"title": [ { "properties": { "text": { "expr": { "Literal": { "Value": "'$title'" } } }, "show": { "expr": { "Literal": { "Value": "true" } } } } } ]
}
"@
}
$json = @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/1.0.0/schema.json",
"name": "$vid",
"position": { "x": $x, "y": $y, "z": 0, "width": $w, "height": $h, "tabOrder": 0 },
"visual": {
"visualType": "$vtype",
"query": { "queryState": { $queryState } },
"drillFilterOtherVisuals": true$titleObj
}
}
"@
W (Join-Path $vdir "visual.json") $json
return $vid
}
$pageIds = @()
# ============ PAGINA 1: Radiografia ============
$p1 = G; $pageIds += $p1
$p1dir = Join-Path $RP "definition\pages\$p1"
New-Item -ItemType Directory -Force -Path $p1dir | Out-Null
W (Join-Path $p1dir "page.json") @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/page/1.0.0/schema.json",
"name": "$p1",
"displayName": "Radiografia",
"displayOption": "FitToPage",
"height": 720,
"width": 1280
}
"@
[void](Visual $p1dir "card" 16 16 280 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Ventas Netas")) } "Ventas Netas")
[void](Visual $p1dir "card" 312 16 280 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Utilidad Bruta")) } "Utilidad Bruta")
[void](Visual $p1dir "card" 688 16 280 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Utilidad Operativa")) } "Utilidad Operativa")
[void](Visual $p1dir "card" 984 16 280 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Utilidad Neta")) } "Utilidad Neta")
[void](Visual $p1dir "waterfallChart" 16 170 620 300 @{ "Category" = @((Field-Column "vwPLMensual" "linea")); "Y" = @((Field-Measure "vwPLMensual" "Utilidad Neta")) } "Estado de Resultados (cascada)")
[void](Visual $p1dir "lineClusteredColumnComboChart" 652 170 612 300 @{ "Category" = @((Field-Column "DimCalendario" "Mes")); "Y" = @((Field-Measure "vwPLMensual" "Ventas Netas")); "Y2" = @((Field-Measure "vwPLMensual" "Utilidad Neta")) } "Comportamiento del periodo (Ventas vs Utilidad)")
[void](Visual $p1dir "clusteredColumnChart" 16 484 620 220 @{ "Category" = @((Field-Column "DimCalendario" "Anio")); "Y" = @((Field-Measure "vwPLMensual" "Ventas Netas"),(Field-Measure "vwPLMensual" "Utilidad Neta")) } "Trayectoria anual")
[void](Visual $p1dir "slicer" 652 484 300 120 @{ "Values" = @((Field-Column "DimCalendario" "Anio")) } "Ano")
# ============ PAGINA 2: Gastos ============
$p2 = G; $pageIds += $p2
$p2dir = Join-Path $RP "definition\pages\$p2"
New-Item -ItemType Directory -Force -Path $p2dir | Out-Null
W (Join-Path $p2dir "page.json") @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/page/1.0.0/schema.json",
"name": "$p2",
"displayName": "Analisis de Gastos",
"displayOption": "FitToPage",
"height": 720,
"width": 1280
}
"@
[void](Visual $p2dir "card" 16 16 300 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Gasto Total")) } "Gastos Operativos")
[void](Visual $p2dir "card" 332 16 300 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Gasto % de Ventas")) } "Gasto / Ventas")
[void](Visual $p2dir "barChart" 16 170 620 300 @{ "Category" = @((Field-Column "vwGastosDepto" "gerencia")); "Y" = @((Field-Measure "vwPLMensual" "Gasto Total")) } "Gasto por gerencia")
[void](Visual $p2dir "tableEx" 652 170 612 300 @{ "Values" = @((Field-Column "vwGastosDepto" "subgrupo_desc"),(Field-Measure "vwPLMensual" "Gasto Total"),(Field-Measure "vwPLMensual" "Gasto % de Ventas")) } "Naturaleza del gasto")
[void](Visual $p2dir "columnChart" 16 484 1248 220 @{ "Category" = @((Field-Column "DimCalendario" "Mes")); "Y" = @((Field-Measure "vwPLMensual" "Gasto Total")) } "Gasto mensual")
# ============ PAGINA 3: Estructura ============
$p3 = G; $pageIds += $p3
$p3dir = Join-Path $RP "definition\pages\$p3"
New-Item -ItemType Directory -Force -Path $p3dir | Out-Null
W (Join-Path $p3dir "page.json") @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/page/1.0.0/schema.json",
"name": "$p3",
"displayName": "Estructura Financiera",
"displayOption": "FitToPage",
"height": 720,
"width": 1280
}
"@
[void](Visual $p3dir "card" 16 16 300 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Activos")) } "Activos Totales")
[void](Visual $p3dir "card" 332 16 300 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Razon Corriente")) } "Razon Corriente")
[void](Visual $p3dir "card" 648 16 300 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Capital de Trabajo")) } "Capital de Trabajo")
[void](Visual $p3dir "card" 964 16 300 140 @{ "Values" = @((Field-Measure "vwPLMensual" "Endeudamiento %")) } "Endeudamiento")
[void](Visual $p3dir "clusteredColumnChart" 16 170 620 300 @{ "Category" = @((Field-Column "vwBalanceMensual" "grupo_desc")); "Y" = @((Field-Measure "vwPLMensual" "Saldo (fin periodo)")) } "Activos / Pasivos / Patrimonio")
[void](Visual $p3dir "tableEx" 652 170 612 300 @{ "Values" = @((Field-Column "vwBalanceMensual" "subgrupo_desc"),(Field-Measure "vwPLMensual" "Saldo (fin periodo)")) } "Composicion")
# ---------------- pages.json ----------------
$order = ($pageIds | ForEach-Object { "`"$_`"" }) -join ", "
W (Join-Path $RP "definition\pages\pages.json") @"
{
"`$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/pagesMetadata/1.0.0/schema.json",
"pageOrder": [ $order ],
"activePageName": "$($pageIds[0])"
}
"@
Write-Output "Reporte escrito."
Write-Output ("PROYECTO GENERADO EN: " + $Root)
Get-ChildItem -Recurse $Root | Measure-Object | ForEach-Object { Write-Output ("Archivos: " + $_.Count) }
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+117
View File
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ManagedForm fileVersion="31400" gstVersion="3140a" name="ManagedForm" uid="{8f013df5-71e9-4123-ace5-57cb0d559141}">
<AGSettings>
<DynamicProperties version="2"/>
</AGSettings>
<Record name="scr_costos" uid="{1072830e-e04e-4a63-8f41-4aa8efa5ffaa}">
<RecordField colName="tipo" fieldIdRef="11" name="tipo" sqlTabName="formonly" uid="{d9350682-2ead-47c0-8563-a7d127b1ec5d}"/>
<RecordField fieldIdRef="5" name="codigo" uid="{7225c2f2-2ca5-4952-9439-39d6105683b2}"/>
<RecordField colName="emp_no" fieldIdRef="8" name="emp_no" sqlTabName="formonly" sqlType="DECIMAL" uid="{ada70def-e69a-4c50-bd69-1fb91fd596cf}"/>
<RecordField colName="h_directa" fieldIdRef="12" name="h_directa" sqlTabName="formonly" uid="{f0d26a13-bbd5-4de4-a3ad-9e26feb8ccb0}"/>
<RecordField colName="h_indirecta" fieldIdRef="13" name="h_indirecta" sqlTabName="formonly" uid="{d3a40df7-5349-4812-82bc-a96aa2c4027b}"/>
<RecordField colName="e_directa" fieldIdRef="14" name="e_directa" sqlTabName="formonly" uid="{d24a8ff5-f9b6-4fbb-a667-451a948c3f7b}"/>
<RecordField colName="e_indirecta" fieldIdRef="15" name="e_indirecta" sqlTabName="formonly" uid="{9a0f1103-7db4-43c3-8147-f715eab9a3c1}"/>
<RecordField colName="cod_prod" fieldIdRef="9" name="cod_prod" sqlTabName="formonly" uid="{e1b64282-cd3b-4615-bcb8-fde9313110e2}"/>
<RecordField fieldIdRef="20" name="lado1" uid="{10db271d-bbce-4ae7-9e10-144888550c81}"/>
<RecordField fieldIdRef="21" name="lado2" uid="{f134fcc5-822c-4f75-8b71-70263f00284c}"/>
<RecordField fieldIdRef="22" name="lado3" uid="{98f897e4-b702-4356-bf11-25e1b93bb2ab}"/>
<RecordField colName="cantidad" fieldIdRef="17" name="cantidad" sqlTabName="formonly" uid="{166ac25b-ad15-45f8-8b8e-7862ac3bccfe}"/>
<RecordField fieldIdRef="23" name="medida1" uid="{c1b4ea3b-4927-423f-8dfd-a3dc80f64090}"/>
<RecordField colName="codigo_bloque" fieldIdRef="2" name="codigo_bloque" sqlTabName="formonly" uid="{d03b323d-b9bb-4eea-9514-c14bcccd7a56}"/>
<RecordField colName="turno" fieldIdRef="0" name="turno" sqlTabName="formonly" uid="{cea5543d-5e89-46ba-a306-d6d732238f3a}"/>
<RecordField fieldIdRef="24" name="depto_receptor" uid="{33d0c1ec-7dc1-4ec0-b489-b23701305b3c}"/>
<RecordField fieldIdRef="28" name="ref" uid="{e955cc32-7b71-4cec-90cd-379631ca8437}"/>
<RecordField fieldIdRef="50" name="num_oc" uid="{b2c3d4e5-0050-4a00-9050-0d0c0b0a0950}"/>
</Record>
<Record name="record1" uid="{af6b78f0-189c-4e68-8607-46f11a433423}">
<RecordField colName="num_doc" fieldIdRef="4" name="num_doc" sqlTabName="formonly" uid="{2bec5bf1-0623-4163-9235-ba4b878a0590}"/>
<RecordField colName="fecha" fieldIdRef="7" name="fecha" sqlTabName="formonly" sqlType="DATE" uid="{77a2edd0-719f-44f1-83dc-e532b159653f}"/>
<RecordField colName="factor" fieldIdRef="6" name="factor" sqlTabName="formonly" uid="{6dee7883-621c-45f7-8519-0cf206a8f484}"/>
<RecordField colName="departamento" fieldIdRef="3" name="departamento" sqlTabName="formonly" uid="{b4139611-41fc-494f-9bba-b6dee92f1e87}"/>
<RecordField colName="descripcion" fieldIdRef="18" name="descripcion" sqlTabName="formonly" uid="{f5f4d146-6d13-4504-b957-e3f116446c65}"/>
<RecordField colName="medida" fieldIdRef="16" name="medida" sqlTabName="formonly" uid="{f4fcca96-d1c9-43fa-a343-4b1ed7441d3a}"/>
<RecordField colName="nombre" fieldIdRef="19" name="nombre" sqlTabName="formonly" uid="{0b987b65-36cf-4e02-91a5-46831177aa0a}"/>
<RecordField fieldIdRef="27" name="cod_mov" uid="{611b980b-7ec3-480b-82f2-c4509213bf31}"/>
</Record>
<Record name="s_docs" uid="{a1b2c3d4-0001-4a00-9001-0d0c0b0a0901}">
<RecordField fieldIdRef="40" name="d_num_doc" uid="{a1b2c3d4-0002-4a00-9002-0d0c0b0a0902}"/>
<RecordField fieldIdRef="41" name="d_fecha" uid="{a1b2c3d4-0003-4a00-9003-0d0c0b0a0903}"/>
<RecordField fieldIdRef="42" name="d_departamento" uid="{a1b2c3d4-0004-4a00-9004-0d0c0b0a0904}"/>
<RecordField fieldIdRef="43" name="d_movimiento" uid="{a1b2c3d4-0005-4a00-9005-0d0c0b0a0905}"/>
<RecordField fieldIdRef="44" name="d_estado" uid="{a1b2c3d4-0006-4a00-9006-0d0c0b0a0906}"/>
<RecordField fieldIdRef="45" name="d_bloques" uid="{a1b2c3d4-0007-4a00-9007-0d0c0b0a0907}"/>
</Record>
<Form gridHeight="20" gridWidth="258" name="prfmmt003" style="basic" text="CREACION DOCUMENTO PRODUCCION">
<ToolBar name="toolbar1">
<ToolBarItem comment="Nuevo Documento" image="new" name="nuevo" text="Produccion"/>
<ToolBarItem comment="Criterio de busqueda" image="find" name="buscar" text="Buscar Documento"/>
<ToolBarItem comment="Anula Registro en Screen" image="cancel" name="anular" text="Anular Registros"/>
<ToolBarItem comment="Lista de documentos (mas recientes primero)" image="detail" name="documentos" text="Documentos"/>
<ToolBarItem comment="Recorrido/trazabilidad del bloque" image="fa-sitemap" name="traza" text="Trazabilidad"/>
<ToolBarSeparator name="toolbarseparator1"/>
<ToolBarItem image="quit" name="salir" text="Salir"/>
</ToolBar>
<Folder gridHeight="20" gridWidth="258" name="folder1" posX="0" posY="0">
<Page action="documentos" name="pg_docs" text="Documentos">
<Grid gridHeight="18" gridWidth="257" name="grid_docs" posX="0" posY="0">
<Table gridHeight="17" gridWidth="255" name="table_docs" posX="1" posY="0" totalRows="16" unitWidth="characters" width="150">
<Edit fieldId="40" gridHeight="1" gridWidth="12" name="d_num_doc" noEntry="true" posX="0" posY="0" scroll="true" tabIndex="-1" title="NUM. DOC" widget="Edit"/>
<Edit fieldId="41" gridHeight="1" gridWidth="14" name="d_fecha" noEntry="true" posX="12" posY="0" scroll="true" tabIndex="-1" title="FECHA" widget="Edit"/>
<Edit fieldId="42" gridHeight="1" gridWidth="42" name="d_departamento" noEntry="true" posX="26" posY="0" scroll="true" tabIndex="-1" title="DEPARTAMENTO" widget="Edit"/>
<Edit fieldId="43" gridHeight="1" gridWidth="36" name="d_movimiento" noEntry="true" posX="68" posY="0" scroll="true" tabIndex="-1" title="MOVIMIENTO" widget="Edit"/>
<Edit fieldId="44" gridHeight="1" gridWidth="12" name="d_estado" noEntry="true" posX="104" posY="0" scroll="true" tabIndex="-1" title="ESTADO" widget="Edit"/>
<Edit fieldId="45" gridHeight="1" gridWidth="34" name="d_bloques" noEntry="true" posX="116" posY="0" scroll="true" tabIndex="-1" title="BLOQUES" widget="Edit"/>
</Table>
</Grid>
</Page>
<Page name="pg_prod" text="Produccion">
<Grid gridHeight="18" gridWidth="258" name="grid1" posX="0" posY="0">
<Group gridHeight="6" gridWidth="62" name="group1" posX="1" posY="0" text="General">
<Label gridHeight="1" gridWidth="10" name="label1" posX="3" posY="1" text="Secuencia"/>
<Edit colName="num_doc" fieldId="4" gridHeight="1" gridWidth="5" name="num_doc" noEntry="false" posX="14" posY="1" sqlTabName="formonly" tabIndex="1" widget="Edit"/>
<Label gridHeight="1" gridWidth="6" name="label2" posX="21" posY="1" text="Fecha"/>
<DateEdit colName="fecha" fieldId="7" format="DD/MM/YYYY" gridHeight="1" gridWidth="9" name="fecha" posX="28" posY="1" required="true" sqlTabName="formonly" sqlType="DATE" tabIndex="2" widget="DateEdit"/>
<Label gridHeight="1" gridWidth="6" name="label3" posX="3" posY="2" text="Factor"/>
<Edit colName="factor" comment="Digite factor que desa calcular las horas normales" fieldId="6" gridHeight="1" gridWidth="5" name="factor" posX="14" posY="2" sqlTabName="formonly" tabIndex="3" widget="Edit"/>
<Label gridHeight="1" gridWidth="8" name="label4" posX="3" posY="3" text="Departa."/>
<ComboBox colName="departamento" fieldId="3" gridHeight="1" gridWidth="32" items="" name="departamento" posX="14" posY="3" required="true" sqlTabName="formonly" tabIndex="4" widget="ComboBox"/>
<Label gridHeight="1" gridWidth="10" name="label6" posX="3" posY="4" text="Cod. Movimiento"/>
<ComboBox fieldId="27" gridHeight="1" gridWidth="35" items="" name="cod_mov" posX="14" posY="4" tabIndex="-1" title="combobox1" widget="ComboBox"/>
</Group>
<Group gridHeight="8" gridWidth="257" name="group2" posX="1" posY="6" text="Detalle">
<Table gridHeight="6" gridWidth="254" name="table1" posX="2" posY="1" totalRows="5" unitWidth="characters" width="76">
<ComboBox colName="tipo" comment="Digite Codigo de la Maquina" fieldId="11" gridHeight="1" gridWidth="30" items="" name="tipo" posX="0" posY="0" scroll="true" sqlTabName="formonly" tabIndex="5" title="OPERACION" widget="ComboBox"/>
<ComboBox fieldId="5" gridHeight="1" gridWidth="48" items="" name="codigo" posX="30" posY="0" scroll="true" tabIndex="-1" title="Equipo" unhidable="true" unmovable="true" unsortable="true" widget="ComboBox"/>
<ButtonEdit action="empleado" autoNext="true" colName="emp_no" fieldId="8" gridHeight="1" gridWidth="10" name="emp_no" posX="78" posY="0" sqlTabName="formonly" sqlType="DECIMAL" tabIndex="6" title="EMPLEADO" widget="ButtonEdit"/>
<Edit autoNext="true" colName="h_directa" fieldId="12" gridHeight="1" gridWidth="6" name="h_directa" posX="88" posY="0" sqlTabName="formonly" tabIndex="7" title="N.DIRECTA" widget="Edit"/>
<Edit autoNext="true" colName="h_indirecta" fieldId="13" gridHeight="1" gridWidth="6" name="h_indirecta" posX="94" posY="0" sqlTabName="formonly" tabIndex="8" title="N.IND." widget="Edit"/>
<Edit autoNext="true" colName="e_directa" fieldId="14" gridHeight="1" gridWidth="6" name="e_directa" posX="100" posY="0" sqlTabName="formonly" tabIndex="9" title="E. DIRECTAS" widget="Edit"/>
<Edit autoNext="true" colName="e_indirecta" fieldId="15" gridHeight="1" gridWidth="5" name="e_indirecta" posX="106" posY="0" sqlTabName="formonly" tabIndex="10" title="E.INDIRECTAS" widget="Edit"/>
<ButtonEdit action="semielaborado" colName="cod_prod" fieldId="9" gridHeight="1" gridWidth="10" name="cod_prod" posX="111" posY="0" sqlTabName="formonly" tabIndex="11" title="SEMI-ELABORADO" widget="ButtonEdit"/>
<Edit fieldId="20" gridHeight="1" gridWidth="8" name="lado1" posX="121" posY="0" tabIndex="-1" title="Ancho" widget="Edit"/>
<Edit fieldId="21" gridHeight="1" gridWidth="8" name="lado2" posX="129" posY="0" tabIndex="-1" title="Largo" widget="Edit"/>
<Edit fieldId="22" gridHeight="1" gridWidth="8" name="lado3" posX="137" posY="0" tabIndex="-1" title="Espesor" widget="Edit"/>
<Edit colName="cantidad" comment="Digite Cantidad Producida" fieldId="17" gridHeight="1" gridWidth="12" name="cantidad" posX="145" posY="0" sqlTabName="formonly" tabIndex="12" title="CANTIDAD" widget="Edit"/>
<Edit fieldId="23" gridHeight="1" gridWidth="8" name="medida1" noEntry="true" posX="157" posY="0" tabIndex="-1" title="Medida" widget="Edit"/>
<Edit case="upper" colName="codigo_bloque" fieldId="2" gridHeight="1" gridWidth="20" name="codigo_bloque" posX="165" posY="0" scroll="true" sqlTabName="formonly" tabIndex="13" title="BLOQUE" widget="Edit"/>
<ComboBox colName="turno" fieldId="0" gridHeight="1" gridWidth="20" items="" name="turno" posX="185" posY="0" sqlTabName="formonly" tabIndex="14" title="TURNO" widget="ComboBox"/>
<ComboBox fieldId="24" gridHeight="1" gridWidth="13" items="" name="depto_receptor" notNull="false" posX="205" posY="0" required="false" tabIndex="-1" title="DEPTO. RECEPTOR" widget="ComboBox"/>
<ButtonEdit action="ordenped" fieldId="50" gridHeight="1" gridWidth="12" name="num_oc" posX="218" posY="0" scroll="true" tabIndex="18" title="ORDEN PED." widget="ButtonEdit"/>
<Phantom fieldId="28" name="ref" widget="Phantom"/>
</Table>
</Group>
<Group gridHeight="4" gridWidth="56" name="group3" posX="1" posY="14" text="INFORMACION">
<Label gridHeight="1" gridWidth="7" name="label5" posX="1" posY="1" text="Produce"/>
<Edit colName="descripcion" fieldId="18" gridHeight="1" gridWidth="31" name="descripcion" noEntry="true" posX="12" posY="1" sqlTabName="formonly" tabIndex="15" widget="Edit"/>
<Edit colName="medida" fieldId="16" gridHeight="1" gridWidth="3" name="medida" noEntry="true" posX="44" posY="1" sqlTabName="formonly" tabIndex="16" widget="Edit"/>
<Label gridHeight="1" gridWidth="8" name="label9" posX="1" posY="2" text="Empleado"/>
<Edit colName="nombre" fieldId="19" gridHeight="1" gridWidth="31" name="nombre" noEntry="true" posX="12" posY="2" sqlTabName="formonly" tabIndex="17" widget="Edit"/>
</Group>
</Grid>
</Page>
</Folder>
</Form>
<DiagramLayout>
<![CDATA[AAAAAgAAAEwAewAxADAANwAyADgAMwAwAGUALQBlADAANABlAC0ANABhADYAMwAtADgAZgA0ADEALQA0AGEAYQA4AGUAZgBhADUAZgBmAGEAYQB9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAEwAewBhADEAYgAyAGMAMwBkADQALQAwADAAMAAxAC0ANABhADAAMAAtADkAMAAwADEALQAwAGQAMABjADAAYgAwAGEAMAA5ADAAMQB9QDAAAAQAAABAMAAABAAAAAAAAAAAAAAAAQAAAEwAewBhAGYANgBiADcAOABmADAALQAxADgAOQBjAC0ANABlADYAOAAtADgANgAwADcALQA0ADYAZgAxADEAYQA0ADMAMwA0ADIAMwB9QHMAAEhgAHpAPVVV1VVWYD9QYk3S8an8AQ==]]>
</DiagramLayout>
</ManagedForm>
+33
View File
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ManagedForm databaseName="smarmotech" fileVersion="40100" gstVersion="60003" name="ManagedForm" uid="{9ab131cc-e3f5-494e-91de-5c09b774e85d}">
<AGSettings>
<DynamicProperties version="4"/>
</AGSettings>
<Record name="record1" uid="{443dc023-d478-4ecd-b508-5a36ada894a4}">
<RecordField colName="area_num" fieldIdRef="0" fieldType="TABLE_COLUMN" name="prtb00016.area_num" sqlTabName="prtb00016" uid="{b8203607-0471-4c7e-8ab9-ac7bdafd7886}"/>
<RecordField colName="nombre_area" fieldIdRef="1" fieldType="TABLE_COLUMN" name="prtb00016.nombre_area" sqlTabName="prtb00016" uid="{2b1fdb6d-375f-4d84-aa7d-ae809175a607}"/>
<RecordField colName="status_t" fieldIdRef="2" fieldType="TABLE_COLUMN" name="prtb00016.status_t" sqlTabName="prtb00016" uid="{b8200b51-c72d-4706-a20a-b0385227b951}"/>
<RecordField colName="us_crea" fieldIdRef="3" fieldType="TABLE_COLUMN" name="prtb00016.us_crea" sqlTabName="prtb00016" uid="{f55a0f80-bb96-418d-a961-e4e8ec620b54}"/>
<RecordField colName="us_mod" fieldIdRef="4" fieldType="TABLE_COLUMN" name="prtb00016.us_mod" sqlTabName="prtb00016" uid="{26703a61-e09e-4233-a55b-114ae9719153}"/>
<RecordField colName="fech_crea" fieldIdRef="5" fieldType="TABLE_COLUMN" name="prtb00016.fech_crea" sqlTabName="prtb00016" uid="{5a2a88ed-161c-40bd-89e5-6f8ccd84b675}"/>
<RecordField colName="fech_mod" fieldIdRef="6" fieldType="TABLE_COLUMN" name="prtb00016.fech_mod" sqlTabName="prtb00016" uid="{6cd4a9f5-97ad-4424-9a3d-5b5c283c03a4}"/>
</Record>
<Form gridHeight="24" gridWidth="80" name="prfmmt010" text="ADMINISTRACION AREAS">
<Grid gridHeight="24" gridWidth="80" name="grid1" posX="0" posY="0">
<Label gridHeight="1" gridWidth="4" name="label1" posX="3" posY="0" text="Area"/>
<Edit colName="area_num" comment="Digite el Numero del Area" fieldId="0" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="5" name="prtb00016.area_num" posX="22" posY="0" sqlTabName="prtb00016" tabIndex="1" widget="Edit"/>
<Label gridHeight="1" gridWidth="16" name="label2" posX="3" posY="1" text="Descripcion Area"/>
<Edit case="upper" colName="nombre_area" comment="Digite la descripcion del Area" fieldId="1" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="29" name="prtb00016.nombre_area" posX="22" posY="1" required="true" sqlTabName="prtb00016" tabIndex="2" widget="Edit"/>
<Label gridHeight="1" gridWidth="6" name="label3" posX="3" posY="2" text="Status"/>
<Edit colName="status_t" fieldId="2" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="1" name="prtb00016.status_t" noEntry="true" posX="22" posY="2" sqlTabName="prtb00016" tabIndex="3" widget="Edit"/>
<Label gridHeight="1" gridWidth="16" name="label4" posX="3" posY="4" text="Usuario Creador"/>
<Edit colName="us_crea" fieldId="3" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="8" name="prtb00016.us_crea" noEntry="true" posX="20" posY="4" sqlTabName="prtb00016" tabIndex="4" widget="Edit"/>
<Label gridHeight="1" gridWidth="20" name="label5" posX="41" posY="4" text="Usuario Modificador"/>
<Edit colName="us_mod" fieldId="4" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="8" name="prtb00016.us_mod" noEntry="true" posX="62" posY="4" sqlTabName="prtb00016" tabIndex="5" widget="Edit"/>
<Label gridHeight="1" gridWidth="14" name="label6" posX="3" posY="5" text="Fecha Creacion"/>
<Edit colName="fech_crea" fieldId="5" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="16" name="prtb00016.fech_crea" noEntry="true" posX="20" posY="5" sqlTabName="prtb00016" tabIndex="6" widget="Edit"/>
<Label gridHeight="1" gridWidth="20" name="label7" posX="41" posY="5" text="Usuario Modificador"/>
<Edit colName="fech_mod" fieldId="6" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="16" name="prtb00016.fech_mod" noEntry="true" posX="62" posY="5" sqlTabName="prtb00016" tabIndex="7" widget="Edit"/>
</Grid>
</Form>
</ManagedForm>
+1 -1
View File
@@ -40,7 +40,7 @@
<Label gridHeight="1" gridWidth="8" name="label2" posX="24" posY="1" text="FECHA FINAL"/>
<DateEdit fieldId="16" gridHeight="1" gridWidth="13" name="fech_final" posX="33" posY="1" tabIndex="-1" title="dateedit2" widget="DateEdit"/>
<Label gridHeight="1" gridWidth="6" name="label3" posX="47" posY="1" text="ESTADO "/>
<ComboBox fieldId="17" gridHeight="1" gridWidth="12" items="ABIERTA, CERRADA" name="estado1" posX="54" posY="1" tabIndex="-1" title="combobox1" widget="ComboBox">
<ComboBox fieldId="17" gridHeight="1" gridWidth="12" items="ABIERTA, CERRADA" name="estado1" notNull="true" posX="54" posY="1" tabIndex="-1" title="combobox1" widget="ComboBox">
<Item lstrtext="false" name="ABIERTA" text="ABIERTA"/>
<Item lstrtext="false" name="CERRADA" text="CERRADA"/>
</ComboBox>
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ManagedForm databaseName="smarmotech" fileVersion="40100" gstVersion="60003" name="ManagedForm" uid="{50926d70-025d-4be1-a15f-45acbf1b2888}">
<AGSettings>
<DynamicProperties version="4"/>
</AGSettings>
<Record name="record1" uid="{ae577ed1-a849-40c1-a3a8-3df0bfba35f6}">
<RecordField colName="cotizacion_no" fieldIdRef="5" name="cotizacion_no" sqlTabName="formonly" uid="{34fb79d0-ea3c-45e5-bd43-bd2484db0e24}"/>
<RecordField colName="num_oc" fieldIdRef="12" name="num_oc" sqlTabName="formonly" uid="{1b817c74-fb63-4453-9c9e-580cd0ebe8dd}"/>
<RecordField colName="cerrada" fieldIdRef="10" name="cerrada" sqlTabName="formonly" uid="{a0ade89e-f809-4801-83fc-82267e75339d}"/>
<RecordField colName="sec_vend" fieldIdRef="13" name="sec_vend" sqlTabName="formonly" uid="{532f53e9-4b3f-4c15-8919-c4afedd6e638}"/>
<RecordField colName="historico" defaultValue="N" fieldIdRef="0" name="historico" sqlTabName="formonly" uid="{a297c185-81e7-4ae6-8988-2224946811de}"/>
<RecordField colName="fecha" fieldIdRef="11" name="fecha" sqlTabName="formonly" sqlType="DATE" uid="{62430a14-a00f-413f-b6b1-766e90f9315e}"/>
<RecordField colName="tipo_cliente" fieldIdRef="7" name="tipo_cliente" sqlTabName="formonly" uid="{7cf8df86-dc57-4cd8-9b40-6636785559c9}"/>
<RecordField colName="sec_cliente" fieldIdRef="8" name="sec_cliente" sqlTabName="formonly" uid="{c77b4cbf-8ab9-4072-b566-5ce5401f170b}"/>
<RecordField colName="nombre_cliente" fieldIdRef="6" name="nombre_cliente" sqlTabName="formonly" uid="{b775b626-23dd-4f6c-8fda-b729a1e40605}"/>
<RecordField colName="telefono_r" fieldIdRef="9" name="telefono_r" sqlTabName="formonly" uid="{c545bc0e-23c1-465b-9688-5d5039b27597}"/>
<RecordField colName="cod_n" fieldIdRef="1" name="cod_n" sqlTabName="formonly" uid="{a8bcc1fa-5503-4b65-8249-fdaa1e91c258}"/>
<RecordField colName="cod_grupo" fieldIdRef="2" name="cod_grupo" sqlTabName="formonly" uid="{71e68d6d-8151-44c2-a42c-4e9465dd3c2b}"/>
<RecordField colName="cod_tipo" fieldIdRef="3" name="cod_tipo" sqlTabName="formonly" uid="{a5d7c1ab-90d7-4feb-b86d-6a74f1966b44}"/>
<RecordField colName="cod_sec" fieldIdRef="4" name="cod_sec" sqlTabName="formonly" uid="{0fed854c-cd15-4a85-b593-c3a9f114d277}"/>
<RecordField colName="salida" defaultValue="Detallado" fieldIdRef="14" name="salida" sqlTabName="formonly" uid="{72b478e3-81f8-4d24-ad49-d777be1c0608}"/>
<RecordField colName="visualiza" defaultValue="PANTALLA" fieldIdRef="15" name="visualiza" sqlTabName="formonly" uid="{7c7aa938-7433-4dd6-bcc2-c27d6b3e2e34}"/>
</Record>
<Form gridHeight="10" gridWidth="67" name="prfmrp116" text="STATUS ORDENES PEDIDOS">
<ActionDefaultList name="actiondefaultlist1">
<ActionDefault image="print" name="ejecutar" text="Genera Reporte"/>
</ActionDefaultList>
<Grid gridHeight="10" gridWidth="67" name="grid1" posX="0" posY="0">
<Label gridHeight="1" gridWidth="10" name="label1" posX="3" posY="0" text="Cotizacion"/>
<Edit colName="cotizacion_no" comment="Digite un numero de cotizacion o deje en blanco para todas" fieldId="5" gridHeight="1" gridWidth="10" name="cotizacion_no" posX="19" posY="0" sqlTabName="formonly" tabIndex="1" widget="Edit"/>
<Label gridHeight="1" gridWidth="5" name="label2" posX="3" posY="1" text="Orden"/>
<Edit colName="num_oc" comment="Digite un numero de orden o deje en blanco para todas" fieldId="12" gridHeight="1" gridWidth="10" name="num_oc" posX="19" posY="1" sqlTabName="formonly" tabIndex="2" widget="Edit"/>
<Label gridHeight="1" gridWidth="12" name="label3" posX="34" posY="1" text="Status Orden"/>
<ComboBox colName="cerrada" fieldId="10" gridHeight="1" gridWidth="14" items="Cerrada, Abiertas" name="cerrada" notNull="true" posX="47" posY="1" sqlTabName="formonly" tabIndex="3" widget="ComboBox">
<Item name="S" text="Cerrada"/>
<Item name="N" text="Abiertas"/>
</ComboBox>
<Label gridHeight="1" gridWidth="8" name="label4" posX="3" posY="2" text="Vendedor"/>
<Edit colName="sec_vend" comment="Digite un numero de vendedor o deje en blanco para todos" fieldId="13" gridHeight="1" gridWidth="10" name="sec_vend" posX="19" posY="2" sqlTabName="formonly" tabIndex="4" widget="Edit"/>
<RadioGroup colName="historico" defaultValue="N" fieldId="0" gridHeight="1" gridWidth="26" items="HISTORICO, ACTUAL" name="historico" posX="35" posY="2" sqlTabName="formonly" tabIndex="5" widget="RadioGroup">
<Item name="H" text="HISTORICO"/>
<Item name="N" text="ACTUAL"/>
</RadioGroup>
<Label gridHeight="1" gridWidth="5" name="label5" posX="3" posY="3" text="Fecha"/>
<DateEdit colName="fecha" fieldId="11" format="dd/mm/yyyy" gridHeight="1" gridWidth="10" name="fecha" posX="19" posY="3" sqlTabName="formonly" sqlType="DATE" tabIndex="6" widget="DateEdit"/>
<Label gridHeight="1" gridWidth="15" name="label6" posX="3" posY="4" text="Codigo Cliente"/>
<Edit colName="tipo_cliente" fieldId="7" gridHeight="1" gridWidth="3" name="tipo_cliente" posX="19" posY="4" sqlTabName="formonly" tabIndex="7" widget="Edit"/>
<Label gridHeight="1" gridWidth="1" name="label7" posX="23" posY="4" text="-"/>
<Edit colName="sec_cliente" fieldId="8" gridHeight="1" gridWidth="6" name="sec_cliente" posX="25" posY="4" sqlTabName="formonly" tabIndex="8" widget="Edit"/>
<Label gridHeight="1" gridWidth="15" name="label8" posX="3" posY="5" text="Nombre Cliente"/>
<Edit colName="nombre_cliente" comment="Utilice el simbolo (*) para buscar nombres similares al que desea" fieldId="6" gridHeight="1" gridWidth="47" name="nombre_cliente" posX="19" posY="5" sqlTabName="formonly" tabIndex="9" widget="Edit"/>
<Label gridHeight="1" gridWidth="13" name="label9" posX="3" posY="6" text="Telefono Res."/>
<Edit colName="telefono_r" fieldId="9" gridHeight="1" gridWidth="15" name="telefono_r" posX="19" posY="6" sqlTabName="formonly" tabIndex="10" widget="Edit"/>
<Label gridHeight="1" gridWidth="8" name="label10" posX="3" posY="7" text="Producto"/>
<Edit colName="cod_n" fieldId="1" gridHeight="1" gridWidth="5" name="cod_n" posX="19" posY="7" sqlTabName="formonly" tabIndex="11" widget="Edit"/>
<Edit colName="cod_grupo" fieldId="2" gridHeight="1" gridWidth="6" name="cod_grupo" posX="26" posY="7" sqlTabName="formonly" tabIndex="12" widget="Edit"/>
<Edit colName="cod_tipo" fieldId="3" gridHeight="1" gridWidth="6" name="cod_tipo" posX="34" posY="7" sqlTabName="formonly" tabIndex="13" widget="Edit"/>
<Edit colName="cod_sec" fieldId="4" gridHeight="1" gridWidth="7" name="cod_sec" posX="42" posY="7" sqlTabName="formonly" tabIndex="14" widget="Edit"/>
<Label gridHeight="1" gridWidth="15" name="label11" posX="3" posY="8" text="Salida Reporte"/>
<ComboBox colName="salida" defaultValue="Detallado" fieldId="14" gridHeight="1" gridWidth="15" items="Detallado, Resumido" name="salida" posX="19" posY="8" sqlTabName="formonly" tabIndex="15" widget="ComboBox">
<Item name="prprrp116.4rp" text="Detallado"/>
<Item name="prprrp016a.4rp" text="Resumido"/>
</ComboBox>
<Label gridHeight="1" gridWidth="13" name="label12" posX="3" posY="9" text="Visualizacion"/>
<ComboBox colName="visualiza" defaultValue="PANTALLA" fieldId="15" gridHeight="1" gridWidth="15" items="PANTALLA, ACROBAT READER, EXCEL" name="visualiza" posX="19" posY="9" sqlTabName="formonly" tabIndex="16" widget="ComboBox">
<Item name="SVG" text="PANTALLA"/>
<Item name="PDF" text="ACROBAT READER"/>
<Item name="XLSX" text="EXCEL"/>
</ComboBox>
</Grid>
</Form>
</ManagedForm>
+1 -1
View File
@@ -48,7 +48,7 @@ DATEEDIT f1 = formonly.fecha type date,format = "dd/mm/yyyy";
o1 = formonly.num_oc,comments="Digite un numero de orden o deje en blanco para todas";
v1 = formonly.sec_vend,comments="Digite un numero de vendedor o deje en blanco para todos";
COMBOBOX s=formonly.salida,ITEMS=(("prprrp116.4rp","Detallado"),("prprrp016a.4rp","Resumido")),default="Detallado";
COMBOBOX v=formonly.visualiza,ITEMS=(("SVG","PANTALLA"),("PDF","ACROBAT READER")),default="PANTALLA";
COMBOBOX v=formonly.visualiza,ITEMS=(("SVG","PANTALLA"),("PDF","ACROBAT READER"),("XLSX","EXCEL")),default="PANTALLA";
instructions
delimiters " "
end
+1 -1
View File
@@ -11,7 +11,7 @@
END RECORD,
nombre_cia STRING
FUNCTION impresion(pnumoc)
FUNCTION impresion_oc(pnumoc)
DEFINE pnumoc,I INT
DECLARE busca_orden CURSOR FOR
+4 -2
View File
@@ -32,7 +32,8 @@ FUNCTION imprime (datos_c, arr_costos)
codigo_bloque LIKE cttb00003.codigo_bloque,
turno SMALLINT,
depto_receptor SMALLINT,
ref INT
ref INT,
num_oc INT
END RECORD
DEFINE nombre, descripcion, movimiento, departamento, turno, maquina, depto_receptor STRING
@@ -125,7 +126,8 @@ REPORT p_diaria(datos_c, arr_costos, nombre, descripcion, movimiento, departamen
codigo_bloque LIKE cttb00003.codigo_bloque,
turno SMALLINT,
depto_receptor SMALLINT,
ref INT
ref INT,
num_oc INT
END RECORD
DEFINE nombre, descripcion, movimiento, departamento, descrip_turno,
+3 -1
View File
@@ -71,7 +71,9 @@ DEFINE hoy DATE
END INPUT
CONSTRUCT BY NAME criterio ON a.tipo_cliente,a.sec_cliente,
a.num_oc,a.fecha
a.num_oc,a.fecha_oc
FROM tipo_cliente,sec_cliente,
num_oc,fecha
AFTER CONSTRUCT
IF tipo_orden = 'N' THEN
-9
View File
@@ -57,15 +57,6 @@ GLOBALS
nombre LIKE vetb00004.nombre
END RECORD
DEFINE arrprtb08 DYNAMIC ARRAY OF RECORD
cod_n_c LIKE prtb00008.cod_n,
cod_grupo_c LIKE prtb00008.cod_grupo,
cod_tipo_c LIKE prtb00008.cod_tipo,
cod_sec_c LIKE prtb00008.cod_sec,
cantidad_c LIKE prtb00008.cantidad ,
descrip_esp_c LIKE intb00001.descrip_esp,
unidad_c LIKE intb00001.unidad_med
END RECORD
DEFINE nombre_dia DYNAMIC ARRAY OF char(10)
+2 -2
View File
@@ -114,8 +114,8 @@ FUNCTION prprmt003()
CLEAR SCREEN
OPEN FORM prfmmt003 FROM "prfmmt003"
DISPLAY FORM prfmmt003
OPEN FORM prfmmt003pr FROM "prfmmt003pr"
DISPLAY FORM prfmmt003pr
DISPLAY "Registro de Produccion Diaria" AT 4,25
DISPLAY "prprmt003" AT 4,3
# CALL pantalla1()
+67 -56
View File
@@ -7,6 +7,16 @@
------------------------------------------------------------------
}
GLOBALS "prprgb000.4gl"
DEFINE arrprtb08 DYNAMIC ARRAY OF RECORD
cod_n_c LIKE prtb00008.cod_n,
cod_grupo_c LIKE prtb00008.cod_grupo,
cod_tipo_c LIKE prtb00008.cod_tipo,
cod_sec_c LIKE prtb00008.cod_sec,
cantidad_c LIKE prtb00008.cantidad,
descrip_esp_c LIKE intb00001.descrip_esp,
unidad_c LIKE intb00001.unidad_med
END RECORD
DEFINE nombre LIKE vetb00004.nombre,
descrip_esp_c,descrip_esp LIKE iptb00002.descrip_esp,
unidad LIKE iptb00002.unidad_med,
@@ -41,10 +51,11 @@ END MAIN
FORM LINE 9,
ERROR LINE 23,
COMMENT LINE 21
CALL pantalla()
# (pantalla() es el encabezado de la pantalla de texto antigua; no aplica en GUI)
OPEN FORM ctfmmt006 FROM "prfmmt006"
DISPLAY FORM ctfmmt006
CALL pantalla()
CALL ui.Window.getCurrent().setText("Ordenes de Produccion")
# (pantalla() es el encabezado de la pantalla de texto antigua; no aplica en GUI)
DISPLAY "prprmt006" AT 4,3
DISPLAY "Ordenes De Produccion" AT 6,32
@@ -280,13 +291,13 @@ FUNCTION prpcad006()
b.cod_sec = prtb07.cod_sec AND
a.num_oc = b.num_oc
LET idx = 1
FOREACH buscame INTO prtb08[idx].*
FOREACH buscame INTO arrprtb08[idx].*
LET idx = idx + 1
END FOREACH
CALL set_count(idx-1)
}
INPUT ARRAY prtb08 FROM s_orden.*
INPUT ARRAY arrprtb08 FROM s_orden.*
ON KEY(CONTROL-W)
CALL busca_material()
@@ -295,13 +306,13 @@ FUNCTION prpcad006()
LET scr_l = scr_line()
AFTER FIELD cod_sec_c
LET descrip_esp_c = NULL
IF prtb08[curr].cod_sec_c IS NOT NULL THEN
IF arrprtb08[curr].cod_sec_c IS NOT NULL THEN
SELECT a.descrip_esp,a.unidad_med INTO descrip_esp_c,unidad_c
FROM intb00001 a
WHERE a.cod_n = prtb08[curr].cod_n_c AND
a.cod_grupo = prtb08[curr].cod_grupo_c AND
a.cod_tipo = prtb08[curr].cod_tipo_c AND
a.cod_sec = prtb08[curr].cod_sec_c AND
WHERE a.cod_n = arrprtb08[curr].cod_n_c AND
a.cod_grupo = arrprtb08[curr].cod_grupo_c AND
a.cod_tipo = arrprtb08[curr].cod_tipo_c AND
a.cod_sec = arrprtb08[curr].cod_sec_c AND
a.status_t IS NULL
IF STATUS = NOTFOUND THEN
LET numero_msg = 3
@@ -309,15 +320,15 @@ FUNCTION prpcad006()
NEXT FIELD cod_n_c
END IF
END IF
LET prtb08[curr].descrip_esp_c = descrip_esp_c
LET prtb08[curr].unidad_c = unidad_c
DISPLAY prtb08[curr].descrip_esp_c TO s_orden[scr_l].descrip_esp_c
LET arrprtb08[curr].descrip_esp_c = descrip_esp_c
LET arrprtb08[curr].unidad_c = unidad_c
DISPLAY arrprtb08[curr].descrip_esp_c TO s_orden[scr_l].descrip_esp_c
ATTRIBUTE(BLUE)
DISPLAY prtb08[curr].unidad_c TO s_orden[scr_l].unidad_c
DISPLAY arrprtb08[curr].unidad_c TO s_orden[scr_l].unidad_c
ATTRIBUTE(BLUE)
AFTER FIELD cantidad_c
IF prtb08[curr].cod_n_c IS NOT NULL THEN
IF prtb08[curr].cantidad_c IS NULL THEN
IF arrprtb08[curr].cod_n_c IS NOT NULL THEN
IF arrprtb08[curr].cantidad_c IS NULL THEN
LET numero_msg = 16
CALL msg(numero_msg)
NEXT FIELD cantidad_c
@@ -347,23 +358,23 @@ FUNCTION prpcad006()
# SE ESTA VALIDANDO EL PRODUCTO TERMINADO EN EL CODIGO DE LA MATERIA PRIMA
# PARA CUANDO LA ORDEN SEA PARA PRODUCTOS IMPORTADOS QUE NO TIENEN COMPOSICION
IF prtb08[1].cod_n_c IS NULL THEN
LET prtb08[1].cod_n_c = prtb07.cod_n
LET prtb08[1].cod_grupo_c = prtb07.cod_grupo
LET prtb08[1].cod_tipo_c = prtb07.cod_tipo
LET prtb08[1].cod_sec_c = prtb07.cod_Sec
OUTPUT TO REPORT ordenes(prtb07.num_oc,prtb08[idx].*)
IF arrprtb08[1].cod_n_c IS NULL THEN
LET arrprtb08[1].cod_n_c = prtb07.cod_n
LET arrprtb08[1].cod_grupo_c = prtb07.cod_grupo
LET arrprtb08[1].cod_tipo_c = prtb07.cod_tipo
LET arrprtb08[1].cod_sec_c = prtb07.cod_Sec
OUTPUT TO REPORT ordenes(prtb07.num_oc,arrprtb08[idx].*)
END IF
FOR idx = 1 TO arr_count()
IF prtb08[idx].cod_n_c IS NOT NULL THEN
IF arrprtb08[idx].cod_n_c IS NOT NULL THEN
INSERT INTO prtb00008 VALUES (prtb07.num_oc,
prtb08[idx].cod_n_c,
prtb08[idx].cod_grupo_c,
prtb08[idx].cod_tipo_c,
prtb08[idx].cod_sec_c,
prtb08[idx].cantidad_c,
arrprtb08[idx].cod_n_c,
arrprtb08[idx].cod_grupo_c,
arrprtb08[idx].cod_tipo_c,
arrprtb08[idx].cod_sec_c,
arrprtb08[idx].cantidad_c,
SUSER_SNAME(),current,null,null)
OUTPUT TO REPORT ordenes(prtb07.num_oc,prtb08[idx].*)
OUTPUT TO REPORT ordenes(prtb07.num_oc,arrprtb08[idx].*)
END IF
END FOR
FINISH REPORT ordenes
@@ -534,24 +545,24 @@ LABEL sale9:
END FUNCTION
FUNCTION limpia()
FOR idx = 1 TO 10
LET prtb08[idx].cod_n_c = null
LET prtb08[idx].cod_grupo_c = null
LET prtb08[idx].cod_tipo_c = null
LET prtb08[idx].cod_sec_c = null
LET prtb08[idx].unidad_c = null
LET prtb08[idx].cantidad_c = null
LET prtb08[idx].descrip_esp_c = null
LET arrprtb08[idx].cod_n_c = null
LET arrprtb08[idx].cod_grupo_c = null
LET arrprtb08[idx].cod_tipo_c = null
LET arrprtb08[idx].cod_sec_c = null
LET arrprtb08[idx].unidad_c = null
LET arrprtb08[idx].cantidad_c = null
LET arrprtb08[idx].descrip_esp_c = null
END FOR
FOR idx = 1 TO 5
DISPLAY prtb08[idx].cod_n_c TO s_orden[idx].cod_n_c
DISPLAY prtb08[idx].cod_grupo_c TO s_orden[idx].cod_grupo_c
DISPLAY prtb08[idx].cod_tipo_c TO s_orden[idx].cod_tipo_c
DISPLAY prtb08[idx].cod_sec_c TO s_orden[idx].cod_sec_c
DISPLAY prtb08[idx].cantidad_c TO s_orden[idx].cantidad_c
DISPLAY arrprtb08[idx].cod_n_c TO s_orden[idx].cod_n_c
DISPLAY arrprtb08[idx].cod_grupo_c TO s_orden[idx].cod_grupo_c
DISPLAY arrprtb08[idx].cod_tipo_c TO s_orden[idx].cod_tipo_c
DISPLAY arrprtb08[idx].cod_sec_c TO s_orden[idx].cod_sec_c
DISPLAY arrprtb08[idx].cantidad_c TO s_orden[idx].cantidad_c
DISPLAY prtb08[idx].descrip_esp_c TO s_orden[idx].descrip_esp_c
DISPLAY arrprtb08[idx].descrip_esp_c TO s_orden[idx].descrip_esp_c
ATTRIBUTE(BLUE)
DISPLAY prtb08[idx].unidad_c TO s_orden[idx].unidad_c
DISPLAY arrprtb08[idx].unidad_c TO s_orden[idx].unidad_c
ATTRIBUTE(BLUE)
END FOR
@@ -565,28 +576,28 @@ FUNCTION busca_detalle()
WHERE a.num_oc = numero_oc
LET idx = 1
FOREACH busca_d INTO prtb08[idx].*
FOREACH busca_d INTO arrprtb08[idx].*
SELECT a.descrip_esp,a.unidad_med INTO descrip_esp_c,unidad_c
FROM intb00001 a
WHERE a.cod_n = prtb08[idx].cod_n_c AND
a.cod_grupo = prtb08[idx].cod_grupo_c AND
a.cod_tipo = prtb08[idx].cod_tipo_c AND
a.cod_sec = prtb08[idx].cod_sec_c AND
WHERE a.cod_n = arrprtb08[idx].cod_n_c AND
a.cod_grupo = arrprtb08[idx].cod_grupo_c AND
a.cod_tipo = arrprtb08[idx].cod_tipo_c AND
a.cod_sec = arrprtb08[idx].cod_sec_c AND
a.status_t IS NULL
IF idx > 5 THEN
EXIT FOREACH
END IF
LET prtb08[idx].descrip_esp_c = descrip_esp_c
LET prtb08[idx].unidad_c = unidad_c
DISPLAY prtb08[idx].cod_n_c TO s_orden[idx].cod_n_c
DISPLAY prtb08[idx].cod_grupo_c TO s_orden[idx].cod_grupo_c
DISPLAY prtb08[idx].cod_tipo_c TO s_orden[idx].cod_tipo_c
DISPLAY prtb08[idx].cod_sec_c TO s_orden[idx].cod_sec_c
DISPLAY prtb08[idx].cantidad_c TO s_orden[idx].cantidad_c
LET arrprtb08[idx].descrip_esp_c = descrip_esp_c
LET arrprtb08[idx].unidad_c = unidad_c
DISPLAY arrprtb08[idx].cod_n_c TO s_orden[idx].cod_n_c
DISPLAY arrprtb08[idx].cod_grupo_c TO s_orden[idx].cod_grupo_c
DISPLAY arrprtb08[idx].cod_tipo_c TO s_orden[idx].cod_tipo_c
DISPLAY arrprtb08[idx].cod_sec_c TO s_orden[idx].cod_sec_c
DISPLAY arrprtb08[idx].cantidad_c TO s_orden[idx].cantidad_c
DISPLAY prtb08[idx].descrip_esp_c TO s_orden[idx].descrip_esp_c
DISPLAY arrprtb08[idx].descrip_esp_c TO s_orden[idx].descrip_esp_c
ATTRIBUTE(BLUE)
DISPLAY prtb08[idx].unidad_c TO s_orden[idx].unidad_c
DISPLAY arrprtb08[idx].unidad_c TO s_orden[idx].unidad_c
ATTRIBUTE(BLUE)
LET idx = idx + 1
END FOREACH
+20 -14
View File
@@ -64,7 +64,7 @@ GLOBALS "prprgb000.4gl"
nombre_vend,nombres,apellidos CHAR(40),fcalle CHAR(25),
fcasa_num CHAR(5), fbarrio,furbanizacion CHAR(15),
monto_desc,total1,p_costos1,total_i,total_mo DECIMAL(12,2),
ult_numero,cuenta INTEGER,
ult_numero,cuenta,existe_oc INTEGER,
vetb05 RECORD LIKE vetb00005.*,
cuenta_p,ridx SMALLINT,
pbalance1,pbalance2 DEC(12,2),
@@ -798,19 +798,26 @@ FUNCTION prpcad008()
# SE COLOCO QUE EL NUMERO SE GENERARA A PARTIR DEL 01/01/2003 HACIA ATRAS POR MODIFICACION DEL
# SISTEMA Y LA INCLUSION DEL NCF A PARTIR DEL 01/01/2007
# FECHA MODIFICACION: 11/01/2007
SELECT num_oc INTO ult_numero FROM prtb00020
IF nuevo = "S" THEN
IF ult_numero IS NULL THEN
LET ult_numero = 0
END IF
LET ult_numero = ult_numero + 1
LET prtb08.num_oc = ult_numero
DISPLAY BY NAME prtb08.num_oc
UPDATE prtb00020 set num_oc = ult_numero,
# CONSECUTIVO ATOMICO: el UPDATE incrementa y bloquea la fila de prtb00020
# hasta el COMMIT, asi dos usuarios no pueden tomar el mismo num_oc
# (antes se leia y luego se escribia -> PK_prtb00012 duplicada)
BEGIN WORK
UPDATE prtb00020 SET num_oc = ISNULL(num_oc, 0) + 1,
us_crea = SUSER_SNAME(),
fech_crea = GETDATE()
SELECT num_oc INTO ult_numero FROM prtb00020
# AUTOCORRECCION: si el contador quedo por detras de prtb00012, salta al siguiente libre
LET existe_oc = 0
SELECT COUNT(*) INTO existe_oc FROM prtb00012 WHERE num_oc = ult_numero
IF existe_oc > 0 THEN
SELECT MAX(num_oc) + 1 INTO ult_numero FROM prtb00012
UPDATE prtb00020 SET num_oc = ult_numero
END IF
COMMIT WORK
LET prtb08.num_oc = ult_numero
DISPLAY BY NAME prtb08.num_oc
{ CALL defecto(usuarios,clave,impresor) RETURNING imprime,negrilla_on,negrillas_of,
doble_on,doble_off,comp_on,comp_off,
doce,normal,archivo,copia1
@@ -851,9 +858,8 @@ CALL seleccionarsalida() RETURNING r_output
fech_crea = GETDATE()
WHERE @num_oc = prtb09.num_oc
UPDATE prtb00020 SET num_oc = ult_numero,
us_Crea = SUSER_SNAME(),
fech_crea = GETDATE()
# (se elimino la re-escritura de prtb00020 aqui: el consecutivo ya se tomo
# arriba de forma atomica y re-escribirlo podia retroceder el contador)
# ACTUALIZA NUMERO TEMPORAL PARA EL DESPIECE
UPDATE prtb00022 SET num_oc = prtb08.num_oc WHERE num_oc = tmpnumero
+1 -1
View File
@@ -249,7 +249,7 @@ FUNCTION prpcmf010()
CALL msg(numero_msg)
## AQUI SE ELIMINAN LOS REGISTROS
COMMAND KEY ("L") "eLiminar"
COMMAND KEY ("L") "Eliminar"
UPDATE prtb00016 SET status_t = "E"
WHERE a.area_num = prtb16.area_num
+7 -6
View File
@@ -140,6 +140,7 @@ FUNCTION prprmt011()
--fechaSolDespacho
OPEN WINDOW prfmmt011 AT 10,10 WITH FORM "prfmmt011"
CALL ui.Window.getCurrent().setText("Administracion Ordenes")
#WHENEVER ERROR CONTINUE
LET w = ui.Window.getCurrent()
@@ -201,7 +202,7 @@ FUNCTION prprmt011()
IF busqueda IS NULL THEN
LET selec1 =
" SELECT 'N', x.cerrada, x1.estado_produccion,x1.estado_producto,x1.departamento,x3.nom_dpto,RTRIM(CAST(x.sec_vend AS CHAR)) + ' ' + RTRIM(b.nom1_emp), b.apell1_emp, ",
" CONVERT(CHAR(10), x.fecha_oc,103) AS fecha_orden , CONVERT(char(10),x1.fecha_compromiso,103) ,x1.fecha_llegada, x1.fecha_disp_entrega, ",
" x.fecha_oc AS fecha_orden , x1.fecha_compromiso ,x1.fecha_llegada, x1.fecha_disp_entrega, ",
" x1.fecha_solic_despacho, x1.fecha_instalacion, x.cotizacion_no, x.num_oc,x5.num_oc, x.observacion,g.descripcion, CAST(e.tipo_cliente AS CHAR(2)) ",
" + '-' + CAST(e.sec_cliente AS CHAR(6)) + ' ' + RTRIM(e.nombre) ,x4.descripcion, CAST(x1.cod_n AS VARCHAR(4)) + '-' + CAST(x1.cod_grupo AS VARCHAR(4)) ",
" + '-' + CAST(x1.cod_tipo AS VARCHAR(4)) + '-' + CAST(x1.cod_sec AS VARCHAR(7)) + ' ' + RTRIM(x2.descrip_esp), ",
@@ -243,7 +244,7 @@ FUNCTION prprmt011()
END IF
LET selec1 =
" SELECT 'N', x.cerrada, x1.estado_produccion,x1.estado_producto,x1.departamento,x3.nom_dpto,RTRIM(CAST(x.sec_vend AS CHAR)) + ' ' + RTRIM(b.nom1_emp), b.apell1_emp, ",
" CONVERT(CHAR(10), x.fecha_oc,103) AS fecha_orden , CONVERT(char(10),x1.fecha_compromiso,103) ,
" x.fecha_oc AS fecha_orden , x1.fecha_compromiso ,
x1.fecha_llegada,x1.fecha_disp_entrega, ",
" x1.fecha_solic_despacho, x1.fecha_instalacion, x.cotizacion_no, x.num_oc,x5.num_oc, x.observacion,g.descripcion, CAST(e.tipo_cliente AS CHAR(2)) ",
" + '-' + CAST(e.sec_cliente AS CHAR(6)) + ' ' + RTRIM(e.nombre) ,x4.descripcion, CAST(x1.cod_n AS VARCHAR(4)) + '-' + CAST(x1.cod_grupo AS VARCHAR(4)) ",
@@ -281,7 +282,7 @@ FUNCTION prprmt011()
IF actualiza_log_produccion="SI" THEN
LET selec1=
" SELECT 'N', x.cerrada, x1.estado_produccion,x1.departamento,x3.nom_dpto,RTRIM(CAST(x.sec_vend AS CHAR)) + ' ' + RTRIM(b.nom1_emp), b.apell1_emp, ",
" CONVERT(CHAR(10), x.fecha_oc,103) AS fecha_orden , CONVERT(char(10),x1.fecha_compromiso,103) ,' ', x.cotizacion_no, x.num_oc, x.observacion,g.descripcion, CAST(e.tipo_cliente AS CHAR(2)) ",
" x.fecha_oc AS fecha_orden , x1.fecha_compromiso ,' ', x.cotizacion_no, x.num_oc, x.observacion,g.descripcion, CAST(e.tipo_cliente AS CHAR(2)) ",
" + '-' + CAST(e.sec_cliente AS CHAR(6)) + ' ' + RTRIM(e.nombre) , CAST(x1.cod_n AS VARCHAR(4)) + '-' + CAST(x1.cod_grupo AS VARCHAR(4)) ",
" + '-' + CAST(x1.cod_tipo AS VARCHAR(4)) + '-' + CAST(x1.cod_sec AS VARCHAR(4)) + ' ' + RTRIM(x2.descrip_esp), ",
" SUM(x1.cantidad), '0' , '0' , '0' , x.sec_vend, x1.cod_n, x1.cod_grupo, x1.cod_tipo, x1.cod_Sec, e.tipo_cliente, e.sec_cliente, ",
@@ -440,7 +441,7 @@ FUNCTION prprmt011()
IF veces > 1 THEN
LET att[idx].col7 = 'blue reverse'
ELSE
SELECT CONVERT(CHAR(10),a.fecha_llegada,103) INTO arr_ordenes[idx].fecha_llegada
SELECT a.fecha_llegada INTO arr_ordenes[idx].fecha_llegada
FROM cctb00026 a
WHERE a.num_oc = arr_ordenes[idx].num_oc AND
a.cod_n = arr_ordenes[idx].cod_n AND
@@ -1091,7 +1092,7 @@ FUNCTION fparciales(xnum_oc,xcodn,xcodgrupo,xcodtipo,xcodsec,xfecha,xproducto)
DECLARE busca_parcial CURSOR FOR
SELECT CONVERT(CHAR(10),a.fecha_compromiso,103),a.cantidad FROM prtb00028 a
SELECT a.fecha_compromiso,a.cantidad FROM prtb00028 a
WHERE a.num_oc = xnum_oc AND
a.cod_n = xcodn AND
a.cod_grupo = xcodgrupo AND
@@ -1313,7 +1314,7 @@ FUNCTION vepcmf008(num_cotizacion)
LET SELEC = " SELECT DISTINCT a.cod_cia,a.ventas,a.cotizacion_no,a.tipo_cliente,a.sec_cliente,a.nombre_cliente, " ||
" a.rnc,a.nombre_proyecto,a.direccion_cliente,a.cod_provincia,a.direccion_proyecto, " ||
" a.telefono_r,a.telefono_o,a.email,a.tipo_precio,a.beeper,a.celular,a.prima,a.fax1,a.celular1, " ||
" a.fax, CONVERT(CHAR(10),a.fecha,103),CONVERT(CHAR(10),a.fecha_entrega,103), " ||
" a.fax, a.fecha,a.fecha_entrega, " ||
" a.plazo_entrega,a.comentario,a.contacto, a.cond_pago,a.sec_Vend,a.porc_itbi," ||
" a.total_bruto,a.sub_total,a.monto_Desc,a.monto_itbi,a.total_neto,a.monto_dolar,a.num_emp_inst, " ||
" a.codigo_dgii,a.tipo_ncf,a.cliente_generico,a.sec_vend_aux,a.codigo,a.cod_zona,a.sincronizado, "||
+2 -2
View File
@@ -54,7 +54,7 @@ FUNCTION prprmt020()
OPEN WINDOW w1 WITH FORM "prfmmt012"
DIALOG ATTRIBUTES(UNBUFFERED,FIELD ORDER FORM)
INPUT BY NAME prtb09.num_oc
INPUT BY NAME prtb08.num_oc
BEFORE INPUT
LET d_tipos="PDF"
@@ -86,7 +86,7 @@ FUNCTION prprmt020()
AFTER FIELD num_oc
SELECT a.cotizacion_no,b.nombre,a.sec_vend,ISNULL(c.nom1_emp,' ')+ISNULL(c.apell1_emp,' '),
a.tipo_cliente,a.sec_cliente
INTO prtb09.cotizacion_no,nombre_cliente,psec_vend,vendedor,
INTO prtb08.cotizacion_no,nombre_cliente,psec_vend,vendedor,
prtb08.tipo_cliente,prtb08.sec_cliente
FROM prtb00012 a,vetb00004 b,adtb00003 c
WHERE a.num_oc = prtb08.num_oc AND
+1 -1
View File
@@ -177,7 +177,7 @@ END RECORD
" ORDEN ECOMMERCE ",orden_externa USING "&&&&&&&"
INPUT ARRAY detalle FROM sdetalle.* ATTRIBUTE(WITHOUT DEFAULTS)
ON ACTION impresion ATTRIBUTE(TEXT="Orden",IMAGE="printer")
CALL impresion(pnum_oc)
CALL impresion_oc(pnum_oc)
ON ACTION etiqueta ATTRIBUTE(TEXT="Label",IMAGE="fa-tag")
LET datos.celular = orden.celular
LET datos.cliente = orden.nombre_envio
+1 -1
View File
@@ -18,7 +18,7 @@
<LAYOUTNODE name="Layout Node9" y="max-33.3652" width="214.531" length="26.3906" anchorY="1" alignment="center" layoutDirection="topToBottom" floatingBehavior="free">
<WORDBOX name="WordBox34" width="213.984" length="14.3281" alignment="far" fontSize="20" fontBold="true" underline="true" layoutDirection="topToBottom" baselineType="leftleft" textAlignment="center" text="ANÁLISIS PRODUCCIÓN" trimText="both"/>
</LAYOUTNODE>
<IMAGEBOX name="ImageBox1_1" y="6.5535" width="230.836" length="92.4741" floatingBehavior="enclosed" url="file:///F:/MARMOTECHC/IMAGENES/logo.png" intendedResolution="120"/>
<IMAGEBOX name="ImageBox1_1" y="6.5535" width="230.836" length="92.4741" floatingBehavior="enclosed" url="IMAGENES/Logo.png" intendedResolution="120"/>
<rtl:input-variable name="fecha_reporte" type="FGLString" expectedLocation="expectedAhead"/>
<WORDBOX name="fecha_reporte Value1" class="grwDateValue" x="4.0943" y="414.196" width="103.969" anchorX="0" anchorY="0" floatingBehavior="enclosed" textAlignment="right" text="{{fecha_reporte}}"/>
</MINIPAGE>
+63 -28
View File
@@ -79,6 +79,8 @@ FUNCTION prprrp016()
END RECORD,
salida,visualiza CHAR(20)
DEFINE hay_datos SMALLINT
OPTIONS
PROMPT LINE 23,
FORM LINE 8,
@@ -201,12 +203,46 @@ FUNCTION prprrp016()
"WHERE ",criterio clipped,
" and a.status_t is null and f.status_t is null "
END IF
END IF
PREPARE comando FROM selec
DECLARE busca CURSOR FOR comando
-- Verifica primero si hay registros: si el reporte se inicia sin filas,
-- el motor de reportes falla al no poder resolver p_compania.nombre
-- (variable "look ahead" del encabezado) porque nunca se llega a imprimir nada.
OPEN busca
FETCH busca INTO busqueda.cotizacion_no,busqueda.fecha,busqueda.tipo_cliente,
busqueda.sec_cliente,busqueda.nombre_proyecto,busqueda.direccion_proyecto,
busqueda.telefono_r,busqueda.nombre,busqueda.num_oc,busqueda.fecha_oc,
busqueda.fecha_entrega,busqueda.fecha_cierre,busqueda.cod_n,
busqueda.cod_grupo,busqueda.cod_tipo,busqueda.cod_sec,
busqueda.descrip_esp,busqueda.unidad_med,busqueda.cantidad,
busqueda.precio,busqueda.cantidad_2,busqueda.cod_mov,
busqueda.fecha_doc,busqueda.documento,busqueda.status_mov,
busqueda.simbolo,busqueda.vendedor,busqueda.monto_cotizacion,
busqueda.condicion,busqueda.estado_orden,busqueda.telefono,
busqueda.celular,busqueda.email,busqueda.contacto
IF STATUS = NOTFOUND THEN
CALL fgl_winmessage("WARNING","NO EXISTEN REGISTROS CON ESA CONDICION","SOP")
LET hay_datos = FALSE
ELSE
LET hay_datos = TRUE
END IF
# El formulario solo guarda el texto visible del combo (no el valor interno
# que tenia el .per original), asi que aqui se traduce de vuelta.
CASE salida CLIPPED
WHEN "Detallado" LET salida = "prprrp116.4rp"
WHEN "Resumido" LET salida = "prprrp016a.4rp"
END CASE
CASE visualiza CLIPPED
WHEN "PANTALLA" LET visualiza = "SVG"
WHEN "ACROBAT READER" LET visualiza = "PDF"
WHEN "EXCEL" LET visualiza = "XLSX"
END CASE
LET r_filename = salida CLIPPED
IF fgl_report_loadCurrentSettings(r_filename) THEN -- load the .4rp file
LET r_output=visualiza CLIPPED
LET preview=1
@@ -216,30 +252,13 @@ FUNCTION prprrp016()
END IF
IF handler IS NOT NULL THEN -- report engine was configured ok
IF handler IS NOT NULL AND hay_datos THEN -- report engine was configured ok and there is data to print
START REPORT reporte_16 TO XML HANDLER handler
FOREACH busca INTO busqueda.cotizacion_no,busqueda.fecha,busqueda.tipo_cliente,
busqueda.sec_cliente,busqueda.nombre_proyecto,busqueda.direccion_proyecto,
busqueda.telefono_r,busqueda.nombre,busqueda.num_oc,busqueda.fecha_oc,
busqueda.fecha_entrega,busqueda.fecha_cierre,busqueda.cod_n,
busqueda.cod_grupo,busqueda.cod_tipo,busqueda.cod_sec,
busqueda.descrip_esp,busqueda.unidad_med,busqueda.cantidad,
busqueda.precio,busqueda.cantidad_2,busqueda.cod_mov,
busqueda.fecha_doc,busqueda.documento,busqueda.status_mov,
busqueda.simbolo,busqueda.vendedor,busqueda.monto_cotizacion,
busqueda.condicion,busqueda.estado_orden,busqueda.telefono,
busqueda.celular,busqueda.email,busqueda.contacto
IF STATUS = NOTFOUND THEN
CALL fgl_winmessage("WARNING","NO EXISTEN REGISTROS CON ESA CONDICION","SOP")
EXIT FOREACH
END IF
-- La primera fila ya fue leida arriba (para saber si hay_datos); aqui se
-- procesa esa fila y se sigue con FETCH manual hasta agotar el cursor.
WHILE hay_datos
IF busqueda.cantidad_2 IS NULL THEN
LET busqueda.cantidad_2 = 0
END IF
@@ -247,7 +266,7 @@ IF handler IS NOT NULL THEN -- report engine was configured ok
LET busqueda.fecha_avance= NULL
LET busqueda.monto_avance = NULL
SELECT MAX(a.num_doc),MAX(a.fecha_orig)
SELECT MAX(a.num_doc),MAX(a.fecha_orig)
INTO busqueda.avance,busqueda.fecha_avance,
busqueda.monto_avance
FROM cctb00001 a
@@ -255,7 +274,7 @@ IF handler IS NOT NULL THEN -- report engine was configured ok
a.tipo_Doc = 'AV' and a.tipo_cliente = busqueda.tipo_cliente and
a.sec_cliente = busqueda.sec_cliente and a.status_t is null and
a.fecha_orig > '08/01/2009'
LET busqueda.codigo = busqueda.cod_n using "&&&&","-",
busqueda.cod_grupo USING "&&&&","-",
busqueda.cod_tipo USING "&&&&","-",
@@ -266,11 +285,27 @@ IF handler IS NOT NULL THEN -- report engine was configured ok
IF busqueda.estado_orden = "S" THEN
LET busqueda.estado_orden = "CERRADA"
END IF
OUTPUT TO REPORT reporte_16(busqueda.*)
END FOREACH
FETCH busca INTO busqueda.cotizacion_no,busqueda.fecha,busqueda.tipo_cliente,
busqueda.sec_cliente,busqueda.nombre_proyecto,busqueda.direccion_proyecto,
busqueda.telefono_r,busqueda.nombre,busqueda.num_oc,busqueda.fecha_oc,
busqueda.fecha_entrega,busqueda.fecha_cierre,busqueda.cod_n,
busqueda.cod_grupo,busqueda.cod_tipo,busqueda.cod_sec,
busqueda.descrip_esp,busqueda.unidad_med,busqueda.cantidad,
busqueda.precio,busqueda.cantidad_2,busqueda.cod_mov,
busqueda.fecha_doc,busqueda.documento,busqueda.status_mov,
busqueda.simbolo,busqueda.vendedor,busqueda.monto_cotizacion,
busqueda.condicion,busqueda.estado_orden,busqueda.telefono,
busqueda.celular,busqueda.email,busqueda.contacto
IF STATUS = NOTFOUND THEN
LET hay_datos = FALSE
END IF
END WHILE
FINISH REPORT reporte_16
END IF
CLOSE busca
AFTER DIALOG
@@ -349,7 +384,7 @@ BEFORE GROUP OF x.cotizacion_no
PRINTX x.cotizacion_no,x.direccion_proyecto,x.nombre_proyecto,
x.tipo_cliente,x.sec_cliente,x.telefono_r,x.num_oc,x.fecha,x.fecha_cierre,
x.fecha_entrega,x.fecha_oc
x.fecha_entrega,x.fecha_oc,p_compania.nombre
BEFORE GROUP OF x.codigo
+10 -4
View File
@@ -35,14 +35,16 @@
<RecordField colName="" fieldIdRef="26" name="xnum_emp" sqlTabName="" table_alias_name="" uid="{cbe6a079-16f8-4d94-8834-508b8802f0eb}"/>
<RecordField colName="" fieldIdRef="27" name="nombre_empleado" sqlTabName="" table_alias_name="" uid="{025a8c47-52a6-46a7-809d-068fce546410}"/>
<RecordField colName="" fieldIdRef="28" name="bloque" sqlTabName="" table_alias_name="" uid="{1fdfddbb-c15b-430b-900a-277fe124636e}"/>
<RecordField colName="" fieldIdRef="29" name="xnum_ocp" sqlTabName="" table_alias_name="" uid="{3b6f1c2e-8d4a-4f7b-9e21-6a5c0d9e7f11}"/>
<RecordField colName="" fieldIdRef="30" name="proveedor" sqlTabName="" table_alias_name="" uid="{9c2e7a41-5b3d-4e8f-a1c6-2d7f8e0b4a22}"/>
</Record>
<Form gridHeight="31" gridWidth="163" name="acfmrp010" style="basic" text="ETIQUETAS">
<Form gridHeight="33" gridWidth="163" name="acfmrp010" style="basic" text="ETIQUETAS">
<ActionDefaultList name="ActionDefaultList1">
<ActionDefault image="cancel" name="cancel" text="Cancela operacion"/>
<ActionDefault image="find" name="busca" text="Busca informacion"/>
<ActionDefault image="printer" name="imprime" text="Imprimir"/>
</ActionDefaultList>
<Grid gridHeight="28" gridWidth="163" name="Grid1" posX="0" posY="1">
<Grid gridHeight="30" gridWidth="163" name="Grid1" posX="0" posY="1">
<Group gridHeight="10" gridWidth="138" name="Group1" posX="1" posY="1" text="INFORMACIONES SOBRE EL TAMANO DE LA ETIQUETA E INVENTARIO">
<Label posX="1" posY="1" text="INVENTARIO"/>
<ComboBox aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="inventario" defaultValue="PRODUCTOS TERMINADOS" fieldId="9" gridHeight="1" gridWidth="43" include="ACTIVOS FIJOS|PRODUCTOS TERMINADOS|MATERIA PRIMA|REPUESTOS" items="ACTIVOS FIJOS, PRODUCTOS TERMINADOS, MATERIA PRIMA, REPUESTOS" name="inventario" posX="20" posY="1" sqlTabName="formonly" tabIndex="1" table_alias_name="" widget="ComboBox">
@@ -99,7 +101,7 @@
<Label posX="2" posY="4" text="DEPARTAMENTO"/>
<Edit aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="codigo_dp" fieldId="13" gridHeight="1" gridWidth="7" name="codigo_dp" posX="21" posY="4" sqlTabName="formonly" tabIndex="13" table_alias_name="" widget="Edit"/>
</Group>
<Group gridHeight="6" gridWidth="70" name="Group4" posX="70" posY="11" text="Informacion Orden">
<Group gridHeight="8" gridWidth="70" name="Group4" posX="70" posY="11" text="Informacion Orden">
<Label gridHeight="1" gridWidth="10" name="Label2" posX="3" posY="1" text="Orden"/>
<Edit aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="" fieldId="23" gridHeight="1" gridWidth="10" name="xnum_oc" posX="17" posY="1" sqlTabName="" tabIndex="25" table_alias_name="" title="Edit1" widget="Edit"/>
<Label gridHeight="1" gridWidth="10" name="Label3" posX="3" posY="2" text="Cliente"/>
@@ -109,8 +111,12 @@
<Edit aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="" fieldId="27" gridHeight="1" gridWidth="40" name="nombre_empleado" posX="28" posY="3" sqlTabName="" tabIndex="28" table_alias_name="" title="Edit3" widget="Edit"/>
<Label gridHeight="1" gridWidth="10" name="Label5" posX="3" posY="4" text="Bloque"/>
<Edit aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" case="upper" colName="" fieldId="28" gridHeight="1" gridWidth="27" name="bloque" posX="17" posY="4" scroll="true" sqlTabName="" tabIndex="29" table_alias_name="" title="Edit1" widget="Edit"/>
<Label gridHeight="1" gridWidth="12" name="Label6" posX="3" posY="5" text="Orden Compra"/>
<Edit aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="" comment="Orden de compra (cotb00014)" fieldId="29" gridHeight="1" gridWidth="10" name="xnum_ocp" posX="17" posY="5" sqlTabName="" tabIndex="30" table_alias_name="" title="Edit4" widget="Edit"/>
<Label gridHeight="1" gridWidth="10" name="Label7" posX="3" posY="6" text="Proveedor"/>
<Edit aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="" fieldId="30" gridHeight="1" gridWidth="51" name="proveedor" posX="17" posY="6" sqlTabName="" tabIndex="31" table_alias_name="" title="Edit5" widget="Edit"/>
</Group>
<Group gridHeight="9" gridWidth="161" name="Group3" posX="1" posY="17" text="MEDIDAS, SOLO PARA MATERIA PRIMA O PRODUCTOS TERMINADOS">
<Group gridHeight="9" gridWidth="161" name="Group3" posX="1" posY="19" text="MEDIDAS, SOLO PARA MATERIA PRIMA O PRODUCTOS TERMINADOS">
<Table gridHeight="5" gridWidth="157" name="Table1" posX="2" posY="2" totalRows="4" unitWidth="characters" width="157">
<CheckBox aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="imp" defaultValue="NO" fieldId="14" gridHeight="1" gridWidth="3" name="imp" notNull="true" posX="0" posY="0" required="true" sqlTabName="formonly" tabIndex="14" table_alias_name="" title="IMPRIME" valueChecked="SI" valueUnchecked="NO" widget="CheckBox"/>
<Edit aggregateColName="" aggregateName="" aggregateTableAliasName="" aggregateTableName="" colName="pcodid" fieldId="0" gridHeight="1" gridWidth="10" name="pcodid" posX="3" posY="0" scroll="true" sqlTabName="formonly" tabIndex="15" table_alias_name="" widget="Edit"/>
+18 -6
View File
@@ -442,6 +442,11 @@ FUNCTION acpcad001() --Consultar Datos Activo
LET i = i + 1
END FOREACH
-- el FOREACH deja un elemento vacio al final; al seleccionarlo getdata armaba
-- "WHERE a.codigo = " sin valor (-201) y el programa se caia
IF DisArray.getLength() >= i THEN
CALL DisArray.deleteElement(i)
END IF
END FUNCTION
@@ -470,12 +475,12 @@ FUNCTION getdata(idx INT)
,a.id_MaintainX
,a.id_codigo
,b.nombre
FROM actb00001 a left join irtb00009 b on a.id_codigo = b.codigo
WHERE a.codigo = " || DisArray[idx].codigo1 || "
AND a.status_t is null and b.status_t is null
FROM actb00001 a left join irtb00009 b on a.id_codigo = b.codigo AND b.status_t is null
WHERE a.codigo = ?
AND a.status_t is null
ORDER BY a.codigo"
EXECUTE query INTO infoArray.*
EXECUTE query USING DisArray[idx].codigo1 INTO infoArray.*
SELECT a.descripcion
INTO des.descripcion2
@@ -568,6 +573,9 @@ FUNCTION insertData()
IF infoArray.id_MaintainX IS NULL THEN
ROLLBACK WORK
-- antes seguia grabando fuera de la transaccion (el COMMIT caia -255)
CALL fgl_winmessage("MaintainX", "NO SE PUDO REGISTRAR EN MAINTAINX, OPERACION CANCELADA", "stop")
RETURN
END IF
END IF
@@ -701,6 +709,8 @@ INITIALIZE checking TO NULL
IF answer IS NULL THEN
ROLLBACK WORK
CALL fgl_winmessage("MaintainX", "NO SE PUDO ACTUALIZAR MAINTAINX, OPERACION CANCELADA", "stop")
RETURN
END IF
END IF
@@ -811,11 +821,13 @@ INITIALIZE checking TO NULL
END IF
IF infoArray.id_MaintainX IS NOT NULL THEN
CALL ApiMaintainX('DELETE',infoArray.id_MaintainX,maquinaria.*, infoArray.*,extraCampos.*,NULL)
CALL ApiMaintainX('DELETE',infoArray.id_MaintainX,infoArray.*,maquinaria.*,extraCampos.*,NULL) -- antes maquinaria/infoArray invertidos
RETURNING answer
IF answer != 1 THEN
IF answer != 1 OR answer IS NULL THEN
ROLLBACK WORK
CALL fgl_winmessage("MaintainX", "NO SE PUDO ELIMINAR EN MAINTAINX, OPERACION CANCELADA", "stop")
RETURN
END IF
END IF
@@ -0,0 +1,17 @@
-- acprmt001 (version ene-2025, integracion MaintainX) usa 4 columnas que nunca se
-- crearon en actb00001: proveedor del activo, tipo de activo y activo padre.
-- Todas NULL: no afectan filas existentes ni a los programas que no las usan.
-- Ejecutar primero en la .250 (QA G6); en produccion (.40.8) solo cuando se apruebe.
USE marmotech;
GO
IF COL_LENGTH('dbo.actb00001','cod_sp') IS NULL
ALTER TABLE dbo.actb00001 ADD cod_sp INT NULL; -- cotb00001.cod_sp (proveedor)
IF COL_LENGTH('dbo.actb00001','cod_sp_sec') IS NULL
ALTER TABLE dbo.actb00001 ADD cod_sp_sec INT NULL; -- cotb00001.cod_sp_sec
IF COL_LENGTH('dbo.actb00001','tipo_activo') IS NULL
ALTER TABLE dbo.actb00001 ADD tipo_activo VARCHAR(30) NULL; -- CAMIONES, IT HARDWARE, MAQUINARIAS, MONTACARGAS, EDIFICIOS
IF COL_LENGTH('dbo.actb00001','activo_padre') IS NULL
ALTER TABLE dbo.actb00001 ADD activo_padre INT NULL; -- actb00001.codigo del activo padre
GO
SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('dbo.actb00001')
AND name IN ('cod_sp','cod_sp_sec','tipo_activo','activo_padre');
+3 -2
View File
@@ -235,11 +235,12 @@ FUNCTION acpcmf004()
RETURN
END IF
-- G6: trans LIKE actb00004.* incluye rowid; sin el 2o a.rowid todo quedaba corrido una columna (-1213)
LET SELEC =
"SELECT a.rowid,a.codigo
"SELECT a.rowid,a.rowid,a.codigo
,a.num_doc
,CONVERT(VARCHAR(10),a.fecha,103)
,a.cod_mov
@@ -419,7 +420,7 @@ FUNCTION acpcmf004()
CALL fgl_winmessage("INFO","NO SE ACTUALIZARON REGISTROS","INFO")
EXIT PROGRAM
END IF
SELECT MIN(convert(varchar(10),a.fecha,103)) INTO fecha6 FROM actb00004 a
SELECT MIN(a.fecha) INTO fecha6 FROM actb00004 a -- G6: MIN sobre texto dd/mm/yyyy no da la fecha menor
WHERE a.codigo = trans.codigo AND a.status_t IS NULL
IF fecha6 IS NULL THEN

Some files were not shown because too many files have changed in this diff Show More