From 665dc2d86db4e42aa3492961e7e13b7e33ce7586 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Sat, 10 Aug 2024 21:09:56 +0200 Subject: [PATCH 01/42] xml service --- ci4/app/Services/PedidoXMLService.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 ci4/app/Services/PedidoXMLService.php diff --git a/ci4/app/Services/PedidoXMLService.php b/ci4/app/Services/PedidoXMLService.php new file mode 100644 index 00000000..4281b6d9 --- /dev/null +++ b/ci4/app/Services/PedidoXMLService.php @@ -0,0 +1,16 @@ +pedido = $pedido; + } + +} \ No newline at end of file From 5648f4341380d9655a80920550ca2b004c27c10d Mon Sep 17 00:00:00 2001 From: amazuecos Date: Mon, 12 Aug 2024 08:02:14 +0200 Subject: [PATCH 02/42] xml service --- ci4/app/Config/Routes.php | 3 +- ci4/app/Controllers/Pedidos/Pedido.php | 11 ++- ci4/app/Models/Pedidos/PedidoModel.php | 67 +++++++++++++ ci4/app/Services/PedidoXMLService.php | 128 +++++++++++++++++++++++-- 4 files changed, 199 insertions(+), 10 deletions(-) diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 9ddf7463..adcad4bf 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -1,7 +1,6 @@ group('pedidos', ['namespace' => 'App\Controllers\Pedidos'], function ( $routes->post('getlineas', 'Pedido::getLineas', ['as' => 'tablaLineasPedido']); $routes->post('cambiarestado', 'Pedido::cambiarEstado', ['as' => 'cambiarEstadoPedido']); $routes->post('update/(:any)', 'Pedido::update/$1', ['as' => 'actualizarPedido']); + $routes->get('xml/(:num)', 'Pedido::get_xml_pedido/$1',['as' => 'getXMLPedido']); + }); $routes->resource('pedidos', ['namespace' => 'App\Controllers\Pedidos', 'controller' => 'Pedido', 'except' => 'show,new,create,update']); diff --git a/ci4/app/Controllers/Pedidos/Pedido.php b/ci4/app/Controllers/Pedidos/Pedido.php index 647ff134..345d9807 100755 --- a/ci4/app/Controllers/Pedidos/Pedido.php +++ b/ci4/app/Controllers/Pedidos/Pedido.php @@ -5,7 +5,7 @@ use App\Controllers\BaseController; use App\Entities\Pedidos\PedidoEntity; use App\Models\Collection; use App\Models\Pedidos\PedidoModel; - +use App\Services\PedidoXMLService; class Pedido extends \App\Controllers\BaseResourceController { @@ -21,7 +21,6 @@ class Pedido extends \App\Controllers\BaseResourceController protected $indexRoute = 'pedidoList'; - public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger) { $this->viewData['pageTitle'] = lang('Pedidos.moduleTitle'); @@ -327,5 +326,13 @@ class Pedido extends \App\Controllers\BaseResourceController $pedidoEntity->fecha_encuadernado_text = $pedidoEntity->fecha_encuadernado ? date('d/m/Y', strtotime($pedidoEntity->fecha_encuadernado)) : ''; $pedidoEntity->fecha_entrega_externo_text = $pedidoEntity->fecha_entrega_externo ? date('d/m/Y', strtotime($pedidoEntity->fecha_entrega_externo)) : ''; } + public function get_xml_pedido($pedido_id) + { + $data_pedido = $this->model->getPedidoClientePresupuesto($pedido_id); + $data_pedido_presupuesto = $this->model->getPedidoPresupuestoLineas($pedido_id); + // PedidoXMLService::generate_xml($data); + // $xml_service = new PedidoXMLService($this->model); + return $this->respond(["pedido_presupuesto" => $data_pedido,"pedido_presupuesto_linea" => $data_pedido_presupuesto]); + } } \ No newline at end of file diff --git a/ci4/app/Models/Pedidos/PedidoModel.php b/ci4/app/Models/Pedidos/PedidoModel.php index 04755c6e..7f938a54 100644 --- a/ci4/app/Models/Pedidos/PedidoModel.php +++ b/ci4/app/Models/Pedidos/PedidoModel.php @@ -2,6 +2,8 @@ namespace App\Models\Pedidos; +use function PHPSTORM_META\map; + class PedidoModel extends \App\Models\BaseModel { protected $table = "pedidos"; @@ -85,4 +87,69 @@ class PedidoModel extends \App\Models\BaseModel return $lineasPresupuesto; } + public function getPedidoClientePresupuesto(int $pedido_id) + { + $query = $this->db->table($this->table) + ->select([ + 'pedidos.id as pedidoId', + 'clientes.nombre as customerName', + 'presupuestos.total_aceptado as totalAceptado', + 'presupuestos.margen', + 'presupuestos.inc_rei', + 'presupuestos.tirada', + 'presupuestos.titulo', + 'presupuestos.paginas', + 'presupuestos.papel_formato_personalizado', + 'presupuestos.papel_formato_ancho as papelAnchoPersonalidado ', + 'presupuestos.papel_formato_alto as papelAltoPersonalidado', + 'lg_papel_formato.ancho as lgPapelFormatoAncho ', + 'lg_papel_formato.alto as lgPapelFormatoAlto', + 'lg_tarifa_acabado.nombre as lgTarifaAcabadoNombre', + ]) + ->join('pedidos_linea','pedidos_linea.id = pedidos.id','left') + ->join('presupuestos','presupuestos.id = pedidos_linea.presupuesto_id','left') + // ->join('presupuesto_linea','presupuestos.id = presupuesto_linea.presupuesto_id','left') + ->join('clientes','clientes.id = presupuestos.cliente_id','left') + ->join('lg_papel_formato','lg_papel_formato.id = presupuestos.papel_formato_id','left') + ->join('lg_tarifa_acabado','lg_tarifa_acabado.id = presupuestos.acabado_cubierta_id','left') + + ->where('pedidos.id',$pedido_id); + $cliente_presupuesto = $query->get()->getFirstRow(); + return $cliente_presupuesto; + } + public function getPedidoPresupuestoLineas(int $pedido_id) + { + $query = $this->db->table($this->table) + ->select([ + 'presupuesto_linea.*', + 'lg_papel_generico.code as papelCode', + + ]) + ->join('pedidos_linea','pedidos_linea.id = pedidos.id','left') + ->join('presupuestos','presupuestos.id = pedidos_linea.presupuesto_id','left') + ->join('presupuesto_linea','presupuestos.id = presupuesto_linea.presupuesto_id','left') + ->join('lg_papel_generico','lg_papel_generico.id = presupuesto_linea.papel_id','left') + + + ->where('pedidos.id',$pedido_id); + $pedido_presupuesto_lineas = $query->get()->getResultObject(); + return $pedido_presupuesto_lineas; + } + public function getPedidoClienteDirecciones($pedido_id){ + $query = $this->db->table($this->table) + ->select([ + 'pedidos.id as pedidoId', + 'clientes.nombre as customerName', + 'cliente_direcciones.*', + 'lg_paises.code3' + ]) + ->join('pedidos_linea','pedidos_linea.id = pedidos.id','left') + ->join('presupuestos','presupuestos.id = pedidos_linea.presupuesto_id','left') + ->join('clientes','clientes.id = presupuestos.cliente_id','left') + ->join('cliente_direcciones','clientes.id = cliente_direcciones.cliente_id','left') + ->join('lg_paises','lg_paises.id = cliente_direcciones.pais_id','left') + ->where('pedidos.id',$pedido_id); + $pedido_cliente_direcciones = $query->get()->getResultObject(); + return $pedido_cliente_direcciones; + } } \ No newline at end of file diff --git a/ci4/app/Services/PedidoXMLService.php b/ci4/app/Services/PedidoXMLService.php index 4281b6d9..9882a18e 100644 --- a/ci4/app/Services/PedidoXMLService.php +++ b/ci4/app/Services/PedidoXMLService.php @@ -1,16 +1,130 @@ -pedido = $pedido; + + public static function generate_xml($data) + { + $papel_formato_ancho = 0; + $papel_formato_alto = 0; + $xml = new DOMDocument('1.0', 'utf-8'); + $xml_order_el = $xml->createElement('Order'); + $xml_header_el = $xml->createElement('Header'); + $xml_header_el->appendChild($xml->createElement('CustomerCode', 988)); + $xml_header_el->appendChild($xml->createElement('CodeNode', "false")); + $xml_header_el->appendChild($xml->createElement('ExternId', $data->pedido_presupuesto->pedidoId)); + $xml_header_el->appendChild($xml->createElement('NumProducts', 988)); + $xml_header_el->appendChild($xml->createElement('Date', now_db())); + $xml_order_el->appendChild($xml_header_el); + $xml_products_el = $xml->createElement('Products'); + $xml_products_el->appendChild($xml->createElement('ItemId', $data->pedido_presupuesto->pedidoId)); + $xml_products_el->appendChild($xml->createElement('Quantity', $data->pedido_presupuesto->tirada)); + $xml_products_el->appendChild($xml->createElement('Title', $data->pedido_presupuesto->titulo)); + $xml_products_el->appendChild($xml->createElement('Pages', $data->pedido_presupuesto->paginas)); + $xml_products_el->appendChild($xml->createElement('Reprint', $data->pedido_presupuesto->inc_rei)); + + if ($data->pedido_presupuesto->papel_formato_personalizado) { + $papel_formato_ancho = $data->pedido_presupuesto->papelAnchoPersonalidado; + $papel_formato_alto = $data->pedido_presupuesto->papelAltoPersonalidado; + } else { + $papel_formato_ancho = $data->pedido_presupuesto->lgPapelFormatoAncho; + $papel_formato_alto = $data->pedido_presupuesto->lgPapelFormatoAlto; + } + $xml_products_el->appendChild($xml->createElement('Width', $papel_formato_ancho)); + $xml_products_el->appendChild($xml->createElement('Height', $papel_formato_alto)); + $presupuestoLineaTipoCubierta = null; + $xml_presupuesto_lineas_el = $xml->createElement('Lines'); + ## Iterate throught presupuesto_lineas + foreach ($data->pedido_presupuesto_lineas as $row) { + if (str_contains($row->tipo, "rot") || str_contains($row->tipo, "bn") || str_contains($row->tipo, "color")) { + $colorInterior = PedidoXMLService::get_color_interior($row); + $xmlInside = $xml->createElement('Inside'); + $xmlInside->appendChild($xml->createElement('TypeOfPrint', $colorInterior)); + $xmlInside->appendChild($xml->createElement('HQ', str_contains($row->tipo, 'hq') ? 1 : 0)); + $xmlInside->appendChild($xml->createElement('Pages', $row->paginas)); + $xmlInside->appendChild($xml->createElement('Paper', $row->papelCode)); + $xmlInside->appendChild($xml->createElement('Weight', $row->gramaje)); + $xml_presupuesto_lineas_el->appendChild($xmlInside); + } else if (str_contains($row->tipo, "cubierta") || str_contains($row->tipo, "sobrecubierta")) { + $papelCubiertaCode = $row->papelCode; + $papelCubiertaGramaje = $row->gramaje; + $presupuestoLineaTipoCubierta = $row->tipo == "lp_cubierta" ? $row : null; + } + } + + $xml_products_el->appendChild($xml_presupuesto_lineas_el); + if ($presupuestoLineaTipoCubierta) { + $lgTarifaAcabadoNombre = $data->pedido_presupuesto->lgTarifaAcabadoNombre; + if(str_contains('brillo',$lgTarifaAcabadoNombre)){ + $acabado = "brillo"; + }else{ + $acabado = "mate"; + } + $xmlCover = $xml->createElement('Cover'); + $xmlCover->appendChild($xml->createElement('Sides', $presupuestoLineaTipoCubierta->paginas)); //! PAGINAS CUBIERTA + $xmlCover->appendChild($xml->createElement('Paper', $presupuestoLineaTipoCubierta->papelCode)); //? + $xmlCover->appendChild($xml->createElement('Weight', $presupuestoLineaTipoCubierta->gramaje)); + $xmlCover->appendChild($xml->createElement('Flaps', $data->pedido_presupuesto->solapas)); + $xmlCover->appendChild($xml->createElement('WidthFlaps', $data->pedido_presupuesto->solapas_ancho)); + $xmlCover->appendChild($xml->createElement('Finish', $acabado)); + $xml_products_el->appendChild($xmlCover); + } + $xml_services_el = $xml->createElement('Services'); + $xml_services_el->appendChild($xml->createElement('Bookmark', $data->pedido_presupuesto->marcapaginas)); + $xml_services_el->appendChild($xml->createElement('ShrinkWrapping', $data->pedido_presupuesto->retractilado)); + //? $xml_services_el->appendChild($xml->createElement('PlakeneT', $data->pedido_presupuesto->plakeneT)); + $xml_services_el->appendChild($xml->createElement('Urgent', $data->pedido_presupuesto->urgent)); + $xml_services_el->appendChild($xml->createElement('Prototype', $data->pedido_presupuesto->prototipo)); + $xml_services_el->appendChild($xml->createElement('Layout', $data->pedido_presupuesto->maquetacion)); + $xml_services_el->appendChild($xml->createElement('Correction', $data->pedido_presupuesto->correccion)); + $xml_services_el->appendChild($xml->createElement('Review', $data->pedido_presupuesto->revision)); + $xml_services_el->appendChild($xml->createElement('Design', $data->pedido_presupuesto->diseno)); + $xml_products_el->appendChild($xml_services_el); + + $xml_envios_el = $xml->createElement('Shipments'); + foreach ($data->pedido_cliente_direcciones as $pedido_cliente_direccion) { + $xml_envio_el = $xml->createElement('Shipment'); + //! Tirada o cantidad de envios? + $xml_envio_el->appendChild($xml->createElement('Qty', $data->pedido_presupuesto->tirada)); + //! Precio del presupuesto o del envio? + $xml_envio_el->appendChild($xml->createElement('Price', $data->pedido_presupuesto->total_aceptado)); + $xml_envio_el->appendChild($xml->createElement('Attention', $pedido_cliente_direccion->att)); + $xml_envio_el->appendChild($xml->createElement('Email', $pedido_cliente_direccion->email)); + $xml_envio_el->appendChild($xml->createElement('Address', $pedido_cliente_direccion->direccion)); + $xml_envio_el->appendChild($xml->createElement('Province', $pedido_cliente_direccion->provincia)); + $xml_envio_el->appendChild($xml->createElement('City', $pedido_cliente_direccion->ciudad)); + $xml_envio_el->appendChild($xml->createElement('Zip', $pedido_cliente_direccion->cp)); + $xml_envio_el->appendChild($xml->createElement('CountryCode', $pedido_cliente_direccion->code3)); + $xml_envio_el->appendChild($xml->createElement('Telephone', $pedido_cliente_direccion->telefono)); + $xml_envios_el->appendChild($xml_envio_el); + + } + $xml_products_el->appendChild($xml_envios_el); + $xml_products_el->appendChild($xml->createElement('Comments', $data->pedido_presupuesto->comentarios_safekat)); + $xml_products_el->appendChild($xml->createElement('CommentsClient', $data->pedido_presupuesto->comentarios_cliente)); + } - -} \ No newline at end of file + protected static function get_color_interior($pre_linea): ?string + { + $color_interior = null; + $bn_tipo_array = ['lp_bn', 'lp_bnhq', 'lp_rot_bn']; + $color_tipo_array = ['lp_color', 'lp_color_hq', 'lp_rot_color']; + + if (in_array($pre_linea->tipo, $bn_tipo_array)) { + $color_interior = "bn"; + }; + if (in_array($pre_linea->tipo, $color_tipo_array)) { + $color_interior = "color"; + }; + return $color_interior; + } +} From 070ffb934dc4976bca7f62c26d01e5a69901f7e0 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Mon, 12 Aug 2024 10:59:53 +0200 Subject: [PATCH 03/42] xml envios --- ci4/app/Models/Pedidos/PedidoModel.php | 121 +++++++++++++------------ ci4/app/Services/PedidoXMLService.php | 43 ++++----- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/ci4/app/Models/Pedidos/PedidoModel.php b/ci4/app/Models/Pedidos/PedidoModel.php index 7f938a54..37b40e6c 100644 --- a/ci4/app/Models/Pedidos/PedidoModel.php +++ b/ci4/app/Models/Pedidos/PedidoModel.php @@ -31,11 +31,11 @@ class PedidoModel extends \App\Models\BaseModel ]; protected $allowedFields = [ - "total_precio", - "total_tirada", - "estado", - "user_created_id", - "user_updated_id", + "total_precio", + "total_tirada", + "estado", + "user_created_id", + "user_updated_id", "user_validated_id", "fecha_entrega_real", "fecha_impresion", @@ -55,22 +55,25 @@ class PedidoModel extends \App\Models\BaseModel public static $labelField = "id"; - public function obtenerDatosForm($pedido_id){ + public function obtenerDatosForm($pedido_id) + { $builder = $this->db ->table($this->table . " t1") ->select( - "t4.id AS cliente_id, t4.nombre AS cliente, CONCAT(t5.first_name, ' ', t5.last_name) AS comercial"); + "t4.id AS cliente_id, t4.nombre AS cliente, CONCAT(t5.first_name, ' ', t5.last_name) AS comercial" + ); - $builder->join("pedidos_linea t2", "t2.pedido_id = t1.id", "left"); - $builder->join("presupuestos t3", "t2.presupuesto_id = t3.id", "left"); + $builder->join("pedidos_linea t2", "t2.pedido_id = t1.id", "left"); + $builder->join("presupuestos t3", "t2.presupuesto_id = t3.id", "left"); $builder->join("clientes t4", "t4.id = t3.cliente_id", "left"); $builder->join("users t5", "t5.id = t4.comercial_id", "left"); - - + + return $builder->get()->getResultObject(); } - public function obtenerLineasPedido($pedido_id){ + public function obtenerLineasPedido($pedido_id) + { $builder = $this->db ->table($this->table . " t1") ->select( @@ -81,7 +84,7 @@ class PedidoModel extends \App\Models\BaseModel $model_presupuesto = model("App\Models\Presupuestos\PresupuestoModel"); $lineasPresupuesto = []; - foreach($builder->get()->getResultObject() as $row){ + foreach ($builder->get()->getResultObject() as $row) { array_push($lineasPresupuesto, $model_presupuesto->generarLineaPedido($row->presupuesto_id)[0]); } @@ -90,66 +93,66 @@ class PedidoModel extends \App\Models\BaseModel public function getPedidoClientePresupuesto(int $pedido_id) { $query = $this->db->table($this->table) - ->select([ - 'pedidos.id as pedidoId', - 'clientes.nombre as customerName', - 'presupuestos.total_aceptado as totalAceptado', - 'presupuestos.margen', - 'presupuestos.inc_rei', - 'presupuestos.tirada', - 'presupuestos.titulo', - 'presupuestos.paginas', - 'presupuestos.papel_formato_personalizado', - 'presupuestos.papel_formato_ancho as papelAnchoPersonalidado ', - 'presupuestos.papel_formato_alto as papelAltoPersonalidado', - 'lg_papel_formato.ancho as lgPapelFormatoAncho ', - 'lg_papel_formato.alto as lgPapelFormatoAlto', - 'lg_tarifa_acabado.nombre as lgTarifaAcabadoNombre', - ]) - ->join('pedidos_linea','pedidos_linea.id = pedidos.id','left') - ->join('presupuestos','presupuestos.id = pedidos_linea.presupuesto_id','left') - // ->join('presupuesto_linea','presupuestos.id = presupuesto_linea.presupuesto_id','left') - ->join('clientes','clientes.id = presupuestos.cliente_id','left') - ->join('lg_papel_formato','lg_papel_formato.id = presupuestos.papel_formato_id','left') - ->join('lg_tarifa_acabado','lg_tarifa_acabado.id = presupuestos.acabado_cubierta_id','left') + ->select([ + 'pedidos.id as pedidoId', + 'clientes.nombre as customerName', + 'presupuestos.total_aceptado as totalAceptado', + 'presupuestos.margen', + 'presupuestos.inc_rei', + 'presupuestos.tirada', + 'presupuestos.titulo', + 'presupuestos.paginas', + 'presupuestos.papel_formato_personalizado', + 'presupuestos.papel_formato_ancho as papelAnchoPersonalidado ', + 'presupuestos.papel_formato_alto as papelAltoPersonalidado', + 'lg_papel_formato.ancho as lgPapelFormatoAncho ', + 'lg_papel_formato.alto as lgPapelFormatoAlto', + 'lg_tarifa_acabado.nombre as lgTarifaAcabadoNombre', + ]) + ->join('pedidos_linea', 'pedidos_linea.id = pedidos.id', 'left') + ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left') + // ->join('presupuesto_linea','presupuestos.id = presupuesto_linea.presupuesto_id','left') + ->join('clientes', 'clientes.id = presupuestos.cliente_id', 'left') + ->join('lg_papel_formato', 'lg_papel_formato.id = presupuestos.papel_formato_id', 'left') + ->join('lg_tarifa_acabado', 'lg_tarifa_acabado.id = presupuestos.acabado_cubierta_id', 'left') - ->where('pedidos.id',$pedido_id); + ->where('pedidos.id', $pedido_id); $cliente_presupuesto = $query->get()->getFirstRow(); return $cliente_presupuesto; } public function getPedidoPresupuestoLineas(int $pedido_id) { $query = $this->db->table($this->table) - ->select([ - 'presupuesto_linea.*', - 'lg_papel_generico.code as papelCode', + ->select([ + 'presupuesto_linea.*', + 'lg_papel_generico.code as papelCode', - ]) - ->join('pedidos_linea','pedidos_linea.id = pedidos.id','left') - ->join('presupuestos','presupuestos.id = pedidos_linea.presupuesto_id','left') - ->join('presupuesto_linea','presupuestos.id = presupuesto_linea.presupuesto_id','left') - ->join('lg_papel_generico','lg_papel_generico.id = presupuesto_linea.papel_id','left') + ]) + ->join('pedidos_linea', 'pedidos_linea.id = pedidos.id', 'left') + ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left') + ->join('presupuesto_linea', 'presupuestos.id = presupuesto_linea.presupuesto_id', 'left') + ->join('lg_papel_generico', 'lg_papel_generico.id = presupuesto_linea.papel_id', 'left') - ->where('pedidos.id',$pedido_id); + ->where('pedidos.id', $pedido_id); $pedido_presupuesto_lineas = $query->get()->getResultObject(); return $pedido_presupuesto_lineas; } - public function getPedidoClienteDirecciones($pedido_id){ + public function getPedidoPresupuestoDirecciones($pedido_id) + { $query = $this->db->table($this->table) - ->select([ - 'pedidos.id as pedidoId', - 'clientes.nombre as customerName', - 'cliente_direcciones.*', - 'lg_paises.code3' - ]) - ->join('pedidos_linea','pedidos_linea.id = pedidos.id','left') - ->join('presupuestos','presupuestos.id = pedidos_linea.presupuesto_id','left') - ->join('clientes','clientes.id = presupuestos.cliente_id','left') - ->join('cliente_direcciones','clientes.id = cliente_direcciones.cliente_id','left') - ->join('lg_paises','lg_paises.id = cliente_direcciones.pais_id','left') - ->where('pedidos.id',$pedido_id); + ->select([ + 'clientes.nombre as customerName', + 'presupuesto_direcciones.*', + 'lg_paises.code3' + ]) + ->join('pedidos_linea', 'pedidos_linea.id = pedidos.id', 'left') + ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left') + ->join('clientes', 'clientes.id = presupuestos.cliente_id', 'left') + ->join('cliente_direcciones', 'clientes.id = cliente_direcciones.cliente_id', 'left') + ->join('lg_paises', 'lg_paises.id = presupuesto_direcciones.pais_id', 'left') + ->where('pedidos.id', $pedido_id); $pedido_cliente_direcciones = $query->get()->getResultObject(); return $pedido_cliente_direcciones; } -} \ No newline at end of file +} diff --git a/ci4/app/Services/PedidoXMLService.php b/ci4/app/Services/PedidoXMLService.php index 9882a18e..a535ebab 100644 --- a/ci4/app/Services/PedidoXMLService.php +++ b/ci4/app/Services/PedidoXMLService.php @@ -64,13 +64,13 @@ class PedidoXMLService extends BaseService $xml_products_el->appendChild($xml_presupuesto_lineas_el); if ($presupuestoLineaTipoCubierta) { $lgTarifaAcabadoNombre = $data->pedido_presupuesto->lgTarifaAcabadoNombre; - if(str_contains('brillo',$lgTarifaAcabadoNombre)){ + if (str_contains('brillo', $lgTarifaAcabadoNombre)) { $acabado = "brillo"; - }else{ + } else { $acabado = "mate"; } $xmlCover = $xml->createElement('Cover'); - $xmlCover->appendChild($xml->createElement('Sides', $presupuestoLineaTipoCubierta->paginas)); //! PAGINAS CUBIERTA + $xmlCover->appendChild($xml->createElement('Sides', $presupuestoLineaTipoCubierta->paginas / 2)); //! PAGINAS CUBIERTA $xmlCover->appendChild($xml->createElement('Paper', $presupuestoLineaTipoCubierta->papelCode)); //? $xmlCover->appendChild($xml->createElement('Weight', $presupuestoLineaTipoCubierta->gramaje)); $xmlCover->appendChild($xml->createElement('Flaps', $data->pedido_presupuesto->solapas)); @@ -80,38 +80,35 @@ class PedidoXMLService extends BaseService } $xml_services_el = $xml->createElement('Services'); $xml_services_el->appendChild($xml->createElement('Bookmark', $data->pedido_presupuesto->marcapaginas)); + //? Retractilado5 y Retractilado o ambas $xml_services_el->appendChild($xml->createElement('ShrinkWrapping', $data->pedido_presupuesto->retractilado)); //? $xml_services_el->appendChild($xml->createElement('PlakeneT', $data->pedido_presupuesto->plakeneT)); - $xml_services_el->appendChild($xml->createElement('Urgent', $data->pedido_presupuesto->urgent)); + //? $xml_services_el->appendChild($xml->createElement('Urgent', $data->pedido_presupuesto->urgent)); $xml_services_el->appendChild($xml->createElement('Prototype', $data->pedido_presupuesto->prototipo)); - $xml_services_el->appendChild($xml->createElement('Layout', $data->pedido_presupuesto->maquetacion)); - $xml_services_el->appendChild($xml->createElement('Correction', $data->pedido_presupuesto->correccion)); - $xml_services_el->appendChild($xml->createElement('Review', $data->pedido_presupuesto->revision)); - $xml_services_el->appendChild($xml->createElement('Design', $data->pedido_presupuesto->diseno)); + //? $xml_services_el->appendChild($xml->createElement('Layout', $data->pedido_presupuesto->maquetacion)); + //? $xml_services_el->appendChild($xml->createElement('Correction', $data->pedido_presupuesto->correccion)); + //? $xml_services_el->appendChild($xml->createElement('Review', $data->pedido_presupuesto->revision)); + //? $xml_services_el->appendChild($xml->createElement('Design', $data->pedido_presupuesto->diseno)); $xml_products_el->appendChild($xml_services_el); $xml_envios_el = $xml->createElement('Shipments'); - foreach ($data->pedido_cliente_direcciones as $pedido_cliente_direccion) { + foreach ($data->pedido_presupuesto_direcciones as $pedido_presupuesto_direccion) { $xml_envio_el = $xml->createElement('Shipment'); - //! Tirada o cantidad de envios? - $xml_envio_el->appendChild($xml->createElement('Qty', $data->pedido_presupuesto->tirada)); - //! Precio del presupuesto o del envio? - $xml_envio_el->appendChild($xml->createElement('Price', $data->pedido_presupuesto->total_aceptado)); - $xml_envio_el->appendChild($xml->createElement('Attention', $pedido_cliente_direccion->att)); - $xml_envio_el->appendChild($xml->createElement('Email', $pedido_cliente_direccion->email)); - $xml_envio_el->appendChild($xml->createElement('Address', $pedido_cliente_direccion->direccion)); - $xml_envio_el->appendChild($xml->createElement('Province', $pedido_cliente_direccion->provincia)); - $xml_envio_el->appendChild($xml->createElement('City', $pedido_cliente_direccion->ciudad)); - $xml_envio_el->appendChild($xml->createElement('Zip', $pedido_cliente_direccion->cp)); - $xml_envio_el->appendChild($xml->createElement('CountryCode', $pedido_cliente_direccion->code3)); - $xml_envio_el->appendChild($xml->createElement('Telephone', $pedido_cliente_direccion->telefono)); + $xml_envio_el->appendChild($xml->createElement('Qty', $pedido_presupuesto_direccion->cantidad)); + $xml_envio_el->appendChild($xml->createElement('Price', $data->pedido_presupuesto_direccion->precio)); + $xml_envio_el->appendChild($xml->createElement('Attention', $pedido_presupuesto_direccion->att)); + $xml_envio_el->appendChild($xml->createElement('Email', $pedido_presupuesto_direccion->email)); + $xml_envio_el->appendChild($xml->createElement('Address', $pedido_presupuesto_direccion->direccion)); + $xml_envio_el->appendChild($xml->createElement('Province', $pedido_presupuesto_direccion->provincia)); + $xml_envio_el->appendChild($xml->createElement('City', $pedido_presupuesto_direccion->ciudad)); + $xml_envio_el->appendChild($xml->createElement('Zip', $pedido_presupuesto_direccion->cp)); + $xml_envio_el->appendChild($xml->createElement('CountryCode', $pedido_presupuesto_direccion->code3)); + $xml_envio_el->appendChild($xml->createElement('Telephone', $pedido_presupuesto_direccion->telefono)); $xml_envios_el->appendChild($xml_envio_el); - } $xml_products_el->appendChild($xml_envios_el); $xml_products_el->appendChild($xml->createElement('Comments', $data->pedido_presupuesto->comentarios_safekat)); $xml_products_el->appendChild($xml->createElement('CommentsClient', $data->pedido_presupuesto->comentarios_cliente)); - } protected static function get_color_interior($pre_linea): ?string { From 5169174e57166c3401fe8ef09b8b387590a43ba1 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Mon, 12 Aug 2024 12:16:04 +0200 Subject: [PATCH 04/42] git push --- ci4/app/Services/PedidoXMLService.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ci4/app/Services/PedidoXMLService.php b/ci4/app/Services/PedidoXMLService.php index a535ebab..55751ba1 100644 --- a/ci4/app/Services/PedidoXMLService.php +++ b/ci4/app/Services/PedidoXMLService.php @@ -81,14 +81,15 @@ class PedidoXMLService extends BaseService $xml_services_el = $xml->createElement('Services'); $xml_services_el->appendChild($xml->createElement('Bookmark', $data->pedido_presupuesto->marcapaginas)); //? Retractilado5 y Retractilado o ambas + //! MIRAR $xml_services_el->appendChild($xml->createElement('ShrinkWrapping', $data->pedido_presupuesto->retractilado)); - //? $xml_services_el->appendChild($xml->createElement('PlakeneT', $data->pedido_presupuesto->plakeneT)); - //? $xml_services_el->appendChild($xml->createElement('Urgent', $data->pedido_presupuesto->urgent)); - $xml_services_el->appendChild($xml->createElement('Prototype', $data->pedido_presupuesto->prototipo)); - //? $xml_services_el->appendChild($xml->createElement('Layout', $data->pedido_presupuesto->maquetacion)); - //? $xml_services_el->appendChild($xml->createElement('Correction', $data->pedido_presupuesto->correccion)); - //? $xml_services_el->appendChild($xml->createElement('Review', $data->pedido_presupuesto->revision)); - //? $xml_services_el->appendChild($xml->createElement('Design', $data->pedido_presupuesto->diseno)); + //? $xml_services_el->appendChild($xml->createElement('PlakeneT', $data->pedido_presupuesto->plakeneT)); ?? + //? $xml_services_el->appendChild($xml->createElement('Urgent', $data->pedido_presupuesto->urgent)); PEDIDO URGENTE + $xml_services_el->appendChild($xml->createElement('Prototype', $data->pedido_presupuesto->prototipo)); // + //? $xml_services_el->appendChild($xml->createElement('Layout', $data->pedido_presupuesto->maquetacion)); , MAQUETACION + //? $xml_services_el->appendChild($xml->createElement('Correction', $data->pedido_presupuesto->correccion)); CORRECCION ORTOGRAFICA + //? $xml_services_el->appendChild($xml->createElement('Review', $data->pedido_presupuesto->revision)); REVISION ?? + //? $xml_services_el->appendChild($xml->createElement('Design', $data->pedido_presupuesto->diseno)); DISEÑO DE CUBIERTA $xml_products_el->appendChild($xml_services_el); $xml_envios_el = $xml->createElement('Shipments'); From ec8288e6e47271f42b2497e5bb8f33434ef0d3d9 Mon Sep 17 00:00:00 2001 From: imnavajas Date: Fri, 16 Aug 2024 15:44:45 +0200 Subject: [PATCH 05/42] Preparada factura en PDF --- ci4/app/Config/Routes.php | 9 + ci4/app/Controllers/Pdf/PrintFacturas.php | 65 ++++ ci4/app/Models/Facturas/FacturaLineaModel.php | 50 +++ ci4/app/Models/Facturas/FacturaModel.php | 34 ++ ci4/app/Views/themes/vuexy/pdfs/factura.php | 193 +++++++++++ httpdocs/themes/vuexy/css/pdf.factura.css | 313 ++++++++++++++++++ 6 files changed, 664 insertions(+) create mode 100644 ci4/app/Controllers/Pdf/PrintFacturas.php create mode 100644 ci4/app/Views/themes/vuexy/pdfs/factura.php create mode 100644 httpdocs/themes/vuexy/css/pdf.factura.css diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 9ddf7463..41530954 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -700,6 +700,15 @@ $routes->group( } ); +$routes->group( + 'print-factura', + ['namespace' => 'App\Controllers\Pdf'], + function ($routes) { + $routes->get('index/(:num)', 'PrintFacturas::index/$1', ['as' => 'viewFacturaPDF']); + $routes->get('generar/(:num)', 'PrintFacturas::generar/$1', ['as' => 'facturaToPdf']); + } +); + $routes->group( 'export-giros', ['namespace' => 'App\Controllers\Excel'], diff --git a/ci4/app/Controllers/Pdf/PrintFacturas.php b/ci4/app/Controllers/Pdf/PrintFacturas.php new file mode 100644 index 00000000..08e6e230 --- /dev/null +++ b/ci4/app/Controllers/Pdf/PrintFacturas.php @@ -0,0 +1,65 @@ +getResourceForPdf($id_factura)->get()->getRow(); + $data['lineas_factura'] = $lineasFacturaModel->getResourceForPdf($id_factura)->get()->getResultObject(); + $data['resumen_por_iva'] = $lineasFacturaModel->getResourceResumenIVAsForPdf($id_factura)->get()->getResultObject(); + + return view(getenv('theme.path') . 'pdfs/factura', $data); + } + + public function generar($id_factura) + { + + // Cargar modelos + $facturaModel = model('App\Models\Facturas\FacturaModel'); + $lineasFacturaModel = model('App\Models\Facturas\FacturaLineaModel'); + + // Informacion del presupuesto + $data['factura'] = $facturaModel->getResourceForPdf($id_factura)->get()->getRow(); + $data['lineas_factura'] = $lineasFacturaModel->getResourceForPdf($id_factura)->get()->getResultObject(); + $data['resumen_por_iva'] = $lineasFacturaModel->getResourceResumenIVAsForPdf($id_factura)->get()->getResultObject(); + + // Crear una instancia de Dompdf + $options = new \Dompdf\Options(); + $options->set('isHtml5ParserEnabled', true); + $options->set('isPhpEnabled', true); + $options->set('isRemoteEnabled', true); + $dompdf = new \Dompdf\Dompdf($options); + + // Contenido HTML del documento + $dompdf->loadHtml(view(getenv('theme.path').'pdfs/factura', $data)); + + // Establecer el tamaño del papel + $dompdf->setPaper('A4', 'portrait'); + + // Renderizar el PDF + $dompdf->render(); + + // Obtener el contenido generado + $output = $dompdf->output(); + + // Establecer las cabeceras para visualizar en lugar de descargar + $file_name = $data['factura']->numero . ".pdf"; + return $this->response + ->setStatusCode(200) + ->setHeader('Content-Type', 'application/pdf') + ->setHeader('Content-Disposition', 'inline; filename="' . $file_name . '"') + ->setHeader('Cache-Control', 'private, max-age=0, must-revalidate') + ->setHeader('Pragma', 'public') + ->setHeader('Content-Length', strlen($output)) + ->setBody($output); + } +} \ No newline at end of file diff --git a/ci4/app/Models/Facturas/FacturaLineaModel.php b/ci4/app/Models/Facturas/FacturaLineaModel.php index b808ac8c..b1bd1d9f 100644 --- a/ci4/app/Models/Facturas/FacturaLineaModel.php +++ b/ci4/app/Models/Facturas/FacturaLineaModel.php @@ -54,6 +54,56 @@ class FacturaLineaModel extends \App\Models\BaseModel { return $builder; } + + public function getResourceResumenIVAsForPdf($factura_id = -1) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.iva, + ROUND(SUM(t1.base), 2) AS base, + ROUND(SUM(t1.total_iva), 2) AS total_iva, + ROUND(SUM(t1.total), 2) AS total" + ) + ->where("t1.factura_id", $factura_id) + ->groupBy('t1.iva') + ->orderBy('t1.iva', 'ASC'); // Ordena por iva en forma ascendente + + return $builder; + } + + + /** + * Get resource data for creating PDFs. + * + * @param string $search + * + * @return \CodeIgniter\Database\BaseBuilder + */ + public function getResourceForPdf($factura_id = -1) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.factura_id AS factura_id, + t1.pedido_linea_impresion_id AS pedido_linea_impresion_id, t1.pedido_maquetacion_id AS pedido_maquetacion_id, + t1.descripcion AS descripcion, t1.cantidad as cantidad, t1.precio_unidad AS precio_unidad, t1.iva AS iva, + t1.base AS base, t1.total_iva AS total_iva, t1.total AS total, t1.data AS data, t2.pedido_id AS pedido_id, + t3.total_aceptado AS total_aceptado, t4.tirada_flexible AS tirada_flexible, t4.descuento_tirada_flexible AS descuento_tirada_flexible, + t6.cantidad AS cantidad_albaran" + ) + ->join("pedidos_linea t2", "t2.id = t1.pedido_linea_impresion_id", "left") + ->join("presupuestos t3", "t3.id = t2.presupuesto_id", "left") + ->join("clientes t4", "t4.id = t3.cliente_id", "left") + ->join("albaranes t5", "t5.pedido_id = t2.pedido_id", "left") + ->join("albaranes_lineas t6", "t6.albaran_id = t5.id", "left") + ->where("t1.factura_id", $factura_id) + ->where("t1.deleted_at", null); + + return $builder; + } + + public function addFacturaPedidoLinea($factura_id, $pedido_linea_id, $cantidad) { $data = [ diff --git a/ci4/app/Models/Facturas/FacturaModel.php b/ci4/app/Models/Facturas/FacturaModel.php index ccdf7f43..aeb8e46c 100644 --- a/ci4/app/Models/Facturas/FacturaModel.php +++ b/ci4/app/Models/Facturas/FacturaModel.php @@ -102,6 +102,40 @@ class FacturaModel extends \App\Models\BaseModel { } + /** + * Get resource data for creating PDFs. + * + * @param string $search + * + * @return \CodeIgniter\Database\BaseBuilder + */ + public function getResourceForPdf($factura_id = -1) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.numero AS numero, DATE_FORMAT(t1.fecha_factura_at, '%d/%m/%Y') AS fecha_factura_at, + t1.base AS base, t1.total AS total, t1.pendiente AS pendiente, + t1.creditoAsegurado AS creditoAsegurado, t1.estado AS estado, t1.estado_pago AS estado_pago, + t4.nombre AS forma_pago, + DATE_FORMAT(MIN(CASE WHEN t3.fecha_vencimiento_at != '0000-00-00 00:00:00' THEN t3.fecha_vencimiento_at ELSE NULL END), '%d/%m/%Y') AS vencimiento, + t2.nombre AS cliente, t2.direccion AS cliente_direccion, t2.ciudad AS cliente_ciudad, + t2.cp AS cliente_cp, t2.cif AS cliente_cif, t2.vencimiento AS dias_vencimiento, t2.ccc AS cliente_ccc, + t5.nombre AS cliente_pais" + ); + + $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->join("lg_paises t5", "t2.pais_id = t5.id", "left"); + + $builder->where("t1.deleted_at IS NULL"); + $builder->groupBy("t1.id"); // Agrupa por id de la factura + + return $builder; + } + + public function getResourcePedidos($pedido_id) { $builder = $this->db diff --git a/ci4/app/Views/themes/vuexy/pdfs/factura.php b/ci4/app/Views/themes/vuexy/pdfs/factura.php new file mode 100644 index 00000000..55a05982 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/pdfs/factura.php @@ -0,0 +1,193 @@ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FACTURA Nº:estado == 'draft') ? 'BORRADOR' : $factura->numero ?>FECHA:fecha_factura_at ?>
Dirección:
Persona de contacto:cliente_direccion ?>
Razón social: cliente ?> + cliente_cp ?> + , cliente_ciudad ?>
CIF: cliente_cif ?>cliente_pais ?>
+ +
+ + + + + + + + + + + + + precio_unidad > 0): ?> + + + + + + + + + + +
Tipo y Nombre del trabajoUds.PrecioIVASubtotal
+ descripcion); ?> + + cantidad > 0) ? $linea->cantidad : '' ?> + + cantidad > 0) ? $linea->precio_unidad : '' ?> + + cantidad > 0) ? $linea->iva : '' ?> + + cantidad > 0) ? $linea->base : '' ?> +
+
+ + +
+ +
+ Sello Solunion + +
+ + + + + + + + + + + + + + + + + + + + +
BASEIVATOTAL
base ?> €iva ?> %total_iva ?> €total ?> €
+ + + + + + +
TOTALtotal ?> €
+
+ + + + + + + + + + + + + + + + + + +
VencimientoFechaForma de pagoBIC / IBAN
dias_vencimiento ?> díasvencimiento ?>forma_pago ?> + forma_pago == "Transferencias") ? 'ES33 2100 1134 14 1300319844' : $factura->cliente_ccc ?> +
+ + + +
+ + diff --git a/httpdocs/themes/vuexy/css/pdf.factura.css b/httpdocs/themes/vuexy/css/pdf.factura.css new file mode 100644 index 00000000..c34cddfa --- /dev/null +++ b/httpdocs/themes/vuexy/css/pdf.factura.css @@ -0,0 +1,313 @@ +/* Facturas Safekat */ + +* { + box-sizing: border-box; +} + +body { + font-family: 'Open Sans', sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} + +table { + border-spacing: 0; + background-color: transparent; + border-collapse: collapse; +} + +th { + text-align: left; +} + +td { + padding: 0; +} + +body table.logo { + padding: 0; + width: 100%; + color: black; +} + +body table.logo td.logo img { + width: 100%; + vertical-align: middle; +} +/* Estilos intro-factura */ +body table.intro-factura { + width: 100%; + font-size: 12px; + margin-top: -22px; +} + +body table.intro-factura th { + background: black; + color: white; + padding: 7px; +} + +body table.intro-factura th.intro_num_factura { + width: 20%; + padding-left: 15px; +} + +body table.intro-factura th.num_factura { + width: 47%; + font-weight: lighter; + text-align: left; +} + +body table.intro-factura th.intro_fecha { + width: 17%; + text-align: right; +} + +body table.intro-factura th.fecha { + width: 15%; + text-align: right; + font-weight: lighter; +} + +body table.intro-factura td { + background: #e3e4e7; + padding-left: 15px; + color: black; + font-size: 12px; +} + +body table.intro-factura td.intro_direccion { + padding-top: 10px; + padding-right: 8px; + font-weight: bold; +} + +body table.intro-factura td.direccion { + padding-right: 8px; +} + +/* Estilos cuerpo factura */ +div.cuerpo-factura { + margin-bottom: 25px; +} + +table.factura-data-superior { + width: 100%; +} + +table.factura-data-superior th { + padding: 5px !important; + background: #0C2C84; + color: white; + padding-left: 10px; + font-weight: lighter; + font-size: 12px; + border-right: 1px solid white; +} + +table.factura-data-superior td { + border: 1px dotted #4e4e4e; + border-top: none; + padding: 5px !important; + text-align: right; + font-size: 11px; +} + +table.factura-data-superior td.tipo_trabajo { + border-left: none; + text-align: left; +} + +table.factura-data-superior td.subtotal { + border-right: none; +} + +/* Estilos para el sello de Solunion */ +.sello-solunion { + float: left; /* Hace que el sello flote a la izquierda */ + margin-left: 100px; /* Espacio entre el sello y la tabla */ +} + +.sello-solunion img { + display: block; /* Asegura que la imagen se comporte como un bloque dentro del div */ + width: 80px; /* Ajusta el tamaño de la imagen según sea necesario */ + height: auto; +} + +/* Contenedor para manejar el flujo de contenido */ +.container { + overflow: hidden; /* Asegura que el contenedor se ajuste al contenido flotante */ +} + +/* Estilos para la tabla de precios inferior */ +table.factura-precio-inferior { + width: 60%; /* Ajusta el ancho de la tabla al 100% del contenedor */ + text-align: right; + border-collapse: collapse; /* Asegura que los bordes se colapsen para evitar espacio extra */ + margin-bottom: 0; /* Elimina el margen inferior para evitar espacio extra */ +} + +table.factura-precio-inferior th, table.factura-precio-inferior td { + padding: 5px; + border-bottom: 1px dotted #4e4e4e; +} + +table.factura-precio-inferior th.intro_base, +table.factura-precio-inferior th.intro_iva, +table.factura-precio-inferior th.intro_total { + background: #0C2C84; + color: white; + font-size: 12px; +} + +table.factura-precio-inferior td.base, +table.factura-precio-inferior td.iva, +table.factura-precio-inferior td.value_iva, +table.factura-precio-inferior td.total { + font-size: 11px; +} + +/* Estilos para la tabla de totales */ +table.totales { + width: 28%; /* Ajusta el ancho de la tabla según sea necesario */ + background: #0C2C84; + color: white; + font-size: 12px; + border-collapse: collapse; /* Asegura que los bordes se colapsen para evitar espacio extra */ + margin-top: 0; /* Elimina el margen superior para evitar espacio extra */ + margin-bottom: 0; /* Elimina el margen inferior para evitar espacio extra */ +} + +table.totales td.intro_total_factura { + width: 20%; + text-align: right; + padding: 5px; +} + +table.totales td.total_factura { + width: 15%; + text-align: right; + padding-right: 10px; +} + + +/* Estilos factura-data-inferior-iva */ +table.factura-data-inferior-iva { + width: 100%; + margin-top: 8px; +} + +table.factura-data-inferior-iva th { + padding: 5px !important; + background: rgb(233, 240, 255); + font-weight: lighter; + font-size: 12px; + padding-left: 7px; + color: black; + border-right: 1px solid white; +} + +table.factura-data-inferior-iva th.intro_vencimiento, +table.factura-data-inferior-iva th.inferior_intro_fecha { + width: 15%; +} + +table.factura-data-inferior-iva th.intro_forma_pago { + width: 20%; +} + +table.factura-data-inferior-iva th.intro_bic { + width: 50%; +} + +table.factura-data-inferior-iva td { + border-bottom: 1px dotted #4e4e4e; + border-top: none; + padding-left: 8px; + padding: 3px !important; + font-size: 11px; +} + +table.factura-data-inferior-iva td.vencimiento, +table.factura-data-inferior-iva td.inferior_fecha, +table.factura-data-inferior-iva td.forma_pago { + border-right: 1px dotted black; +} + +/* Estilos factura-precio-inferior */ +table.factura-data-inferior { + width: 100%; + background: #e3e4e7; + font-size: 12px; + margin-top: 5px; +} + +table.factura-data-inferior th { + padding-top: 2px; + font-weight: lighter; +} + +table.factura-data-inferior th.intro_vencimiento, +table.factura-data-inferior th.intro_base, +table.factura-data-inferior th.base { + padding-top: 8px; +} + +table.factura-data-inferior th.intro_vencimiento, +table.factura-data-inferior th.inferior_intro_fecha, +table.factura-data-inferior th.intro_forma_pago, +table.factura-data-inferior th.intro_bic { + font-weight: bold; + padding-left: 10px; +} + +table.factura-data-inferior th.intro_base, +table.factura-data-inferior th.intro_value_iva, +table.factura-data-inferior th.intro_iva, +table.factura-data-inferior th.intro_total { + color: #0C2C84; + text-align: right; + padding-right: 5px; +} + +table.factura-data-inferior th.base, +table.factura-data-inferior th.iva, +table.factura-data-inferior th.value_iva, +table.factura-data-inferior th.total { + border-left: 1px dashed grey; + text-align: right; + padding-right: 10px; + width: 15%; +} + +table.factura-data-inferior th.intro_bic, +table.factura-data-inferior th.intro_total, +table.factura-data-inferior th.total { + padding-bottom: 8px; +} + +/* Estilos para el pie de página */ +.footer { + width: 95%; + position: fixed; /* Fija el pie de página en la parte inferior */ + bottom: 15px; /* Coloca el pie de página en la parte inferior de la página */ +} + +/* Estilos pie */ +div.pie { + font-family: sans-serif; + font-size: 7px; + margin: 5mm 0 5mm 0; +} + +/* Estilos pie-pagina */ +table.pie-pagina { + font-family: sans-serif; + color: #0C2C84; + float: left; + vertical-align: bottom; + font-size: 10px; + font-weight: bold; +} \ No newline at end of file From 1170852209544fed4dfe48770d442c068dc5a2f7 Mon Sep 17 00:00:00 2001 From: imnavajas Date: Fri, 16 Aug 2024 16:01:43 +0200 Subject: [PATCH 06/42] Fix bug del id de factura --- ci4/app/Models/Facturas/FacturaLineaModel.php | 10 ++-------- ci4/app/Models/Facturas/FacturaModel.php | 1 + 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/ci4/app/Models/Facturas/FacturaLineaModel.php b/ci4/app/Models/Facturas/FacturaLineaModel.php index b1bd1d9f..539ee3fd 100644 --- a/ci4/app/Models/Facturas/FacturaLineaModel.php +++ b/ci4/app/Models/Facturas/FacturaLineaModel.php @@ -66,6 +66,7 @@ class FacturaLineaModel extends \App\Models\BaseModel { ROUND(SUM(t1.total), 2) AS total" ) ->where("t1.factura_id", $factura_id) + ->where("t1.deleted_at", null) ->groupBy('t1.iva') ->orderBy('t1.iva', 'ASC'); // Ordena por iva en forma ascendente @@ -88,15 +89,8 @@ class FacturaLineaModel extends \App\Models\BaseModel { "t1.id AS id, t1.factura_id AS factura_id, t1.pedido_linea_impresion_id AS pedido_linea_impresion_id, t1.pedido_maquetacion_id AS pedido_maquetacion_id, t1.descripcion AS descripcion, t1.cantidad as cantidad, t1.precio_unidad AS precio_unidad, t1.iva AS iva, - t1.base AS base, t1.total_iva AS total_iva, t1.total AS total, t1.data AS data, t2.pedido_id AS pedido_id, - t3.total_aceptado AS total_aceptado, t4.tirada_flexible AS tirada_flexible, t4.descuento_tirada_flexible AS descuento_tirada_flexible, - t6.cantidad AS cantidad_albaran" + t1.base AS base, t1.total_iva AS total_iva, t1.total AS total, t1.data AS data" ) - ->join("pedidos_linea t2", "t2.id = t1.pedido_linea_impresion_id", "left") - ->join("presupuestos t3", "t3.id = t2.presupuesto_id", "left") - ->join("clientes t4", "t4.id = t3.cliente_id", "left") - ->join("albaranes t5", "t5.pedido_id = t2.pedido_id", "left") - ->join("albaranes_lineas t6", "t6.albaran_id = t5.id", "left") ->where("t1.factura_id", $factura_id) ->where("t1.deleted_at", null); diff --git a/ci4/app/Models/Facturas/FacturaModel.php b/ci4/app/Models/Facturas/FacturaModel.php index aeb8e46c..f79d5044 100644 --- a/ci4/app/Models/Facturas/FacturaModel.php +++ b/ci4/app/Models/Facturas/FacturaModel.php @@ -129,6 +129,7 @@ class FacturaModel extends \App\Models\BaseModel { $builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left"); $builder->join("lg_paises t5", "t2.pais_id = t5.id", "left"); + $builder->where("t1.id", $factura_id); $builder->where("t1.deleted_at IS NULL"); $builder->groupBy("t1.id"); // Agrupa por id de la factura From d8eefcf1b75ff44f6b6f6d8dce8f57847d81c4f5 Mon Sep 17 00:00:00 2001 From: imnavajas Date: Sat, 17 Aug 2024 18:37:13 +0200 Subject: [PATCH 07/42] Implementados botones de imprimir factura y exportar lineas pedido --- ci4/app/Config/Routes.php | 8 +++ ci4/app/Controllers/Excel/PrintLineas.php | 70 +++++++++++++++++++ ci4/app/Models/Facturas/FacturaLineaModel.php | 26 +++++++ .../form/facturas/_facturaCabeceraItems.php | 18 ++--- .../vuexy/form/facturas/viewFacturaForm.php | 22 ++++-- 5 files changed, 128 insertions(+), 16 deletions(-) create mode 100644 ci4/app/Controllers/Excel/PrintLineas.php diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 41530954..1425d588 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -717,6 +717,14 @@ $routes->group( } ); +$routes->group( + 'export-lineas', + ['namespace' => 'App\Controllers\Excel'], + function ($routes) { + $routes->get('generar/(:num)', 'PrintLineas::generateExcel/$1', ['as' => 'lineasToExcel']); + } +); + $routes->group( 'buscadorpresupuestos', ['namespace' => 'App\Controllers\Presupuestos'], diff --git a/ci4/app/Controllers/Excel/PrintLineas.php b/ci4/app/Controllers/Excel/PrintLineas.php new file mode 100644 index 00000000..729c79ff --- /dev/null +++ b/ci4/app/Controllers/Excel/PrintLineas.php @@ -0,0 +1,70 @@ +getResourceForExcel($factura_id)->get()->getResultObject(); + + + // Crear un nuevo Spreadsheet + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + + // Especificar encabezados + $headers = [ + 'Factura', + 'ID Pedido', + 'Ref. Cliente', + 'Base' + ]; + + // Establecer los encabezados en la primera fila + $column = 'A'; + foreach ($headers as $header) { + $sheet->setCellValue($column . '1', $header); + $column++; + } + + // Rellenar las filas con datos + $rowNumber = 2; // Empezar en la segunda fila + foreach ($infoLineasFactura as $infoLineaFactura) { + $column = 'A'; + foreach ($infoLineaFactura as $cell) { + $sheet->setCellValue($column . $rowNumber, $cell); + $column++; + } + $rowNumber++; + } + + // Ajustar automáticamente el tamaño de las columnas + foreach (range('A', $column) as $col) { + $sheet->getColumnDimension($col)->setAutoSize(true); + } + + // Crear un escritor para guardar el archivo + $writer = new Xlsx($spreadsheet); + + // Configurar la respuesta para descarga + $fileName = 'lineas-pedido.xlsx'; + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + header('Content-Disposition: attachment;filename="' . $fileName . '"'); + header('Cache-Control: max-age=0'); + + // Escribir el archivo a la salida + $writer->save('php://output'); + exit; + + } + +} \ No newline at end of file diff --git a/ci4/app/Models/Facturas/FacturaLineaModel.php b/ci4/app/Models/Facturas/FacturaLineaModel.php index 539ee3fd..2abb52e2 100644 --- a/ci4/app/Models/Facturas/FacturaLineaModel.php +++ b/ci4/app/Models/Facturas/FacturaLineaModel.php @@ -97,6 +97,32 @@ class FacturaLineaModel extends \App\Models\BaseModel { return $builder; } + /** + * Get resource data for creating PDFs. + * + * @param string $search + * + * @return \CodeIgniter\Database\BaseBuilder + */ + public function getResourceForExcel($factura_id = -1) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t2.numero AS ref_factura, + t3.pedido_id AS pedido_id, + t4.referencia_cliente AS referencia_cliente, + t1.base AS base" + ) + ->join("facturas t2", "t2.id = t1.factura_id", "left") + ->join("pedidos_linea t3", "t3.id = t1.pedido_linea_impresion_id", "left") + ->join("presupuestos t4", "t4.id = t3.presupuesto_id", "left") + ->where("t1.factura_id", $factura_id) + ->where("t1.deleted_at", null); + + return $builder; + } + public function addFacturaPedidoLinea($factura_id, $pedido_linea_id, $cantidad) { diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php index 4bba5e7f..06227a6f 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php @@ -191,15 +191,15 @@ - - + + id), + '' . + lang("Facturas.exportarLineas"), + [ + "class" => "btn btn-label-primary float-start me-sm-3 me-1", + ] + ) ?> '. $validation . - ''; - } -} - -function sweetAlert() -{ - try { - $session = session(); - $alert = $session->getFlashdata('sweet'); - if (count((array)$alert) == 2){ - return ""; - } - if (count((array)$alert) == 4){ - return ""; - } - }catch (Exception $ex){ - } -} - -function toastAlert() -{ - try { - $session = session(); - $alert = $session->getFlashdata('toast'); - if (count((array)$alert) == 3) { - return ""; - } - }catch (Exception $ex){ - } -} - -//////////////////////////////////////////////////// -/// Security -//////////////////////////////////////////////////// - -function generatePassword($length = 8) { - $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_!@#$%&*()-+{[]}'; - $count = mb_strlen($chars); - for ($i = 0, $result = ''; $i < $length; $i++) { - $index = Rand(0, $count - 1); - $result .= mb_substr($chars, $index, 1); - } - return $result; -} - -//////////////////////////////////////////////////// -/// Others -//////////////////////////////////////////////////// - -function now_db() { - $unixdatetime = time(); - return strftime("%Y-%m-%d %H:%M:%S", $unixdatetime); -} - -function escape_value($value='') { - $value = strip_tags(htmlentities($value)); - return filter_var($value, FILTER_SANITIZE_STRING); -} - -function escape_only($value='') { - $value = strip_tags(htmlentities($value), '

'); - return filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS); -} - -function unescape($value='') { - //return html_entity_decode($value,null,'UTF-8');; - return html_entity_decode($value,ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,'UTF-8'); -} - -function redirect_to( $location = NULL ) { - if ($location != NULL) { - header("Location: {$location}"); - exit; - } -} - -function momentDateJS() { - $format = session()->get('settings')['default_date_format']; - switch ($format) { - case "Y-m-d": - return "YYYY-MM-DD"; - case "d-m-Y": - return "DD-MM-YYYY"; - case "d/m/Y": - return "DD/MM/YYYY"; - case "m-d-Y": - return "MM-DD-YYYY"; - case "m/d/Y": - return "MM/DD/YYYY"; - default: - return ""; - } -} - -function momentDateTimeJS() { - $format = session()->get('settings')['default_date_format']; - switch ($format) { - case "Y-m-d": - return "YYYY-MM-DD HH:mm:ss"; - case "d-m-Y": - return "DD-MM-YYYY HH:mm:ss"; - case "d/m/Y": - return "DD/MM/YYYY HH:mm:ss"; - case "m-d-Y": - return "MM-DD-YYYY HH:mm:ss"; - case "m/d/Y": - return "MM/DD/YYYY HH:mm:ss"; - default: - return ""; - } -} - -function dateFormatWeb($date) { - $format = session()->get('settings')['default_date_format']; - switch ($format) { - case "Y-m-d": - return $date; - case "d-m-Y": - case "d/m/Y": - case "m-d-Y": - case "m/d/Y": - $phpDate = strtotime($date); - if(strlen($date) > 10){ - return date( $format.' H:i:s', $phpDate); - }else{ - return date( $format, $phpDate); - } - default: - return null; - } -} - -function dateFormatMysql($date) { - $format = session()->get('settings')['default_date_format']; - switch ($format) { - case "Y-m-d": - return $date; - case "d-m-Y": - $dateTimeSplit = explode(' ',$date); - $dateSplit = explode('-',$dateTimeSplit[0]); - if(count($dateTimeSplit) > 1){ - return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0].' '. $dateTimeSplit[1]; - }else{ - return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0]; - } - case "d/m/Y": - $dateTimeSplit = explode(' ',$date); - $dateSplit = explode('/',$dateTimeSplit[0]); - if(count($dateTimeSplit) > 1){ - return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0].' '. $dateTimeSplit[1]; - }else{ - return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0]; - } - case "m-d-Y": - $dateTimeSplit = explode(' ',$date); - $dateSplit = explode('-',$dateTimeSplit[0]); - if(count($dateTimeSplit) > 1){ - return $dateSplit[2].'-'.$dateSplit[0].'-'.$dateSplit[1].' '. $dateTimeSplit[1]; - }else{ - return $dateSplit[2].'-'.$dateSplit[0].'-'.$dateSplit[1]; - } - case "m/d/Y": - $dateTimeSplit = explode(' ',$date); - $dateSplit = explode('/',$dateTimeSplit[0]); - if(count($dateTimeSplit) > 1){ - return $dateSplit[2].'-'.$dateSplit[0].'-'.$dateSplit[1].' '. $dateTimeSplit[1]; - }else { - return $dateSplit[2] . '-' . $dateSplit[0] . '-' . $dateSplit[1]; - } - default: - return null; - } -} - -function langJS() { - $lang = session()->get('lang')??'en'; - switch ($lang) { - case "pt": - return "pt-br"; - default: - return $lang; - } -} - -function socialBG() { - return [ - "facebook" => "bg-facebook", - "linkedin" => "bg-linkedin", - "google" => "bg-google-plus", - "youtube" => "bg-youtube", - "twitter" => "bg-twitter", - "instagram" => "bg-instagram", - "tiktok" => "bg-tiktok", - "whatsapp" => "bg-whatsapp", - "website" => "bg-website", - "api" => "bg-api", - "github" => "bg-github", - "slack" => "bg-slack", - "spotify" => "btn-spotify", - "reddit" => "btn-reddit", - "discord" => "btn-discord", - "dribbble" => "btn-dribbble", - "dropbox" => "btn-dropbox", - "gitlab" => "btn-gitlab", - "tumblr" => "btn-tumblr", - "strava" => "btn-strava", - "twitch" => "btn-twitch", - "vkontakte" => "btn-vk", - "wordpress" => "btn-wordpress", - "yahoo" => "btn-yahoo", - "bitbucket" => "btn-bitbucket", - "wechat" => "btn-wechat", - ]; -} -function keywordEmail() { - return [ - 'user_first_name', - 'user_last_name', - 'user_date_birth', - 'user_address', - 'user_city', - 'user_state', - 'user_country', - 'user_zip_code', - 'user_mobile', - 'user_email', - 'user_picture' - ]; -} - -function templateSelect($templates=[],$name='',$type='') { - foreach ($templates as $item){ - if($item['type'] == $type){ - if($item['name'] == $name){ - return $item; - } - } - } - return null; -} - -function get_filter_datatables_columns($request){ - $columnSearch = array(); - - if ( isset( $request['columns'] ) ) { - for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) { - $requestColumn = $request['columns'][$i]; - - $str = $requestColumn['search']['value']; - - if ( $requestColumn['searchable'] == 'true' && - $str != '' ) { - array_push($columnSearch, [$i, $requestColumn['data'], $str]); - } - } - } - - return $columnSearch; -} - -// Devuelve true si los intervalos (a1,a2) (b1,b2) se solapan -// https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap -function check_overlap($a1, $a2, $b1, $b2){ - - if (max($a2, $b2) - min($a1, $b1) <= ($a2 - $a1) + ($b2 - $b1)) - return true; - return false; -} - -function check_overlap_with_extremos($a1, $a2, $b1, $b2){ - - if (max($a2, $b2) - min($a1, $b1) < ($a2 - $a1) + ($b2 - $b1)) - return true; - return false; -} - -function version() { - return "1.2.1"; -} \ No newline at end of file diff --git a/ci4/app/Services/FTPService.php b/ci4/app/Services/FTPService.php new file mode 100644 index 00000000..fa4650cc --- /dev/null +++ b/ci4/app/Services/FTPService.php @@ -0,0 +1,48 @@ +ftp = new FtpClient(); + $this->ftp_config = config("FTP"); + $this->host = $this->ftp_config->host; + $this->username = $this->ftp_config->username; + $this->password = $this->ftp_config->password; + $this->base_dir = $this->ftp_config->base_dir; + } + /** + * Upload the content of $filename to the base directory declared in App\Config\FTP.php + * + * @param string $content + * @param string $filename + * @return boolean + */ + public function uploadXML(string $content, string $filename): bool + { + try { + $remotePath = implode("/", [$this->base_dir, $filename]); + $this->ftp->connect(host: $this->host, port: $this->port); + $this->ftp->login(username: $this->username, password: $this->password); + $this->ftp->putFromString($remotePath, $content); + return true; + } catch (\Throwable $th) { + log_message('error',$th->getMessage()); + return false; + } + } +} diff --git a/ci4/app/Services/PedidoXMLService.php b/ci4/app/Services/PedidoXMLService.php index b09edaa1..3ece7f7c 100644 --- a/ci4/app/Services/PedidoXMLService.php +++ b/ci4/app/Services/PedidoXMLService.php @@ -9,6 +9,7 @@ use App\Models\Pedidos\PedidoLineaModel; use App\Models\Presupuestos\PresupuestoModel; use DOMDocument; use DOMNode; +use FTP; class PedidoXMLService extends BaseService { @@ -168,8 +169,15 @@ class PedidoXMLService extends BaseService $xml_products_el->appendChild($xml->createElement('CommentsClient', $data["pedido_cliente_presupuesto"]->comentarios_cliente)); $xml->appendChild($xml_products_el); $file_has_suffix = hash('sha512',$data["pedido_cliente_presupuesto"]->pedidoId); + $file_name = PedidoXMLService::generate_xml_file_name($file_has_suffix); + $ftp = service('FTPService'); + $ftp->uploadXML($xml->textContent,$file_name); return $data; } + protected static function generate_xml_file_name(string $hash) : string + { + return implode("",["Safekat_",$hash,".xml"]); + } protected static function get_color_interior($pre_linea): ?string { $color_interior = null; From eb4ea31cefdf8186378263fc5ffbfe498cd7afc2 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Wed, 28 Aug 2024 22:28:49 +0200 Subject: [PATCH 18/42] add php ftp lib --- ci4/composer.json | 3 ++- ci4/composer.lock | 54 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/ci4/composer.json b/ci4/composer.json index 8fe6ffc5..1b6032ae 100755 --- a/ci4/composer.json +++ b/ci4/composer.json @@ -13,7 +13,8 @@ "php": "^8.2", "codeigniter4/framework": "^4.0", "codeigniter4/shield": "^1.0", - "dompdf/dompdf": "^2.0" + "dompdf/dompdf": "^2.0", + "nicolab/php-ftp-client": "^2.0" }, "require-dev": { "fakerphp/faker": "^1.9", diff --git a/ci4/composer.lock b/ci4/composer.lock index 4596b329..72107154 100644 --- a/ci4/composer.lock +++ b/ci4/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b2eee64c89c81ed0f0edef73637b9199", + "content-hash": "ad46e8d1c155c881b11c8b8054611788", "packages": [ { "name": "codeigniter4/framework", @@ -399,6 +399,58 @@ }, "time": "2024-03-31T07:05:07+00:00" }, + { + "name": "nicolab/php-ftp-client", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/Nicolab/php-ftp-client.git", + "reference": "a1d007c8b203895611f68b0da314281d4a5c3d49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nicolab/php-ftp-client/zipball/a1d007c8b203895611f68b0da314281d4a5c3d49", + "reference": "a1d007c8b203895611f68b0da314281d4a5c3d49", + "shasum": "" + }, + "require": { + "ext-ftp": "*", + "php": ">=5.4" + }, + "type": "library", + "autoload": { + "psr-0": { + "FtpClient": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Tallefourtane", + "email": "dev@nicolab.net", + "homepage": "http://nicolab.net" + } + ], + "description": "A flexible FTP and SSL-FTP client for PHP. This lib provides helpers easy to use to manage the remote files.", + "homepage": "https://github.com/Nicolab/php-ftp-client", + "keywords": [ + "file", + "ftp", + "helper", + "lib", + "server", + "sftp", + "ssl", + "ssl-ftp" + ], + "support": { + "source": "https://github.com/Nicolab/php-ftp-client/tree/v2.0.2" + }, + "time": "2022-08-10T11:09:32+00:00" + }, { "name": "phenx/php-font-lib", "version": "0.5.6", From 251268fb246999751f5948bcb5ca4f5652f319bf Mon Sep 17 00:00:00 2001 From: amazuecos Date: Thu, 29 Aug 2024 01:02:15 +0200 Subject: [PATCH 19/42] add Libraries path --- ci4/app/Config/Autoload.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ci4/app/Config/Autoload.php b/ci4/app/Config/Autoload.php index dbe37194..acc365fc 100755 --- a/ci4/app/Config/Autoload.php +++ b/ci4/app/Config/Autoload.php @@ -46,6 +46,7 @@ class Autoload extends AutoloadConfig public $psr4 = [ APP_NAMESPACE => APPPATH, // For custom app namespace 'Config' => APPPATH . 'Config', + 'Libraries' => APPPATH . 'Libraries', 'Dompdf' => APPPATH . 'ThirdParty/dompdf/src', ]; From c3248cd3ec7ed46c16faff8215fc0bd551310812 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Thu, 29 Aug 2024 01:02:33 +0200 Subject: [PATCH 20/42] add FTP Config file --- ci4/app/Config/FTP.php | 50 +++++------------------------------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/ci4/app/Config/FTP.php b/ci4/app/Config/FTP.php index f3faf0a0..d3b963f1 100644 --- a/ci4/app/Config/FTP.php +++ b/ci4/app/Config/FTP.php @@ -6,53 +6,13 @@ use CodeIgniter\Config\BaseConfig; class FTP extends BaseConfig { - /** - * Lets you choose which connection group to - * use if no other is specified. - */ - public string $defaultGroup = 'default'; - /** - * The default ftp connection. - */ - public array $default = [ - "host" => "sk-ftp", - "user" => "admin", - "password" => "A77h3b0X4OA2rOYAf4w2", - "base_dir" => "/home/admin/safekat" # FTP server directory - ]; - /** - * This database connection is used when - * running PHPUnit database tests. - */ - public array $production = [ - "host" => "sk-ftp", - "user" => "admin", - "password" => "A77h3b0X4OA2rOYAf4w2", - "base_dir" => "/home/admin/safekat" # FTP server directory - ]; - /** - * This database connection is used when - * running PHPUnit database tests. - */ - public array $development = [ - "host" => "sk-ftp", - "port" => "21000", - "user" => "admin", - "password" => "A77h3b0X4OA2rOYAf4w2", - "base_dir" => "/home/admin/safekat" # FTP server directory + public string $host = "10.5.0.6"; + public int $port = 21; + public string $username = "admin"; + public string $password = "A77h3b0X4OA2rOYAf4w2"; + public string $base_dir = "/home/admin/safekat"; # FTP server directory - ]; - public function __construct() - { - parent::__construct(); - // Ensure that we always set the database group to 'tests' if - // we are currently running an automated test suite, so that - // we don't overwrite live data on accident. - if (ENVIRONMENT === 'development') { - $this->defaultGroup = 'development'; - } - } } From 01cc74ed60293d526ca11b009daa40f7eb71a402 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Thu, 29 Aug 2024 01:03:00 +0200 Subject: [PATCH 21/42] delete ftp method --- ci4/app/Config/Services.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ci4/app/Config/Services.php b/ci4/app/Config/Services.php index 572aec46..a802b838 100755 --- a/ci4/app/Config/Services.php +++ b/ci4/app/Config/Services.php @@ -30,11 +30,4 @@ class Services extends BaseService * return new \CodeIgniter\Example(); * } */ - public static function ftp(bool $getShared = true): FTPService - { - if ($getShared) { - return static::getSharedInstance('ftp'); - } - return new FTPService(); - } } From 8e5d208bbf9b50ff97787a809ba5059cfc6dcdec Mon Sep 17 00:00:00 2001 From: amazuecos Date: Thu, 29 Aug 2024 01:03:29 +0200 Subject: [PATCH 22/42] add general_helper, deleted by error --- ci4/app/Helpers/general_helper.php | 683 +++++++++++++++++++++++++++++ 1 file changed, 683 insertions(+) create mode 100644 ci4/app/Helpers/general_helper.php diff --git a/ci4/app/Helpers/general_helper.php b/ci4/app/Helpers/general_helper.php new file mode 100644 index 00000000..e0578134 --- /dev/null +++ b/ci4/app/Helpers/general_helper.php @@ -0,0 +1,683 @@ +$value){ + if($key==$section){ + foreach($value as $item){ + if($item==$method){ + return true; + } + } + } + } + return false; + + /*var_dump($key. ' '. $value[0]); + + echo '

';
+        $rules = 
+        echo '
'; + dd();*/ +} + +function getAllClass($controller = null){ + try { + helper('filesystem'); + helper('directory'); + if(strtolower(PHP_OS) == 'linux'){ + $compatibility = '/'; + }else{ + $compatibility = '\\'; + } + if(empty($controller)){ + $map = directory_map(APPPATH.'Controllers'); + foreach ($map as $key=>$item) + { + if(!strpos(strtolower($key),$compatibility)){ + $name = str_replace('.php', '', $item); + if(!getIgnoreController($name)){ + $controllers[] = [ + 'name' => $name, + 'path' => '', + 'methods' => get_class_methods('App\Controllers\\'.$name) + ]; + } + }else{ + foreach ($item as $subitem){ + $name = str_replace('.php', '', $subitem); + if(!getIgnoreController($name)) { + $controllers[] = [ + 'name' => $name, + 'path' => $key, + 'methods' => get_class_methods('App\Controllers\\' . str_replace('/', '\\', $key) . $name) + ]; + } + } + } + } + }else{ + $array = explode('/',$controller); + $dir = count($array) > 1 ? $array[0] : ''; + $name = count($array) > 1 ? '\\'.$array[1] : $array[0]; + $controllers[] = [ + 'name' => $name, + 'path' => $dir, + 'methods' => get_class_methods('App\Controllers\\'.str_replace('/','\\',$dir).$name) + ]; + } + return $controllers??[]; + } catch (Exception $e) { + return []; + } +} + + +// IMN +function getCurrentLanguageFlag(){ + try { + $session = session(); + + if($session->get('lang') == 'en'){ + return "fi-gb"; + }else{ + return "fi-es"; + } + } catch (Exception $e) { + return "fi-es"; + } +} + + +function getAllClassFolder($folder = null){ + try { + helper('filesystem'); + helper('directory'); + + if(!empty($folder)){ + $map = directory_map(APPPATH.'Controllers'); + foreach ($map as $key=>$item) + { + if(strtolower(PHP_OS) == 'linux'){ + $compatibility = '/'; + }else{ + $compatibility = '\\'; + } + if(str_replace($compatibility,'',strtolower($key)) == strtolower($folder)){ + foreach ($item as $subitem){ + $name = str_replace('.php', '', $subitem); + $controllers[] = [ + 'name' => $name, + 'path' => $key, + 'methods' => get_class_methods('App\Controllers\\'.str_replace('/','\\',$key).$name) + ]; + } + } + } + } + return $controllers??[]; + } catch (Exception $e) { + return []; + } +} + +function getAllFolder(){ + try { + helper('filesystem'); + helper('directory'); + $map = directory_map(APPPATH.'Controllers',1); + if(strtolower(PHP_OS) == 'linux'){ + $compatibility = '/'; + }else{ + $compatibility = '\\'; + } + foreach ($map as $item) { + if(strpos(strtolower($item),$compatibility)){ + $folders[] = str_replace($compatibility,"",$item); + } + } + return $folders??[]; + } catch (Exception $e) { + return []; + } +} + + + +function getIgnoreController($controller) +{ + try { + $loginAuthFilter = new \App\Filters\LoginAuthFilter(); + foreach ($loginAuthFilter->whiteListController() as $item){ + if($controller == $item){ + return true; + } + } + return false; + } catch (Exception $e) { + return []; + } +} + +function getIgnoreMethod($method) +{ + try { + $loginAuthFilter = new \App\Filters\LoginAuthFilter(); + foreach ($loginAuthFilter->whiteListMethod() as $item){ + if($method == $item){ + return true; + } + } + return false; + } catch (Exception $e) { + return []; + } +} + +function getDictionary($word=''){ + try { + $dictionary = [ + 'index' => lang("App.permisos_index"), + 'view' => lang("App.permisos_view"), + 'add' => lang("App.permisos_add"), + 'edit' => lang("App.permisos_editar"), + 'delete' => lang("App.permisos_del"), + 'store' => lang("App.permisos_save"), + 'import' => lang("App.permisos_import"), + 'export' => lang("App.permisos_export"), + + 'Profile' => lang("App.permisos_perfil"), + 'Activity' => lang("App.permisos_actividad"), + 'Settings' => lang("App.permisos_configuracion"), + 'my' => lang("App.permisos_my"), + 'Notification' => lang("App.permisos_notificacion"), + + 'Users' => lang("App.permisos_usuarios"), + 'User' => lang("App.permisos_usuario"), + 'Group' => lang("App.permisos_roles"), + + 'Logistica' => lang("App.permisos_logistica"), + + 'Tarifas' => lang("App.permisos_tarifas"), + 'Tarifapreimpresion' => lang("App.permisos_tarifapreimpresion"), + 'Tarifamanipulado' => lang("App.permisos_tarifamanipulado"), + 'Tarifapapelcompra' => lang("App.permisos_tarifapapelcompra"), + 'Tarifaacabado' => lang("App.permisos_tarifaacabado"), + 'Tarifapapeldefecto' => lang("App.permisos_tarifapapeldefecto"), + 'Tarifaenvio' => lang("App.permisos_tarifaenvio"), + 'Tarifaimpresion' => lang("App.permisos_tarifaimpresion"), + + 'Configuracion' => lang("App.permisos_configuracion"), + 'Tareaservicio' => lang("App.permisos_tareasservicio"), + 'Formaspago' => lang("App.permisos_formaspago"), + 'Papelgenerico' => lang("App.permisos_papelgenerico"), + 'Tiposimpresion' => lang("App.permisos_tiposimpresion"), + 'Trabajo' => lang("App.permisos_trabajo"), + 'Maquina' => lang("App.permisos_maquina"), + 'Tamaniolibros' => lang("App.permisos_tamaniolibros"), + 'Imposiciones' => lang("App.permisos_imposiciones"), + 'Seriefactura' => lang("App.permisos_seriefactura"), + 'Tamanioformatos' => lang("App.permisos_tamanioformatos"), + 'Serviciocliente' => lang("App.permisos_serviciocliente"), + 'Calendario' => lang("App.permisos_calendario"), + 'Correo' => lang("App.permisos_correo"), + 'Paises' => lang("App.permisos_paises"), + 'Tipologias' => lang("App.permisos_tipologias"), + + 'Presupuestos' => lang("App.permisos_presupuestos"), + 'Presupuesto' => lang("App.permisos_presupuestos"), + 'Presupuestomaquetacion' => lang("App.permisos_presupuestomaquetacion"), + + 'Catalogo' => lang("App.permisos_catalogo"), + + 'Cliente' => lang("App.permisos_clientes"), + 'Tarifacliente' => lang("App.permisos_tarifacliente"), + + 'Proveedores' => lang("App.permisos_proveedores"), + 'Proveedor' => lang("App.permisos_proveedores"), + + 'Informes' => lang("App.permisos_informes"), + 'Informe' => lang("App.permisos_informes"), + + 'Facturacion' => lang("App.permisos_facturación"), + 'Albaran' => lang("App.permisos_albaran"), + 'Factura' => lang("App.permisos_facturas"), + + 'Pedidos' => lang("App.permisos_pedidos"), + 'Pedido' => lang("App.permisos_pedidos"), + + 'Serviciosdigitalizacion' => lang("App.permisos_digitalización"), + 'Digitalizacion' => lang("App.permisos_digitalización"), + + 'Produccion' => lang("App.permisos_produccion"), + 'Ordentrabajomaquetacion' => lang("App.permisos_ordentrabajomaquetacion"), + 'Ordenmaquina' => lang("App.permisos_ordenmaquina"), + 'Pedidoproduccion' => lang("App.permisos_pedidoproduccion"), + 'Ordentrabajo' => lang("App.permisos_ordentrabajo"), + + 'oauth' => lang("App.group_rules_label_oauth"), + 'template' => lang("App.group_rules_label_template"), + 'all' => lang("App.group_rules_label_all"), + 'oauth_store' => lang("App.group_rules_label_oauth_store"), + 'template_store' => lang("App.group_rules_label_template_store"), + + ]; + return array_key_exists($word,$dictionary)?$dictionary[$word] : $word; + } catch (Exception $e) { + return ''; + } +} + +function getMenuControl(){ + try { + $getClass = getAllClass(); + $getRules = json_decode(session()->get('rules')??'[]'); + foreach ($getClass as $item){ + foreach ($getRules as $key=>$value){ + if($key == $item['name']){ + $item['methods'] = $value; + $data[] = $item; + } + } + } + return $data??[]; + } catch (Exception $e) { + session()->setFlashdata('alert', 'error_acesso'); + return []; + } +} + +function allowMenuSection(array $array, array $keys, $method){ + try{ + $value = false; + foreach($keys as $key){ + if (count($temp=getArrayItem($array,'name',$key)) > 0){ + if (count(getArrayItem($temp,'methods','index',true)) > 0){ + $value = true; + } + } + } + return $value; + + } catch (Exception $e) { + return []; + } +} + +function getArrayItem(array $array, $key, $word, $isArray=false) +{ + try { + foreach ($array as $item){ + if ($isArray){ + foreach ($item[$key] as $subitem){ + if($subitem == $word){ + $data[]=$subitem; + } + } + }else{ + if($item[$key] == $word){ + $data[]=$item; + } + } + } + return $data??[]; + } catch (Exception $e) { + return []; + } +} + +//////////////////////////////////////////////////// +/// Notification Messages +//////////////////////////////////////////////////// + +function formAlert() +{ + $session = session(); + $alert = $session->getFlashdata('error'); + $validation = \Config\Services::validation()->listErrors(); + if (!empty($alert)){ + return '
'. + ' '. $validation . + '
'; + } +} + +function sweetAlert() +{ + try { + $session = session(); + $alert = $session->getFlashdata('sweet'); + if (count((array)$alert) == 2){ + return ""; + } + if (count((array)$alert) == 4){ + return ""; + } + }catch (Exception $ex){ + } +} + +function toastAlert() +{ + try { + $session = session(); + $alert = $session->getFlashdata('toast'); + if (count((array)$alert) == 3) { + return ""; + } + }catch (Exception $ex){ + } +} + +//////////////////////////////////////////////////// +/// Security +//////////////////////////////////////////////////// + +function generatePassword($length = 8) { + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_!@#$%&*()-+{[]}'; + $count = mb_strlen($chars); + for ($i = 0, $result = ''; $i < $length; $i++) { + $index = Rand(0, $count - 1); + $result .= mb_substr($chars, $index, 1); + } + return $result; +} + +//////////////////////////////////////////////////// +/// Others +//////////////////////////////////////////////////// + +function now_db() { + $unixdatetime = time(); + return strftime("%Y-%m-%d %H:%M:%S", $unixdatetime); +} + +function escape_value($value='') { + $value = strip_tags(htmlentities($value)); + return filter_var($value, FILTER_SANITIZE_STRING); +} + +function escape_only($value='') { + $value = strip_tags(htmlentities($value), '

'); + return filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS); +} + +function unescape($value='') { + //return html_entity_decode($value,null,'UTF-8');; + return html_entity_decode($value,ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,'UTF-8'); +} + +function redirect_to( $location = NULL ) { + if ($location != NULL) { + header("Location: {$location}"); + exit; + } +} + +function momentDateJS() { + $format = session()->get('settings')['default_date_format']; + switch ($format) { + case "Y-m-d": + return "YYYY-MM-DD"; + case "d-m-Y": + return "DD-MM-YYYY"; + case "d/m/Y": + return "DD/MM/YYYY"; + case "m-d-Y": + return "MM-DD-YYYY"; + case "m/d/Y": + return "MM/DD/YYYY"; + default: + return ""; + } +} + +function momentDateTimeJS() { + $format = session()->get('settings')['default_date_format']; + switch ($format) { + case "Y-m-d": + return "YYYY-MM-DD HH:mm:ss"; + case "d-m-Y": + return "DD-MM-YYYY HH:mm:ss"; + case "d/m/Y": + return "DD/MM/YYYY HH:mm:ss"; + case "m-d-Y": + return "MM-DD-YYYY HH:mm:ss"; + case "m/d/Y": + return "MM/DD/YYYY HH:mm:ss"; + default: + return ""; + } +} + +function dateFormatWeb($date) { + $format = session()->get('settings')['default_date_format']; + switch ($format) { + case "Y-m-d": + return $date; + case "d-m-Y": + case "d/m/Y": + case "m-d-Y": + case "m/d/Y": + $phpDate = strtotime($date); + if(strlen($date) > 10){ + return date( $format.' H:i:s', $phpDate); + }else{ + return date( $format, $phpDate); + } + default: + return null; + } +} + +function dateFormatMysql($date) { + $format = session()->get('settings')['default_date_format']; + switch ($format) { + case "Y-m-d": + return $date; + case "d-m-Y": + $dateTimeSplit = explode(' ',$date); + $dateSplit = explode('-',$dateTimeSplit[0]); + if(count($dateTimeSplit) > 1){ + return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0].' '. $dateTimeSplit[1]; + }else{ + return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0]; + } + case "d/m/Y": + $dateTimeSplit = explode(' ',$date); + $dateSplit = explode('/',$dateTimeSplit[0]); + if(count($dateTimeSplit) > 1){ + return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0].' '. $dateTimeSplit[1]; + }else{ + return $dateSplit[2].'-'.$dateSplit[1].'-'.$dateSplit[0]; + } + case "m-d-Y": + $dateTimeSplit = explode(' ',$date); + $dateSplit = explode('-',$dateTimeSplit[0]); + if(count($dateTimeSplit) > 1){ + return $dateSplit[2].'-'.$dateSplit[0].'-'.$dateSplit[1].' '. $dateTimeSplit[1]; + }else{ + return $dateSplit[2].'-'.$dateSplit[0].'-'.$dateSplit[1]; + } + case "m/d/Y": + $dateTimeSplit = explode(' ',$date); + $dateSplit = explode('/',$dateTimeSplit[0]); + if(count($dateTimeSplit) > 1){ + return $dateSplit[2].'-'.$dateSplit[0].'-'.$dateSplit[1].' '. $dateTimeSplit[1]; + }else { + return $dateSplit[2] . '-' . $dateSplit[0] . '-' . $dateSplit[1]; + } + default: + return null; + } +} + +function langJS() { + $lang = session()->get('lang')??'en'; + switch ($lang) { + case "pt": + return "pt-br"; + default: + return $lang; + } +} + +function socialBG() { + return [ + "facebook" => "bg-facebook", + "linkedin" => "bg-linkedin", + "google" => "bg-google-plus", + "youtube" => "bg-youtube", + "twitter" => "bg-twitter", + "instagram" => "bg-instagram", + "tiktok" => "bg-tiktok", + "whatsapp" => "bg-whatsapp", + "website" => "bg-website", + "api" => "bg-api", + "github" => "bg-github", + "slack" => "bg-slack", + "spotify" => "btn-spotify", + "reddit" => "btn-reddit", + "discord" => "btn-discord", + "dribbble" => "btn-dribbble", + "dropbox" => "btn-dropbox", + "gitlab" => "btn-gitlab", + "tumblr" => "btn-tumblr", + "strava" => "btn-strava", + "twitch" => "btn-twitch", + "vkontakte" => "btn-vk", + "wordpress" => "btn-wordpress", + "yahoo" => "btn-yahoo", + "bitbucket" => "btn-bitbucket", + "wechat" => "btn-wechat", + ]; +} +function keywordEmail() { + return [ + 'user_first_name', + 'user_last_name', + 'user_date_birth', + 'user_address', + 'user_city', + 'user_state', + 'user_country', + 'user_zip_code', + 'user_mobile', + 'user_email', + 'user_picture' + ]; +} + +function templateSelect($templates=[],$name='',$type='') { + foreach ($templates as $item){ + if($item['type'] == $type){ + if($item['name'] == $name){ + return $item; + } + } + } + return null; +} + +function get_filter_datatables_columns($request){ + $columnSearch = array(); + + if ( isset( $request['columns'] ) ) { + for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) { + $requestColumn = $request['columns'][$i]; + + $str = $requestColumn['search']['value']; + + if ( $requestColumn['searchable'] == 'true' && + $str != '' ) { + array_push($columnSearch, [$i, $requestColumn['data'], $str]); + } + } + } + + return $columnSearch; +} + +// Devuelve true si los intervalos (a1,a2) (b1,b2) se solapan +// https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap +function check_overlap($a1, $a2, $b1, $b2){ + + if (max($a2, $b2) - min($a1, $b1) <= ($a2 - $a1) + ($b2 - $b1)) + return true; + return false; +} + +function check_overlap_with_extremos($a1, $a2, $b1, $b2){ + + if (max($a2, $b2) - min($a1, $b1) < ($a2 - $a1) + ($b2 - $b1)) + return true; + return false; +} + +function version() { + return "1.2.1"; +} \ No newline at end of file From c8335b5740a59d11b811c56cf0bf4f909f9b2296 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Thu, 29 Aug 2024 01:03:50 +0200 Subject: [PATCH 23/42] add SafekatFtpClient Library --- ci4/app/Libraries/SafekatFtpClient.php | 48 ++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 ci4/app/Libraries/SafekatFtpClient.php diff --git a/ci4/app/Libraries/SafekatFtpClient.php b/ci4/app/Libraries/SafekatFtpClient.php new file mode 100644 index 00000000..a5ee2f7e --- /dev/null +++ b/ci4/app/Libraries/SafekatFtpClient.php @@ -0,0 +1,48 @@ +ftp = new FtpClient(); + $this->ftp_config = config("FTP"); + $this->host = $this->ftp_config->host; + $this->username = $this->ftp_config->username; + $this->password = $this->ftp_config->password; + $this->port = $this->ftp_config->port; + $this->base_dir = $this->ftp_config->base_dir; + } + /** + * Upload the content of $filename to the base directory declared in App\Config\FTP.php + * + * @param string $content + * @param string $filename + * @return boolean + */ + public function uploadXML(string $content, string $filename): bool + { + try { + $remotePath = implode("/", [$this->base_dir, $filename]); + $this->ftp->connect(host: $this->host, port: $this->port); + $this->ftp->login(username: $this->username, password: $this->password); + $this->ftp->putFromString($remotePath, $content); + return true; + } catch (\Throwable $th) { + throw $th; + log_message('error',$th->getMessage()); + return false; + } + } +} From 3a0011b49ac6a8a766af7d1986eb0b12a61ddf93 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Thu, 29 Aug 2024 01:04:10 +0200 Subject: [PATCH 24/42] delete FTPService, moved to Libraries --- ci4/app/Services/FTPService.php | 48 --------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 ci4/app/Services/FTPService.php diff --git a/ci4/app/Services/FTPService.php b/ci4/app/Services/FTPService.php deleted file mode 100644 index fa4650cc..00000000 --- a/ci4/app/Services/FTPService.php +++ /dev/null @@ -1,48 +0,0 @@ -ftp = new FtpClient(); - $this->ftp_config = config("FTP"); - $this->host = $this->ftp_config->host; - $this->username = $this->ftp_config->username; - $this->password = $this->ftp_config->password; - $this->base_dir = $this->ftp_config->base_dir; - } - /** - * Upload the content of $filename to the base directory declared in App\Config\FTP.php - * - * @param string $content - * @param string $filename - * @return boolean - */ - public function uploadXML(string $content, string $filename): bool - { - try { - $remotePath = implode("/", [$this->base_dir, $filename]); - $this->ftp->connect(host: $this->host, port: $this->port); - $this->ftp->login(username: $this->username, password: $this->password); - $this->ftp->putFromString($remotePath, $content); - return true; - } catch (\Throwable $th) { - log_message('error',$th->getMessage()); - return false; - } - } -} From 43fdafc09980058b47904536613eb30f293fa2a5 Mon Sep 17 00:00:00 2001 From: amazuecos Date: Thu, 29 Aug 2024 01:04:44 +0200 Subject: [PATCH 25/42] upload xml to server by ftp --- ci4/app/Services/PedidoXMLService.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ci4/app/Services/PedidoXMLService.php b/ci4/app/Services/PedidoXMLService.php index 3ece7f7c..9af64ea1 100644 --- a/ci4/app/Services/PedidoXMLService.php +++ b/ci4/app/Services/PedidoXMLService.php @@ -2,14 +2,11 @@ namespace App\Services; -use App\Entities\Pedidos\PedidoEntity; +use DOMDocument; +use App\Libraries\SafekatFtpClient; use CodeIgniter\Config\BaseService; use App\Models\Pedidos\PedidoModel; -use App\Models\Pedidos\PedidoLineaModel; use App\Models\Presupuestos\PresupuestoModel; -use DOMDocument; -use DOMNode; -use FTP; class PedidoXMLService extends BaseService { @@ -170,8 +167,8 @@ class PedidoXMLService extends BaseService $xml->appendChild($xml_products_el); $file_has_suffix = hash('sha512',$data["pedido_cliente_presupuesto"]->pedidoId); $file_name = PedidoXMLService::generate_xml_file_name($file_has_suffix); - $ftp = service('FTPService'); - $ftp->uploadXML($xml->textContent,$file_name); + $ftp = new SafekatFtpClient(); + $ftp->uploadXML($xml->saveXML(),$file_name); return $data; } protected static function generate_xml_file_name(string $hash) : string From b908c5b5bf4057d597a337206c613b376175efc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Thu, 29 Aug 2024 09:27:05 +0200 Subject: [PATCH 26/42] modificado presupuesto comercial --- ci4/app/Config/Routes.php | 1 + .../Presupuestos/Presupuestoacabados.php | 38 ++++- .../Tarifas/Acabados/TarifaAcabadosLineas.php | 2 +- .../PresupuestoAcabadosEntity.php | 2 + .../Presupuestos/PresupuestoAcabadosModel.php | 40 ++++- .../Tarifas/Acabados/TarifaAcabadoModel.php | 8 +- ci4/app/Services/PresupuestoService.php | 9 +- .../cosidotapablanda/_datosServiciosItems.js | 152 +++++++++++++++++- .../cosidotapablanda/_datosServiciosItems.php | 2 + 9 files changed, 235 insertions(+), 19 deletions(-) diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 1425d588..05556596 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -590,6 +590,7 @@ $routes->resource('presupuestocliente', ['namespace' => 'App\Controllers\Presupu $routes->group('serviciosacabados', ['namespace' => 'App\Controllers\Presupuestos'], function ($routes) { $routes->post('datatable', 'Presupuestoacabados::datatable', ['as' => 'dataTableOfPresupuestoAcabados']); + $routes->post('menuitems', 'Presupuestoacabados::menuItems', ['as' => 'menuItemsOfPresupuestoAcabados']); $routes->post('edit/(:num)', 'Presupuestoacabados::edit/$1', ['as' => 'updatePresupuestoacabados']); }); diff --git a/ci4/app/Controllers/Presupuestos/Presupuestoacabados.php b/ci4/app/Controllers/Presupuestos/Presupuestoacabados.php index 47f2eb68..48fa392c 100755 --- a/ci4/app/Controllers/Presupuestos/Presupuestoacabados.php +++ b/ci4/app/Controllers/Presupuestos/Presupuestoacabados.php @@ -99,12 +99,13 @@ class Presupuestoacabados extends \App\Controllers\BaseResourceController $tarifa_acabado_id = $reqData['tarifa_acabado_id'] ?? 0; $tirada = $reqData['tirada'] ?? 0; + $proveedor_id = $reqData['proveedor_id'] ?? -1; $POD = $reqData['POD'] ?? 0; $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); - $values = $this->model->getPrecioTarifa($tarifa_acabado_id, $tirada, $POD); + $values = $this->model->getPrecioTarifa($tarifa_acabado_id, $tirada, $proveedor_id, $POD); $data = [ 'values' => $values, @@ -119,4 +120,39 @@ class Presupuestoacabados extends \App\Controllers\BaseResourceController } + public function menuItems() + { + if ($this->request->isAJAX()) { + + $reqData = $this->request->getPost(); + try{ + + $tarifa_id = $reqData['tarifa_id'] ?? -1; + $tirada = $reqData['tirada'] ?? 0; + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + $menu = $this->model->getProveedoresForSelector($tarifa_id, $tirada); + + $data = [ + 'menu' => $menu, + $csrfTokenName => $newTokenHash + ]; + + } + catch(Exception $e){ + $data = [ + 'error' => $e, + $csrfTokenName => $newTokenHash + ]; + } + finally{ + return $this->respond($data); + } + + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } } diff --git a/ci4/app/Controllers/Tarifas/Acabados/TarifaAcabadosLineas.php b/ci4/app/Controllers/Tarifas/Acabados/TarifaAcabadosLineas.php index a79a6221..e3021245 100644 --- a/ci4/app/Controllers/Tarifas/Acabados/TarifaAcabadosLineas.php +++ b/ci4/app/Controllers/Tarifas/Acabados/TarifaAcabadosLineas.php @@ -216,7 +216,7 @@ class TarifaAcabadosLineas extends \App\Controllers\BaseResourceController $searchValues = get_filter_datatables_columns($reqData); $resourceData = $this->model->getResource($searchValues, $id_TA)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject(); - $query = $this->model->db->getLastQuery(); + return $this->respond(Collection::datatable( $resourceData, $this->model->getResource()->countAllResults(), diff --git a/ci4/app/Entities/Presupuestos/PresupuestoAcabadosEntity.php b/ci4/app/Entities/Presupuestos/PresupuestoAcabadosEntity.php index 71c10315..02af9b3a 100755 --- a/ci4/app/Entities/Presupuestos/PresupuestoAcabadosEntity.php +++ b/ci4/app/Entities/Presupuestos/PresupuestoAcabadosEntity.php @@ -9,6 +9,7 @@ class PresupuestoAcabadosEntity extends \CodeIgniter\Entity\Entity "id" => null, "presupuesto_id" => null, "tarifa_acabado_id" => null, + "proveedor_id" => null, "precio_unidad" => null, "precio_total" => null, "margen" => null, @@ -20,6 +21,7 @@ class PresupuestoAcabadosEntity extends \CodeIgniter\Entity\Entity protected $casts = [ "presupuesto_id" => "int", "tarifa_acabado_id" => "int", + "proveedor_id" => "int", "precio_unidad" => "float", "precio_total" => "float", "margen" => "float", diff --git a/ci4/app/Models/Presupuestos/PresupuestoAcabadosModel.php b/ci4/app/Models/Presupuestos/PresupuestoAcabadosModel.php index 9eadaf14..08d98bfb 100755 --- a/ci4/app/Models/Presupuestos/PresupuestoAcabadosModel.php +++ b/ci4/app/Models/Presupuestos/PresupuestoAcabadosModel.php @@ -17,11 +17,12 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel const SORTABLE = [ 0 => "t2.nombre", - 1 => "t1.precio_unidad", - 2 => "t1.precio_total" + 1 => "t1.proveedor_id", + 2 => "t1.precio_unidad", + 3 => "t1.precio_total" ]; - protected $allowedFields = ["presupuesto_id", "tarifa_acabado_id", "nombre", "precio_total", "precio_unidad", "margen", "cubierta", "sobrecubierta"]; + protected $allowedFields = ["presupuesto_id", "tarifa_acabado_id", "proveedor_id", "nombre", "precio_total", "precio_unidad", "margen", "cubierta", "sobrecubierta"]; protected $returnType = "App\Entities\Presupuestos\PresupuestoAcabadosEntity"; protected $useTimestamps = true; @@ -46,10 +47,29 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel ], ]; - public function getPrecioTarifa($tarifa_acabado_id, $tirada, $POD){ + + public function getProveedoresForSelector($tarifa_acabado_id, $tirada){ + + $proveedores = []; + $modelTarifa = model('App\Models\Tarifas\Acabados\TarifaAcabadoModel'); + + $tarifa_value = $modelTarifa->getTarifaPresupuestoAcabado($tarifa_acabado_id, $tirada); + + if (count($tarifa_value)>0) { + foreach($tarifa_value as $tarifa) + array_push($proveedores, + (object)[ + 'id'=> $tarifa->proveedor_id, + 'text'=> $tarifa->proveedor_nombre, + ]); + } + return $proveedores; + } + + public function getPrecioTarifa($tarifa_acabado_id, $tirada, $proveedor_id, $POD){ $modelTarifa = model('App\Models\Tarifas\Acabados\TarifaAcabadoModel'); - $tarifa_value = $modelTarifa->getTarifaPresupuestoAcabado($tarifa_acabado_id, $tirada); + $tarifa_value = $modelTarifa->getTarifaPresupuestoAcabado($tarifa_acabado_id, $tirada, $proveedor_id); if (count($tarifa_value)>0) { $result_data = $this->calcularTarifa($tarifa_value[0], $tirada, $POD<$tirada?false:true); @@ -59,6 +79,8 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel 'precio_unidad'=> $result_data[0], 'total'=> $result_data[1], 'margen'=> $result_data[2], + 'proveedor' => $tarifa_value[0]->proveedor_nombre, + 'proveedor_id' => $tarifa_value[0]->proveedor_id, ]; return $ret_array; } @@ -119,6 +141,8 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel foreach($tarifas as $tarifa){ + $proveedor = $tarifa->proveedor_id=='undefined'?'NULL':$tarifa->proveedor_id; + $builder = $this->db ->table($this->table . " t1"); $builder->select("id"); @@ -132,6 +156,7 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel ->table($this->table . " t1") ->where('presupuesto_id', $presupuesto_id) ->where('tarifa_acabado_id', $tarifa->tarifa_id) + ->set('proveedor_id', $proveedor) ->set('precio_unidad', $tarifa->precio_unidad) ->set('precio_total', $tarifa->precio_total) ->set('margen', $tarifa->margen) @@ -146,6 +171,7 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel ->table($this->table . " t1") ->set('presupuesto_id', $presupuesto_id) ->set('tarifa_acabado_id', $tarifa->tarifa_id) + ->set('proveedor_id', $proveedor, false) ->set('precio_unidad', $tarifa->precio_unidad) ->set('precio_total', $tarifa->precio_total) ->set('margen', $tarifa->margen) @@ -169,11 +195,13 @@ class PresupuestoAcabadosModel extends \App\Models\BaseModel ->table($this->table . " t1") ->select( "t1.id AS id, t1.tarifa_acabado_id AS tarifa_acabado_id, t1.precio_unidad AS precio_unidad, - t1.precio_total AS precio_total, t1.margen AS margen, t2.nombre AS nombre, t1.cubierta AS cubierta, t1.sobrecubierta AS sobrecubierta" + t1.precio_total AS precio_total, t1.margen AS margen, t2.nombre AS nombre, t1.cubierta AS cubierta, t1.sobrecubierta AS sobrecubierta, + t1.proveedor_id AS proveedor_id, t3.nombre AS proveedor," ); $builder->where('t1.presupuesto_id', $presupuesto_id); $builder->join("lg_tarifa_acabado t2", "t1.tarifa_acabado_id = t2.id", "left"); + $builder->join("lg_proveedores t3", "t1.proveedor_id = t3.id", "left"); return $builder; } diff --git a/ci4/app/Models/Tarifas/Acabados/TarifaAcabadoModel.php b/ci4/app/Models/Tarifas/Acabados/TarifaAcabadoModel.php index 3d2e3162..4ae2b09f 100644 --- a/ci4/app/Models/Tarifas/Acabados/TarifaAcabadoModel.php +++ b/ci4/app/Models/Tarifas/Acabados/TarifaAcabadoModel.php @@ -114,16 +114,17 @@ class TarifaAcabadoModel extends \App\Models\BaseModel return $builder->orderBy("t1.nombre", "asc")->get()->getResultObject(); } - public function getTarifaPresupuestoAcabado($tarifa_id, $tirada){ + public function getTarifaPresupuestoAcabado($tarifa_id, $tirada, $proveedor_id = -1){ $builder = $this->db ->table($this->table . " t1") ->select( "t1.id AS tarifa_acabado_id, t1.nombre AS tarifa_acabado_nombre, t1.precio_min AS tarifa_precio_min, t1.importe_fijo AS tarifa_importe_fijo, t1.acabado_cubierta AS acabado_cubierta, t1.acabado_sobrecubierta AS acabado_sobrecubierta, t2.id AS tarifa_linea_id, t2.tirada_min AS tirada_min, t2.tirada_max AS tirada_max, - t2.precio_min AS precio_min, t2.precio_max AS precio_max, t2.margen AS margen" + t2.precio_min AS precio_min, t2.precio_max AS precio_max, t2.margen AS margen, t2.proveedor_id AS proveedor_id, t3.nombre AS proveedor_nombre" ) ->join("tarifa_acabado_lineas t2", "t1.id = t2.tarifa_acabado_id", "left") + ->join("lg_proveedores t3", "t2.proveedor_id = t3.id", "left") ->where("t1.is_deleted", 0) //->where("t1.mostrar_en_presupuesto", 1) ->where("t2.is_deleted", 0); @@ -132,6 +133,9 @@ class TarifaAcabadoModel extends \App\Models\BaseModel $builder->where('t2.tirada_min <=', $tirada); $builder->where('t2.tirada_max >=', $tirada); + if($proveedor_id != -1){ + $builder->where('t2.proveedor_id', $proveedor_id); + } return $builder->get()->getResultObject(); } diff --git a/ci4/app/Services/PresupuestoService.php b/ci4/app/Services/PresupuestoService.php index 0fe6e6f3..94bac7e7 100755 --- a/ci4/app/Services/PresupuestoService.php +++ b/ci4/app/Services/PresupuestoService.php @@ -1353,7 +1353,14 @@ class PresupuestoService extends BaseService $model = new PresupuestoAcabadosModel(); foreach ($servicios as $servicio) { - $nueva_tarifa = $model->getPrecioTarifa($servicio->tarifa_acabado_id, $input_data['tirada'], $input_data['POD']); + // Si es un presupuesto duplicado hay que buscar el proveedor más barato + if($input_data['is_duplicado']){ + $nueva_tarifa = $model->getPrecioTarifa($servicio->tarifa_acabado_id, $input_data['tirada'], -1, $input_data['POD']); + } + else{ + $nueva_tarifa = $model->getPrecioTarifa($servicio->tarifa_acabado_id, $input_data['tirada'], $servicio->proveedor_id, $input_data['POD']); + } + if($nueva_tarifa && count($nueva_tarifa)>0){ if(round($nueva_tarifa[0]->precio_unidad, 2) != round($servicio->precio_unidad,2) || $nueva_tarifa[0]->margen != $servicio->margen){ diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.js b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.js index e2977d49..31de5f54 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.js +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.js @@ -207,9 +207,9 @@ function init_servicio_acabado(){ tableServiciosAcabado.row.add([ element.tarifa_acabado_id, nombre_completo, - '' + '' + '', '' + parseFloat(element.precio_unidad).toFixed(2) + '', @@ -218,6 +218,44 @@ function init_servicio_acabado(){ '' ]).draw(false) + $('#proveedor_acabado_' + element.tarifa_acabado_id).select2({ + allowClear: false, + minimumResultsForSearch: -1, + ajax: { + url: window.routes_servicios.menuItemsOfPresupuestoAcabados, + type: 'post', + dataType: 'json', + + data: function (params) { + + if(parseInt($('#tirada').val())>0){ + var tirada = parseInt($('#tirada').val()) + } + else{ + var tirada = 0 + } + + var return_data = { + tarifa_id: element.tarifa_acabado_id, + tirada: tirada, + }; + return_data = Object.assign(return_data, window.token_ajax); + + return return_data; + }, + delay: 60, + processResults: function (response) { + yeniden(response[window.csrf_token]); + return { + results: response.menu + }; + }, + cache: true + } + }); + $('#proveedor_acabado_' + element.tarifa_acabado_id).on('change', select_acabado_event) + + $('#precio_total_acabado_' + element.tarifa_acabado_id).on('change', function(){ updatePresupuesto({ update_lineas: false, @@ -228,9 +266,55 @@ function init_servicio_acabado(){ }) }) + check_serv_acabado_error() } +function select_acabado_event(){ + + if(parseInt($('#tirada').val())>0){ + var tirada = parseInt($('#tirada').val()) + parseInt($('#merma').val()) + } + else{ + var tirada = 0 + } + + var tarifa_id = null; + if(this.id.includes('proveedor_acabado')){ + tarifa_id = this.id.split('_')[2]; + } + else{ + tarifa_id = this.id.split('_')[1]; + } + + var datos = { + tarifa_acabado_id: tarifa_id, + tirada: tirada, + proveedor_id: parseInt($('#proveedor_acabado_' + tarifa_id).select2('data')[0].id), + POD: parseInt($('#POD').val()) + }; + datos = Object.assign(datos, window.token_ajax); + + $.ajax({ + type: "POST", + url: window.routes_servicios.dataTableOfPresupuestoAcabados, + data: datos, + success: function (data) { + + $('#precio_unidad_acabado_' + datos.tarifa_acabado_id).text(parseFloat(data.values[0].precio_unidad).toFixed(2)) + $('#precio_total_acabado_' + datos.tarifa_acabado_id).val(parseFloat(data.values[0].total).toFixed(2)) + $('#acabado_margen_' + datos.tarifa_acabado_id).val(parseFloat(data.values[0].margen).toFixed(2)) + + yeniden(data[window.csrf_token]); + return true; + }, + error: function(e){ + return false; + } + }) + return false; +} + function check_serv_acabado_error(){ var htmlString = ''; @@ -285,6 +369,11 @@ function get_tarifas_acabado(tarifa_id = -1, uso=null){ tableServiciosAcabado.row.add([ row.tarifa_id, nombre, + '', '' + parseFloat(row.precio_unidad).toFixed(2) + '', '', '', @@ -300,6 +389,44 @@ function get_tarifas_acabado(tarifa_id = -1, uso=null){ update_tiradas_alternativas: true}) }) + + + $('#proveedor_acabado_' + row.tarifa_id).select2({ + allowClear: false, + minimumResultsForSearch: -1, + ajax: { + url: window.routes_servicios.menuItemsOfPresupuestoAcabados, + type: 'post', + dataType: 'json', + + data: function (params) { + + if(parseInt($('#tirada').val())>0){ + var tirada = parseInt($('#tirada').val()) + } + else{ + var tirada = 0 + } + + var return_data = { + tarifa_id: row.tarifa_id, + tirada: tirada, + }; + return_data = Object.assign(return_data, window.token_ajax); + + return return_data; + }, + delay: 60, + processResults: function (response) { + yeniden(response[window.csrf_token]); + return { + results: response.menu + }; + }, + cache: true + } + }); + $('#proveedor_acabado_' + row.tarifa_id).on('change', select_acabado_event) }); check_serv_acabado_error() @@ -420,12 +547,15 @@ function get_datos_acabado(){ values['sobrecubierta'] = 0 break case 2: - values['precio_unidad'] = $(this).text() + values['proveedor_id'] = $(this).children(":first").select2('data')[0].id break case 3: - values['precio_total'] = $(this).children(":first").val() + values['precio_unidad'] = $(this).text() break case 4: + values['precio_total'] = $(this).children(":first").val() + break + case 5: values['margen'] = $(this).text() break } @@ -736,11 +866,7 @@ async function get_tarifas_enc(tipo=null, tarifa_id = -1){ var datos = { tarifa_encuadernacion_id : tarifa_id, - solapas: $('#solapas').is(':checked')?1:0, - paginas: parseInt($('#paginas').val())>0?parseInt($('#paginas').val()):0, tirada: tirada, - ancho: dimension.ancho, - alto: dimension.alto, POD: parseInt($('#POD').val()) }; datos = Object.assign(datos, window.token_ajax) @@ -1743,9 +1869,19 @@ async function actualizar_servicios(update_preimpresion=false){ .then(response => response.json()) .then(data => { data.lines.forEach((line) => { + $('#proveedor_acabado_' + line[0].tarifa_id).off('change') + if(line[0].hasOwnProperty('proveedor_id')){ + $('#proveedor_acabado_' + line[0].tarifa_id) + .append('') + } + else{ + $('#proveedor_acabado_' + line[0].tarifa_id).empty() + .append('') + } $('#precio_unidad_acabado_' + line[0].tarifa_id).text(parseFloat(line[0].precio_unidad).toFixed(2)) $('#precio_total_acabado_' + line[0].tarifa_id).val(parseFloat(line[0].total).toFixed(2)) $('#acabado_margen_' + line[0].tarifa_id).text(parseFloat(line[0].margen).toFixed(2)) + $('#proveedor_acabado_' + line[0].tarifa_id).on('change', select_enc_event) }); check_serv_acabado_error() yeniden(data[window.csrf_token]); diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.php index 498fd0eb..e54931d2 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosServiciosItems.php @@ -90,6 +90,7 @@ + @@ -297,6 +298,7 @@ window.routes_servicios = { dataTableOfPresupuestoAcabados: "", + menuItemsOfPresupuestoAcabados: '', dataTableOfPresupuestoPreimpresion: "", dataTableOfPresupuestoEncuadernaciones: "", dataTableOfPresupuestoManipulados: "", From e1a72e7874c0c572db8a6b7c5bee83f9ba865ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Thu, 29 Aug 2024 09:32:58 +0200 Subject: [PATCH 27/42] modificado lo necesario para presupuesto cliente --- ci4/app/Services/PresupuestoClienteService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci4/app/Services/PresupuestoClienteService.php b/ci4/app/Services/PresupuestoClienteService.php index ecb1f1ad..bf6c6408 100644 --- a/ci4/app/Services/PresupuestoClienteService.php +++ b/ci4/app/Services/PresupuestoClienteService.php @@ -385,7 +385,7 @@ class PresupuestoClienteService extends BaseService $POD = $data['POD'] ?? -1; $model = model('App\Models\Presupuestos\PresupuestoAcabadosModel'); - $values = $model->getPrecioTarifa($tarifa_id, $tirada, $POD); + $values = $model->getPrecioTarifa($tarifa_id, $tirada, -1, $POD); // proveedor más barato return $values; } From 1f09a1c603401c5f643362b1e00c2c76fd6f6e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Thu, 29 Aug 2024 11:55:58 +0200 Subject: [PATCH 28/42] quitado pais como campo obligatorio para nuevo presupuesto administrador --- ci4/app/Models/Presupuestos/PresupuestoModel.php | 2 +- .../presupuestos/cosidotapablanda/_datosPresupuestoItems.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci4/app/Models/Presupuestos/PresupuestoModel.php b/ci4/app/Models/Presupuestos/PresupuestoModel.php index 424ba107..aa88fd61 100755 --- a/ci4/app/Models/Presupuestos/PresupuestoModel.php +++ b/ci4/app/Models/Presupuestos/PresupuestoModel.php @@ -162,7 +162,7 @@ class PresupuestoModel extends \App\Models\BaseModel ], "pais_id" => [ "label" => "Presupuestos.paisId", - "rules" => "required|integer|greater_than[0]", + "rules" => "integer", ], "cliente_id" => [ "label" => "Presupuestos.clienteId", diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosPresupuestoItems.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosPresupuestoItems.php index ec087bb1..f4410468 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosPresupuestoItems.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_datosPresupuestoItems.php @@ -126,7 +126,7 @@