196 Commits

Author SHA1 Message Date
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
179 changed files with 6363 additions and 3807 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 = 'custom';
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 = 'custom';
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

@ -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

@ -552,6 +552,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']);
@ -645,6 +646,8 @@ $routes->group('messages', ['namespace' => 'App\Controllers\Chat'], function ($r
$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']);
@ -764,6 +767,7 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func
$routes->get('tareas/datatable/(:num)', 'Ordentrabajo::tareas_datatable/$1', ['as' => 'datatableTareasOrdenTrabajo']);
$routes->get('maquinas/ots/datatable/(:num)','Ordentrabajo::datatable_maquina_ordenes_trabajo/$1');
$routes->get('maquinas/ots/(:num)','Ordentrabajo::get_maquina_ots/$1');
/**======================
* UPDATES
*========================**/
@ -781,10 +785,11 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func
$routes->post("update/tarea/progress", "Ordentrabajo::store_orden_trabajo_progress_date");
$routes->post("update/tarea/pliegos", "Ordentrabajo::update_orden_trabajo_pliegos");
$routes->post("update/tarea/proveedor", "Ordentrabajo::update_presupuesto_tarea_proveedor");
$routes->post("fa/tareas/finish", 'Ordentrabajo::update_orden_trabajo_fa_tareas');
$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');
@ -803,6 +808,7 @@ $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');
@ -816,6 +822,7 @@ $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');
@ -837,6 +844,9 @@ $routes->group('produccion', ['namespace' => 'App\Controllers\Produccion'], func
/** 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');
});
});
});
@ -865,6 +875,8 @@ $routes->group('logistica', ['namespace' => 'App\Controllers\Logistica'], functi
$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']);
});

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

@ -32,6 +32,7 @@ $routes->group('importador', ['namespace' => 'App\Controllers\Importadores'], fu
/**======================
* AJAX
*========================**/
$routes->post('validar-fila', 'ImportadorBubok::validarFila');
$routes->post('importar-fila', 'ImportadorBubok::importarFila');
});

View File

@ -30,6 +30,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 +56,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

@ -182,6 +182,10 @@ class Validation extends BaseConfig
"rules" => "required|integer",
"label" => "Máquina"
],
"estado" => [
"rules" => "required|in_list[P,I,S,D,F,E]",
"label" => "estado"
],
"tareas" => [
"rules" => "required",
"label" => "Tareas"

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" />';

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,40 @@ 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',
't1.total',
't1.estado'
])
->edit('total', fn($row) => number_format((float) $row->total, 2, ',', '.') . ' €')
->edit('precio_ud', fn($row) => number_format((float) $row->total, 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

@ -363,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();
}
@ -538,6 +537,23 @@ class ChatController extends BaseController
->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);
@ -605,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

@ -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

@ -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

@ -3,6 +3,7 @@ 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
@ -39,6 +40,7 @@ class ImportadorBubok extends BaseResourceController
public function index()
{
checkPermission('importadores.bubok');
$viewData = [
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
@ -50,9 +52,81 @@ class ImportadorBubok extends BaseResourceController
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
@ -83,7 +157,7 @@ class ImportadorBubok extends BaseResourceController
'message' => 'Número de orden o ID del producto no reconocidos.'
]);
}
$refCliente = "$orderNumber - $productId";
$refCliente = "$orderNumber-$productId";
// Titulo
$titulo = $producto->title ?? null;
@ -277,6 +351,15 @@ class ImportadorBubok extends BaseResourceController
]
];
// 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,
@ -295,8 +378,8 @@ class ImportadorBubok extends BaseResourceController
'tipo' => '',
'tipo_presupuesto_id' => $encuadernadoId,
'clienteId' => 40, // BUBOK ID
'isColor' => ($interiorTipo === 'color') ? 1 : 0,
'isHq' => 0,
'isColor' => $isColor,
'isHq' => $isHq,
'paginas' => $paginas,
'paginasColor' => ($interiorTipo === 'color') ? $paginas : 0,
'paginasCuadernillo' => 32,
@ -317,15 +400,16 @@ class ImportadorBubok extends BaseResourceController
'sobrecubierta' => [],
'faja' => null,
'entrega_taller' => 1,
//'direcciones' => $direcciones, las direcciones que aparecen no se añaden, ya que la recogida la hacen ellos con su empresa de mensajeria
'direcciones' => $direcciones,
'ivaReducido' => 1,
];
/*return $this->respond([
'status' => 400,
'message' => $dataToImport
'message' => $dataToImport,
'interiorTipo' => $interiorTipo,
'isColor' => $isColor
]);*/
// 5. Guardar
@ -358,11 +442,11 @@ class ImportadorBubok extends BaseResourceController
];
}
}
// confirmar y crear pedido y ot
$presupuestoModel->confirmarPresupuesto($response['sk_id']);
PresupuestoService::crearPedido($response['sk_id']);
PresupuestoService::crearPedido($response['sk_id'], isImported: true);
if (!isset($response['sk_id'])) {
return $this->respond([
@ -372,6 +456,76 @@ class ImportadorBubok extends BaseResourceController
], 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' => [
@ -380,6 +534,7 @@ class ImportadorBubok extends BaseResourceController
]
]);
} catch (\Throwable $e) {
return $this->respond([
'status' => 500,

View File

@ -3,6 +3,7 @@ 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;
@ -42,10 +43,11 @@ class ImportadorCatalogo extends BaseResourceController
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
@ -56,39 +58,55 @@ class ImportadorCatalogo extends BaseResourceController
public function validarFila()
{
checkPermission('importadores.catalogo');
$json = $this->request->getJSON();
if (!$json || !isset($json->fila[0])) {
// 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' => 'Datos inválidos'
'reason' => 'ISBN no proporcionado o datos inválidos'
]);
}
$input = trim($json->fila[0]); // Asumimos que 'input' es el primer campo de la fila
$input = trim($json->fila[0]); // ISBN
$refCliente = isset($json->fila[1]) ? trim($json->fila[1]) : null;
if (empty($input)) {
// Validar formato del refCliente (esperado: idpedido-idlinea)
if (empty($refCliente) || strpos($refCliente, '-') === false) {
return $this->response->setJSON([
'apto' => false,
'reason' => 'ISBN no proporiconado'
'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();
// 1. Buscar por ISBN exacto
// 2. Buscar por ISBN exacto
$libroPorIsbn = $catalogoModel->where('isbn', $input)->first();
if ($libroPorIsbn) {
return $this->response->setJSON([
'apto' => true
]);
}
// 2. Buscar por EAN sin guiones
// 3. Buscar por EAN sin guiones
$eanLimpio = str_replace('-', '', $input);
$libroPorEan = $catalogoModel->where('REPLACE(ean, "-", "")', $eanLimpio)->first();
$libroPorEan = $catalogoModel
->where('REPLACE(ean, "-", "")', $eanLimpio, false) // false para evitar escapado automático
->first();
if ($libroPorEan) {
return $this->response->setJSON([
@ -96,7 +114,7 @@ class ImportadorCatalogo extends BaseResourceController
]);
}
// No encontrado
// 4. No encontrado
return $this->response->setJSON([
'apto' => false,
'reason' => 'No encontrado en catálogo'
@ -104,9 +122,10 @@ class ImportadorCatalogo extends BaseResourceController
}
public function importarFila()
{
checkPermission('importadores.catalogo');
$json = $this->request->getJSON();
if (!$json || !isset($json->fila[0])) {
@ -116,12 +135,10 @@ class ImportadorCatalogo extends BaseResourceController
]);
}
// Mapear cada columna a una variable
// 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;
//$descripcion = isset($json->fila[2]) ? trim($json->fila[2]) : null;
$tirada = isset($json->fila[3]) ? (float) $json->fila[3] : null;
$precio_compra = isset($json->fila[4]) ? (float) $json->fila[4] : null;
if (empty($isbn)) {
return $this->response->setJSON([
@ -130,6 +147,17 @@ class ImportadorCatalogo extends BaseResourceController
]);
}
// 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
@ -191,13 +219,22 @@ class ImportadorCatalogo extends BaseResourceController
// Sobrecubierta
$sobrecubierta = [];
if (!is_null($libro->sobrecubierta_paginas)) {
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,
@ -221,8 +258,8 @@ class ImportadorCatalogo extends BaseResourceController
'tipo' => "",
'tipo_presupuesto_id' => $libro->encuadernacion_id,
'clienteId' => 251,
'isColor' => (in_array(strtolower($libro->tipo_impresion), ['color', 'colorhq']) ? 1 : 0),
'isHq' => (in_array(strtolower($libro->tipo_impresion), ['negrohq', 'colorhq']) ? 1 : 0),
'isColor' => $isColor,
'isHq' => $isHq,
'paginas' => $libro->paginas,
'paginasColor' => $colorPaginas,
'papelInteriorDiferente' => $papelInteriorDiferente,
@ -254,6 +291,32 @@ class ImportadorCatalogo extends BaseResourceController
'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
@ -287,7 +350,7 @@ class ImportadorCatalogo extends BaseResourceController
$response['data']['sk_id'],
$precio_compra,
$tirada,
null,
null,
true
);
if ($respuesta_ajuste['warning'] == true) {
@ -299,7 +362,7 @@ class ImportadorCatalogo extends BaseResourceController
// confirmar y crear pedido y ot
model('App\Models\Presupuestos\PresupuestoModel')->confirmarPresupuesto($response['data']['sk_id']);
PresupuestoService::crearPedido($response['data']['sk_id']);
PresupuestoService::crearPedido($response['data']['sk_id'],isImported:true);
return $this->respond($response);
@ -316,6 +379,79 @@ class ImportadorCatalogo extends BaseResourceController
}
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

@ -163,7 +163,7 @@ class EtiquetasTitulosController extends BaseController
$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')
@ -440,7 +440,7 @@ class EtiquetasTitulosController extends BaseController
$impresora_id = $this->request->getPost('impresora_id') ?? null;
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name, ip, port, user, pass')
$impresora = $modelImpresora->select('id, name, description, ip, port, user, pass')
->where('deleted_at', null)
->where('id', $impresora_id)
->orderBy('name', 'asc')

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,6 +60,8 @@ class LogisticaController extends BaseController
public function gestionEnvios()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.gestionEnvios'),
@ -73,6 +77,8 @@ class LogisticaController extends BaseController
public function gestionEnviosFerros()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.envioFerros'),
@ -87,6 +93,8 @@ class LogisticaController extends BaseController
public function etiquetasLogistica()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Logistica.etiquetasTitulos'),
@ -98,7 +106,10 @@ class LogisticaController extends BaseController
return view(static::$viewPath . 'viewImpresionEtiquetas', $viewData);
}
public function listAlbaranes(){
public function listAlbaranes()
{
checkPermission('logistica.logistica');
$viewData = [
'currentModule' => static::$controllerSlug,
'boxTitle' => lang('Albaran.albaranes'),
@ -117,7 +128,7 @@ class LogisticaController extends BaseController
$tipo_envio = $this->request->getGet('tipo_envio') ?? 'estandar';
if($tipo_envio == 'ferro_prototipo'){
if ($tipo_envio == 'ferro_prototipo') {
$query = LogisticaService::findForNewEnvioFerro();
} else {
$query = LogisticaService::findForNewEnvio();
@ -132,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()) {
$ot = $this->request->getGet('ot_id');
if($ot == null || $ot == 0){
if ($ot == null || $ot == 0) {
return [];
}
$searchVal = $this->request->getGet("q") ?? "";
$result = LogisticaService::findDireccionesNewEnvio($ot, $searchVal);
return $this->response->setJSON($result);
} else {
return $this->failUnauthorized('Invalid request', 403);
@ -185,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'
@ -202,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'
@ -213,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'
@ -221,12 +235,12 @@ class LogisticaController extends BaseController
}
$modelImpresora = model('App\Models\Configuracion\ImpresoraEtiquetaModel');
$impresora = $modelImpresora->select('id, name, ip, port, user, pass')
$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'
@ -330,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')
@ -384,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 {
@ -392,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)
{
@ -406,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) {
@ -420,17 +451,35 @@ class LogisticaController extends BaseController
)->edit(
"unidadesEnvio",
function ($row, $meta) {
if($row->finalizado == 1 || $row->tipo_envio == 'ferro_prototipo'){
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()
{
@ -471,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'
@ -480,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([
@ -503,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([
@ -526,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

@ -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(
@ -1076,20 +1083,22 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
$resourceData = PresupuestoService::obtenerComparadorPlana($input_data);
if($calcular_merma == 1 && count($resourceData) > 0 &&
count($resourceData[0]['fields']) >0 && $resourceData[0]['fields']['num_formas'] > 0) {
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']);
$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);
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada, $POD, $num_formas);
$resourceData = PresupuestoService::obtenerComparadorPlana($input_data);
}
@ -1126,20 +1135,22 @@ 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) {
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']);
$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);
$datosPedido->merma = PresupuestoService::calcular_merma($datosPedido->tirada, $POD, $num_formas);
$resourceData = PresupuestoService::obtenerComparadorRotativa($input_data);
}
@ -1209,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']) {
@ -1265,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') {
@ -1294,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"))
@ -1333,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') {
@ -1350,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,
@ -1360,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"))
@ -1593,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()
{
@ -1806,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 => '--'
@ -1820,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 = [
@ -1837,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 = [
@ -1860,14 +1801,58 @@ 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 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);
}
}
@ -1897,7 +1882,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;
}
}
@ -1966,4 +1951,6 @@ class Presupuestoadmin extends \App\Controllers\BaseResourceController
return $direcciones;
}
}

View File

@ -332,15 +332,15 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
// Para POD siempre es HQ
if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$isHq = true;
}
$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,
@ -463,7 +463,6 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
//$reqData = $this->request->getPost();
$modelPapelGenerico = new PapelGenericoModel();
$id = $reqData['id'] ?? 0;
$cliente_id = $reqData['clienteId'] ?? -1;
@ -760,13 +759,12 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
// Para POD siempre es HQ
if ($tirada[0] <= $POD && !$cliente->forzar_rotativa_pod) {
$isHq = true;
}
$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(
@ -1340,7 +1338,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$datos_presupuesto['entrega_taller'] = $reqData['entrega_taller'] ?? 0;
$resultado_presupuesto['info']['merma'] = PresupuestoService::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;
@ -2079,13 +2078,12 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$cliente_model = model(('App\Models\Clientes\ClienteModel'));
$cliente = $cliente_model->find($cliente_id);
// Para POD siempre es HQ
if ($tirada[$t] <= $POD && !$cliente->forzar_rotativa_pod) {
$isHq = true;
}
$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(
@ -2155,6 +2153,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
$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) {
@ -2270,7 +2269,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) {
@ -3584,4 +3583,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

@ -11,6 +11,8 @@ 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;
@ -22,6 +24,7 @@ use Exception;
use Hermawan\DataTables\DataTable;
use Psr\Log\LoggerInterface;
class Ordentrabajo extends BaseController
{
protected $format = 'json';
@ -219,8 +222,9 @@ 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);
@ -239,6 +243,7 @@ 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()
@ -254,6 +259,7 @@ 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()
@ -269,6 +275,7 @@ 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()
@ -284,6 +291,7 @@ 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()
@ -298,6 +306,7 @@ 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_prod()
@ -312,6 +321,7 @@ 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_waiting()
@ -326,6 +336,7 @@ 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_revision_com()
@ -340,6 +351,7 @@ 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 papel_gramaje_datatable()
@ -360,6 +372,19 @@ 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();
@ -475,10 +500,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") : "")
@ -501,7 +523,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()
@ -513,7 +536,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)
@ -626,10 +650,19 @@ class Ordentrabajo extends BaseController
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],
@ -686,7 +719,7 @@ class Ordentrabajo extends BaseController
$r = $this->produccionService->storeOrdenTrabajoTareaProgressDate($validatedData);
$otTareaEntity = $this->otTarea->find($validatedData['ot_tarea_id']);
$data = [
"tiempo_trabajado" => float_seconds_to_hhmm_string($otTareaEntity->tiempo_real),
"tiempo_trabajado" => float_seconds_to_hhmmss_string($otTareaEntity->tiempo_real),
"tarea" => $otTareaEntity,
"estado" => $validatedData['estado'],
];
@ -707,7 +740,7 @@ 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);
@ -750,6 +783,13 @@ class Ordentrabajo extends BaseController
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) {
@ -758,18 +798,38 @@ class Ordentrabajo extends BaseController
foreach ($validatedData['tareas'] as $key => $tareaId) {
$this->produccionService->storeOrdenTrabajoTareaProgressDate(
[
'estado' => 'F',
'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);
@ -783,7 +843,7 @@ class Ordentrabajo extends BaseController
$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();
$maquinaOtTarea = $this->maquinaOtTareaModel->where('orden_trabajo_id', $orden_trabajo_id)->where('maquina_id', $validatedData['maquina_id'])->where('deleted_at', null)->countAllResults();
if ($maquinaOtTarea) {
continue;
}
@ -815,17 +875,15 @@ class Ordentrabajo extends BaseController
$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);
$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);
$this->otTarea->save($tarea);
}
if ($estado == "F") {
$this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->delete();
@ -835,7 +893,7 @@ class Ordentrabajo extends BaseController
}
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]);
}
@ -849,7 +907,7 @@ class Ordentrabajo extends BaseController
$this->produccionService->deleteOrdenTrabajoTareaProgressDates($tarea->id);
}
}
$status = $this->maquinaOtTareaModel->where('maquina_id',$maquina_id)->delete();
$status = $this->maquinaOtTareaModel->where('maquina_id', $maquina_id)->delete();
return $this->response->setJSON(["message" => lang("App.user_alert_delete"), "status" => $status]);
}
@ -876,19 +934,54 @@ class Ordentrabajo extends BaseController
$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['tiempo_total_estimado'] += $tarea->tiempo_estimado;
$responseData['tiempo_total_real'] += $tarea->tiempo_real;
$responseData["estado"] = $tarea->lastState()->estado;
if($tarea->presupuesto_linea_id){
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

@ -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

@ -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;
@ -32,28 +31,7 @@ class Test extends BaseController
public function index()
{
$this->emailService = service('emailService');
$a= $this->emailService->send('prueba', 'Esto es una prueba', ['imnavajas@coit.es','imnavajas@gmail.com']);
echo var_dump($a);
/*$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

@ -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');
}
}

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,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

@ -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

@ -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

@ -248,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

@ -212,7 +212,7 @@ class OrdenTrabajoTareaEntity extends Entity
public function isCosido(): bool
{
$isTareaCosido = false;
$pm = $this->presupuesto_manipulado();
$pm = $this->presupuesto_encuadernacion();
if ($pm) {
$isTareaCosido = $pm->tarifa()->isCosido();
}

View File

@ -40,7 +40,10 @@ class TarifaEncuadernacionEntity extends \CodeIgniter\Entity\Entity
$words_initial = array_map(fn($w) => substr(strtoupper($w),0,1),$words);
return implode("",$words_initial);
}
public function isCosido(): bool
{
return in_array($this->attributes['id'], [3, 17]);
}
}

View File

@ -36,6 +36,6 @@ class TarifaManipuladoEntity extends \CodeIgniter\Entity\Entity
public function isCosido(): bool
{
return in_array($this->attributes['id'], [3, 17]);
return in_array($this->attributes['id'], [2, 3, 17, 45]);
}
}

View File

@ -0,0 +1,32 @@
<?php
if (!function_exists('active_route')) {
/**
* Devuelve 'active' si la ruta actual coincide con la proporcionada.
*
* @param string $routeName Nombre de la ruta definida en route_to().
* @return string
*/
function active_route(string $routeName): string
{
try {
return current_url() === route_to($routeName) ? 'active' : '';
} catch (\Exception $e) {
return ''; // Por si la ruta no existe o lanza error
}
}
}
if (!function_exists('active_uri_starts_with')) {
/**
* Devuelve 'open active' si uri_string() comienza con el prefijo dado.
* Útil para marcar menús padres.
*
* @param string $prefix Prefijo del URI, como 'config', 'catalogo', etc.
* @return string
*/
function active_uri_starts_with(string $prefix): string
{
return str_starts_with(uri_string(), $prefix) ? 'open active' : '';
}
}

View File

@ -29,6 +29,7 @@ return [
'min' => 'Min POD',
'moduleTitle' => 'Machines',
'nombre' => 'Name',
'alias_ot' => 'Alias',
'observaciones' => 'Remarks',
'ordenPlanning' => 'Planning order',
'padreId' => 'Variante',

View File

@ -13,6 +13,7 @@ return [
'att' => 'Att',
'direccion' => 'Dirección',
'cajas' => 'Cajas',
'unidadesCaja' => 'Unidades/Caja',
'acciones' => 'Acciones',
'unidades' => 'Unidades',

View File

@ -35,6 +35,7 @@ return [
"global_next" => "Siguiente",
"global_save_file" => "Guardar ficheros",
"global_upload_files" => "Subir ficheros",
"global_download_files" => "Descargar ficheros",
"global_all" => "Todos",
// LOGIN - Index
"login_title" => "Iniciar sesión en su cuenta",
@ -721,7 +722,7 @@ return [
"menu_digitalizacion" => "Digitalización",
"menu_importadores" => "Importadores",
"menu_importadores_catalogo" => "Desde catálogo",
"menu_importadores_catalogo" => "RA-MA", //"Desde catálogo",
"menu_importadores_bubok" => "Bubok",
"menu_catalogo" => "Catálogo",

View File

@ -63,6 +63,10 @@ return [
'createdAt' => 'Fecha de Creación',
'updatedAt' => 'Fecha de Actualización',
'deletedAt' => 'Fecha de Eliminación',
'tirada' => 'Tirada',
'precioUd' => 'Precio Ud.',
'total' => 'Total',
'estado' => 'Estado',
'catalogoLibro' => 'Libro',
'catalogoLibroList' => 'Lista de Libros',

View File

@ -60,6 +60,7 @@ return [
"subscribe_admin_chat_wrong" => "Tienes que seleccionar un usuario.",
"help_select_chat_department_user" => "Solamente son listados los usuarios que pertenecen al personal. Los clientes no son listados, para añadirlos a la conversación se realiza desde la sección de mensajería de las diferentes secciones(presupuesto,pedido,factura ...)",
"store_department" => "Crear departamento",
"direct_messsages" => "Mensajes directos",
"mail" => [
"mail_subject" => "Nuevo mensaje"
]

View File

@ -21,8 +21,8 @@ return [
'dias' => 'Días',
'serieFacturacion' => 'Serie facturación',
'creditoAsegurado' => 'Crédito asegurado',
'facturaRectificada' => 'Factura rectificada',
'facturaRectificativa' => 'Factura rectificativa',
'facturaRectificada' => 'Fact. rectificada',
'facturaRectificativa' => 'Fact. rectificativa',
'razonSocial' => 'Razón Social',
'cif' => 'CIF',
'direccion' => 'Dirección',
@ -77,6 +77,10 @@ return [
"acumuladoFacturacion" => "Acumulado Facturación",
"totalPendientePago" => "Pendiente de pago",
"textoConformarFactura" => "La factura rectificativa se conformará y pasará a estar pagada.",
"conformarFactura" => "Conformar factura",
"facturaConformada" => "Factura conformada correctamente",
'errors' => [
'requiredFields' => 'Los campos marcados con * son obligatorios',

View File

@ -12,7 +12,7 @@ return [
'precio_compra' => 'Precio Compra',
'importar' => 'Importar',
'subirArchivoRama' => 'Cargar Excel proporcionado por RA-MA',
'subirArchivoBubok' => 'Cargar XML proporcionado por BUBOK',
'subirArchivoBubok' => 'Cargar ZIP proporcionado por BUBOK',
'libro' => 'libro',
'id' => 'ID',

View File

@ -44,6 +44,7 @@ return [
'totales' => 'Totales',
'cajas' => 'Cajas',
'ordenTrabajo' => 'OT',
'pedido' => 'Pedido',
'presupuesto' => 'Presupuesto',
'unidadesEnvio' => 'Unidades envío',
@ -59,9 +60,11 @@ return [
'selectAll' => 'Seleccionar todo',
'peso' => 'Peso (kg): ',
'unidadesTotalesFooter' => 'Unidades:',
'fechaEncuadernado' => 'Fecha encuadernado',
'codigoSeguimiento' => 'Código de seguimiento',
'empresaMensajería' => 'Empresa de mensajería',
'ficharEmbalaje' => 'Fichar embalaje',
'finalizarEnvio' => 'Finalizar envío',
'finalizarEnvioYOTs' => 'Finalizar envío y OTS',
@ -90,6 +93,7 @@ return [
'errorInsertarEtiqueta' => 'Error al insertar la etiqueta',
'noEtiqueta' => 'No se ha encontrado la etiqueta',
'noEtiquetaLineas' => 'No se han encontrado líneas de etiqueta',
'noLineas' => 'No se ha seleccionado ninguna línea',
],
'success' => [
'finalizado' => 'El envío se ha finalizado correctamente',
@ -101,6 +105,7 @@ return [
'comentariosUpdated' => 'Comentarios actualizados correctamente',
'successReordenarCajas' => 'Cajas reordenadas correctamente',
'imprimirEtiquetas' => 'Etiquetas impresas correctamente',
'successFicharEmbalaje' => 'Embalaje fichado correctamente',
],
];

View File

@ -3,174 +3,179 @@
return [
'acabado' => 'acabado',
'alto' => 'Alto',
'altoClick' => 'Alto Click',
'altoImpresion' => 'Alto Impresion',
'ancho' => 'Ancho',
'anchoImpresion' => 'Ancho Impresion',
'createdAt' => 'Created At',
'deletedAt' => 'Deleted At',
'duracionJornada' => 'Duracion Jornada',
'forzarNumFormasHorizontalesPortada' => 'Forzar Num Formas Horizontales Cubierta',
'forzarNumFormasVerticalesPortada' => 'Forzar Num Formas Verticales Cubierta',
'id' => 'ID',
'impresion' => 'impresion',
'isDeleted' => 'Is Deleted',
'isPadre' => 'Usar para variante?',
'isRotativa' => 'Es Rotativa?',
'isTinta' => 'Inkjet',
'manipulado' => 'manipulado',
'maquina' => 'Maquina',
'maquinaList' => 'Lista Máquinas',
'maquinas' => 'Máquinas',
'max' => 'POD Max',
'metrosxminuto' => 'Metros x minuto',
'min' => 'POD Min',
'moduleTitle' => 'Máquinas',
'nombre' => 'Nombre',
'observaciones' => 'Observaciones',
'ordenPlanning' => 'Orden Planning',
'padreId' => 'Variante',
'precioHoraCorte' => 'Precio Hora Corte',
'precioTintaCG' => 'Precio Tinta CG',
'precioTintaColor' => 'Precio Tinta Color',
'precioTintaNegro' => 'Precio Tinta Negro',
'tipo' => 'Tipo',
'updatedAt' => 'Updated At',
'userCreatedId' => 'User Created ID',
'userUpdatedId' => 'User Updated ID',
'velocidad' => 'Velocidad',
'velocidadCorte' => 'Velocidad Corte',
'maquina_tarea' => 'Máquina tarea',
'namePlaceholderDuplicated' => "Inserte el nombre de la máquina a duplicar ...",
'validation' => [
'alto_menor_alto_impresion' => 'El campo \'Alto impresión\' debe ser menor que \'Alto\'',
'ancho_menor_ancho_impresion' => '\'Ancho Impresión\' debe ser menor que \'Ancho\'',
'alto' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'acabado' => 'acabado',
'alto' => 'Alto',
'altoClick' => 'Alto Click',
'altoImpresion' => 'Alto Impresion',
'ancho' => 'Ancho',
'anchoImpresion' => 'Ancho Impresion',
'createdAt' => 'Created At',
'deletedAt' => 'Deleted At',
'duracionJornada' => 'Duracion Jornada',
'forzarNumFormasHorizontalesPortada' => 'Forzar Num Formas Horizontales Cubierta',
'forzarNumFormasVerticalesPortada' => 'Forzar Num Formas Verticales Cubierta',
'id' => 'ID',
'impresion' => 'impresion',
'isDeleted' => 'Is Deleted',
'isPadre' => 'Usar para variante?',
'isRotativa' => 'Es Rotativa?',
'isTinta' => 'Inkjet',
'isEtiquetaEnvio' => 'Etiqueta títulos',
'manipulado' => 'manipulado',
'maquina' => 'Maquina',
'maquinaList' => 'Lista Máquinas',
'maquinas' => 'Máquinas',
'max' => 'POD Max',
'metrosxminuto' => 'Metros x minuto',
'min' => 'POD Min',
'moduleTitle' => 'Máquinas',
'nombre' => 'Nombre',
'alias_ot' => 'Alias',
'observaciones' => 'Observaciones',
'ordenPlanning' => 'Orden Planning',
'padreId' => 'Variante',
'precioHoraCorte' => 'Precio Hora Corte',
'precioTintaCG' => 'Precio Tinta CG',
'precioTintaColor' => 'Precio Tinta Color',
'precioTintaNegro' => 'Precio Tinta Negro',
'tipo' => 'Tipo',
'updatedAt' => 'Updated At',
'userCreatedId' => 'User Created ID',
'userUpdatedId' => 'User Updated ID',
'velocidad' => 'Velocidad',
'velocidadCorte' => 'Velocidad Corte',
'maquina_tarea' => 'Máquina tarea',
'namePlaceholderDuplicated' => "Inserte el nombre de la máquina a duplicar ...",
'validation' => [
'alto_menor_alto_impresion' => 'El campo \'Alto impresión\' debe ser menor que \'Alto\'',
'ancho_menor_ancho_impresion' => '\'Ancho Impresión\' debe ser menor que \'Ancho\'',
'alto' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'ancho' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'ancho' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'forzar_num_formas_horizontales_cubierta' => [
'integer' => 'El campo {field} debe contener un número entero.',
'forzar_num_formas_horizontales_cubierta' => [
'integer' => 'El campo {field} debe contener un número entero.',
],
],
'forzar_num_formas_verticales_cubierta' => [
'integer' => 'El campo {field} debe contener un número entero.',
'forzar_num_formas_verticales_cubierta' => [
'integer' => 'El campo {field} debe contener un número entero.',
],
],
'alto_click' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'alto_click' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'alto_impresion' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'alto_impresion' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'ancho_impresion' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'ancho_impresion' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'greater_than' => 'El campo {field} debe ser mayor que {param}',
],
'duracion_jornada' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
'duracion_jornada' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
],
],
'max' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
'max' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
],
],
'metrosxminuto' => [
'max_length' => 'El campo {field} no puede exeder de {param} caracteres de longitud.',
'required' => 'El campo {field} es obligatorio.',
'metrosxminuto' => [
'max_length' => 'El campo {field} no puede exceder de {param} caracteres de longitud.',
'required' => 'El campo {field} es obligatorio.',
],
],
'min' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
'min' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
],
],
'nombre' => [
'max_length' => 'El campo {field} no puede exeder de {param} caracteres de longitud.',
'required' => 'El campo {field} es obligatorio.',
'nombre' => [
'max_length' => 'El campo {field} no puede exceder de {param} caracteres de longitud.',
'required' => 'El campo {field} es obligatorio.',
],
],
'alias' => [
'max_length' => 'El campo {field} no puede exceder de {param} caracteres de longitud.',
],
'observaciones' => [
'max_length' => 'El campo {field} no puede exeder de {param} caracteres de longitud.',
'required' => 'El campo {field} es obligatorio.',
'observaciones' => [
'max_length' => 'El campo {field} no puede exceder de {param} caracteres de longitud.',
'required' => 'El campo {field} es obligatorio.',
],
],
'orden_planning' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
'orden_planning' => [
'integer' => 'El campo {field} debe contener un número entero.',
'required' => 'El campo {field} es obligatorio.',
],
],
'precio_hora_corte' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'precio_hora_corte' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
],
],
'precio_tinta_cg' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'precio_tinta_cg' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
],
],
'precio_tinta_color' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'precio_tinta_color' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
],
],
'precio_tinta_negro' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'precio_tinta_negro' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
],
],
'tipo' => [
'in_list' => 'El campo {field} debe ser uno uno de: {param}.',
'required' => 'El campo {field} es obligatorio.',
'tipo' => [
'in_list' => 'El campo {field} debe ser uno uno de: {param}.',
'required' => 'El campo {field} es obligatorio.',
],
],
'velocidad' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
'velocidad' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
],
'velocidad_corte' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
],
],
'velocidad_corte' => [
'decimal' => 'El campo {field} debe contener un número decimal.',
'required' => 'El campo {field} es obligatorio.',
],
];
],
];

View File

@ -0,0 +1,6 @@
<?php
return [
'tiradaFlexible' => 'El cliente tiene opción de tirada flexible: ±{unidades, number, integer} unidades.',
];

View File

@ -61,7 +61,7 @@ return [
'coleccion' => 'Colección',
'numeroEdicion' => 'Número de edición',
'isbn' => 'ISBN',
'referenciaCliente' => 'Referencia del cliente',
'referenciaCliente' => 'Referencia cliente',
'referenciaCliente2' => 'Referencia',
'papelFormatoId' => "Tamaño",
'papelFormatoPersonalizado' => 'Tamaño personalizado',
@ -363,6 +363,9 @@ return [
'borrador' => 'Borrador',
'confirmado' => 'Confirmado',
'reprint' => 'Reimpresión',
'presupuestoGenerado' => 'Presupuesto generado con éxito',
'files' => 'Ficheros',
'titulos' => [
'libroFresadoTapaDura' => 'Rústica Fresado tapa dura',
@ -392,6 +395,7 @@ return [
'gramaje_interior' => 'Seleccione el gramaje',
'pais' => 'Debe seleccionar un país',
'integer_greatherThan_0' => 'Número entero > 0 requerido',
'greater_than_0' => 'El campo {field} debe ser mayor que 0',
'tirada_no_valida' => "Tirada no valida",
'sin_gramaje' => "Seleccione gramaje",
'tipo_cubierta' => 'Seleccione tipo de cubierta',
@ -402,6 +406,7 @@ return [
],
'errores' => [
'presupuestoNotFound' => 'Presupuesto no encontrado',
'paginas' => 'El campo páginas tiene que ser mayor que cero',
'paginasLP' => 'El número de páginas no coincide con el total',
'tiradas' => 'El campo tiradas tiene que ser mayor que cero',

View File

@ -1,6 +1,7 @@
<?php
return [
"downloadPdf" => "Descargar",
"navs" => [
'finalizadas' => 'Finalizadas',
'pendientes' => 'Pendientes',
@ -12,6 +13,7 @@ return [
'prod' => 'Producción'
],
"datatable" => [
"nombre" => "Nombre",
"ot_id" => "OT ID",
"barcode" => "Código",
"pedido_id" => "Pedido ID",
@ -37,6 +39,7 @@ return [
"progreso" => "Progreso",
"logo" => "Logo impresion",
"filter_by_task" => "Filtrar por tarea",
"filter_by_machine" => "Filtrar por máquina",
"filter_by_paper" => "Filtrar por papel",
"metros" => "Metros",
"corte" => "Corte",
@ -73,6 +76,7 @@ return [
"formato" => "Formato",
"paginas" => "Páginas",
"guillotina" => "Guillotina/Corte",
"prep_interior_guillotina" => "Prep. interior guillotina",
"tirada" => "Tirada",
"merma" => "Merma",
"pendiente_ferro" => "Pendiente ferro",
@ -118,6 +122,7 @@ return [
//IMPRESION
"impresion_bn" => "Impresión BN",
"cubierta" => "Cubierta/Portada",
"sobrecubierta" => "Sobrecubierta",
"guarda" => "Guarda",
"encuadernacion" => "Encuadernación",
@ -139,7 +144,8 @@ return [
"attr_not_exist" => "El atributo {0,string} no pertenece al modelo Pedido"
],
"maquinas_planas" => "Máquinas planas",
"select_maquina_padre" => "Seleccione una máquina",
"progress_ferro" => "Ferro",
"progress_preimpresion" => "Preimpresión",
"progress_logistica" => "Logística",
@ -180,6 +186,7 @@ return [
'duplicate_estado_tarea_progress' => "Último estado de la tarea repetido",
'task_already_finished' => "La tarea se ha marcado como finalizada.",
'print_label' => "Imprimir etiqueta",
'fichar_embalaje' => "Fichar embalaje",
'click_init' => "Clicks al inicio",
'click_end' => "Clicks al final",
"comentarios" => "Comentarios",
@ -199,5 +206,10 @@ return [
"tareas_finalizadas" => "Las tareas de esta OT y máquina están marcadas como finalizadas",
"ot_not_found" => "La orden de trabajo número {ot_id} no existe"
]
],
'hunkeler' => "Corte HUNKELER",
'tecnau' => "Corte TECNAU",
'end_cut' => "Corte final",
"interior_cut" => "Preparación interior",
"cover_cut" => "Preparación cubierta"
];

View File

@ -63,6 +63,7 @@ return [
'ajustesSection' => 'Ajustes',
'actividadSection' => 'Accesos',
'facturasSection' => 'Facturas',
'logisticaSection' => 'Logística',
'albaranesPermission' => 'Albaranes',
'vencimientosPermission' => 'Vencimientos',
"ticketsSection" => "Tickets",
@ -71,6 +72,7 @@ return [
'importadoresSection' => 'Importadores',
'catalogoPermission' => 'Desde catálogo',
'bubokPermission' => 'Bubok',
'logisticaPermission' => 'Logística',

View File

@ -40,13 +40,14 @@ class SafekatFtpClient
public function uploadXML(string $content, string $filename): bool
{
try {
if ($this->xml_enabled == false) return false;
$remotePath = implode("/", [$this->base_dir,'pedidos','xml_nuevos']);
if ($this->xml_enabled == false)
return false;
$remotePath = implode("/", [$this->base_dir, 'pedidos', 'xml_nuevos']);
$this->ftp->login(username: $this->username, password: $this->password);
if(!$this->ftp->is_dir($remotePath)){
$this->ftp->mkdir($remotePath,recursive:true);
if (!$this->ftp->is_dir($remotePath)) {
$this->ftp->mkdir($remotePath, recursive: true);
}
$this->ftp->put($remotePath.'/'.$filename, $content);
$this->ftp->put($remotePath . '/' . $filename, $content);
return true;
} catch (\Throwable $th) {
@ -58,22 +59,23 @@ class SafekatFtpClient
public function uploadFilePresupuesto(int $presupuesto_id)
{
try {
if ($this->xml_enabled == false) return false;
if ($this->xml_enabled == false)
return false;
$model = model(PresupuestoFicheroModel::class);
$modelPedidoLinea = model(PedidoLineaModel::class);
$pedidoLinea = $modelPedidoLinea->findByPresupuesto($presupuesto_id);
$rootIdExtern = $this->pedido_xml_config->id_offset + $pedidoLinea->pedido_id;
$presupuestoFiles = $model->getFiles($presupuesto_id);
$this->ftp->login(username: $this->username, password: $this->password);
foreach ($presupuestoFiles as $key => $value) {
$filename = array_reverse(explode("/", $value->file_path))[0];
$remoteDir = implode("/", [$this->base_dir,"pedidos_files",$rootIdExtern]);
$remoteFile = implode("/", [$this->base_dir,"pedidos_files",$rootIdExtern,$filename]);
if(!$this->ftp->is_dir($remoteDir)){
$this->ftp->mkdir($remoteDir,recursive:true);
$remoteDir = implode("/", [$this->base_dir, "pedidos_files", $rootIdExtern]);
$remoteFile = implode("/", [$this->base_dir, "pedidos_files", $rootIdExtern, $filename]);
if (!$this->ftp->is_dir($remoteDir)) {
$this->ftp->mkdir($remoteDir, recursive: true);
}
$this->ftp->put($remoteFile,$value->file_path,mode:$this->ftp::SOURCE_LOCAL_FILE);
$this->ftp->put($remoteFile, $value->file_path, mode: $this->ftp::SOURCE_LOCAL_FILE);
}
$this->ftp->disconnect();
} catch (Exception $e) {
@ -91,10 +93,10 @@ class SafekatFtpClient
$rootIdExtern = $this->pedido_xml_config->id_offset + $pedidoLinea->pedido_id;
$presupuestoFiles = $model->getFiles($presupuesto_id);
$this->ftp->login(username: $this->username, password: $this->password);
foreach ($presupuestoFiles as $key => $value) {
$filename = array_reverse(explode("/", $value->file_path))[0];
$remoteFile = implode("/", [$this->base_dir,"pedidos_files",$rootIdExtern,$filename]);
$remoteFile = implode("/", [$this->base_dir, "pedidos_files", $rootIdExtern, $filename]);
$this->ftp->delete($remoteFile);
}
$this->ftp->disconnect();
@ -103,4 +105,66 @@ class SafekatFtpClient
throw $e;
}
}
public function getPresupuestoRemotePath(int $presupuesto_id): string
{
$modelPedidoLinea = model(PedidoLineaModel::class);
$pedidoLinea = $modelPedidoLinea->findByPresupuesto($presupuesto_id);
$rootIdExtern = $this->pedido_xml_config->id_offset + $pedidoLinea->pedido_id;
return implode('/', [$this->base_dir, 'pedidos_files', $rootIdExtern]);
}
public function downloadZipPresupuesto(int $presupuesto_id): ?string
{
$modelPedidoLinea = model(PedidoLineaModel::class);
$model = model(PresupuestoFicheroModel::class);
$pedidoLinea = $modelPedidoLinea->findByPresupuesto($presupuesto_id);
$rootIdExtern = $this->pedido_xml_config->id_offset + $pedidoLinea->pedido_id;
$remotePath = implode('/', [$this->base_dir, 'pedidos_files', $rootIdExtern]);
$this->ftp->login(username: $this->username, password: $this->password);
if (!$this->ftp->is_dir($remotePath)) {
return null;
}
$files = $model->getFiles($presupuesto_id);
if (empty($files)) {
return null;
}
$localTempDir = WRITEPATH . 'zip_presupuestos/' . uniqid("presupuesto_");
if (!is_dir($localTempDir)) {
mkdir($localTempDir, 0777, true);
}
foreach ($files as $file) {
$originalName = $file->nombre ?? basename($file->file_path);
$localFile = $localTempDir . '/' . $originalName;
$remoteFile = $remotePath . '/' . basename($file->file_path);
$this->ftp->get($remoteFile, $localFile);
}
$zipPath = $localTempDir . '.zip';
$zip = new \ZipArchive();
if ($zip->open($zipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
foreach (glob($localTempDir . '/*') as $localFile) {
$zip->addFile($localFile, basename($localFile));
}
$zip->close();
}
// Limpieza temporal
foreach (glob($localTempDir . '/*') as $localFile) {
unlink($localFile);
}
rmdir($localTempDir);
return $zipPath;
}
}

View File

@ -30,6 +30,8 @@ class AlbaranLineaModel extends \App\Models\BaseModel
'created_at',
'updated_at',
'deleted_at',
'cajas',
'unidades_cajas',
];
protected $useSoftDeletes = true;
@ -70,7 +72,7 @@ class AlbaranLineaModel extends \App\Models\BaseModel
->table($this->table . " t1")
->select(
"t1.id, t1.titulo as titulo, t1.isbn as isbn, t1.ref_cliente as ref_cliente,
t1.cantidad as unidades, t1.precio_unidad as precio_unidad, t1.iva_reducido as iva_reducido,
t1.cantidad as unidades, t1.cajas, t1.unidades_cajas, t1.precio_unidad as precio_unidad, t1.iva_reducido as iva_reducido,
t1.total as total, pedidos.id AS pedido"
)
->join("pedidos_linea", "t1.pedido_linea_id = pedidos_linea.id", "left")

View File

@ -93,12 +93,12 @@ class CatalogoLibroModel extends Model
protected $validationMessages = [];
protected $skipValidation = false;
protected $beforeInsert = ['asignarIsk', 'asignarEan', 'asignarCubiertaUrl'];
protected $beforeInsert = ['asignarIskn', 'asignarEan', 'asignarCubiertaUrl'];
protected $beforeUpdate = ['asignarEan', 'asignarCubiertaUrl'];
protected function asignarIsk(array $data): array
protected function asignarIskn(array $data): array
{
$data['data']['isk'] = model('App\Models\Catalogo\IdentificadorIskModel')->newIsk();
$data['data']['iskn'] = model('App\Models\Catalogo\IdentificadorIsknModel')->newIskn();
return $data;
}

View File

@ -1,79 +0,0 @@
<?php
namespace App\Models\Catalogo;
use CodeIgniter\Model;
use RuntimeException;
class IdentificadorIskModel extends Model
{
protected $table = 'identificadores_isk';
protected $primaryKey = 'id';
protected $returnType = \App\Entities\Catalogo\IdentificadorIsk::class;
protected $useSoftDeletes = false; // No soft delete
protected $useTimestamps = true;
protected $allowedFields = ['isk'];
protected $beforeInsert = ['agregarIsk'];
/**
* Crea un nuevo registro con un ISK único y lo devuelve.
*/
public function newIsk(string $contexto = 'libro'): string
{
$isk = $this->generarIskUnico($contexto);
$this->insert(['isk' => $isk]);
return $isk;
}
/**
* Genera un ISK único validado contra la base de datos.
*/
private function generarIskUnico(string $contexto): string
{
do {
$isk = $this->generarIsk($contexto);
} while ($this->where('isk', $isk)->countAllResults() > 0);
return $isk;
}
/**
* Formato legible de ISK, ejemplo: isk_libro_20250419_ab12c
*/
private function generarIsk(string $contexto): string
{
$fecha = date('Ymd');
$random = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789'), 0, 5);
return "isk_{$contexto}_{$fecha}_{$random}";
}
/**
* Hook para generar el ISK automáticamente al insertar.
*/
protected function agregarIsk(array $data): array
{
if (!isset($data['data']['isk']) || empty($data['data']['isk'])) {
$data['data']['isk'] = $this->generarIskUnico('registro');
}
return $data;
}
// Bloqueo total de eliminaciones
public function delete($id = null, bool $purge = false)
{
throw new RuntimeException('La eliminación de registros está deshabilitada.');
}
public function deleteWhere($where)
{
throw new RuntimeException('La eliminación de registros está deshabilitada.');
}
public function deleteBatch($where)
{
throw new RuntimeException('La eliminación de registros está deshabilitada.');
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace App\Models\Catalogo;
use CodeIgniter\Model;
use RuntimeException;
class IdentificadorIsknModel extends Model
{
protected $table = 'identificadores_iskn';
protected $primaryKey = 'id';
protected $returnType = \App\Entities\Catalogo\IdentificadorIskn::class;
protected $useSoftDeletes = false; // No soft delete
protected $useTimestamps = true;
protected $allowedFields = ['iskn'];
protected $beforeInsert = ['agregarIskn'];
/**
* Crea un nuevo registro con un ISKN único y lo devuelve.
*/
public function newIskn(string $contexto = ''): string
{
$iskn = $this->generarIsknUnico($contexto);
$this->insert(['iskn' => $iskn]);
return $iskn;
}
/**
* Genera un ISKN único validado contra la base de datos.
*/
private function generarIsknUnico(string $contexto): string
{
do {
$iskn = $this->generarIskn($contexto);
} while ($this->where('iskn', $iskn)->countAllResults() > 0);
return $iskn;
}
/**
* Formato legible de ISKN, ejemplo: iskn_libro_20250419_ab12c
*/
private function generarIskn(string $contexto): string
{
$fecha = date('Ymd');
$random = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz0123456789'), 0, 5);
return "iskn_{$contexto}_{$fecha}_{$random}";
}
/**
* Hook para generar el ISKN automáticamente al insertar.
*/
protected function agregarIskn(array $data): array
{
if (!isset($data['data']['iskn']) || empty($data['data']['iskn'])) {
$data['data']['iskn'] = $this->generarIsknUnico('registro');
}
return $data;
}
// Bloqueo total de eliminaciones
public function delete($id = null, bool $purge = false)
{
throw new RuntimeException('La eliminación de registros está deshabilitada.');
}
public function deleteWhere($where)
{
throw new RuntimeException('La eliminación de registros está deshabilitada.');
}
public function deleteBatch($where)
{
throw new RuntimeException('La eliminación de registros está deshabilitada.');
}
}

View File

@ -136,7 +136,7 @@ class ChatModel extends Model
$chatDeparmentModel = model(ChatDeparmentModel::class);
$ot = $model->find($orden_trabajo_id);
return $this->insert([
"title" => "[OT]".$ot->id . "[" . $chatDeparmentModel->getDisplay($chat_department_id) . "]",
"title" => "[OT]" . $ot->id . "[" . $chatDeparmentModel->getDisplay($chat_department_id) . "]",
"orden_trabajo_id" => $orden_trabajo_id,
"chat_department_id" => $chat_department_id
]);
@ -381,8 +381,7 @@ class ChatModel extends Model
$row->title = $row->facturaId;
$rows_new[] = $row;
}
elseif ($row->ordenTrabajoId) {
} elseif ($row->ordenTrabajoId) {
// $row->model = $facturaModel->find($row->facturaId);
$row->uri = "/chat/ot/" . $row->ordenTrabajoId . "#accordionChatOrdenTrabajo";
$row->avatar = "OT";
@ -439,8 +438,7 @@ class ChatModel extends Model
$row->chatDisplay .= "[INTERNAL]";
$row->title = $row->facturaId;
$rows_new[] = $row;
}
elseif ($row->ordenTrabajoId) {
} elseif ($row->ordenTrabajoId) {
$row->uri = "/produccion/ordentrabajo/edit/" . $row->ordenTrabajoId . "#accordionChatOrdenTrabajo";
$row->avatar = "OT";
$row->chatDisplay .= "[INTERNAL]";
@ -847,7 +845,7 @@ class ChatModel extends Model
->join("users u", "u.id = cm.sender_id", 'left')
->where("chats.presupuesto_id is NOT NULL", NULL, FALSE);
if (auth()->user()->inGroup("cliente-administrador","cliente")) {
if (auth()->user()->inGroup("cliente-administrador", "cliente")) {
$query->where('presupuestos.cliente_id', auth()->user()->cliente_id)
->where("chats.chat_department_id is NOT NULL", NULL, FALSE);
}
@ -878,7 +876,7 @@ class ChatModel extends Model
->join("presupuestos", "presupuestos.id = pedidos_linea.presupuesto_id", 'left')
->where("chats.pedido_id is NOT NULL", NULL, FALSE);
if (auth()->user()->inGroup("cliente-administrador","cliente")) {
if (auth()->user()->inGroup("cliente-administrador", "cliente")) {
$query->where('presupuestos.cliente_id', auth()->user()->cliente_id)
->where("chats.chat_department_id is NOT NULL", NULL, FALSE);
}
@ -908,10 +906,10 @@ class ChatModel extends Model
->join("facturas", "facturas.id = chats.factura_id", "left")
->where("chats.factura_id is NOT NULL", NULL, FALSE);
if (auth()->user()->inGroup("cliente-administrador","cliente")) {
$query->where('facturas.cliente_id', auth()->user()->cliente_id)
->where("chats.chat_department_id is NOT NULL", NULL, FALSE);
}
if (auth()->user()->inGroup("cliente-administrador", "cliente")) {
$query->where('facturas.cliente_id', auth()->user()->cliente_id)
->where("chats.chat_department_id is NOT NULL", NULL, FALSE);
}
return $query->groupBy('chatMessageId');
}
public function getQueryDatatableMessageOrdenTrabajo(int $user_id): BaseBuilder
@ -938,10 +936,42 @@ class ChatModel extends Model
->join("ordenes_trabajo", "ordenes_trabajo.id = chats.orden_trabajo_id", "left")
->where("chats.orden_trabajo_id is NOT NULL", NULL, FALSE);
if (auth()->user()->inGroup("cliente-administrador","cliente")) {
$query->where('facturas.cliente_id', auth()->user()->cliente_id)
->where("chats.chat_department_id is NOT NULL", NULL, FALSE);
}
if (auth()->user()->inGroup("cliente-administrador", "cliente")) {
$query->where('facturas.cliente_id', auth()->user()->cliente_id)
->where("chats.chat_department_id is NOT NULL", NULL, FALSE);
}
return $query->groupBy('chatMessageId');
}
public function getQueryDatatableDirectMessages(): BaseBuilder
{
$query = $this->builder()
->select([
"chats.id",
"cm.id as chatMessageId",
"u.id as userId",
"cm.message",
"chats.created_at",
"
(
SELECT cm2.updated_at
FROM chat_messages cm2
WHERE cm2.chat_id = chats.id
ORDER BY cm2.updated_at DESC LIMIT 1
) as updated_at",
"CONCAT(u.first_name,' ',u.last_name) as creator",
"chats.title as title",
])
->join("chat_messages cm", "chats.id = cm.chat_id", "left")
->join("users u", "u.id = cm.sender_id", 'left')
->where("chats.presupuesto_id", NULL)
->where("chats.pedido_id", NULL)
->where("chats.factura_id", NULL)
->where("chats.orden_trabajo_id", NULL)
->groupStart()
->orWhere("cm.receiver_id",auth()->user()->id)
->orWhere("cm.sender_id",auth()->user()->id)
->groupEnd();
return $query->groupBy('chatMessageId');
}
public function createNewDirectChat(string $title, string $message, array $users)

View File

@ -52,7 +52,9 @@ class MaquinaModel extends \App\Models\BaseModel
"deleted_at",
"is_deleted",
"user_created_id",
"user_updated_id"
"user_updated_id",
"etiqueta_envio",
"alias_ot",
];
protected $returnType = "App\Entities\Configuracion\Maquina";
@ -148,6 +150,10 @@ class MaquinaModel extends \App\Models\BaseModel
"label" => "Maquinas.velocidadCorte",
"rules" => "decimal",
],
"alias_ot" => [
"label" => "Maquinas.alias_ot",
"rules" => "max_length[255]",
],
];
protected $validationMessages = [
@ -195,6 +201,9 @@ class MaquinaModel extends \App\Models\BaseModel
"max_length" => "Maquinas.validation.nombre.max_length",
"required" => "Maquinas.validation.nombre.required",
],
"alias_ot" => [
"max_length" => "Maquinas.validation.alias.max_length"
],
"observaciones" => [
"max_length" => "Maquinas.validation.observaciones.max_length",
//"required" => "Maquinas.validation.observaciones.required",

View File

@ -433,7 +433,7 @@ class PapelGenericoModel extends \App\Models\BaseModel
4.-> papeles genericos que aparecen en esos papeles impresion
*/
if ($POD == true && ($tipo == 'color' || $tipo == 'negro')) {
if ($POD == true && ($tipo == 'color')) {
if ($tipo == 'color')
$tipo = 'colorhq';
else if ($tipo == 'negro')

View File

@ -13,20 +13,22 @@ class PapelImpresionModel extends \App\Models\BaseModel
protected $useAutoIncrement = true;
const SORTABLE = [
0 => "t1.nombre",
1 => "t2.nombre",
2 => "t1.gramaje",
3 => "t1.interior",
4 => "t1.bn",
5 => "t1.color",
6 => "t1.cubierta",
7 => "t1.use_for_tapa_dura",
8 => "t1.sobrecubierta",
9 => "t1.guardas",
10 => "t1.inkjet",
11 => "t1.rotativa",
12 => "t1.isActivo",
13 => "t1.use_in_client",
0 => "t1.id",
1 => "t1.nombre",
2 => "t2.nombre",
3 => "t1.gramaje",
4 => "t1.interior",
5 => "t1.bn",
6 => "t1.color",
7 => "t1.cubierta",
8 => "t1.use_for_tapa_dura",
9 => "t1.sobrecubierta",
10 => "t1.guardas",
11 => "t1.inkjet",
12 => "t1.rotativa",
13 => "t1.isActivo",
14 => "t1.use_in_client",
15 => "t1.precio_tonelada",
];
@ -173,7 +175,7 @@ class PapelImpresionModel extends \App\Models\BaseModel
->groupStart()
->like("t1.nombre", $search)
->orLike("t1.gramaje", $search)
->orLike("t1.nombre", $search)
->orLike("t1.precio_tonelada", $search)
->orLike("t1.gramaje", $search)
->orLike("t2.nombre", $search)
->groupEnd();

View File

@ -0,0 +1,71 @@
<?php
namespace App\Models\Configuracion;
use CodeIgniter\Model;
use App\Entities\Configuracion\SelectorCalidadImpresion;
class SelectorCalidadImpresionModel extends Model
{
protected $table = 'selector_calidad_impresion';
protected $primaryKey = 'id';
protected $returnType = SelectorCalidadImpresion::class;
protected $useSoftDeletes = true;
protected $allowedFields = [
'alias',
'cliente_id',
'isPod',
'input_isColor',
'input_isHq',
'output_isColor',
'output_isHq',
];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
public function getCalidadImpresion($alias = 'cliente', $cliente_id = null, $isColor = 0, $isHq = 0, $tirada = 100)
{
$pod = intval(model('App\Models\Configuracion\ConfigVariableModel')->getVariable('POD')->value);
$isPoD = $tirada <= $pod ? 1 : 0;
$builder = $this->db
->table($this->table . " t1")
->select('output_isColor, output_isHq')
->where('alias', $alias)
->where('input_isColor', $isColor)
->where('input_isHq', $isHq)
->where('isPod', $isPoD)
->where('deleted_at', null);
if ($cliente_id) {
$builder->where('cliente_id', $cliente_id);
}
$output_isColor = 0;
$output_isHq = 0;
$result = $builder->get()->getRowArray();
if ($result){
$output_isColor = $result['output_isColor'];
$output_isHq = $result['output_isHq'];
return [
'status' => true,
'isColor' => $output_isColor,
'isHq' => $output_isHq,
];
} else {
return [
'status' => false,
'isColor' => $output_isColor,
'isHq' => $output_isHq,
];
}
}
}

View File

@ -27,9 +27,9 @@ class FacturaModel extends \App\Models\BaseModel
];
const SORTABLE_PEDIDOS = [
1 => "t1.numero",
2 => "t2.nombre",
3 => "t4.cantidad",
1 => "t1.id",
2 => "t1.numero",
3 => "t4.ejemplares",
4 => "t2.nombre",
5 => "t1.estado",
6 => "t1.fecha_factura_at",
@ -129,7 +129,7 @@ class FacturaModel extends \App\Models\BaseModel
$builder->join("clientes t2", "t2.id = t1.cliente_id", "left");
$builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left");
$builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left");
$builder->where("t1.deleted_at", null);
if (auth()->user()->inGroup("cliente-admin") || auth()->user()->inGroup("cliente-editor")) {
@ -140,7 +140,7 @@ class FacturaModel extends \App\Models\BaseModel
$builder->where("t1.cliente_id", $cliente_id);
}
$builder->groupBy("t1.id");
$builder->groupBy("t1.id");
//$query = $builder->getCompiledSelect();
return $builder;
}
@ -166,9 +166,10 @@ class FacturaModel extends \App\Models\BaseModel
return !empty($result);
}
public function getSumatoriosFacturacionCliente($cliente_id = -1){
public function getSumatoriosFacturacionCliente($cliente_id = -1)
{
if($cliente_id == -1){
if ($cliente_id == -1) {
return [
'total_facturacion' => 0,
'total_pendiente' => 0
@ -183,7 +184,7 @@ class FacturaModel extends \App\Models\BaseModel
->where('f.estado', 'validada')
->get()
->getResultObject();
$result['total_facturacion'] =
$result['total_facturacion'] =
round(floatval(($data && $data[0]->total != null) ? $data[0]->total : 0), 2);
$data = $this->db->table('facturas f')
@ -253,7 +254,17 @@ class FacturaModel extends \App\Models\BaseModel
$builder->join("pedidos t6", "t5.pedido_id = t6.id", "left");
$builder->where("t1.deleted_at IS NULL");
$builder->where("t6.id", $pedido_id);
$builder->groupStart()
->where("t6.id", $pedido_id)
->orWhere("t1.factura_rectificada_id IN (
SELECT f.numero
FROM facturas f
JOIN facturas_pedidos_lineas fpl ON f.id = fpl.factura_id
JOIN pedidos_linea pl ON fpl.pedido_linea_id = pl.id
JOIN pedidos p ON pl.pedido_id = p.id
WHERE p.id = {$pedido_id}
)")
->groupEnd();
$builder->groupBy("t1.id"); // Agrupa por id de la factura

View File

@ -35,7 +35,7 @@ class EnvioLineaModel extends Model
$builder = $this->db
->table($this->table . " t1")
->select(
"t1.id, t1.pedido_id as pedido, t3.id as presupuesto,
"t1.id, t1.pedido_id as pedido, t3.id as presupuesto, t4.id as ordenTrabajo,
t3.titulo as titulo, t1.unidades_envio as unidadesEnvio, t1.unidades_envio as unidadesEnvioRaw,
t1.unidades_total as unidadesTotal, t2.tipo_envio as tipo_envio,
IFNULL((
@ -59,6 +59,7 @@ class EnvioLineaModel extends Model
);
$builder->join("envios t2", "t1.envio_id = t2.id", "left");
$builder->join("presupuestos t3", "t1.presupuesto_id = t3.id", "left");
$builder->join("ordenes_trabajo t4", "t1.pedido_id = t4.pedido_id", "left");
$builder->where("t1.envio_id", $envio_id);

View File

@ -143,4 +143,25 @@ class OrdenTrabajoModel extends Model
->groupBy('orden_trabajo_tareas.id');
return $query;
}
public function queryProximosEnvios()
{
$query = $this->builder()
->select([
'ordenes_trabajo.id as ot',
'orden_trabajo_dates.encuadernacion_at as fechaEncuadernado',
])
->join('pedidos', 'pedidos.id = ordenes_trabajo.pedido_id', 'left')
->join('pedidos_linea', 'pedidos.id = pedidos_linea.pedido_id', 'left')
->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left')
->join('presupuesto_direcciones', 'presupuestos.id = presupuesto_direcciones.presupuesto_id', 'left')
->join('orden_trabajo_dates', 'orden_trabajo_dates.orden_trabajo_id = ordenes_trabajo.id', 'left')
->where('ordenes_trabajo.deleted_at', null)
->where('orden_trabajo_dates.encuadernacion_at !=', null)
//->where('orden_trabajo_dates.fecha_encuadernado_at >=', 0)
//->where('ordenes_trabajo.fecha_entrega_warning >=', date("Y-m-d H:i:s"))
->groupBy('ordenes_trabajo.id');
return $query;
}
}

View File

@ -20,7 +20,7 @@ class BuscadorModel extends \App\Models\BaseModel
3 => "t2.nombre",
4 => "t3.first_name",
5 => "t1.titulo",
6 => "t5.nombre",
6 => "t1.referencia_cliente",
7 => "t1.inc_rei",
8 => "t1.paginas",
9 => "t1.tirada",
@ -127,13 +127,12 @@ class BuscadorModel extends \App\Models\BaseModel
->select(
"t1.id AS id, t1.created_at AS fecha, t7.codigo as codigo, t2.nombre AS cliente,
CONCAT(t3.first_name, ' ', t3.last_name) AS comercial, t1.titulo AS titulo,
t5.nombre AS pais, t1.inc_rei AS inc_rei, t1.paginas AS paginas, t1.tirada AS tirada,
t1.referencia_cliente AS refCliente, t1.inc_rei AS inc_rei, t1.paginas AS paginas, t1.tirada AS tirada,
t1.total_presupuesto AS total_presupuesto, t1.total_presupuesto AS total_presupuesto,
t6.estado AS estado"
);
$builder->join("clientes t2", "t1.cliente_id = t2.id", "left");
$builder->join("users t3", "t2.comercial_id = t3.id", "left");
$builder->join("lg_paises t5", "t1.pais_id = t5.id", "left");
$builder->join("presupuesto_estados t6", "t1.estado_id = t6.id", "left");
$builder->join("tipos_presupuestos t7", "t1.tipo_impresion_id = t7.id", "left");

View File

@ -8,7 +8,8 @@ class ImportadorModel extends \App\Models\BaseModel
protected $primaryKey = 'id';
protected $DBGroup = 'old_erp';
public function getClientList(){
public function getClientList()
{
$db = \Config\Database::connect($this->DBGroup); // Conectar a olderp
$builder = $db->table('customers');
@ -19,29 +20,31 @@ class ImportadorModel extends \App\Models\BaseModel
}
public function getPresupuestosList($clienteId, $search = ""){
public function getPresupuestosList($clienteId, $search = "")
{
$db = \Config\Database::connect($this->DBGroup); // Conectar a olderp
$builder = $db->table('pedido_libro');
$builder->select('id as id, CONCAT(id, " - ", titulo) as name');
$builder->where('customer_id', $clienteId);
$builder->whereIn('estado', ['finalizado', 'validado']);
$builder->whereIn('estado', ['finalizado', 'validado', 'presupuesto']);
$builder->where('deleted_at', NULL);
$builder->orderBy('updated_at', 'DESC');
return empty($search) ?
$builder->get()->getResultObject() :
return empty($search) ?
$builder->get()->getResultObject() :
$builder->groupStart()->
like('titulo', $search)->
orLike('id', $search)->
orLike('id', $search)->
groupEnd()->get()->getResultObject();
}
public function getPresupuestoForImport($id){
public function getPresupuestoForImport($id)
{
$db = \Config\Database::connect($this->DBGroup); // Conectar a olderp
$builder = $db->table('pedido_libro t1')
->select('t1.paginas, t1.tirada, t1.papel_formato_personalizado,
->select('t1.paginas, t1.tirada, t1.papel_formato_personalizado, t1.customer_id,
t1.papel_formato_ancho as papel_formato_personalizado_ancho,
t1.papel_formato_alto as papel_formato_personalizado_alto,
t2.ancho as papel_formato_ancho, t2.alto as papel_formato_alto,
@ -50,7 +53,7 @@ class ImportadorModel extends \App\Models\BaseModel
->where('t1.id', $id)
->where('t1.deleted_at', NULL);
$query = $builder->get();
$datosGenerales = $query->getRow();
$datosGenerales = $query->getRow();
$builder = $db->table('pedido_libro_manipulado')
->select('nombre')
@ -69,10 +72,9 @@ class ImportadorModel extends \App\Models\BaseModel
->where('pedido_libro_id', $id)
->where('nombre', 'Prototipo');
$query = $builder->countAllResults();
if($query > 0){
if ($query > 0) {
$datosGenerales->prototipo = 1;
}
else{
} else {
$datosGenerales->prototipo = 0;
}
@ -85,7 +87,7 @@ class ImportadorModel extends \App\Models\BaseModel
$query = $builder->get();
$lineas = $query->getResultObject();
return [
'datosGenerales' => $datosGenerales,
'manipulados' => $manipulados,
@ -95,8 +97,9 @@ class ImportadorModel extends \App\Models\BaseModel
}
public function getDatosGuardar($id){
public function getDatosGuardar($id)
{
$db = \Config\Database::connect($this->DBGroup); // Conectar a olderp
$db = \Config\Database::connect($this->DBGroup); // Conectar a olderp
$builder = $db->table('pedido_libro t1')
@ -107,12 +110,13 @@ class ImportadorModel extends \App\Models\BaseModel
->where('t1.id', $id)
->where('t1.deleted_at', NULL);
$query = $builder->get();
$datosGenerales = $query->getRow();
$datosGenerales = $query->getRow();
return $query->getRow();
}
public function getDirecciones($id){
public function getDirecciones($id)
{
$db = \Config\Database::connect($this->DBGroup); // Conectar a olderp
$builder = $db->table('pedido_libro_envios t1')
->select('t1.ejemplares as unidades, t1.att, t1.email, t1.direccion, t1.pais,
@ -123,6 +127,29 @@ class ImportadorModel extends \App\Models\BaseModel
return $query->getResultObject();
}
public function getHistoricoPedidosCatalogo(?int $catalogoId = null)
{
$db = \Config\Database::connect($this->DBGroup);
$builder = $db->table('pedido_libro t1')
->select(
't1.id,
t1.created_at,
t1.tirada,
(CASE
WHEN t1.tirada > 0 THEN t1.total / t1.tirada
ELSE 0
END) AS precio_ud,
t1.total,
t1.estado');
if ($catalogoId !== null) {
$builder->where('t1.catalogo_id', $catalogoId);
}
return $builder;
}
}

View File

@ -305,17 +305,17 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel
$precio_unidad = $tarifa->precio_max;
$precio_unidad = $precio_unidad * (1 + floatval($tarifa->margen) / 100.0);
if (!$is_POD) {
$precio_unidad += floatval($tarifa->tarifa_importe_fijo)/floatval($tirada);
}
$total = $precio_unidad * $tirada;
$margen = floatval($tarifa->margen);
$tarifa_precio_min = floatval($tarifa->tarifa_precio_min);
if ($tarifa->tarifa_precio_min > $total) {
$total = $total - ($total * $margen / 100.0);
$margen = round(100.0 * (floatval($tarifa->tarifa_precio_min) - $total) / floatval($tarifa->tarifa_precio_min), 0);
$total = floatval($tarifa->tarifa_precio_min);
if ($tarifa_precio_min * (1 + floatval($tarifa->margen) / 100.0) > $total) {
$total = $tarifa_precio_min * (1 + floatval($tarifa->margen)/100.0);
$precio_unidad = round(floatval($total / $tirada), 2);
}
if (!$is_POD) {
$total += floatval($tarifa->tarifa_importe_fijo) ;
$precio_unidad = round(floatval($total / $tirada), 2);
}

View File

@ -86,6 +86,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
'tarifa_nombre' => $tarifa_proveedor->tarifa_enc_nombre,
'nombre' => $tarifa_proveedor->tarifa_enc_nombre,
'precio_unidad' => $result_data[0],
'importe_fijo' => $tarifa_proveedor->importe_fijo,
'tiempo' => $tiempo,
'total' => $result_data[1],
'precio_total' => $result_data[1],
@ -124,6 +125,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
'nombre' => $tarifa['tarifa_nombre'],
'proveedor' => lang('Presupuestos.no_disponible'),
'precio_unidad' => 0,
'importe_fijo' => 0,
'tiempo' => null,
'total' => 0,
'precio_total' => 0,
@ -143,6 +145,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
'tarifa_nombre' => $tarifa_proveedor->tarifa_enc_nombre,
'nombre' => $tarifa_proveedor->tarifa_enc_nombre,
'precio_unidad' => $result_data[0],
'importe_fijo' => $tarifa_proveedor->importe_fijo,
'tiempo' => null,
'total' => $result_data[1],
'precio_total' => $result_data[1],
@ -170,6 +173,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
'nombre' => $tarifa['tarifa_nombre'],
'proveedor' => lang('Presupuestos.no_disponible'),
'precio_unidad' => 0,
'importe_fijo' => 0,
'tiempo' => null,
'total' => 0,
'precio_total' => 0,
@ -228,6 +232,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
array_push($ret_array, (object) [
'tarifa_id' => $tarifa->tarifa_enc_id,
'tarifa_nombre' => $tarifa->tarifa_enc_nombre,
'importe_fijo' => $tarifa->importe_fijo,
'nombre' => $tarifa->tarifa_enc_nombre,
'precio_unidad' => $result_data[0],
'tiempo' => null,
@ -254,6 +259,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
'nombre' => $modelTarifa->getNombreTarifaEncuadernacion($tarifa_encuadernacion_id)[0]->nombre,
'proveedor' => lang('Presupuestos.no_disponible'),
'precio_unidad' => 0,
'importe_fijo' => 0,
'tiempo' => null,
'total' => 0,
'precio_total' => 0,
@ -309,6 +315,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
'precio_unidad' => $result_data[0],
'tiempo' => $tiempo,
'paginas_por_cuadernillo' => $paginas_cuadernillo,
'importe_fijo' => $tarifa_proveedor->importe_fijo,
'precio_total' => $result_data[1],
'total' => $result_data[1],
'margen' => $result_data[2],
@ -334,6 +341,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
'nombre' => $modelTarifa->getNombreTarifaEncuadernacion($tarifa_encuadernacion_id)[0]->nombre,
'proveedor' => lang('Presupuestos.no_disponible'),
'precio_unidad' => 0,
'importe_fijo' => 0,
'tiempo' => null,
'paginas_por_cuadernillo' => null,
'total' => 0,
@ -351,22 +359,23 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
$precio_unidad = floatval($tarifa->precio_max) - (floatval($tarifa->precio_max) - floatval($tarifa->precio_min)) / ($tarifa->paginas_max - $tarifa->paginas_min) * ($paginas - $tarifa->paginas_min);
if ($paginas > $tarifa->paginas_max)
$precio_unidad = $tarifa->precio_max;
$precio_unidad = $precio_unidad * (1 + floatval($tarifa->margen) / 100.0);
if (!$is_POD) {
$precio_unidad += floatval($tarifa->tarifa_importe_fijo) / floatval($ejemplares);
}
$precio_unidad = $precio_unidad * (1 + floatval($tarifa->margen)/100.0);
$precio_unidad = round($precio_unidad, 2);
$total = $precio_unidad * $ejemplares;
$margen = floatval($tarifa->margen);
$tarifa_precio_min = floatval($tarifa->tarifa_precio_min);
if ($tarifa_precio_min > $total) {
$total = $total - ($total * $margen / 100.0);
$margen = round(100.0 * (floatval($tarifa_precio_min) - $total) / floatval($tarifa_precio_min), 0);
$total = floatval($tarifa_precio_min);
if ($tarifa_precio_min * (1 + floatval($tarifa->margen) / 100.0) > $total) {
$total = $tarifa_precio_min * (1 + floatval($tarifa->margen)/100.0);
$precio_unidad = round(floatval($total / $ejemplares), 2);
}
if (!$is_POD) {
$total += floatval($tarifa->tarifa_importe_fijo) ;
$precio_unidad = round(floatval($total / $ejemplares), 2);
}
@ -459,18 +468,66 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
*/
public function getResource($presupuesto_id = -1)
{
$builder = $this->db
->table($this->table . " t1")
->select(
"t1.id AS id, t1.tarifa_encuadernado_id AS tarifa_encuadernado_id, t1.precio_unidad AS precio_unidad, t1.tiempo AS tiempo,
t1.precio_total AS precio_total, t1.margen AS margen, t2.nombre AS nombre, t1.proveedor_id AS proveedor_id, t3.nombre AS proveedor,
t1.paginas_por_cuadernillo AS paginas_por_cuadernillo"
);
$builder->where('t1.presupuesto_id', $presupuesto_id);
$builder->join("tarifa_encuadernacion t2", "t1.tarifa_encuadernado_id = t2.id", "left");
$builder->join("lg_proveedores t3", "t1.proveedor_id = t3.id", "left");
$builder = $this->db->table('presupuesto_encuadernaciones t1')
->select("
t1.id AS id,
t1.tarifa_encuadernado_id AS tarifa_encuadernado_id,
t1.precio_unidad AS precio_unidad,
t1.tiempo AS tiempo,
t1.precio_total AS precio_total,
t1.margen AS margen,
t2.nombre AS nombre,
t1.proveedor_id AS proveedor_id,
t3.nombre AS proveedor,
t1.paginas_por_cuadernillo AS paginas_por_cuadernillo,
presupuestos.tirada AS tirada,
CASE
WHEN t2.por_horas = 0 THEN (
SELECT t2_sub.importe_fijo
FROM tarifa_encuadernacion_tiradas t2_sub
JOIN tarifa_encuadernacion_lineas t3_sub ON t2_sub.id = t3_sub.tirada_encuadernacion_id
JOIN tarifa_encuadernacion_dimensiones t4_sub ON t3_sub.dimensiones_id = t4_sub.id
WHERE t2_sub.tarifa_encuadernacion_id = t1.tarifa_encuadernado_id
AND t2_sub.tirada_min <= presupuestos.tirada
AND t2_sub.tirada_max >= presupuestos.tirada
AND t3_sub.paginas_libro_min <= presupuestos.paginas
AND t3_sub.paginas_libro_max >= presupuestos.paginas
AND t4_sub.ancho_min <=
CASE WHEN presupuestos.papel_formato_personalizado = 1 THEN LEAST(presupuestos.papel_formato_ancho, presupuestos.papel_formato_alto)
ELSE LEAST(lg_papel_formato.ancho, lg_papel_formato.alto) END
AND t4_sub.ancho_max >
CASE WHEN presupuestos.papel_formato_personalizado = 1 THEN LEAST(presupuestos.papel_formato_ancho, presupuestos.papel_formato_alto)
ELSE LEAST(lg_papel_formato.ancho, lg_papel_formato.alto) END
AND t4_sub.alto_min <=
CASE WHEN presupuestos.papel_formato_personalizado = 1 THEN GREATEST(presupuestos.papel_formato_ancho, presupuestos.papel_formato_alto)
ELSE GREATEST(lg_papel_formato.ancho, lg_papel_formato.alto) END
AND t4_sub.alto_max >=
CASE WHEN presupuestos.papel_formato_personalizado = 1 THEN GREATEST(presupuestos.papel_formato_ancho, presupuestos.papel_formato_alto)
ELSE GREATEST(lg_papel_formato.ancho, lg_papel_formato.alto) END
AND t2_sub.proveedor_id = t1.proveedor_id
LIMIT 1
)
WHEN t2.por_horas = 1 THEN (
SELECT t2_sub.importe_fijo
FROM tarifa_encuadernacion_tiradas t2_sub
JOIN tarifa_encuadernacion_lineas_horas t3_sub ON t2_sub.id = t3_sub.tirada_encuadernacion_id
WHERE t2_sub.tarifa_encuadernacion_id = t1.tarifa_encuadernado_id
AND t2_sub.tirada_min <= presupuestos.tirada
AND t2_sub.tirada_max > presupuestos.tirada
AND t3_sub.tiempo_min <= t1.tiempo
AND t3_sub.tiempo_max > t1.tiempo
AND t2_sub.proveedor_id = t1.proveedor_id
LIMIT 1
)
ELSE NULL
END AS importe_fijo
")
->join("tarifa_encuadernacion t2", "t1.tarifa_encuadernado_id = t2.id", "left")
->join("lg_proveedores t3", "t1.proveedor_id = t3.id", "left")
->join("presupuestos", "presupuestos.id = t1.presupuesto_id", "left")
->join("lg_papel_formato", "lg_papel_formato.id = presupuestos.papel_formato_id", "left")
->where("t1.presupuesto_id", $presupuesto_id);
return $builder;
}
@ -486,7 +543,7 @@ class PresupuestoEncuadernacionesModel extends \App\Models\BaseModel
return 0.01;
else
return $temp;
}
private function calcularTiempoCosido($maquina_id, $paginas, $tirada, $cuadernillos_por_pagina = 32)

View File

@ -24,10 +24,11 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
public static $labelField = "nombre";
public function saveFileInBBDD($presupuesto_id, $filename, $extension ,$user_id) {
try{
public function saveFileInBBDD($presupuesto_id, $filename, $extension, $user_id)
{
try {
$new_filename = $this->generateFileHash($filename) . '.' . $extension;
$this->db->table($this->table . " t1")
->set('presupuesto_id', $presupuesto_id)
->set('nombre', $filename)
@ -42,13 +43,14 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
}
}
public function deleteFiles($presupuesto_id, $old_files = []){
public function deleteFiles($presupuesto_id, $old_files = [])
{
$files = $this->db
->table($this->table . " t1")
->where('presupuesto_id', $presupuesto_id)->get()->getResult();
if($files){
foreach($files as $file){
if ($files) {
foreach ($files as $file) {
// se comprueba que el $file->nombre no sea igual a ninguno de los elementos del array $old_files
if (!in_array($file->nombre, $old_files)) {
@ -67,21 +69,52 @@ class PresupuestoFicheroModel extends \App\Models\BaseModel
}
public function getFiles($presupuesto_id){
public function copyFiles($presupuesto_id_origen, $presupuesto_id_destino)
{
$files = $this->db
->table($this->table . " t1")
->where('presupuesto_id', $presupuesto_id_origen)->get()->getResult();
if ($files) {
foreach ($files as $file) {
$hash = $this->generateFileHash($file->nombre);
// se copia el fichero a la nueva ubicación
if (!file_exists(WRITEPATH . $file->file_path)) {
copy($file->file_path, WRITEPATH . 'uploads/presupuestos/' . $hash);
}
$this->db->table($this->table . " t1")
->set('presupuesto_id', $presupuesto_id_destino)
->set('nombre', $file->nombre)
->set('file_path', WRITEPATH . 'uploads/presupuestos/' . $hash)
->set('upload_by', auth()->user()->id)
->set('upload_at', date('Y-m-d H:i:s'))
->insert();
}
}
}
public function getFiles($presupuesto_id)
{
return $this->db
->table($this->table . " t1")
->where('presupuesto_id', $presupuesto_id)->get()->getResult();
}
/**
* Función para convertir el nombre y extensión de un fichero en un hash único
* usando cifrado simétrico.
*
* @param string $filename Nombre del fichero con extensión
* @return string Hash encriptado del fichero
*/
private function generateFileHash($filename) {
* Función para convertir el nombre y extensión de un fichero en un hash único
* usando cifrado simétrico.
*
* @param string $filename Nombre del fichero con extensión
* @return string Hash encriptado del fichero
*/
private function generateFileHash($filename)
{
return hash('sha256', $filename);
}

View File

@ -102,17 +102,15 @@ class PresupuestoManipuladosModel extends \App\Models\BaseModel
$precio_unidad = $tarifa->precio_max;
$precio_unidad = $precio_unidad * (1 + floatval($tarifa->margen) / 100.0);
if (!$is_POD) {
$precio_unidad += floatval($tarifa->tarifa_importe_fijo)/floatval($tirada);
}
$total = $precio_unidad * $tirada;
$margen = floatval($tarifa->margen);
if ($tarifa->tarifa_precio_min > $total) {
$total = $total - ($total * $margen / 100.0);
$margen = round(100.0 * (floatval($tarifa->tarifa_precio_min) - $total) / floatval($tarifa->tarifa_precio_min), 0);
$total = floatval($tarifa->tarifa_precio_min);
$tarifa_precio_min = floatval($tarifa->tarifa_precio_min);
if ($tarifa_precio_min * (1 + floatval($tarifa->margen) / 100.0) > $total) {
$total = $tarifa_precio_min * (1 + floatval($tarifa->margen)/100.0);
$precio_unidad = round(floatval($total / $tirada), 2);
}
if (!$is_POD) {
$total += floatval($tarifa->tarifa_importe_fijo);
$precio_unidad = round(floatval($total / $tirada), 2);
}

View File

@ -151,6 +151,14 @@ class PresupuestoModel extends \App\Models\BaseModel
public static $labelField = "titulo";
protected $validationRulesAdd = [
"tirada" => [
"label" => "Presupuestos.tirada",
"rules" => "required|integer|greater_than[0]",
],
"paginas" => [
"label" => "Presupuestos.paginas",
"rules" => "required|integer|greater_than[0]",
],
"autor" => [
"label" => "Presupuestos.autor",
"rules" => "trim|max_length[150]",
@ -190,6 +198,12 @@ class PresupuestoModel extends \App\Models\BaseModel
];
protected $validationMessagesAdd = [
"tirada" => [
"greater_than" => "Presupuestos.validation.greater_than_0",
],
"paginas" => [
"greater_than" => "Presupuestos.validation.greater_than_0",
],
"autor" => [
"max_length" => "Presupuestos.validation.max_length",
"required" => "Presupuestos.validation.requerido",
@ -271,7 +285,7 @@ class PresupuestoModel extends \App\Models\BaseModel
t1.total_presupuesto AS total_presupuesto, t1.total_presupuesto AS total_presupuesto, t6.estado AS estado"
);
$builder->join("clientes t2", "t1.cliente_id = t2.id", "left");
$builder->join("users t3", "t1.user_update_id = t3.id", "left");
$builder->join("users t3", "t2.comercial_id = t3.id", "left");
$builder->join("lg_paises t5", "t1.pais_id = t5.id", "left");
$builder->join("presupuesto_estados t6", "t1.estado_id = t6.id", "left");
@ -453,7 +467,7 @@ class PresupuestoModel extends \App\Models\BaseModel
'comparador_json_data' => $this->generateJson($data),
'faja_color' => is_array($data['faja']) ? 1 : 0,
'faja_color' => is_array($data['faja']) && count($data['faja'])>0 ? 1 : 0,
'solapas_ancho_faja_color' => is_array($data['faja']) && $data['faja'] !== [] ? $data['faja']['solapas'] : 60,
'alto_faja_color' => is_array($data['faja']) && $data['faja'] !== [] ? $data['faja']['alto'] : 50,
@ -508,15 +522,18 @@ class PresupuestoModel extends \App\Models\BaseModel
'excluir_rotativa' => $excluir_rotativa,
];
/* Actualizacion */
if ($id != 0) {
$fields['id'] = $id;
$fields['updated_at'] = date('Y-m-d H:i:s', now());
}
if ($id != 0) {
$fields['user_update_id'] = auth()->id();
$this->db->table($this->table)->where('id', $id)->update($fields);
return $id;
} else {
}
/* Inserccion */
else {
$fields['user_created_id'] = auth()->id();
$fields['user_update_id'] = auth()->id();
$this->db->table($this->table)->insert($fields);
return $this->db->insertID();
}

View File

@ -20,7 +20,7 @@ class ActivityModel extends BaseModel
const SORTABLE = [
1 => "t1.id",
2 => "t2.username",
2 => "t3.secret",
3 => "t1.level",
4 => "t1.event",
5 => "t1.ip",
@ -55,10 +55,17 @@ class ActivityModel extends BaseModel
$builder = $this->db
->table($this->table . " t1")
->select(
"t1.id AS id, t2.username AS user, t1.level AS level, t1.event AS event, t1.ip AS ip, t1.os AS os,
t1.browser AS browser, t1.created_at AS created_at"
"t1.id AS id,
t3.secret AS user,
t1.level AS level,
t1.event AS event,
t1.ip AS ip,
t1.os AS os,
t1.browser AS browser,
t1.created_at AS created_at"
)
->join("users t2", "t1.user_id = t2.id", "left")
->join("auth_identities t3", "t3.user_id = t2.id AND t3.type = 'email_password'", "left")
->orderBy('t1.created_at', 'DESC');
return empty($search)
@ -66,7 +73,7 @@ class ActivityModel extends BaseModel
: $builder
->groupStart()
->like("t1.id", $search)
->orLike("t2.username", $search)
->orLike("t3.secret", $search)
->orLike("t1.level", $search)
->orLike("t1.event", $search)
->orLike("t1.ip", $search)

View File

@ -127,7 +127,7 @@ class TarifaEncuadernacionModel extends \App\Models\BaseModel
$builder = $this->db
->table($this->table . " t1")
->select(
"t1.id AS tarifa_enc_id, t1.nombre AS tarifa_enc_nombre, t3.total_min AS tarifa_precio_min, t2.importe_fijo AS tarifa_importe_fijo,
"t1.id AS tarifa_enc_id, t1.nombre AS tarifa_enc_nombre, t3.total_min AS tarifa_precio_min, t2.importe_fijo AS tarifa_importe_fijo, t2.importe_fijo AS importe_fijo,
t2.id AS tarifa_tirada_id, t2.proveedor_id AS proveedor_id, t5.nombre AS proveedor_nombre, t2.tirada_min AS tirada_min, t2.tirada_max AS tirada_max,
t3.id AS tarifa_linea_id, t3.paginas_libro_min AS paginas_min, t3.paginas_libro_max AS paginas_max, t3.precio_min AS precio_min, t3.precio_max AS precio_max, t3.margen AS margen,
t4.ancho_min AS ancho_min, t4.ancho_max AS ancho_max, t4.alto_min AS alto_min, t4.alto_max AS alto_max"
@ -166,7 +166,7 @@ class TarifaEncuadernacionModel extends \App\Models\BaseModel
$builder = $this->db
->table($this->table . " t1")
->select(
"t1.id AS tarifa_enc_id, t1.nombre AS tarifa_enc_nombre, t3.total_min AS tarifa_precio_min, t2.importe_fijo AS tarifa_importe_fijo,
"t1.id AS tarifa_enc_id, t1.nombre AS tarifa_enc_nombre, t3.total_min AS tarifa_precio_min, t2.importe_fijo AS tarifa_importe_fijo, t2.importe_fijo AS importe_fijo,
t2.id AS tarifa_tirada_id, t2.proveedor_id AS proveedor_id, t5.nombre AS proveedor_nombre, t2.tirada_min AS tirada_min, t2.tirada_max AS tirada_max,
t3.id AS tarifa_linea_id, t3.tiempo_min AS tiempo_min, t3.tiempo_max AS tiempo_max, t3.precio_hora AS precio_hora, t3.margen AS margen"
)

View File

@ -13,7 +13,7 @@ class EmailService
// Si no estamos en producción, forzar el destinatario a uno fijo
if ($skEnv !== 'production') {
$recipient = env('MAIL_DEV_RECIPIENT', 'imnavajas@coit.es'); // fallback opcional
$recipient = env('MAIL_DEV_RECIPIENT', 'imnavajas@coit.es,info@jjimenez.eu'); // fallback opcional
}
$settings_model = model('App\Models\Configuracion\ConfigVariableModel');
@ -43,7 +43,13 @@ class EmailService
$email->setSubject($subject);
$email->setMessage($body);
return $email->send();
if (!$email->send()) {
log_message('error', 'Error enviando email: ' . $email->printDebugger(['headers', 'subject', 'body']));
return false;
}
return true;
} catch (\Throwable $e) {
log_message('error', 'EmailService failed: ' . $e->getMessage());
return false;

View File

@ -283,7 +283,6 @@ class EtiquetasTitulosService
array_push($data['grupos'], [
]);
$prefix = 1;
$lineas = array_filter($etiquetas_lineas, function ($linea) use ($caja) {
return $linea->numero_caja == $caja;
});
@ -313,12 +312,12 @@ class EtiquetasTitulosService
$data['grupos'][$index_etiqueta][] = [
'prefix' => $caja,
'prefix' => $lineaCounter+1,
'titulo' => mb_substr($datos_etiqueta->titulo, 0, 40),
'cantidad' => $linea->unidades,
'tirada' => $datos_etiqueta->total_tirada,
'ean' => str_replace('-', '', $datos_etiqueta->isbn),
'npedido' => $datos_etiqueta->id,
'npedido' => $datos_etiqueta->id_pedido,
'refcliente' => $datos_etiqueta->referencia_cliente,
];

View File

@ -96,7 +96,7 @@ class ImpresoraEtiquetaService extends BaseService
// Crear variables específicas del grupo
foreach ($grupo as $libro) {
$prefix = $libro['prefix'];
$prefix = $libro['prefix']==1 ? '' : $libro['prefix'];
$variables = [
"titulo$prefix" => $libro['titulo'],
@ -134,6 +134,87 @@ class ImpresoraEtiquetaService extends BaseService
return $xml->saveXML();
}
public function generateEtiquetasEmbalaje($ot_id, $ejemplares_caja, $printer)
{
$data = [
"printer" => $printer->name,
"header" => [
"_FORMAT" => "E:PEDIDO.ZPL",
"_QUANTITY" => 1,
"_PRINBTERNAME" => $printer->name,
"_JOBNAME" => "LBL101"
],
];
$ot_model = model('App\Models\OrdenTrabajo\OrdenTrabajoModel');
$datos = $ot_model->select('
ordenes_trabajo.total_tirada as unidades,
clientes.nombre as cliente,
presupuestos.titulo as titulo,
presupuestos.isbn as isbn,
presupuestos.referencia_cliente as referencia_cliente,
pedidos.id as pedido
')
->join('pedidos', 'ordenes_trabajo.pedido_id = pedidos.id')
->join('pedidos_linea', 'pedidos.id = pedidos_linea.pedido_id')
->join('presupuestos', 'pedidos_linea.presupuesto_id = presupuestos.id')
->join('clientes', 'presupuestos.cliente_id = clientes.id')
->where('ordenes_trabajo.id', $ot_id)
->first();
$cajas = ceil($datos->unidades / $ejemplares_caja);
$cantidad = 0;
for( $i = 1; $i <= $cajas; $i++) {
$data["labels"][] = [
"cliente" => $datos->cliente,
"titulo" => $datos->titulo,
"cantidad" => $cantidad + $ejemplares_caja <= $datos->unidades ? $ejemplares_caja : $datos->unidades-$cantidad,
"tirada" => $datos->unidades,
"cajas" => $i . '/' . $cajas,
"ean" => str_replace("-", "", $datos->isbn),
"nombre" => null,
"direccion" => null,
"notas" => "",
"refcliente" => $datos->referencia_cliente,
"npedido" => $datos->pedido
];
$cantidad += $ejemplares_caja;
}
$servicioImpresora = new ImpresoraEtiquetaService();
$xml = $servicioImpresora->createEtiqueta($data);
if ($xml == null) {
return [
'status' => false,
'message' => lang('Logistica.errors.noEtiquetas'),
];
}
$sk_environment = getenv('SK_ENVIRONMENT');
if ($sk_environment == 'production') {
$status = $servicioImpresora->sendToImpresoraEtiqueta("ETIQUETA", $xml, $printer);
if ($status) {
return [
'status' => true,
'message' => lang('Logistica.success.imprimirEtiquetas'),
'data' => $xml
];
} else {
return [
'status' => false,
'message' => lang('Logistica.errors.noEtiquetas'),
];
}
} else {
return [
'status' => true,
'message' => lang('Logistica.success.imprimirEtiquetas'),
'data' => $xml
];
}
}
public function sendToImpresoraEtiqueta(string $name, string $content, ImpresoraEtiquetaEntity $impresoraEtiqueta): bool

View File

@ -57,7 +57,8 @@ class LogisticaService
->join('orden_trabajo_dates ot_dates', 'ot_dates.orden_trabajo_id = ot.id')
->whereIn('pr.id', $presupuestoIds)
->whereIn('p.estado', ['finalizado', 'produccion'])
->where('ot_dates.embalaje_at IS NOT NULL')
->where('p.fecha_encuadernado IS NOT NULL')
->where('DATE(p.fecha_encuadernado) <=', date('Y-m-d'))
->where("NOT EXISTS (
SELECT 1
FROM envios_lineas el
@ -78,6 +79,79 @@ class LogisticaService
return $builder;
}
public static function findNextEnvios(int $envio_id)
{
$db = \Config\Database::connect();
// 1. Dirección del envío actual
$envio = $db->table('envios')->select('direccion')->where('id', $envio_id)->get()->getRow();
if (!$envio) {
return $db->table('(SELECT NULL AS id, NULL AS name) AS empty')->where('1 = 0');
}
$direccionNormalizada = str_replace(' ', '', strtolower(trim($envio->direccion)));
$direccionSQL = $db->escape($direccionNormalizada);
// 2. Obtener presupuestos con esa dirección
$presupuestosConEsaDireccion = $db->table('presupuesto_direcciones')
->select('presupuesto_id')
->where("REPLACE(LOWER(TRIM(direccion)), ' ', '') = $direccionSQL", null, false)
->get()
->getResultArray();
$presupuestoIds = array_column($presupuestosConEsaDireccion, 'presupuesto_id');
if (empty($presupuestoIds)) {
return $db->table('(SELECT NULL AS id, NULL AS name) AS empty')->where('1 = 0');
}
$hoy = date('Y-m-d');
$sieteDiasDespues = date('Y-m-d', strtotime('+7 days'));
// 3. Subconsulta principal
$subBuilder = $db->table('pedidos_linea pl')
->select("
ot.id AS ot,
DATE(p.fecha_encuadernado) as fechaEncuadernado,
(
SELECT IFNULL(SUM(el.unidades_envio), 0)
FROM envios_lineas el
JOIN envios e ON e.id = el.envio_id
WHERE el.pedido_id = p.id
AND el.presupuesto_id = pr.id
AND REPLACE(LOWER(TRIM(e.direccion)), ' ', '') = $direccionSQL
AND (e.finalizado = 1 OR e.id = $envio_id)
) AS unidades_enviadas,
pd.cantidad AS cantidad
")
->join('pedidos p', 'p.id = pl.pedido_id')
->join('presupuestos pr', 'pr.id = pl.presupuesto_id')
->join('presupuesto_direcciones pd', 'pd.presupuesto_id = pr.id')
->join('ordenes_trabajo ot', 'ot.pedido_id = p.id')
->join('orden_trabajo_dates ot_dates', 'ot_dates.orden_trabajo_id = ot.id')
->whereIn('pr.id', $presupuestoIds)
->whereIn('p.estado', ['finalizado', 'produccion'])
->where('p.fecha_encuadernado IS NOT NULL')
->where('DATE(p.fecha_encuadernado) >=', $hoy)
->where('DATE(p.fecha_encuadernado) <=', $sieteDiasDespues)
->where("NOT EXISTS (
SELECT 1
FROM envios_lineas el
WHERE el.envio_id = $envio_id
AND el.pedido_id = p.id
AND el.presupuesto_id = pr.id
GROUP BY el.pedido_id, el.presupuesto_id
HAVING SUM(el.unidades_envio) >= pd.cantidad
)", null, false)
->groupBy('pl.id');
// 4. Envolver y filtrar por unidades pendientes
$builder = $db->table("({$subBuilder->getCompiledSelect(false)}) AS sub");
$builder->select('ot, fechaEncuadernado');
$builder->where('cantidad > unidades_enviadas');
return $builder;
}
public static function findForNewEnvio()
{
@ -103,16 +177,15 @@ class LogisticaService
->join('presupuestos pr', 'pr.id = pl.presupuesto_id')
->join('presupuesto_direcciones pd', 'pd.presupuesto_id = pr.id')
->join('ordenes_trabajo ot', 'ot.pedido_id = p.id')
->join('orden_trabajo_dates ot_dates', 'ot_dates.orden_trabajo_id = ot.id')
->whereIn('p.estado', ['finalizado', 'produccion'])
->where('ot_dates.embalaje_at IS NOT NULL')
->where('p.fecha_encuadernado IS NOT NULL')
->where('DATE(p.fecha_encuadernado) <=', date('Y-m-d'))
->groupBy('pl.id');
// 4. Envolver y filtrar por unidades pendientes
$builder = $db->table("({$subBuilder->getCompiledSelect(false)}) AS sub");
$builder->select('id, name');
$builder->where('cantidad > unidades_enviadas');
$builder->orderBy('name', 'ASC');
return $builder;
}
@ -289,6 +362,81 @@ class LogisticaService
}
public static function sendConfirmacionEnvio($envio, $lineaEnvio, $isFerro = false)
{
$view = \Config\Services::renderer();
if ($isFerro)
$subject = '[Safekat]' . " El envio del ferro de su pedido se ha realizado";
else
$subject = '[Safekat]' . " El envio de su pedido se ha realizado";
$presupuestoModel = model('App\Models\Presupuestos\PresupuestoModel');
$presupuesto = $presupuestoModel->find($lineaEnvio->presupuesto_id);
$proveedorModel = model('App\Models\Compras\ProveedorModel');
$proveedor = $proveedorModel->find($envio->proveedor_id);
$userModel = model('App\Models\Usuarios\UserModel');
$datos_correo = $userModel->select("CONCAT(users.first_name, ' ', users.last_name) as comercial_nombre, auth_identities.secret as comercial_correo, clientes.email as cliente_email")
->join('auth_identities', 'auth_identities.user_id = users.id')
->join('clientes', 'clientes.comercial_id = users.id')
->where('clientes.id', $presupuesto->cliente_id)
->first();
$pedido = (object) [
'pedido_id' => $lineaEnvio->pedido_id,
'titulo' => $presupuesto->titulo,
'cp' => $envio->cp,
'proveedor_nombre' => $proveedor->nombre,
'codigo_seguimiento' => $envio->codigo_seguimiento,
'comercial_nombre' => $datos_correo->comercial_nombre,
'comercial_correo' => $datos_correo->comercial_correo,
];
if ($proveedor->nombre == "GLS") {
$pedido->url = 'https://m.asmred.com/e/' . $envio->codigo_seguimiento . '/' . $envio->cp;
}
$content = $view->setVar('datos_pedido', $pedido)
->render('themes/vuexy/mail/envio_pedido');
// Renderiza la plantilla completa
if ($isFerro)
$finalBody = $view->setVar('emailTitle2', "El ferro de su pedido " . $lineaEnvio->pedido_id . " ha sido enviado el " . date('d/m/Y'))
->setVar('content', $content)
->render('themes/vuexy/mail/mail_layout_2');
else
$finalBody = $view->setVar('emailTitle2', "Su pedido " . $lineaEnvio->pedido_id . " ha sido enviado el " . date('d/m/Y'))
->setVar('content', $content)
->render('themes/vuexy/mail/mail_layout_2');
$email = service('emailService');
$result = $email->send($subject, $finalBody, $datos_correo->cliente_email);
$chat = Service('chat');
$data = [
'chat_department_id' => 5,
'client' => $presupuesto->cliente_id,
'message' => "El pedido " . $lineaEnvio->pedido_id . " ha sido enviado el " . date('d/m/Y') . ".<br><br>" .
"CP:" . $envio->cp . ".<br>" .
"Proveedor envío: " . $proveedor->nombre . ".<br>" .
"Código de seguimiento: " . $envio->codigo_seguimiento . ".<br>"
];
if ($proveedor->nombre == "GLS") {
$data['message'] = $data['message'] . 'URL segumiento: <a style="color:white;" target="_blank" href="' . 'https://m.asmred.com/e/' . $envio->codigo_seguimiento . '/' . $envio->cp . ' ">' .
'https://m.asmred.com/e/' . $envio->codigo_seguimiento . '/' . $envio->cp . '</a>';
}
$chat->storeChatMessage(5, "pedido", $lineaEnvio->pedido_id, $data);
return [
'status' => $result,
'message' => $result ? lang('Logistica.success.emailSent') : lang('Logistica.errors.emailNotSent'),
];
}
public static function generateEnvio($ot_id, $direccion = null)
{
@ -533,16 +681,29 @@ class LogisticaService
"name" => "ferro_en_cliente_at",
"ferro_en_cliente_at" => date('Y-m-d H:i:s')
]);
LogisticaService::sendConfirmacionEnvio($envio, $linea, true);
} else {
if ($cantidad_enviada + $linea->unidades_envio == $pedido->total_tirada) {
if ($cantidad_enviada + $linea->unidades_envio >= $pedido->total_tirada) {
$otModel = model('App\Models\OrdenTrabajo\OrdenTrabajoModel');
$ot = $otModel->where('pedido_id', $linea->pedido_id)
->first();
$ps = (new ProductionService())->init($ot->id);
$date = $ps->getOrdenTrabajo()->dates()->embalaje_at;
if (is_null($date) || empty($date)) {
$ps->updateOrdenTrabajoDate([
"name" => "embalaje_at",
"embalaje_at" => date('Y-m-d H:i:s')
]);
}
$ps->updateOrdenTrabajoDate([
"name" => "envio_at",
"envio_at" => date('Y-m-d H:i:s')
]);
LogisticaService::sendConfirmacionEnvio($envio, $linea);
if ($finalizar_ot) {
$ps->updateOrdenTrabajo(
[
@ -572,6 +733,29 @@ class LogisticaService
return $data_return;
}
public static function ficharEmbalaje($ids = null)
{
if (is_null($ids) || empty($ids) || count($ids) == 0) {
return [
'status' => false,
'message' => lang('Logistica.errors.noLineas'),
];
}
for ($index = 0; $index < count($ids); $index++) {
$ps = (new ProductionService())->init($ids[$index]);
$ps->updateOrdenTrabajoDate([
"name" => "embalaje_at",
"embalaje_at" => date('Y-m-d')
]);
}
return [
'status' => true,
'message' => lang('Logistica.success.successFicharEmbalaje'),
];
}
public static function generateEtiquetasTitulos($envio, $lineas, $printer, $cajas)
{
$data = [

View File

@ -13,11 +13,15 @@ class PresupuestoClienteService extends BaseService
{
public static function obtenerInterior($data)
{
$POD = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('POD')->value;
$tirada = $data['datosPedido']->tirada;
$isPoD = $POD >= $tirada;
$rotativa = [];
$plana = [];
// no se busca en plana cuando es estándar (no Premium)
if ($data['isHq'])
// no se busca en plana cuando es estándar (no Premium) excepto cuando es PoD
if ($data['isHq'] || $isPoD)
$plana = PresupuestoClienteService::obtenerPresupuestoClienteInterior($data);
if (!$data['excluirRotativa'] && !$data['isHq'])
$rotativa = PresupuestoClienteService::obtenerPresupuestoClienteInteriorRotativa($data);

View File

@ -253,7 +253,8 @@ class PresupuestoService extends BaseService
$linea['fields']['precio_libro'] = $linea['fields']['pliegos_libro'] * $linea['fields']['precios_pliegos'];
// Precio papel pedido
$linea['fields']['precio_pedido'] = $linea['fields']['precio_libro'] * ($datosPedido->tirada + $datosPedido->merma);
$linea['fields']['margen_papel_pedido'] = $linea['fields']['pliegos_libro'] * $margen_pliego_impresion * ($datosPedido->tirada + $datosPedido->merma);;
$linea['fields']['margen_papel_pedido'] = $linea['fields']['pliegos_libro'] * $margen_pliego_impresion * ($datosPedido->tirada + $datosPedido->merma);
;
$linea['fields']['a_favor_fibra'] = $parametrosRotativa->a_favor_fibra;
$linea['fields']['maquina'] = $maquina->maquina;
@ -614,9 +615,9 @@ class PresupuestoService extends BaseService
// precio tinta
$data['precio_tinta'] = round(
round(($data['peso_gotas_negro_pedido'] / 1000.0) * $maquina->precio_tinta_negro, 2) +
round(($data['peso_gotas_cyan_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) +
round(($data['peso_gotas_magenta_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) +
round(($data['peso_gotas_amarillo_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2),
round(($data['peso_gotas_cyan_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) +
round(($data['peso_gotas_magenta_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2) +
round(($data['peso_gotas_amarillo_pedido'] / 1000.0) * $maquina->precio_tinta_color, 2),
2
);
@ -1785,6 +1786,8 @@ class PresupuestoService extends BaseService
options: $opciones_papel
);
#$query = model("App\Models\Configuracion\PapelImpresionModel")->db->getLastQuery();
$lineas = array();
// Para cada papel, se obtienen las maquinas disponibles
foreach ($papeles as $papel) {
@ -1798,6 +1801,8 @@ class PresupuestoService extends BaseService
papel_impresion_id: $papel->id,
)->orderBy("t1.id", "asc")->get()->getResultObject();
$query = model("App\Models\Configuracion\PapelImpresionModel")->db->getLastQuery();
// Se recorren las máquinas y se calcula el coste de linea por cada una
foreach ($maquinas as $maquina) {
@ -1863,7 +1868,7 @@ class PresupuestoService extends BaseService
public static function crearPedido($presupuesto_id)
public static function crearPedido($presupuesto_id, ?bool $isImported = false)
{
$model_pedido = model('App\Models\Pedidos\PedidoModel');
$model_pedido_linea = model('App\Models\Pedidos\PedidoLineaModel');
@ -1895,7 +1900,7 @@ class PresupuestoService extends BaseService
"user_updated_id" => auth()->user()->id,
];
$id_linea = $model_pedido_linea->insert($data_pedido_linea);
PedidoXMLService::generate_xml($pedido_id);
//PedidoXMLService::generate_xml($pedido_id);
}
if ($id_linea != 0 && $pedido_id != 0) {
@ -1907,8 +1912,25 @@ class PresupuestoService extends BaseService
$serviceProduction->setPedido($pedido);
if (!$pedido->orden_trabajo()) {
$r = $serviceProduction->createOrdenTrabajo(true);
$r = $serviceProduction->createOrdenTrabajo($isImported);
$modelPedido->set(['estado' => 'produccion'])->where('id', $pedido_id)->update();
$clienteModel = model('App\Models\Clientes\ClienteModel');
$cliente = $clienteModel->find($datos_presupuesto->cliente_id);
$clienteModel = model('App\Models\Clientes\ClienteModel');
if ($cliente) {
if ($cliente->tirada_flexible == 1) {
$ejemplares_tirada_flexible = intval($datos_presupuesto->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 true;
@ -2055,7 +2077,10 @@ class PresupuestoService extends BaseService
$merma = 0;
if ($tirada > $POD) {
if ($tirada == 0) {
$merma = 0;
}
else if ($tirada > $POD) {
$merma = $tirada * 0.1;
} else {
$merma_lineas = [];
@ -2072,4 +2097,114 @@ class PresupuestoService extends BaseService
return round($merma, 0);
}
public static function getCalidad($alias, $cliente_id, $isColor, $isHq, $tirada)
{
$model = model('App\Models\Configuracion\SelectorCalidadImpresionModel');
$calidad = $model->getCalidadImpresion($alias, $cliente_id, $isColor, $isHq, $tirada);
if ($calidad) {
return [$calidad['isColor'], $calidad['isHq']];
}
return null;
}
public static function duplicarPresupuesto($id = null, $is_reimpresion = false, $copy_files = false)
{
try {
$modelPresupuesto = model('App\Models\Presupuestos\PresupuestoModel');
$presupuesto = $modelPresupuesto->find($id);
if (!$presupuesto || $id == null) {
return [
'success' => false,
'message' => lang('Presupuestos.presupuestoNotFound'),
];
}
$presupuesto->titulo = $presupuesto->titulo . ' - ' . lang('Presupuestos.duplicado');
$presupuesto->is_duplicado = 1;
$presupuesto->estado_id = 1;
if($is_reimpresion && boolval($copy_files)){
$presupuesto->inc_rei = "reimpresion";
$modelPedidoLinea = model('App\Models\Pedidos\PedidoLineaModel');
$pedido_linea = $modelPedidoLinea->where('presupuesto_id', $id)->first();
if($pedido_linea){
$text = "REIMPRESION [" . date('Y-m-d H:i:s') . "] - PEDIDO: " . $pedido_linea->pedido_id .
"\n================================================\n";
$presupuesto->comentarios_safekat = $text . $presupuesto->comentarios_safekat ;
}
}
else if($is_reimpresion){
$presupuesto->inc_rei = null;
$modelPedidoLinea = model('App\Models\Pedidos\PedidoLineaModel');
$pedido_linea = $modelPedidoLinea->where('presupuesto_id', $id)->first();
if($pedido_linea){
$text = "DUPLICADO [" . date('Y-m-d H:i:s') . "] - PEDIDO: " . $pedido_linea->pedido_id .
"\n================================================\n";
$presupuesto->comentarios_safekat = $text . $presupuesto->comentarios_safekat;
}
}
else{
$presupuesto->inc_rei = null;
}
$new_id = $modelPresupuesto->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);
if (boolval($copy_files)== true) {
$presupuestoFilesModel = model('App\Models\Presupuestos\PresupuestoFicheroModel');
$presupuestoFilesModel->copyFiles($presupuesto->id, $new_id);
}
return [
'success' => true,
'id' => $new_id,
'message' => lang('Presupuestos.presupuestoGenerado'),
];
} catch (\Exception $e) {
return [
'success' => false,
'message' => $e->getMessage()
];
}
}
}

View File

@ -84,6 +84,12 @@ class ProductionService extends BaseService
* @var string
*/
public string $statusColor;
public int $guillotinaMaquinaId;
public int $hunkelerMaquinaId;
public int $tecnauMaquinaId;
public int $trimmingMaquinaId;
public int $guillotinaPreparacionInteriorMaquinaId;
/**
* Valor límite del POD
*
@ -182,6 +188,14 @@ class ProductionService extends BaseService
* @var boolean
*/
public bool $isCorte = false; //* CHECK DONE
/**
* Indica si hay una tarea de preparacion interior de guillotina ya se cubierta o interior
* Se usa para mostrar la fecha correspondiente en la vista
*
* @var boolean
*/
public bool $isPrepInteriorGuillotina = false; //* CHECK DONE
/**
* Pedido Entity
*
@ -198,6 +212,7 @@ class ProductionService extends BaseService
public function __construct()
{
$this->otModel = model(OrdenTrabajoModel::class);
$this->maquinaModel = model(MaquinaModel::class);
$this->otDate = model(OrdenTrabajoDate::class);
$this->otTarea = model(OrdenTrabajoTarea::class);
$this->otUser = model(OrdenTrabajoUser::class);
@ -212,6 +227,12 @@ class ProductionService extends BaseService
$this->statusColor = $this->ordenTrabajoConfig->OT_COLORS["sin_imprimir"];
$this->configVariableModel = model(ConfigVariableModel::class);
$this->podValue = $this->configVariableModel->getVariable('POD')->value;
$this->guillotinaMaquinaId = $this->configVariableModel->getVariable('maquina_guillotina_id_default')->value;
$this->hunkelerMaquinaId = $this->configVariableModel->getVariable('maquina_hunkeler_id')->value;
$this->tecnauMaquinaId = $this->configVariableModel->getVariable('maquina_tecnau_id')->value;
$this->trimmingMaquinaId = $this->configVariableModel->getVariable('maquina_trimming_id')->value;
$this->guillotinaPreparacionInteriorMaquinaId = $this->configVariableModel->getVariable('maquina_guillotina_prep_id_default')->value;
$this->OT_TAREA_STATUS_TITLE = [
"P" => lang('Produccion.tarea_estados.P'),
"F" => lang('Produccion.tarea_estados.F'),
@ -225,11 +246,9 @@ class ProductionService extends BaseService
public function init(int $orden_trabajo_id): self
{
try {
$this->maquinaModel = model(MaquinaModel::class);
$this->otModel = model(OrdenTrabajoModel::class);
$ot = $this->otModel->find($orden_trabajo_id);
if($ot == null){
throw new Exception(lang('Produccion.errors.ot_not_found',['ot_id' => $orden_trabajo_id]));
if ($ot == null) {
throw new Exception(lang('Produccion.errors.ot_not_found', ['ot_id' => $orden_trabajo_id]));
}
$this->ot = $ot;
$pedido = $this->ot->pedido();
@ -368,6 +387,8 @@ class ProductionService extends BaseService
$this->storeOrdenTrabajoManipuladoTareas();
// $this->storeOrdenTrabajoPreimpresionTareas();
$this->storeOrdenTrabajoEncuadernacionTareas();
$this->storeTareaCorteFinal();
// $this->storeOrdenTrabajoExtraTareas();
}
/**
@ -408,10 +429,37 @@ class ProductionService extends BaseService
$ot_tareas["tiempo_real"] = 0;
$insert_query_result = $this->otTarea->insert($ot_tareas);
$ot_tareas = [];
$this->storeTareaCorteBloque($p_linea);
$this->storeTareaCorte($p_linea);
}
return $insert_query_result;
}
/**
* Inserta una tarea de corte si la impresion es en `rotativa`
*
* @return OrdenTrabajoTareaEntity|null
*/
protected function storeTareaCorteFinal(): ?OrdenTrabajoTareaEntity
{
$maquina_id = $this->presupuesto->solapas == 1 ? $this->trimmingMaquinaId : $this->defaultMaquinaCorte->id;
$presupuestoLineaImpresion = $this->presupuesto->presupuestoLineaImpresion();
$maquinaCorteEntity = $this->maquinaModel->find($maquina_id);
$data = [
'orden_trabajo_id' => $this->ot->id,
'presupuesto_linea_id' => $presupuestoLineaImpresion->id,
'nombre' => lang('Produccion.end_cut'),
'maquina_id' => $maquina_id,
'orden' => $maquinaCorteEntity->orden_planning,
'tiempo_estimado' => $this->tiempoCorteFinalEstimado($maquinaCorteEntity),
'tiempo_real' => 0,
'is_corte' => true,
'tipo_corte' => "bobina",
];
$tareaId = $this->otTarea->insert($data);
$otCorte = $this->otTarea->find($tareaId);
return $otCorte;
}
/**
* Inserta una tarea de corte si la impresion es en `rotativa`
*
@ -421,23 +469,70 @@ class ProductionService extends BaseService
protected function storeTareaCorte(PresupuestoLineaEntity $pLinea): ?OrdenTrabajoTareaEntity
{
$otCorte = null;
$presupuestoTipo = $this->presupuesto->tipo_presupuesto()->codigo;
$isRusticaFresado = str_contains($presupuestoTipo, "Fresado");
$maquinaCorteEntity = $this->maquinaModel->find($this->guillotinaPreparacionInteriorMaquinaId);
$data = [
'orden_trabajo_id' => $this->ot->id,
'presupuesto_linea_id' => $pLinea->id,
'nombre' => 'Corte',
'maquina_id' => $this->guillotinaPreparacionInteriorMaquinaId,
'orden' => $this->maquinaModel->find($this->guillotinaPreparacionInteriorMaquinaId)->orden_planning,
'tiempo_estimado' => $pLinea->rotativa_tiempo_corte * 60,
'tiempo_real' => 0,
'is_corte' => true,
'tipo_corte' => "prep",
];
if ($pLinea->isCubierta()) {
$data['nombre'] = lang('Produccion.cover_cut');
$data['tiempo_estimado'] = $this->tiempoCortePrepInterior($maquinaCorteEntity);
$tareaId = $this->otTarea->insert($data);
$otCorte = $this->otTarea->find($tareaId);
}
if ($pLinea->isImpresionInteriorPlana() || $pLinea->isRotativa()) {
if ($pLinea->isImpresionInteriorPlana()) {
$data['tiempo_estimado'] = $this->tiempoCortePrepInterior($maquinaCorteEntity);
}
$data['nombre'] = lang('Produccion.interior_cut');
//* Si es rustica fresado y rotativa no se añade preparación de interior en guillotina
if (!$isRusticaFresado && !$pLinea->isRotativa()) {
$tareaId = $this->otTarea->insert($data);
$otCorte = $this->otTarea->find($tareaId);
return $otCorte;
}
}
return $otCorte;
}
/**
* Inserta una tarea de corte a bloque
* Se añade después de una tarea de impresión interior en rotativa.
*
*
* @param PresupuestoLineaEntity $pLinea
* @return OrdenTrabajoTareaEntity|null
*/
protected function storeTareaCorteBloque(PresupuestoLineaEntity $pLinea)
{
$otCorte = null;
$name = $this->cosido() ? lang('Produccion.hunkeler') : lang('Produccion.tecnau');
$maquina_id = $this->cosido() ? $this->hunkelerMaquinaId : $this->tecnauMaquinaId;
if ($pLinea->isRotativa()) {
$tareaId = $this->otTarea->insert([
'orden_trabajo_id' => $this->ot->id,
'presupuesto_linea_id' => $pLinea->id,
'nombre' => 'Corte',
'maquina_id' => $this->defaultMaquinaCorte->id,
'orden' => $this->defaultMaquinaCorte->orden_planning,
'nombre' => $name,
'maquina_id' => $maquina_id,
'orden' => $this->maquinaModel->find($maquina_id)->orden_planning,
'tiempo_estimado' => $pLinea->rotativa_tiempo_corte * 60,
'tiempo_real' => 0,
'is_corte' => true,
'tipo_corte' => "bobina",
'tipo_corte' => "bloque",
]);
$otCorte = $this->otTarea->find($tareaId);
}
return $otCorte;
}
/**
* General las tareas de acabado segun las líneas de presupuesto_acabados
*
@ -610,17 +705,21 @@ class ProductionService extends BaseService
}
return ["tareas" => $tareas];
}
public function getTareasWithMaquina(int $maquina_id,?array $tareaEstados = null) : ?array
public function getTareasWithMaquina(int $maquina_id, ?array $tareaEstados = null): ?array
{
return $this->otModel->queryMaquinaTareas($maquina_id, $tareaEstados)
->where('ordenes_trabajo.id', $this->ot->id)
->get()->getResult(OrdenTrabajoTareaEntity::class);
->where('ordenes_trabajo.id', $this->ot->id)
->get()->getResult(OrdenTrabajoTareaEntity::class);
}
public function getPdf()
{
return view("themes/vuexy/pdfs/orden_trabajo", $this->getDataPdf());
}
public function getPdfContent()
{
return view("themes/vuexy/pdfs/orden_trabajo_view", $this->getDataPdf());
}
public function getFerroPdf()
{
return view("themes/vuexy/pdfs/ferro", $this->getDataPdf());
@ -702,6 +801,7 @@ class ProductionService extends BaseService
->join("lg_imposiciones", "lg_imposiciones.id = orden_trabajo_tareas.imposicion_id", "left")
->whereIn("presupuesto_linea.tipo", $this->TIPOS_ROTATIVA)
->where('lg_maquinas.is_rotativa', true)
->where('lg_maquinas.tipo', 'impresion')
->where("orden_trabajo_tareas.deleted_at", null)
->orderBy("orden_trabajo_tareas.orden", "ASC")
->groupBy('ordenes_trabajo.id');
@ -744,6 +844,7 @@ class ProductionService extends BaseService
// ->where("orden_trabajo_tareas.orden_trabajo_id", $this->ot->id)
->whereIn("presupuesto_linea.tipo", $this->TIPOS_PLANA)
->where('lg_maquinas.is_rotativa', false)
->where('lg_maquinas.tipo', 'impresion')
->where("orden_trabajo_tareas.deleted_at", null)
->orderBy("orden_trabajo_tareas.orden", "ASC")
->groupBy('ordenes_trabajo.id');
@ -838,6 +939,31 @@ class ProductionService extends BaseService
return $q;
}
public function maquinaPlanaDatatableQuery()
{
$q = $this->otModel->builder()->select([
"lg_maquinas.nombre as maquinaNombre",
"lg_maquinas.id as maquinaId",
"COUNT(orden_trabajo_tareas.id) as tareasCount",
"presupuesto_linea.pliegos_pedido as pliegosPedido",
"SUM(ordenes_trabajo.total_tirada) as totalTirada",
"SUM(orden_trabajo_tareas.tiempo_real) as tiempoReal"
])
->join("orden_trabajo_tareas", "orden_trabajo_tareas.orden_trabajo_id = ordenes_trabajo.id", "left")
->join("presupuesto_linea", "presupuesto_linea.id = orden_trabajo_tareas.presupuesto_linea_id", "left")
->join("presupuestos", "presupuestos.id = presupuesto_linea.presupuesto_id", "right")
->join('lg_maquinas', "lg_maquinas.id = orden_trabajo_tareas.maquina_id", "left")
->where("orden_trabajo_tareas.deleted_at", null)
->where("orden_trabajo_tareas.presupuesto_linea_id IS NOT NULL", NULL, FALSE)
->whereIn("presupuesto_linea.tipo", $this->TIPOS_PLANA)
->where('lg_maquinas.tipo', 'impresion')
// ->where('lg_maquinas.padre_id', 0)
->groupBy('lg_maquinas.id');
return $q;
}
/**
@ -873,7 +999,7 @@ class ProductionService extends BaseService
"tareas_encuadernacion" => $this->tareas_encuadernacion(),
"tareas_preimpresion" => $this->tareas_preimpresion(),
"tareas_impresion" => $this->tareas_impresion(),
"tiempo_procesamiento" => $this->getTiempoProcesamientoHHMM(),
"tiempo_procesamiento" => $this->getTiempoProcesamientoHHMMSS(),
"tiempo_total" => $this->getTiempoTotalTareas(),
"statusColor" => $this->getOtColorStatus(),
"tareaCosido" => $this->getTareaCosido(),
@ -902,8 +1028,8 @@ class ProductionService extends BaseService
"peso_unidad" => $logistica_data["peso_unidad"],
"peso_pedido" => $logistica_data["peso_pedido"],
"imposicion" => $this->getImposicionTareaImpresion(),
"tiempo_procesamiento" => $this->getTiempoProcesamientoHHMM(),
"tiempo_impresion" => $this->getTiempoTareasImpresionHHMM(),
"tiempo_procesamiento" => $this->getTiempoProcesamientoHHMMSS(),
"tiempo_impresion" => $this->getTiempoTareasImpresionHHMMSS(),
"colors" => $this->getPdfColors(),
"isPOD" => $this->isPOD,
"uvi" => $this->getUVI(),
@ -1082,6 +1208,16 @@ class ProductionService extends BaseService
$this->updateProgress();
return $result;
}
public function updateOrdenTrabajoData($data)
{
$result = $this->otModel->where('id', $this->ot->id)
->set($data['name'], $data[$data['name']])
->update();
return $result;
}
public function emptyOrdenTrabajoDate(int $orden_trabajo_id, string $dateName)
{
$status = $this->otDate->where('orden_trabajo_id', $orden_trabajo_id)
@ -1238,13 +1374,14 @@ class ProductionService extends BaseService
->whereIn("presupuesto_linea.tipo", $this->TIPOS_ROTATIVA)
->where('lg_maquinas.is_rotativa', true)
->where("orden_trabajo_tareas.deleted_at", null)
->orderBy("orden_trabajo_tareas.orden", "ASC");
->orderBy("orden_trabajo_tareas.orden", "ASC")
->groupBy('lg_maquinas.id');
if ($q) {
$query->like('lg_maquinas.nombre', $q);
}
return $query->get()->getResultArray();
}
public function querySelectMaquinaPlanningPlana($q)
public function querySelectMaquinaPlanningPlana($q, ?string $padreId)
{
$query = $this->otModel->builder()->select([
"orden_trabajo_tareas.maquina_id as id",
@ -1256,10 +1393,14 @@ class ProductionService extends BaseService
->whereIn("presupuesto_linea.tipo", $this->TIPOS_PLANA)
->where('lg_maquinas.is_rotativa', false)
->where("orden_trabajo_tareas.deleted_at", null)
->orderBy("orden_trabajo_tareas.orden", "ASC");
->orderBy("orden_trabajo_tareas.orden", "ASC")
->groupBy('lg_maquinas.id');
if ($q) {
$query->like('lg_maquinas.nombre', $q);
}
if ($padreId) {
$query->where('lg_maquinas.padre_id', $padreId);
}
return $query->get()->getResultArray();
}
public function querySelectMaquinaPadrePlanningPlana($q)
@ -1272,10 +1413,8 @@ class ProductionService extends BaseService
->join("presupuesto_linea", "presupuesto_linea.id = orden_trabajo_tareas.presupuesto_linea_id", "left")
->join("lg_maquinas", "lg_maquinas.id = orden_trabajo_tareas.maquina_id", "left")
->join("lg_maquinas mp", "mp.id = lg_maquinas.padre_id", "left")
->whereIn("presupuesto_linea.tipo", $this->TIPOS_PLANA)
->where('lg_maquinas.is_rotativa', false)
->where('mp.is_padre', 0)
->where("orden_trabajo_tareas.deleted_at", null)
->where('lg_maquinas.is_padre !=', 0)
->groupBy("mp.id");
if ($q) {
$query->like('lg_maquinas.nombre', $q);
@ -1302,7 +1441,7 @@ class ProductionService extends BaseService
}
return $query->get()->getResultArray();
}
public function querySelectPapelPlanningPlana($q)
public function querySelectPapelPlanningPlana($q, ?string $maquinaId)
{
$query = $this->otModel->builder()->select([
"lg_papel_impresion.id",
@ -1320,12 +1459,15 @@ class ProductionService extends BaseService
if ($q) {
$query->like('lg_papel_impresion.nombre', $q);
}
if ($maquinaId) {
$query->where('orden_trabajo_tareas.maquina_id', $maquinaId);
}
return $query->get()->getResultArray();
}
public function tareaUpdateMaquinaCorte($orden_trabajo_id): bool
{
$cvm = model(ConfigVariableModel::class);
$otTarea = $this->otTarea->where('orden_trabajo_id', $orden_trabajo_id)->where('is_corte', true)->first();
$otTarea = $this->otTarea->where('orden_trabajo_id', $orden_trabajo_id)->where('is_corte', true)->whereIn('tipo_corte', ['bobina', 'guillotina'])->first();
$toggleCorte = "bobina";
if ($otTarea->tipo_corte == "bobina") {
$maquina_id = $cvm->where('name', "id_maquina_guillotina_corte_ot_tarea")->first()["value"];
@ -1435,17 +1577,27 @@ class ProductionService extends BaseService
}
return $pedidoUserDates;
}
public function getTiempoProcesamientoHHMM(): ?string
public function getTiempoEstimadoTotalTareasSeconds(): int
{
try {
$time_tareas_seconds = array_map(fn($q) => $q->tiempo_estimado ?? 0, $this->ot->tareas());
$seconds = array_sum($time_tareas_seconds);
return float_seconds_to_hhmm_string($seconds);
return $seconds;
} catch (\Throwable $th) {
return '00:00';
return 0;
}
}
public function getTiempoTareasImpresionHHMM(): string
public function getTiempoProcesamientoHHMMSS(): ?string
{
try {
$time_tareas_seconds = array_map(fn($q) => $q->tiempo_estimado ?? 0, $this->ot->tareas());
$seconds = array_sum($time_tareas_seconds);
return float_seconds_to_hhmmss_string($seconds);
} catch (\Throwable $th) {
return '00:00:00';
}
}
public function getTiempoTareasImpresionHHMMSS(): string
{
try {
$tareas_impresion = $this->ot->tareas_impresion();
@ -1455,7 +1607,7 @@ class ProductionService extends BaseService
$tiempo_seconds += $tarea->tiempo_estimado;
}
}
return float_seconds_to_hhmm_string($tiempo_seconds);
return float_seconds_to_hhmmss_string($tiempo_seconds);
} catch (\Throwable $th) {
return '00:00';
}
@ -1486,33 +1638,36 @@ class ProductionService extends BaseService
}
return $uvi;
}
//TODO ACTUALIZAR
public function updateProgress(): bool
{
$userDates = $this->ordenTrabajoConfig->DATE_USER_MAPPING;
$pedidoUserDates = $this->ordenTrabajoConfig->DATE_USER_MAPPING_PEDIDO;
$fill_dates = 0;
$status = false;
$total = count($userDates) + count($pedidoUserDates);
$progress = $this->getOtProgress();
if ($this->ot->estado != "F") {
if ($this->ot->dates()) {
foreach ($userDates as $key => $value) {
if ($this->ot->dates()->{$key} != null) $fill_dates++;
}
foreach ($pedidoUserDates as $key => $value) {
if ($this->pedido->{$key} != null) $fill_dates++;
}
$progreso = (float) $fill_dates / $total * 100;
$status = $this->otModel->update($this->ot->id, ["progreso" => round($progreso, 2)]);
}
$status = $this->otModel->update($this->ot->id, ["progreso" => round($progress, 2)]);
} else {
$status = $this->otModel->update($this->ot->id, ["progreso" => 100]);
}
return $status;
}
public function getOtProgress()
{
$datesWithTime = $this->getOrdenTrabajoTareaDatesWithTiempoEstimado();
$tiempo_estimado_total = $this->getTiempoEstimadoTotalTareasSeconds();
$progress = 0;
$otDates = $this->ot->dates();
foreach ($datesWithTime as $key => $dateWithTime) {
["date" => $date, "tiempo_estimado" => $tiempo_estimado] = $dateWithTime;
try {
if ($otDates->{$date}) {
$progress += $tiempo_estimado / $tiempo_estimado_total * 100;
}
} catch (\Throwable $th) {
//throw $th;
$progress += 0;
}
}
return $progress;
}
public function getOtColorStatus(): string
{
if ($this->ot->dates()) {
@ -1642,22 +1797,22 @@ class ProductionService extends BaseService
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['default'];
$papel_code = $papel->code_ot;
if ($papel_code) {
if (strpos($papel_code, "BCLOF")) {
if (str_contains($papel_code, "BCLOF")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['blanco'];
}
if (strpos($papel_code, "AH") && $papel->code == "OFF2") {
if (str_contains($papel_code, "AH")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['ahuesado'];
}
if (strpos($papel_code, "MARF")) {
if (str_contains($papel_code, "MARF")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['marfil'];
}
if (strpos($papel_code, "VOLAH")) {
if (str_contains($papel_code, "VOLAH")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['volumen_ahuesado'];
}
if ($papel_code == "EM") {
if (str_contains($papel_code, "EM")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['estucado_mate'];
}
if ($papel_code == "CGE") {
if (str_contains($papel->nombre, "CARTULINA")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['cartulina'];
}
}
@ -1675,22 +1830,22 @@ class ProductionService extends BaseService
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['default'];
$papel_code = $papel->code_ot;
if ($papel_code) {
if (strpos($papel_code, "BCLOF")) {
if (str_contains($papel_code, "BCLOF")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['blanco'];
}
if (strpos($papel_code, "AH") && $papel->code == "OFF2") {
if (str_contains($papel_code, "AH")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['ahuesado'];
}
if (strpos($papel_code, "MARF")) {
if (str_contains($papel_code, "MARF")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['marfil'];
}
if (strpos($papel_code, "VOLAH")) {
if (str_contains($papel_code, "VOLAH")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['volumen_ahuesado'];
}
if ($papel_code == "EM") {
if (str_contains($papel_code, "EM")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['estucado_mate'];
}
if ($papel_code == "CGE") {
if (str_contains($papel->nombre, "CARTULINA")) {
$color = $this->ordenTrabajoConfig->OT_PAPEL_COLOR['cartulina'];
}
}
@ -1752,6 +1907,7 @@ class ProductionService extends BaseService
"isColor" => $this->isColor,
"isBN" => $this->isBN,
"isCorte" => $this->corte(),
"isPrepInteriorGuillotina" => $this->hasPrepInteriorGuillotina(),
"isGrapado" => $this->isGrapado,
"isCosido" => $this->cosido(),
];
@ -1845,10 +2001,10 @@ class ProductionService extends BaseService
public function cosido(): bool
{
$flag = false;
$manipulados = $this->presupuesto->manipulados();
foreach ($manipulados as $key => $manipulado) {
$tarifa_manipulado = $manipulado->tarifa();
if ($tarifa_manipulado->isCosido()) {
$encuadernaciones = $this->presupuesto->encuadernaciones();
foreach ($encuadernaciones as $key => $encuadernacion) {
$tarifaEncuadernacionEntity = $encuadernacion->tarifa();
if ($tarifaEncuadernacionEntity->isCosido()) {
$flag = true;
break;
}
@ -1917,6 +2073,17 @@ class ProductionService extends BaseService
}
return $this->isCorte;
}
public function hasPrepInteriorGuillotina(): bool
{
$ot_tareas = $this->ot->tareas();
foreach ($ot_tareas as $key => $tarea) {
if ($tarea->is_corte && $tarea->tipo_corte = "prep") {
$this->isPrepInteriorGuillotina = true;
break;
}
}
return $this->isPrepInteriorGuillotina;
}
public function getFileBarCode()
{
return $this->ot->getBarCodeFile();
@ -2190,6 +2357,15 @@ class ProductionService extends BaseService
}
return $data;
}
public function getOrdenTrabajoTareaDatesWithTiempoEstimado(): array
{
$dates = [];
foreach ($this->ot->tareas() as $key => $tarea) {
$dates[$tarea->id]["date"] = $this->getOrdenTrabajoTareaDate($tarea);
$dates[$tarea->id]["tiempo_estimado"] = $tarea->tiempo_estimado;
}
return $dates;
}
public function getOrdenTrabajoTareaDates(): array
{
$dates = [];
@ -2213,6 +2389,12 @@ class ProductionService extends BaseService
if ($tarea->isEncuadernado()) {
$dateName = "encuadernacion_at";
}
if ($tarea->is_corte) {
$dateName = "corte_at";
}
if ($tarea->is_corte && $tarea->tipo_corte == "prep") {
$dateName = "preparacion_interiores_at";
}
return $dateName;
}
public function getTitleTareaEstado($tarea_id): array
@ -2234,4 +2416,38 @@ class ProductionService extends BaseService
"userName" => $userName ?? "",
];
}
/**
* Devuelve en segundos el tiempo que tarda una máquina de corte en realizar el corte de la tirada completa
*
* $t = tirada[libros] / velocidad_maquina[libros/minutos]$
*
* @param MaquinaEntity $maquina
* @return float $seconds
*/
public function tiempoCorteFinalEstimado(MaquinaEntity $maquina): float
{
$seconds = 0;
if ($this->presupuesto->tirada > 0) {
$minutos = $this->presupuesto->tirada / $maquina->velocidad;
$seconds = $minutos * 60;
}
return $seconds;
}
/**
* Devuelve en segundos el tiempo que tarda una máquina de corte en realizar
*
* $t = tirada[libros] / velocidad_maquina[libros/minutos]$
*
* @param MaquinaEntity $maquina
* @return float $seconds
*/
public function tiempoCortePrepInterior(MaquinaEntity $maquina)
{
$seconds = 0;
if ($this->presupuesto->tirada > 0) {
$minutos = $this->presupuesto->tirada / $maquina->velocidad;
$seconds = $minutos * 60;
}
return $seconds;
}
}

View File

@ -11,7 +11,7 @@
<div class="col-md-6">
<div class="mt-lg-4 mt-lg-2 mb-lg-4 mb-2 pt-1 w-100">
<p class="mb-0">OT ID</p>
<h4 class="mb-0"><?= $ot->id ?></h4>
<h4 id="otId" class="mb-0"><?= $ot->id ?></h4>
</div>
<div class="mt-lg-4 mt-lg-2 mb-lg-4 mb-2 pt-1 w-100">
<p class="mb-0">Clicks presupuesto</p>

View File

@ -31,6 +31,10 @@
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('App.global_save_file') ?></span>
<i class="ti ti-device-floppy ti-xs"></i>
</button>
<button id="<?= $id ?>_btnDownloadFiles" class="btn mt-3 btn-secondary btn-sm waves-effect waves-light ml-2">
<span class="align-middle d-sm-inline-block d-none me-sm-1"><?= lang('App.global_download_files') ?></span>
<i class="ti ti-device-floppy ti-xs"></i>
</button>
</div>
</div>
</div>

View File

@ -3,6 +3,8 @@
<table id="<?= $id ?>" class="table table-hover text-dark" style="width: 100%;">
<thead>
<tr>
<th></th>
<th class="w-10"><?= lang('Produccion.datatable.ot_id') ?></th>
<th><?= lang('Produccion.datatable.pedido_id') ?></th>
<th><?= lang('Produccion.datatable.fecha_encuadernacion') ?></th>
<th><?= lang('Produccion.datatable.cliente') ?></th>
@ -14,6 +16,20 @@
<th><?= lang('Produccion.datatable.progreso') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr>
<tr>
<th></th>
<th><input type="text" class="form-control ot-filter" name="id"></th>
<th><input type="text" class="form-control ot-filter" name="pedido_id"></th>
<th><input type="text" class="form-control ot-filter" name="fecha_encuadernado_at"></th>
<th><input type="text" class="form-control ot-filter" name="cliente_nombre"></th>
<th><input type="text" class="form-control ot-filter" name="presupuesto_titulo"></th>
<th><input type="text" class="form-control ot-filter" name="ubicacion_nombre"></th>
<th><input type="text" class="form-control ot-filter" name="total_tirada"></th>
<th><input type="text" class="form-control ot-filter" name="tipo_presupuesto_impresion"></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>

View File

@ -0,0 +1,28 @@
<div class="table-responsive">
<table id="<?= $id ?>" class="table table-striped table-hover" style="width: 100%;">
<thead>
<tr>
<th><?= lang('Produccion.datatable.nombre') ?></th>
<th><?= lang('Produccion.datatable.tareas') ?></th>
<th><?= lang('Produccion.datatable.tirada') ?></th>
<th><?= lang('Produccion.datatable.pliegos_libro') ?></th>
<th><?= lang('Produccion.datatable.tiempo') ?>(HH:MM)</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th colspan="3" style="text-align:right">Total:</th>
<th><span id="total-pliegos-maquina"></span></th>
<th id="total-tiempo-pliego-maquina"></th>
<th></th>
</tr>
</tfoot>
</table>
</div>

View File

@ -24,7 +24,6 @@
<th><input type="text" class="form-control planning-filter" name="presupuesto_titulo" placeholder="Titulo"></th>
<th>
<div class="d-flex flex-column gap-2">
<select class="select2 form-select-sm planning-maquina-padre-select" name="lg_maquinas.padre_id"></select>
<select class="select2 form-select-sm planning-maquina-select" name="maquina_planning_nombre"></select>
</div>
</th>

View File

@ -70,9 +70,9 @@
</div>
<div class="col-md-3 mb-3">
<label for="isk" class="form-label">Identificador ISK</label>
<input type="text" id="isk" name="isk" class="form-control" readonly
value="<?= old('isk', $catalogoLibrosEntity->isk) ?>" maxlength="64"
<label for="iskn" class="form-label">Identificador ISKN</label>
<input type="text" id="iskn" name="iskn" class="form-control" readonly
value="<?= old('iskn', $catalogoLibrosEntity->iskn) ?>" maxlength="64"
style="background: #E8E8E8;">
</div>

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