381 Commits

Author SHA1 Message Date
26249c893c Merge branch 'fix/factor' into 'main'
resuelto: no hay que sumar las horas para el calculo del divisor del factor

See merge request jjimenez/safekat!875
2025-07-01 12:19:24 +00:00
b9360ef7e5 resuelto: no hay que sumar las horas para el calculo del divisor del factor 2025-07-01 14:19:03 +02:00
911124287f resuelto: no hay que sumar las horas para el calculo del divisor del factor 2025-07-01 14:16:55 +02:00
055274d6df Merge branch 'mod/costes_margenes' into 'main'
Mod/costes margenes

See merge request jjimenez/safekat!874
2025-07-01 09:54:51 +00:00
f900ace902 limitar descuento a total margen 2025-07-01 11:49:20 +02:00
401c2c8f5a desglosados costes y margenes impresion 2025-07-01 11:02:59 +02:00
594da68b3a desglosados costes y margenes impresion 2025-07-01 11:02:03 +02:00
34701e5960 Merge branch 'mod/lineas_presupuesto_costes_margenes' into 'main'
coste-margen de clicks y horas en las lineas y añadidos colores. se toca...

See merge request jjimenez/safekat!873
2025-06-30 14:26:06 +00:00
364b9f8ccd coste-margen de clicks y horas en las lineas y añadidos colores. se toca resumen para que todo cuadrea con lo nuevo 2025-06-30 16:25:42 +02:00
b3336273d0 Merge branch 'fix/cambio_sobrecubierta_infinite_loop' into 'main'
arreglado

See merge request jjimenez/safekat!872
2025-06-30 10:20:13 +00:00
bbd2a389af arreglado 2025-06-30 12:19:53 +02:00
8007e33760 Merge branch 'fix/change_limite_paginas' into 'main'
arreglado

See merge request jjimenez/safekat!871
2025-06-30 10:13:58 +00:00
266e872f8f arreglado 2025-06-30 12:13:23 +02:00
b11b1807d8 Merge branch 'fix/change_faja_infinite_loop' into 'main'
arreglado el bucle infinito the change faja

See merge request jjimenez/safekat!870
2025-06-30 09:47:47 +00:00
f5a58dc32d arreglado el bucle infinito the change faja 2025-06-30 11:47:20 +02:00
102ba8267b Merge branch 'mod/presupuesto_catalogoId' into 'main'
Mod/presupuesto catalogo

See merge request jjimenez/safekat!869
2025-06-29 21:27:23 +00:00
508758331d Añadida la logica en importador de RAMA 2025-06-29 23:27:03 +02:00
416b4db915 Añadida la logica de crear la columna y modelo 2025-06-29 23:09:09 +02:00
4e2003b8b8 Merge branch 'fix/forzar_rotativa_obtener_interior_cliente' into 'main'
corregidos varios fallos que no permitian cogetr la rotativa cuando es un...

See merge request jjimenez/safekat!868
2025-06-28 10:46:15 +00:00
5590076d7d corregidos varios fallos que no permitian cogetr la rotativa cuando es un presupuesto con forzar_rotativa_pod 2025-06-28 12:45:52 +02:00
ddf3255a8a Merge branch 'mod/presupuesto_cliente' into 'main'
Mod/presupuesto cliente

See merge request jjimenez/safekat!867
2025-06-28 09:59:48 +00:00
4694d62cd4 Merge branch 'main' into mod/presupuesto_cliente 2025-06-28 11:52:34 +02:00
0c85af66da Merge branch 'fix/importador_erpold_gramajes' into 'main'
modificado error de obtener gramajes en comparador cubierta. tambien corregido...

See merge request jjimenez/safekat!866
2025-06-28 09:51:28 +00:00
f6ffa20d5f modificado error de obtener gramajes en comparador cubierta. tambien corregido problema con la obtencion de gramajes en presupuesto admin que no cogia el valor de las solapas 2025-06-28 11:50:59 +02:00
53ec5945e8 trabajando en el formulario envio de ferros 2025-06-28 11:29:21 +02:00
9fcda514f0 guardando direcciones ferro en presupuesto cliente 2025-06-28 11:27:39 +02:00
410d21dc5f trabajando en las direcciones ferro / prototipo 2025-06-27 12:44:55 +02:00
4a60bcdd61 corregido el texto del error del tipo de libro y que se borre el error 2025-06-27 08:38:23 +02:00
33a196667e modificado archivo de config para evitar error 2025-06-26 09:34:41 +02:00
03b43de185 terminado datosGenerales para la validacion 2025-06-26 08:58:13 +02:00
2d267386a6 nuevo docker 2025-06-25 18:27:17 +02:00
7e82142b38 nuevo docker 2025-06-25 18:26:27 +02:00
b240107565 Merge branch 'main' into mod/presupuesto_cliente 2025-06-25 13:55:54 +02:00
647c0bd72d trabajando en la validación de los datosgenerales 2025-06-25 13:55:31 +02:00
847b476341 Merge branch 'fix/historico_catalogo' into 'main'
Filtrando por estados finalizados para catalogo del ERP antiguo

See merge request jjimenez/safekat!865
2025-06-25 09:21:49 +00:00
6081a34c05 Filtrando por estados finalizados para catalogo del ERP antiguo 2025-06-25 11:20:05 +02:00
c3bce03921 terminada validación nueva en diseniocubierta 2025-06-25 11:14:09 +02:00
0b598e14d7 Merge branch 'main' into mod/presupuesto_cliente 2025-06-25 10:06:42 +02:00
83753d1784 trabajando en cubierta 2025-06-25 10:06:21 +02:00
c35e683089 Merge branch 'imnavajas-main-patch-59857' into 'main'
Delete wire-o.png:Zone.Identifier

See merge request jjimenez/safekat!864
2025-06-25 08:05:31 +00:00
c9b822c9c2 Delete wire-o.png:Zone.Identifier 2025-06-25 08:05:16 +00:00
ff9ce9eda2 trabajando en la cubierta 2025-06-25 07:50:01 +02:00
41fde19f43 modificado disenio interior para que borre los errores 2025-06-24 17:56:22 +02:00
3b0da8d560 Merge branch 'mod/pedidos_produccion_a_facturas' into 'main'
corregidos varios problemas con los presupuestos (calculo envio base debido al...

See merge request jjimenez/safekat!863
2025-06-24 15:07:20 +00:00
fc68676c29 hecho 2025-06-24 17:05:53 +02:00
365a487791 Merge branch 'main' into mod/presupuesto_cliente 2025-06-24 13:52:22 +02:00
9c505584b1 Merge branch 'fix/lista_maquinas_en_papeles_solo_imp' into 'main'
Fix/lista maquinas en papeles solo imp

See merge request jjimenez/safekat!862
2025-06-24 11:51:43 +00:00
94b72073e4 terminado 2025-06-24 13:50:47 +02:00
0b3574ca63 resolviendo errores 2025-06-24 13:44:20 +02:00
cf8ddb3156 añadidos js para edit y add 2025-06-24 13:34:57 +02:00
fd81a188d4 Merge branch 'main' into mod/presupuesto_cliente 2025-06-24 13:09:59 +02:00
4bfc679c3e los acabados tienen que tener el check de mostrar en cliente a 1. Además se ha corregido un error al editar este check dentro de los servicios de acabado 2025-06-24 13:06:46 +02:00
819f297e90 añadido checkeo de lomo en presupuesto admin 2025-06-23 18:33:46 +02:00
da0ca27c8c correjidas cosas en cuanto a mostrar lomo. También añadido calculo de paginas pares 2025-06-20 19:51:32 +02:00
75ac2e0218 añadida migración para el tamaño de los lomos. Cambiado nombre de variables en el codigo también 2025-06-20 18:46:05 +02:00
d89d140dac arreglado el calculo del coste del envio para cuando hay más tiradas 2025-06-19 21:50:07 +02:00
4da6ee19c6 arreglado vista del mensaje de lomo máximo 2025-06-19 17:39:18 +02:00
4fde46a222 quitado d-flex para que hide() funcione en tipodelibro 2025-06-19 16:26:30 +02:00
55b10a7266 añadido wire-o 2025-06-18 13:44:03 +02:00
219bdfeaa3 añadida imagen wire-o 2025-06-18 09:45:50 +02:00
1f5a625513 arreglado total aceptado 2025-06-18 09:36:12 +02:00
beefc2f416 arreglado resumen de cliente y mensaje de cubierta sin plastificado 2025-06-18 09:29:16 +02:00
73fe7e5097 se añaden los limites del numero de paginas en el presupuesto admin dependiendo del tipo de libro 2025-06-17 10:40:33 +02:00
7d1eef9b28 grapado sólo tapa blanda 2025-06-17 09:38:44 +02:00
018119a3c3 corregidos varios problemas con los presupuestos (calculo envio base debido al peso de las guardas, resumen, etc) 2025-06-16 20:19:39 +02:00
b2652fc277 solucionado problema con solapas 2025-06-16 15:13:23 +02:00
6c020375be Merge branch 'bug/delete_maquina' into 'main'
Arreglada url delete

See merge request jjimenez/safekat!861
2025-06-13 06:44:07 +00:00
45bd973507 Arreglada url delete 2025-06-13 08:43:20 +02:00
75020a075c validación correcta. Falta que no se guardan las solapas 2025-06-12 19:30:01 +02:00
900e0b373e Merge branch 'main' into mod/presupuesto_cliente 2025-06-12 15:32:26 +02:00
00073b3f7e modificado mensaje de cubierta sin acabado 2025-06-12 15:31:56 +02:00
154dfd14f6 Merge branch 'feat/backups' into 'main'
Feat/backups

See merge request jjimenez/safekat!860
2025-06-12 12:58:16 +00:00
8288219872 Implementada logica para entornos dev/prod 2025-06-12 14:57:48 +02:00
db91776747 terminada validación de cubierta 2025-06-12 13:49:56 +02:00
70087a24b6 modificado para que no checkee en el interior si ha habido problema previo 2025-06-11 20:11:50 +02:00
505cc6fb31 terminados datos generales e interior 2025-06-11 20:08:17 +02:00
b0bceb20bc Merge branch 'feat/backups' of https://git.imnavajas.es/jjimenez/safekat into feat/backups 2025-06-10 20:37:47 +02:00
b31d9b94eb Merge branch 'main' into feat/backups 2025-06-10 20:37:35 +02:00
ae60955b3f Merge branch 'fix/review_OT_tables' into 'main'
cambiadas las query de las OTs

See merge request jjimenez/safekat!858
2025-06-10 18:37:11 +00:00
ee4de11cca cambiadas las query de las OTs 2025-06-10 20:36:41 +02:00
7aa577f316 Avances 2025-06-10 15:10:19 +02:00
882cc913de Merge branch 'main' into feat/backups 2025-06-09 21:25:27 +02:00
4fe8930217 Merge branch 'fix/tiempo_tarea_maquinista' into 'main'
corregido el error de que añadía el tiempo desde la parada a la finalización...

See merge request jjimenez/safekat!857
2025-06-09 19:21:53 +00:00
0bcd9899ef corregido el error de que añadía el tiempo desde la parada a la finalización en la tarea del maquinista. También se cambia el label del boton continuar dependiendo si la tarea está pendiente o pausada 2025-06-09 21:21:13 +02:00
6967a61d93 Avances 2025-06-09 15:18:12 +02:00
e53626bbfe Merge branch 'main' into 'feat/backups'
arreglado albaranes para que muestren las cajas. tambien se ha actualizado...

See merge request jjimenez/safekat!856
2025-06-09 08:08:21 +00:00
808bcd3847 Merge branch 'fix/update_ot_object_after_reset_tareas' into 'main'
reinicialización del servicio después de resetear las tareas

See merge request jjimenez/safekat!855
2025-06-07 09:41:52 +00:00
e0974068a0 reinicialización del servicio después de resetear las tareas 2025-06-07 11:40:59 +02:00
d3bcd295cb Merge branch 'fix/orden_trabajo_tareas_tiempo_estimado' into 'main'
solucionado el problema que al borrar una fecha de la OT se quedaba en caché...

See merge request jjimenez/safekat!853
2025-06-07 09:27:18 +00:00
6a3a10c7e8 solucionado el problema que al borrar una fecha de la OT se quedaba en caché el objeto anterior y no actualizaba el progreso 2025-06-07 11:26:52 +02:00
e2ff0f6667 Merge branch 'main' into fix/orden_trabajo_tareas_tiempo_estimado 2025-06-06 15:15:56 +02:00
3a0f355ffe Merge branch 'mod/registro' into 'main'
Deshabilitado registro

See merge request jjimenez/safekat!852
2025-06-06 08:45:49 +00:00
87661d855d Deshabilitado registro 2025-06-06 10:45:22 +02:00
95ffb22c84 Merge branch 'fix/versioned_assets' into 'main'
Fix/versioned assets

See merge request jjimenez/safekat!851
2025-06-06 08:03:58 +00:00
0e802f791b Aplicado a JS estaticos 2025-06-06 09:12:51 +02:00
5a9326ae82 Añadido helper de gestion de assets caducados e implementado en CSS de PDFs 2025-06-06 09:06:28 +02:00
06ba0c0500 realizados cambios para que se calcule el tiempo estimado 2025-06-05 23:48:21 +02:00
760144b5fc Merge branch 'fix/pdf_ot_albaranes' into 'main'
arreglado albaranes para que muestren las cajas. tambien se ha actualizado...

See merge request jjimenez/safekat!850
2025-06-05 19:27:29 +00:00
49140cea40 arreglado albaranes para que muestren las cajas. tambien se ha actualizado para que cuando se modifiquen las cajas de la linea se modifiquen el total del albarán 2025-06-05 21:25:48 +02:00
6a9331747e solucionado el problema de la impresion de las ots 2025-06-05 18:57:03 +02:00
fb292520a2 Merge branch 'feat/albaran_anonimo' into 'main'
Feat/albaran anonimo

See merge request jjimenez/safekat!849
2025-06-05 09:45:28 +00:00
909228512c Feedback JM 2025-06-05 11:45:00 +02:00
602fb591f9 Añadida funcionalidad de albaran anonimo y corregidos bugs 2025-06-05 11:38:16 +02:00
764d5c8f29 Merge branch 'bug/catalogo_historico' into 'main'
Arreglado precio ud en tabla

See merge request jjimenez/safekat!848
2025-06-05 07:30:24 +00:00
b1cd63f665 Arreglado precio ud en tabla 2025-06-05 09:28:30 +02:00
5058ae488b Merge branch 'mod/historico_catalogo' into 'main'
Mod/historico catalogo

See merge request jjimenez/safekat!847
2025-06-05 06:44:59 +00:00
10889a9e7f Refactorizazion 2025-06-05 08:44:34 +02:00
8d363b8abd Merge branch 'main' into 'mod/historico_catalogo'
Main

See merge request jjimenez/safekat!846
2025-06-04 21:30:11 +00:00
63866b6f2f COrregidos cambios JM 2025-06-04 23:27:31 +02:00
4e65361df8 Merge branch 'fix/error_en_pais_save_direccionecliente_presupuestoadmin' into 'main'
solucionado

See merge request jjimenez/safekat!845
2025-06-04 13:51:48 +00:00
391927aaf6 solucionado 2025-06-04 15:51:21 +02:00
96e12c0192 Merge branch 'feat/catalogo_historico_pedidos' into 'main'
Feat/catalogo historico pedidos

See merge request jjimenez/safekat!844
2025-06-04 13:22:38 +00:00
7f88ea7296 Merge branch 'main' into 'feat/catalogo_historico_pedidos'
Main

See merge request jjimenez/safekat!843
2025-06-04 13:21:11 +00:00
884f9f1a67 Merge branch 'fix/view_all_tickets_cliente' into 'main'
resuelto el problema de que los clientes veian todos los tickets

See merge request jjimenez/safekat!842
2025-06-03 13:17:36 +00:00
c5dc026c33 resuelto el problema de que los clientes veian todos los tickets 2025-06-03 15:17:11 +02:00
5fbb6cc854 Merge branch 'fix/add_presupuesto_tirada_0' into 'main'
arreglada la comprobación de páginas y tirada cuando se añade un presupuesto

See merge request jjimenez/safekat!841
2025-06-03 11:42:52 +00:00
40439b532f arreglada la comprobación de páginas y tirada cuando se añade un presupuesto 2025-06-03 13:41:52 +02:00
84693d5c6c Iniciada implementacion de recuperacion de historicos erp antiguo 2025-06-03 11:24:44 +02:00
2c711c526b Merge branch 'mod/iskn2' into 'main'
Eliminado contexto libro por defecto

See merge request jjimenez/safekat!840
2025-06-02 09:30:59 +00:00
a12f034daa Eliminado contexto libro por defecto 2025-06-02 11:30:36 +02:00
e732b36ece Merge branch 'mod/iskn' into 'main'
Modificaciones en html

See merge request jjimenez/safekat!839
2025-06-02 09:16:29 +00:00
5fcc1bdd9d Modificaciones en html 2025-06-02 11:16:10 +02:00
da57cb23ee Merge branch 'feat/importador_libros_catalogo_antiguo' into 'main'
Feat/importador libros catalogo antiguo

See merge request jjimenez/safekat!838
2025-06-02 09:13:15 +00:00
e1aa62f198 Cambio de isk a iskn, añadido comando generador de iskn en libros del catalogo que no lo tengan 2025-06-02 11:12:45 +02:00
50e8c35ef3 Merge branch 'feat/maquinas-corte-ot' into 'main'
Feat/maquinas corte ot

See merge request jjimenez/safekat!837
2025-05-31 06:38:02 +00:00
f10d584453 Merge branch 'fix/planning-plana-select-maquina-papel' into feat/maquinas-corte-ot 2025-05-31 08:35:50 +02:00
67c4b4bc93 add filter padre - hija - papel 2025-05-31 08:35:01 +02:00
23a577b55e tareas corte y tiempo procesamiento 2025-05-31 07:58:43 +02:00
6ca84232fa Merge branch 'mod/reimpresion_mensaje_duplicado' into 'main'
añadido mensaje cuando es un duplicado

See merge request jjimenez/safekat!836
2025-05-30 15:42:33 +00:00
95e153adbb añadido mensaje cuando es un duplicado 2025-05-30 17:41:55 +02:00
4e8265d8a5 Merge branch 'main' into feat/maquinas-corte-ot 2025-05-30 17:00:31 +02:00
e9986dd3bb Merge branch 'fix/maquina-padre-hijo-select' into 'main'
Fix/maquina padre hijo select

See merge request jjimenez/safekat!835
2025-05-30 14:58:49 +00:00
96bc9cde73 Merge branch 'main' into fix/maquina-padre-hijo-select 2025-05-30 16:57:51 +02:00
b9c18bf78c fix 2025-05-30 16:57:08 +02:00
784789841d Merge branch 'fix/hasFiles_false_reimpresion_3' into 'main'
cambiado reimprimir

See merge request jjimenez/safekat!834
2025-05-30 13:33:46 +00:00
744680198b cambiado reimprimir 2025-05-30 15:33:28 +02:00
f42063dd4c Merge branch 'fix/hasFiles_false_reimpresion_2' into 'main'
Fix/has files false reimpresion 2

See merge request jjimenez/safekat!833
2025-05-30 13:15:43 +00:00
53ce60f6de cuando no tiene ficheros reimprimir directamente 2025-05-30 15:15:28 +02:00
b5128bdcaf cuando no tiene ficheros reimprimir directamente 2025-05-30 15:15:10 +02:00
1350c04060 Merge branch 'fix/hasFiles_false_reimpresion' into 'main'
Fix/has files false reimpresion

See merge request jjimenez/safekat!832
2025-05-30 13:11:46 +00:00
8ab2c28686 cuando no tiene ficheros reimprimir directamente 2025-05-30 15:11:19 +02:00
b7563598e0 cuando no tiene ficheros reimprimir directamente 2025-05-30 15:10:34 +02:00
192525ebae Merge branch 'fix/error_reimpresion' into 'main'
si no se usan los mismos archivos no es reimpresion

See merge request jjimenez/safekat!831
2025-05-30 12:55:49 +00:00
78c4082596 si no se usan los mismos archivos no es reimpresion 2025-05-30 14:55:29 +02:00
e0da3b56c7 Merge branch 'feat/boton_reimprimir' into 'main'
terminada funcionalidad reimpresion presupuestos

See merge request jjimenez/safekat!830
2025-05-30 12:53:08 +00:00
be16690f73 terminada funcionalidad reimpresion presupuestos 2025-05-30 14:52:48 +02:00
aaf2ee6fd3 Implementando comando 2025-05-30 14:34:48 +02:00
81393317b7 Merge branch 'fix/planning-plana' into 'main'
Fix/planning plana

See merge request jjimenez/safekat!829
2025-05-30 09:47:33 +00:00
2f1b34f668 Merge branch 'main' into fix/planning-plana 2025-05-30 11:46:56 +02:00
52c53e6920 feat: add filter maquina plana 2025-05-30 11:45:48 +02:00
3b43551064 Merge branch 'mod/calculo_merma' into 'main'
cuando la tirada es 1 la merma es 0

See merge request jjimenez/safekat!828
2025-05-30 09:32:16 +00:00
e5389db7be cuando la tirada es 1 la merma es 0 2025-05-30 11:31:53 +02:00
3db124ea24 add maquinas default corte 2025-05-30 07:31:18 +02:00
cd0a1c3c2a Merge branch 'fix/uri_duplicar_maquinas' into 'main'
cambio realizado. también se arregla que se pueda dejar null el alias_ot

See merge request jjimenez/safekat!827
2025-05-27 10:17:56 +00:00
97568151a6 cambio realizado. también se arregla que se pueda dejar null el alias_ot 2025-05-27 12:17:36 +02:00
a6fc99e726 Merge branch 'fix/migrate_albaranes' into 'main'
solucionado el nombre de la clase

See merge request jjimenez/safekat!826
2025-05-27 09:08:49 +00:00
a86bdcac53 solucionado el nombre de la clase 2025-05-27 11:08:25 +02:00
303fde9861 Merge branch 'mod/logistica_v2' into 'main'
Mod/logistica v2

See merge request jjimenez/safekat!825
2025-05-26 19:10:11 +00:00
0cd68f369e añadida la migración de las lineas de albaran 2025-05-26 21:09:44 +02:00
6dc91bfa4c terminada la modificacion de las lineas de albaran 2025-05-26 21:09:24 +02:00
43e0ced1bd añadido mensaje en comentarios logistica para tirada flexible 2025-05-26 20:23:15 +02:00
981eb30c02 Merge branch 'mod/permisos' into 'main'
Añadidos permisos para logistica e importadores

See merge request jjimenez/safekat!824
2025-05-23 13:30:45 +00:00
e070e5101e Añadidos permisos para logistica e importadores 2025-05-23 14:45:13 +02:00
55ac2b4bcb Merge branch 'mod/download_file' into 'main'
Añadida funcionalidad de descarga por archivo

See merge request jjimenez/safekat!823
2025-05-23 11:39:18 +00:00
4da8981cd8 Añadida funcionalidad de descarga por archivo 2025-05-23 13:38:13 +02:00
e625dd1e76 Merge branch 'feat/download_zip' into 'main'
Implementada funcionalidad descarga en zip

See merge request jjimenez/safekat!822
2025-05-22 20:10:26 +00:00
e3c202ae64 Implementada funcionalidad descarga en zip 2025-05-22 22:10:14 +02:00
b084d1bd7c Merge branch 'feat/update-ot-flow' into 'main'
Feat/update ot flow

See merge request jjimenez/safekat!821
2025-05-22 16:41:34 +00:00
611df53de1 Merge branch 'main' into feat/update-ot-flow 2025-05-22 18:34:08 +02:00
aba97202cc Merge branch 'main' of https://git.imnavajas.es/jjimenez/safekat 2025-05-22 18:33:44 +02:00
b775f65b3a fix title size 2025-05-22 18:32:48 +02:00
690eaf4195 update flow tareas orden trabajo con tareas de corte final y tras impresión 2025-05-22 17:47:35 +02:00
1e47b58400 Merge branch 'mod/importar_presup_borrador' into 'main'
cambio realizado

See merge request jjimenez/safekat!820
2025-05-22 11:56:50 +00:00
dd530b8b89 cambio realizado 2025-05-22 13:56:20 +02:00
e33e5e0840 Merge branch 'mod/mensajes_confirmacion_envios' into 'main'
añadido mensajeria

See merge request jjimenez/safekat!819
2025-05-21 19:25:39 +00:00
2faa88297e añadido mensajeria 2025-05-21 21:25:02 +02:00
306ae02a10 Merge branch 'mod/nombre_impresoras' into 'main'
Añadida descripcion en el select de las impresoras

See merge request jjimenez/safekat!818
2025-05-21 07:05:13 +00:00
242029714d Añadida descripcion en el select de las impresoras 2025-05-21 09:04:50 +02:00
edbca8fc6e Merge branch 'feat/bubok_files' into 'main'
Implementada funcionalidad

See merge request jjimenez/safekat!817
2025-05-21 06:24:11 +00:00
cb17d661a8 Implementada funcionalidad 2025-05-20 14:31:17 +02:00
5f76e0e437 add chat direct 2025-05-20 00:01:26 +02:00
976c7980d4 activate ot download 2025-05-19 23:05:02 +02:00
42edf2bbc0 add alias_ot to maquina code header in pdf and seeder to update alias in lg_maquinas 2025-05-19 21:13:21 +02:00
64337257ee add alias_ot field to lg_maquinas 2025-05-19 20:57:40 +02:00
2ef98a9496 fix pdf font sizes and updated info 2025-05-19 20:47:19 +02:00
b500229b37 Merge branch 'mod/logistica' into 'main'
Mod/logistica

See merge request jjimenez/safekat!815
2025-05-19 16:43:04 +00:00
438000ebad hecho lo de proximos envios 2025-05-19 18:41:48 +02:00
decdcf3703 trabajando en la lista de envios proximos 2025-05-15 23:55:09 +02:00
f5a015bc6d Merge branch 'fix/username' into 'main'
Fixed campo secret para obtener el email

See merge request jjimenez/safekat!814
2025-05-15 17:39:19 +00:00
359e13260f Fixed campo secret para obtener el email 2025-05-15 18:02:32 +02:00
cfdc8d64e1 Merge branch 'mod/ref_cliente_buscador' into 'main'
Cambiado pais por referencia cliente en el buscador de presupuestos

See merge request jjimenez/safekat!813
2025-05-14 18:38:55 +00:00
22bdb9b960 Cambiado pais por referencia cliente en el buscador de presupuestos 2025-05-14 20:38:39 +02:00
1991691533 Merge branch 'fix/faja_always_on' into 'main'
Fix/faja always on

See merge request jjimenez/safekat!812
2025-05-14 12:04:16 +00:00
760b9bdd94 arreglado también problema de sobrecubierta en importador rama 2025-05-14 13:57:33 +02:00
ce124cb38a resuelto 2025-05-14 13:49:08 +02:00
778ef712e9 Merge branch 'mod/facturas_rectificativas_conformar' into 'main'
terminado

See merge request jjimenez/safekat!811
2025-05-13 18:19:12 +00:00
bc7929f44b terminado 2025-05-13 20:18:44 +02:00
438e696e88 Merge branch 'feat/link_facturas' into 'main'
Añadidos enlaces a facturas rectificativas/rectificadas

See merge request jjimenez/safekat!810
2025-05-13 13:40:27 +00:00
199e5f2018 Añadidos enlaces a facturas rectificativas/rectificadas 2025-05-13 15:40:04 +02:00
cb15fbe94a Merge branch 'fix/importador_bubok' into 'main'
Fix/importador bubok

See merge request jjimenez/safekat!809
2025-05-13 11:29:53 +00:00
fa77952ea6 Corregidos bugs y homegeneizado 2025-05-13 13:28:54 +02:00
88d6b69857 Merge branch 'main' into fix/importador_bubok 2025-05-13 09:05:32 +02:00
7ffaec042c Merge branch 'import/usuarios_sk' into 'main'
Subido script para comprobar identidades

See merge request jjimenez/safekat!808
2025-05-13 06:44:35 +00:00
6ba2694733 Subido script para comprobar identidades 2025-05-12 22:36:07 +02:00
15ce7ed670 Merge branch 'fix/listado_facturas_pedidos' into 'main'
arreglado

See merge request jjimenez/safekat!807
2025-05-12 19:33:21 +00:00
565ef7f170 arreglado 2025-05-12 21:32:59 +02:00
f3c92fa205 Merge branch 'fix/facturas' into 'main'
arreglado el tema de las facturas rectificadas/rectificativas

See merge request jjimenez/safekat!806
2025-05-12 17:19:42 +00:00
6ee4b1e89d arreglado el tema de las facturas rectificadas/rectificativas 2025-05-12 19:19:12 +02:00
d253183ab6 Merge branch 'fix/rama_loader' into 'main'
Implementados cambios del loader

See merge request jjimenez/safekat!805
2025-05-12 13:16:50 +00:00
3e6ba658cd Implementados cambios del loader 2025-05-12 15:16:28 +02:00
de536b894d Merge branch 'feat/add-datatable-ot-header-filters' into 'main'
Feat/add datatable ot header filters

See merge request jjimenez/safekat!804
2025-05-10 07:32:40 +00:00
836ace0e42 add check preimpresion when imported from Bubok or Catalogo 2025-05-10 09:27:40 +02:00
bbea2229d7 remove preimpresion check default when create an ot 2025-05-10 09:25:32 +02:00
90a47aa6bb add datatable ot filters 2025-05-10 09:23:59 +02:00
59609df471 Añadidas modificaciones para PDF y bug detectado 2025-05-09 13:54:41 +02:00
43ae427137 Merge branch 'fix/importador_rama_tarifa' into 'main'
Fix/importador rama tarifa

See merge request jjimenez/safekat!803
2025-05-09 10:32:48 +00:00
36a2740eb7 Añadido selector de calidad 2025-05-09 12:32:07 +02:00
0a9d1ef68d Redondeo de precio tarifa a 2 decimales 2025-05-08 22:10:01 +02:00
a9d9dbab5c Merge branch 'fix/importador_rama_tarifa' of https://git.imnavajas.es/jjimenez/safekat into fix/importador_rama_tarifa 2025-05-08 22:07:46 +02:00
79dc8ca713 Añadida tarifa hardcoded 2025-05-08 22:07:26 +02:00
f7d08b9c79 Merge branch 'mod/selector_calidad' into 'main'
añadido cambio de calidad en importador erp antiguo. falta añadirlo a rama y bubok

See merge request jjimenez/safekat!802
2025-05-08 18:17:26 +00:00
f4ef874568 añadido cambio de calidad en importador erp antiguo. falta añadirlo a rama y bubok 2025-05-08 20:16:40 +02:00
6537e16a0a Merge branch 'fix/calculo_merma_sin_formas' into 'main'
corregido

See merge request jjimenez/safekat!801
2025-05-08 11:19:25 +00:00
5d228cc10c corregido 2025-05-08 13:18:33 +02:00
ed9f67badd Merge branch 'feat/scripts_varios' into 'main'
Creados scripts

See merge request jjimenez/safekat!800
2025-05-07 09:52:18 +00:00
ff7ed8f594 Creados scripts 2025-05-07 11:51:52 +02:00
ec4d00e0ab Merge branch 'fix/pod_en_plana' into 'main'
terminado

See merge request jjimenez/safekat!799
2025-05-06 14:19:32 +00:00
85318aa10e terminado 2025-05-06 16:18:32 +02:00
a4782358c6 Merge branch 'fix/asunto_tickets' into 'main'
terminado

See merge request jjimenez/safekat!798
2025-05-06 14:05:18 +00:00
528f117c7c terminado 2025-05-06 16:04:25 +02:00
6775646ec3 Merge branch 'fix/ruta_paises_esta_en_configuracion' into 'main'
arraglado

See merge request jjimenez/safekat!797
2025-05-06 12:21:58 +00:00
efef0c0199 arraglado 2025-05-06 14:20:25 +02:00
5057586987 Merge branch 'fix/resumen_no_envio_base' into 'main'
cuando se añade más de una direccion y tiene el cliente marcado que no tenga...

See merge request jjimenez/safekat!794
2025-05-06 12:00:33 +00:00
15227998aa cuando se añade más de una direccion y tiene el cliente marcado que no tenga envio base, se suman las dos direcciones al presupuesto 2025-05-06 14:00:03 +02:00
456dc7ff18 Merge branch 'add/margen_precio_min' into 'main'
Add/margen precio min

See merge request jjimenez/safekat!793
2025-05-06 11:21:26 +00:00
89bcd0bda1 resuelto 2025-05-06 13:20:48 +02:00
1a1f5947a0 arreglado 2025-05-06 13:11:31 +02:00
999553f767 Merge branch 'fix/importe_minimo_es_coste' into 'main'
puesto como precio minimo el coste

See merge request jjimenez/safekat!792
2025-05-06 11:07:10 +00:00
89e6d0787a puesto como precio minimo el coste 2025-05-06 13:06:48 +02:00
cbe8ee0f5c Merge branch 'mod/importe_fijo_margen' into 'main'
Mod/importe fijo margen

See merge request jjimenez/safekat!791
2025-05-06 10:50:37 +00:00
51d0a1bcfe Merge branch 'main' into mod/importe_fijo_margen 2025-05-06 12:28:58 +02:00
eeba76b124 arreglado servicios de encuadernacion 2025-05-06 12:28:03 +02:00
33a3ccb832 Merge branch 'fix/comercial_id' into 'main'
Expuestos campos ID y PrecioTonelada en visualizacion de papeles de impresion

See merge request jjimenez/safekat!790
2025-05-06 10:23:14 +00:00
d3dd18a156 Expuestos campos ID y PrecioTonelada en visualizacion de papeles de impresion 2025-05-06 12:23:00 +02:00
cab7bc3daf Arreglado bug en listado de comerciales en vista diferente al buscador de presupuestos 2025-05-06 12:09:54 +02:00
804d8ba28b Merge branch 'fix/comercial_id' into 'main'
Arreglado bug en listado de comerciales en vista diferente al buscador de presupuestos

See merge request jjimenez/safekat!789
2025-05-06 10:09:52 +00:00
7101c8934e Merge branch 'fix/user_id_presupuestos_2' into 'main'
Al crear un presupuesto hay que fijar el user_update_id. FIXED

See merge request jjimenez/safekat!788
2025-05-06 08:55:21 +00:00
20594bd44c Al crear un presupuesto hay que fijar el user_update_id. FIXED 2025-05-06 10:55:21 +02:00
c2011e1c25 Merge branch 'fix/user_id_presupuestos' into 'main'
Añadidos IDs de los usuarios creador y actualizador al guardar desde presupuesto cliente

See merge request jjimenez/safekat!787
2025-05-06 08:17:37 +00:00
8b340b76d3 Añadidos IDs de los usuarios creador y actualizador al guardar desde presupuesto cliente 2025-05-06 10:17:33 +02:00
5ae2827623 Merge branch 'fix/ot-progress' into 'main'
Fix/ot progress

See merge request jjimenez/safekat!786
2025-05-06 08:07:57 +00:00
f6b8d2ba85 columns searching and ordering ots 2025-05-06 10:06:33 +02:00
ddd7c471a1 progress ot 2025-05-06 08:40:07 +02:00
30c5b06d3d update progress based on task time and task date 2025-05-06 08:30:01 +02:00
aac8ab24be Merge branch 'feat/ot-pdf-zip' into 'main'
Feat/ot pdf zip

See merge request jjimenez/safekat!785
2025-05-05 19:01:26 +00:00
99ffe1f462 Merge branch 'main' into feat/ot-pdf-zip 2025-05-05 21:00:33 +02:00
caac71a48d zip pdf download 2025-05-05 20:59:57 +02:00
478077721b Merge branch 'fix/varios' into 'main'
Fix/varios

See merge request jjimenez/safekat!784
2025-05-05 18:14:05 +00:00
10b5ae911a Añadidas mejoras propuestas por Manolo a la importacion de RAMA 2025-05-05 20:13:59 +02:00
43fef3a1a0 Merge branch 'fix/impresion_titulos' into 'main'
Fix/impresion titulos

See merge request jjimenez/safekat!783
2025-05-05 17:45:32 +00:00
c6fb4b3213 terminado 2025-05-05 19:42:45 +02:00
247fa7e6f9 prueba2 2025-05-05 19:36:33 +02:00
21e907ad50 prueba 2025-05-05 19:27:17 +02:00
bf146d4024 Revision de la entidad de catalogo libros 2025-05-05 18:53:44 +02:00
68a39bd749 Merge branch 'mod/servicios' into 'main'
terminado

See merge request jjimenez/safekat!782
2025-05-05 16:52:39 +00:00
514905ff47 terminado 2025-05-05 18:52:16 +02:00
75f06c44a1 Añadida opcion 'uso' en las queries de catalogo 2025-05-05 18:38:30 +02:00
4120ded07b Renombrado importador desde catalogo a RA-MA 2025-05-05 17:37:07 +02:00
24fc4ff1c1 Merge branch 'fix/pod_nohq_negro_enviobase' into 'main'
ahora el pod puede ser negro estandar. Para presupuestos no importados, si...

See merge request jjimenez/safekat!781
2025-05-05 15:35:59 +00:00
899365f2c2 Puesto en grupo beta opcion Catalogo -> Importar 2025-05-05 17:35:22 +02:00
302d12da1e ahora el pod puede ser negro estandar. Para presupuestos no importados, si no_envio_base no se añade 2025-05-05 17:34:51 +02:00
659d1d17ea Merge branch 'fix/remove_button_imposiciones' into 'main'
quitado el boton en las nuevas

See merge request jjimenez/safekat!779
2025-05-05 14:32:15 +00:00
ff5d853032 quitado el boton en las nuevas 2025-05-05 16:31:55 +02:00
ba6f92b3e6 Merge branch 'mod/ordenar_menus' into 'main'
Modificaciones

See merge request jjimenez/safekat!778
2025-05-05 14:31:12 +00:00
1ebc22c74b Modificaciones 2025-05-05 16:30:11 +02:00
785b9ea693 Merge branch 'mod/etiquetas_embalaje' into 'main'
cambiado el campo cajas

See merge request jjimenez/safekat!777
2025-05-05 14:23:49 +00:00
d2c6d131b3 cambiado el campo cajas 2025-05-05 16:23:12 +02:00
df1f003cbd Merge branch 'fix/imposicion-form' into 'main'
Fix/imposicion form

See merge request jjimenez/safekat!776
2025-05-05 12:33:36 +00:00
3936e3175a Merge branch 'main' into fix/imposicion-form 2025-05-05 14:32:55 +02:00
571338c4b3 fix imposicion form 2025-05-05 14:31:59 +02:00
5e5cff9eae Merge branch 'add/print_labels_maquinista' into 'main'
terminado

See merge request jjimenez/safekat!775
2025-05-05 11:14:14 +00:00
1d75f825a4 terminado 2025-05-05 13:13:44 +02:00
95e10820a3 Merge branch 'feat/menu_active' into 'main'
Añadida funcionalidad de marcar el menu que esta activo

See merge request jjimenez/safekat!774
2025-05-05 09:23:49 +00:00
b41dc836c7 Merge branch 'fix/btn-cancel-fa' into 'main'
fix btn cancel fa

See merge request jjimenez/safekat!773
2025-05-05 09:23:34 +00:00
4afcf05049 Añadida funcionalidad de marcar el menu que esta activo 2025-05-05 11:23:34 +02:00
0ecd18f5ff fix btn cancel fa 2025-05-05 11:22:41 +02:00
ff648fec87 Merge branch 'fix/respuesta_tickets' into 'main'
resuelto

See merge request jjimenez/safekat!772
2025-05-05 08:57:46 +00:00
b5c1053f8c resuelto 2025-05-05 10:57:21 +02:00
4701329d25 Merge branch 'fix/tickets_list' into 'main'
corregidos problemas

See merge request jjimenez/safekat!771
2025-05-05 08:32:40 +00:00
7a119eb197 corregidos problemas 2025-05-05 10:32:09 +02:00
3f8b7981c7 Merge branch 'fix/add_merma_servicios_2' into 'main'
arreglado

See merge request jjimenez/safekat!770
2025-05-05 07:56:13 +00:00
fa6e9208a1 arreglado 2025-05-05 09:55:48 +02:00
1f1bd32fa4 Merge branch 'mod/smtp_produccion' into 'main'
Modificados parametros SMTP de SK para produccion

See merge request jjimenez/safekat!769
2025-05-05 07:44:28 +00:00
8100350e3b Modificados parametros SMTP de SK para produccion 2025-05-05 09:44:04 +02:00
2af2dcdbb8 Merge branch 'feat/lg_maquinas_etiqueta_pedido' into 'main'
Feat/lg maquinas etiqueta pedido

See merge request jjimenez/safekat!768
2025-05-05 06:29:00 +00:00
1c581db4cf add etiqueta envio maquina model and show in tarea card 2025-05-05 08:27:01 +02:00
b4dfdfa101 add ot_id in ots datatables 2025-05-05 08:07:17 +02:00
8cbe5a7051 fix papel ot color 2025-05-05 08:04:46 +02:00
46176adc70 fix show form cosido in ot task 2025-05-05 07:53:36 +02:00
67bac8f666 Merge branch 'add/impresion_etiquetas_footer' into 'main'
terminado

See merge request jjimenez/safekat!767
2025-05-05 05:43:11 +00:00
ba3f4ab43c terminado 2025-05-05 07:42:27 +02:00
058857e51b Merge branch 'feat/revision-ot-2' into 'main'
Feat/revision ot 2

See merge request jjimenez/safekat!766
2025-05-04 22:48:57 +00:00
5ce6859a2f Merge branch 'main' into feat/revision-ot-2 2025-05-05 00:48:01 +02:00
2bfdd89085 Merge branch 'main' of https://git.imnavajas.es/jjimenez/safekat 2025-05-05 00:47:51 +02:00
305eea00e6 fichaje automatico y escaneo 2025-05-05 00:47:00 +02:00
8ea6128109 Merge branch 'add/interfaz_impresion_etiquetas' into 'main'
Add/interfaz impresion etiquetas

See merge request jjimenez/safekat!765
2025-05-04 16:37:34 +00:00
7b645539e3 terminado 2025-05-04 18:35:08 +02:00
fb7f2a28d9 revision ot v2 2025-05-04 17:25:53 +02:00
39639d9ff8 falta ordenar por cajas 2025-05-04 13:05:37 +02:00
3f90665c39 trabajando en la tabla de las lineas 2025-05-03 18:27:52 +02:00
71e70bf551 terminando a falta del listado añadir etiquetas 2025-05-03 12:06:25 +02:00
db70c57fb3 Merge branch 'main' into feat/preimpresion-revisada-check 2025-05-02 21:03:49 +02:00
91b044bbae Merge branch 'main' of https://git.imnavajas.es/jjimenez/safekat 2025-05-02 21:03:33 +02:00
a88ffda50d add revision preimpresion ot 2025-05-02 21:02:53 +02:00
d7a85ca04f Primeros pasos sistema backup 2025-05-02 14:10:49 +02:00
746955c3b1 Merge branch 'feat/prod_dev_environment' into 'main'
Feat/prod dev environment

See merge request jjimenez/safekat!764
2025-05-02 10:56:25 +00:00
8ca0a40b2b Añadida gestion de correos de pruebas en produccion 2025-05-02 11:54:11 +02:00
20c009f445 Añadida distincion visual para entorno de desarrollo 2025-05-02 11:29:19 +02:00
5138681718 feat/ot-datatable-news 2025-05-02 07:56:28 +02:00
9283059f9d Merge branch 'fix/entrega_taller_bubok' into 'main'
corregido

See merge request jjimenez/safekat!763
2025-05-01 07:08:36 +00:00
b75278f449 corregido 2025-05-01 09:08:14 +02:00
3fb944ff97 Merge branch 'mod/importador_bubok' into 'main'
añadido ajuste de precio, url en comentarios y crear pedido y ot

See merge request jjimenez/safekat!762
2025-05-01 06:59:59 +00:00
c7250cb8fd añadido ajuste de precio, url en comentarios y crear pedido y ot 2025-05-01 08:59:34 +02:00
7a9b2af8a6 Merge branch 'feat/ot-new-features' into 'main'
Features:

See merge request jjimenez/safekat!761
2025-05-01 04:16:42 +00:00
cf5a42de8d Merge branch 'main' into feat/ot-new-features 2025-05-01 06:15:26 +02:00
a259d76e5e ot new features 2025-05-01 06:02:22 +02:00
f696153d74 Merge branch 'fix/pliegos_presupuesto' into 'main'
terminado

See merge request jjimenez/safekat!760
2025-04-30 18:24:13 +00:00
9181905233 terminado 2025-04-30 20:23:45 +02:00
0ec7dff479 Merge branch 'feat/importador_bubok' into 'main'
Primera version del importador de Bubok

See merge request jjimenez/safekat!759
2025-04-30 13:39:21 +00:00
b0fb0f18fb Primera version del importador de Bubok 2025-04-30 15:36:33 +02:00
cf4c4df80a Features:
- Prototipo PDF
 - Ferro PDF
 - Ferro OK fecha cambiado a Ferro/Prototipo OK
 - Comentarios para orden,impresion,cubierta,encuadernacion y logistica
 - Migración para comentarios
 - Tarifas acabado migraciones con campos para identificar mejor si es plastificado,plakene,retractilado y el tipo de cada uno
2025-04-30 09:23:37 +02:00
36c9227586 fix pdf tables encuadernacion. Add tarifa acabado configuration for ots 2025-04-30 01:25:24 +02:00
4e9dfb51c7 Merge branch 'fix/descuento_con_ajuste' into 'main'
arreglado

See merge request jjimenez/safekat!757
2025-04-29 18:03:58 +00:00
5aab9a33ac arreglado 2025-04-29 20:03:02 +02:00
ea762a09c0 Merge branch 'fix/confirmar_presupuesto_ajustado' into 'main'
corregido

See merge request jjimenez/safekat!756
2025-04-29 17:56:28 +00:00
21014d029f corregido 2025-04-29 19:56:08 +02:00
9c31f2bbc5 Merge branch 'add/configuracion_cliente_cambios_importador_catalogo' into 'main'
terminado

See merge request jjimenez/safekat!755
2025-04-29 17:33:59 +00:00
b288ca498c terminado 2025-04-29 19:30:35 +02:00
96a6845c0c Merge branch 'feat/importador_rama_2' into 'main'
Feat/importador rama 2

See merge request jjimenez/safekat!754
2025-04-29 15:10:55 +00:00
eed5c0994e Importador rama con ajuste del precio 2025-04-29 17:09:19 +02:00
e2ab42cd84 Arreglado bug impresora de tickets (logistica) 2025-04-29 17:01:16 +02:00
7da76af866 Primera version del importador RAMA 2025-04-29 15:42:50 +02:00
bf1e66d746 Corregido bug en API imprimelibros 2025-04-29 12:40:35 +02:00
adccc414be Merge branch 'fix/bugs-ot' into 'main'
Fix/bugs ot

See merge request jjimenez/safekat!752
2025-04-28 06:13:50 +00:00
95fa192cb9 remove ? from orden_trabajo pdf 2025-04-28 08:12:22 +02:00
9310d2dabd delete class text-center from div.card otTask 2025-04-28 08:06:44 +02:00
3abf45ca6e tiempo real tarea empty when created 2025-04-28 08:00:39 +02:00
6ea22066c2 Merge branch 'feat/festivos-calendar' into 'main'
Feat/festivos calendar

See merge request jjimenez/safekat!751
2025-04-28 00:11:16 +00:00
bf21a336b1 Merge branch 'main' into feat/festivos-calendar 2025-04-28 02:10:52 +02:00
d1e5731d1d create POD dates pedido 2025-04-28 02:03:40 +02:00
029757bb40 add calendar festivos 2025-04-28 00:42:15 +02:00
bb4c9690b9 Merge branch 'feat/importador_rama' into 'main'
Feat/importador rama

See merge request jjimenez/safekat!750
2025-04-27 20:01:26 +00:00
6d45a950df Trabajando JS 2025-04-27 22:00:52 +02:00
6f8890a8b1 Merge branch 'main' into 'feat/importador_rama'
Main

See merge request jjimenez/safekat!749
2025-04-27 18:56:08 +00:00
c093c01c00 Merge branch 'main' into feat/festivos-calendar 2025-04-27 19:30:31 +02:00
a4532a7ff6 Merge branch 'fix/filter-datatable-ot' into 'main'
Fix/filter datatable ot

See merge request jjimenez/safekat!748
2025-04-27 17:27:30 +00:00
31a12ff343 try catch getTiempoProcesamientoHHMM 2025-04-27 19:26:02 +02:00
1d6f5fe53e default table encuadernacion 2025-04-27 19:24:11 +02:00
0b767c63e9 fix filter ferro 2025-04-27 19:13:06 +02:00
e464652fe2 festivo entity model 2025-04-27 19:01:23 +02:00
dd20f2a20e Merge branch 'maquinista-change-user' into 'main'
Maquinista change user

See merge request jjimenez/safekat!747
2025-04-27 16:54:35 +00:00
97554bffc9 add maquinista change user session 2025-04-27 18:53:24 +02:00
73e9e941ed Merge branch 'main' into maquinista-change-user 2025-04-27 12:25:09 +02:00
05720cf1ce Merge branch 'fix/migrate' into 'main'
fix migrate class name

See merge request jjimenez/safekat!746
2025-04-27 10:20:33 +00:00
04e9e3ee6f fix migrate class name 2025-04-27 12:18:20 +02:00
9804a6a927 change user session 2025-04-27 12:17:31 +02:00
3402e67fb2 Merge branch 'add/envio_ferros' into 'main'
Add/envio ferros

See merge request jjimenez/safekat!745
2025-04-27 10:14:05 +00:00
b1932e6f85 terminado envio de ferros 2025-04-27 12:12:52 +02:00
13ae70236e Merge branch 'feat/sk-44' into 'main'
Feat/sk 44

See merge request jjimenez/safekat!744
2025-04-27 09:00:23 +00:00
a0b5f3b4df trabajando en envio de ferros 2025-04-27 09:51:52 +02:00
0e444295e3 trabajando en el formulario envio de ferros 2025-04-27 09:51:04 +02:00
ae7707057a Cambiando titulo pagina 2025-04-27 09:17:46 +02:00
ff115f4f20 Configurando logica de captacion del Excel 2025-04-27 09:16:15 +02:00
ae456c8890 Implementado script principal 2025-04-27 00:00:58 +02:00
e8958dc893 Implementado menu lateral 2025-04-26 23:23:04 +02:00
b0ac132e59 Arreglado bug en archivo de migrate del catalogo 2025-04-26 23:05:15 +02:00
b50e564641 Desplegando arcihvos iniciales 2025-04-26 21:32:22 +02:00
894770d6ce Merge branch 'feat/importador_rama' of https://git.imnavajas.es/jjimenez/safekat into feat/importador_rama 2025-04-26 21:25:18 +02:00
367c7c2ea8 Merge branch 'main' into 'feat/importador_rama'
Main

See merge request jjimenez/safekat!743
2025-04-26 19:24:58 +00:00
9375b9b624 Añadiendo idiomas 2025-04-26 21:22:39 +02:00
033184cfa2 Iniciando herramienta de importacion desde catalogo 2025-04-26 16:52:59 +02:00
585 changed files with 59129 additions and 7915 deletions

7
.vscode/sftp.json vendored
View File

@ -24,10 +24,15 @@
"username": "sk-dev",
"password": "KXvYsubai9v*g61~"
},
"prod":{
"sk-prod":{
"host": "erp.safekat.es",
"username": "erp-demo",
"password": "lNkEyukTc1~*3yy9"
},
"sk-dev":{
"host": "erp-dev.safekat.es",
"username": "erp-dev",
"password": "snqyxNZIhg8m3!9~"
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Commands;
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use Config\Database;
use App\Models\Catalogo\IdentificadorIsknModel;
class CatalogoLibroAsignarIskn extends BaseCommand
{
protected $group = 'Safekat';
protected $name = 'catalogo:libro-asignar-iskn';
protected $description = 'Asigna ISKN directamente en la base de datos a los libros que no lo tienen.';
public function run(array $params)
{
$db = Database::connect();
$modelISKN = new IdentificadorIsknModel();
// Obtener todos los libros sin ISKN
$libros = $db->table('catalogo_libros')
->select('id')
->where('iskn IS NULL')
->where('deleted_at IS NULL')
->get()
->getResultArray();
if (empty($libros)) {
CLI::write('No hay libros sin ISKN por asignar.', 'green');
return;
}
CLI::write('Asignando ISKN a ' . count($libros) . ' libros...', 'yellow');
$i = 1;
foreach ($libros as $libro) {
$iskn = $modelISKN->newIskn();
if ($iskn !== null) {
$db->table('catalogo_libros')
->where('id', $libro['id'])
->update(['iskn' => $iskn]);
CLI::write("[{$i}] ISKN '{$iskn}' asignado a libro ID {$libro['id']}", 'cyan');
} else {
CLI::error("[{$i}] No se pudo generar ISKN para libro ID {$libro['id']}");
}
$i++;
}
CLI::write('Proceso finalizado.', 'green');
}
}

View File

@ -0,0 +1,204 @@
<?php
namespace App\Commands;
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
class CatalogoLibroImportar extends BaseCommand
{
protected $group = 'Safekat';
protected $name = 'catalogo:libro-importar';
protected $description = 'Importa los registros de catalogo_libro a catalogo_libros para un customer_id dado';
public function run(array $params)
{
$db = \Config\Database::connect();
$totalImportados = 0;
// Al inicio del método run()
$papeles = $db->table('lg_papel_generico')
->select('id, code')
->where('is_deleted', 0)
->get()
->getResultArray();
// Mapa code => id
$papelMap = [];
foreach ($papeles as $p) {
if (!empty($p['code'])) {
$papelMap[trim($p['code'])] = $p['id'];
}
}
// Mapa de acabados => id
$acabadosMap = [
'plastificado_brillo' => 1,
'plastificado_mate' => 5,
];
// Mapa de encuadernaciones => id
$encuadernacionMap = [
'RCHV' => 4, // cosido tapa blanda
'RCHVS' => 20, // cosido tapa blanda solapas
'RDF' => 1, // fresado tapa dura
'RF' => 2, // fresado tapa blanda
'RFS' => 2, // fresado tapa blanda solapas
'TDC' => 3, // cosido tapa dura
];
if (empty($params[0]) || !is_numeric($params[0])) {
CLI::error('Debes proporcionar un customer_id válido como parámetro.');
return;
}
$customerId = (int) $params[0];
CLI::write("Iniciando importación para customer_id = $customerId ...", 'yellow');
$libros = $db->table('catalogo_libro_antiguo_erp')
->where('customer_id', $customerId)
->where('deleted_at', null)
->get()
->getResultArray();
if (empty($libros)) {
CLI::write('No se encontraron registros para importar.', 'red');
return;
}
foreach ($libros as $libro) {
$nuevoLibro = [
'id' => $libro['id'],
'cliente_id' => $libro['customer_id'],
'proveedor_id' => null,
'user_created_id' => 1,
'user_update_id' => 1,
'cubierta_archivo' => $libro['cover_file'],
'cubierta_url' => $libro['cover_url'],
'ancho' => $libro['ancho'],
'alto' => $libro['alto'],
'peso' => $libro['peso'],
'titulo' => $libro['titulo'],
'autor' => $libro['autor'] ?? null,
'autor_entidad' => $libro['autor_entidad'],
'traductor' => $libro['traductor'],
'ilustrador' => $libro['ilustrador'],
'idioma' => $libro['idioma'],
'num_edic' => $libro['num_edic'],
'fecha_disponibilidad' => $libro['fecha_disponibilidad'],
'fecha_public' => $libro['fecha_public'],
'num_fotos' => $libro['num_fotos'],
'num_ilustr' => $libro['num_ilustr'],
'num_ilustr_color' => $libro['num_ilustr_color'],
'num_ilustr_bn' => $libro['num_ilustr_bn'],
'coleccion' => $libro['coleccion'] ?? null,
'isbn' => $libro['isbn'],
'ean' => $this->generarEAN($libro['isbn']),
'editorial' => $libro['editorial'],
'resumen' => $libro['resumen'],
'resumen_breve' => $libro['resumen_breve'],
'sello' => $libro['sello'],
'paginas' => $libro['paginas'],
'tipo_impresion' => $this->mapTipoImpresion($libro['tipo_impresion']),
'comentarios' => $libro['comentarios'],
'negro_paginas' => $libro['negro_paginas'],
'negro_papel_id' => $this->getPapelId($libro['negro_papel'], $papelMap),
'negro_gramaje' => $libro['negro_gramaje'],
'negro_pod_papel_id' => $this->getPapelId($libro['negro_papel'], $papelMap),
'negro_pod_gramaje' => $libro['negro_gramaje'],
'color_paginas' => $libro['color_paginas'],
'color_papel_id' => $this->getPapelId($libro['color_papel'], $papelMap),
'color_gramaje' => $libro['color_gramaje'],
'color_pod_papel_id' => $this->getPapelId($libro['color_papel'], $papelMap),
'color_pod_gramaje' => $libro['color_gramaje'],
'cubierta_paginas' => $libro['portada_paginas'],
'cubierta_papel_id' => $this->getPapelId($libro['portada_papel'], $papelMap),
'cubierta_gramaje' => $libro['portada_gramaje'],
'cubierta_pod_papel_id' => $this->getPapelId($libro['portada_papel'], $papelMap),
'cubierta_pod_gramaje' => $libro['portada_gramaje'],
'cubierta_acabado_id' => $this->getAcabadoId($libro['portada_acabado'], $acabadosMap),
'cubierta_ancho_solapas' => $libro['solapas_ancho'],
'sobrecubierta_paginas' => $libro['cubierta_paginas'],
'sobrecubierta_papel_id' => $this->getPapelId($libro['cubierta_papel'], $papelMap),
'sobrecubierta_gramaje' => $libro['cubierta_gramaje'],
'sobrecubierta_pod_papel_id' => $this->getPapelId($libro['cubierta_papel'], $papelMap),
'sobrecubierta_pod_gramaje' => $libro['cubierta_gramaje'],
'sobrecubierta_acabado_id' => $this->getAcabadoId($libro['cubierta_acabado'], $acabadosMap),
'sobrecubierta_ancho_solapas' => 0,
'encuadernacion_id' => $this->getEncuadernacionId($libro['encuardenacion'], $encuadernacionMap),
'ubicacion' => $libro['ubicacion'],
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'deleted_at' => $libro['deleted_at'],
'iskn' => null,
];
$exists = $db->table('catalogo_libros')
->where('id', $libro['id'])
->countAllResults();
if ($exists == 0) {
$db->table('catalogo_libros')->insert($nuevoLibro);
$totalImportados++;
}else{
CLI::write("El libro con ISBN " . $libro['isbn'] . " ya existe para el cliente con id " . $customerId . ".", 'yellow');
}
}
CLI::write("Importación finalizada. Se insertaron " . $totalImportados . " registros.", 'green');
}
private function mapTipoImpresion($tipo)
{
switch ($tipo) {
case 'bn':
return 'negro';
case 'color':
return 'color';
case 'colorfoto':
return 'colorhq';
case 'bicolor':
return 'color';
default:
return null;
}
}
private function getPapelId(?string $code, array $map): ?int
{
if ($code === null)
return null;
$code = trim($code);
return $map[$code] ?? null;
}
private function getAcabadoId(?string $nombre, array $map): ?int
{
if ($nombre === null)
return null;
$nombre = trim($nombre);
return $map[$nombre] ?? null;
}
private function getEncuadernacionId(?string $codigo, array $map): ?int
{
if ($codigo === null)
return null;
$codigo = trim($codigo);
return $map[$codigo] ?? null;
}
private function generarEAN(?string $isbn): ?string
{
if ($isbn === null)
return null;
return str_replace('-', '', $isbn);
}
}

View File

@ -0,0 +1,93 @@
<?php
namespace App\Commands;
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use ZipArchive;
class RestoreBackup extends BaseCommand
{
protected $group = 'Safekat';
protected $name = 'restore:backup';
protected $description = 'Restaura un backup desde un archivo .zip en writable/backups/.';
protected $usage = 'restore:backup [--dry-run]';
protected $options = [
'--dry-run' => 'Simula el proceso de restauración sin ejecutarlo realmente.',
];
public function run(array $params)
{
$isDryRun = CLI::getOption('dry-run');
$backupDir = WRITEPATH . 'backups/';
$backups = glob($backupDir . '*.zip');
if (empty($backups)) {
CLI::error("No se encontraron backups .zip en: $backupDir");
return;
}
CLI::write("Backups disponibles:", 'blue');
foreach ($backups as $i => $file) {
CLI::write("[" . ($i + 1) . "] " . basename($file));
}
$index = CLI::prompt("Selecciona el número del backup a restaurar", null, 'required');
if (!is_numeric($index) || $index < 1 || $index > count($backups)) {
CLI::error("Selección no válida.");
return;
}
$selectedFile = $backups[$index - 1];
CLI::write("🎯 Seleccionado: " . basename($selectedFile), 'cyan');
if ($isDryRun) {
CLI::write("🔍 Modo simulación activado (--dry-run)", 'yellow');
}
$zip = new ZipArchive();
if ($zip->open($selectedFile) !== TRUE) {
CLI::error("No se pudo abrir el archivo ZIP.");
return;
}
$extractPath = WRITEPATH . 'backups/tmp_restore/';
if (!is_dir($extractPath)) {
mkdir($extractPath, 0775, true);
}
$zip->extractTo($extractPath);
$zip->close();
$sqlFiles = glob($extractPath . '*.sql');
if (count($sqlFiles) === 0) {
CLI::error("No se encontró ningún .sql dentro del backup.");
return;
}
$sqlFile = escapeshellarg($sqlFiles[0]);
$db = config('Database')->default;
$cmd = "mysql -h {$db['hostname']} -u {$db['username']} -p'{$db['password']}' {$db['database']} < {$sqlFile}";
if ($isDryRun) {
CLI::write("📋 Comando que se ejecutaría:", 'yellow');
CLI::write($cmd, 'light_gray');
CLI::write("✅ Simulación completa. No se hizo ninguna modificación.", 'green');
} else {
CLI::write("⏳ Restaurando...", 'yellow');
system($cmd, $retval);
if ($retval !== 0) {
CLI::error("❌ Error al restaurar la base de datos (código $retval).");
} else {
CLI::write("✅ Backup restaurado correctamente.", 'green');
}
}
array_map('unlink', glob($extractPath . '*'));
rmdir($extractPath);
}
}

View File

@ -154,7 +154,7 @@ class Auth extends ShieldAuth
* --------------------------------------------------------------------
* Determines whether users can register for the site.
*/
public bool $allowRegistration = true;
public bool $allowRegistration = false;
/**
* --------------------------------------------------------------------

View File

@ -6,14 +6,14 @@ use CodeIgniter\Config\BaseConfig;
class Email extends BaseConfig
{
public string $fromEmail = 'soporte_erp@safekat.es';
public string $fromName = 'Safekat ERP';
public string $fromEmail = 'no-reply@safekat.es';
public string $fromName = 'ERP Safekat 2.0';
public string $recipients = '';
/**
* The "user agent"
*/
public string $userAgent = 'Safekat SL';
public string $userAgent = 'ERP Safekat 2.0';
/**
* The mail sending protocol: mail, sendmail, smtp
@ -28,22 +28,22 @@ class Email extends BaseConfig
/**
* SMTP Server Hostname
*/
public string $SMTPHost = 'localhost';
public string $SMTPHost = 'smtp.ionos.es';
/**
* SMTP Username
*/
public string $SMTPUser = 'soporte_erp@safekat.es';
public string $SMTPUser = 'no-reply@safekat.es';
/**
* SMTP Password
*/
public string $SMTPPass = '';
public string $SMTPPass = '5LKHH^CR#ecR#l55x7ke';
/**
* SMTP Port
*/
public int $SMTPPort = 465;
public int $SMTPPort = 587;
/**
* SMTP Timeout (in seconds)

View File

@ -42,7 +42,7 @@ class Kint extends BaseConfig
*/
public string $richTheme = 'aante-light.css';
public bool $richFolder = false;
public int $richSort = AbstractRenderer::SORT_FULL;
public int $richSort = 0; //AbstractRenderer::SORT_FULL;
/**
* @var array<string, class-string<ValuePluginInterface>>|null

View File

@ -12,8 +12,14 @@ class OrdenTrabajo extends BaseConfig
"interior_bn_at" => "interior_bn_user_id",
"interior_color_at" => "interior_color_user_id",
"cubierta_at" => "cubierta_user_id",
"sobrecubierta_at" => "sobrecubierta_user_id",
"guarda_at" => "guarda_user_id",
//ACABADO
"plastificado_at" => "plastificado_user_id",
"plakene_at" => "plakene_user_id",
"retractilado_at" => "retractilado_user_id",
"estampado_at" => "estampado_user_id",
"uvi_at" => "uvi_user_id",
"encuadernacion_at" => "encuadernacion_user_id",
"corte_at" => "corte_user_id",
"preparacion_interiores_at" => "preparacion_interior_user_id",
@ -21,7 +27,6 @@ class OrdenTrabajo extends BaseConfig
"cosido_at" => "cosido_user_id",
"grapado_at" => "grapado_user_id",
"solapa_at" => "solapa_user_id",
"retractilado_at" => "retractilado_user_id",
"retractilado5_at" => "retractilado5_user_id",
"prototipo_at" => "prototipo_user_id",
"marcapaginas_at" => "marcapaginas_user_id",
@ -100,9 +105,9 @@ class OrdenTrabajo extends BaseConfig
];
public array $OT_PLASTIFICADO_COLOR =
[
"BRIL" => ["bg" => "#00B0F0", "color" => "white"],
"BRILLO" => ["bg" => "#00B0F0", "color" => "white"],
"MATE" => ["bg" => "#FF0000", "color" => "white"],
"SOFT_TOUCH" => ["bg" => "#00B050", "color" => "white"],
"SOFT" => ["bg" => "#00B050", "color" => "white"],
"SANDY" => ["bg" => "#782170", "color" => "white"],
"ANTIRAYADO" => ["bg" => "#E97132", "color" => "white"],
"GOFRADO" => ["bg" => "#FFFF00", "color" => "black"],
@ -116,6 +121,14 @@ class OrdenTrabajo extends BaseConfig
"default" => ["bg" => "white", "color" => "black"],
];
public array $OT_TAREA_STATUS_COLOR = [
"P" => '#FFB22C',
"F" => '#67AE6E',
"S" => '#EB5B00',
"I" => '#3A59D1',
"E" => '#FF0B55',
"D" => '#FFA725',
];
public function __construct()

Binary file not shown.

View File

@ -20,12 +20,6 @@ $routes->get('viewmode/(:alpha)', 'Viewmode::index/$1');
$routes->get('test', 'Test::index');
$routes->group('activity', ['namespace' => 'App\Controllers\Sistema'], function ($routes) {
$routes->get('', 'Actividad::index', ['as' => 'activityList']);
$routes->post('datatable', 'Actividad::datatable', ['as' => 'activityDT']);
});
/*
* --------------------------------------------------------------------
* Route Definitions
@ -40,6 +34,8 @@ foreach (glob(APPPATH . 'Config/Routes/*Routes.php') as $routeFile) {
$routes->group('users', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) {
$routes->get('', 'Users::index', ['as' => 'userList']);
$routes->get('maquinista/change/user', 'Users::index_maquinista_change_user', ['as' => 'maquinistaUserChangeList']);
$routes->get('maquinista/change/session/(:num)', 'Users::change_user_session/$1', ['as' => 'maquinistaChangeUserSession']);
$routes->get('list', 'Users::index', ['as' => 'userList2']);
$routes->get('add', 'Users::add', ['as' => 'newUser']);
$routes->post('add', 'Users::add', ['as' => 'createUser']);
@ -323,6 +319,7 @@ $routes->group('clienteusuarios', ['namespace' => 'App\Controllers\Clientes'], f
$routes->group('misdirecciones', ['namespace' => 'App\Controllers\Clientes'], function ($routes) {
$routes->get('', 'Clientedirecciones::index', ['as' => 'clientedireccionesIndex']);
$routes->get('get/(:num)', 'Clientedirecciones::get/$1', ['as' => 'get']);
$routes->get('getId', 'Clientedirecciones::getDireccionIdFromData');
$routes->get('getDireccionPresupuesto/(:num)', 'Clientedirecciones::getDireccionPresupuesto/$1', ['as' => 'getDireccionPresupuesto']);
$routes->post('add', 'Clientedirecciones::add', ['as' => 'newClientedirecciones']);
$routes->get('getSelect2', 'Clientedirecciones::getSelect2', ['as' => 'listaClientedirecciones']);
@ -550,6 +547,7 @@ $routes->group('facturas', ['namespace' => 'App\Controllers\Facturacion'], funct
$routes->post('updateTotales/(:any)', 'Facturas::updateTotales/$1', ['as' => 'updateFacturaTotales']);
$routes->post('updateCabecera/(:any)', 'Facturas::updateCabecera/$1', ['as' => 'updateCabecera']);
$routes->post('datatablePagos/(:any)', 'FacturasPagos::datatable/$1', ['as' => 'dataTableOfPagosFacturas']);
$routes->post('conformarFactura', 'FacturasPagos::addPagoRectificativa');
$routes->post('editorPagos', 'FacturasPagos::datatable_editor', ['as' => 'editorOfPagosFacturas']);
$routes->post('deleteFacturaLineaPago', 'Facturas::deleteLineaPago', ['as' => 'deleteLineaPago']);
$routes->post('datatablePedidos', 'Facturas::datatablePedidos', ['as' => 'dataTableOfFacturasPedido']);
@ -572,6 +570,7 @@ $routes->group(
function ($routes) {
$routes->get('index/(:num)', 'PrintAlbaranes::index/$1', ['as' => 'viewAlbaranPDF']);
$routes->get('generar/(:num)', 'PrintAlbaranes::generar/$1', ['as' => 'albaranToPdf']);
$routes->get('generar-anonimo/(:num)', 'PrintAlbaranes::generarAnonimo/$1', ['as' => 'albaranAnonimoToPdf']);
}
);
@ -642,6 +641,9 @@ $routes->group('messages', ['namespace' => 'App\Controllers\Chat'], function ($r
$routes->get('datatable/presupuesto', 'ChatController::datatable_presupuesto_messages', ['as' => 'getDatatablePresupuestoMessages']);
$routes->get('datatable/pedido', 'ChatController::datatable_pedido_messages', ['as' => 'getDatatablePedidoMessages']);
$routes->get('datatable/factura', 'ChatController::datatable_factura_messages', ['as' => 'getDatatableFacturaMessages']);
$routes->get('datatable/ots', 'ChatController::datatable_ot_messages', ['as' => 'getDatatableOtMessages']);
$routes->get('datatable/direct', 'ChatController::datatable_direct_messages', ['as' => 'getDatatableDirectMessages']);
$routes->post('direct', 'ChatController::store_new_direct_message', ['as' => 'storeNewDirectMessage']);
$routes->post('direct/client', 'ChatController::store_new_direct_message_client', ['as' => 'storeNewDirectMessageClient']);
@ -652,6 +654,8 @@ $routes->group('chat', ['namespace' => 'App\Controllers\Chat'], function ($route
$routes->get('presupuesto/(:num)', 'ChatController::get_chat_presupuesto_view/$1', ['as' => 'getChatPresupuestoView']);
$routes->get('pedido/(:num)', 'ChatController::get_chat_pedido_view/$1', ['as' => 'getChatPedidoView']);
$routes->get('factura/(:num)', 'ChatController::get_chat_factura_view/$1', ['as' => 'getChatFacturaView']);
$routes->get('ot/(:num)', 'ChatController::get_chat_ot_view/$1', ['as' => 'getChatOtView']);
$routes->get('direct/conversation/(:num)', 'ChatController::get_chat_direct/$1', ['as' => 'getChatDirect']);
$routes->get('direct/users/select/(:num)', 'ChatController::get_chat_direct_select_users/$1', ['as' => 'getChatDirectSelectUsers']);
@ -737,18 +741,29 @@ $routes->group('soporte', ['namespace' => 'App\Controllers\Soporte'], function (
$routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], function ($routes) {
$routes->group('ordentrabajo', ['namespace' => 'App\Controllers\Produccion'], function ($routes) {
/** VIEWS */
$routes->get('', 'Ordentrabajo::index', ['as' => 'viewOrdenTrabajoIndex']);
$routes->get('edit/(:num)', 'Ordentrabajo::edit/$1', ['as' => 'viewOrdenTrabajoEdit']);
$routes->delete('reset/tareas/(:num)', 'Ordentrabajo::reset_tareas/$1');
$routes->delete('tareas/(:num)', 'Ordentrabajo::delete_tarea/$1');
/** GET */
$routes->get('summary/(:num)', 'Ordentrabajo::get_orden_trabajo_summary/$1', ['as' => 'getOrdenTrabajoSumary']);
$routes->get("tarea/progress/(:num)", "Ordentrabajo::get_orden_trabajo_progress_date/$1");
$routes->get('tarea/(:num)', 'Ordentrabajo::find_tarea/$1');
$routes->get('tarea/dates/(:num)', 'Ordentrabajo::get_orden_trabajo_tareas_dates/$1');
$routes->get('tareas/maquina/(:num)/(:num)','Ordentrabajo::get_tareas_ot_maquina/$1/$2');
/** DATATABLES */
$routes->get('datatable', 'Ordentrabajo::datatable');
$routes->get('datatable_pendientes', 'Ordentrabajo::datatable_pendientes');
$routes->get('datatable_ferro_pendiente', 'Ordentrabajo::datatable_ferro_pendiente');
$routes->get('datatable_ferro_ok', 'Ordentrabajo::datatable_ferro_ok');
$routes->get('datatable_news', 'Ordentrabajo::datatable_news');
$routes->get('datatable_prod', 'Ordentrabajo::datatable_prod');
$routes->get('datatable_waiting', 'Ordentrabajo::datatable_waiting');
$routes->get('datatable_revision_com', 'Ordentrabajo::datatable_revision_com');
$routes->get('tareas/datatable/(:num)', 'Ordentrabajo::tareas_datatable/$1', ['as' => 'datatableTareasOrdenTrabajo']);
$routes->get("tarea/progress/(:num)", "Ordentrabajo::get_orden_trabajo_progress_date/$1");
$routes->get('tarea/(:num)', 'Ordentrabajo::find_tarea/$1');
$routes->get('maquinas/ots/datatable/(:num)','Ordentrabajo::datatable_maquina_ordenes_trabajo/$1');
$routes->get('maquinas/ots/(:num)','Ordentrabajo::get_maquina_ots/$1');
/**======================
* UPDATES
*========================**/
@ -757,16 +772,28 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func
$routes->post("reset/date", 'Ordentrabajo::reset_orden_trabajo_date');
$routes->post("update/pedido/date", 'Ordentrabajo::update_orden_trabajo_pedido_date');
$routes->post("reset/pedido/date", 'Ordentrabajo::reset_orden_trabajo_pedido_date');
$routes->post("update/pod/pedido/date/(:num)", 'Ordentrabajo::update_pod_pedido_dates/$1');
$routes->post("update/pedido", 'Ordentrabajo::update_orden_trabajo_pedido');
$routes->post("update/user", 'Ordentrabajo::update_orden_trabajo_user');
$routes->post("update", 'Ordentrabajo::update_orden_trabajo');
$routes->post("upload/portada", 'Ordentrabajo::upload_orden_trabajo_portada');
$routes->delete("portada/(:num)", 'Ordentrabajo::delete_orden_trabajo_portada/$1');
$routes->get("color/(:num)", 'Ordentrabajo::get_orden_trabajo_color_status/$1');
$routes->post("update/tarea/progress", "Ordentrabajo::store_orden_trabajo_progress_date");
$routes->post("update/tarea/pliegos", "Ordentrabajo::update_orden_trabajo_pliegos");
$routes->delete("tarea/progress/(:num)", "Ordentrabajo::delete_orden_trabajo_progress_date/$1");
$routes->post("update/tarea/proveedor", "Ordentrabajo::update_presupuesto_tarea_proveedor");
$routes->post("fa/tareas/update", 'Ordentrabajo::update_orden_trabajo_fa_tareas');
$routes->post("fa/tareas/reset",'Ordentrabajo::delete_orden_trabajo_fa_tareas');
$routes->post('maquinas/ots','Ordentrabajo::store_maquina_ordenes_trabajo');
$routes->post('maquinas/ots/estado','Ordentrabajo::update_maquina_ordenes_trabajo_estado');
/**DELETES */
$routes->delete("portada/(:num)", 'Ordentrabajo::delete_orden_trabajo_portada/$1');
$routes->delete("tarea/progress/(:num)", "Ordentrabajo::delete_orden_trabajo_progress_date/$1");
$routes->delete('reset/tareas/(:num)', 'Ordentrabajo::reset_tareas/$1');
$routes->delete('tareas/(:num)', 'Ordentrabajo::delete_tarea/$1');
$routes->delete('maquinas/ots/(:num)', 'Ordentrabajo::delete_maquina_orden_trabajo_tarea/$1');
$routes->delete('maquinas/ots/all/(:num)', 'Ordentrabajo::delete_maquina_orden_trabajo_all/$1');
/**======================
* FILES
*========================**/
@ -777,7 +804,11 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func
* PDF
*========================**/
$routes->get('pdf/(:num)', 'Ordentrabajo::get_pdf/$1');
$routes->get('pdf/content/(:num)', 'Ordentrabajo::get_ot_pdf_content/$1');
$routes->get('pdf/ferro/(:num)', 'Ordentrabajo::get_ferro_pdf/$1');
$routes->get('pdf/prototipo/(:num)', 'Ordentrabajo::get_prototipo_pdf/$1');
$routes->get('portada/(:num)', 'Ordentrabajo::get_portada_img/$1');
/** PLANNING */
$routes->group('planning', ['namespace' => 'App\Controllers\Produccion'], function ($routes) {
$routes->get('select/maquina/rotativa', 'Ordentrabajo::select_maquina_planning_rot');
$routes->get('select/papel/rotativa', 'Ordentrabajo::select_papel_planning_rot');
@ -787,18 +818,31 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func
$routes->get('rotativa', 'Ordentrabajo::index_planning_rotativa');
$routes->get('papel/datatable', 'Ordentrabajo::papel_gramaje_datatable');
$routes->get('papel/plana/datatable', 'Ordentrabajo::papel_pliego_datatable');
$routes->get('maquina/plana/datatable', 'Ordentrabajo::maquina_plana_datatable');
$routes->get('rotativa/datatable', 'Ordentrabajo::planning_rotativa_datatable');
$routes->get('plana/datatable', 'Ordentrabajo::planning_plana_datatable');
$routes->post('tarea/toggle/corte/(:num)', 'Ordentrabajo::tarea_toggle_corte/$1');
});
$routes->group('maquinista', ['namespace' => 'App\Controllers\Produccion'], function ($routes) {
/**
* VIEWS
*/
$routes->get('maquinas/view', 'Ordentrabajo::maquinista_maquinas_view', ['as' => 'viewProduccionMaquinistaMaquinas']);
$routes->get('maquinas/view/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_list/$1', ['as' => 'viewProduccionMaquinaTareasList']);
$routes->get('maquinas/tareas/datatable/(:alpha)/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_datatable/$1/$2', ['as' => 'viewMaquinistaMaquinaTareaDatatable']);
$routes->get('maquinas/view/auto/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_fichaje_automatico/$1', ['as' => 'viewMaquinistaFichajeAutomatico']);
$routes->get('maquinas/view/scan/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_scan/$1', ['as' => 'viewMaquinistaTareaScan']);
$routes->get('maquinas/view/tarea/(:num)', 'Ordentrabajo::maquinista_maquina_tarea_view/$1', ['as' => 'viewProduccionMaquinistaTareaView']);
$routes->get('maquinas/view/maquina/ot/tareas/(:num)', 'Ordentrabajo::maquinista_maquina_ot_tareas_view/$1', ['as' => 'viewProduccionMaquinistaOtTareasView']);
$routes->get('colas/view', 'Ordentrabajo::maquinista_colas_view', ['as' => 'viewProduccionMaquinistaColas']);
/** DATATABLE */
$routes->get('maquinas/tareas/datatable/(:alpha)/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_datatable/$1/$2', ['as' => 'viewMaquinistaMaquinaTareaDatatable']);
$routes->get('maquinas/tareas/aplazadas/datatable/(:num)', 'Ordentrabajo::maquinista_maquina_tareas_aplazada_datatable/$1', ['as' => 'viewMaquinistaMaquinaTareaAplazadaDatatable']);
/** POST */
$routes->post('maquinas/tareas/printLabels', 'Ordentrabajo::printPackagingLabels');
});
});
});
@ -807,6 +851,8 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi
$routes->get('print/label/test', 'LogisticaController::print_test_label');
$routes->get('panel', 'LogisticaController::panel', ['as' => 'LogisticaPanel']);
$routes->get('envios', 'LogisticaController::gestionEnvios', ['as' => 'gestionEnvios']);
$routes->get('enviosFerros', 'LogisticaController::gestionEnviosFerros', ['as' => 'gestionEnviosFerros']);
$routes->get('etiquetasLogistica', 'LogisticaController::etiquetasLogistica', ['as' => 'etiquetasLogistica']);
$routes->get('datatableEnvios', 'LogisticaController::datatable_envios');
$routes->get('datatableLineasEnvios/(:num)', 'LogisticaController::datatable_enviosEdit/$1');
$routes->get('envio/(:num)', 'LogisticaController::editEnvio/$1');
@ -821,12 +867,33 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi
$routes->post('updateProveedorEnvio', 'LogisticaController::updateProveedorEnvio');
$routes->post('finalizarEnvio', 'LogisticaController::finalizarEnvio');
$routes->post('generateEnvio', 'LogisticaController::generarEnvio');
$routes->post('generateEnvioFerro', 'LogisticaController::generarEnvioFerro');
$routes->get('selectForNewEnvio', 'LogisticaController::findForNewEnvio');
$routes->get('selectDireccionForEnvio', 'LogisticaController::selectDireccionForEnvio');
$routes->post('imprimirEtiquetas', 'LogisticaController::imprimirEtiquetas');
$routes->post('ficharEmbalaje', 'LogisticaController::ficharEmbalaje');
$routes->get('datatableProximosEnvios/(:num)', 'LogisticaController::datatable_proximosEnvios/$1');
$routes->get('listAlbaranes', 'LogisticaController::listAlbaranes', ['as' => 'albaranesList']);
});
$routes->group('etiquetasTitulos', ['namespace' => 'App\Controllers\Logistica'], function ($routes) {
$routes->get('otList', 'EtiquetasTitulosController::findOTs');
$routes->get('addList', 'EtiquetasTitulosController::findAddresses');
$routes->post('newEtiquetaTitulos', 'EtiquetasTitulosController::addEtiqueta');
$routes->get('datatable', 'EtiquetasTitulosController::datatable');
$routes->post('delete', 'EtiquetasTitulosController::deleteEtiqueta');
$routes->get('edit/(:num)', 'EtiquetasTitulosController::edit/$1');
$routes->get('datatableLineas/(:num)', 'EtiquetasTitulosController::datatableLineasEtiquetas/$1');
$routes->get('findOts', 'EtiquetasTitulosController::findOtsWithAddress');
$routes->post('addLineas', 'EtiquetasTitulosController::addLineasEtiqueta');
$routes->post('deleteLineas', 'EtiquetasTitulosController::deleteLineasEtiqueta');
$routes->post('updateLineas', 'EtiquetasTitulosController::updateLineasEtiqueta');
$routes->post('updateComentarios', 'EtiquetasTitulosController::updateComentarios');
$routes->post('updateOrdenCajas', 'EtiquetasTitulosController::updateOrdenCajas');
$routes->post('renumber', 'EtiquetasTitulosController::renumberCajas');
$routes->post('imprimirEtiquetas', 'EtiquetasTitulosController::imprimirEtiquetas');
});
/*
@ -836,6 +903,8 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi
*/
$routes->group('translate', ['namespace' => 'App\Controllers'], function ($routes) {
$routes->post('getTranslation', 'Language::getTranslation', ['as' => 'getKeys']);
$routes->get('lang/(:segment)', 'Language::file/$1');
});
$routes->resource('translate', ['namespace' => 'App\Controllers', 'controller' => 'Language', 'except' => '']);

View File

@ -23,6 +23,7 @@ $routes->group('catalogo', ['namespace' => 'App\Controllers\Catalogo'], function
* AJAX
*========================**/
$routes->get('clientlist', 'CatalogoLibros::getClientList', ['as' => 'catalogoLibrosClientList']);
$routes->get('pedidosAntiguos', 'CatalogoLibros::datatablePedidosAntiguos', ['as' => 'catalogoLibrosPedidosAntiguosDT']);
});

View File

@ -53,7 +53,6 @@ $routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion']
$routes->post('duplicate/(:num)', 'Papelesimpresion::duplicate/$1', ['as' => 'duplicatePapelImpresion']);
$routes->get('select', 'Papelesimpresion::papel_impresion_select', ['as' => 'papelImpresionSelect']);
$routes->get('show/(:num)', 'Papelesimpresion::papel_impresion_find/$1', ['as' => 'showPapelImpresion']);
});
/* Maquinas */
@ -149,5 +148,15 @@ $routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion']
$routes->group("messages", ["namespace" => 'App\Controllers\Chat'], function ($routes) {
$routes->get('', 'ChatController::config_view', ['as' => 'configMessagesIndex']);
});
});
/* Festivos */
$routes->group("festivos", ["namespace" => 'App\Controllers\Configuracion'], function ($routes) {
$routes->get('', 'FestivoController::index', ['as' => 'festivosList']);
$routes->post('', 'FestivoController::store_festivo_date', ['as' => 'storeFestivoDate']);
$routes->delete('(:num)', 'FestivoController::delete_festivo_date/$1', ['as' => 'deleteFestivoDate']);
$routes->get('all', 'FestivoController::find_all', ['as' => 'getFindAllFestivos']);
});
});

View File

@ -0,0 +1,39 @@
<?php
use CodeIgniter\Router\RouteCollection;
/** @var RouteCollection $routes */
/* Rutas para tarifas */
$routes->group('importador', ['namespace' => 'App\Controllers\Importadores'], function ($routes) {
/* Desde Catalogo */
$routes->group('catalogo', ['namespace' => 'App\Controllers\Importadores'], function ($routes) {
/**======================
* Tool
*========================**/
$routes->get('', 'ImportadorCatalogo::index', ['as' => 'importadorCatalogoTool']);
/**======================
* AJAX
*========================**/
$routes->post('validar-fila', 'ImportadorCatalogo::validarFila');
$routes->post('importar-fila', 'ImportadorCatalogo::importarFila');
});
/* Desde Cliente Bubok */
$routes->group('bubok', ['namespace' => 'App\Controllers\Importadores'], function ($routes) {
/**======================
* Tool
*========================**/
$routes->get('', 'ImportadorBubok::index', ['as' => 'importadorBubokTool']);
/**======================
* AJAX
*========================**/
$routes->post('validar-fila', 'ImportadorBubok::validarFila');
$routes->post('importar-fila', 'ImportadorBubok::importarFila');
});
});

View File

@ -17,6 +17,8 @@ $routes->group('presupuestoadmin', ['namespace' => 'App\Controllers\Presupuestos
$routes->post('allmenuitems', 'Presupuestoadmin::allItemsSelect', ['as' => 'select2ItemsOfPresupuestoAdmin']);
$routes->post('menuitems', 'Presupuestoadmin::menuItems', ['as' => 'menuItemsOfPresupuestoAdmin']);
$routes->get('checklomointerior', 'Presupuestoadmin::checkLomo');
$routes->get('cargar/(:any)', 'Presupuestoadmin::cargar/$1');
$routes->post('comparadorinterior', 'Presupuestoadmin::obtenerComparadorInterior');
$routes->post('comparadorexteriores', 'Presupuestoadmin::obtenerComparadorExteriores');
@ -30,6 +32,11 @@ $routes->group('presupuestoadmin', ['namespace' => 'App\Controllers\Presupuestos
$routes->get('presupuestosCliente', 'Presupuestoadmin::tablaClienteForm');
$routes->get('getSumCliente/(:num)', 'Presupuestoadmin::obtenerTotalPresupuestosCliente/$1');
$routes->get('hasFiles', 'Presupuestoadmin::hasFiles');
$routes->post('reprint', 'Presupuestoadmin::reprintPresupuesto');
$routes->post('download_zip', 'Presupuestocliente::download_zip', ['as' => 'descargarAdminArchivos']);
});
//$routes->resource('presupuestoadmin', ['namespace' => 'App\Controllers\Presupuestos', 'controller' => 'Presupuestoadmin', 'except' => 'show,new,create,update']);
@ -51,6 +58,7 @@ $routes->group('presupuestocliente', ['namespace' => 'App\Controllers\Presupuest
$routes->post('calcular', 'Presupuestocliente::calcular', ['as' => 'calcularPresupuesto']);
$routes->post('calcularsolapas', 'Presupuestocliente::calcularMaxSolapas', ['as' => 'calcularSolapas']);
$routes->post('checklomo', 'Presupuestocliente::check_lomo_interior');
$routes->post('download_zip', 'Presupuestocliente::download_zip', ['as' => 'descargarClienteArchivos']);
});
//$routes->resource('presupuestocliente', ['namespace' => 'App\Controllers\Presupuestos', 'controller' => 'Presupuestocliente', 'except' => 'show,new,create,update']);

View File

@ -0,0 +1,13 @@
<?php
use CodeIgniter\Router\RouteCollection;
/** @var RouteCollection $routes */
/* Rutas para tarifas */
$routes->group('scripts', ['namespace' => 'App\Controllers\Scripts'], function ($routes) {
//$routes->get('completar-identidades', 'UsersIntegrity::completarIdentidades');
});

View File

@ -0,0 +1,35 @@
<?php
use CodeIgniter\Router\RouteCollection;
/** @var RouteCollection $routes */
/* Rutas para tarifas */
$routes->group('sistema', ['namespace' => 'App\Controllers\Sistema'], function ($routes) {
/* Actividad */
$routes->group('actividad', ['namespace' => 'App\Controllers\Sistema'], function ($routes) {
/**======================
* CRUD
*========================**/
$routes->get('', 'Actividad::index', ['as' => 'activityList']);
$routes->post('datatable', 'Actividad::datatable', ['as' => 'activityDT']);
});
/* Backups */
$routes->group('backups', function ($routes) {
/**======================
* Tool
*========================**/
$routes->get('', 'Backups::index', ['as' => 'backupsList']);
$routes->get('create', 'Backups::create', ['as' => 'backupsCreate']);
$routes->get('create-dev', 'Backups::createDevelopment', ['as' => 'backupsCreateDev']);
$routes->get('backups/download/(:segment)', 'Backups::download/$1', ['as' => 'backupsDownload']);
$routes->get('delete-local/(:num)', 'Backups::deleteLocal/$1', ['as' => 'backupsDeleteLocal']);
$routes->get('delete-local-dev/(:segment)', 'Backups::deleteLocalDevelopment/$1', ['as' => 'backupsDeleteLocalDev']);
$routes->get('restore/(:segment)/local', 'Backups::restoreLocal/$1', ['as' => 'backupsRestoreLocal']);
$routes->get('restore/(:segment)/remote', 'Backups::restoreRemote/$1', ['as' => 'backupsRestoreRemote']);
});
});

View File

@ -172,6 +172,44 @@ class Validation extends BaseConfig
"label" => "Orden trabajo"
],
];
public array $orden_trabajo_fichaje_auto = [
"orden_trabajo_id" => [
"rules" => "required|integer",
"label" => "Orden trabajo"
],
"maquina_id" => [
"rules" => "required|integer",
"label" => "Máquina"
],
"estado" => [
"rules" => "required|in_list[P,I,S,D,F,E]",
"label" => "estado"
],
"tareas" => [
"rules" => "required",
"label" => "Tareas"
],
"click_init" => [
"rules" => "required|integer",
"label" => "Click init"
],
"click_end" => [
"rules" => "required|integer",
"label" => "Click end"
],
];
public array $maquina_ordenes_trabajo = [
"ordenes_trabajo" => [
"rules" => "required",
"label" => "Orden trabajo"
],
"maquina_id" => [
"rules" => "required|integer",
"label" => "Máquina"
],
];
public array $chat_department =
[
@ -184,4 +222,15 @@ class Validation extends BaseConfig
"label" => "maquina",
],
];
public array $proveedor_tarea =
[
"proveedor_id" => [
"rules" => "required|integer",
"label" => "Proveedor",
],
"orden_trabajo_tarea_id" => [
"rules" => "required|integer",
"label" => "Tarea",
],
];
}

View File

@ -5,22 +5,13 @@ namespace App\Controllers\API;
use App\Controllers\Presupuestos\Presupuestocliente;
use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use App\Models\API\ItemModel;
class ImprimelibrosApi extends ResourceController
{
use ResponseTrait;
public function index()
{
$model = new ItemModel();
$data = $model->findAll();
return $this->respond($data);
}
public function calcular()
{
helper(['form']);

View File

@ -411,6 +411,14 @@ class Albaran extends \App\Controllers\BaseResourceController
return '<input type="text" class="form-control form-control-sm input-albaran-linea" value="' . $q->titulo .
'" data-id="' . $q->id . '" data-field="titulo" />';
})
->edit('cajas', function ($q) {
return '<input class="form-control input-albaran-linea
form-control-sm text-center" value="' . $q->cajas . '" data-id="' . $q->id . '" data-field="cajas" />';
})
->edit('unidades_cajas', function ($q) {
return '<input class="form-control input-albaran-linea
form-control-sm text-center" value="' . $q->unidades_cajas . '" data-id="' . $q->id . '" data-field="unidades_cajas" />';
})
->edit('total', function ($q) {
return '<input class="form-control autonumeric-2 input-albaran-linea
form-control-sm text-center" value="' . $q->total . '" data-id="' . $q->id . '" data-field="total" />';
@ -468,10 +476,29 @@ class Albaran extends \App\Controllers\BaseResourceController
$model_linea->update($id, $linea->toArray());
if($fieldName == 'cajas'){
$cajas = $model_linea->where('albaran_id', $linea->albaran_id)
->where('cajas > 0')
->select('SUM(cajas) as total_cajas')
->get();
$albaranModel = model('App\Models\Albaranes\AlbaranModel');
$albaran = $albaranModel->find($linea->albaran_id);
if($albaran != false) {
$albaran->cajas = $cajas->getRow()->total_cajas;
$albaran->user_updated_id = auth()->user()->id;
$albaran->updated_at = date('Y-m-d H:i:s');
$albaranModel->update($linea->albaran_id, $albaran->toArray());
}
}
$data = [
'success' => true,
'message' => lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.',
];
if($fieldName == 'cajas') {
$data['cajas'] = $cajas->getRow()->total_cajas;
};
return $this->respond($data);
} else {

View File

@ -35,7 +35,7 @@ class BaseController extends Controller
*
* @var array
*/
protected $helpers = ['general', 'go_common', 'rbac'];
protected $helpers = ['general', 'go_common', 'rbac', 'assets'];
/**
* Constructor.

View File

@ -85,7 +85,7 @@ abstract class BaseResourceController extends \CodeIgniter\RESTful\ResourceContr
*
* @var array
*/
protected $helpers = ['session', 'go_common', 'form', 'text', 'general', 'rbac']; //JJO
protected $helpers = ['session', 'go_common', 'form', 'text', 'general', 'rbac', 'assets']; //JJO
/**
* Initializer method.

View File

@ -5,6 +5,7 @@ use App\Controllers\BaseResourceController;
use App\Entities\Catalogo\CatalogoLibroEntity;
use App\Models\Catalogo\CatalogoLibroModel;
use App\Models\Clientes\ClienteModel;
use App\Models\Presupuestos\ImportadorModel;
use Hermawan\DataTables\DataTable;
class CatalogoLibros extends BaseResourceController
@ -48,7 +49,6 @@ class CatalogoLibros extends BaseResourceController
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Catalogo.catalogo')]),
'catalogoLibrosEntity' => new CatalogoLibroEntity(),
'usingServerSideDataTable' => true,
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
@ -67,7 +67,7 @@ class CatalogoLibros extends BaseResourceController
$sanitizedData = $this->sanitized($postData, true);
$sanitizedData['user_created_id'] = auth()->user()->id;
unset($sanitizedData['isk']);
unset($sanitizedData['iskn']);
$noException = true;
if ($successfulResult = $this->canValidate()):
@ -132,11 +132,11 @@ class CatalogoLibros extends BaseResourceController
$postData = $this->request->getPost();
$sanitizedData = $this->sanitized($postData, true);
unset($sanitizedData['isk']);
unset($sanitizedData['iskn']);
$sanitizedData['user_update_id'] = auth()->user()->id;
$noException = true;
if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) :
@ -174,7 +174,7 @@ class CatalogoLibros extends BaseResourceController
endif; // $noException && $successfulResult
endif; // ($requestMethod === 'post')
$this->viewData['catalogoLibrosEntity'] = $catalogoLibrosEntity;
$this->viewData['formAction'] = route_to('catalogoLibrosEdit', $id);
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Catalogo.moduleTitle') . ' ' . lang('Basic.global.edit3');
@ -225,7 +225,6 @@ class CatalogoLibros extends BaseResourceController
}
/* IMN */
public function getClientList()
{
@ -235,5 +234,41 @@ class CatalogoLibros extends BaseResourceController
}
/* Historico de pedidos ERP antiguo */
public function datatablePedidosAntiguos()
{
$reqData = $this->request->getGet();
$start = $reqData['start'] ?? 0;
$length = $reqData['length'] ?? 10;
$catalogoId = $reqData['catalogo_id'] ?? null;
// Instanciar el modelo directamente
$importadorModel = new ImportadorModel();
$q = $importadorModel->getHistoricoPedidosCatalogo($catalogoId);
return DataTable::of($q)
->setSearchableColumns([
't1.id',
't1.created_at',
't1.tirada',
'(CASE WHEN t1.tirada > 0 THEN t1.total / t1.tirada ELSE 0 END)',
't1.total',
't1.estado'
])
->edit('total', fn($row) => number_format((float) $row->total, 2, ',', '.') . ' €')
->edit('precio_ud', fn($row) => number_format((float) $row->precio_ud, 2, ',', '.') . ' €')
->edit('created_at', fn($row) => date('d/m/Y', strtotime($row->created_at)))
->add('actionBtns', function ($row) {
return '<div class="btn-group btn-group-sm">
<a href="https://gestion.safekat.es/pedido/detail/' . $row->id . '" class="btn btn-sm btn-info" target="_blank">
<i class="ti ti-eye"></i> Ver
</a>
</div>';
}, 'last')
->toJson(returnAsObject: true);
}
}

View File

@ -1,2 +0,0 @@
Portada Id Cliente Título Edición Autor Archivo ISBN EAN Páginas Acciones
Lo que hay que listar

View File

@ -222,6 +222,25 @@ class ChatController extends BaseController
return view(static::$viewPath . 'messageChatInternal', $this->viewData);
}
}
public function get_chat_ot_view($chat_id)
{
$chat = $this->chatModel->find($chat_id);
$this->viewData['breadcrumb'] = [
['title' => lang("Chat.chat"), 'route' => route_to("mensajeriaView"), 'active' => false],
['title' => $chat->title, 'route' => 'javascript:void(0);', 'active' => true]
];
$this->viewData["modelId"] = $chat->orden_trabajo_id;
$this->viewData["type"] = "ot";
$auth_user = auth()->user();
$this->chatModel->setAsViewedChatUserNotifications($chat_id, $auth_user->id);
$this->chatModel->setAsUnviewedChatUserMessages($chat_id, $auth_user->id);
if ($chat->chat_department_id) {
return view(static::$viewPath . 'messageChatFactura', $this->viewData);
} else {
return view(static::$viewPath . 'messageChatInternal', $this->viewData);
}
}
public function get_chat(int $chat_id)
{
@ -344,14 +363,13 @@ class ChatController extends BaseController
$query = $this->userModel->builder()->select(
[
"id",
"CONCAT(first_name,' ',last_name,'(',username,')') as name"
"CONCAT(first_name,' ',last_name) as name"
]
)
->where("deleted_at", null)
->whereNotIn("id", [auth()->user()->id]);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("users.username", $this->request->getGet("q"))
->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
->groupEnd();
}
@ -502,6 +520,40 @@ class ChatController extends BaseController
->toJson(true);
}
public function datatable_ot_messages()
{
$auth_user_id = auth()->user()->id;
$isAdmin = auth()->user()->inGroup('admin');
$query = $this->chatModel->getQueryDatatableMessageOrdenTrabajo($auth_user_id);
return DataTable::of($query)
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
->add("action", fn($q) => ["type" => "ot", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
"view_chat" => lang('Chat.view_chat'),
"view_by_alt_message" => lang('Chat.view_by_alt_message')
]])
->toJson(true);
}
public function datatable_direct_messages()
{
$auth_user_id = auth()->user()->id;
$isAdmin = auth()->user()->inGroup('admin');
$query = $this->chatModel->getQueryDatatableDirectMessages($auth_user_id);
return DataTable::of($query)
->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
->edit("creator",fn($q) => $q->userId == $auth_user_id ? '<span class="badge text-bg-success w-100">'.lang("App.me").'</span>' : $q->creator)
->add("viewed", fn($q) => $this->chatModel->isMessageChatViewed($q->chatMessageId))
->add("action", fn($q) => ["type" => "direct", "modelId" => $q->id, "isAdmin" => $isAdmin,"chatMessageId" => $q->chatMessageId, "lang" => [
"view_chat" => lang('Chat.view_chat'),
"view_by_alt_message" => lang('Chat.view_by_alt_message')
]])
->toJson(true);
}
public function get_notifications_not_viewed_from_message(int $chat_message_id)
{
$unviewedNotifications = $this->chatModel->getUsersNotificationNotViewedFromChat($chat_message_id);
@ -569,14 +621,13 @@ class ChatController extends BaseController
$query = $this->userModel->builder()->select(
[
"id",
"CONCAT(first_name,' ',last_name,'(',username,')') as name"
"CONCAT(first_name,' ',last_name) as name"
]
)
->where("deleted_at", null)
->whereNotIn("id", $chat_users_id);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("users.username", $this->request->getGet("q"))
->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
->groupEnd();
}

View File

@ -215,13 +215,13 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
{
try {
$resourceData = $this->model->getDireccion($id);
$response = (object)[
$response = (object) [
'error' => false,
'data' => $resourceData
];
return $this->respond($response);
} catch (\Exception $e) {
$response = (object)[
$response = (object) [
'error' => true,
'message' => $e->getMessage()
];
@ -229,22 +229,61 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
}
}
public function getDireccionIdFromData()
{
$data = $this->request->getGet('data') ?? [];
$cliente_id = $this->request->getGet('cliente_id') ?? -1;
$att = $data['att'] ?? "";
$direccion = $data['direccion'] ?? "";
$cp = $data['cp'] ?? "";
$municipio = $data['municipio'] ?? "";
$provincia = $data['provincia'] ?? "";
$pais_id = $data['pais_id'] ?? -1;
$email = $data['email'] ?? "";
$telefono = $data['telefono'] ?? "";
try {
$model = model('App\Models\Clientes\ClienteDireccionesModel');
$id = $model->select('id')
->where('att', $att)
->where('direccion', $direccion)
->where('cp', $cp)
->where('municipio', $municipio)
->where('provincia', $provincia)
->where('pais_id', $pais_id)
->where('email', $email)
->where('telefono', $telefono)
->where('cliente_id', $cliente_id)
->get()
->getResultObject();
if (count($id) > 0) {
$id = $id[0]->id;
} else {
$id = null;
}
return $id;
} catch (\Exception $e) {
throw new \RuntimeException($e->getMessage());
}
}
public function getDireccionPresupuesto($id)
{
try {
$model = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
$resourceData = $model->getDireccion($id);
if(count($resourceData) > 0){
if (count($resourceData) > 0) {
$resourceData[0]->direccionId = $id;
}
$response = (object)[
$response = (object) [
'error' => false,
'data' => $resourceData
];
return $this->respond($response);
} catch (\Exception $e) {
$response = (object)[
$response = (object) [
'error' => true,
'message' => $e->getMessage()
];
@ -400,11 +439,11 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
protected function getComunidadAutonomaListItems($selId = null)
{
$data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('ComunidadesAutonomas.comunidadAutonoma'))])];
if (!is_null($selId)) :
if (!is_null($selId)):
$comunidadAutonomaModel = model('App\Models\Configuracion\ComunidadAutonomaModel');
$selOption = $comunidadAutonomaModel->where('id', $selId)->findColumn('nombre');
if (!empty($selOption)) :
if (!empty($selOption)):
$data[$selId] = $selOption[0];
endif;
endif;
@ -414,11 +453,11 @@ class Clientedirecciones extends \App\Controllers\BaseResourceController
protected function getProvinciaListItems($selId = null)
{
$data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Provincias.provincia'))])];
if (!empty($selId)) :
if (!empty($selId)):
$provinciaModel = model('App\Models\Configuracion\ProvinciaModel');
$selOption = $provinciaModel->where('id', $selId)->findColumn('nombre');
if (!empty($selOption)) :
if (!empty($selOption)):
$data[$selId] = $selOption[0];
endif;
endif;

View File

@ -0,0 +1,103 @@
<?php
namespace App\Controllers\Configuracion;
use App\Controllers\BaseController;
use App\Controllers\BaseResourceController;
use App\Entities\Configuracion\FestivoEntity;
use App\Models\Collection;
use App\Entities\Configuracion\Imposicion;
use App\Models\Configuracion\FestivoModel;
use App\Models\Configuracion\ImposicionEsquemaModel;
use App\Models\Configuracion\ImposicionModel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Validation\Validation;
use Hermawan\DataTables\DataTable;
use Psr\Log\LoggerInterface;
class FestivoController extends BaseController
{
protected $modelName = FestivoModel::class;
protected FestivoModel $model;
protected static $controllerSlug = 'festivos';
protected $format = 'json';
protected string $viewPath = 'themes/vuexy/form/configuracion/festivos/';
protected $indexRoute = 'festivoList';
protected array $viewData = [];
protected Validation $validation;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->viewData['pageTitle'] = lang('Festivos.moduleTitle');
$this->viewData['usingSweetAlert'] = true;
$this->model = model($this->modelName);
$this->validation = service("validation");
parent::initController($request, $response, $logger);
}
public function index()
{
return view($this->viewPath . $this->indexRoute);
}
public function store_festivo_date()
{
$bodyData = $this->request->getPost();
$date = $bodyData['date'];
$count = $this->model->where('date',$date)->countAllResults();
if ($count) {
$status = $this->model->where('date', $date)->delete(purge: true);
return $this->response->setJSON([
"message" => lang("App.user_alert_delete"),
"status" => $status,
]);
} else {
$status = $this->model->insert($bodyData);
if ($status) {
$festivoEntity = $this->model->find($status);
return $this->response->setJSON([
"message" => lang("App.global_alert_save_success"),
"status" => $status,
"data" => $festivoEntity
]);
} else {
return $this->response->setJSON([
"message" => lang("App.global_alert_save_error"),
"errors" => $this->model->errors(),
"status" => true
])->setStatusCode(400);
}
}
}
public function delete_festivo_date($id)
{
$status = $this->model->delete($id, true);
if ($status) {
return $this->response->setJSON([
"message" => lang("App.user_alert_delete"),
"status" => $status,
]);
} else {
return $this->response->setJSON([
"message" => lang("App.global_alert_save_error"),
"errors" => $this->model->errors(),
"status" => true
])->setStatusCode(400);
}
}
public function find_all()
{
$festivos = $this->model->findAll();
return $this->response->setJSON([
"message" => lang("App.global_alert_fetch_success"),
"status" => true,
"data" => $festivos
]);
}
}

View File

@ -67,6 +67,7 @@ class Imposiciones extends BaseController
['title' => lang("App.menu_imposiciones"), 'route' => route_to("imposicionList"), 'active' => true],
];
$this->viewData["method"] = "add";
return view(static::$viewPath . 'viewImposicionNewForm', $this->viewData);
}
public function add_esquema()
@ -88,6 +89,7 @@ class Imposiciones extends BaseController
];
}
$this->viewData["method"] = "edit";
return view(static::$viewPath . 'viewImposicionForm', $this->viewData);
}
public function edit_imposicion_esquema($imposicion_esquema_id = null)

View File

@ -207,6 +207,9 @@ class Maquinas extends \App\Controllers\BaseResourceController
if ($this->request->getPost('is_inkjet') == null) {
$sanitizedData['is_inkjet'] = false;
}
if ($this->request->getPost('etiqueta_envio') == null) {
$sanitizedData['etiqueta_envio'] = false;
}
// JJO
$sanitizedData['user_updated_id'] = auth()->user()->id;

View File

@ -1,4 +1,6 @@
<?php namespace App\Controllers\Configuracion;
<?php
namespace App\Controllers\Configuracion;
use App\Entities\Usuarios\UserEntity;
use App\Models\Chat\ChatDeparmentModel;
@ -54,7 +56,6 @@ class Users extends \App\Controllers\GoBaseController
];
parent::initController($request, $response, $logger);
}
public function index()
@ -87,7 +88,7 @@ class Users extends \App\Controllers\GoBaseController
// Marcar el username como NULL
$sanitizedData = $this->sanitized($postData, true);
$noException = true;
// Obtener proveedor de usuarios
@ -118,11 +119,10 @@ class Users extends \App\Controllers\GoBaseController
} // Email is not unique!
else {
$this->viewData['errorMessage'] = "El correo '". $sanitizedData['email'] ."' ya está registrado en el sistema";
$this->viewData['errorMessage'] = "El correo '" . $sanitizedData['email'] . "' ya está registrado en el sistema";
$this->session->setFlashdata('formErrors', $this->model->errors());
$successfulResult = false; // Hacked
}
} catch (\Exception $e) {
$noException = false;
$this->viewData['errorMessage'] = $e->getMessage();
@ -234,7 +234,6 @@ class Users extends \App\Controllers\GoBaseController
} else {
$successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData);
}
} catch (\Exception $e) {
$noException = false;
$this->dealWithException($e);
@ -319,8 +318,6 @@ class Users extends \App\Controllers\GoBaseController
$message = "Usuario eliminado correctamente";
return $this->redirect2listView('successMessage', $message);
} // end function delete(...)
@ -374,9 +371,10 @@ class Users extends \App\Controllers\GoBaseController
}
}
public function datatable(){
public function datatable()
{
if($this->request->isAJAX()){
if ($this->request->isAJAX()) {
$reqData = $this->request->getPost();
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
@ -405,7 +403,6 @@ class Users extends \App\Controllers\GoBaseController
$this->model->getResource([])->countAllResults(),
$this->model->getResource($searchValues)->countAllResults()
));
} else {
return $this->failUnauthorized('Invalid request', 403);
}
@ -447,4 +444,27 @@ class Users extends \App\Controllers\GoBaseController
return $data;
}
public function index_maquinista_change_user()
{
$this->viewData['breadcrumb'] = [
['title' => lang("App.menu_change_session"), 'route' => route_to('maquinistaUserChangeList'), 'active' => true]
];
$maquinistas = [];
$users = auth()->getProvider()->whereNotIn('id',[auth()->user()->id])->findAll();
foreach ($users as $key => $user) {
if ($user->inGroup('maquina') && !$user->inGroup('admin', 'comercial', 'cliente-editor', 'cliente-admin')) {
$maquinistas[] = $user;
}
}
$this->viewData['maquinistas'] = $maquinistas;
return view('/themes/vuexy/form/produccion/maquinista/viewMaquinistaCambioUserList.php', $this->viewData);
}
public function change_user_session(int $user_id)
{
// Check the credentials
$user = auth()->getProvider()->findById($user_id);
auth()->logout();
auth()->login($user);
return redirect("home");
}
}

View File

@ -234,6 +234,13 @@ class Facturas extends \App\Controllers\BaseResourceController
$factura->showDeleteButton = model('App\Models\Facturas\FacturaPagoModel')
->where('factura_id', $factura->id)->countAllResults() == 0;
if($factura->numero != null && $factura->numero != '' && strpos($factura->numero, "REC ") === 0) {
$modelPagos = model('App\Models\Facturas\FacturaPagoModel');
if($modelPagos->where('factura_id', $factura->id)->countAllResults() > 0) {
$factura->facturaRectificativaPagada = 1;
}
}
$this->viewData['facturaEntity'] = $factura;
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Facturas.factura') . ' ' . lang('Basic.global.edit3');
@ -831,11 +838,15 @@ class Facturas extends \App\Controllers\BaseResourceController
'user_updated_id' => auth()->user()->id,
];
if ((strpos($numero, "REC ") === 0)) {
$data['estado_pago'] = 'pagada';
}
$this->model->update($factura_id, $data);
if ((strpos($numero, "REC ") === 0)) {
$this->model->where('numero', $factura->factura_rectificada_id)->set([
'factura_rectificativa_id' => $numero,
'user_updated_id' => auth()->user()->id,
])->update();
}
}

View File

@ -92,7 +92,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
Field::inst('id'),
Field::inst('base'),
Field::inst('total_iva'),
Field::inst('total'),
Field::inst('total')->set(Field::SET_BOTH),
Field::inst('cantidad')
->validator(
'Validate::numeric',
@ -126,19 +126,6 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
'message' => lang('Facturas.validation.requerido')
)
),
Field::inst('total')
->validator(
'Validate::numeric',
array(
'message' => lang('Facturas.validation.numerico')
)
)
->validator(
'Validate::notEmpty',
array(
'message' => lang('Facturas.validation.requerido')
)
),
Field::inst('pedido_linea_impresion_id')
->setFormatter(function ($val, $data, $opts) {
return $val === '' ? null : $val;
@ -157,7 +144,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['total'],
$values['iva'],
$values['cantidad'],
$values['old_cantidad'],
$values['old_cantidad'],
$values['base']
);
$editor
@ -183,7 +170,7 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['total'],
$values['iva'],
$values['cantidad'],
$values['old_cantidad'],
$values['old_cantidad'],
$values['base']
);
$editor
@ -256,14 +243,13 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
$values['base'] = $base;
$values['total_iva'] = $total_iva;
$values['total'] = $total;
}
else{
} else {
// se pasa la base y el iva
$total_iva = round($base_input * $iva / 100, 2);
$total = round($base_input + $total_iva, 2);
$values = [];
$values['base'] = $base_input;
$values['base'] = (float) $base_input;
$values['total_iva'] = $total_iva;
$values['total'] = $total;

View File

@ -136,4 +136,36 @@ class FacturasPagos extends \App\Controllers\BaseResourceController
}
}
public function addPagoRectificativa()
{
if ($this->request->isAJAX()) {
$data['factura_id'] = $this->request->getPost('factura_id');
$data['fecha_vencimiento_at'] = $this->request->getPost('fecha');
$data['total'] = $this->request->getPost('total');
$data['user_updated_id'] = auth()->user()->id;
$data['forma_pago_id'] = 6; // compensada
if($data['fecha_vencimiento_at'] != null && $data['fecha_vencimiento_at'] != '') {
$data['fecha_vencimiento_at'] = date('Y-m-d H:i:s', strtotime($data['fecha_vencimiento_at']));
}
$model = new FacturaPagoModel();
$model->insert($data);
$modelFactura = model('App\Models\Facturas\FacturaModel');
$modelFactura->update($data['factura_id'], [
'estado_pago' => 'pagada',
'updated_at' => date('Y-m-d H:i:s'),
'user_updated_id' => auth()->user()->id,
]);
return $this->response->setJSON([
'status' => true,
'message' => lang('Facturas.facturaConformada'),
]);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
}

View File

@ -139,7 +139,7 @@ abstract class GoBaseController extends Controller
*
* @var array
*/
protected $helpers = ['session', 'go_common', 'text', 'general', 'jwt', 'rbac']; //JJO
protected $helpers = ['session', 'go_common', 'text', 'general', 'jwt', 'rbac', 'assets']; //JJO
public static $queries = [];

View File

@ -0,0 +1,551 @@
<?php
namespace App\Controllers\Importadores;
use App\Controllers\BaseResourceController;
use App\Controllers\Presupuestos\Presupuestocliente;
use App\Models\Presupuestos\PresupuestoModel;
use App\Services\PresupuestoService;
class ImportadorBubok extends BaseResourceController
{
protected $format = 'json';
protected static $singularObjectName = 'Importador';
protected static $singularObjectNameCc = 'ImportadorBubok';
protected static $pluralObjectName = 'Importadores';
protected static $pluralObjectNameCc = 'importadores';
protected static $controllerSlug = 'importador';
protected static $viewPath = 'themes/vuexy/form/importador/bubok/';
protected $indexRoute = 'ImportadorBubokTool';
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
{
$this->viewData['pageTitle'] = lang('Importador.listingPage');
$this->viewData['usingSweetAlert'] = true;
// Breadcrumbs (IMN)
$this->viewData['breadcrumb'] = [
['title' => lang("App.menu_importadores"), 'route' => "javascript:void(0);", 'active' => false],
['title' => lang("App.menu_importadores_bubok"), 'route' => route_to('importadorBubokTool'), 'active' => true]
];
parent::initController($request, $response, $logger);
}
public function index()
{
checkPermission('importadores.bubok');
$viewData = [
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
return view(static::$viewPath . 'viewImportadorBubokTool', $viewData);
}
public function validarFila()
{
checkPermission('importadores.bubok');
$json = $this->request->getJSON();
if (!$json || empty($json->producto) || empty($json->pedido)) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'Datos incompletos'
]);
}
$producto = $json->producto;
$pedido = $json->pedido;
// Validar existencia de ID de producto
if (empty($producto->id)) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'ID de producto no proporcionado'
]);
}
$refCliente = $pedido->orderNumber . '-' . $producto->id;
// Validar formato Ref. Cliente
if (strpos($refCliente, '-') === false || strlen($refCliente) < 5) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'Ref. cliente inválido'
]);
}
// 1. Verificar si ya fue importado
$presupuestoModel = new PresupuestoModel();
$yaExiste = $presupuestoModel->where('referencia_cliente', $refCliente)->first();
if ($yaExiste) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'Referencia ya importada'
]);
}
// 2. Validación básica del producto (puedes expandir con más reglas si lo necesitas)
$errores = [];
if (empty($producto->title))
$errores[] = 'Falta título';
if (empty($producto->body->pages))
$errores[] = 'Faltan páginas';
if (empty($producto->amount))
$errores[] = 'Falta tirada';
if (!empty($errores)) {
return $this->response->setJSON([
'apto' => false,
'reason' => implode(', ', $errores)
]);
}
// 3. Producto considerado apto
return $this->response->setJSON([
'apto' => true
]);
}
public function importarFila()
{
checkPermission('importadores.bubok');
$json = $this->request->getJSON();
// Validación mínima de datos comunes
$pedido = $json->pedido ?? null;
if (!$pedido || !isset($pedido->orderNumber)) {
return $this->respond([
'status' => 400,
'message' => 'Datos comunes del pedido ausentes o inválidos.'
]);
}
// Validación mínima de existencia del producto en la linea
if (!$json || !isset($json->producto)) {
return $this->respond([
'status' => 400,
'message' => 'Producto no proporcionado o inválido.'
]);
}
$producto = $json->producto;
// 1. Datos básicos:
// Referencia del cliente
$orderNumber = $pedido->orderNumber ?? null;
$productId = $producto->id ?? null;
if (is_null($orderNumber) || is_null($productId)) {
return $this->respond([
'status' => 400,
'message' => 'Número de orden o ID del producto no reconocidos.'
]);
}
$refCliente = "$orderNumber-$productId";
// Titulo
$titulo = $producto->title ?? null;
if (is_null($titulo)) {
return $this->respond([
'status' => 400,
'message' => 'Título del libro no reconocido.'
]);
}
// Validación de páginas y tirada
$paginas = isset($producto->body->pages) ? (int) $producto->body->pages : 0;
$tirada = isset($producto->amount) ? (int) $producto->amount : 0;
if ($paginas <= 0 || $tirada <= 0) {
$errores = [];
if ($paginas <= 0) {
$errores[] = 'Número de páginas inválido.';
}
if ($tirada <= 0) {
$errores[] = 'Tirada inválida.';
}
return $this->respond([
'status' => 400,
'message' => implode(' ', $errores)
]);
}
// Ancho y alto
$ancho = null;
$alto = null;
foreach ($producto->size as $key => $val) {
if ($val == 1) {
// ejemplo: size170x235
$size = str_replace('size', '', $key);
[$ancho, $alto] = explode('x', $size);
$ancho = (int) $ancho;
$alto = (int) $alto;
break;
}
}
if (!$ancho || !$alto) {
return $this->respond([
'status' => 400,
'message' => 'Tamaño del libro no reconocido.'
]);
}
/*$numGuardaPages = 4;
$hasGuarda = !empty($producto->cover->guarda);
if ($hasGuarda)
$paginas += $numGuardaPages;*/
// 2. Interior: color o negro
// Determinar tipo de impresión interior
$interiorTipo = null;
if (isset($producto->body->color->CMYK) && $producto->body->color->CMYK == '1') {
$interiorTipo = 'color';
} elseif (isset($producto->body->color->Monochrome) && $producto->body->color->Monochrome == '1') {
$interiorTipo = 'negro';
} elseif (isset($producto->body->color->Semicolor) && $producto->body->color->Semicolor == '1') {
return $this->respond([
'status' => 400,
'message' => 'Tipo de impresión "Semicolor" no soportado.'
]);
}
if (is_null($interiorTipo)) {
return $this->respond([
'status' => 400,
'message' => 'No se pudo determinar si el interior es en color o blanco y negro.'
]);
}
// Determinar tipo de papel interior
$papelInteriorId = null;
if (isset($producto->body->paperColor->white) && $producto->body->paperColor->white == '1') {
$papelInteriorId = 3; // Offset blanco 'OFF1'
} elseif (isset($producto->body->paperColor->cream) && $producto->body->paperColor->cream == '1') {
$papelInteriorId = 4; // Offset ahuesado 'OFF2'
} else {
return $this->respond([
'status' => 400,
'message' => 'Tipo de papel interior no definido.'
]);
}
// Determinar el gramaje del papel
$gramajePapelInterior = null;
foreach ($producto->body->paperWeight as $key => $val) {
if ($val == 1) {
$gramajePapelInterior = (int) str_replace(['weight', 'gr'], '', $key);
break;
}
}
if (!$gramajePapelInterior) {
return $this->respond([
'status' => 400,
'message' => 'Gramaje del papel no válido.'
]);
}
// 3. Encuadernación
// Tapa dura
$tapaDura = isset($producto->cover->type->tapadura) && $producto->cover->type->tapadura == '1';
// Solapas
$solapas = isset($producto->cover->type->consolapas) && $producto->cover->type->consolapas == '1';
// Doble cara (a veces se activa con tapa dura) una cara => 2; dos caras => 4
$doscara = false;
// Tipo de encuadernado
$encuadernadoId = null;
if (isset($producto->cover->coverType->SoftCover) && $producto->cover->coverType->SoftCover == '1') {
if ($tapaDura) {
$encuadernadoId = 1; // Libro fresado tapa dura
$doscara = true;
} else {
$encuadernadoId = 2; // Libro fresado tapa blanda
}
} elseif (isset($producto->cover->coverType->SaddleStitch) && $producto->cover->coverType->SaddleStitch == '1') {
if ($tapaDura) {
$encuadernadoId = 3; // Libro cosido tapa dura
$doscara = true;
} else {
$encuadernadoId = $solapas ? 20 : 4; // Libro cosido tapa blanda (solapas) : (sin solapas)
}
} elseif (isset($producto->cover->coverType->CoilBinding) && $producto->cover->coverType->CoilBinding == '1') {
if ($tapaDura) {
$encuadernadoId = 5; // Libro espiral tapa dura
$doscara = true;
} else {
$encuadernadoId = 6; // Libro espiral tapa blanda
}
}
if (!$encuadernadoId) {
return $this->respond([
'status' => 400,
'message' => 'Tipo de encuadernación no identificado.'
]);
}
// Determinar el acabado de la cubierta
$acabadoId = null;
if (isset($producto->cover->acabado->brillo) && $producto->cover->acabado->brillo == '1') {
$acabadoId = 1; // Plastificado brillo 1/c
} elseif (isset($producto->cover->acabado->mate) && $producto->cover->acabado->mate == '1') {
$acabadoId = 2; // Plastificado mate 1/c
} else {
return $this->respond([
'status' => 400,
'message' => 'Tipo de acabado de cubierta no definido.'
]);
}
// 4. ENVÍO: recuperamos la primera dirección del cliente BUBOK (ID 40)
$clienteDireccionModel = model('App\Models\Clientes\ClienteDireccionesModel');
$direccionCliente = $clienteDireccionModel
->where('cliente_id', 40)
->orderBy('id', 'asc')
->first();
if (!$direccionCliente) {
return $this->respond([
'status' => 400,
'message' => 'El cliente Bubok no tiene direcciones asociadas.'
]);
}
$direcciones = [
[
'direccion' => [
'id' => (int) $direccionCliente->id,
'cliente_id' => (int) $direccionCliente->cliente_id,
'cliente_nombre' => $direccionCliente->clienteNombre,
'att' => $direccionCliente->persona_contacto ?? '',
'alias' => $direccionCliente->alias ?? '',
'email' => $direccionCliente->email ?? '',
'direccion' => $direccionCliente->direccion,
'pais_id' => (int) $direccionCliente->pais_id,
'pais' => $direccionCliente->paisNombre,
'municipio' => $direccionCliente->municipio,
'provincia' => $direccionCliente->provincia,
'cp' => $direccionCliente->cp,
'telefono' => $direccionCliente->telefono,
],
'unidades' => $tirada,
'entregaPalets' => false
]
];
// Recalcular calidad (isColor y isHq) en funcion del cliente
[$isColor, $isHq] = PresupuestoService::getCalidad(
'importador-bubok',
null,
((trim(strtolower($interiorTipo)) === 'color') ? 1 : 0),
0,
intval($tirada ?? 0)
);
// Generamos el objeto a importar
$dataToImport = [
'selectedTirada' => $tirada,
'datosCabecera' => [
'titulo' => $titulo,
'autor' => null,
'isbn' => null,
'coleccion' => null,
'referenciaCliente' => $refCliente
],
'tirada' => [$tirada],
'tamanio' => [
'ancho' => $ancho,
'alto' => $alto
],
'tipo' => '',
'tipo_presupuesto_id' => $encuadernadoId,
'clienteId' => 40, // BUBOK ID
'isColor' => $isColor,
'isHq' => $isHq,
'paginas' => $paginas,
'paginasColor' => ($interiorTipo === 'color') ? $paginas : 0,
'paginasCuadernillo' => 32,
'interior' => [
'papelInterior' => $papelInteriorId,
'gramajeInterior' => $gramajePapelInterior
],
'cubierta' => [
'papelCubierta' => 2, // 'EST2'
'carasCubierta' => $doscara ? 2 : 4,
'gramajeCubierta' => in_array($encuadernadoId, [1, 3]) ? 150 : 300, // 150 gramos para "fresado tapa dura" y "cosido tapa dura"
'solapas' => !empty($producto->cover->type->consolapas) ? 80 : 0,
'acabado' => $acabadoId,
'cabezada' => 'WHI',
'lomoRedondo' => 0
],
'guardas' => [],
'sobrecubierta' => [],
'faja' => null,
'direcciones' => $direcciones,
'ivaReducido' => 1,
];
/*return $this->respond([
'status' => 400,
'message' => $dataToImport,
'interiorTipo' => $interiorTipo,
'isColor' => $isColor
]);*/
// 5. Guardar
try {
$presupuestocliente = new Presupuestocliente();
$response = $presupuestocliente->guardar($dataToImport);
// Guardar la URL de la portada y el cuerpo en los comentarios del presupuesto
$presupuestoModel = model('App\Models\Presupuestos\PresupuestoModel');
$presupuestoModel->update($response['sk_id'], [
'comentarios_safekat' => 'URL COVER: ' . $producto->cover->file . "\nURL BODY: " . $producto->body->file,
]);
// Ajuste del precio
$precio_compra = $json->producto->prices->unitPrice ?? null;
if ($precio_compra != null && $precio_compra > 0) {
$respuesta_ajuste = PresupuestoService::ajustarPresupuesto(
$response['sk_id'],
$precio_compra,
$tirada,
null,
true
);
if ($respuesta_ajuste['warning'] == true) {
$response['price_warning'] = [
'new_precio_unidad' => $respuesta_ajuste['new_precio_unidad'],
'new_total' => $respuesta_ajuste['new_total'],
];
}
}
// confirmar y crear pedido y ot
$presupuestoModel->confirmarPresupuesto($response['sk_id']);
PresupuestoService::crearPedido($response['sk_id'], isImported: true);
if (!isset($response['sk_id'])) {
return $this->respond([
'status' => 400,
'error' => 'Missing sk_id',
'message' => 'No se pudo crear el presupuesto.'
], 400);
}
// Descarga y subida de archivos al SFTP
$presupuestoFicheroModel = model('App\Models\Presupuestos\PresupuestoFicheroModel');
$ftp = new \App\Libraries\SafekatFtpClient();
$archivoUrls = [
'cover' => $producto->cover->file ?? null,
'body' => $producto->body->file ?? null,
];
foreach ($archivoUrls as $tipo => $url) {
if (!$url)
continue;
try {
$contenido = @file_get_contents($url); // silenciar errores de PHP
if ($contenido === false || strlen($contenido) === 0) {
// No se pudo descargar el archivo: generar archivo de error para FTP
$errorMessage = "ERROR: No se pudo descargar el archivo remoto para $tipo desde la URL: $url";
$remoteDir = $ftp->getPresupuestoRemotePath($response['sk_id']); // crea esta función si no existe
$remoteErrorFile = $remoteDir . '/ERROR_' . strtoupper($tipo) . '.txt';
// Crear archivo temporal con el mensaje de error
$tempErrorFile = WRITEPATH . 'uploads/presupuestos/ERROR_' . $tipo . '.txt';
file_put_contents($tempErrorFile, $errorMessage);
if (!$ftp->is_dir($remoteDir)) {
$ftp->mkdir($remoteDir, recursive: true);
}
$ftp->put($remoteErrorFile, $tempErrorFile, $ftp::SOURCE_LOCAL_FILE);
continue; // no procesar este archivo
}
// ✅ Procesar normalmente si la descarga tuvo éxito
$nombreOriginal = basename(parse_url($url, PHP_URL_PATH));
$extension = pathinfo($nombreOriginal, PATHINFO_EXTENSION);
$nombreLimpio = $presupuestoFicheroModel->saveFileInBBDD(
$response['sk_id'],
$nombreOriginal,
$extension,
auth()->id()
);
if (is_null($nombreLimpio))
continue;
$rutaLocal = WRITEPATH . 'uploads/presupuestos/';
if (!is_dir($rutaLocal)) {
mkdir($rutaLocal, 0777, true);
}
file_put_contents($rutaLocal . $nombreLimpio, $contenido);
} catch (\Throwable $e) {
//log_message('error', 'Error inesperado en descarga de archivo remoto: ' . $e->getMessage());
}
}
// Subir al FTP después de guardar localmente
try {
$ftp->uploadFilePresupuesto($response['sk_id']);
} catch (\Throwable $e) {
log_message('error', 'Error subiendo archivos al FTP: ' . $e->getMessage());
}
return $this->respond([
'status' => 200,
'data' => [
'sk_id' => $response['sk_id'],
'sk_url' => $response['sk_url'] ?? null
]
]);
} catch (\Throwable $e) {
return $this->respond([
'status' => 500,
'error' => 'Server error',
'message' => 'Error inesperado',
'debug' => $e->getMessage()
]);
}
}
}

View File

@ -0,0 +1,462 @@
<?php
namespace App\Controllers\Importadores;
use App\Controllers\BaseResourceController;
use App\Entities\Catalogo\CatalogoLibroEntity;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Catalogo\CatalogoLibroModel;
use App\Controllers\Presupuestos\Presupuestocliente;
use App\Services\PresupuestoService;
class ImportadorCatalogo extends BaseResourceController
{
protected $modelName = CatalogoLibroModel::class;
protected $format = 'json';
protected static $singularObjectName = 'Importador';
protected static $singularObjectNameCc = 'ImportadorCatalogo';
protected static $pluralObjectName = 'Importadores';
protected static $pluralObjectNameCc = 'importadores';
protected static $controllerSlug = 'importador';
protected static $viewPath = 'themes/vuexy/form/importador/catalogo/';
protected $indexRoute = 'ImportadorCatalogoTool';
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
{
$this->viewData['pageTitle'] = lang('Importador.listingPage');
$this->viewData['usingSweetAlert'] = true;
// Breadcrumbs (IMN)
$this->viewData['breadcrumb'] = [
['title' => lang("App.menu_importadores"), 'route' => "javascript:void(0);", 'active' => false],
['title' => lang("App.menu_importadores_catalogo"), 'route' => route_to('importadorCatalogoTool'), 'active' => true]
];
parent::initController($request, $response, $logger);
}
public function index()
{
checkPermission('importadores.catalogo');
$viewData = [
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
return view(static::$viewPath . 'viewImportadorCatalogoTool', $viewData);
}
public function validarFila()
{
checkPermission('importadores.catalogo');
$json = $this->request->getJSON();
// Validación inicial del JSON y del ISBN
if (!$json || !isset($json->fila[0]) || empty(trim($json->fila[0]))) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'ISBN no proporcionado o datos inválidos'
]);
}
$input = trim($json->fila[0]); // ISBN
$refCliente = isset($json->fila[1]) ? trim($json->fila[1]) : null;
// Validar formato del refCliente (esperado: idpedido-idlinea)
if (empty($refCliente) || strpos($refCliente, '-') === false) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'Ref. cliente inválido'
]);
}
// 1. Comprobar duplicado en tabla de presupuestos
$presupuestoModel = new PresupuestoModel(); // Usa el modelo real que corresponda
$yaExiste = $presupuestoModel->where('referencia_cliente', $refCliente)->first();
if ($yaExiste) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'Referencia ya importada'
]);
}
$catalogoModel = new CatalogoLibroModel();
// 2. Buscar por ISBN exacto
$libroPorIsbn = $catalogoModel->where('isbn', $input)->first();
if ($libroPorIsbn) {
return $this->response->setJSON([
'apto' => true
]);
}
// 3. Buscar por EAN sin guiones
$eanLimpio = str_replace('-', '', $input);
$libroPorEan = $catalogoModel
->where('REPLACE(ean, "-", "")', $eanLimpio, false) // false para evitar escapado automático
->first();
if ($libroPorEan) {
return $this->response->setJSON([
'apto' => true
]);
}
// 4. No encontrado
return $this->response->setJSON([
'apto' => false,
'reason' => 'No encontrado en catálogo'
]);
}
public function importarFila()
{
checkPermission('importadores.catalogo');
$json = $this->request->getJSON();
if (!$json || !isset($json->fila[0])) {
return $this->response->setJSON([
'success' => false,
'message' => 'Datos inválidos.'
]);
}
// Mapear cada columna a una variable (debe coincidir con catalogo_tool.js)
$isbn = isset($json->fila[0]) ? trim($json->fila[0]) : null;
$refCliente = isset($json->fila[1]) ? trim($json->fila[1]) : null;
$tirada = isset($json->fila[3]) ? (float) $json->fila[3] : null;
if (empty($isbn)) {
return $this->response->setJSON([
'success' => false,
'message' => 'Input vacío o no proporcionado.'
]);
}
// 0. Comprobar duplicado en tabla de presupuestos
$presupuestoModel = new PresupuestoModel(); // Usa el modelo real que corresponda
$yaExiste = $presupuestoModel->where('referencia_cliente', $refCliente)->first();
if ($yaExiste) {
return $this->response->setJSON([
'success' => false,
'message' => 'Referencia ya importada'
]);
}
$catalogoModel = new CatalogoLibroModel();
// 1. Buscar por ISBN exacto
$libro = $catalogoModel->where('isbn', $isbn)->first();
// 2. Si no, buscar por EAN sin guiones
if (!$libro) {
$eanLimpio = str_replace('-', '', $isbn);
$libro = $catalogoModel->where('REPLACE(ean, "-", "")', $eanLimpio)->first();
}
if (!$libro) {
return $this->response->setJSON([
'success' => false,
'message' => 'No se encontró el libro en el catálogo.'
]);
}
// Aquí ya tenemos el libro correcto.
// Ahora se prepara la "inserción" o el "registro" a importar
// Variables intermedias
$colorPaginas = (int) ($libro->color_paginas ?? 0);
$negroPaginas = (int) ($libro->negro_paginas ?? 0);
$papelInteriorDiferente = ($colorPaginas > 0 && $negroPaginas > 0) ? 1 : 0;
// --- Interior (lo que cambiamos ahora)
if ($papelInteriorDiferente) {
// Mixto: páginas en negro + color
$interior = [
'papelInterior' => [
'negro' => $libro->negro_papel_id,
'color' => $libro->color_papel_id,
],
'gramajeInterior' => [
'negro' => $libro->negro_gramaje,
'color' => $libro->color_gramaje,
]
];
} else {
// SOLO un tipo: negro O color
$colorPaginas = (int) ($libro->color_paginas ?? 0);
$negroPaginas = (int) ($libro->negro_paginas ?? 0);
if ($colorPaginas > 0 && $negroPaginas == 0) {
// Libro completamente en color
$interior = [
'papelInterior' => $libro->color_papel_id,
'gramajeInterior' => $libro->color_gramaje,
];
} else {
// Libro completamente en blanco y negro
$interior = [
'papelInterior' => $libro->negro_papel_id,
'gramajeInterior' => $libro->negro_gramaje,
];
}
}
// Sobrecubierta
$sobrecubierta = [];
if (!is_null($libro->sobrecubierta_paginas) && $libro->sobrecubierta_paginas != 0) {
$sobrecubierta['papel'] = $libro->sobrecubierta_papel_id;
$sobrecubierta['gramaje'] = $libro->sobrecubierta_gramaje;
$sobrecubierta['solapas'] = $libro->sobrecubierta_solapas;
$sobrecubierta['acabado'] = $libro->sobrecubierta_acabado_id;
}
// Recalcular calidad (isColor y isHq) en funcion del cliente
[$isColor, $isHq] = PresupuestoService::getCalidad(
'importador-rama',
null,
(in_array(strtolower($libro->tipo_impresion), ['color', 'colorhq']) ? 1 : 0),
(in_array(strtolower($libro->tipo_impresion), ['negrohq', 'colorhq']) ? 1 : 0),
intval($tirada ?? 0)
);
$dataToImport = [
'selectedTirada' => $tirada,
'datosCabecera' => [
'titulo' => $libro->titulo,
'autor' => $libro->autor,
'isbn' => $isbn,
'coleccion' => $libro->coleccion,
'referenciaCliente' => $refCliente
],
'tirada' => array_values(array_filter([
$tirada,
null,
null,
null,
])),
'tamanio' => [
'ancho' => $libro->ancho,
'alto' => $libro->alto
],
'tipo' => "",
'tipo_presupuesto_id' => $libro->encuadernacion_id,
'clienteId' => 251,
'isColor' => $isColor,
'isHq' => $isHq,
'paginas' => $libro->paginas,
'paginasColor' => $colorPaginas,
'papelInteriorDiferente' => $papelInteriorDiferente,
'paginasCuadernillo' => 32,
'interior' => $interior,
'cubierta' => [
'papelCubierta' => $libro->cubierta_papel_id,
'gramajeCubierta' => $libro->cubierta_gramaje,
'solapas' => $libro->cubierta_ancho_solapas,
'acabado' => $libro->cubierta_acabado_id,
'cabezada' => 'WHI',
'lomoRedondo' => 0
],
'ivaReducido' => 1,
'guardas' => [],
'sobrecubierta' => $sobrecubierta,
//'faja' => null,
'entrega_taller' => 1,
];
/*return $this->response->setJSON([
'success' => true,
'message' => 'Libro encontrado y preparado para importar.',
'data' => $dataToImport
]);*/
$tarifas = $this->obtenerTarifas();
$precioDesdeTarifa = $this->calcularPrecioDesdeTarifa(
$dataToImport['isColor'],
$libro->encuadernacion_id,
$libro->ancho,
$libro->alto,
$libro->paginas,
$tarifas
);
if (is_null($precioDesdeTarifa)) {
return $this->response->setJSON([
'success' => false,
'message' => 'No se pudo calcular el precio desde las tarifas disponibles.',
'detalle' => [
'tinta' => $dataToImport['isColor'] ? 'color' : 'negro',
'encuadernacion_id' => $libro->encuadernacion_id,
'ancho' => $libro->ancho,
'alto' => $libro->alto,
'paginas' => $libro->paginas
]
]);
}
// Usar precio calculado
$precio_compra = $precioDesdeTarifa;
// Procedemos a intentar guardar el presupuesto
// Instancia de presupuesto cliente
$presupuestocliente = new Presupuestocliente();
try {
$response = $presupuestocliente->guardar($dataToImport);
// DEBUG LINE
//return $this->respond($response);
if (!isset($response['sk_id'])) {
return $this->respond([
'status' => 400,
'error' => 'Missing sk_id',
'message' => 'El identificador sk_id es requerido pero no se recibió.'
], 400);
}
$response = [
'status' => 200,
'error' => null,
'data' => [
'sk_id' => $response['sk_id'],
'sk_url' => $response['sk_url'] ?? null
]
];
// Vincular el presupuesto con el catálogo
model('\App\Models\Presupuestos\PresupuestoModel')
->vincularCatalogo($response['data']['sk_id'], $libro->id);
// Ajuste del precio a RAMA
$respuesta_ajuste = PresupuestoService::ajustarPresupuesto(
$response['data']['sk_id'],
$precio_compra,
$tirada,
null,
true
);
if ($respuesta_ajuste['warning'] == true) {
$response['price_warning'] = [
'new_precio_unidad' => $respuesta_ajuste['new_precio_unidad'],
'new_total' => $respuesta_ajuste['new_total'],
];
}
// confirmar y crear pedido y ot
model('App\Models\Presupuestos\PresupuestoModel')->confirmarPresupuesto($response['data']['sk_id']);
PresupuestoService::crearPedido($response['data']['sk_id'], isImported: true);
return $this->respond($response);
} catch (\Exception $e) {
return $this->respond([
'status' => 500,
'error' => 'Server error',
'message' => 'Error inesperado durante el procesado',
'debug' => $e->getMessage()
]);
}
}
private function calcularPrecioDesdeTarifa($isColor, $encuadernacionId, $ancho, $alto, $paginas, $tarifas)
{
// Solo aplicamos tarifa si la encuadernación es Rústica Fresada (id = 2)
if ((int) $encuadernacionId !== 2) {
return null;
}
$tinta = $isColor ? 'color' : 'negro';
foreach ($tarifas as $tarifa) {
if (
strtolower($tarifa['tinta']) === $tinta &&
strtolower($tarifa['manipulado']) === 'rústica fresada' &&
(int) $tarifa['ancho'] === (int) $ancho &&
(int) $tarifa['alto'] === (int) $alto
) {
return round($tarifa['precio_fijo'] + ($tarifa['precio_variable'] * $paginas), 2);
}
}
return null; // No se encontró tarifa válida
}
private function obtenerTarifas()
{
return [
[
'tinta' => 'color',
'manipulado' => 'Rústica Fresada',
'ancho' => 200,
'alto' => 245,
'precio_fijo' => 1.15,
'precio_variable' => 0.076
],
[
'tinta' => 'negro',
'manipulado' => 'Rústica Fresada',
'ancho' => 200,
'alto' => 245,
'precio_fijo' => 1.15,
'precio_variable' => 0.009724
],
[
'tinta' => 'color',
'manipulado' => 'Rústica Fresada',
'ancho' => 150,
'alto' => 210,
'precio_fijo' => 1.15,
'precio_variable' => 0.03217
],
[
'tinta' => 'negro',
'manipulado' => 'Rústica Fresada',
'ancho' => 150,
'alto' => 210,
'precio_fijo' => 1.15,
'precio_variable' => 0.00572
],
[
'tinta' => 'negro',
'manipulado' => 'Rústica Fresada',
'ancho' => 170,
'alto' => 240,
'precio_fijo' => 1.15,
'precio_variable' => 0.008
]
];
}
}

View File

@ -39,4 +39,19 @@ class Language extends BaseController
}
}
public function file(string $file)
{
$locale = $this->request->getLocale(); // es, en, fr…
$path = APPPATH."Language/{$locale}/{$file}.php";
if (! is_file($path)) {
return $this->response->setStatusCode(404);
}
/** @var array $lines */
$lines = require $path; // el array que devuelve tu lang-file
return $this->response->setJSON($lines); // Content-Type: application/json
}
}

View File

@ -0,0 +1,467 @@
<?php
namespace App\Controllers\Logistica;
use App\Controllers\BaseController;
use App\Services\ImpresoraEtiquetaService;
use App\Services\EtiquetasTitulosService;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use Hermawan\DataTables\DataTable;
class EtiquetasTitulosController extends BaseController
{
protected ImpresoraEtiquetaService $impresoraEtiquetaService;
protected string $locale;
protected array $viewData;
protected static $controllerSlug = 'etiquetas_titulos';
protected static $viewPath = 'themes/vuexy/form/logistica/';
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->impresoraEtiquetaService = service('impresora_etiqueta');
$this->locale = session()->get('lang');
$this->model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$this->viewData['pageTitle'] = lang('Logistica.logistica');
// Breadcrumbs
$this->viewData['breadcrumb'] = [
['title' => lang("App.menu_logistica"), 'route' => route_to("LogisticaPanel"), 'active' => false],
];
parent::initController($request, $response, $logger);
}
public function findOTs()
{
if ($this->request->isAJAX()) {
$query = EtiquetasTitulosService::getOtsWithTitulos();
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("ot.id", $this->request->getGet("q"))
->orLike("pr.titulo)", $this->request->getGet("q"))
->groupEnd();
}
$result = $query->orderBy("id", "DESC")->get()->getResultObject();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function findAddresses()
{
if ($this->request->isAJAX()) {
$ot_id = $this->request->getGet("ot_id");
$query = EtiquetasTitulosService::getDireccionesOT($ot_id);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("pd.direccion", $this->request->getGet("q"))
->groupEnd();
}
$result = $query->orderBy("pd.direccion", "ASC")->get()->getResultObject();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function addEtiqueta()
{
if ($this->request->isAJAX()) {
$data = [];
$data['user_id'] = auth()->user()->id;
$data['ot_id'] = $this->request->getPost('ot_id') ?? null;
$data['direccion'] = $this->request->getPost('direccion') ?? null;
$data['unidades_caja'] = $this->request->getPost('unidades_caja') ?? null;
if (
$this->request->getPost('ot_id') == null ||
$this->request->getPost('direccion') == null ||
$this->request->getPost('unidades_caja') == null
) {
return [
'status' => false,
'message' => lang('Logistica.errorMissingData')
];
}
$result = EtiquetasTitulosService::addEtiqueta($data);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function deleteEtiqueta($id = null)
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id') ?? null;
if ($id == null) {
return [
'status' => false,
'message' => lang('Logistica.errorMissingData')
];
}
$modelLineas = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
$ids = $modelLineas->where('etiqueta_titulos_id', $id)->findColumn('id');
if ($ids) {
$modelLineas->delete($ids);
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$id = $model->where('id', $id)->findColumn('id');
if ($id) {
$model->delete($id);
}
$result = [
'status' => true,
'message' => lang('Logistica.success.jhn<successDeleteEtiqueta'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function edit($id = null)
{
if (empty($id)) {
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$etiquetaEntity = $model->select('etiquetas_titulos.*, clientes.nombre as cliente')
->join('clientes', 'clientes.id = etiquetas_titulos.cliente_id', 'left')
->where('etiquetas_titulos.id', $id)
->first();
if (empty($etiquetaEntity)) {
return redirect()->to(base_url('logistica/etiquetasLogistica'))->with('error', lang('Logistica.errors.noEnvio'));
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresoras = $modelImpresora->select('id, name, description')
->where('deleted_at', null)
->where('tipo', 1)
->orderBy('name', 'asc')
->findAll();
$etiquetaEntity->impresoras = $impresoras;
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => '<i class="ti ti-ticket ti-xl"></i>' . ' ' . lang('Logistica.EtiquetasTitulos') . ' [' . $etiquetaEntity->id . ']: ' . $etiquetaEntity->direccion,
'usingServerSideDataTable' => true,
'etiquetaEntity' => $etiquetaEntity,
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
return view(static::$viewPath . 'viewEtiquetasTitulosEdit', $viewData);
}
public function datatable()
{
$q = $this->model->getEtiquetasTitulos();
if (!empty($otsFilter)) {
$q->groupStart();
$q->like('etl.ot_id', $otsFilter);
$q->groupEnd();
}
$result = DataTable::of($q)
->add("action", callback: function ($q) {
return '
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete" data-id="' . $q->id . '"></i></a>
</div>
';
});
return $result->toJson(returnAsObject: true);
}
public function findOtsWithAddress()
{
if ($this->request->isAJAX()) {
$id = $this->request->getGet('id') ?? null;
$query = EtiquetasTitulosService::findOTsWithAddress($id);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("name", $this->request->getGet("q"))
->groupEnd();
}
$result = $query->orderBy("id", "DESC")->get()->getResultObject();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function addLineasEtiqueta()
{
if ($this->request->isAJAX()) {
$etiqueta_id = $this->request->getPost('etiqueta_id') ?? null;
$ot_id = $this->request->getPost('ot_id') ?? null;
$unidades = $this->request->getPost('unidades') ?? null;
$cajas = $this->request->getPost('cajas') ?? null;
$result = EtiquetasTitulosService::addLineasEtiqueta($etiqueta_id, $ot_id, $unidades, $cajas);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function datatableLineasEtiquetas($id = null)
{
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
$id = $this->request->getGet('id') ?? null;
$direccion = $this->request->getGet('direccion') ?? null;
$q = $model->getDatatableQuery($id, $direccion);
$result = DataTable::of($q)
->add(
"rowSelected",
callback: function ($q) {
return '<input type="checkbox" class="form-check-input checkbox-linea-envio" name="row_selected[]" value="' . $q->id . '">';
}
)
->edit(
"ot",
function ($row, $meta) {
return '<a href="' . base_url('produccion/ordentrabajo/edit/' . $row->ot) . '" target="_blank">' . $row->ot . '</a>';
}
)
->edit(
"unidades",
function ($row, $meta) {
return '<input type="number" class="form-control input-lineas input-unidades text-center"
data-id="' . $row->id . '" data-name="unidades" value="' . $row->unidades . '">';
}
)
->edit(
"numero_caja",
function ($row, $meta) {
return '<input type="number" class="form-control input-lineas input-cajas text-center"
data-id="' . $row->id . '" data-name="numero_caja" value="' . $row->numero_caja . '">';
}
)
->add("unidades_raw", fn($row) => $row->unidades)
->add("pesoUnidad_raw", fn($row) => $row->pesoUnidad)
->add(
"action",
callback: function ($q) {
return '
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete" data-id="' . $q->id . '"></i></a>
</div>
';
}
);
return $result->toJson(returnAsObject: true);
}
public function deleteLineasEtiqueta()
{
if ($this->request->isAJAX()) {
$ids = $this->request->getPost('ids') ?? [];
if ($ids == [] || $ids == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
for ($i = 0; $i < count($ids); $i++) {
$model->delete($ids[$i]);
}
$result = [
'status' => true,
'message' => lang('Logistica.success.successDeleteLines'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function updateLineasEtiqueta()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id') ?? null;
$name = $this->request->getPost('name') ?? null;
$value = $this->request->getPost('value') ?? null;
if ($id == null || $name == null || $value == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
$model->update($id, [$name => $value]);
$result = [
'status' => true,
'message' => lang('Logistica.success.successUpdateLine'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function updateComentarios()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id') ?? null;
$comentarios = $this->request->getPost('comentarios') ?? null;
if ($id == null || $comentarios == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosModel');
$model->update($id, ['comentarios' => $comentarios]);
$result = [
'status' => true,
'message' => lang('Logistica.success.comentariosUpdated'),
];
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function updateOrdenCajas()
{
$rawInput = $this->request->getBody();
$data = json_decode($rawInput, true);
$orden = $data['orden'] ?? [];
if (!is_array($orden)) {
return $this->response->setJSON([
'status' => false,
'message' => 'Datos inválidos'
]);
}
$model = model('App\Models\Etiquetas\EtiquetasTitulosLineasModel');
foreach ($orden as $item) {
if (isset($item['id'], $item['numero_caja'])) {
$model->update($item['id'], [
'numero_caja' => $item['numero_caja'],
'updated_at' => date('Y-m-d H:i:s') // opcional
]);
}
}
return $this->response->setJSON([
'status' => true,
'message' => 'Orden de cajas actualizado correctamente'
]);
}
public function renumberCajas()
{
$id = $this->request->getPost('id') ?? null;
if ($id == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$result = EtiquetasTitulosService::reordenarCajas($id);
return $this->response->setJSON($result);
}
public function imprimirEtiquetas()
{
$etiqueta_id = $this->request->getPost('etiqueta_id') ?? null;
$ids = $this->request->getPost('ids') ?? [];
$impresora_id = $this->request->getPost('impresora_id') ?? null;
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name, description, ip, port, user, pass')
->where('deleted_at', null)
->where('id', $impresora_id)
->orderBy('name', 'asc')
->first();
if ($impresora == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Impresora no válida'
]);
}
if ($etiqueta_id == null || $ids == []) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$result = EtiquetasTitulosService::imprimirEtiquetas($etiqueta_id, $ids, $impresora);
return $this->response->setJSON($result);
}
}

View File

@ -44,6 +44,8 @@ class LogisticaController extends BaseController
public function panel()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.panel'),
@ -58,10 +60,13 @@ class LogisticaController extends BaseController
public function gestionEnvios()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.gestionEnvios'),
'usingServerSideDataTable' => true,
'tipo_envio' => 'estandar',
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
@ -69,7 +74,42 @@ class LogisticaController extends BaseController
return view(static::$viewPath . 'viewLogisticaSelectEnvios', $viewData);
}
public function listAlbaranes(){
public function gestionEnviosFerros()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.envioFerros'),
'usingServerSideDataTable' => true,
'tipo_envio' => 'ferro_prototipo',
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
return view(static::$viewPath . 'viewLogisticaSelectEnvios', $viewData);
}
public function etiquetasLogistica()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.etiquetasTitulos'),
'usingServerSideDataTable' => true,
];
$viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
return view(static::$viewPath . 'viewImpresionEtiquetas', $viewData);
}
public function listAlbaranes()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Albaran.albaranes'),
@ -85,7 +125,14 @@ class LogisticaController extends BaseController
{
if ($this->request->isAJAX()) {
$query = LogisticaService::findForNewEnvio();
$tipo_envio = $this->request->getGet('tipo_envio') ?? 'estandar';
if ($tipo_envio == 'ferro_prototipo') {
$query = LogisticaService::findForNewEnvioFerro();
} else {
$query = LogisticaService::findForNewEnvio();
}
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("id", $this->request->getGet("q"))
@ -96,22 +143,25 @@ class LogisticaController extends BaseController
$result = $query->orderBy("name", "asc")->get()->getResultObject();
$query = model('App\Models\Logistica\EnvioModel')->db->getLastQuery();
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function selectDireccionForEnvio(){
public function selectDireccionForEnvio()
{
if ($this->request->isAJAX()) {
$pedido_id = $this->request->getGet('pedido_id');
if($pedido_id == null || $pedido_id == 0){
$ot = $this->request->getGet('ot_id');
if ($ot == null || $ot == 0) {
return [];
}
$searchVal = $this->request->getGet("q") ?? "";
$result = LogisticaService::findDireccionesNewEnvio($pedido_id, $searchVal);
$result = LogisticaService::findDireccionesNewEnvio($ot, $searchVal);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
@ -124,9 +174,22 @@ class LogisticaController extends BaseController
{
if ($this->request->isAJAX()) {
$pedido_id = $this->request->getPost('pedido_id');
$direccion = $this->request->getPost('direccion');
$result = LogisticaService::generateEnvio($pedido_id, $direccion);
$ot_id = $this->request->getPost('ot_id');
$direccion = $this->request->getPost('direccion') ?? "";
$result = LogisticaService::generateEnvio($ot_id, $direccion);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function generarEnvioFerro()
{
if ($this->request->isAJAX()) {
$ot_id = $this->request->getPost('ot_id');
$result = LogisticaService::generateEnvioFerro($ot_id);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
@ -136,12 +199,12 @@ class LogisticaController extends BaseController
public function imprimirEtiquetas()
{
if ($this->request->isAJAX()) {
$envio_id = $this->request->getPost('envio_id');
$envio_id = $this->request->getPost('envio_id');
$ids = $this->request->getPost('envio_lineas');
$cajas = $this->request->getPost('cajas');
$printer_id = $this->request->getPost('printer_id');
if($cajas == null || $cajas == 0){
if ($cajas == null || $cajas == 0) {
return $this->response->setJSON([
'status' => false,
'message' => 'Cajas no válidas'
@ -153,7 +216,7 @@ class LogisticaController extends BaseController
->join('clientes', 'clientes.id = envios.cliente_id', 'left')
->where('envios.id', $envio_id)
->first();
if($envio == null){
if ($envio == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Envio no válido'
@ -164,7 +227,7 @@ class LogisticaController extends BaseController
$lineas = $model->select('envios_lineas.*, presupuestos.titulo as titulo, presupuestos.referencia_cliente as referencia_cliente')
->join('presupuestos', 'presupuestos.id = envios_lineas.presupuesto_id', 'left')
->whereIn('envios_lineas.id', $ids)->findAll();
if($lineas == null){
if ($lineas == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Lineas no válidas'
@ -172,12 +235,12 @@ class LogisticaController extends BaseController
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name')
$impresora = $modelImpresora->select('id, name, description, ip, port, user, pass')
->where('deleted_at', null)
->where('id', $printer_id)
->orderBy('name', 'asc')
->first();
if($impresora == null){
if ($impresora == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Impresora no válida'
@ -233,9 +296,10 @@ class LogisticaController extends BaseController
{
$otsFilter = $this->request->getGetPost('otsFilter');
$tipo_envio = $this->request->getGetPost('tipo_envio') ?? 'estandar';
$model = model('App\Models\Logistica\EnvioModel');
$q = $model->getDatatableQuery();
$q = $model->getDatatableQuery($tipo_envio);
if (!empty($otsFilter)) {
$q->groupStart();
@ -280,19 +344,19 @@ class LogisticaController extends BaseController
if (empty($envioEntity)) {
return redirect()->to(base_url('logistica/selectEnvios/simple'))->with('error', lang('Logistica.errors.noEnvio'));
}
$modelProveedor = model('App\Models\Compras\ProveedorModel');
$proveedor = $modelProveedor->select('id, nombre')
->where('deleted_at', null)
->where('id', $envioEntity->proveedor_id)
->orderBy('nombre', 'asc')
->first();
if(!empty($proveedor)){
if (!empty($proveedor)) {
$envioEntity->proveedor_nombre = $proveedor->nombre;
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresoras = $modelImpresora->select('id, name')
$impresoras = $modelImpresora->select('id, name, description')
->where('deleted_at', null)
->where('tipo', 1)
->orderBy('name', 'asc')
@ -334,7 +398,7 @@ class LogisticaController extends BaseController
$id = $this->request->getPost('id') ?? null;
$finalizar_ots = $this->request->getPost('finalizar_ots') ?? false;
$result = LogisticaService::finalizarEnvio($id, $finalizar_ots);
return $this->response->setJSON($result);
} else {
@ -342,6 +406,17 @@ class LogisticaController extends BaseController
}
}
public function ficharEmbalaje()
{
if ($this->request->isAJAX()) {
$ids = $this->request->getPost('ids') ?? [];
$result = LogisticaService::ficharEmbalaje($ids);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function datatable_enviosEdit($idEnvio)
{
@ -356,6 +431,12 @@ class LogisticaController extends BaseController
return '<input type="checkbox" class="form-check-input checkbox-linea-envio" name="row_selected[]" value="' . $q->id . '">';
}
)
->edit(
"ordenTrabajo",
function ($row, $meta) {
return '<a href="' . base_url('produccion/ordentrabajo/edit/' . $row->ordenTrabajo) . '" target="_blank">' . $row->ordenTrabajo . '</a>';
}
)
->edit(
"pedido",
function ($row, $meta) {
@ -370,17 +451,35 @@ class LogisticaController extends BaseController
)->edit(
"unidadesEnvio",
function ($row, $meta) {
if($row->finalizado == 1){
if ($row->finalizado == 1 || $row->tipo_envio == 'ferro_prototipo') {
return $row->unidadesEnvio;
}
return '<input type="number" class="form-control input-lineas input-unidades text-center"
data-id="'. $row->id.'" data-name="unidades_envio" value="' . $row->unidadesEnvio . '">';
data-id="' . $row->id . '" data-name="unidades_envio" value="' . $row->unidadesEnvio . '">';
}
);
return $result->toJson(returnAsObject: true);
}
public function datatable_proximosEnvios($envio_id = null)
{
$q = LogisticaService::findNextEnvios($envio_id);
$result = DataTable::of($q)
->edit(
"ot",
function ($row, $meta) {
return '<a href="' . base_url('produccion/ordentrabajo/edit/' . $row->ot) . '" target="_blank">' . $row->ot . '</a>';
}
);
$result = $result->toJson(returnAsObject: true);
$query = model('App\Models\Logistica\EnvioModel')->db->getLastQuery();
return $result;
}
public function setCajaLinea()
{
@ -421,7 +520,7 @@ class LogisticaController extends BaseController
$fieldName = $this->request->getPost('name');
$fieldValue = $this->request->getPost('value');
if (!$id || !$fieldName || ($fieldName=='unidades_envio' && !$fieldValue)) {
if (!$id || !$fieldName || ($fieldName == 'unidades_envio' && !$fieldValue)) {
return $this->response->setJSON([
'status' => false,
'message' => 'Datos inválidos'
@ -430,7 +529,7 @@ class LogisticaController extends BaseController
$model = model('App\Models\Logistica\EnvioLineaModel');
$updated = $model->update($id, [
"" . $fieldName => $fieldValue==""? null: $fieldValue,
"" . $fieldName => $fieldValue == "" ? null : $fieldValue,
]);
return $this->response->setJSON([
@ -453,7 +552,7 @@ class LogisticaController extends BaseController
$model = model('App\Models\Logistica\EnvioModel');
$updated = $model->update($id, [
"codigo_seguimiento" => $fieldValue==""? null: $fieldValue,
"codigo_seguimiento" => $fieldValue == "" ? null : $fieldValue,
]);
return $this->response->setJSON([
@ -476,7 +575,7 @@ class LogisticaController extends BaseController
$model = model('App\Models\Logistica\EnvioModel');
$updated = $model->update($id, [
"proveedor_id" => $fieldValue==""? null: $fieldValue,
"proveedor_id" => $fieldValue == "" ? null : $fieldValue,
]);
return $this->response->setJSON([

View File

@ -71,4 +71,55 @@ class PrintAlbaranes extends BaseController
->setHeader('Content-Length', strlen($output))
->setBody($output);
}
public function generarAnonimo($albaran_id)
{
// Cargar modelos
$albaranModel = model('App\Models\Albaranes\AlbaranModel');
$lineasAlbaranModel = model('App\Models\Albaranes\AlbaranLineaModel');
// Informacion del presupuesto
$data['albaran'] = $albaranModel->getResourceForPdf($albaran_id)->get()->getRow();
$data['albaranLineas'] = $lineasAlbaranModel->getResourceForPdf($albaran_id)->get()->getResultObject();
// Obtener contenido HTML de la vista
$html = view(getenv('theme.path') . 'pdfs/albaran-anonimo', $data);
// Cargar CSS desde archivo local
$css = file_get_contents(FCPATH . 'themes/vuexy/css/pdf.albaran.css');
// Combinar CSS y HTML
$html_con_css = "<style>$css</style>" . $html;
// Crear una instancia de Dompdf
$options = new \Dompdf\Options();
$options->set('isHtml5ParserEnabled', true);
$options->set('isPhpEnabled', true);
$options->set('isRemoteEnabled', true);
$dompdf = new \Dompdf\Dompdf($options);
// Contenido HTML del documento
$dompdf->loadHtml($html_con_css);
// Establecer el tamaño del papel
$dompdf->setPaper('A4', 'portrait');
// Renderizar el PDF
$dompdf->render();
// Obtener el contenido generado
$output = $dompdf->output();
// Establecer las cabeceras para visualizar en lugar de descargar
$file_name = "alabaran-$albaran_id.pdf";
return $this->response
->setStatusCode(200)
->setHeader('Content-Type', 'application/pdf')
->setHeader('Content-Disposition', 'inline; filename="' . $file_name . '"')
->setHeader('Cache-Control', 'private, max-age=0, must-revalidate')
->setHeader('Pragma', 'public')
->setHeader('Content-Length', strlen($output))
->setBody($output);
}
}

View File

@ -12,7 +12,7 @@ use Hermawan\DataTables\DataTable;
use CodeIgniter\I18n\Time;
class Pedido extends \App\Controllers\BaseResourceController
{
{
protected $modelName = PedidoModel::class;
protected $format = 'json';
@ -29,9 +29,9 @@ class Pedido extends \App\Controllers\BaseResourceController
{
$this->viewData['pageTitle'] = lang('Pedidos.moduleTitle');
// Se indica que este controlador trabaja con soft_delete
$this->viewData = ['usingServerSideDataTable' => true];
// Breadcrumbs
$this->viewData['breadcrumb'] = [
['title' => lang("App.menu_pedidos"), 'route' => "javascript:void(0);", 'active' => false],
@ -169,7 +169,7 @@ class Pedido extends \App\Controllers\BaseResourceController
public function todos()
{
$viewData = [
'currentModule' => static::$controllerSlug,
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Pedidos.pedido')]),
@ -195,21 +195,23 @@ class Pedido extends \App\Controllers\BaseResourceController
}
public function cambiarEstado(){
if($this->request->isAJAX()){
public function cambiarEstado()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id');
$estado = $this->request->getPost('estado');
$this->model->where('id', $id)->set(['estado' => $estado])->update();
return $this->respond(['status' => 'success', 'message' => lang('Basic.global.success')]);
}else{
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function update($id = null){
public function update($id = null)
{
$data = [];
@ -217,7 +219,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$newTokenHash = csrf_hash();
$csrfTokenName = csrf_token();
if ($id == null) :
if ($id == null):
$data = [
'error' => 2,
$csrfTokenName => $newTokenHash
@ -227,7 +229,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$id = filter_var($id, FILTER_SANITIZE_URL);
$pedidoEntity = $this->model->find($id);
if ($pedidoEntity == false) :
if ($pedidoEntity == false):
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.pedido')), $id]);
$data = [
'error' => $message,
@ -236,19 +238,19 @@ class Pedido extends \App\Controllers\BaseResourceController
return $this->respond($data);
endif;
if ($this->request->getPost()) :
if ($this->request->getPost()):
$nullIfEmpty = true; // !(phpversion() >= '8.1');
$postData = $this->request->getPost();
$sanitizedData = $this->sanitized($postData, $nullIfEmpty);
foreach(array_keys($sanitizedData) as $key){
if(str_starts_with($key, "fecha_")){
$sanitizedData[$key . "_change_user_id"] =
foreach (array_keys($sanitizedData) as $key) {
if (str_starts_with($key, "fecha_")) {
$sanitizedData[$key . "_change_user_id"] =
auth()->user()->id;
$data[$key . "_change_user"] =
$data[$key . "_change_user"] =
model('App\Models\Usuarios\UserModel')->getFullName(auth()->user()->id);
}
}
@ -256,9 +258,9 @@ class Pedido extends \App\Controllers\BaseResourceController
$sanitizedData['user_updated_id'] = auth()->user()->id;
$noException = true;
if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :
if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) :
if ($this->canValidate()) :
if ($this->canValidate()):
try {
$successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData);
} catch (\Exception $e) {
@ -274,7 +276,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$pedidoEntity->fill($sanitizedData);
endif;
if ($noException && $successfulResult) :
if ($noException && $successfulResult):
$id = $pedidoEntity->id ?? $id;
$message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.';
@ -291,39 +293,39 @@ class Pedido extends \App\Controllers\BaseResourceController
$csrfTokenName => $newTokenHash
];
return $this->respond($data);
}
else {
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function edit($id=null){
if ($id == null) :
public function edit($id = null)
{
if ($id == null):
return $this->redirect2listView();
endif;
$id = filter_var($id, FILTER_SANITIZE_URL);
$pedidoEntity = $this->model->find($id);
if ($pedidoEntity == false) :
if ($pedidoEntity == false):
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Pedidos.pedido')), $id]);
return $this->redirect2listView('sweet-error', $message);
endif;
$this->obtenerDatosFormulario($pedidoEntity);
$pedidoEntity->fecha_entrega_real_change_user = $pedidoEntity->fecha_entrega_real_change_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_real_change_user_id):"";
$pedidoEntity->fecha_impresion_change_user = $pedidoEntity->fecha_impresion_change_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_impresion_change_user_id):"";
$pedidoEntity->fecha_encuadernado_change_user = $pedidoEntity->fecha_encuadernado_change_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_encuadernado_change_user_id):"";
$pedidoEntity->fecha_entrega_change_externo_user = $pedidoEntity->fecha_entrega_change_externo_user_id?model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_change_externo_user_id):"";
$pedidoEntity->fecha_entrega_real_change_user = $pedidoEntity->fecha_entrega_real_change_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_real_change_user_id) : "";
$pedidoEntity->fecha_impresion_change_user = $pedidoEntity->fecha_impresion_change_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_impresion_change_user_id) : "";
$pedidoEntity->fecha_encuadernado_change_user = $pedidoEntity->fecha_encuadernado_change_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_encuadernado_change_user_id) : "";
$pedidoEntity->fecha_entrega_change_externo_user = $pedidoEntity->fecha_entrega_change_externo_user_id ? model('App\Models\Usuarios\UserModel')->
getFullName($pedidoEntity->fecha_entrega_change_externo_user_id) : "";
$this->viewData['pedidoEntity'] = $pedidoEntity;
if($pedidoEntity->estado == 'validacion'){
if ($pedidoEntity->estado == 'validacion') {
$clienteModel = model('App\Models\Clientes\ClienteModel');
$pendiente = $clienteModel->getPendienteCobro($pedidoEntity->cliente_id);
$pendiente = $pendiente[0] + $pendiente[1];
@ -332,24 +334,25 @@ class Pedido extends \App\Controllers\BaseResourceController
$modelOrden = new \App\Models\OrdenTrabajo\OrdenTrabajoModel();
$orden = $modelOrden->where('pedido_id', $pedidoEntity->id)->first();
if($orden){
if ($orden) {
$this->viewData['orden_id'] = $orden->id;
}
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Pedidos.moduleTitle') . ' ' . lang('Basic.global.edit3');
return $this->displayForm(__METHOD__, $id);
}
public function datatable(){
public function datatable()
{
if ($this->request->isAJAX()) {
$reqData = $this->request->getPost();
if (!isset($reqData['draw']) || !isset($reqData['columns']) ) {
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
$errstr = 'No data available in response to this specific request.';
$response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr);
$response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
return $response;
}
$start = $reqData['start'] ?? 0;
@ -360,7 +363,8 @@ class Pedido extends \App\Controllers\BaseResourceController
$dir = $reqData['order']['0']['dir'] ?? 'asc';
$estado = $reqData['estado'] ?? 'todos';
$cliente_id = $reqData['cliente_id'] ?? -1;
if($estado == 'todos') $estado = '';
if ($estado == 'todos')
$estado = '';
$showTotal = $reqData['showTotal'] ?? false;
@ -373,7 +377,7 @@ class Pedido extends \App\Controllers\BaseResourceController
$extra_data['total_tirada'] = $totalTirada;
$extra_data['total'] = $total;
$total2 = 0;
if($showTotal){
if ($showTotal) {
$total2 = $model_linea->getTotalOfTotalAceptado($estado);
$tirada2 = $model_linea->getTotalTirada($estado);
$extra_data['total2'] = $total2;
@ -422,11 +426,11 @@ class Pedido extends \App\Controllers\BaseResourceController
$result = DataTable::of($q)
->edit(
'fecha',
fn($q) => $q->fecha?Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y"):""
fn($q) => $q->fecha ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y") : ""
)
->edit(
'fecha_entrega',
fn($q) => $q->fecha_entrega?Time::createFromFormat("Y-m-d H:i:s", $q->fecha_entrega)->format("d/m/Y"):""
fn($q) => $q->fecha_entrega ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_entrega)->format("d/m/Y") : ""
)
->edit(
"estado",
@ -453,13 +457,14 @@ class Pedido extends \App\Controllers\BaseResourceController
<a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
</div>
';
});
return $result->toJson(returnAsObject: true) ;
return $result->toJson(returnAsObject: true);
}
public function obtenerTotalPedidosCliente($cliente_id){
public function obtenerTotalPedidosCliente($cliente_id)
{
$error = false;
$result = [
@ -472,37 +477,37 @@ class Pedido extends \App\Controllers\BaseResourceController
->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id')
->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id')
->groupBy('presupuestos.cliente_id')->get()->getResultObject();
if(count($data) > 0){
if (count($data) > 0) {
$result['total_impresion'] = round(floatval($data[0]->total), 2);
}
else{
} else {
$error = true;
}
$result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
return $this->respond(['status' => $error ? 'error' : 'success', 'totales' => $result]);
}
public function obtenerPedidosForFacturas(){
public function obtenerPedidosForFacturas()
{
if ($this->request->isAJAX()) {
$reqData = $this->request->getPost();
$start = $reqData['start'] ?? 0;
}
else {
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function getlineas(){
public function getlineas()
{
if ($this->request->isAJAX()) {
$reqData = $this->request->getPost();
if (!isset($reqData['draw']) || !isset($reqData['columns']) ) {
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
$errstr = 'No data available in response to this specific request.';
$response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr);
$response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
return $response;
}
$id = $reqData['pedido_id'] ?? 0;
$resourceData = $this->model->obtenerLineasPedido($id);
@ -517,25 +522,26 @@ class Pedido extends \App\Controllers\BaseResourceController
}
public function addFactura(){
public function addFactura()
{
if ($this->request->isAJAX()) {
if($this->request->isAJAX()){
$modelFactura = model('App\Models\Facturas\FacturaModel');
$modelFacturaLinea = model('App\Models\Facturas\FacturaLineaModel');
$pedido_id = $this->request->getPost('pedido_id');
$serie_id = $this->request->getPost('serie_id');
$datosFactura = $this->model->obtenerDatosForFactura($pedido_id);
if(count($datosFactura) == 0){
if (count($datosFactura) == 0) {
return $this->respond(['status' => 'error', 'message' => 'Error obteniendo datos de factura']);
}
$datosFactura = $datosFactura[0];
$modelFactura->insert([
'cliente_id' => $datosFactura->cliente_id,
'serie_id' => $serie_id,
@ -555,13 +561,13 @@ class Pedido extends \App\Controllers\BaseResourceController
$factura_id = $modelFactura->getInsertID();
if($factura_id){
if ($factura_id) {
$model_pedido_linea = model('\App\Models\Pedidos\PedidoLineaModel');
$lineas = $model_pedido_linea->where('pedido_id', $pedido_id)->first();
$facturas = new Facturas();
$result = $facturas->addLineaPedidoImpresion($factura_id, $lineas->id);
if($result['error'] == 0){
if ($result['error'] == 0) {
// Se actualiza el precio total de la factura obtenido de la linea añadida
$linea_added = $modelFacturaLinea->where('factura_id', $factura_id)->first();
$modelFactura->set([
@ -570,27 +576,28 @@ class Pedido extends \App\Controllers\BaseResourceController
'pendiente' => $linea_added->total,
])->where('id', $factura_id)->update();
return $this->respond(['status' => 'success', 'id' => $factura_id, 'message' => lang('Basic.global.success')]);
}else{
} else {
return $this->respond(['status' => 'error', 'message' => 'Error insertando lineas de factura']);
}
}
return $this->respond(['status' => 'error', 'message' => 'Error insertando factura']);
}else{
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
private function obtenerDatosFormulario(&$pedidoEntity){
private function obtenerDatosFormulario(&$pedidoEntity)
{
$datos = $this->model->obtenerDatosForm($pedidoEntity->id);
$pedidoEntity->estadoText = lang('Pedidos.' . $pedidoEntity->estado);
if(count($datos) > 0){
if (count($datos) > 0) {
$pedidoEntity->cliente = $datos[0]->cliente;
$pedidoEntity->cliente_id = $datos[0]->cliente_id;
$pedidoEntity->comercial = $datos[0]->comercial;
@ -602,8 +609,8 @@ class Pedido extends \App\Controllers\BaseResourceController
$pedidoEntity->fecha_entrega_externo_text = $pedidoEntity->fecha_entrega_externo ? date('d/m/Y', strtotime($pedidoEntity->fecha_entrega_externo)) : '';
$userModel = model('App\Models\Usuarios\UserModel');
$pedidoEntity->created_by = $userModel->getFullName($pedidoEntity->user_created_id);
$pedidoEntity->updated_by = $userModel->getFullName($pedidoEntity->user_updated_id);
$pedidoEntity->created_by = $userModel->getFullName($pedidoEntity->user_created_id);
$pedidoEntity->updated_by = $userModel->getFullName($pedidoEntity->user_updated_id);
$pedidoEntity->created_at_footer = $pedidoEntity->created_at ? date(' H:i d/m/Y', strtotime($pedidoEntity->created_at)) : '';
$pedidoEntity->updated_at_footer = $pedidoEntity->updated_at ? date(' H:i d/m/Y', strtotime($pedidoEntity->updated_at)) : '';
}
@ -613,21 +620,36 @@ class Pedido extends \App\Controllers\BaseResourceController
// $xml_service = new PedidoXMLService($this->model);
return $this->respond($data);
}
public function to_produccion($pedido_id)
{
$serviceProduction = service('production');
$pedido = $this->model->find($pedido_id);
$cliente = $pedido->presupuesto()->cliente_id;
$serviceProduction->setPedido($pedido);
if($pedido->orden_trabajo()){
return $this->response->setJSON(["status"=>false,"data"=>$pedido->orden_trabajo(),"message" => "Ya existe una orden de trabajo para este pedido"]);
if ($pedido->orden_trabajo()) {
return $this->response->setJSON(["status" => false, "data" => $pedido->orden_trabajo(), "message" => "Ya existe una orden de trabajo para este pedido"]);
}else{
} else {
$r = $serviceProduction->createOrdenTrabajo();
$this->model->set(['estado' => 'produccion'])->where('id', $pedido_id)->update();
return $this->response->setJSON(["status"=>true, "data"=>$r,"message" => "Orden trabajo creada correctamente"]);
$clienteModel = model('App\Models\Clientes\ClienteModel');
$cliente = $clienteModel->find($cliente);
if ($cliente) {
if ($cliente->tirada_flexible == 1) {
$ejemplares_tirada_flexible = intval($pedido->total_tirada * 0.05);
$comentario = lang('OrdenTrabajo.tiradaFlexible', [
'unidades' => $ejemplares_tirada_flexible
]) . "\n" . trim($cliente->comentarios_tirada_flexible);
$serviceProduction->init($r->id)->updateOrdenTrabajoData([
'name' => 'comment_logistica',
'comment_logistica' => $comentario
]);
}
}
return $this->response->setJSON(["status" => true, "data" => $r, "message" => "Orden trabajo creada correctamente"]);
}
}
}

View File

@ -4,6 +4,7 @@ namespace App\Controllers\Presupuestos;
use App\Models\Presupuestos\ImportadorModel;
use App\Models\Clientes\ClienteModel;
use App\Services\PresupuestoService;
use stdClass;
class Importadorpresupuestos extends \App\Controllers\BaseResourceController
@ -484,6 +485,14 @@ class Importadorpresupuestos extends \App\Controllers\BaseResourceController
$isColor = true;
}
// se recalcula isColor y isHq
[$isColor, $isHq] = PresupuestoService::getCalidad(
'admin',
null,
$isColor,
$isHq,
intval($this->request->getPost('tirada') ?? 0));
$tapaCubierta = model('App\Models\Configuracion\TipoPresupuestoModel')->
select("is_tapa_dura")->where('id', $tipo_presupuesto_id)->first();
$tapaCubierta = $tapaCubierta->is_tapa_dura == 0 ? "tapaBlanda" : "tapaDura";

View File

@ -130,11 +130,10 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$POD = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('POD')->value;
$ancho = 0;
$alto = 0;
if(isset($sanitizedData['papel_formato_personalizado']) && $sanitizedData['papel_formato_personalizado'] == '1'){
if (isset($sanitizedData['papel_formato_personalizado']) && $sanitizedData['papel_formato_personalizado'] == '1') {
$ancho = $sanitizedData['papel_formato_ancho'];
$alto = $sanitizedData['papel_formato_alto'];
}
else{
} else {
$papelFormatoModel = new PapelFormatoModel();
$papelFormato = $papelFormatoModel->find($sanitizedData['papel_formato_id']);
$ancho = $papelFormato->ancho;
@ -152,7 +151,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
]);
$model = new PresupuestoEncuadernacionesModel();
foreach($servDefectoEnc as $servicio){
foreach ($servDefectoEnc as $servicio) {
$data = [
'presupuesto_id' => $id,
@ -202,6 +201,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$this->viewData['pais_default_id'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_pais_defecto')->value;
$this->viewData['pais_default'] = model('App\Models\Configuracion\PaisModel')->find($this->viewData['pais_default_id'])->nombre;
$this->viewData['no_envio_base'] = 0;
$this->viewData['formAction'] = route_to('createPresupuestoAdmin', $tipo_impresion_id);
$this->viewData = array_merge($this->viewData, $this->getStringsFromTipoImpresion($tipo_impresion_id));
@ -236,12 +237,14 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$postData = $this->request->getPost();
$postData['updated_at'] = gmdate('Y-m-d H:m:s', time());
$sanitizedData = $this->sanitized($postData, $nullIfEmpty);
$sanitizedData['user_updated_id'] = auth()->user()->id;
if(isset($sanitizedData['total_aceptado_revisado']) && $sanitizedData['total_aceptado_revisado'] != 0
&& $sanitizedData['total_aceptado_revisado'] != null && $sanitizedData['total_aceptado_revisado'] != ""){
if (
isset($sanitizedData['total_aceptado_revisado']) && $sanitizedData['total_aceptado_revisado'] != 0
&& $sanitizedData['total_aceptado_revisado'] != null && $sanitizedData['total_aceptado_revisado'] != ""
) {
$sanitizedData['aprobado_at'] = $sanitizedData['updated_at'];
$sanitizedData['aprobado_user_id'] = $sanitizedData['user_updated_id'];
}
@ -367,9 +370,9 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
}
// modificar los datos del pedido y de la factura si no está la factura validada
if ($presupuestoEntity->estado_id == 2){
if ($presupuestoEntity->estado_id == 2) {
$facturaModel = model('App\Models\Facturas\FacturaModel');
if(!$facturaModel->presupuestoHasFacturaValidada($id)){
if (!$facturaModel->presupuestoHasFacturaValidada($id)) {
// se actualiza primero el pedido
$pedidoModel = model('App\Models\Pedidos\PedidoLineaModel');
$pedidoLineaId = $pedidoModel->where('presupuesto_id', $id)->first()->id;
@ -434,6 +437,10 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$this->viewData['POD'] = $this->getPOD();
$this->viewData['no_envio_base'] = model('App\Models\Clientes\ClienteModel')->where('id', $presupuestoEntity->cliente_id)->first();
if ($this->viewData['no_envio_base'])
$this->viewData['no_envio_base'] = $this->viewData['no_envio_base']->no_envio_base;
$this->viewData['serviciosAutomaticos'] = [
'solapas_cubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('servicio_solapas_cubierta')->value,
'solapas_sobrecubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('servicio_solapas_sobrecubierta')->value,
@ -459,11 +466,11 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$modelPedidoLinea = new \App\Models\Pedidos\PedidoLineaModel();
$linea = $modelPedidoLinea->where('presupuesto_id', $id)->first();
if($linea){
if ($linea) {
$this->viewData['pedido_id'] = $linea->pedido_id;
$modelOrden = new \App\Models\OrdenTrabajo\OrdenTrabajoModel();
$orden = $modelOrden->where('pedido_id', $linea->pedido_id)->first();
if($orden){
if ($orden) {
$this->viewData['orden_id'] = $orden->id;
}
}
@ -633,7 +640,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$data['comparador']['json_data'] = json_decode($presupuesto->comparador_json_data, true);
if ($data['comparador']['json_data'] != null) {
foreach ($data['comparador']['json_data'] as &$item) {
if(intval($item['papel_id'])>0)
if (intval($item['papel_id']) > 0)
$item['papel_nombre'] = $modelPapelGenerico->getNombre($item['papel_id'])['nombre'];
}
}
@ -657,7 +664,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$data['comentarios_pdf'] = $presupuesto->comentarios_pdf;
$data['comentarios_presupuesto'] = $presupuesto->comentarios_presupuesto;
$data['comentarios_produccion'] = $presupuesto->comentarios_produccion;
$data['tiradasAlternativas'] = json_decode($presupuesto->tirada_alternativa_json_data);
@ -688,9 +695,9 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$data['resumen']['total_factor_ponderado'] = is_numeric($presupuesto->total_factor_ponderado) ? $presupuesto->total_factor_ponderado : 0;
$data['total_aceptado_revisado'] = $presupuesto->total_aceptado_revisado;
$data['aprobado_by_at'] = ($presupuesto->aprobado_user_id != null)?
model('App\Models\Usuarios\UserModel')->getFullName($presupuesto->aprobado_user_id) . ', '
. date('d/m/Y H:i:s', strtotime($presupuesto->aprobado_at)):'';
$data['aprobado_by_at'] = ($presupuesto->aprobado_user_id != null) ?
model('App\Models\Usuarios\UserModel')->getFullName($presupuesto->aprobado_user_id) . ', '
. date('d/m/Y H:i:s', strtotime($presupuesto->aprobado_at)) : '';
$data['resumen']['iva_reducido'] = $presupuesto->iva_reducido;
@ -811,7 +818,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$paginas_color = $sobrecubierta['datosPedido']['paginas'] ?? 0;
$tipo_impresion_id = $sobrecubierta['tipo_impresion_id'];
$faja = intval($sobrecubierta['faja'] ?? 0);
$uso = $faja==1? 'faja' : $sobrecubierta['uso'];
$uso = $faja == 1 ? 'faja' : $sobrecubierta['uso'];
$data = array(
@ -993,6 +1000,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$reqData = $this->request->getPost();
$calcular_merma = $reqData['calcular_merma'] ?? 0;
$type = $reqData['type'] ?? null;
// por defecto, se deja cosido tapa blanda por ahora JJO
$tipo_impresion_id = $reqData['tipo_impresion_id'] ?? 4;
@ -1071,8 +1080,29 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
'a_favor_fibra' => $a_favor_fibra
);
$resourceData = PresupuestoService::obtenerComparadorPlana($input_data);
if (
$calcular_merma == 1 && count($resourceData) > 0 &&
count($resourceData[0]['fields']) > 0 && $resourceData[0]['fields']['num_formas'] > 0
) {
usort($resourceData, function ($a, $b) {
return $b['fields']['total_impresion'] <=> $a['fields']['total_impresion'];
});
$num_formas = [];
$formas_linea = $datosPedido->isCosido ? intval($resourceData[0]['fields']['num_formas']['value']) / 2 :
intval($resourceData[0]['fields']['num_formas']['value']);
array_push($num_formas, $formas_linea);
$POD = $this->getPOD();
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada, $POD, $num_formas);
$resourceData = PresupuestoService::obtenerComparadorPlana($input_data);
}
} else if ($type == 'interior_rot') {
$paginas = (object) array(
@ -1105,6 +1135,26 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$resourceData = PresupuestoService::obtenerComparadorRotativa($input_data);
if (
$calcular_merma == 1 && count($resourceData) > 0 &&
count($resourceData[0]['fields']) > 0 && $resourceData[0]['fields']['num_formas'] > 0
) {
usort($resourceData, function ($a, $b) {
return $b['fields']['total_impresion'] <=> $a['fields']['total_impresion'];
});
$num_formas = [];
$formas_linea = $datosPedido->isCosido ? intval($resourceData[0]['fields']['num_formas']['value']) / 2 :
intval($resourceData[0]['fields']['num_formas']['value']);
array_push($num_formas, $formas_linea);
$POD = $this->getPOD();
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada, $POD, $num_formas);
$resourceData = PresupuestoService::obtenerComparadorRotativa($input_data);
}
} else if ($type == 'cubierta' || $type == 'sobrecubierta' || $type == 'faja') {
$datosPedido->solapas = $reqData['solapas'];
@ -1170,7 +1220,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
return $this->respond($data);
} else if ($tipo == 'duplicar') {
$presupuesto_id = $reqData['presupuesto_id'] ?? -1;
$result = $this->duplicarPresupuesto($presupuesto_id);
$result = PresupuestoService::duplicarPresupuesto($presupuesto_id);
$newTokenHash = csrf_hash();
$csrfTokenName = csrf_token();
if ($result['success']) {
@ -1226,12 +1276,12 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$cubierta = false;
if ($uso == 'cubierta') {
$cubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$sobrecubierta = false;
if ($uso == 'sobrecubierta') {
$sobrecubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$guardas = false;
if ($uso == 'guardas') {
@ -1255,7 +1305,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$isPOD,
$anchoLibro,
$alto,
$tirada);
$tirada
);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("t1.nombre", $this->request->getGet("q"))
@ -1294,12 +1345,12 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$cubierta = false;
if ($uso == 'cubierta') {
$cubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$sobrecubierta = false;
if ($uso == 'sobrecubierta') {
$sobrecubierta = true;
$anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
$anchoLibro = 2 * $ancho + 2 * $solapas + $lomo;
}
$guardas = false;
if ($uso == 'guardas') {
@ -1311,7 +1362,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
}
$model = model('App\Models\Configuracion\PapelGenericoModel');
$query = $model->getGramajeForComparador($tipo,
$query = $model->getGramajeForComparador(
$tipo,
$papel_generico_id,
$cubierta,
$sobrecubierta,
@ -1321,7 +1373,8 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$isPOD,
$anchoLibro,
$alto,
$tirada);
$tirada
);
if ($this->request->getGet("q")) {
$query->groupStart()
->orLike("t2.gramaje", $this->request->getGet("q"))
@ -1554,81 +1607,6 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
}
/**
* Duplica un presupuesto dado por su ID.
*
* Esta función duplica un presupuesto y todas sus entidades relacionadas como acabados, encuadernaciones, manipulados,
* preimpresiones, direcciones y lineas. El presupuesto duplicado se marca como tal y a su título se le añade
* una cadena 'duplicado'. La función devuelve un array con un estado de éxito y el ID del nuevo presupuesto.
*
* @param int $id El ID del presupuesto a duplicar.
* @return array Un array asociativo que contiene una clave 'success' que indica el estado de éxito de la operación,
* y una clave 'id' que contiene el ID del nuevo presupuesto si la operación fue exitosa.
* Si ocurre una excepción, la clave 'success' será false y una clave 'message' contendrá el mensaje de la excepción.
* @throws \Exception Si ocurre un error durante la operación.
*/
private function duplicarPresupuesto($id)
{
try {
$presupuesto = $this->model->find($id);
$presupuesto->titulo = $presupuesto->titulo . ' - ' . lang('Presupuestos.duplicado');
$presupuesto->is_duplicado = 1;
$presupuesto->estado_id = 1;
$new_id = $this->model->insert($presupuesto);
$presupuestoAcabadosModel = model('App\Models\Presupuestos\PresupuestoAcabadosModel');
foreach ($presupuestoAcabadosModel->where('presupuesto_id', $presupuesto->id)->findAll() as $acabado) {
$acabado->presupuesto_id = $new_id;
$presupuestoAcabadosModel->insert($acabado);
}
$presupuestoEncuadernacionesModel = model('App\Models\Presupuestos\PresupuestoEncuadernacionesModel');
foreach ($presupuestoEncuadernacionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $encuadernacion) {
$encuadernacion->presupuesto_id = $new_id;
$presupuestoEncuadernacionesModel->insert($encuadernacion);
}
$presupuestoManipuladosModel = model('App\Models\Presupuestos\PresupuestoManipuladosModel');
foreach ($presupuestoManipuladosModel->where('presupuesto_id', $presupuesto->id)->findAll() as $manipulado) {
$manipulado->presupuesto_id = $new_id;
$presupuestoManipuladosModel->insert($manipulado);
}
$presupuestoPreimpresionesModel = model('App\Models\Presupuestos\PresupuestoPreimpresionesModel');
foreach ($presupuestoPreimpresionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $preimpresion) {
$preimpresion->presupuesto_id = $new_id;
$presupuestoPreimpresionesModel->insert($preimpresion);
}
$presupuestoServiciosExtraModel = model('App\Models\Presupuestos\PresupuestoServiciosExtraModel');
foreach ($presupuestoServiciosExtraModel->where('presupuesto_id', $presupuesto->id)->findAll() as $servicioExtra) {
$servicioExtra->presupuesto_id = $new_id;
$presupuestoServiciosExtraModel->insert($servicioExtra);
}
$presupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
foreach ($presupuestoDireccionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $direccion) {
$direccion->presupuesto_id = $new_id;
$presupuestoDireccionesModel->insert($direccion);
}
$presupuestoLineaModel = model('App\Models\Presupuestos\PresupuestoLineaModel');
$presupuestoLineaModel->duplicateLineasPresupuesto($presupuesto->id, $new_id);
return [
'success' => true,
'id' => $new_id
];
} catch (\Exception $e) {
return [
'success' => false,
'message' => $e->getMessage()
];
}
}
public function allItemsSelect()
{
@ -1767,10 +1745,11 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$result = DataTable::of($q)
->edit(
'fecha',
fn($q) => $q->fecha?Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y"):""
fn($q) => $q->fecha ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y") : ""
)
->edit(
'estado', fn($q) => match ($q->estado) {
'estado',
fn($q) => match ($q->estado) {
"1" => lang('Presupuestos.borrador'),
"2" => lang('Presupuestos.confirmado'),
default => '--'
@ -1781,13 +1760,14 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
<a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
</div>
';
});
return $result->toJson(returnAsObject: true) ;
return $result->toJson(returnAsObject: true);
}
public function obtenerTotalPresupuestosCliente($cliente_id){
public function obtenerTotalPresupuestosCliente($cliente_id)
{
$error = false;
$result = [
@ -1798,17 +1778,17 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
->where('presupuestos.cliente_id', $cliente_id)
->select('SUM(presupuestos.total_aceptado) as total')
->groupBy('presupuestos.cliente_id')->get()->getResultObject();
if(count($data) > 0){
if (count($data) > 0) {
$result['total_impresion'] = round(floatval($data[0]->total), 2);
}
else{
} else {
$error = true;
}
$result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
return $this->respond(['status' => $error ? 'error' : 'success', 'totales' => $result]);
}
public function obtenerTotalPedidosCliente($cliente_id){
public function obtenerTotalPedidosCliente($cliente_id)
{
$error = false;
$result = [
@ -1821,14 +1801,70 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id')
->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id')
->groupBy('presupuestos.cliente_id')->get()->getResultObject();
if(count($data) > 0){
if (count($data) > 0) {
$result['total_impresion'] = round(floatval($data[0]->total), 2);
}
else{
} else {
$error = true;
}
$result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
return $this->respond(['status' => $error ? 'error' : 'success', 'totales' => $result]);
}
public function hasFiles()
{
if ($this->request->isAJAX()) {
$id = $this->request->getGet('id');
$presupuesto = $this->model->find($id);
if (!$presupuesto) {
return $this->respond([
'status' => 'error',
'message' => lang('Presupuestos.presupuestoNotFound'),
]);
}
$files = $presupuesto->files() ?? [];
if (count($files) == 0) {
return $this->respond([
'status' => 'success',
'hasFiles' => false,
]);
} else {
return $this->respond([
'status' => 'success',
'hasFiles' => true,
]);
}
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function checkLomo()
{
if ($this->request->isAJAX()) {
$tipo_impresion_id = $this->request->getGet('tipo_impresion_id');
$lomo = $this->request->getGet('lomo') ?? 0;
$response = PresupuestoService::check_lomo_interior($tipo_impresion_id, $lomo);
return $this->respond($response);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
public function reprintPresupuesto()
{
if ($this->request->isAJAX()) {
$id = $this->request->getPost('id');
$duplicateFiles = $this->request->getPost('duplicateFiles') ?? false;
$response = PresupuestoService::duplicarPresupuesto($id, true, $duplicateFiles);
return $this->respond($response);
} else {
return $this->failUnauthorized('Invalid request', 403);
}
}
@ -1858,7 +1894,7 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$modelPapel = new PapelGenericoModel();
foreach ($lineas as $linea) {
$linea->papel_generico = (new PapelGenericoModel())->find($linea->papel_id)->nombre;
if($linea->tipo == 'lp_faja'){
if ($linea->tipo == 'lp_faja') {
$linea->alto_faja = $presupuestoEntity->alto_faja_color;
}
}
@ -1927,4 +1963,6 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
return $direcciones;
}
}

View File

@ -130,7 +130,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$this->viewData['paisList'] = model('App\Models\Configuracion\PaisModel')->getAllForMenu('id, nombre', 'nombre', true);
$this->viewData['clienteId'] = $clienteId;
$this->viewData['POD'] = $POD;
$this->viewData['lomo_maximo'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo')->value;
$this->viewData['lomo_maximo_fresado_cosido'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo_fresado_cosido')->value;
$this->viewData['lomo_minimo_fresado_cosido'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_minimo_fresado_cosido')->value;
$this->viewData['eb'] = 0;
@ -175,7 +175,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$this->viewData['clienteId'] = $clienteId;
$this->viewData['POD'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('POD')->value;
$this->viewData['lomo_maximo'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo')->value;
$this->viewData['lomo_maximo_fresado_cosido'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo_fresado_cosido')->value;
$this->viewData['lomo_minimo_fresado_cosido'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_minimo_fresado_cosido')->value;
$this->viewData['eb'] = $presupuestoEntity->envio_base;
@ -323,18 +323,24 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$datosPedido = (object) array(
'paginas' => $paginas,
'tirada' => $tirada[0],
'merma' => $this->calcular_merma($tirada[0], $POD),
'merma' => PresupuestoService::calcular_merma($tirada[0], $POD),
'ancho' => intval($tamanio['ancho']) ?? 100000,
'alto' => intval($tamanio['alto']) ?? 100000,
'isCosido' => $is_cosido,
'a_favor_fibra' => 1,
);
// Para POD siempre es HQ
if ($tirada[0] <= $POD) {
$isHq = true;
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
$forzarRotativa = false;
if ($tirada[0] <= $POD && $cliente->forzar_rotativa_pod) {
$forzarRotativa = true;
} else if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$excluirRotativa = true;
}
$input_data = array(
'uso' => 'interior',
'tipo_impresion_id' => $tipo_impresion_id,
@ -346,7 +352,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
'cliente_id' => $cliente_id,
'paginas_color' => $paginas_color,
'excluirRotativa' => $excluirRotativa,
'papelInteriorDiferente' => $papelInteriorDiferente
'papelInteriorDiferente' => $papelInteriorDiferente,
'forzarRotativa' => $forzarRotativa,
);
$interior = PresupuestoClienteService::obtenerInterior($input_data);
@ -411,21 +418,53 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
'value' => ""
];
$lomo_minimo_fresado_cosido = intval(model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_minimo_fresado_cosido')->value);
$lomo_maximo = intval(model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo')->value);
$lomo_maximo_fresado_cosido = intval(model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo_fresado_cosido')->value);
$lomo_maximo_espiral = intval(model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo_espiral')->value);
$lomo_maximo_wireo = intval(model('App\Models\Configuracion\ConfigVariableModel')->getVariable('lomo_maximo_wireo')->value);
if ($tipo == 'cosido' || $tipo == 'fresado') {
if ($lomo < $lomo_minimo_fresado_cosido) {
$errors['status'] = 1;
$errors['value'] = 'No se pueden encuadernar libros cosidos o fresados con lomo inferior a '
. $lomo_minimo_fresado_cosido . ' mm. El lomo actual es de ' . $lomo . ' mm. ' .
"Por favor, aumente el número de páginas o el gramaje del papel para que sea encuadernable.";
$errors['value'] = lang(
'Presupuestos.errores.error_lomo_minimo',
[
lang('Presupuestos.cosido') . "/" . lang('Presupuestos.fresado'),
$lomo_minimo_fresado_cosido,
$lomo,
]
);
}
if ($lomo > $lomo_maximo) {
if ($lomo > $lomo_maximo_fresado_cosido) {
$errors['status'] = 1;
$errors['value'] = 'No se pueden encuadernar con un lomo superior a '
. $lomo_maximo . ' mm. El lomo actual es de ' . $lomo . ' mm. ' .
"Por favor, disminuya el número de páginas o el gramaje del papel para que sea encuadernable.";
$errors['value'] = lang(
'Presupuestos.errores.error_lomo_maximo',
[
lang('Presupuestos.cosido') . "/" . lang('Presupuestos.fresado'),
$lomo_maximo_fresado_cosido,
$lomo,
]
);
}
} else if ($tipo == 'espiral' && $lomo > $lomo_maximo_espiral) {
$errors['status'] = 1;
$errors['value'] = lang(
'Presupuestos.errores.error_lomo_maximo',
[
lang('Presupuestos.espiral'),
$lomo_maximo_espiral,
$lomo,
]
);
} else if ($tipo == 'wireo' && $lomo > $lomo_maximo_wireo) {
$errors['status'] = 1;
$errors['value'] = lang(
'Presupuestos.errores.error_lomo_maximo',
[
lang('Presupuestos.wireo'),
$lomo_maximo_wireo,
$lomo,
]
);
}
$data = (object) array(
@ -456,13 +495,13 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
//$reqData = $this->request->getPost();
$modelPapelGenerico = new PapelGenericoModel();
$id = $reqData['id'] ?? 0;
$cliente_id = $reqData['clienteId'] ?? -1;
$noEnvioBase = model('App\Models\Clientes\ClienteModel')->find($cliente_id)->no_envio_base ?? false;
$tirada = $reqData['tirada'] ?? 0;
$selectedTirada = $reqData['selectedTirada'] ?? -1;
$selectedTirada = $reqData['selectedTirada'] ?? (is_array($tirada) ? $tirada[0] : $tirada);
$tamanio = $reqData['tamanio'];
$paginas = $reqData['paginas'] ?? 0;
$paginas_color = $reqData['paginasColor'] ?? 0;
@ -558,7 +597,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
'servicios' => $reqData['servicios'] ?? [],
);
$return_data = $this->calcular_presupuesto($datos_presupuesto, 0, false); //TRUE FOR DEBUG
$develoment_mode = getenv('SK_ENVIRONMENT') !== 'production';
$return_data = $this->calcular_presupuesto($datos_presupuesto, $selectedTirada, $develoment_mode); //TRUE FOR DEBUG
if (array_key_exists('errors', $return_data)) {
if ($return_data['errors']->status == 1) {
$return_data = [
@ -609,6 +649,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
} else {
$coste = floatval($coste_direccion->coste);
$margen = $coste * (intval($coste_direccion->margen) / 100.0);
if ($noEnvioBase) {
$coste = 0.0;
$margen = 0.0;
}
$return_data['eb'][$i] = round($coste + $margen, 2);
}
}
@ -620,13 +664,13 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$return_data['precio_u'][$i] = round(floatval($return_data['precio_u'][$i]) + $coste_envio, 4);
}
$envio_base = true;
$coste_envio = 0.0; // se inicializa para calcular los costes de envíos restantes si es que hay
$return_data['coste_envio'] = [];
if (count($direcciones) > 0) {
for ($i = 0; $i < count($tirada); $i++) {
$coste_envio = 0.0;
$envio_base = true;
foreach ($direcciones as $direccion) {
// El primer envio no se calcula ya que se añade el base
if ($envio_base) {
@ -739,16 +783,21 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$datosPedido = (object) array(
'paginas' => $paginas,
'tirada' => $tirada[0],
'merma' => $tirada[0] > $POD ? $this->calcular_merma($tirada[0], $POD) : 0,
'merma' => $tirada[0] > $POD ? PresupuestoService::calcular_merma($tirada[0], $POD) : 0,
'ancho' => intval($tamanio['ancho']) ?? 100000,
'alto' => intval($tamanio['alto']) ?? 100000,
'isCosido' => $is_cosido,
'a_favor_fibra' => 1,
);
// Para POD siempre es HQ
if ($tirada[0] <= $POD) {
$isHq = true;
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
$forzarRotativa = false;
if ($tirada[0] <= $POD && $cliente->forzar_rotativa_pod) {
$forzarRotativa = true;
} else if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$excluirRotativa = true;
}
$input_data = array(
@ -762,7 +811,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
'cliente_id' => $cliente_id,
'paginas_color' => $paginas_color,
'excluirRotativa' => $excluirRotativa,
'papelInteriorDiferente' => $papelInteriorDiferente
'papelInteriorDiferente' => $papelInteriorDiferente,
'forzarRotativa' => $forzarRotativa,
);
$interior = PresupuestoClienteService::obtenerInterior($input_data);
@ -1015,6 +1065,9 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$direcciones = $reqData['direcciones'] ?? [];
$direccionesFP1 = $reqData['direccionesFP1'] ?? [];
$direccionesFP2 = $reqData['direccionesFP2'] ?? [];
if ($tipo != "")
$tipo_impresion_id = $this->getTipoImpresion($tipo, $cubierta['tipoCubierta']);
else
@ -1126,6 +1179,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$peso_libro = $resultado_presupuesto['peso'][array_search($selected_tirada, $tirada)];
// calculo del envio base (tirada_maxima)
$noEnvioBase = model('App\Models\Clientes\ClienteModel')->find($cliente_id)->no_envio_base ?? false;
$resultado_presupuesto['eb'] = [];
$datos_presupuesto['envio_base'] = 0;
for ($i = 0; $i < count($tirada); $i++) {
@ -1139,6 +1193,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
);
if (intval($selected_tirada) == intval($tirada[$i])) {
if ($noEnvioBase) {
$coste_direccion->coste = 0.0;
$coste_direccion->margen = 0.0;
}
$datos_presupuesto['envio_base'] = round($coste_direccion->coste * (1 + $coste_direccion->margen / 100.0), 2);
}
@ -1160,6 +1218,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
];
return $resultado_presupuesto;
} else {
if ($noEnvioBase) {
$coste_direccion->coste = 0.0;
$coste_direccion->margen = 0.0;
}
$resultado_presupuesto['eb'][$i] = round($coste_direccion->coste, 2);
$resultado_presupuesto['eb_margen'][$i] = round($coste_direccion->margen, 2);
}
@ -1174,12 +1236,14 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
// para el calculo del precio unidad, sólo se tiene en cuenta el envío base
for ($i = 0; $i < count($tirada); $i++) {
$coste_envio = 0.0;
$coste_envio += ($resultado_presupuesto['eb'][$i] / $tirada[$i]);
$resultado_presupuesto['info']['totales'][$i]['envio_base_margen'] =
floatval($resultado_presupuesto['eb'][$i])*(floatval($resultado_presupuesto['eb_margen'][$i])/100.0);
$resultado_presupuesto['info']['totales'][$i]['envio_base_margen'] =
floatval($resultado_presupuesto['eb'][$i]) * (floatval($resultado_presupuesto['eb_margen'][$i]) / 100.0);
$resultado_presupuesto['info']['totales'][$i]['envio_base_coste'] = $resultado_presupuesto['eb'][$i];
$coste_envio = round(round($resultado_presupuesto['info']['totales'][$i]['envio_base_margen'] +
$resultado_presupuesto['info']['totales'][$i]['envio_base_coste'], 2) / 50, 4);
$resultado_presupuesto['precio_u'][$i] = round(floatval($resultado_presupuesto['precio_u'][$i]) + $coste_envio, 4);
}
@ -1312,7 +1376,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$datos_presupuesto['entrega_taller'] = $reqData['entrega_taller'] ?? 0;
$resultado_presupuesto['info']['merma'] = $this->calcular_merma($selected_tirada, $POD);
$resultado_presupuesto['info']['merma'] = isset($resultado_presupuesto['info']['num_formas']) ?
PresupuestoService::calcular_merma($selected_tirada, $POD, $resultado_presupuesto['info']['num_formas']) : PresupuestoService::calcular_merma($selected_tirada, $POD);
$datos_presupuesto['faja'] = $faja;
@ -1357,7 +1422,11 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
foreach ($serviciosAcabado as $service) {
$model = model('App\Models\Presupuestos\PresupuestoAcabadosModel');
$servicio = $model->getPrecioTarifa(
intval($service), intval($selected_tirada)+$resultado_presupuesto['info']['merma'], -1, $POD);
intval($service),
intval($selected_tirada) + $resultado_presupuesto['info']['merma'],
-1,
$POD
);
if (count($servicio) > 0) {
if ($servicio[0]->total > 0) {
@ -1375,8 +1444,11 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
foreach ($serviciosAcabado as $service) {
$model = model('App\Models\Presupuestos\PresupuestoAcabadosModel');
$servicio = $model->getPrecioTarifa(
intval($service),
intval($selected_tirada) + $resultado_presupuesto['info']['merma'], -1, $POD);
intval($service),
intval($selected_tirada) + $resultado_presupuesto['info']['merma'],
-1,
$POD
);
if (count($servicio) > 0) {
if ($servicio[0]->total > 0) {
@ -1393,8 +1465,11 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
foreach ($serviciosAcabado as $service) {
$model = model('App\Models\Presupuestos\PresupuestoAcabadosModel');
$servicio = $model->getPrecioTarifa(
intval($service),
intval($selected_tirada) + $resultado_presupuesto['info']['merma'], -1, $POD);
intval($service),
intval($selected_tirada) + $resultado_presupuesto['info']['merma'],
-1,
$POD
);
if (count($servicio) > 0) {
if ($servicio[0]->total > 0) {
@ -1407,7 +1482,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$tarifa_id = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_lomo_redondo')->value;
$serv_lomo = PresupuestoCLienteService::getServiciosManipulado([
'tarifa_id' => intval($tarifa_id),
'tirada' => $selected_tirada+$resultado_presupuesto['info']['merma'],
'tirada' => $selected_tirada + $resultado_presupuesto['info']['merma'],
'POD' => $POD,
])[0];
@ -1485,6 +1560,14 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
}
}
if (count($direccionesFP1) > 0) {
$this->guardarLineaEnvio($id, $direccionesFP1, $peso_libro, true);
}
if (count($direccionesFP2) > 0) {
$this->guardarLineaEnvio($id, $direccionesFP2, $peso_libro, true);
}
if ($confirmar) {
$model_presupuesto->confirmarPresupuesto($id);
PresupuestoService::crearPedido($id);
@ -1513,7 +1596,6 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$modelPapelFormato = new PapelFormatoModel();
$modelCliente = new ClienteModel();
$presupuesto = $this->model->find($id);
$data = [];
if ($presupuesto) {
@ -1623,7 +1705,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
if (intval($presupuesto->recoger_en_taller) == 1) {
$data['direcciones']['entrega_taller'] = 1;
} else {
$data['direcciones'] = $this->obtenerDireccionesEnvio($id, $presupuesto->cliente_id);
$data['direcciones'] = $this->obtenerDireccionesEnvio($id);
}
if (intval($presupuesto->estado_id) == 2) {
@ -1789,12 +1871,13 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
}
protected function guardarLineaEnvio($presupuestoId, $direccion, $peso_libro)
protected function guardarLineaEnvio($presupuestoId, $direccion, $peso_libro, $coste_cero = false)
{
$unidades = intval($direccion['unidades']);
$peso_envio = $peso_libro * $unidades / 1000.0;
$data = $this->getCosteEnvio(
$direccion['direccion'],
$peso_libro,
@ -1808,7 +1891,11 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$data->presupuesto_id = $presupuestoId;
$data->tarifa_id = $data->id;
unset($data->id);
$data->precio = $data->coste;
if($coste_cero) {
$data->coste = 0;
} else {
$data->precio = $data->coste;
}
unset($data->coste);
$data->entregaPieCalle = ($direccion['entregaPalets'] == 'false' || $direccion['entregaPalets'] == 0) ? 0 : 1;
unset($data->tipo);
@ -2029,7 +2116,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$datosPedido = (object) array(
'paginas' => $paginas,
'tirada' => $tirada[$t],
'merma' => $this->calcular_merma($tirada[$t], $POD),
'merma' => PresupuestoService::calcular_merma($tirada[$t], $POD),
'ancho' => intval($tamanio['ancho']) ?? 100000,
'alto' => intval($tamanio['alto']) ?? 100000,
'isCosido' => $is_cosido,
@ -2039,9 +2126,14 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$info['merma'] = $datosPedido->merma;
}
// Para POD siempre es HQ
if ($tirada[$t] <= $POD) {
$isHq = true;
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
$forzarRotativa = false;
if ($tirada[$t] <= $POD && $cliente->forzar_rotativa_pod) {
$forzarRotativa = true;
} else if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$excluirRotativa = true;
}
$input_data = array(
@ -2055,7 +2147,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
'cliente_id' => $cliente_id,
'paginas_color' => $paginas_color,
'excluirRotativa' => $excluirRotativa,
'papelInteriorDiferente' => $papelInteriorDiferente
'papelInteriorDiferente' => $papelInteriorDiferente,
'forzarRotativa' => $forzarRotativa,
);
$interior = PresupuestoClienteService::obtenerInterior($input_data);
@ -2082,9 +2175,11 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
foreach ($interior as $linea) {
if (count($linea) > 0) {
$costeInterior += round(floatval($linea['total_impresion']), 2);
$peso_interior += floatval($linea['peso']);
$lomo += floatval($linea['mano']);
$info['lomo_interior'] += floatval($linea['mano']);
$peso_interior += round(floatval($linea['peso']), 2);
if (intval($tirada[$t]) == intval($selected_tirada)) {
$lomo += floatval($linea['mano']);
$info['lomo_interior'] += floatval($linea['mano']);
}
if ($extra_info) {
$this->calcular_coste_linea(
$linea,
@ -2107,9 +2202,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
array_push($num_formas, $formas_linea);
}
}
$input_data['datosPedido']->merma = $this->calcular_merma($tirada[$t], $POD, $num_formas);
$input_data['datosPedido']->merma = PresupuestoService::calcular_merma($tirada[$t], $POD, $num_formas);
if ($extra_info) {
$info['merma'] = max($info['merma'], $input_data['datosPedido']->merma);
$info['num_formas'] = $num_formas;
}
$interior = PresupuestoClienteService::obtenerInterior($input_data);
if ($interior == -1) {
@ -2142,8 +2238,11 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
foreach ($interior as $linea) {
if (count($linea) > 0) {
$costeInterior += round(floatval($linea['total_impresion']), 2);
if (intval($tirada[$t]) == intval($selected_tirada)) {
$info['lomo_interior'] += floatval($linea['mano']);
$lomo += floatval($linea['mano']);
}
$peso_interior += floatval($linea['peso']);
$lomo += floatval($linea['mano']);
if ($extra_info) {
$this->calcular_coste_linea(
@ -2194,8 +2293,11 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$peso_cubierta = 0.0;
if (count($cubierta) > 0) {
$coste_cubierta += round(floatval($cubierta['total_impresion']), 2);
$peso_cubierta += floatval($cubierta['peso']);
$lomo += floatval($cubierta['mano']);
$peso_cubierta += round(floatval($cubierta['peso']), 2);
if (intval($tirada[$t]) == intval($selected_tirada)) {
$lomo += floatval($cubierta['mano']);
}
if ($extra_info) {
$this->calcular_coste_linea(
@ -2225,7 +2327,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
return $return_data;
}
$cantidad_total = intval($datosPedido->tirada) + intval($datosPedido->merma);
$cantidad_total = intval($datosPedido->tirada);// + intval($datosPedido->merma);
// Acabado Cubierta
if (intval($datos_entrada['cubierta']['acabado']) != 0) {
@ -2258,9 +2360,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
}
$coste_servicios += round(floatval($acabadoCubierta[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($acabadoCubierta[0]->total), 2);
//$totalServicios += round(floatval($acabadoCubierta[0]->total), 2);
$base = round(floatval($acabadoCubierta[0]->total / (1 + $acabadoCubierta[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($acabadoCubierta[0]->total - $base), 2);
}
}
@ -2297,9 +2400,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
}
$coste_servicios += round(floatval($resultado[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->total), 2);
//$totalServicios += round(floatval($resultado[0]->total), 2);
$base = round(floatval($resultado[0]->total / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->total - $base), 2);
}
@ -2330,7 +2434,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
if (count($linea_sobrecubierta) > 0) {
$coste_sobrecubierta += round(floatval($linea_sobrecubierta['total_impresion']), 2);
$peso_sobrecubierta += floatval($linea_sobrecubierta['peso']);
$peso_sobrecubierta += round(floatval($linea_sobrecubierta['peso']), 2);
if ($extra_info) {
$this->calcular_coste_linea(
@ -2393,9 +2497,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($acabadoSobrecubierta[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($acabadoSobrecubierta[0]->total), 2);
//$totalServicios += round(floatval($acabadoSobrecubierta[0]->total), 2);
$base = round(floatval($acabadoSobrecubierta[0]->total / (1 + $acabadoSobrecubierta[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($acabadoSobrecubierta[0]->total - $base), 2);
}
}
@ -2435,7 +2540,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
if (count($guardas) > 0) {
$coste_guardas += round(floatval($guardas['total_impresion']), 2);
$peso_guardas += floatval($guardas['peso']);
$peso_guardas += round(floatval($guardas['peso']), 2);
if (intval($tirada[$t]) == intval($selected_tirada)) {
$lomo += floatval($guardas['mano']);
}
if ($extra_info) {
$this->calcular_coste_linea(
@ -2551,9 +2659,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($acabadoFaja[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($acabadoFaja[0]->total), 2);
//$totalServicios += round(floatval($acabadoFaja[0]->total), 2);
$base = round(floatval($acabadoFaja[0]->total / (1 + $acabadoFaja[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($acabadoFaja[0]->total - $base), 2);
}
}
@ -2605,9 +2714,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$costeServiciosDefecto += round(floatval($servicio->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($servicio->total), 2);
//$totalServicios += round(floatval($servicio->total), 2);
$base = round(floatval($servicio->total / (1 + $servicio->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($servicio->total - $base), 2);
}
}
@ -2642,9 +2752,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$costeServiciosDefecto += round(floatval($servicio->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($servicio->total), 2);
//$totalServicios += round(floatval($servicio->total), 2);
$base = round(floatval($servicio->total / (1 + $servicio->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($servicio->total - $base), 2);
}
}
@ -2747,9 +2858,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($resultado[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->total), 2);
//$totalServicios += round(floatval($resultado[0]->total), 2);
$base = round(floatval($resultado[0]->total / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->total - $base), 2);
}
} else if ($servicio->nombre == "ferro" || $servicio->nombre == "prototipo") {
@ -2779,9 +2891,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($resultado[0]->precio), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->precio), 2);
//$totalServicios += round(floatval($resultado[0]->precio), 2);
$base = round(floatval($resultado[0]->total / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->total - $base), 2);
}
} else if ($servicio->nombre == 'solapas_cubierta' || $servicio->nombre == 'solapas_sobrecubierta' || $servicio->nombre == 'solapas_faja') {
@ -2813,9 +2926,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($resultado[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->total), 2);
//$totalServicios += round(floatval($resultado[0]->total), 2);
$base = round(floatval($resultado[0]->total / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->total - $base), 2);
}
}
@ -2854,9 +2968,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($resultado[0]->precio), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->precio), 2);
//$totalServicios += round(floatval($resultado[0]->precio), 2);
$base = round(floatval($resultado[0]->precio / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->precio - $base), 2);
}
}
@ -2893,9 +3008,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($resultado[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->total), 2);
//$totalServicios += round(floatval($resultado[0]->total), 2);
$base = round(floatval($resultado[0]->total / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->total - $base), 2);
}
}
@ -2930,9 +3046,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($resultado[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->total), 2);
//$totalServicios += round(floatval($resultado[0]->total), 2);
$base = round(floatval($resultado[0]->total / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->total - $base), 2);
}
}
@ -2967,19 +3084,23 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$coste_servicios += round(floatval($resultado[0]->total), 2);
if ($extra_info) {
$totalServicios += round(floatval($resultado[0]->total), 2);
//$totalServicios += round(floatval($resultado[0]->total), 2);
$base = round(floatval($resultado[0]->total / (1 + $resultado[0]->margen / 100.0)), 2);
$base = round(floatval($base / $cantidad_total), 2) * $cantidad_total;
$totalServicios += $base;
$margenServicios += round(floatval($resultado[0]->total - $base), 2);
}
}
$total_por_tirada = $costeInterior +
/*$total_por_tirada = $costeInterior +
$coste_cubierta +
$coste_sobrecubierta +
$coste_guardas +
$coste_faja +
$costeServiciosDefecto + $coste_servicios;
$costeServiciosDefecto + $coste_servicios;*/
$total_por_tirada = $totalPapel + $margenPapel +
$totalImpresion + $margenImpresion +
$totalServicios + $margenServicios;
array_push(
$precio_u,
round(($total_por_tirada) / $tirada[$t], 4)
@ -2987,7 +3108,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
array_push($peso, round($peso_interior + $peso_cubierta + $peso_sobrecubierta + $peso_guardas + $peso_faja, 2));
if ($extra_info) {
$totalServicios -= $margenServicios;
//$totalServicios -= $margenServicios;
if (($margenServicios + $totalServicios) > 0) {
$porcentajeMargenServicios = $margenServicios / ($totalServicios) * 100;
} else {
@ -3003,20 +3124,26 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
'totalImpresion' => $totalImpresion,
'margenImpresion' => $margenImpresion,
'sumForFactor' => $sumForFactor,
'sumForFactorPonderado' => $sumForFactorPonderado,
'totalServicios' => $totalServicios,
'margenServicios' => $margenServicios,
'porcentajeMargenPapel' => $porcentajeMargenPapel,
'porcentajeMargenImpresion' => $porcentajeMargenImpresion,
'porcentajeMargenServicios' => $porcentajeMargenServicios
'porcentajeMargenPapel' => round($porcentajeMargenPapel, 0),
'porcentajeMargenImpresion' => round($porcentajeMargenImpresion, 0),
'porcentajeMargenServicios' => round($porcentajeMargenServicios, 0),
'sumForFactor' => $sumForFactor,
'sumForFactorPonderado' => $sumForFactorPonderado,
'total' => round($total_por_tirada, 2),
'precio_u' => round(($total_por_tirada) / $tirada[$t], 4),
));
}
$info['lomo_cubierta'] = round(floatval($lomo), 2);
$info['lomo_sobrecubierta'] = round(floatval($lomo_sobrecubierta), 2);
if (intval($tirada[$t]) == intval($selected_tirada)) {
$info['lomo_cubierta'] = round(floatval($lomo), 2);
$info['lomo_sobrecubierta'] = round(floatval($lomo_sobrecubierta), 2);
}
$return_data['info'] = $info;
@ -3068,12 +3195,14 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
return;
$totalPapel += round($linea['precio_pedido'], 2);
$totalPapel -= round($linea['margen_papel_pedido'], 2);
$totalPapel = round($totalPapel, 2);
$sumForFactor += round($linea['precio_pedido'], 2)
- round($linea['margen_papel_pedido'], 2);
$margenPapel += round($linea['margen_papel_pedido'], 2);
$totalImpresion += round($linea['precio_click_pedido'], 2);
$totalImpresion -= round($linea['margen_click_pedido'], 2);
$totalImpresion = round($totalImpresion, 2);
$sumForFactor += round($linea['precio_click_pedido'], 2)
- round($linea['margen_click_pedido'], 2);
@ -3088,6 +3217,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$margenImpresion += round($linea['precio_impresion_horas'], 2); // coste de maquina y magen son MARGEN, no COSTE
$margenImpresion += round($linea['margen_impresion_horas'], 2);
$margenImpresion += round($linea['margen_click_pedido'], 2);
$margenImpresion = round($margenImpresion, 2);
}
@ -3142,31 +3272,6 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
}
}
protected function calcular_merma($tirada, $POD, $formas_lineas_interior = [])
{
$merma = 0;
if ($tirada > $POD) {
$merma = $tirada * 0.1;
} else {
$merma_lineas = [];
foreach ($formas_lineas_interior as $formas_linea) {
if ($formas_linea > $tirada)
array_push($merma_lineas, $formas_linea - $tirada);
else
array_push($merma_lineas, $tirada % $formas_linea);
}
if (count($merma_lineas) > 0)
$merma = max($merma_lineas);
}
return round($merma, 0);
}
protected function getPapelFormatoListItems($selId = null)
{
$papelFormatoModel = model('App\Models\Configuracion\PapelFormatoModel');
@ -3308,39 +3413,22 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
}
}
protected function obtenerDireccionesEnvio($id, $cliente_id)
protected function obtenerDireccionesEnvio($id)
{
$model = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
$model_direcciones = model('App\Models\Clientes\ClienteDireccionesModel');
$direcciones = $model->where('presupuesto_id', $id)->asArray()->findAll();
$direcciones = $model->where('presupuesto_id', $id)
->where('is_ferro_prototipo', 0)->asArray()->findAll();
return $direcciones;
}
$result = [];
$temp = [];
for ($i = 0; $i < count($direcciones); $i++) {
$direccion_id = $model_direcciones->getIdForPresupuestoCliente(
$cliente_id,
$direcciones[$i]->att,
$direcciones[$i]->email,
$direcciones[$i]->direccion,
$direcciones[$i]->cp,
$direcciones[$i]->pais_id,
$direcciones[$i]->telefono
);
if (count($direccion_id) > 0) {
$temp = $direcciones[$i]->toArray();
array_push($result, [
'id' => $temp['id'],
'unidades' => $temp['cantidad'],
'palets' => $temp['entregaPieCalle'],
]);
}
}
if (count($result) > 0)
return $result;
else
return [];
protected function obtenerDireccionesEnvioFerro($id)
{
$model = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
$direcciones = $model->where('presupuesto_id', $id)
->where('is_ferro_prototipo', 0)->asArray()->findAll();
return $direcciones;
}
protected function obtenerDatosPapel($presupuesto_id)
@ -3553,10 +3641,18 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
foreach ($data as $servicio) {
$id = "service_extra_" . $servicio->id;
$tarifa_excluyente = false;
if (str_contains(strtolower($servicio->nombre), 'ferro') || str_contains(strtolower($servicio->nombre), 'prototipo')) {
$tarifa_excluyente = true;
}
$atributo_excluyente = $tarifa_excluyente ? 'data-tarifa-extra-excluyente="1"' : '';
array_push(
$servicios,
"<input class=\"calcular-presupuesto form-check-input\" type=\"checkbox\" id=\"{$id}\"
name=\"{$id}\" value=\"1\" data-tarifa-id=\"{$servicio->id}\" data-tarifa-tipo=\"extra\" data-tarifa-nombre=\"{$servicio->nombre}\">
name=\"{$id}\" value=\"1\" data-tarifa-id=\"{$servicio->id}\" data-tarifa-tipo=\"extra\" data-tarifa-nombre=\"{$servicio->nombre}\"
{$atributo_excluyente}>
<label class=\"form-check-label\" for=\"{$id}\">{$servicio->nombre}</label>"
);
}
@ -3564,4 +3660,29 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
return $servicios;
}
public function download_zip()
{
$presupuesto_id = $this->request->getPost('presupuesto_id');
if (!$presupuesto_id) {
return $this->response->setStatusCode(400)->setBody('Presupuesto ID requerido');
}
$ftpClient = new \App\Libraries\SafekatFtpClient();
try {
$zipPath = $ftpClient->downloadZipPresupuesto((int) $presupuesto_id);
if ($zipPath === null || !file_exists($zipPath)) {
return $this->response->setStatusCode(404)->setBody('No se encontraron archivos');
}
return $this->response
->download($zipPath, null) // null = usar nombre original del archivo
->setFileName('archivos_presupuesto_' . $presupuesto_id . '.zip');
} catch (\Throwable $e) {
log_message('error', $e->getMessage());
return $this->response->setStatusCode(500)->setBody('Error interno');
}
}
}

View File

@ -54,6 +54,7 @@ class Presupuestodirecciones extends \App\Controllers\BaseResourceController
$proveedor = $reqData['proveedor'] ?? "";
$proveedor_id = $reqData['proveedor_id'] ?? "";
$entregaPieCalle = $reqData['entregaPieCalle'] ?? 0;
$is_ferro_prototipo = $reqData['is_ferro_prototipo'] ?? 0;
$data = [
"presupuesto_id" => $presupuesto_id,
@ -73,6 +74,7 @@ class Presupuestodirecciones extends \App\Controllers\BaseResourceController
"proveedor" => $proveedor,
"proveedor_id" => $proveedor_id,
"entregaPieCalle" => $entregaPieCalle,
"is_ferro_prototipo" => $is_ferro_prototipo
];
$response = $this->model->insert($data);

View File

@ -3,12 +3,16 @@
namespace App\Controllers\Produccion;
use App\Controllers\BaseController;
use App\Models\Compras\ProveedorModel;
use App\Models\Configuracion\MaquinaModel;
use App\Models\Configuracion\MaquinaOtTareaModel;
use App\Models\OrdenTrabajo\OrdenTrabajoModel;
use App\Models\OrdenTrabajo\OrdenTrabajoTarea;
use App\Models\OrdenTrabajo\OrdenTrabajoUser;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Usuarios\UserModel;
use App\Services\EtiquetasTitulosService;
use App\Services\ImpresoraEtiquetaService;
use App\Services\ProductionService;
use CodeIgniter\Files\File;
use CodeIgniter\HTTP\RequestInterface;
@ -20,6 +24,7 @@ use Exception;
use Hermawan\DataTables\DataTable;
use Psr\Log\LoggerInterface;
class Ordentrabajo extends BaseController
{
protected $format = 'json';
@ -28,7 +33,9 @@ class Ordentrabajo extends BaseController
protected OrdenTrabajoModel $otModel;
protected OrdenTrabajoUser $otUserModel;
protected OrdenTrabajoTarea $otTarea;
protected ProveedorModel $proveedorModel;
protected MaquinaModel $maquinaModel;
protected MaquinaOtTareaModel $maquinaOtTareaModel;
protected UserModel $userModel;
protected Validation $validation;
protected static $viewPath = 'themes/vuexy/form/produccion/';
@ -45,6 +52,8 @@ class Ordentrabajo extends BaseController
$this->produccionService = new ProductionService();
$this->otTarea = model(OrdenTrabajoTarea::class);
$this->maquinaModel = model(MaquinaModel::class);
$this->maquinaOtTareaModel = model(MaquinaOtTareaModel::class);
$this->proveedorModel = model(ProveedorModel::class);
$this->validation = service("validation");
helper("time");
parent::initController($request, $response, $logger);
@ -105,11 +114,13 @@ class Ordentrabajo extends BaseController
public function update_orden_trabajo_tarea()
{
$bodyData = $this->request->getPost();
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "data" => $bodyData]);
$validated = $this->validation->run($bodyData, "orden_trabajo_tarea");
if ($validated) {
$tareaEntity = $this->otTarea->find($bodyData["orden_trabajo_tarea_id"]);
$this->produccionService->init($tareaEntity->orden_trabajo_id);
$r = $this->produccionService->updateOrdenTrabajoTarea($bodyData["orden_trabajo_tarea_id"], $bodyData);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $bodyData]);
$tareaEntity = $this->otTarea->find($bodyData["orden_trabajo_tarea_id"]);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $tareaEntity]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
@ -138,6 +149,18 @@ class Ordentrabajo extends BaseController
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function update_presupuesto_tarea_proveedor()
{
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "proveedor_tarea");
if ($validated) {
$validatedData = $this->validation->getValidated();
$r = $this->produccionService->updateProveedorLinea($validatedData['orden_trabajo_tarea_id'], $validatedData['proveedor_id']);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function reset_orden_trabajo_date()
{
$bodyData = $this->request->getPost();
@ -146,6 +169,7 @@ class Ordentrabajo extends BaseController
if ($validated) {
$validatedData = $bodyData;
$r = $this->produccionService->emptyOrdenTrabajoDate($validatedData['orden_trabajo_id'], $validatedData['name']);
$this->produccionService->init($validatedData['orden_trabajo_id']); // Re-init service to update the state of the OT
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "user" => auth()->user(), "data" => $bodyData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
@ -201,13 +225,18 @@ class Ordentrabajo extends BaseController
$this->viewData["user_dates"] = $this->produccionService->userDates();
$this->viewData["pedido_user_dates"] = $this->produccionService->pedidoUserDates();
$this->viewData["colors"] = $this->produccionService->getPdfColors();
$this->viewData["tiempo_estimado"] = $this->produccionService->getTiempoProcesamientoHHMM();
$this->viewData["tiempo_estimado"] = $this->produccionService->getTiempoProcesamientoHHMMSS();
$this->viewData["flags"] = $this->produccionService->getFlags();
$this->viewData["tareaCosido"] = $this->produccionService->getTareaCosido();
return view(static::$viewPath . $this->editRoute, $this->viewData);
}
/**
* DataTable for Ordenes de Trabajo Finalizadas
* @return \CodeIgniter\HTTP\ResponseInterface
*/
public function datatable()
{
$logo = config(LogoImpresion::class);
@ -221,14 +250,18 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_pendientes()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->whereIn("ordenes_trabajo.estado", ["I", "PM"]);
// return $this->response->setJSON($q->get()->getResultArray());
$q = $this->otModel->getDatatableQuery()
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
->where('ordenes_trabajo.preimpresion_revisada', true)
->where('ordenes_trabajo.is_pedido_espera', false)
->where('ordenes_trabajo.progreso <=', 0);
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
@ -236,13 +269,14 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_ferro_pendiente()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where("ferro_ok_at", null);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro', 1)->where("ferro_ok_at", null);
// return $this->response->setJSON($q->get()->getResultArray());
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
@ -251,13 +285,14 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_ferro_ok()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where("ferro_ok_at is NOT NULL", NULL, FALSE);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro', 1)->where("ferro_ok_at is NOT NULL", NULL, FALSE);
// return $this->response->setJSON($q->get()->getResultArray());
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
@ -266,6 +301,77 @@ class Ordentrabajo extends BaseController
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_news()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
->where('ordenes_trabajo.preimpresion_revisada', false)
->where('ordenes_trabajo.is_pedido_espera', false);
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_prod()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
->where('ordenes_trabajo.preimpresion_revisada', true)
->where('ordenes_trabajo.is_pedido_espera', false)
->where('ordenes_trabajo.progreso >', 0)
->where('pedidos.estado', 'produccion');
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_waiting()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()
->whereIn("ordenes_trabajo.estado", ["I", "PM"])
->where('ordenes_trabajo.is_pedido_espera', 1);
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function datatable_revision_com()
{
$logo = config(LogoImpresion::class);
$q = $this->otModel->getDatatableQuery()->where('presupuestos.ferro', 1)->where("ferro_ok_at is NOT NULL", NULL, FALSE);
return DataTable::of($q)
->add("logo", fn($q) => ["logo" => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)), "imposicion" => $q->imposicion_name, "color" => $this->produccionService->init($q->id)->getOtColorStatus()])
->edit(
"fecha_encuadernado_at",
fn($q) => $q->fecha_encuadernado_at ? Time::createFromFormat("Y-m-d H:i:s", $q->fecha_encuadernado_at)->format("d/m/Y") : ""
)
->add("action", fn($q) => $q->id)
->add("pdf_check", fn($q) => $q->id)
->toJson(true);
}
public function papel_gramaje_datatable()
@ -286,9 +392,23 @@ class Ordentrabajo extends BaseController
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_paper'), 'data' => $q])
->toJson(true);
}
public function maquina_plana_datatable()
{
// return $this->response->setStatusCode(400);
$padreId = $this->request->getGet('padre_id');
$q = $this->produccionService->maquinaPlanaDatatableQuery();
if ($padreId) {
$q->where('lg_maquinas.padre_id', $padreId);
}
return DataTable::of($q)
->edit("tiempoReal", fn($q) => $q->tiempoReal)
->add("action", fn($q) => ["title" => lang('Produccion.datatable.filter_by_machine'), 'data' => $q])
->toJson(true);
}
public function reset_tareas(int $orden_trabajo_id)
{
$r = $this->produccionService->init($orden_trabajo_id)->resetAllTareas();
$this->produccionService->init($orden_trabajo_id); // Re-init service to update the state of the OT
return $this->response->setJSON(["message" => "Tareas reseteadas", "status" => $r]);
}
public function delete_tarea(int $orden_trabajo_tarea_id)
@ -303,8 +423,10 @@ class Ordentrabajo extends BaseController
return DataTable::of($q)
->add("action", fn($q) => $q)
->edit("orden", fn($q) => ["id" => $q->id, "orden" => $q->orden])
->edit("tiempo_estimado", fn($q) => float_seconds_to_hhmm_string($q->tiempo_estimado))
->edit("tiempo_real", fn($q) => float_seconds_to_hhmm_string($q->tiempo_real))
->add("tarea_estado", fn($q) => $this->produccionService->getTitleTareaEstado($q->id))
->edit("tiempo_estimado", fn($q) => float_seconds_to_hhmmss_string($q->tiempo_estimado))
->edit("tiempo_real", fn($q) => float_seconds_to_hhmmss_string($q->tiempo_real))
->add("proveedor", fn($q) => $this->produccionService->getProveedorTarea($q->id))
->edit("maquina_tarea", fn($q) => ["id" => $q->id, "maquina_id" => $q->maquina_tarea, "maquina_name" => $q->maquina_nombre])
->add("imposicion", fn($q) => ["id" => $q->id, "imposicion_id" => $q->imposicion_id, "name" => $q->imposicion_name, "is_presupuesto_linea" => $q->presupuesto_linea_id ? true : false])
->toJson(true);
@ -313,6 +435,14 @@ class Ordentrabajo extends BaseController
{
return $this->produccionService->init($orden_trabajo_id)->getPdf();
}
public function get_ferro_pdf($orden_trabajo_id)
{
return $this->produccionService->init($orden_trabajo_id)->getFerroPdf();
}
public function get_prototipo_pdf($orden_trabajo_id)
{
return $this->produccionService->init($orden_trabajo_id)->getPrototipoPdf();
}
public function upload_orden_trabajo_portada()
{
try {
@ -391,10 +521,7 @@ class Ordentrabajo extends BaseController
public function planning_plana_datatable()
{
$query = $this->produccionService->planningPlanaQueryDatatable();
$padreId = $this->request->getGet('padre_id');
if ($padreId) {
$query->where('lg_maquinas.padre_id', $padreId);
}
return DataTable::of($query)
->edit("tiempo_real_sum", fn($q) => $q->tiempo_real_sum)
->edit("fecha_entrega_real_at", fn($q) => $q->fecha_entrega_real_at ? Time::createFromFormat("Y-m-d", $q->fecha_entrega_real_at)->format("d/m/Y") : "")
@ -417,7 +544,8 @@ class Ordentrabajo extends BaseController
public function select_maquina_planning_plana()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectMaquinaPlanningPlana($q);
$padreId = $this->request->getGet('padre_id');
$result = $this->produccionService->querySelectMaquinaPlanningPlana($q, $padreId);
return $this->response->setJSON($result);
}
public function select_maquina_padre_planning_plana()
@ -429,7 +557,8 @@ class Ordentrabajo extends BaseController
public function select_papel_planning_plana()
{
$q = $this->request->getGet('q');
$result = $this->produccionService->querySelectPapelPlanningPlana($q);
$maquinaId = $this->request->getGet('maquina_id');
$result = $this->produccionService->querySelectPapelPlanningPlana($q,$maquinaId);
return $this->response->setJSON($result);
}
public function tarea_toggle_corte($orden_trabajo_id)
@ -520,23 +649,60 @@ class Ordentrabajo extends BaseController
['title' => $maquina->nombre, 'route' => route_to("viewProduccionMaquinistaMaquina", $maquina_id), 'active' => true],
];
$this->viewData["maquinaEntity"] = $maquina;
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTareas', $this->viewData);
$tareasRunning = $this->maquinaOtTareaModel->queryDatatableJoinOrdenTrabajo($maquina->id)->countAllResults();
if ($tareasRunning) {
return view(static::$viewPath . '/maquinista/viewProduccionMaquinistaOtTareasView', $this->viewData);
} else {
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTareas', $this->viewData);
}
}
public function maquinista_maquina_tareas_fichaje_automatico(int $maquina_id)
{
$maquina = $this->maquinaModel->find($maquina_id);
$this->viewData["maquinaEntity"] = $maquina;
return view(static::$viewPath . '/maquinista/viewMaquinistaFichajeAutomatico', $this->viewData);
}
public function maquinista_maquina_tareas_scan(int $maquina_id)
{
$maquina = $this->maquinaModel->find($maquina_id);
$this->viewData["maquinaEntity"] = $maquina;
return view(static::$viewPath . '/maquinista/viewMaquinistaTareaScan', $this->viewData);
}
public function maquinista_maquina_tarea_view(int $orden_trabajo_tarea_id)
{
$modelImpresoras = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresoras = $modelImpresoras->select('id, name')
->where('deleted_at', null)
->where('tipo', 1)
->orderBy('name', 'asc')
->findAll();
$impresoras = array_map(fn($impresora) => $impresora->toArray(), $impresoras);
$otTareaEntity = $this->otTarea->find($orden_trabajo_tarea_id);
$this->viewData['ot_tarea'] = $otTareaEntity;
$this->viewData['ot'] = $otTareaEntity->orden_trabajo();
$this->viewData['presupuesto'] = $this->viewData['ot']->presupuesto();
$this->viewData['impresoras'] = $impresoras;
$this->viewData['breadcrumb'] = [
['title' => lang("Produccion.maquinista.maquinas"), 'route' => route_to("viewProduccionMaquinistaMaquinas"), 'active' => false],
['title' => $otTareaEntity->maquina_actual()->nombre, 'route' => route_to("viewProduccionMaquinaTareasList", $otTareaEntity?->maquina_actual()?->id), 'active' => true],
['title' => $otTareaEntity->nombre, 'route' => route_to("viewProduccionMaquinistaTareaView", $otTareaEntity->id), 'active' => true]
];
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTarea', $this->viewData);
}
public function maquinista_maquina_ot_tareas_view(int $maquina_id)
{
$maquinaEntity = $this->maquinaModel->find($maquina_id);
$this->viewData['maquinaEntity'] = $maquinaEntity;
$tareasRunning = $this->maquinaOtTareaModel->queryDatatableJoinOrdenTrabajo($maquina_id)->countAllResults();
if ($tareasRunning) {
return view(static::$viewPath . '/maquinista/viewProduccionMaquinistaOtTareasView', $this->viewData);
} else {
return view(static::$viewPath . '/maquinista/viewMaquinistaMaquinaTareas', $this->viewData);
}
}
public function maquinista_colas_view()
{
return view(static::$viewPath . '/maquinista/viewMaquinistaPlanningList', $this->viewData);
@ -549,6 +715,16 @@ class Ordentrabajo extends BaseController
}
return DataTable::of($pm)
->edit('fecha_impresion', fn($q) => $q->fecha_impresion ? Time::createFromFormat('Y-m-d H:i:s', $q->fecha_impresion)->format('d/m/Y') : '')
->add("tareaEstado", fn($q) => $this->produccionService->getTitleTareaEstado($q->ot_tarea_id))
->add('action', fn($q) => $this->produccionService->buttonActionDatatableTareaList($q->ot_tarea_id))
->toJson(true);
}
public function maquinista_maquina_tareas_aplazada_datatable(int $maquina_id)
{
$pm = $this->produccionService->getMaquinaImpresionTareasList($maquina_id)->where("tarea_progress.estado", 'D');
return DataTable::of($pm)
->edit('fecha_impresion', fn($q) => $q->fecha_impresion ? Time::createFromFormat('Y-m-d H:i:s', $q->fecha_impresion)->format('d/m/Y') : '')
->add("tareaEstado", fn($q) => $this->produccionService->getTitleTareaEstado($q->ot_tarea_id))
->add('action', fn($q) => $this->produccionService->buttonActionDatatableTareaList($q->ot_tarea_id))
->toJson(true);
}
@ -559,10 +735,16 @@ class Ordentrabajo extends BaseController
try {
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "orden_trabajo_tarea_progress_date");
// return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "data" => $this->validation->getValidated(),"errors" => $this->validation->getErrors()]);
if ($validated) {
$r = $this->produccionService->storeOrdenTrabajoTareaProgressDate($this->validation->getValidated());
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $bodyData]);
$validatedData = $this->validation->getValidated();
$r = $this->produccionService->storeOrdenTrabajoTareaProgressDate($validatedData);
$otTareaEntity = $this->otTarea->find($validatedData['ot_tarea_id']);
$data = [
"tiempo_trabajado" => float_seconds_to_hhmmss_string($otTareaEntity->tiempo_real),
"tarea" => $otTareaEntity,
"estado" => $validatedData['estado'],
];
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $data]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
@ -572,7 +754,6 @@ class Ordentrabajo extends BaseController
}
public function delete_orden_trabajo_progress_date(int $orden_trabajo_tarea_id)
{
$status = $this->produccionService->deleteOrdenTrabajoTareaProgressDates($orden_trabajo_tarea_id);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $status]);
}
@ -580,9 +761,248 @@ class Ordentrabajo extends BaseController
{
$otTareaEntity = $this->otTarea->find($orden_trabajo_tarea_id);
$data = [
"tiempo_trabajado" => float_seconds_to_hhmm_string($otTareaEntity->tiempo_trabajado()),
"tiempo_trabajado" => float_seconds_to_hhmmss_string($otTareaEntity->tiempo_trabajado()),
"progress_dates" => $otTareaEntity->progress_dates(),
];
return $this->response->setJSON($data);
}
public function update_pod_pedido_dates($orden_trabajo_id)
{
$this->produccionService->init($orden_trabajo_id);
if ($this->produccionService->isPOD) {
$status = $this->produccionService->updatePodDates();
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $status, "data" => $this->produccionService->getPedido()]);
} else {
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => false, "data" => $this->produccionService->getPedido()]);
}
}
public function get_orden_trabajo_tareas_dates($orden_trabajo_id)
{
$data = $this->produccionService->init($orden_trabajo_id)->getOrdenTrabajoTareaDates();
return $this->response->setJSON(["data" => $data]);
}
public function get_tareas_ot_maquina(int $orden_trabajo_id, int $maquina_id)
{
$tareasWithMaquina = $this->produccionService->init($orden_trabajo_id)->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
if ($tareasWithMaquina) {
$data = [
'tareas' => $tareasWithMaquina,
'ot' => $this->produccionService->getOrdenTrabajo(),
'presupuesto' => $this->produccionService->getPresupuesto()
];
return $this->response->setJSON(["message" => lang("App.global_alert_fetch_success"), "data" => $data]);
} else {
$tareasWithMaquina = $this->produccionService->init($orden_trabajo_id)->getTareasWithMaquina($maquina_id, ['F']);
if ($tareasWithMaquina) {
return $this->response->setJSON(["message" => lang("Produccion.errors.tareas_finalizadas"), "data" => $tareasWithMaquina])->setStatusCode(400);
} else {
return $this->response->setJSON(["message" => lang("Produccion.errors.maquina_not_in_ot"), "data" => null])->setStatusCode(400);
}
}
}
public function update_orden_trabajo_fa_tareas()
{
$responseData = [
"tiempo_total_estimado" => 0,
"tiempo_total_real" => 0,
"clicks_total" => 0,
"tirada_total" => 0,
"estado" => "P",
];
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "orden_trabajo_fichaje_auto");
if ($validated) {
$validatedData = $this->validation->getValidated();
$this->produccionService->init($validatedData['orden_trabajo_id']);
foreach ($validatedData['tareas'] as $key => $tareaId) {
$this->produccionService->storeOrdenTrabajoTareaProgressDate(
[
'estado' => $validatedData['estado'],
'ot_tarea_id' => $tareaId
]
);
$tareaEntity = $this->otTarea->find($tareaId);
$tiempo_trabajado = $tareaEntity->tiempo_trabajado();
$responseData['tiempo_total_estimado'] += $tareaEntity->tiempo_estimado;
$responseData['tiempo_total_real'] += $tiempo_trabajado;
$responseData["estado"] = $validatedData["estado"];
$tareaEntity->tiempo_real = $tiempo_trabajado / count($validatedData['tareas']);
$tareaEntity->click_init = $validatedData['click_init'] / count($validatedData['tareas']);
$tareaEntity->click_end = $validatedData['click_end'] / count($validatedData['tareas']);
$this->otTarea->save($tareaEntity);
}
$responseData['tiempo_total_estimado'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_estimado']);
$responseData['tiempo_total_real'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_real']);
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => true, "data" => $responseData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function delete_orden_trabajo_fa_tareas()
{
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "orden_trabajo_fichaje_auto");
if ($validated) {
$validatedData = $this->validation->getValidated();
$this->produccionService->init($validatedData['orden_trabajo_id']);
foreach ($validatedData['tareas'] as $key => $tareaId) {
$this->produccionService->deleteOrdenTrabajoTareaProgressDates($tareaId);
}
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => true, "data" => $validatedData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function store_maquina_ordenes_trabajo()
{
$bodyData = $this->request->getPost();
$validated = $this->validation->run($bodyData, "maquina_ordenes_trabajo");
if ($validated) {
$validatedData = $this->validation->getValidated();
foreach ($validatedData['ordenes_trabajo'] as $key => $orden_trabajo_id) {
$maquinaOtTarea = $this->maquinaOtTareaModel->where('orden_trabajo_id', $orden_trabajo_id)->where('maquina_id', $validatedData['maquina_id'])->where('deleted_at', null)->countAllResults();
if ($maquinaOtTarea) {
continue;
}
$this->maquinaOtTareaModel->insert(['maquina_id' => $validatedData['maquina_id'], 'orden_trabajo_id' => $orden_trabajo_id]);
}
return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => true, "data" => $validatedData]);
} else {
return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
}
}
public function update_maquina_ordenes_trabajo_estado()
{
$bodyData = $this->request->getPost();
$maquina_id = $bodyData['maquina_id'];
$estado = $bodyData['estado'];
$maquina_ots = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->findAll();
$totalTareas = [];
foreach ($maquina_ots as $key => $maquina_ot) {
$tareas = $this->produccionService->init($maquina_ot->orden_trabajo_id)
->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
foreach ($tareas as $key => $tarea) {
$this->produccionService->storeOrdenTrabajoTareaProgressDate(
[
'estado' => $estado,
'ot_tarea_id' => $tarea->id
]
);
$tarea->click_init = $bodyData['click_init'];
$tarea->click_end = $bodyData['click_end'];
$totalTareas[] = $tarea;
}
}
foreach ($totalTareas as $key => $tarea) {
$tiempo_trabajado = $tarea->tiempo_trabajado();
$tarea->tiempo_real = $tiempo_trabajado / count($totalTareas);
$tarea->click_init = $tarea->click_init / count($totalTareas);
$tarea->click_end = $tarea->click_end / count($totalTareas);
$this->otTarea->save($tarea);
}
if ($estado == "F") {
$this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->delete();
}
return $this->response->setJSON(["message" => lang("Produccion.responses.update_maquina_ordenes_trabajo_estado")]);
}
public function delete_maquina_orden_trabajo_tarea($maquina_orden_trabajo_tarea_id)
{
$status = $this->maquinaOtTareaModel->delete($maquina_orden_trabajo_tarea_id);
return $this->response->setJSON(["message" => lang("App.user_alert_delete"), "status" => $status]);
}
public function delete_maquina_orden_trabajo_all($maquina_id)
{
$maquina_ots = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->findAll();
foreach ($maquina_ots as $key => $maquina_ot) {
$tareas = $this->produccionService->init($maquina_ot->orden_trabajo_id)
->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
foreach ($tareas as $key => $tarea) {
$this->produccionService->deleteOrdenTrabajoTareaProgressDates($tarea->id);
}
}
$status = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->delete();
return $this->response->setJSON(["message" => lang("App.user_alert_delete"), "status" => $status]);
}
public function datatable_maquina_ordenes_trabajo($maquina_id)
{
$query = $this->maquinaOtTareaModel->queryDatatableJoinOrdenTrabajo($maquina_id);
return DataTable::of($query)
->add('action', fn($q) => $q->otId)
->add('titulo', fn($q) => $this->otModel->find($q->otId)->presupuesto()->titulo)
->add('barcode', fn($q) => $this->otModel->find($q->otId)->getBarCode())
->toJson(true);
}
public function get_maquina_ots($maquina_id)
{
$responseData = [
"tiempo_total_estimado" => 0,
"tiempo_total_real" => 0,
"clicks_total" => 0,
"tirada_total" => 0,
"estado" => "P",
];
$maquina_ots = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->findAll();
foreach ($maquina_ots as $key => $maquina_ot) {
$tareas = $this->produccionService->init($maquina_ot->orden_trabajo_id)
->getTareasWithMaquina($maquina_id, ['P', 'I', 'S', 'D']);
foreach ($tareas as $key => $tarea) {
$responseData['tiempo_total_estimado'] += $tarea->tiempo_estimado;
$responseData['tiempo_total_real'] += $tarea->tiempo_real;
$responseData["estado"] = $tarea->lastState()->estado;
if ($tarea->presupuesto_linea_id) {
$responseData["clicks_total"] += $tarea->presupuesto_linea()->rotativa_clicks_total;
$responseData["tirada_total"] += $tarea->orden_trabajo()->presupuesto()->tirada;
}
}
}
$responseData['tiempo_total_estimado'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_estimado']);
$responseData['tiempo_total_real'] = float_seconds_to_hhmmss_string($responseData['tiempo_total_real']);
return $this->response->setJSON($responseData);
}
public function printPackagingLabels()
{
$ot_id = $this->request->getPost('ot_id') ?? null;
$unidades_caja = $this->request->getPost('unidades_caja') ?? null;
$impresora_id = $this->request->getPost('impresora_id') ?? null;
if ($ot_id == null || $impresora_id == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.errorMissingData')
];
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name, description, ip, port, user, pass')
->where('deleted_at', null)
->where('id', $impresora_id)
->orderBy('name', 'asc')
->first();
if ($impresora == null) {
return $this->response->setJSON([
'status' => false,
'message' => 'Impresora no válida'
]);
}
$printerService = new ImpresoraEtiquetaService();
$result = $printerService->generateEtiquetasEmbalaje($ot_id, $unidades_caja, $impresora);
return $this->response->setJSON($result);
}
public function get_ot_pdf_content($orden_trabajo_id)
{
return $this->produccionService->init($orden_trabajo_id)->getPdfContent();
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Controllers\Scripts;
use App\Controllers\BaseController;
use App\Models\Usuarios\UserModel;
use App\Entities\Usuarios\UserEntity;
use CodeIgniter\Shield\Authentication\Passwords\IdentityModel;
class UsersIntegrity extends BaseController
{
public function completarIdentidades()
{
$userModel = new UserModel();
// Buscar usuarios safekat.com no eliminados
$usuarios = $userModel
->where('deleted_at', null)
//->like('username', '@safekat.com')
->findAll();
$resultados = [];
foreach ($usuarios as $usuario) {
$email = $usuario->username . "@safekat.com";
// 1. Verificar si el usuario ya tiene identidad tipo email_password
$tieneIdentidad = array_filter(
$usuario->getIdentities(),
fn($identity) => $identity->type === 'email_password'
);
if (!empty($tieneIdentidad)) {
$resultados[] = "✅ Ya tiene identidad: {$email}";
continue;
}
// 2. Verificar si ya existe una identidad globalmente con ese email
$db = db_connect();
$builder = $db->table('auth_identities');
$existeGlobal = $builder
->where('type', 'email_password')
->where('secret', $email)
->get()
->getFirstRow();
if ($existeGlobal) {
$resultados[] = "⚠️ Email ya registrado en otra identidad: {$email}";
continue;
}
// 3. Crear y guardar identidad
try {
$identity = $usuario->createEmailIdentity([
'email' => $email,
'password' => 'Temporal123!', // reemplazar por valor real si lo tenés
]);
//$userModel->saveEmailIdentity($identity);
$resultados[] = " Identidad creada: {$email}";
} catch (\Throwable $e) {
$resultados[] = "❌ Error con {$email}: " . $e->getMessage();
}
}
return $this->response->setJSON([
'status' => 'completado',
'procesados' => count($usuarios),
'resultados' => $resultados,
]);
}
}

View File

@ -0,0 +1,494 @@
<?php
namespace App\Controllers\Sistema;
use App\Controllers\BaseController;
use App\Models\Sistema\BackupModel;
use phpseclib3\Net\SFTP;
use ZipArchive;
class Backups extends BaseController
{
protected $backupModel;
public function __construct()
{
$this->backupModel = new BackupModel();
}
public function index()
{
helper('filesystem');
$entorno = getenv('SK_ENVIRONMENT');
$backups = [];
if ($entorno === 'development') {
// Leer archivos directamente del disco en entorno de desarrollo
$backups = [];
// === 1. Backups locales ===
$localDir = WRITEPATH . 'backups/';
$localFiles = get_filenames($localDir);
foreach ($localFiles as $file) {
if (!str_ends_with($file, '.zip') || !str_starts_with($file, 'backup_dev_')) {
continue;
}
$localPath = $localDir . $file;
$fecha = date('Y-m-d H:i', filemtime($localPath));
$tamano = filesize($localPath);
$tamanoFmt = $tamano > 1048576
? number_format($tamano / 1048576, 2) . ' MB'
: number_format($tamano / 1024, 2) . ' KB';
$backups[$file] = [
'id' => null,
'filename' => $file,
'fecha' => $fecha,
'tamano' => $tamanoFmt,
'local' => true,
'remoto' => false,
];
}
// === 2. Backups remotos en SFTP ===
$sftpHost = getenv('HIDRIVE_HOST');
$sftpUser = getenv('HIDRIVE_USER');
$sftpPass = getenv('HIDRIVE_PASS');
$remoteDir = '/users/erp2019/backups_erp/';
$sftp = new SFTP($sftpHost);
if ($sftp->login($sftpUser, $sftpPass)) {
$remoteFiles = $sftp->nlist($remoteDir);
foreach ($remoteFiles as $file) {
if (!str_ends_with($file, '.zip') || !str_starts_with($file, 'backup_')) {
continue;
}
// Verificar si ya se cargó como local
$alreadyLocal = isset($backups[$file]);
// Obtener info de archivo remoto
$stat = $sftp->stat($remoteDir . $file);
$fecha = isset($stat['mtime']) ? date('Y-m-d H:i', $stat['mtime']) : '-';
$tamano = $stat['size'] ?? null;
$tamanoFmt = $tamano > 1048576
? number_format($tamano / 1048576, 2) . ' MB'
: number_format($tamano / 1024, 2) . ' KB';
$backups[$file] = [
'id' => null,
'filename' => $file,
'fecha' => $fecha,
'tamano' => $tamanoFmt,
'local' => $alreadyLocal,
'remoto' => true,
];
}
} else {
// Opcional: mostrar un error o dejarlo pasar silenciosamente
session()->setFlashdata('warning', 'No se pudo conectar al servidor SFTP para obtener backups remotos.');
}
// Convertir a lista (por si se usó índice por filename)
$backups = array_values($backups);
} else {
// En producción: seguir usando la base de datos
$entries = $this->backupModel->orderBy('created_at', 'DESC')->findAll();
foreach ($entries as $entry) {
$file = $entry['filename'];
if (!str_ends_with($file, '.zip')) {
continue;
}
$localPath = $entry['path_local'];
$remotePath = $entry['path_remote'];
$isLocal = $localPath && file_exists($localPath);
$isRemote = !empty($remotePath);
if ($isLocal) {
$fecha = date('Y-m-d H:i', filemtime($localPath));
$tamano = filesize($localPath);
$tamanoFmt = $tamano > 1048576
? number_format($tamano / 1048576, 2) . ' MB'
: number_format($tamano / 1024, 2) . ' KB';
if ($entry['size'] != $tamano) {
$this->backupModel->update($entry['id'], [
'size' => $tamano,
]);
}
} else {
$fecha = $entry['created_at'] ?? '-';
$tamano = $entry['size'] ?? null;
$tamanoFmt = $tamano > 1048576
? number_format($tamano / 1048576, 2) . ' MB'
: number_format($tamano / 1024, 2) . ' KB';
}
$backups[] = [
'id' => $entry['id'],
'filename' => $file,
'fecha' => $fecha,
'tamano' => $tamanoFmt,
'local' => $isLocal,
'remoto' => $isRemote,
];
}
}
return view('themes/vuexy/form/backups/backupList', ['backups' => $backups]);
}
public function create()
{
if (getenv('SK_ENVIRONMENT') !== 'production') {
return redirect()->to(route_to('backupsList'))->with('error', 'No permitido en entorno de desarrollo.');
}
helper('filesystem');
$timestamp = date('Ymd_His');
$sqlFilename = "backup_{$timestamp}.sql";
$zipFilename = "backup_{$timestamp}.zip";
$sqlPath = WRITEPATH . 'backups/' . $sqlFilename;
$zipPath = WRITEPATH . 'backups/' . $zipFilename;
$dbConfig = config('Database')->default;
$host = $dbConfig['hostname'];
$username = $dbConfig['username'];
$password = $dbConfig['password'];
$database = $dbConfig['database'];
$command = "mysqldump -h {$host} -u" . escapeshellarg($username) . " -p'" . addslashes($password) . "' {$database} > {$sqlPath}";
system($command, $retval);
if ($retval !== 0) {
throw new \RuntimeException("Error al crear el backup.");
}
// Crear el zip
$zip = new ZipArchive();
if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE) {
$zip->addFile($sqlPath, $sqlFilename);
$zip->close();
unlink($sqlPath); // eliminar el .sql original
} else {
throw new \RuntimeException("Error al comprimir el backup.");
}
// Insertar en BD
$backupId = $this->backupModel->insert([
'filename' => $zipFilename,
'type' => 'manual',
'path_local' => $zipPath,
'path_remote' => null,
'size' => filesize($zipPath),
'status' => 'pendiente',
'created_at' => date('Y-m-d H:i:s')
], true);
// Enviar a SFTP
$this->sendToSFTP($zipPath, $zipFilename);
// Actualizar BD
$remotePath = "/users/erp2019/backups_erp/" . $zipFilename;
$this->backupModel->update($backupId, [
'path_remote' => $remotePath,
'status' => 'subido'
]);
return redirect()->to(route_to('backupsList'))->with('message', 'Backup del entorno de produccion creado, comprimido y enviado al remoto.');
}
public function createDevelopment()
{
if (getenv('SK_ENVIRONMENT') !== 'development') {
return redirect()->to(route_to('backupsList'))->with('error', 'Esta acción solo está permitida en desarrollo.');
}
helper('filesystem');
$timestamp = date('Ymd_His');
$sqlFilename = "backup_dev_{$timestamp}.sql";
$zipFilename = "backup_dev_{$timestamp}.zip";
$sqlPath = WRITEPATH . 'backups/' . $sqlFilename;
$zipPath = WRITEPATH . 'backups/' . $zipFilename;
$dbConfig = config('Database')->default;
$host = $dbConfig['hostname'];
$username = $dbConfig['username'];
$password = $dbConfig['password'];
$database = $dbConfig['database'];
$command = "mysqldump -h {$host} -u{$username} -p'{$password}' {$database} > {$sqlPath}";
system($command, $retval);
if ($retval !== 0) {
throw new \RuntimeException("Error al crear el backup local.");
}
$zip = new \ZipArchive();
if ($zip->open($zipPath, \ZipArchive::CREATE) === TRUE) {
$zip->addFile($sqlPath, $sqlFilename);
$zip->close();
unlink($sqlPath);
} else {
throw new \RuntimeException("Error al comprimir el backup local.");
}
// Ya no insertamos en la base de datos; el archivo queda en disco y se listará dinámicamente
return redirect()->to(route_to('backupsList'))->with('message', 'Backup local del entorno de desarrollo creado.');
}
public function download($filename)
{
helper('filesystem');
$entorno = getenv('SK_ENVIRONMENT');
$backup = $this->backupModel->where('filename', $filename)->first();
// 1. Si hay entrada en la base de datos
if ($backup) {
$localPath = $backup['path_local'];
$remotePath = $backup['path_remote'];
if ($localPath && file_exists($localPath)) {
return $this->response->download($localPath, null)->setFileName($filename);
}
if (!empty($remotePath)) {
$sftpHost = getenv('HIDRIVE_HOST');
$sftpUser = getenv('HIDRIVE_USER');
$sftpPass = getenv('HIDRIVE_PASS');
$sftp = new SFTP($sftpHost);
if (!$sftp->login($sftpUser, $sftpPass)) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo conectar al servidor SFTP.');
}
$fileContents = $sftp->get($remotePath);
if ($fileContents === false) {
return redirect()->to(route_to('backupsList'))->with('error', 'Error al descargar desde SFTP.');
}
$newLocalPath = WRITEPATH . 'backups/' . $filename;
write_file($newLocalPath, $fileContents);
// Omitimos update() si estamos en desarrollo sin base de datos
if ($entorno === 'production') {
$this->backupModel->update($backup['id'], ['path_local' => $newLocalPath]);
}
return $this->response->download($newLocalPath, null)->setFileName($filename);
}
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo encontrar el archivo ni local ni remoto.');
}
// 2. Si NO hay entrada en la BD y estamos en desarrollo
if ($entorno === 'development') {
$localPath = WRITEPATH . 'backups/' . $filename;
if (file_exists($localPath)) {
return $this->response->download($localPath, null)->setFileName($filename);
}
// También se puede intentar buscar en el SFTP si quieres
$sftpHost = getenv('HIDRIVE_HOST');
$sftpUser = getenv('HIDRIVE_USER');
$sftpPass = getenv('HIDRIVE_PASS');
$remotePath = '/users/erp2019/backups_erp/' . $filename;
$sftp = new SFTP($sftpHost);
if ($sftp->login($sftpUser, $sftpPass)) {
$fileContents = $sftp->get($remotePath);
if ($fileContents !== false) {
$newLocalPath = WRITEPATH . 'backups/' . $filename;
write_file($newLocalPath, $fileContents);
return $this->response->download($newLocalPath, null)->setFileName($filename);
}
}
return redirect()->to(route_to('backupsList'))->with('error', 'Archivo no encontrado local ni remoto (sin base de datos).');
}
return redirect()->to(route_to('backupsList'))->with('error', 'Backup no encontrado.');
}
public function deleteLocal($id)
{
$entorno = getenv('SK_ENVIRONMENT');
$backup = $this->backupModel->find($id);
if (!$backup) {
return redirect()->to(route_to('backupsList'))->with('error', 'Backup no encontrado en la base de datos.');
}
$localPath = $backup['path_local'];
// Si existe el archivo, intentamos borrarlo
if ($localPath && file_exists($localPath)) {
unlink($localPath);
}
if ($entorno === 'production') {
// Solo desvincular el archivo local
$this->backupModel->update($id, ['path_local' => null]);
return redirect()->to(route_to('backupsList'))->with('message', 'Archivo local eliminado (registro conservado).');
} else {
// Eliminar completamente en desarrollo
$this->backupModel->delete($id);
return redirect()->to(route_to('backupsList'))->with('message', 'Backup de desarrollo eliminado completamente.');
}
}
public function deleteLocalDevelopment($filename)
{
$entorno = getenv('SK_ENVIRONMENT');
if ($entorno !== 'development') {
return redirect()->to(route_to('backupsList'))->with('error', 'Solo permitido en desarrollo.');
}
$path = WRITEPATH . 'backups/' . $filename;
if (file_exists($path)) {
unlink($path);
return redirect()->to(route_to('backupsList'))->with('message', "Archivo '$filename' eliminado del sistema de archivos.");
}
return redirect()->to(route_to('backupsList'))->with('error', "Archivo '$filename' no encontrado en el sistema.");
}
public function restoreLocal($file)
{
$path = WRITEPATH . 'backups/' . $file;
if (!file_exists($path)) {
throw new \CodeIgniter\Exceptions\PageNotFoundException("Backup no encontrado.");
}
$zip = new \ZipArchive();
if ($zip->open($path) === TRUE) {
$extractPath = WRITEPATH . 'backups/tmp_restore/';
if (!is_dir($extractPath)) {
mkdir($extractPath, 0775, true);
}
$zip->extractTo($extractPath);
$zip->close();
$sqlFiles = glob($extractPath . '*.sql');
if (count($sqlFiles) === 0) {
throw new \RuntimeException("No se encontró ningún archivo .sql en el ZIP");
}
$sqlFile = $sqlFiles[0];
$dbConfig = config('Database')->default;
$host = $dbConfig['hostname'];
$username = $dbConfig['username'];
$password = $dbConfig['password'];
$database = $dbConfig['database'];
$cmd = "mysql -h {$host} -u{$username} -p'{$password}' {$database} < {$sqlFile}";
system($cmd, $retval);
if ($retval !== 0) {
throw new \RuntimeException("Error al restaurar la base de datos. Código: $retval");
}
array_map('unlink', glob($extractPath . '*'));
rmdir($extractPath);
return redirect()->to(route_to('backupsList'))->with('message', 'Backup restaurado correctamente (vía sistema).');
} else {
throw new \RuntimeException("No se pudo abrir el archivo ZIP");
}
}
public function restoreRemote($filename)
{
helper('filesystem');
// Buscar el backup en la base de datos
$backup = $this->backupModel->where('filename', $filename)->first();
if (!$backup || empty($backup['path_remote'])) {
return redirect()->to(route_to('backupsList'))->with('error', 'Backup remoto no encontrado en la base de datos.');
}
// Parámetros SFTP
$sftpHost = getenv('HIDRIVE_HOST');
$sftpUser = getenv('HIDRIVE_USER');
$sftpPass = getenv('HIDRIVE_PASS');
$remotePath = $backup['path_remote'];
$localPath = WRITEPATH . 'backups/' . $filename;
// Conectar al SFTP
$sftp = new SFTP($sftpHost);
if (!$sftp->login($sftpUser, $sftpPass)) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.');
}
// Descargar el archivo
$fileContents = $sftp->get($remotePath);
if ($fileContents === false) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.');
}
// Guardar localmente
if (write_file($localPath, $fileContents) === false) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.');
}
// Actualizar la base de datos para marcar el archivo como local
$this->backupModel->update($backup['id'], [
'path_local' => $localPath,
]);
// Restaurar usando el método local
return $this->restoreLocal($filename);
}
private function sendToSFTP($localPath, $remoteFilename)
{
$sftpHost = getenv('HIDRIVE_HOST');
$sftpUser = getenv('HIDRIVE_USER');
$sftpPass = getenv('HIDRIVE_PASS');
$remotePath = '/users/erp2019/backups_erp/' . $remoteFilename;
$sftp = new SFTP($sftpHost);
if (!$sftp->login($sftpUser, $sftpPass)) {
throw new \RuntimeException('Error de autenticación SFTP');
}
$fileContents = file_get_contents($localPath);
if (!$sftp->put($remotePath, $fileContents)) {
throw new \RuntimeException("No se pudo subir el backup al servidor SFTP.");
}
}
}

View File

@ -153,7 +153,10 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController
return $this->redirect2listView();
endif;
$id = filter_var($requestedId, FILTER_SANITIZE_URL);
$ticket = $this->model->find($id);
$ticket = $this->model->select("tickets.*, CONCAT(users.first_name, ' ',users.last_name) as usuario_ticket")
->join('users', 'users.id = tickets.usuario_id', 'left')
->where('tickets.id', $id)->first();
if ($ticket == false):
$message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Tickets.ticket')), $id]);
@ -275,7 +278,7 @@ class Ticketcontroller extends \App\Controllers\BaseResourceController
$searchValues = get_filter_datatables_columns($reqData);
if (auth()->user()->can('tickets.edit')) {
if (auth()->user()->can('tickets.edit') && auth()->user()->inGroup('admin')) {
$user_id = null;
} else {
$user_id = auth()->user()->id;

View File

@ -80,7 +80,7 @@ class ServiciosAcabado extends BaseResourceController
$sanitizedData['user_updated_id'] = auth()->user()->id;
if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) {
$sanitizedData['mostrar_en_presupuesto'] = false;
$sanitizedData['mostrar_en_presupuesto_cliente'] = false;
}
if ($this->request->getPost('acabado_cubierta') == null) {
@ -174,7 +174,7 @@ class ServiciosAcabado extends BaseResourceController
$sanitizedData['user_updated_id'] = auth()->user()->id;
if ($this->request->getPost('mostrar_en_presupuesto_cliente') == null) {
$sanitizedData['mostrar_en_presupuesto'] = false;
$sanitizedData['mostrar_en_presupuesto_cliente'] = false;
}
if ($this->request->getPost('acabado_cubierta') == null) {

View File

@ -12,7 +12,6 @@ use App\Models\Presupuestos\ImportadorModel;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Usuarios\GroupModel;
use App\Models\Catalogo\CatalogoLibroModel;
use App\Models\Catalogo\IdentificadorIskModel;
use App\Services\PresupuestoService;
use CodeIgniter\Shield\Entities\User;
@ -30,23 +29,9 @@ class Test extends BaseController
}
private function index()
public function index()
{
$modelCL = new CatalogoLibroModel();
$modelISK = new IdentificadorIskModel();
// Obtener todos los registros sin isk
$registros = $modelCL->where('isk', null)->findAll();
$i = 0;
foreach ($registros as $registro) {
$isk = $modelISK->newIsk();
$modelCL->update($registro->id, ['isk' => $isk]);
echo "[" . $i++ . "]Asignado ISK {$isk} a ID {$registro->id}<br>";
}
}

View File

@ -11,69 +11,78 @@ class CreateCatalogoLibros extends Migration
$this->db->query('SET foreign_key_checks = 0');
$this->forge->addField([
'id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'auto_increment' => true],
'cliente_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'proveedor_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'user_created_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'default' => 1],
'user_update_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'default' => 1],
'cubierta_archivo' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'cubierta_url' => ['type' => 'VARCHAR', 'constraint' => 500, 'null' => true],
'ancho' => ['type' => 'DOUBLE', 'constraint' => '8,2'],
'alto' => ['type' => 'DOUBLE', 'constraint' => '8,2'],
'peso' => ['type' => 'DOUBLE', 'constraint' => '8,2', 'null' => true],
'titulo' => ['type' => 'VARCHAR', 'constraint' => 300],
'autor' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'autor_entidad' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'traductor' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'ilustrador' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'idioma' => ['type' => 'VARCHAR', 'constraint' => 3, 'default' => 'spa'],
'num_edic' => ['type' => 'INT', 'default' => 1, 'null' => true],
'fecha_disponibilidad' => ['type' => 'DATE', 'null' => true],
'fecha_public' => ['type' => 'DATE', 'null' => true],
'num_fotos' => ['type' => 'INT', 'default' => 0],
'num_ilustr' => ['type' => 'INT', 'default' => 0],
'num_ilustr_color' => ['type' => 'INT', 'default' => 0],
'num_ilustr_bn' => ['type' => 'INT', 'default' => 0],
'coleccion' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'isk' => ['type' => 'VARCHAR', 'constraint' => 64, 'null' => true],
'isbn' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'ean' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'editorial' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'resumen' => ['type' => 'TEXT', 'null' => true],
'resumen_breve' => ['type' => 'TEXT', 'null' => true],
'sello' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'paginas' => ['type' => 'INT'],
'tipo_impresion' => ['type' => 'ENUM', 'constraint' => ['negro','negrohq','color','colorhq'], 'null' => true],
'comentarios' => ['type' => 'TEXT', 'null' => true],
'negro_paginas' => ['type' => 'INT', 'null' => true],
'negro_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'negro_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'negro_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'negro_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'color_paginas' => ['type' => 'INT', 'null' => true],
'color_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'color_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'color_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'color_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'cubierta_paginas' => ['type' => 'INT', 'null' => true],
'cubierta_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'cubierta_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'cubierta_acabado_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'cubierta_ancho_solapas' => ['type' => 'DOUBLE', 'constraint' => '8,2', 'default' => 0.00, 'unsigned' => true],
'cubierta_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'cubierta_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'sobrecubierta_paginas' => ['type' => 'INT', 'null' => true],
'sobrecubierta_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'sobrecubierta_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'auto_increment' => true],
'cliente_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'proveedor_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'user_created_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'default' => 1],
'user_update_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'default' => 1],
'cubierta_archivo' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'cubierta_url' => ['type' => 'VARCHAR', 'constraint' => 500, 'null' => true],
'ancho' => ['type' => 'DOUBLE', 'constraint' => '8,2'],
'alto' => ['type' => 'DOUBLE', 'constraint' => '8,2'],
'peso' => ['type' => 'DOUBLE', 'constraint' => '8,2', 'null' => true],
'titulo' => ['type' => 'VARCHAR', 'constraint' => 300],
'autor' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'autor_entidad' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'traductor' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'ilustrador' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'idioma' => ['type' => 'VARCHAR', 'constraint' => 3, 'default' => 'spa'],
'num_edic' => ['type' => 'INT', 'default' => 1, 'null' => true],
'fecha_disponibilidad' => ['type' => 'DATE', 'null' => true],
'fecha_public' => ['type' => 'DATE', 'null' => true],
'num_fotos' => ['type' => 'INT', 'default' => 0],
'num_ilustr' => ['type' => 'INT', 'default' => 0],
'num_ilustr_color' => ['type' => 'INT', 'default' => 0],
'num_ilustr_bn' => ['type' => 'INT', 'default' => 0],
'coleccion' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'isk' => ['type' => 'VARCHAR', 'constraint' => 64, 'null' => true],
'isbn' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'ean' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'editorial' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'resumen' => ['type' => 'TEXT', 'null' => true],
'resumen_breve' => ['type' => 'TEXT', 'null' => true],
'sello' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'paginas' => ['type' => 'INT'],
'tipo_impresion' => ['type' => 'ENUM', 'constraint' => ['negro', 'negrohq', 'color', 'colorhq'], 'null' => true],
'comentarios' => ['type' => 'TEXT', 'null' => true],
'negro_paginas' => ['type' => 'INT', 'null' => true],
'negro_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'negro_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'negro_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'negro_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'color_paginas' => ['type' => 'INT', 'null' => true],
'color_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'color_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'color_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'color_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'cubierta_paginas' => ['type' => 'INT', 'null' => true],
'cubierta_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'cubierta_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'cubierta_acabado_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'cubierta_ancho_solapas' => ['type' => 'DOUBLE', 'constraint' => '8,2', 'default' => 0.00, 'unsigned' => true],
'cubierta_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'cubierta_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'sobrecubierta_paginas' => ['type' => 'INT', 'null' => true],
'sobrecubierta_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'sobrecubierta_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'sobrecubierta_acabado_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'sobrecubierta_ancho_solapas' => ['type' => 'DOUBLE', 'constraint' => '8,2', 'default' => 0.00, 'unsigned' => true],
'sobrecubierta_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'sobrecubierta_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'encuadernacion_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'ubicacion' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'created_at' => ['type' => 'TIMESTAMP', 'default' => 'CURRENT_TIMESTAMP'],
'updated_at' => ['type' => 'TIMESTAMP', 'null' => true],
'deleted_at' => ['type' => 'TIMESTAMP', 'null' => true],
'sobrecubierta_pod_papel_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'sobrecubierta_pod_gramaje' => ['type' => 'DOUBLE', 'null' => true],
'encuadernacion_id' => ['type' => 'INT', 'constraint' => 10, 'unsigned' => true, 'null' => true],
'ubicacion' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'created_at' => [
'type' => 'TIMESTAMP',
'default' => new \CodeIgniter\Database\RawSql('CURRENT_TIMESTAMP'),
],
'updated_at' => [
'type' => 'TIMESTAMP',
'null' => true,
],
'deleted_at' => [
'type' => 'TIMESTAMP',
'null' => true,
],
]);
$this->forge->addKey('id', true);

View File

@ -7,30 +7,24 @@ use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
use CodeIgniter\I18n\Time;
class AddClickColumnOrdenTrabajoTarea extends Migration
class AddFerroProtoPresupuestoDirecciones extends Migration
{
protected array $COLUMNS = [
"click_init" => [
"type" => "INT",
"is_ferro_prototipo" => [
"type" => "TINYINT",
"unsigned" => true,
"default" => 0,
"comment" => "Click iniciales de una tarea de impresion"
],
"click_end" => [
"type" => "INT",
"unsigned" => true,
"default" => 0,
"comment" => "Click finales de una tarea de impresion"
"comment" => "Indica si es una direccion para el prototipo o ferro",
],
];
public function up()
{
$this->forge->addColumn('orden_trabajo_tareas', $this->COLUMNS);
$this->forge->addColumn('presupuesto_direcciones', $this->COLUMNS);
}
public function down()
{
$this->forge->dropColumn('orden_trabajo_tareas', array_keys($this->COLUMNS));
$this->forge->dropColumn('presupuesto_direcciones', array_keys($this->COLUMNS));
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Database\Migrations;
use App\Models\OrdenTrabajo\OrdenTrabajoTarea;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
use CodeIgniter\I18n\Time;
class AddTipoEnvioEnvios extends Migration
{
protected array $COLUMNS = [
"tipo_envio" => [
"type" => "enum",
"constraint" => ['estandar', 'ferro_prototipo'],
"default" => 'estandar',
"comment" => "Indica el tipo de envio",
],
];
public function up()
{
$this->forge->addColumn('envios', $this->COLUMNS);
}
public function down()
{
$this->forge->dropColumn('envios', array_keys($this->COLUMNS));
}
}

View File

@ -4,7 +4,7 @@ namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddPliegoColumnOrdenTrabajoTarea extends Migration
class AlterFkOrdenTrabajoTareaProgressDates extends Migration
{

View File

@ -0,0 +1,49 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\RawSql;
use CodeIgniter\Database\Migration;
class CreateTableFestivos extends Migration
{
protected array $COLUMNS = [
"id" => [
"type" => "INT",
"unsigned" => true,
"auto_increment" => true
],
"date" => [
"type" => "DATE",
"unique" => true,
],
];
public function up()
{
$this->forge->addField($this->COLUMNS);
$currenttime = new RawSql("CURRENT_TIMESTAMP");
$this->forge->addField([
"created_at" => [
"type" => "TIMESTAMP",
"default" => $currenttime,
],
"updated_at" => [
"type" => "TIMESTAMP",
"null" => true,
],
"deleted_at" => [
"type" => "TIMESTAMP",
"null" => true,
],
]);
$this->forge->addPrimaryKey('id');
$this->forge->createTable("festivos", true);
}
public function down()
{
//
$this->forge->dropTable("festivos", true);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\RawSql;
use CodeIgniter\Database\Migration;
class AddClienteNoBasePODnoHQ extends Migration
{
protected array $COLUMNS = [
"no_envio_base" => [
"type" => "TINYINT",
"default" => 0,
],
"forzar_rotativa_pod" => [
"type" => "TINYINT",
"default" => 0,
],
];
public function up()
{
$this->forge->addColumn('clientes', $this->COLUMNS);
}
public function down()
{
//
$this->forge->dropColumn('clientes', array_keys($this->COLUMNS));
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AlterTarifasAcabadoAddBoleanColumns extends Migration
{
protected array $COLUMNS = [
'plastificado' => [
'type' => 'BOOLEAN',
'default' => false,
],
'plakene' => [
'type' => 'BOOLEAN',
'default' => false,
],
'rectractilado' => [
'type' => 'BOOLEAN',
'default' => false,
],
'estampado' => [
'type' => 'BOOLEAN',
'default' => false,
],
'uvi' => [
'type' => 'BOOLEAN',
'default' => false,
],
'plastificado_tipo' => [
'type' => 'ENUM',
'constraint' => ['BRILLO','MATE','SANDY','GOFRADO','SOFT','ANTIRAYADO'],
'null' => true,
],
'plakene_tipo' => [
'type' => 'ENUM',
'constraint' => ['TRASLUCIDO','MATE','NEGRO'],
'null' => true,
],
'rectractilado_tipo' => [
'type' => 'ENUM',
'constraint' => ['1','3','5'],
'null' => true,
],
'estampado_tipo' => [
'type' => 'ENUM',
'constraint' => ['ORO','PLATA','COBRE','BRONCE'],
'null' => true,
],
'uvi_tipo' => [
'type' => 'ENUM',
'constraint' => ['2D','3D','BRAILLE'],
'null' => true,
]
];
public function up()
{
$this->forge->addColumn('lg_tarifa_acabado',$this->COLUMNS);
}
public function down()
{
$this->forge->dropColumn('lg_tarifa_acabado',array_keys($this->COLUMNS));
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AlterOrdenesTrabajoAddCommentColumns extends Migration
{
protected array $COLUMNS = [
'comment_interior' => [
'type' => 'LONGTEXT',
'null' => true
],
'comment_cubierta' => [
'type' => 'LONGTEXT',
'null' => true
],
'comment_encuadernacion' => [
'type' => 'LONGTEXT',
'null' => true
],
'comment_logistica' => [
'type' => 'LONGTEXT',
'null' => true
],
"info_solapa_guillotina" => [
'type' => 'LONGTEXT',
'null' => true
]
];
public function up()
{
$this->forge->addColumn('ordenes_trabajo',$this->COLUMNS);
}
public function down()
{
$this->forge->dropColumn('ordenes_trabajo',array_keys($this->COLUMNS));
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class AddOrdenTrabajoDatesManipuladoImpresion extends Migration
{
protected array $DATES = [
"sobrecubierta_at" => [
"type" => "DATE",
"null" => true,
],
"guarda_at" => [
"type" => "DATE",
"null" => true,
],
"plakene_at" => [
"type" => "DATE",
"null" => true,
],
"estampado_at" => [
"type" => "DATE",
"null" => true,
],
"uvi_at" => [
"type" => "DATE",
"null" => true,
],
];
protected array $USERS = [
"sobrecubierta_user_id" => [
"type" => "INT",
"unsigned" => true,
"constraint" => 10,
"null" => true,
],
"guarda_user_id" => [
"type" => "INT",
"unsigned" => true,
"constraint" => 10,
"null" => true,
],
"plakene_user_id" => [
"type" => "INT",
"unsigned" => true,
"constraint" => 10,
"null" => true,
],
"estampado_user_id" => [
"type" => "INT",
"unsigned" => true,
"constraint" => 10,
"null" => true,
],
"uvi_user_id" => [
"type" => "INT",
"unsigned" => true,
"constraint" => 10,
"null" => true,
],
];
public function up()
{
$this->forge->addColumn("orden_trabajo_dates", $this->DATES);
$this->forge->addColumn("orden_trabajo_users", $this->USERS);
foreach ($this->USERS as $key => $value) {
$this->forge->addForeignKey([$key],"users",["id"]);
}
}
public function down()
{
$this->forge->dropColumn("orden_trabajo_dates", array_keys($this->DATES));
$this->forge->dropColumn("orden_trabajo_users", array_keys($this->USERS));
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AlterOrdenesTrabajoAddCommentColumns extends Migration
{
protected array $COLUMNS = [
'preimpresion_revisada' => [
'type' => 'BOOL',
'default' => false
],
'preimpresion_revisada_by' => [
'type' => 'INT',
'unsigned' => true,
'constraint' => 11,
],
];
public function up()
{
$this->forge->addColumn('ordenes_trabajo',$this->COLUMNS);
$this->forge->addForeignKey('preimpresion_revisada_by','users','id','NULL','NULL');
$this->forge->processIndexes('ordenes_trabajo');
}
public function down()
{
$this->forge->dropForeignKey('ordenes_trabajo','ordenes_trabajo_preimpresion_revisada_by_foreign');
$this->forge->dropColumn('ordenes_trabajo',array_keys($this->COLUMNS));
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateEtiquetasTitulos extends Migration
{
public function up()
{
// Tabla: etiquetas_titulos
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'comentarios' => ['type' => 'TEXT', 'null' => true],
'direccion' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => false],
'att' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => false],
'cliente_id' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
'deleted_at' => ['type' => 'DATETIME', 'null' => true],
'user_created_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
'user_updated_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
'user_deleted_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addForeignKey('user_created_at', 'users', 'id', 'SET NULL', 'CASCADE');
$this->forge->addForeignKey('user_updated_at', 'users', 'id', 'SET NULL', 'CASCADE');
$this->forge->addForeignKey('user_deleted_at', 'users', 'id', 'SET NULL', 'CASCADE');
$this->forge->addForeignKey('cliente_id', 'clientes', 'id', 'SET NULL', 'CASCADE');
$this->forge->createTable('etiquetas_titulos');
// Tabla: etiquetas_titulos_lineas
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'etiqueta_titulos_id' => ['type' => 'INT', 'unsigned' => true],
'ot_id' => ['type' => 'INT', 'unsigned' => true],
'unidades' => ['type' => 'INT', 'unsigned' => true],
'numero_caja' => ['type' => 'INT', 'unsigned' => true],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
'deleted_at' => ['type' => 'DATETIME', 'null' => true],
'user_created_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
'user_updated_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
'user_deleted_at' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addForeignKey('etiqueta_titulos_id', 'etiquetas_titulos', 'id', 'CASCADE', 'CASCADE');
$this->forge->addForeignKey('ot_id', 'ordenes_trabajo', 'id', 'CASCADE', 'CASCADE');
$this->forge->addForeignKey('user_created_at', 'users', 'id', 'SET NULL', 'CASCADE');
$this->forge->addForeignKey('user_updated_at', 'users', 'id', 'SET NULL', 'CASCADE');
$this->forge->addForeignKey('user_deleted_at', 'users', 'id', 'SET NULL', 'CASCADE');
$this->forge->createTable('etiquetas_titulos_lineas');
}
public function down()
{
$this->forge->dropTable('etiquetas_titulos_lineas', true);
$this->forge->dropTable('etiquetas_titulos', true);
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
use CodeIgniter\Database\RawSql;
class MaquinaOtTareasTable extends Migration
{
protected array $COLUMNS = [
'id' => [
'type' => 'INT',
'unsigned' => true,
'auto_increment' => true,
],
'maquina_id' => [
'type' => 'INT',
'unsigned' => true,
'constraint' => 11
],
'orden_trabajo_id' => [
'type' => 'INT',
'unsigned' => true,
],
];
public function up()
{
$this->forge->addField($this->COLUMNS);
$currenttime = new RawSql('CURRENT_TIMESTAMP');
$this->forge->addField([
'created_at' => [
'type' => 'TIMESTAMP',
'default' => $currenttime,
],
'updated_at' => [
'type' => 'TIMESTAMP',
'null' => true,
],
'deleted_at' => [
'type' => 'TIMESTAMP',
'null' => true,
],
]);
$this->forge->addPrimaryKey('id');
$this->forge->addForeignKey('maquina_id','lg_maquinas','id','CASCADE','CASCADE','maquina_ot_tareas_maquina_id_fk');
$this->forge->addForeignKey('orden_trabajo_id','ordenes_trabajo','id','CASCADE','CASCADE','maquina_ot_tareas_ot_id_fk');
$this->forge->createTable("maquina_ot_tareas");
}
public function down()
{
$this->forge->dropTable("maquina_ot_tareas");
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddEtiquetaEnvioCheckLgMaquinasTable extends Migration
{
protected array $COLUMNS = [
'etiqueta_envio' => [
'type' => 'BOOL',
'default' => false
],
];
public function up()
{
$this->forge->addColumn('lg_maquinas',$this->COLUMNS);
}
public function down()
{
$this->forge->dropColumn('lg_maquinas',array_keys($this->COLUMNS));
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateSelectorCalidadImpresion extends Migration
{
public function up()
{
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
'auto_increment' => true,
],
'alias' => [
'type' => 'VARCHAR',
'constraint' => 255,
],
'cliente_id' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
'null' => true,
],
'isPod' => [
'type' => 'TINYINT',
'constraint' => 1,
'default' => 0,
],
'input_isColor' => [
'type' => 'TINYINT',
'constraint' => 1,
'default' => 0,
],
'input_isHq' => [
'type' => 'TINYINT',
'constraint' => 1,
'default' => 0,
],
'output_isColor' => [
'type' => 'TINYINT',
'constraint' => 1,
'default' => 0,
],
'output_isHq' => [
'type' => 'TINYINT',
'constraint' => 1,
'default' => 0,
],
'created_at' => [
'type' => 'DATETIME',
'null' => true,
],
'updated_at' => [
'type' => 'DATETIME',
'null' => true,
],
'deleted_at' => [
'type' => 'DATETIME',
'null' => true,
],
]);
$this->forge->addKey('id', true);
$this->forge->addForeignKey('cliente_id', 'clientes', 'id', 'CASCADE', 'SET NULL');
$this->forge->createTable('selector_calidad_impresion');
}
public function down()
{
$this->forge->dropTable('selector_calidad_impresion');
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddAliasOtColumnMaquinasTable extends Migration
{
protected array $COLUMNS = [
"alias_ot" => [
"type" => "VARCHAR",
"constraint" => 255,
"null" => true
],
];
public function up()
{
$this->forge->addColumn('lg_maquinas', $this->COLUMNS);
}
public function down()
{
$this->forge->dropColumn('lg_maquinas', array_keys($this->COLUMNS));
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class ModifyAlbaranes extends Migration
{
public function up()
{
$this->forge->addColumn('albaranes_lineas', [
'cajas' => [
'type' => 'INT',
'constraint' => 11,
'null' => true,
],
'unidades_cajas' => [
'type' => 'INT',
'constraint' => 11,
'null' => true,
]
]);
}
public function down()
{
$this->forge->dropColumn('albaranes_lineas', ['cajas', 'unidades_cajas']);
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class RenameIskToIskn extends Migration
{
public function up()
{
// Renombrar columna isk a iskn
$this->forge->modifyColumn('catalogo_libros', [
'isk' => [
'name' => 'iskn',
'type' => 'VARCHAR',
'constraint' => 64,
'null' => true,
'default' => null,
'collation' => 'utf8_unicode_ci',
],
]);
}
public function down()
{
// Revertir el nombre de iskn a isk
$this->forge->modifyColumn('catalogo_libros', [
'iskn' => [
'name' => 'isk',
'type' => 'VARCHAR',
'constraint' => 64,
'null' => true,
'default' => null,
'collation' => 'utf8_unicode_ci',
],
]);
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class RenameIdentificadoresIskToIskn extends Migration
{
public function up()
{
// Renombrar la tabla
$this->db->query('RENAME TABLE identificadores_isk TO identificadores_iskn');
// Eliminar el índice único existente sobre 'isk'
$this->db->query('ALTER TABLE identificadores_iskn DROP INDEX isk');
// Renombrar la columna 'isk' a 'iskn'
$this->forge->modifyColumn('identificadores_iskn', [
'isk' => [
'name' => 'iskn',
'type' => 'VARCHAR',
'constraint' => 64,
'null' => false,
'collation' => 'utf8_general_ci',
],
]);
// Crear nuevo índice único sobre 'iskn'
$this->db->query('ALTER TABLE identificadores_iskn ADD UNIQUE INDEX iskn (iskn)');
}
public function down()
{
// Eliminar índice único sobre 'iskn'
$this->db->query('ALTER TABLE identificadores_iskn DROP INDEX iskn');
// Renombrar la columna 'iskn' de nuevo a 'isk'
$this->forge->modifyColumn('identificadores_iskn', [
'iskn' => [
'name' => 'isk',
'type' => 'VARCHAR',
'constraint' => 64,
'null' => false,
'collation' => 'utf8_general_ci',
],
]);
// Restaurar índice único sobre 'isk'
$this->db->query('ALTER TABLE identificadores_iskn ADD UNIQUE INDEX isk (isk)');
// Renombrar la tabla de nuevo a su nombre original
$this->db->query('RENAME TABLE identificadores_iskn TO identificadores_isk');
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateBackupsTable extends Migration
{
public function up()
{
$this->forge->addField([
'id' => [
'type' => 'INT',
'unsigned' => true,
'auto_increment' => true
],
'filename' => ['type' => 'VARCHAR', 'constraint' => 255],
'type' => ['type' => 'ENUM', 'constraint' => ['manual', 'cron']],
'path_local' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'path_remote' => ['type' => 'VARCHAR', 'constraint' => 255, 'null' => true],
'size' => ['type' => 'INT', 'unsigned' => true, 'null' => true],
'status' => ['type' => 'ENUM', 'constraint' => ['pendiente', 'subido', 'error'], 'default' => 'pendiente'],
'created_at' => ['type' => 'DATETIME', 'null' => false],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->createTable('backups');
}
public function down()
{
$this->forge->dropTable('backups');
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateRestoresTable extends Migration
{
public function up()
{
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'backup_id' => ['type' => 'INT', 'unsigned' => true],
'restored_by' => ['type' => 'VARCHAR', 'constraint' => 100],
'source' => ['type' => 'ENUM', 'constraint' => ['local', 'remote']],
'restored_at' => ['type' => 'DATETIME'],
]);
$this->forge->addKey('id', true);
$this->forge->addForeignKey('backup_id', 'backups', 'id', 'CASCADE', 'CASCADE');
$this->forge->createTable('backup_restores');
}
public function down()
{
$this->forge->dropTable('backup_restores');
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class LomoMaximoLibros extends Migration
{
public function up()
{
// Renombrar campo
$this->db->table('config_variables_app')
->where('name', 'lomo_maximo')
->set('name', 'lomo_maximo_fresado_cosido')
->update();
// Insertar nuevo campo: lomo_maximo_espiral
$this->db->table('config_variables_app')->insert([
'name' => 'lomo_maximo_espiral',
'value' => '45',
'description' => 'Tamaño máximo (mm) para el lomo de los libros espiral',
'created_at' => date('Y-m-d H:i:s')
]);
// Insertar nuevo campo: lomo_maximo_wireo
$this->db->table('config_variables_app')->insert([
'name' => 'lomo_maximo_wireo',
'value' => '26',
'description' => 'Tamaño máximo (mm) para el lomo de los libros wire-O',
'created_at' => date('Y-m-d H:i:s')
]);
}
public function down()
{
// Revertir nombre
$this->db->table('config_variables_app')
->where('name', 'lomo_maximo_fresado_cosido')
->set('name', 'lomo_maximo')
->update();
// Borrar los nuevos campos
$this->db->table('config_variables_app')->whereIn('name', [
'lomo_maximo_espiral',
'lomo_maximo_wireo'
])->delete();
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class DireccionesFerroPrototipo extends Migration
{
public function up()
{
// Insertar nuevo campo: lomo_maximo_espiral
$this->forge->addColumn('presupuesto_direcciones', [
'num_ferro_prototipo' => [
'type' => 'INT',
'constraint' => 3,
'null' => false,
'default' => '0',
'description' => 'numero de ferro/prototipo',
],
]);
}
public function down()
{
$this->db->table('presupuesto_direcciones')->whereIn('name', [
'num_ferro_prototipo',
'lomo_maximo_wireo'
])->delete();
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class AddCatalogoIdToPresupuestos extends Migration
{
public function up()
{
// Añadir columna
$this->forge->addColumn('presupuestos', [
'catalogo_id' => [
'type' => 'INT',
'constraint' => 10,
'unsigned' => true,
'null' => true,
'after' => 'tipologia_id'
],
]);
// Agregar clave foránea
$this->db->query('
ALTER TABLE presupuestos
ADD CONSTRAINT FK_presupuestos_catalogo_libros
FOREIGN KEY (catalogo_id) REFERENCES catalogo_libros(id)
ON DELETE SET NULL
ON UPDATE CASCADE
');
}
public function down()
{
// Eliminar la clave foránea primero
$this->db->query('
ALTER TABLE presupuestos
DROP FOREIGN KEY FK_presupuestos_catalogo_libros
');
// Eliminar columna
$this->forge->dropColumn('presupuestos', 'catalogo_id');
}
}

File diff suppressed because it is too large Load Diff

View File

@ -23,15 +23,41 @@ class DefaultConfigVariablesSeeder extends Seeder
"value" => 6000,
"description" => "Número de libros máximos que se puede producir al día"
],
[
"name" => "maquina_guillotina_id_default",
"value" => 20,
"description" => "ID de máquina que se asigna a tareas de corte tras impresión"
],
[
"name" => "maquina_guillotina_prep_id_default",
"value" => 31,
"description" => "ID de máquina que se asigna a tareas de corte tras impresión"
],
[
"name" => "maquina_tecnau_id",
"value" => 54,
"description" => "ID de máquina que se asigna a tareas de corte TECNAU"
],
[
"name" => "maquina_hunkeler_id",
"value" => 151,
"description" => "ID de máquina que se asigna a tareas de corte HUNKELER"
],
[
"name" => "maquina_trimming_id",
"value" => 149,
"description" => "ID de máquina que se asigna a tareas de corte HUNKELER"
],
];
public function run()
{
$variableModel = model(ConfigVariableModel::class);
foreach ($this->data as $row) {
if($variableModel->where("name",$row["name"])->first() == null){
if ($variableModel->where("name", $row["name"])->first() == null) {
$variableModel->insert($row);
}
}
}
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Database\Seeds;
use App\Models\Configuracion\MaquinaModel;
use CodeIgniter\Database\Seeder;
class MaquinaAliasOtSeeder extends Seeder
{
public function run()
{
$m = model(MaquinaModel::class);
$data = [
[
"value" => "6136p",
"alias" => "6136p"
],
[
"value" => "c6100",
"alias" => "c6100"
],
[
"value" => "2250p",
"alias" => "2250p"
],
[
"value" => "C14 000",
"alias" => "C14 000"
],
[
"value" => "IX",
"alias" => "IX"
]
];
foreach ($data as $key => $row) {
$m->like('nombre', $row['value'])->set(['alias_ot' => $row['alias']])->update();
}
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Database\Seeds;
use App\Models\Configuracion\ConfigVariableModel;
use App\Models\Configuracion\MaquinaTareaModel;
use CodeIgniter\Database\Seeder;
class PedidoPodSeeder extends Seeder
{
public function run()
{
$m = model(ConfigVariableModel::class);
$data = [
[
"name" => "pod_impresion_dias_tras_confirmacion",
"value" => 1,
"description" => "Días a los que se establece la fecha de impresion en pedido tras confirmación"
],
[
"name" => "pod_encuadernacion_dias_tras_confirmacion",
"value" => 2,
"description" => "Días a los que se establece la fecha de encuadernación en pedido tras confirmación"
],
[
"name" => "pod_entrega_real_dias_tras_confirmacion",
"value" => 5,
"description" => "Días a los que se establece la fecha entrega real en pedido tras confirmación"
],
[
"name" => "pod_embalaje_dias_tras_confirmacion",
"value" => 4,
"description" => "Días a los que se establece la fecha de encuadernación en pedido tras confirmación"
],
];
foreach ($data as $key => $row) {
if($m->getVariable($row['name']) == null)
{
$m->insert($row);
}
}
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
class SelectorCalidadImpresionSeeder extends Seeder
{
public function run()
{
$registros = [
// admin
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 0],
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 0, 'output_isHq' => 1],
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 1],
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 0],
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 0, 'output_isHq' => 1],
['alias' => 'admin', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 1],
// cliente
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 0],
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 0, 'output_isHq' => 1],
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 1],
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 0],
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 0, 'output_isHq' => 1],
['alias' => 'cliente', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 1],
// importador-rama
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 0],
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 0],
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'importador-rama', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 0],
// importador-bubok
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 0, 'output_isHq' => 0],
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 1],
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 0, 'output_isHq' => 1],
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 0, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 1],
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 1],
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 0, 'output_isColor' => 1, 'output_isHq' => 1],
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 0, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 1],
['alias' => 'importador-bubok', 'cliente_id' => null, 'isPod' => 1, 'input_isColor' => 1, 'input_isHq' => 1, 'output_isColor' => 1, 'output_isHq' => 1],
];
$this->db->table('selector_calidad_impresion')->insertBatch($registros);
}
}

View File

@ -21,6 +21,7 @@ class AlbaranEntity extends \CodeIgniter\Entity\Entity
'updated_at' => null,
'deleted_at' => null,
'cajas' => null,
'unidades_cajas' => null,
];
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
@ -40,6 +41,7 @@ class AlbaranEntity extends \CodeIgniter\Entity\Entity
'user_created_id' => 'integer',
'user_updated_id' => 'integer',
'fecha_albaran' => '?datetime',
'cajas' => '?integer',
];
// Agrega tus métodos personalizados aquí

View File

@ -21,6 +21,8 @@ class AlbaranLineaEntity extends \CodeIgniter\Entity\Entity
'created_at' => null,
'updated_at' => null,
'deleted_at' => null,
'cajas' => null,
'unidades_cajas' => null,
];
protected $casts = [
@ -36,5 +38,8 @@ class AlbaranLineaEntity extends \CodeIgniter\Entity\Entity
'iva_reducido' => '?boolean',
'user_created_id' => 'integer',
'user_updated_id' => 'integer',
'cajas' => '?integer',
'unidades_cajas' => '?integer',
];
}

View File

@ -10,6 +10,7 @@ use App\Models\Tarifas\Acabados\ServicioAcabadoModel;
use App\Models\Clientes\ClienteModel;
class CatalogoLibroEntity extends Entity
{
protected $attributes = [
'id' => null,
'cliente_id' => null,
@ -35,7 +36,7 @@ class CatalogoLibroEntity extends Entity
'num_ilustr_color' => 0,
'num_ilustr_bn' => 0,
'coleccion' => '',
'isk' => null,
'iskn' => null,
'isbn' => null,
'ean' => null,
'editorial' => '',
@ -44,8 +45,6 @@ class CatalogoLibroEntity extends Entity
'sello' => null,
'paginas' => 0,
'tipo_impresion' => null,
'solapas_ancho' => 0.00,
'cubiertas_ancho' => 0.00,
'comentarios' => '',
'negro_paginas' => null,
'negro_papel' => null,
@ -63,6 +62,8 @@ class CatalogoLibroEntity extends Entity
'cubierta_papel' => null,
'cubierta_papel_id' => null,
'cubierta_gramaje' => null,
'cubierta_ancho_solapas' => 0.00,
'cubierta_acabado_id' => null,
'cubierta_acabado' => null,
'cubierta_pod_papel_id' => null,
'cubierta_pod_gramaje' => null,
@ -70,10 +71,12 @@ class CatalogoLibroEntity extends Entity
'sobrecubierta_papel' => null,
'sobrecubierta_papel_id' => null,
'sobrecubierta_gramaje' => null,
'sobrecubierta_acabado_id' => null,
'sobrecubierta_acabado' => null,
'sobrecubierta_pod_papel_id' => null,
'sobrecubierta_ancho_solapas' => 0.00,
'sobrecubierta_pod_gramaje' => null,
'encuardenacion_id' => 'null',
'encuadernacion_id' => null,
'ubicacion' => null,
'created_at' => null,
'updated_at' => null,
@ -97,8 +100,6 @@ class CatalogoLibroEntity extends Entity
'num_ilustr_color' => '?int',
'num_ilustr_bn' => '?int',
'paginas' => 'int',
'solapas_ancho' => 'float',
'cubiertas_ancho' => 'float',
'negro_paginas' => '?int',
'negro_gramaje' => '?float',
'negro_papel_id' => '?int',
@ -113,15 +114,19 @@ class CatalogoLibroEntity extends Entity
'cubierta_gramaje' => '?float',
'cubierta_papel_id' => '?int',
'cubierta_pod_papel_id' => '?int',
'cubierta_ancho_solapas' => 'float',
'cubierta_pod_gramaje' => '?float',
'cubierta_acabado_id' => '?int',
'sobrecubierta_paginas' => '?int',
'sobrecubierta_gramaje' => '?float',
'sobrecubierta_papel_id' => '?int',
'sobrecubierta_pod_papel_id' => '?int',
'sobrecubierta_ancho_solapas' => 'float',
'sobrecubierta_pod_gramaje' => '?float',
'sobrecubierta_acabado_id' => '?int',
'encuadernacion_id' => '?int',
'fecha_disponibilidad' => 'datetime',
'fecha_public' => 'datetime',
];
public function getClienteName()

View File

@ -4,7 +4,7 @@ namespace App\Entities\Catalogo;
use CodeIgniter\Entity\Entity;
class IdentificadorIsk extends Entity
class IdentificadorIskn extends Entity
{
protected $dates = ['created_at', 'updated_at'];
}

View File

@ -1,7 +1,9 @@
<?php
namespace App\Entities\Cliente;
namespace App\Entities\Clientes;
use CodeIgniter\Entity;
use App\Models\Clientes\ClienteModel;
use App\Models\Configuracion\PaisModel;
class ClienteDireccionesEntity extends \CodeIgniter\Entity\Entity
{
@ -23,4 +25,29 @@ class ClienteDireccionesEntity extends \CodeIgniter\Entity\Entity
"pais_id" => "int",
"cp" => "int",
];
public function getClienteNombre(): ?string
{
if (!$this->cliente_id) {
return null;
}
$clienteModel = model(ClienteModel::class);
$cliente = $clienteModel->find($this->cliente_id);
return $cliente ? $cliente->nombre : null;
}
public function getPaisNombre(): ?string
{
if (!$this->pais_id) {
return null;
}
$paisModel = model(PaisModel::class);
$pais = $paisModel->find($this->pais_id);
return $pais ? $pais->nombre : null;
}
}

View File

@ -48,6 +48,8 @@ class ClienteEntity extends \CodeIgniter\Entity\Entity
"updated_at" => null,
"user_created_id" => 1,
"user_update_id" => 1,
"no_envio_base" => 0,
"forzar_rotativa_pod" => 0,
];
protected $casts = [
"comunidad_autonoma_id" => "?int",
@ -70,6 +72,8 @@ class ClienteEntity extends \CodeIgniter\Entity\Entity
"is_deleted" => "int",
"user_created_id" => "int",
"user_update_id" => "int",
"no_envio_base" => "boolean",
"forzar_rotativa_pod" => "boolean",
];
public function comercial() : ?UserEntity

View File

@ -0,0 +1,14 @@
<?php
namespace App\Entities\Configuracion;
use CodeIgniter\Entity\Entity;
class FestivoEntity extends Entity
{
protected $attributes = [
"id" => null,
"date" => null,
];
protected $casts = [];
}

View File

@ -42,6 +42,8 @@ class Maquina extends \CodeIgniter\Entity\Entity
"updated_at" => null,
"user_created_id" => 0,
"user_updated_id" => 0,
"etiqueta_envio" => false,
"alias_ot" => null,
];
protected $casts = [
"is_padre" => "boolean",
@ -57,6 +59,7 @@ class Maquina extends \CodeIgniter\Entity\Entity
"duracion_jornada" => "int",
"orden_planning" => "int",
"is_rotativa" => "boolean",
"etiqueta_envio" => "boolean",
"precio_tinta_negro" => "float",
"is_inkjet" => "boolean",
"precio_tinta_color" => "float",
@ -68,6 +71,7 @@ class Maquina extends \CodeIgniter\Entity\Entity
"is_deleted" => "int",
"user_created_id" => "int",
"user_updated_id" => "int",
"alias_ot" => "?string"
];
public function papeles_impresion() : ?array

View File

@ -0,0 +1,28 @@
<?php
namespace App\Entities\Configuracion;
use CodeIgniter\Entity\Entity;
class SelectorCalidadImpresion extends Entity
{
protected $attributes = [
'alias' => null,
'cliente_id' => null,
'isPod' => 0,
'input_isColor' => 0,
'input_isHq' => 0,
'output_isColor' => 0,
'output_isHq' => 0,
];
protected $datamap = [];
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
protected $casts = [
'isPod' => 'boolean',
'input_isColor' => 'boolean',
'input_isHq' => 'boolean',
'output_isColor' => 'boolean',
'output_isHq' => 'boolean',
];
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Entities\Etiquetas;
use App\Models\Etiquetas\EtiquetasTitulosLineasModel;
use CodeIgniter\Entity\Entity;
class EtiquetaTitulo extends Entity
{
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
public function getLineas()
{
$model = new EtiquetasTitulosLineasModel();
return $model->where('etiqueta_titulos_id', $this->id)->findAll();
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Entities\Etiquetas;
use CodeIgniter\Entity\Entity;
class EtiquetaTituloLinea extends Entity
{
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
}

View File

@ -48,4 +48,14 @@ class FacturaEntity extends \CodeIgniter\Entity\Entity
'creditoAsegurado' => 'float',
];
public function getIdFromNumero(string $numero): ?int
{
$facturaModel = model('\App\Models\Facturas\FacturaModel');
$factura = $facturaModel->where('numero', $numero)->first();
return $factura?->id;
}
}

View File

@ -31,5 +31,6 @@ class EnvioEntity extends Entity
'created_at' => 'datetime',
'updated_at' => 'datetime',
'cajas' => 'int',
'tipo_envio' => 'string',
];
}

View File

@ -1,7 +1,9 @@
<?php
namespace App\Entities\Presupuestos;
use App\Entities\Compras\ProveedorEntity;
use App\Entities\Tarifas\Acabados\TarifaAcabadoEntity;
use App\Models\Compras\ProveedorModel;
use App\Models\Configuracion\MaquinaModel;
use App\Models\Tarifas\Acabados\TarifaAcabadoModel;
use App\Models\Tarifas\Maquinas\TarifaAcabadoMaquinaModel;
@ -54,5 +56,13 @@ class PresupuestoAcabadosEntity extends \CodeIgniter\Entity\Entity
$m = model(TarifaAcabadoModel::class);
return $m->find($this->attributes["tarifa_acabado_id"]);
}
public function proveedor(): ?ProveedorEntity
{
$proveedor = null;
$m = model(ProveedorModel::class);
if ($this->attributes["proveedor_id"]) {
$proveedor = $m->find($this->attributes["proveedor_id"]);
}
return $proveedor;
}
}

View File

@ -25,6 +25,8 @@ class PresupuestoDireccionesEntity extends \CodeIgniter\Entity\Entity
"proveedor_id" => null,
"margen" => null,
"entregaPieCalle" => null,
"is_ferro_prototipo" => null,
"num_ferro_prototipo" => null,
];
protected $casts = [
"presupuesto_id" => "int",
@ -38,6 +40,8 @@ class PresupuestoDireccionesEntity extends \CodeIgniter\Entity\Entity
"margen" => "float",
"proveedor_id" => "int",
"entregaPieCalle" => "int",
"is_ferro_prototipo" => "int",
"num_ferro_prototipo" => "int",
];
}

View File

@ -1,7 +1,10 @@
<?php
namespace App\Entities\Presupuestos;
use App\Entities\Compras\ProveedorEntity;
use App\Entities\Tarifas\TarifaEncuadernacionEntity;
use App\Models\Compras\ProveedorModel;
use App\Models\Configuracion\MaquinaModel;
use App\Models\Tarifas\Maquinas\TarifaEncuadernacionMaquinaModel;
use App\Models\Tarifas\TarifaEncuadernacionModel;
@ -32,10 +35,10 @@ class PresupuestoEncuadernacionesEntity extends \CodeIgniter\Entity\Entity
"precio_total" => "float",
"margen" => "float",
];
public function maquinas() : array
public function maquinas(): array
{
$m = model(TarifaEncuadernacionMaquinaModel::class);
$tarifa_maquinas = $m->where("tarifa_encuadernacion_id",$this->attributes["tarifa_encuadernado_id"])->findAll();
$tarifa_maquinas = $m->where("tarifa_encuadernacion_id", $this->attributes["tarifa_encuadernado_id"])->findAll();
$maquinaModel = model(MaquinaModel::class);
$maquinas = [];
foreach ($tarifa_maquinas as $key => $tarifa_maquina) {
@ -43,9 +46,18 @@ class PresupuestoEncuadernacionesEntity extends \CodeIgniter\Entity\Entity
}
return $maquinas;
}
public function tarifa() : TarifaEncuadernacionEntity
public function tarifa(): TarifaEncuadernacionEntity
{
$m = model(TarifaEncuadernacionModel::class);
return $m->find($this->attributes["tarifa_encuadernado_id"]);
}
public function proveedor(): ?ProveedorEntity
{
$proveedor = null;
$m = model(ProveedorModel::class);
if ($this->attributes["proveedor_id"]) {
$proveedor = $m->find($this->attributes["proveedor_id"]);
}
return $proveedor;
}
}

View File

@ -27,6 +27,7 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
"user_update_id" => null,
"tipo_impresion_id" => null,
"tipologia_id" => null,
"catalogo_id" => null,
"pais_id" => 1,
"estado_id" => 1,
"inc_rei" => null,
@ -123,6 +124,7 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
"user_update_id" => "?int",
"tipo_impresion_id" => "?int",
"tipologia_id" => "?int",
"catalogo_id" => "?int",
"pais_id" => "int",
"estado_id" => "int",
"retractilado" => "boolean",
@ -210,35 +212,35 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
$q = $model->where('presupuesto_id', $this->attributes["id"])->findAll();
return $q ?? [];
}
/**
* Obtiene las lineas de presupuesto del actual presupuesto
*
* @return ?PresupuestoLineaEntity
*/
public function presupuestoLineaImpresion(): ?PresupuestoLineaEntity
{
$model = model(PresupuestoLineaModel::class);
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo", ["lp_rot_bn", "lp_rot_color", "lp_color", "lp_colorhq", "lp_bn", "lp_bnhq"])->first();
return $q;
}
/**
/**
* Obtiene las lineas de presupuesto del actual presupuesto
*
* @return PresupuestoLineaEntity
*/
public function presupuestoLineaImpresion(): PresupuestoLineaEntity
public function presupuestoLineaCubierta(): ?PresupuestoLineaEntity
{
$model = model(PresupuestoLineaModel::class);
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo",["lp_rot_bn","lp_rot_color","lp_color","lp_colorhq","lp_bn","lp_bnhq"])->first();
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo", ["lp_cubierta"])->first();
return $q;
}
/**
* Obtiene las lineas de presupuesto del actual presupuesto
*
* @return PresupuestoLineaEntity
*/
public function presupuestoLineaCubierta(): PresupuestoLineaEntity
{
$model = model(PresupuestoLineaModel::class);
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo",["lp_cubierta"])->first();
return $q;
}
/**
/**
* Obtiene las lineas de presupuesto del actual presupuesto
*
* @return PresupuestoLineaEntity
@ -247,70 +249,81 @@ class PresupuestoEntity extends \CodeIgniter\Entity\Entity
{
$model = model(PresupuestoLineaModel::class);
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo",["lp_sobrecubierta"])->first();
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo", ["lp_sobrecubierta"])->first();
return $q;
}
public function hasSobrecubierta() : bool
public function presupuestoLineaGuarda(): ?PresupuestoLineaEntity
{
$model = model(PresupuestoLineaModel::class);
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo", ["lp_guardas"])->first();
return $q;
}
public function hasSobrecubierta(): bool
{
$hasSobrecubierta = false;
$model = model(PresupuestoLineaModel::class);
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo",["lp_sobrecubierta"])->countAllResults();
if($q > 0){
$q = $model->where('presupuesto_id', $this->attributes["id"])->whereIn("tipo", ["lp_sobrecubierta"])->countAllResults();
if ($q > 0) {
$hasSobrecubierta = true;
}
return $hasSobrecubierta;
}
public function cliente() : ClienteEntity
public function cliente(): ?ClienteEntity
{
$m = model(ClienteModel::class);
return $m->find($this->attributes["cliente_id"]);
if ($this->attributes['cliente_id']) {
return $m->find($this->attributes["cliente_id"]);
} else {
return null;
}
}
public function encuadernaciones(): array
{
$m = model(PresupuestoEncuadernacionesModel::class);
return $m->where("presupuesto_id",$this->attributes["id"])->findAll();
return $m->where("presupuesto_id", $this->attributes["id"])->findAll();
}
public function acabados(): array
{
$m = model(PresupuestoAcabadosModel::class);
return $m->where("presupuesto_id",$this->attributes["id"])->findAll();
return $m->where("presupuesto_id", $this->attributes["id"])->findAll();
}
public function preimpresiones(): array
{
$m = model(PresupuestoPreimpresionesModel::class);
return $m->where("presupuesto_id",$this->attributes["id"])->findAll();
return $m->where("presupuesto_id", $this->attributes["id"])->findAll();
}
public function manipulados(): array
{
$m = model(PresupuestoManipuladosModel::class);
return $m->where("presupuesto_id",$this->attributes["id"])->findAll();
return $m->where("presupuesto_id", $this->attributes["id"])->findAll();
}
public function extras(): array
{
$m = model(PresupuestoServiciosExtraModel::class);
return $m->where("presupuesto_id",$this->attributes["id"])->findAll();
return $m->where("presupuesto_id", $this->attributes["id"])->findAll();
}
public function papel_formato() : PapelFormatoEntity
public function papel_formato(): PapelFormatoEntity
{
$m = model(PapelFormatoModel::class);
return $m->find($this->attributes["papel_formato_id"]);
}
public function files(): array
public function files(): array
{
$m = model(PresupuestoFicheroModel::class);
$files = $m->where('presupuesto_id',$this->attributes['id'])->findAll();
$files = $m->where('presupuesto_id', $this->attributes['id'])->findAll();
return $files ?? [];
}
public function tipo_presupuesto() : ?TipoPresupuestoEntity
public function tipo_presupuesto(): ?TipoPresupuestoEntity
{
$tipo_presupuesto = null;
$m = model(TipoPresupuestoModel::class);
if($this->attributes["tipo_impresion_id"]){
if ($this->attributes["tipo_impresion_id"]) {
$tipo_presupuesto = $m->find($this->attributes['tipo_impresion_id']);
}
return $tipo_presupuesto;
}
}

View File

@ -222,6 +222,7 @@ class PresupuestoLineaEntity extends \CodeIgniter\Entity\Entity
return $nombre;
}
public function isGuarda(): bool
{
return in_array($this->attributes["tipo"], ["lp_guardas"]);
@ -247,6 +248,10 @@ class PresupuestoLineaEntity extends \CodeIgniter\Entity\Entity
return in_array($this->attributes['tipo'], ["lp_bn", "lp_bnhq", "lp_rot_bn"]);
}
public function isImpresionInteriorPlana():bool
{
return in_array($this->attributes['tipo'], ["lp_bn", "lp_bnhq", "lp_colorhq","lp_color"]);
}
public function tinta(): string
{
$tinta = "";

View File

@ -15,8 +15,15 @@ class OrdenTrabajoDateEntity extends Entity
"interior_bn_at" => null,
"interior_color_at" => null,
"cubierta_at" => null,
"sobrecubierta_at" => null, //TODO
"guarda_at" => null, //TODO
//ACABADO
"plastificado_at" => null,
"plakene_at" => null, //TODO
"retractilado_at"=> null,
"estampado_at" => null, //TODO
"uvi_at" => null, //TODO
//MANIPULADO
"encuadernacion_at" => null,
"corte_at" => null,
"preparacion_interiores_at" => null,
@ -24,9 +31,8 @@ class OrdenTrabajoDateEntity extends Entity
"cosido_at" => null,
"solapa_at" => null,
"grapado_at" => null,
"retractilado_at"=> null,
"retractilado5_at"=> null,
"prototipo_at"=> null,
"retractilado5_at"=> null, // !DELETE
"prototipo_at"=> null, // !DELETE
"marcapaginas_at"=> null,
"espiral_at"=> null,
//FERRO

View File

@ -30,6 +30,11 @@ class OrdenTrabajoEntity extends Entity
"progreso" => 0.00,
"estado" => "I",
"comentarios" => null,
"comment_interior" => null,
"comment_cubierta" => null,
"comment_encuadernacion" => null,
"comment_logistica" => null,
"info_solapa_guillotina" => null,
"revisar_formato" => null,
"revisar_lomo" => null,
"revisar_solapa" => null,
@ -40,6 +45,9 @@ class OrdenTrabajoEntity extends Entity
"portada_path" => null,
"is_pedido_espera" => null,
"pedido_espera_by" => null,
"preimpresion_revisada" => false,
"preimpresion_revisada_by" => null,
];
protected $casts = [
"pedido_id" => "integer",
@ -52,7 +60,12 @@ class OrdenTrabajoEntity extends Entity
"tipo_entrada" => "string",
"progreso" => "float",
"estado" => "string",
"comentarios" => "string",
"comentarios" => "?string",
"comment_interior" => "?string",
"comment_cubierta" => "?string",
"comment_encuadernacion" => "?string",
"comment_logistica" => "?string",
"info_solapa_guillotina" => "?string",
"revisar_formato" => "bool",
"revisar_lomo" => "bool",
"revisar_solapa" => "bool",
@ -62,6 +75,7 @@ class OrdenTrabajoEntity extends Entity
"enviar_impresion" => "bool",
"portada_path" => "string",
"is_pedido_espera" => "bool",
"preimpresion_revisada" => "bool",
];
@ -80,7 +94,22 @@ class OrdenTrabajoEntity extends Entity
$m = model(OrdenTrabajoTarea::class);
return $m->where("orden_trabajo_id", $this->attributes["id"])->where("presupuesto_linea_id IS NOT NULL", NULL, FALSE)->findAll() ?? [];
}
/**
public function tareas_acabado(): array
{
$m = model(OrdenTrabajoTarea::class);
return $m->where("orden_trabajo_id", $this->attributes["id"])->where("presupuesto_acabado_id IS NOT NULL", NULL, FALSE)->findAll() ?? [];
}
public function tareas_encuadernado(): array
{
$m = model(OrdenTrabajoTarea::class);
return $m->where("orden_trabajo_id", $this->attributes["id"])->where("presupuesto_encuadernado_id IS NOT NULL", NULL, FALSE)->findAll() ?? [];
}
public function tareas_manipulado(): array
{
$m = model(OrdenTrabajoTarea::class);
return $m->where("orden_trabajo_id", $this->attributes["id"])->where("presupuesto_manipulado_id IS NOT NULL", NULL, FALSE)->findAll() ?? [];
}
/**
* Devuelve el presupuesto de la orden de trabajo
*
* @return PresupuestoEntity
@ -153,10 +182,23 @@ class OrdenTrabajoEntity extends Entity
return null;
}
}
public function preimpresionRevisadaUser(): ?UserEntity
{
$m = model(UserModel::class);
if ($this->attributes['preimpresion_revisada_by']) {
return $m->findById($this->attributes['preimpresion_revisada_by']);
} else {
return null;
}
}
public function getPedidoEsperaBy(): ?UserEntity
{
return $this->pedidoEsperaBy();
}
public function getPreimpresionRevisadaBy(): ?UserEntity
{
return $this->preimpresionRevisadaUser();
}
public function getFullPath(): ?string
{
helper('filesystem');
@ -183,4 +225,5 @@ class OrdenTrabajoEntity extends Entity
];
return $estados[$this->attributes["estado"]];
}
}

View File

@ -5,6 +5,7 @@ namespace App\Entities\Produccion;
use App\Entities\Configuracion\Imposicion;
use App\Entities\Configuracion\Maquina;
use App\Entities\Presupuestos\PresupuestoAcabadosEntity;
use App\Entities\Presupuestos\PresupuestoEncuadernacionesEntity;
use App\Entities\Presupuestos\PresupuestoLineaEntity;
use App\Entities\Presupuestos\PresupuestoManipuladosEntity;
use App\Models\Configuracion\ImposicionModel;
@ -12,6 +13,7 @@ use App\Models\Configuracion\MaquinaModel;
use App\Models\OrdenTrabajo\OrdenTrabajoModel;
use App\Models\OrdenTrabajo\OrdenTrabajoTareaProgressDate;
use App\Models\Presupuestos\PresupuestoAcabadosModel;
use App\Models\Presupuestos\PresupuestoEncuadernacionesModel;
use App\Models\Presupuestos\PresupuestoLineaModel;
use App\Models\Presupuestos\PresupuestoManipuladosModel;
use CodeIgniter\Entity\Entity;
@ -23,6 +25,11 @@ class OrdenTrabajoTareaEntity extends Entity
"id" => null,
"orden_trabajo_id" => null,
"presupuesto_linea_id" => null,
"presupuesto_acabado_id" => null,
"presupuesto_preimpresion_id" => null,
"presupuesto_encuadernado_id" => null,
"presupuesto_extra_id" => null,
"presupuesto_manipulado_id" => null,
"nombre" => null,
"orden" => null,
"maquina_id" => null,
@ -96,10 +103,15 @@ class OrdenTrabajoTareaEntity extends Entity
*
* @return PresupuestoLineaEntity
*/
public function presupuesto_linea(): PresupuestoLineaEntity
public function presupuesto_linea(): ?PresupuestoLineaEntity
{
$presupuesto_linea = null;
$m = model(PresupuestoLineaModel::class);
return $m->find($this->attributes["presupuesto_linea_id"]);
if ($this->attributes['presupuesto_linea_id']) {
$presupuesto_linea = $m->find($this->attributes["presupuesto_linea_id"]);
}
return $presupuesto_linea;
}
/**
* Devuelve la maquina original del presupuesto linea
@ -108,17 +120,35 @@ class OrdenTrabajoTareaEntity extends Entity
*/
public function maquina_presupuesto_linea(): Maquina
{
return $this->presupuesto_linea()->maquina();
return $this->presupuesto_linea()?->maquina();
}
/**
* Devuelve el presupuesto acabado origen de esta tarea
*
* @return PresupuestoAcabadosEntity
*/
public function presupuesto_acabado(): PresupuestoAcabadosEntity
public function presupuesto_acabado(): ?PresupuestoAcabadosEntity
{
$presupuesto_acabado = null;
$m = model(PresupuestoAcabadosModel::class);
return $m->find($this->attributes["presupuesto_linea_id"]);
if ($this->attributes["presupuesto_acabado_id"]) {
$presupuesto_acabado = $m->find($this->attributes["presupuesto_acabado_id"]);
}
return $presupuesto_acabado;
}
/**
* Devuelve el presupuesto enducadernacion origen de esta tarea
*
* @return PresupuestoEncuadernacionesEntity
*/
public function presupuesto_encuadernacion(): ?PresupuestoEncuadernacionesEntity
{
$presupuesto_encuadernacion = null;
$m = model(PresupuestoEncuadernacionesModel::class);
if ($this->attributes["presupuesto_encuadernado_id"]) {
$presupuesto_encuadernacion = $m->find($this->attributes["presupuesto_encuadernado_id"]);
}
return $presupuesto_encuadernacion;
}
/**
* Devuelve el presupuesto acabado origen de esta tarea
@ -148,22 +178,29 @@ class OrdenTrabajoTareaEntity extends Entity
$m = model(OrdenTrabajoTareaProgressDate::class);
return $m->where('ot_tarea_id', $this->attributes["id"])->findAll() ?? [];
}
public function lastState(): ?OrdenTrabajoTareaProgressDateEntity
{
$m = model(OrdenTrabajoTareaProgressDate::class);
$progressDates = $m->where('ot_tarea_id', $this->attributes["id"])->orderBy('action_at', 'DESC')->first();
return $progressDates;
}
public function tiempo_trabajado()
{
$dates = $this->progress_dates();
$intervals = [];
$init = [];
$end = [];
$init = null;
$end = null;
foreach ($dates as $key => $date) {
if ($date->estado == "I") {
if ($date->action_at) {
$init = Time::createFromFormat('Y-m-d H:i:s', $date->action_at);
$init = $date->action_at;
}
}
if ($date->estado == "S" || $date->estado == "F") {
if ($date->action_at) {
$end = Time::createFromFormat('Y-m-d H:i:s', $date->action_at);
if ($date->action_at && $init) {
$end = $date->action_at;
$intervals[] = $init->difference($end)->getSeconds();
$init = null; // Reset init after calculating the interval
}
}
}
@ -176,10 +213,30 @@ class OrdenTrabajoTareaEntity extends Entity
public function isCosido(): bool
{
$isTareaCosido = false;
$pm = $this->presupuesto_manipulado();
$pm = $this->presupuesto_encuadernacion();
if ($pm) {
$isTareaCosido = $pm->tarifa()->isCosido();
}
return $isTareaCosido;
}
public function isImpresion(): bool
{
return $this->attributes['presupuesto_linea_id'] != null;
}
public function isAcabado(): bool
{
return $this->attributes['presupuesto_acabado_id'] != null;
}
public function isManipulado(): bool
{
return $this->attributes['presupuesto_manipulado_id'] != null;
}
public function isEncuadernado(): bool
{
return $this->attributes['presupuesto_encuadernado_id'] != null;
}
public function isCorte(): bool
{
return $this->attributes['is_corte'];
}
}

View File

@ -2,6 +2,7 @@
namespace App\Entities\Produccion;
use App\Entities\Usuarios\UserEntity;
use App\Models\OrdenTrabajo\OrdenTrabajoTarea;
use CodeIgniter\Entity\Entity;
@ -20,12 +21,21 @@ class OrdenTrabajoTareaProgressDateEntity extends Entity
/**
* Orden de trabajo de la tarea
*
* @return OrdenTrabajoEntity
* @return OrdenTrabajoTareaEntity
*/
public function orden_trabajo_tarea() : OrdenTrabajoTareaEntity
{
$m = model(OrdenTrabajoTarea::class);
return $m->find($this->attributes["ot_tarea_id"]);
}
public function user() : ?UserEntity
{
$user = null;
if($this->attributes['action_user_id'])
{
$user = auth()->getProvider()->findById($this->attributes['action_user_id']);
}
return $user;
}
}

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