diff --git a/ci4/app/Config/RBAC/permissionMatrix.php b/ci4/app/Config/RBAC/permissionMatrix.php index adc25c5b..e0b0fec1 100644 --- a/ci4/app/Config/RBAC/permissionMatrix.php +++ b/ci4/app/Config/RBAC/permissionMatrix.php @@ -29,6 +29,8 @@ const SK_PERMISSION_MATRIX = [ "pedidos-cancelados.menu", "pedidos-todos.view", "pedidos-todos.menu", + "pedidos-gestion.toprod", + "pedidos-gestion.menu", "tarifa-preimpresion.create", "tarifa-preimpresion.edit", "tarifa-preimpresion.delete", @@ -169,6 +171,29 @@ const SK_PERMISSION_MATRIX = [ "token.menu", ], "director" => [ + "clientes.create", + "clientes.edit", + "clientes.menu", + "plantilla-tarifa.create", + "plantilla-tarifa.edit", + "plantilla-tarifa.menu", + "direcciones.create", + "direcciones.edit", + "direcciones.menu", + "presupuesto.create", + "presupuesto.edit", + "presupuesto.menu", + "presupuesto-cliente.create", + "presupuesto-cliente.edit", + "presupuesto-cliente.menu", + "pedidos-activos.view", + "pedidos-activos.menu", + "pedidos-finalizados.view", + "pedidos-finalizados.menu", + "pedidos-cancelados.view", + "pedidos-cancelados.menu", + "pedidos-todos.view", + "pedidos-todos.menu", "tarifa-preimpresion.create", "tarifa-preimpresion.edit", "tarifa-preimpresion.menu", @@ -190,6 +215,11 @@ const SK_PERMISSION_MATRIX = [ "servicio-acabado.create", "servicio-acabado.edit", "servicio-acabado.menu", + "proveedores.create", + "proveedores.edit", + "proveedores.menu", + "tickets.edit", + "tickets.menu", ], "contabilidad" => [ "token.token", diff --git a/ci4/app/Config/RBAC/permissions.php b/ci4/app/Config/RBAC/permissions.php index ac95e36a..b38701ba 100644 --- a/ci4/app/Config/RBAC/permissions.php +++ b/ci4/app/Config/RBAC/permissions.php @@ -29,6 +29,8 @@ const SK_PERMISSIONS = [ 'pedidos-cancelados.menu' => 'Menu shall be visualize', 'pedidos-todos.view' => 'Can view', 'pedidos-todos.menu' => 'Menu shall be visualize', + 'pedidos-gestion.toprod' => 'Can toprod', + 'pedidos-gestion.menu' => 'Menu shall be visualize', 'tarifa-preimpresion.create' => 'Can create', 'tarifa-preimpresion.edit' => 'Can edit', 'tarifa-preimpresion.delete' => 'Can delete', diff --git a/ci4/app/Config/RBAC/roles.php b/ci4/app/Config/RBAC/roles.php index 5ce300a9..d39a912a 100644 --- a/ci4/app/Config/RBAC/roles.php +++ b/ci4/app/Config/RBAC/roles.php @@ -31,7 +31,7 @@ const SK_ROLES = [ ], 'director' => [ 'title' => 'Director', - 'description' => '', + 'description' => 'Para los directores de área', ], 'contabilidad' => [ 'title' => 'Contabilidad', diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index b40d287a..3e1e9adb 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -750,6 +750,7 @@ $routes->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->post('insertfactura', 'Pedido::addFactura'); $routes->get('xml/(:num)', 'Pedido::get_xml_pedido/$1', ['as' => 'getXMLPedido']); $routes->post('produccion/(:num)', 'Pedido::to_produccion/$1', ['as' => 'toProduccion']); }); @@ -772,7 +773,7 @@ $routes->resource('albaranes', ['namespace' => 'App\Controllers\Pedidos', 'contr $routes->group('facturas', ['namespace' => 'App\Controllers\Facturacion'], function ($routes) { $routes->get('list', 'Facturas::list', ['as' => 'facturasList']); - $routes->post('datatable', 'Facturas::datatable', ['as' => 'dataTableOfFacturas']); + $routes->get('datatable', 'Facturas::datatable', ['as' => 'dataTableOfFacturas']); $routes->get('add', 'Facturas::add', ['as' => 'newFactura']); $routes->post('add', 'Facturas::add', ['as' => 'createFactura']); $routes->get('edit/(:any)', 'Facturas::edit/$1', ['as' => 'editarFactura']); diff --git a/ci4/app/Controllers/Facturacion/Facturas.php b/ci4/app/Controllers/Facturacion/Facturas.php index e2755e8e..fd5416c4 100755 --- a/ci4/app/Controllers/Facturacion/Facturas.php +++ b/ci4/app/Controllers/Facturacion/Facturas.php @@ -6,7 +6,8 @@ use App\Models\Facturas\FacturaModel; use App\Entities\Facturas\FacturaEntity; use App\Models\Clientes\ClienteModel; use App\Models\Collection; - +use Hermawan\DataTables\DataTable; +use Exception; class Facturas extends \App\Controllers\BaseResourceController { @@ -26,9 +27,9 @@ class Facturas extends \App\Controllers\BaseResourceController { $this->viewData['pageTitle'] = lang('Facturas.facturas'); // Se indica que este controlador trabaja con soft_delete - + $this->viewData = ['usingServerSideDataTable' => true]; - + // Breadcrumbs $this->viewData['breadcrumb'] = [ ['title' => lang("App.menu_facturas"), 'route' => "javascript:void(0);", 'active' => false], @@ -47,7 +48,7 @@ class Facturas extends \App\Controllers\BaseResourceController $user = $model_user->find(auth()->user()->id); $clienteId = $user->cliente_id; } else { - $clienteId = 0; + $clienteId = -1; } $this->viewData['cliente_id'] = $clienteId; @@ -58,10 +59,10 @@ class Facturas extends \App\Controllers\BaseResourceController parent::index(); } - + public function list() { - + $viewData = [ 'currentModule' => static::$controllerSlug, 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Facturas.facturas')]), @@ -81,27 +82,37 @@ class Facturas extends \App\Controllers\BaseResourceController $user = $model_user->find(auth()->user()->id); $clienteId = $user->cliente_id; } else { - $clienteId = 0; + $clienteId = -1; } $viewData['cliente_id'] = $clienteId; + // Establecer el idioma (opcional, si no está configurado en app/Config/App.php) + $locale = explode('-', config('Basics')->i18n)[0]; // Or dynamically set it: \Config\Services::language()->getLocale(); + // Specify the language file name (without .php) + $fileName = 'datePicker'; + // Build the path to the language file + $filePath = APPPATH . "Language/{$locale}/{$fileName}.php"; + // Load the entire language file as an array + $viewData['datepickerLang'] = json_encode(file_exists($filePath) ? require $filePath : []); + $viewData['datepickerLocale'] = config('Basics')->i18n; + return view(static::$viewPath . 'viewFacturasList', $viewData); } public function add() { - if ($this->request->getPost()) : + if ($this->request->getPost()): $nullIfEmpty = true; // !(phpversion() >= '8.1'); $postData = $this->request->getPost(); $noException = true; - $allData = true; + $allData = true; - if( !isset($postData['cliente_id']) || !isset($postData['serie_id']) ) { + if (!isset($postData['cliente_id']) || !isset($postData['serie_id'])) { $this->viewData['errorMessage'] = lang('Facturas.errors.requiredFields'); $this->session->setFlashdata('formErrors', $this->model->errors()); @@ -113,8 +124,8 @@ class Facturas extends \App\Controllers\BaseResourceController try { $clienteModel = model('App\Models\Clientes\ClienteModel'); $datosCliente = $clienteModel->getClienteDataFacturas($postData['cliente_id']); - if(count($datosCliente)>0){ - // add array data datosCliente to postData + if (count($datosCliente) > 0) { + // add array data datosCliente to postData $postData = array_merge($postData, $datosCliente[0]); } } catch (\Exception $e) { @@ -122,20 +133,20 @@ class Facturas extends \App\Controllers\BaseResourceController $this->dealWithException($e); } - + $sanitizedData = $this->sanitized($postData, $nullIfEmpty); $sanitizedData['user_updated_id'] = auth()->user()->id; $sanitizedData['user_created_id'] = auth()->user()->id; - if(!$sanitizedData['creditoAsegurado']){ + if (!$sanitizedData['creditoAsegurado']) { $sanitizedData['creditoAsegurado'] = 0; } - - if ($allData && $successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : + + if ($allData && $successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) : - if ($this->canValidate()) : + if ($this->canValidate()): try { $successfulResult = $this->model->skipValidation(true)->save($sanitizedData); } catch (\Exception $e) { @@ -148,15 +159,15 @@ class Facturas extends \App\Controllers\BaseResourceController endif; endif; - if ($noException && $successfulResult) : + if ($noException && $successfulResult): $id = $this->model->db->insertID(); $message = lang('Basic.global.saveSuccess', [lang('Basic.global.record')]) . '.'; return redirect()->to(route_to('editarFactura', $id))->with('sweet-success', $message); - - + + endif; // $noException && $successfulResult endif; // ($requestMethod === 'post') @@ -174,7 +185,7 @@ class Facturas extends \App\Controllers\BaseResourceController ['title' => lang("App.menu_facturas"), 'route' => "javascript:void(0);", 'active' => false], ['title' => lang("Facturas.facturaList"), 'route' => route_to('facturasList'), 'active' => true] ]; - + $this->viewData['usingSelect2'] = true; $validation = \Config\Services::validation(); @@ -187,19 +198,20 @@ class Facturas extends \App\Controllers\BaseResourceController } // end function add() - public function edit($id=null){ - - if ($id == null) : + public function edit($id = null) + { + + if ($id == null): return $this->redirect2listView(); endif; $id = filter_var($id, FILTER_SANITIZE_URL); $factura = $this->model->find($id); - if ($factura == false) : + if ($factura == false): $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Facturas.factura')), $id]); return $this->redirect2listView('sweet-error', $message); endif; - + $this->obtenerDatosFormulario($factura); @@ -209,56 +221,147 @@ class Facturas extends \App\Controllers\BaseResourceController ]; $userModel = model('App\Models\UserModel'); - $factura->created_by = $userModel->getFullName($factura->user_created_id); - $factura->updated_by = $userModel->getFullName($factura->user_updated_id); + $factura->created_by = $userModel->getFullName($factura->user_created_id); + $factura->updated_by = $userModel->getFullName($factura->user_updated_id); $factura->created_at_footer = $factura->created_at ? date(' H:i d/m/Y', strtotime($factura->created_at)) : ''; $factura->updated_at_footer = $factura->updated_at ? date(' H:i d/m/Y', strtotime($factura->updated_at)) : ''; $this->viewData['facturaEntity'] = $factura; - + $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Facturas.factura') . ' ' . lang('Basic.global.edit3'); return $this->displayForm(__METHOD__, $id); } - public function datatable(){ - if ($this->request->isAJAX()) { + public function datatable() + { - $reqData = $this->request->getPost(); - if (!isset($reqData['draw']) || !isset($reqData['columns']) ) { - $errstr = 'No data available in response to this specific request.'; - $response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr); - return $response; - } - $start = $reqData['start'] ?? 0; - $length = $reqData['length'] ?? 5; - $search = $reqData['search']['value']; - $requestedOrder = $reqData['order']['0']['column'] ?? 0; - $order = FacturaModel::SORTABLE[$requestedOrder >= 0 ? $requestedOrder : 0]; - $dir = $reqData['order']['0']['dir'] ?? 'asc'; - $cliente_id = $reqData['cliente_id'] ?? -1; - - $resourceData = $this->model->getResource($search, $cliente_id)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject(); - - return $this->respond(Collection::datatable( - $resourceData, - $this->model->getResource("", $cliente_id)->countAllResults(), - $this->model->getResource($search, $cliente_id)->countAllResults() - )); + if (auth()->user()->inGroup('cliente-admin') || auth()->user()->inGroup('cliente-editor')) { + // Se obtiene el cliente ID a partir del usuario de la sesion + $model_user = model('App\Models\Usuarios\UserModel'); + $user = $model_user->find(auth()->user()->id); + $clienteId = $user->cliente_id; } else { - return $this->failUnauthorized('Invalid request', 403); + $clienteId = -1; } + + $model = model(FacturaModel::class); + $q = $model->getDatatableQuery($clienteId); + + $searchValue = $this->request->getGet('fecha_factura') ?? ''; + + if (!empty($searchValue)) { + // Extraer las fechas del formato "YYYY-MM-DD|YYYY-MM-DD" + $dates = explode('|', $searchValue); + if (count($dates) == 2) { + $q->where('t1.fecha_factura_at >=', $dates[0] . ' 00:00:00') + ->where('t1.fecha_factura_at <=', $dates[1] . ' 23:59:59'); + } + } + + + $result = DataTable::of($q) + ->edit( + "creditoAsegurado", + function ($row, $meta) { + switch ($row->creditoAsegurado) { + case "0": + return lang('Basic.global.no'); + case "1": + return lang('Basic.global.yes'); + default: + return '--'; // Debug + } + } + ) + ->edit( + "estado", + function ($row, $meta) { + switch ($row->estado) { + case "borrador": + return lang('Facturas.borrador'); + case "validada": + return lang('Facturas.validada'); + default: + return '--'; // Debug + } + } + ) + ->edit( + "estado_pago", + function ($row, $meta) { + switch ($row->estado_pago) { + case "pendiente": + return lang('Facturas.pendiente'); + case "pagada": + return lang('Facturas.pagada'); + case "insolvente": + return lang('Facturas.insolvente'); + default: + return '--'; // Debug + } + } + ) + ->edit( + "forma_pago", + function ($row, $meta) { + switch ($row->forma_pago) { + case "cheque": + return lang('Facturas.cheque'); + case "compensada": + return lang('Facturas.compensada'); + case "confirming": + return lang('Facturas.confirming'); + case "giroDomiciliado": + return lang('Facturas.giroDomiciliado'); + case "pagare": + return lang('Facturas.pagare'); + case "transferencia": + return lang('Facturas.transferencia'); + default: + return $row->forma_pago; // Debug + + } + } + ) + ->add("action", callback: function ($q) { + if ($q->estado == 'borrador') { + return ' +
+ +
+ '; + } else { + return ' +
+ +
+ '; + } + }); + if ($clienteId != -1) { + $result->hide('cliente'); + $result->hide('creditoAsegurado'); + $result->hide('estado'); + $result->hide('estado_pago'); + $result->hide('forma_pago'); + $result->hide('vencimiento'); + $result->hide('dias_vencimiento'); + } + + return $result->toJson(returnAsObject: true); } - public function datatablePedidos(){ + public function datatablePedidos() + { if ($this->request->isAJAX()) { $reqData = $this->request->getPost(); - if (!isset($reqData['draw']) || !isset($reqData['columns']) ) { + if (!isset($reqData['draw']) || !isset($reqData['columns'])) { $errstr = 'No data available in response to this specific request.'; - $response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr); + $response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr); return $response; } $start = $reqData['start'] ?? 0; @@ -282,13 +385,14 @@ class Facturas extends \App\Controllers\BaseResourceController } } - public function update($id = null){ + public function update($id = null) + { if ($this->request->isAJAX()) { $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); - if ($id == null) : + if ($id == null): $data = [ 'error' => 2, $csrfTokenName => $newTokenHash @@ -298,7 +402,7 @@ class Facturas extends \App\Controllers\BaseResourceController $id = filter_var($id, FILTER_SANITIZE_URL); $facturaEntity = $this->model->find($id); - if ($facturaEntity == false) : + if ($facturaEntity == false): $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Factura.factura')), $id]); $data = [ 'error' => $message, @@ -307,21 +411,21 @@ class Facturas extends \App\Controllers\BaseResourceController return $this->respond($data); endif; - if ($this->request->getPost()) : + if ($this->request->getPost()): $nullIfEmpty = true; // !(phpversion() >= '8.1'); $postData = $this->request->getPost(); $sanitizedData = $this->sanitized($postData, $nullIfEmpty); - + // JJO $sanitizedData['user_updated_id'] = auth()->user()->id; $noException = true; - if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : + if ($successfulResult = $this->canValidate()): // if ($successfulResult = $this->validate($this->formValidationRules) ) : - if ($this->canValidate()) : + if ($this->canValidate()): try { $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); } catch (\Exception $e) { @@ -337,7 +441,7 @@ class Facturas extends \App\Controllers\BaseResourceController $facturaEntity->fill($sanitizedData); endif; - if ($noException && $successfulResult) : + if ($noException && $successfulResult): $id = $facturaEntity->id ?? $id; $message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.'; @@ -355,24 +459,54 @@ class Facturas extends \App\Controllers\BaseResourceController $csrfTokenName => $newTokenHash ]; return $this->respond($data); - } - else { + } else { return $this->failUnauthorized('Invalid request', 403); } } + public function delete($id = null) + { - public function menuPedidosPendientes($cliente_id){ + $user_id = auth()->user()->id; + $datetime = (new \CodeIgniter\I18n\Time("now")); + $rawResult = $this->model->where('id', $id) + ->set([ + 'deleted_at' => $datetime->format('Y-m-d H:i:s'), + 'user_updated_id' => $user_id, + ]) + ->update(); + if (!$rawResult) { + return $this->failNotFound(lang('Basic.global.deleteError', [$objName])); + } + + $modelLineas = model('\App\Models\Facturas\FacturaLineaModel'); + $rawResult = $modelLineas->where('factura_id', $id) + ->set([ + 'deleted_at' => $datetime->format('Y-m-d H:i:s'), + 'user_updated_id' => $user_id, + ]) + ->update(); + + $this->model->db->query('DELETE FROM facturas_pedidos_lineas WHERE factura_id=' . $id); + + // $message = lang('Basic.global.deleteSuccess', [$objName]); IMN commented + $message = lang('Basic.global.deleteSuccess', [lang('Basic.global.record')]); + $response = $this->respondDeleted(['id' => $id, 'msg' => $message]); + return $response; + } + + + public function menuPedidosPendientes($cliente_id) + { if ($this->request->isAJAX()) { $model = model('\App\Models\Pedidos\PedidoLineaModel'); - + $pedidos = []; - try{ + try { $pedidos = $model->obtenerLineasPedidoSinFacturar($cliente_id); - } - catch(Exception $e){ - + } catch (Exception $e) { + } $newTokenHash = csrf_hash(); @@ -382,14 +516,14 @@ class Facturas extends \App\Controllers\BaseResourceController $csrfTokenName => $newTokenHash ]; return $this->respond($data); - } - else { + } else { return $this->failUnauthorized('Invalid request', 403); } } - public function duplicate($factura_id = 0){ - if($this->request->isAJAX()){ + public function duplicate($factura_id = 0) + { + if ($this->request->isAJAX()) { $factura_origen = $this->model->find($factura_id); // se quita la key "id" del objeto @@ -412,18 +546,19 @@ class Facturas extends \App\Controllers\BaseResourceController 'id' => $id, $csrfTokenName => $newTokenHash ]; - return $this->respond($data); + return $this->respond($data); - }else{ + } else { return $this->failUnauthorized('Invalid request', 403); } } - public function updateTotales($factura_id = 0){ - if($this->request->isAJAX()){ + public function updateTotales($factura_id = 0) + { + if ($this->request->isAJAX()) { $postData = $this->request->getPost(); - + $pendiente = $postData['pendiente'] ?? 0; $total = $postData['total'] ?? 0; @@ -433,7 +568,7 @@ class Facturas extends \App\Controllers\BaseResourceController 'pendiente' => $pendiente, 'total_pagos' => $postData['total_pagos'] ?? 0, 'user_updated_id' => auth()->user()->id, - 'estado_pago' => (intval($pendiente)==0 && intval($total)!=0) ? 'pagada' : 'pendiente', + 'estado_pago' => (intval($pendiente) == 0 && intval($total) != 0) ? 'pagada' : 'pendiente', ]; $newTokenHash = csrf_hash(); @@ -441,23 +576,23 @@ class Facturas extends \App\Controllers\BaseResourceController $data_ret = [ $csrfTokenName => $newTokenHash ]; - - if($factura_id == 0){ - return $this->respond($data_ret); + + if ($factura_id == 0) { + return $this->respond($data_ret); } $data_ret['estado_pago'] = $data['estado_pago']; $model = model('\App\Models\Facturas\FacturaModel'); $model->update($factura_id, $data); - return $this->respond($data_ret); - } - else { + return $this->respond($data_ret); + } else { return $this->failUnauthorized('Invalid request', 403); } } - public function addExcedentes($factura_id){ + public function addExcedentes($factura_id) + { if ($this->request->isAJAX()) { $model_factura_linea = model('\App\Models\Facturas\FacturaLineaModel'); @@ -472,26 +607,26 @@ class Facturas extends \App\Controllers\BaseResourceController $pedido_linea_maquetacion_id = $postData['pedido_linea_maquetacion_id'] ?? null; $pedido_id = $postData['pedido_id'] ?? 0; - $nuevo_precio_unidad = round($precio_unidad*(100-floatval($descuento))/100, 4); + $nuevo_precio_unidad = round($precio_unidad * (100 - floatval($descuento)) / 100, 4); $base = round($cantidad * $nuevo_precio_unidad, 2); $total_iva = round($base * $iva / 100, 2); - $data = (object)[ - 'factura_id'=>$factura_id, - 'pedido_linea_impresion_id'=>$pedido_linea_impresion_id, - 'pedido_linea_maquetacion_id'=>$pedido_linea_maquetacion_id, - 'descripcion'=>$newString = preg_replace_callback('/Impresión de (\d+) ejemplares/', function ($matches) use ($cantidad) { - return 'Impresión de ' . $cantidad . ' ejemplares'; - }, $descripcion), - 'cantidad'=>$cantidad, - 'precio_unidad'=> $nuevo_precio_unidad, + $data = (object) [ + 'factura_id' => $factura_id, + 'pedido_linea_impresion_id' => $pedido_linea_impresion_id, + 'pedido_linea_maquetacion_id' => $pedido_linea_maquetacion_id, + 'descripcion' => $newString = preg_replace_callback('/Impresión de (\d+) ejemplares/', function ($matches) use ($cantidad) { + return 'Impresión de ' . $cantidad . ' ejemplares'; + }, $descripcion), + 'cantidad' => $cantidad, + 'precio_unidad' => $nuevo_precio_unidad, 'iva' => $iva, 'base' => $base, 'total_iva' => $total_iva, 'total' => round($base + $total_iva, 2), 'user_updated_id' => auth()->user()->id, ]; - + $model_factura_linea->insert($data); $newTokenHash = csrf_hash(); @@ -499,93 +634,113 @@ class Facturas extends \App\Controllers\BaseResourceController $data_ret = [ $csrfTokenName => $newTokenHash ]; - return $this->respond($data_ret); - } - else { + return $this->respond($data_ret); + } else { return $this->failUnauthorized('Invalid request', 403); } } - - public function addLineaPedidoImpresion($factura_id){ - if ($this->request->isAJAX()) { - $model_pedido_linea = model('\App\Models\Pedidos\PedidoLineaModel'); - $model_presupuesto = model('\App\Models\Presupuestos\PresupuestoModel'); - $model_factura_linea = model('\App\Models\Facturas\FacturaLineaModel'); - - try{ + public function addLineaPedidoImpresion($factura_id, $data = -1) + { + + if ($this->request) { + if ($this->request->isAJAX()) $pedido_linea_id = $this->request->getPost('lineaPedido') ?? 0; - $linea = $model_pedido_linea->find($pedido_linea_id); + } else { + if ($data == -1) { + return "Error: sin datos"; + } + $pedido_linea_id = $data; + } - $factura = $this->model->find($factura_id); - - if($factura){ + $model_pedido_linea = model('\App\Models\Pedidos\PedidoLineaModel'); + $model_presupuesto = model('\App\Models\Presupuestos\PresupuestoModel'); + $model_factura_linea = model('\App\Models\Facturas\FacturaLineaModel'); + $model_factura = model('\App\Models\Facturas\FacturaModel'); - if($linea){ - $presupuesto = $model_presupuesto->find($linea->presupuesto_id); + try { - if($presupuesto){ - // Se añade la linea de factura - $descripcion = $model_presupuesto->generarLineaPedido($presupuesto->id, true, $linea->pedido_id); - $cantidad = intval($presupuesto->tirada) - intval($this->model->getCantidadLineaPedidoFacturada($linea->id)); - $base = $cantidad * floatval($presupuesto->total_precio_unidad); - $base = round($base, 2); - $total_iva = $base * ($presupuesto->iva_reducido==1 ? 0.04 : 0.21); - // se redondea a dos decimales - $total_iva = round($total_iva, 2); - $total = $base + $total_iva; + $linea = $model_pedido_linea->find($pedido_linea_id); - $data = (object)[ - 'factura_id'=>$factura_id, - 'pedido_linea_impresion_id'=>$linea->pedido_id, - 'descripcion'=>$descripcion[0]->concepto, - 'cantidad'=>$cantidad, - 'precio_unidad'=>$presupuesto->total_precio_unidad, - 'iva' => $presupuesto->iva_reducido==1 ? 4 : 21, - 'base' => $base, - 'total_iva' => $total_iva, - 'total' => $total, - 'user_updated_id' => auth()->user()->id, + $factura = $model_factura->find($factura_id); + + if ($factura) { + + if ($linea) { + $presupuesto = $model_presupuesto->find($linea->presupuesto_id); + + if ($presupuesto) { + // Se añade la linea de factura + $descripcion = $model_presupuesto->generarLineaPedido($presupuesto->id, true, $linea->pedido_id); + $cantidad = intval($presupuesto->tirada) - intval($model_factura->getCantidadLineaPedidoFacturada($linea->id)); + $base = $cantidad * floatval($presupuesto->total_precio_unidad); + $base = round($base, 2); + $total_iva = $base * ($presupuesto->iva_reducido == 1 ? 0.04 : 0.21); + // se redondea a dos decimales + $total_iva = round($total_iva, 2); + $total = $base + $total_iva; + + $data = (object) [ + 'factura_id' => $factura_id, + 'pedido_linea_impresion_id' => $linea->pedido_id, + 'descripcion' => $descripcion[0]->concepto, + 'cantidad' => $cantidad, + 'precio_unidad' => $presupuesto->total_precio_unidad, + 'iva' => $presupuesto->iva_reducido == 1 ? 4 : 21, + 'base' => $base, + 'total_iva' => $total_iva, + 'total' => $total, + 'user_updated_id' => auth()->user()->id, + ]; + + $model_factura_linea->insert($data); + + $id = $model_factura_linea->getInsertID(); + + if ($id) { + + $model_factura_linea->addFacturaPedidoLinea($factura_id, $linea->id, $cantidad); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + $data = [ + 'error' => 0, + 'id' => $id, + $csrfTokenName => $newTokenHash ]; - - $model_factura_linea->insert($data); - - $id = $model_factura_linea->getInsertID(); - - if($id){ - - $model_factura_linea->addFacturaPedidoLinea($factura_id, $linea->id, $cantidad); - - $newTokenHash = csrf_hash(); - $csrfTokenName = csrf_token(); - $data = [ - 'error' => 0, - 'id' => $id, - $csrfTokenName => $newTokenHash - ]; - return $this->respond($data); + if ($this->request) { + if ($this->request->isAJAX()) + return $this->respond($data); + } else { + // remove csrf token + unset($data[$csrfTokenName]); + return $data; } } } } } - catch(Exception $e){ - - } - + } catch (Exception $e) { $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); $data = [ + 'error' => 1, + 'error_text' => $e->getMessage(), $csrfTokenName => $newTokenHash ]; - return $this->respond($data); - } - else { - return $this->failUnauthorized('Invalid request', 403); + if ($this->request) { + if ($this->request->isAJAX()) + return $this->respond($data); + } else { + unset($data[$csrfTokenName]); + return $data; + } } } - public function deleteLineaPedidoImpresion(){ + public function deleteLineaPedidoImpresion() + { if ($this->request->isAJAX()) { @@ -603,20 +758,20 @@ class Facturas extends \App\Controllers\BaseResourceController $csrfTokenName => $newTokenHash ]; return $this->respond($data); - } - else { + } else { return $this->failUnauthorized('Invalid request', 403); } } - - public function validar($factura_id){ - if($this->request->isAJAX()){ + public function validar($factura_id) + { + + if ($this->request->isAJAX()) { $factura = $this->model->find($factura_id); - if($factura){ + if ($factura) { $model_series = model('\App\Models\Configuracion\SeriesFacturasModel'); $numero = $model_series->getSerieNumerada($factura->serie_id); @@ -626,13 +781,13 @@ class Facturas extends \App\Controllers\BaseResourceController 'user_updated_id' => auth()->user()->id, ]; - if((strpos($numero, "REC ") === 0)){ - $data['estado_pago'] = 'pagada'; + if ((strpos($numero, "REC ") === 0)) { + $data['estado_pago'] = 'pagada'; } $this->model->update($factura_id, $data); } - + $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); @@ -640,30 +795,30 @@ class Facturas extends \App\Controllers\BaseResourceController $csrfTokenName => $newTokenHash ]; return $this->respond($data); - } - else { + } else { return $this->failUnauthorized('Invalid request', 403); } } - public function updateCabecera($factura_id){ - - if($this->request->isAJAX()){ - if($factura_id == 0){ + public function updateCabecera($factura_id) + { + + if ($this->request->isAJAX()) { + if ($factura_id == 0) { return; } $factura = $this->model->find($factura_id); - if($factura){ + if ($factura) { $postData = $this->request->getPost(); $dataName = $postData['name'] ?? ''; $dataValue = $postData['value'] ?? ''; - if($dataName == 'factura_rectificativa_id'){ + if ($dataName == 'factura_rectificativa_id') { // se actualiza la factura donde el campo 'numero' sea igual al valor de $dataValue. El campo a actualizar es 'factura_rectificada_id' $factura_rectificada = $this->model->where('numero', $dataValue)->first(); - if($factura_rectificada){ + if ($factura_rectificada) { $data2 = [ 'factura_rectificada_id' => $factura->numero, 'user_updated_id' => auth()->user()->id, @@ -686,8 +841,7 @@ class Facturas extends \App\Controllers\BaseResourceController ]; return $this->respond($data); } - } - else { + } else { return $this->failUnauthorized('Invalid request', 403); } } @@ -696,12 +850,13 @@ class Facturas extends \App\Controllers\BaseResourceController * FUNCIONES AUXILIARES ************************************/ - private function obtenerDatosFormulario(&$factura){ - - if($factura->estado == 'borrador'){ + private function obtenerDatosFormulario(&$factura) + { + + if ($factura->estado == 'borrador') { $serieModel = model('App\Models\Configuracion\SeriesFacturasModel'); $serie = $serieModel->find($factura->serie_id); - if($serie){ + if ($serie) { $factura->numero = str_replace("{numero}", $serie->next, $serie->formato); } } @@ -716,9 +871,8 @@ class Facturas extends \App\Controllers\BaseResourceController $formaPagoModel = model('App\Models\Configuracion\FormaPagoModel'); $factura->formas_pago = $formaPagoModel->getMenuItems(); - + $factura->fecha_factura_at_text = $factura->fecha_factura_at ? date('d/m/Y', strtotime($factura->fecha_factura_at)) : ''; } } - \ No newline at end of file diff --git a/ci4/app/Controllers/Pedidos/Pedido.php b/ci4/app/Controllers/Pedidos/Pedido.php index 864933e1..08fd9325 100755 --- a/ci4/app/Controllers/Pedidos/Pedido.php +++ b/ci4/app/Controllers/Pedidos/Pedido.php @@ -2,6 +2,7 @@ namespace App\Controllers\Pedidos; use App\Controllers\BaseController; +use App\Controllers\Facturacion\Facturas; use App\Entities\Pedidos\PedidoEntity; use App\Models\Collection; use App\Models\Pedidos\PedidoModel; @@ -366,6 +367,74 @@ class Pedido extends \App\Controllers\BaseResourceController } } + + public function addFactura(){ + + if($this->request->isAJAX()){ + + + $modelFactura = model('App\Models\Facturas\FacturaModel'); + $modelFacturaLinea = model('App\Models\Facturas\FacturaLineaModel'); + + $pedido_id = $this->request->getPost('pedido_id'); + $serie_id = $this->request->getPost('serie_id'); + + $datosFactura = $this->model->obtenerDatosForFactura($pedido_id); + + if(count($datosFactura) == 0){ + return $this->respond(['status' => 'error', 'message' => 'Error obteniendo datos de factura']); + } + + $datosFactura = $datosFactura[0]; + + $modelFactura->insert([ + 'cliente_id' => $datosFactura->cliente_id, + 'serie_id' => $serie_id, + 'estado' => 'borrador', + 'estado_pago' => 'pendiente', + 'fecha_factura_at' => date('Y-m-d'), + 'cliente_nombre' => $datosFactura->cliente_nombre, + 'cliente_cif' => $datosFactura->cliente_cif, + 'cliente_pais' => $datosFactura->cliente_pais, + 'cliente_address' => $datosFactura->cliente_direccion, + 'cliente_cp' => $datosFactura->cliente_cp, + 'cliente_cuidad' => $datosFactura->cliente_ciudad, + 'cliente_provincia' => $datosFactura->cliente_provincia, + 'user_created_id' => auth()->user()->id, + 'user_updated_id' => auth()->user()->id + ]); + + $factura_id = $modelFactura->getInsertID(); + + if($factura_id){ + + $model_pedido_linea = model('\App\Models\Pedidos\PedidoLineaModel'); + $lineas = $model_pedido_linea->where('pedido_id', $pedido_id)->first(); + $facturas = new Facturas(); + $result = $facturas->addLineaPedidoImpresion($factura_id, $lineas->id); + if($result['error'] == 0){ + // Se actualiza el precio total de la factura obtenido de la linea añadida + $linea_added = $modelFacturaLinea->where('factura_id', $factura_id)->first(); + $modelFactura->set([ + 'base' => $linea_added->base, + 'total' => $linea_added->total, + 'pendiente' => $linea_added->total, + ])->where('id', $factura_id)->update(); + return $this->respond(['status' => 'success', 'id' => $factura_id, 'message' => lang('Basic.global.success')]); + }else{ + return $this->respond(['status' => 'error', 'message' => 'Error insertando lineas de factura']); + } + } + + return $this->respond(['status' => 'error', 'message' => 'Error insertando factura']); + + }else{ + return $this->failUnauthorized('Invalid request', 403); + } + + } + + private function obtenerDatosFormulario(&$pedidoEntity){ $datos = $this->model->obtenerDatosForm($pedidoEntity->id); diff --git a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php index e7741ab0..b25d3db9 100755 --- a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php +++ b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php @@ -605,8 +605,16 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController } } + // para el calculo del precio unidad, sólo se tiene en cuenta el envío base + for ($i = 0; $i < count($tirada); $i++) { + $coste_envio = 0.0; + $coste_envio += ($return_data['eb'][$i] / $tirada[$i]); + $return_data['precio_u'][$i] = round(floatval($return_data['precio_u'][$i]) + $coste_envio, 4); + } $envio_base = true; + $coste_envio = 0.0; // se inicializa para calcular los costes de envíos restantes si es que hay + $return_data['coste_envio'] = []; if (count($direcciones) > 0) { for ($i = 0; $i < count($tirada); $i++) { @@ -614,8 +622,6 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController foreach ($direcciones as $direccion) { // El primer envio no se calcula ya que se añade el base if ($envio_base) { - //aporte del envio al precio unidad - $coste_envio += ($return_data['eb'][$i] / $tirada[$i]); $envio_base = false; continue; } @@ -651,19 +657,17 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController ]; return $return_data; } else { - //aporte del envio al precio unidad - $coste_envio += ($coste_direccion->coste / $tirada[$i]); + // Se añade a los costes de envío + $coste_envio += $coste_direccion->coste; } } - $return_data['precio_u'][$i] = round(floatval($return_data['precio_u'][$i]) + $coste_envio, 4); + + $return_data['coste_envio'][$i] = round($coste_envio, 2); } - } else { - for ($i = 0; $i < count($tirada); $i++) { - $coste_envio = 0.0; - $coste_envio += ($return_data['eb'][$i] / $tirada[$i]); - $return_data['precio_u'][$i] = round(floatval($return_data['precio_u'][$i]) + $coste_envio, 4); - } - } + } + + + if ($this->request) { if ($this->request->isAJAX()) return $this->respond($return_data); @@ -1158,6 +1162,18 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController $resultado_presupuesto['info']['totales'][$i]['coste_envio'] = 0.0; $resultado_presupuesto['info']['totales'][$i]['margen_envio'] = 0.0; } + + // para el calculo del precio unidad, sólo se tiene en cuenta el envío base + for ($i = 0; $i < count($tirada); $i++) { + $coste_envio = 0.0; + $coste_envio += ($resultado_presupuesto['eb'][$i] / $tirada[$i]); + $resultado_presupuesto['info']['totales'][$i]['envio_base_coste'] = $resultado_presupuesto['eb'][$i] - $resultado_presupuesto['eb_margen'][$i]; + $resultado_presupuesto['info']['totales'][$i]['envio_base_margen'] = $resultado_presupuesto['eb_margen'][$i]; + $resultado_presupuesto['precio_u'][$i] = round(floatval($resultado_presupuesto['precio_u'][$i]) + $coste_envio, 4); + } + + $coste_envio = 0.0; // se inicializa para calcular los costes de envíos restantes si es que hay + $resultado_presupuesto['coste_envio'] = []; if (count($direcciones) > 0) { for ($i = 0; $i < count($tirada); $i++) { @@ -1168,11 +1184,6 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController foreach ($direcciones as $direccion) { // El primer envio no se calcula ya que se añade el base if ($envio_base) { - //aporte del envio al precio unidad - $coste_envio += ($resultado_presupuesto['eb'][$i] / $tirada[$i]); - $margen_envio += ($resultado_presupuesto['eb_margen'][$i] / $tirada[$i]); - $resultado_presupuesto['info']['totales'][$i]['coste_envio'] += $resultado_presupuesto['eb'][$i] - $resultado_presupuesto['eb_margen'][$i]; - $resultado_presupuesto['info']['totales'][$i]['margen_envio'] += $resultado_presupuesto['eb_margen'][$i]; $envio_base = false; continue; } @@ -1212,18 +1223,9 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController } } - $resultado_presupuesto['precio_u'][$i] = round(floatval($resultado_presupuesto['precio_u'][$i]) + $coste_envio, 4); + $resultado_presupuesto['coste_envio'][$i] = round($coste_envio, 2); } - } else { - for ($i = 0; $i < count($tirada); $i++) { - $coste_envio = 0.0; - $coste_envio += ($resultado_presupuesto['eb'][$i] / $tirada[$i]); - $resultado_presupuesto['info']['totales'][$i]['coste_envio'] = $resultado_presupuesto['eb'][$i] - $resultado_presupuesto['eb_margen'][$i]; - $resultado_presupuesto['info']['totales'][$i]['margen_envio'] = $resultado_presupuesto['eb_margen'][$i]; - $resultado_presupuesto['precio_u'][$i] = round(floatval($resultado_presupuesto['precio_u'][$i]) + $coste_envio, 4); - } - } - + } $model_presupuesto = new PresupuestoModel(); $tiradas_alternativas = []; @@ -1240,7 +1242,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController $resultado_presupuesto['info']['totales'][$i]['margenPapel'] + $resultado_presupuesto['info']['totales'][$i]['margen_envio']) / ($coste_total + $coste_envio) * 100.0, 2); $total_pedido = round(($coste_total + $resultado_presupuesto['info']['totales'][$i]['totalServicios'] + $resultado_presupuesto['info']['totales'][$i]['margenServicios'] + $coste_envio), 2); - $precio_u = round(($coste_total + $resultado_presupuesto['info']['totales'][$i]['totalServicios'] + $resultado_presupuesto['info']['totales'][$i]['margenServicios'] + $coste_envio) / $tirada[$i], 4); + $precio_u = round( $resultado_presupuesto['precio_u'][$i], 4); array_push($tiradas_alternativas, (object) array( 'tirada' => $tirada[$i], @@ -1252,6 +1254,8 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController )); } else { $resumen_totales = $resultado_presupuesto['info']['totales'][$i]; + $resumen_totales['precio_unidad'] = round($resultado_presupuesto['precio_u'][$i], 4); + } } @@ -1607,7 +1611,10 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController } if (intval($presupuesto->estado_id) == 2) { - $data['resumen']['base'] = $presupuesto->total_aceptado; + $data['resumen']['base'] = $presupuesto->total_antes_descuento; + $data['resumen']['total_envio'] = round( + floatval($presupuesto->total_coste_envios) + + floatval($presupuesto->total_margen_envios), 2); $data['resumen']['precio_unidad'] = $presupuesto->total_precio_unidad; } diff --git a/ci4/app/Controllers/Test.php b/ci4/app/Controllers/Test.php index 9e73792d..9ee22475 100755 --- a/ci4/app/Controllers/Test.php +++ b/ci4/app/Controllers/Test.php @@ -14,6 +14,8 @@ use App\Models\Usuarios\GroupModel; use App\Models\Usuarios\PermisosModel; use App\Services\PresupuestoService; use CodeIgniter\Shield\Entities\User; +use App\Models\Sistema\SettingsModel; + class Test extends BaseController { @@ -29,12 +31,48 @@ class Test extends BaseController public function index() { - - // (new Presupuestocliente())->testRemoteDB(); - (new Importadorpresupuestos())->getClientList(); + $this->sendMail('prueba', 'Esto es una prueba', ['jaimejimenezortega@gmail.com','jaime0jimenez0ortega@gmail.com']); + } + private function sendMail($subject, $body, $recipient) + { + $settings_model = new SettingsModel(); + $config = $settings_model->first()->toArray(); + $gateway = $config['email_gateway']; + $body = html_entity_decode($body); + if ($gateway == 'smtp') { + try { + //https://codeigniter.com/user_guide/libraries/email.html + $email = \Config\Services::email(); + $config['protocol'] = $config['email_gateway']; + $config['SMTPHost'] = $config['email_smtp']; + $config['SMTPUser'] = $config['email_address']; + $config['SMTPPass'] = $config['email_pass']; + $config['SMTPPort'] = intval($config['email_port']); + $config['SMTPCrypto'] = $config['email_cert'] == 'none' ? '' : $config['email_cert']; + $config['SMTPTimeout'] = 15; + $config['mailType'] = 'html'; + $config['wordWrap'] = true; + $email->initialize($config); + + $email->setFrom($config['email_address'], $config['email_name']); + $email->setTo($recipient); + + $email->setSubject($subject); + $email->setMessage($body); + + if (!$email->send()) { + return false; + } else { + return true; + } + } catch (\Exception $ex) { + return false; + } + } + return false; } private function clonar_tarifa_encuadernacion($teOrigen, $teDestino){ diff --git a/ci4/app/Language/es/App.php b/ci4/app/Language/es/App.php index eac95b5e..0704f891 100755 --- a/ci4/app/Language/es/App.php +++ b/ci4/app/Language/es/App.php @@ -757,6 +757,7 @@ return [ "menu_presupuestos_clientes" => "Presupuestos (Clientes)", "menu_presupuesto" => "Libros", "menu_presupuesto_buscador" => "Buscador", + "menu_presupuesto_importador" => "Importador ERP antiguo", "menu_libros" => "Libros", "menu_libros_fresasdo_tapa_dura" => "Fresado tapa dura", "menu_libros_fresasdo_tapa_blanda" => "Fresado tapa blanda", diff --git a/ci4/app/Language/es/Facturas.php b/ci4/app/Language/es/Facturas.php index 90e6962f..9be71bb4 100644 --- a/ci4/app/Language/es/Facturas.php +++ b/ci4/app/Language/es/Facturas.php @@ -41,6 +41,7 @@ return [ 'concepto' => 'Concepto', 'precioUnidad' => '€/u', 'iva' => 'IVA', + 'todos' => 'Todos', 'subtotal' => 'Subtotal', 'pendientePago' => 'Pendiente Pago', 'rectificativa' => 'Rectificativa', @@ -70,6 +71,7 @@ return [ "fechaVencimiento" => "Fecha Vencimiento", "fechaCobro" => "Fecha Cobro", "cantidad" => "Cantidad", + "ejemplares" => "Ejemplares", "addPago" => "Añadir Pago", "facturaPagada" => "Factura rectificativa ya abonada", diff --git a/ci4/app/Language/es/Pedidos.php b/ci4/app/Language/es/Pedidos.php index 25de0a9c..bb9fc447 100644 --- a/ci4/app/Language/es/Pedidos.php +++ b/ci4/app/Language/es/Pedidos.php @@ -77,10 +77,12 @@ return [ 'facturas' => 'Facturas', + 'addFactura' => 'Añadir Factura', 'showTotal' => 'Mostrar totales', - 'validation' => [ + 'validation' => [ + 'errorCantidadAlbaranes' => 'Total en albaranes {0} no coincide con la tirada {1}', ], diff --git a/ci4/app/Language/es/RolesPermisos.php b/ci4/app/Language/es/RolesPermisos.php index 9fbe24ba..9964d943 100644 --- a/ci4/app/Language/es/RolesPermisos.php +++ b/ci4/app/Language/es/RolesPermisos.php @@ -24,6 +24,8 @@ return [ 'editPermission' => 'Editar', 'deletePermission' => 'Eliminar', + 'toprodPermission' => 'Pasar a Producción', + // System sections 'clientesSection' => 'Clientes', 'plantillaTarifaSection' => 'Plantilla de tarifas', @@ -35,6 +37,7 @@ return [ 'pedidosFinalizadosSection' => 'Finalizados', 'pedidosCanceladosSection' => 'Cancelados', 'pedidosTodosSection' => 'Todos', + 'pedidosGestionSection' => 'Gestion', 'tarifaPreimpresionSection' => 'Tarifas de preimpresión', 'tarifaManipuladoSection' => 'Tarifas de manipulado', 'tarifaAcabadoSection' => 'Tarifas de acabado', diff --git a/ci4/app/Models/Facturas/FacturaLineaModel.php b/ci4/app/Models/Facturas/FacturaLineaModel.php index 2abb52e2..0254c301 100644 --- a/ci4/app/Models/Facturas/FacturaLineaModel.php +++ b/ci4/app/Models/Facturas/FacturaLineaModel.php @@ -49,7 +49,8 @@ class FacturaLineaModel extends \App\Models\BaseModel { ->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); + ->where("t1.deleted_at", null) + ->groupBy('t1.id'); return $builder; } diff --git a/ci4/app/Models/Facturas/FacturaModel.php b/ci4/app/Models/Facturas/FacturaModel.php index 80cc59e6..718f94f6 100644 --- a/ci4/app/Models/Facturas/FacturaModel.php +++ b/ci4/app/Models/Facturas/FacturaModel.php @@ -2,7 +2,10 @@ namespace App\Models\Facturas; -class FacturaModel extends \App\Models\BaseModel { +use CodeIgniter\Database\BaseBuilder; + +class FacturaModel extends \App\Models\BaseModel +{ protected $table = 'facturas'; @@ -26,9 +29,11 @@ class FacturaModel extends \App\Models\BaseModel { const SORTABLE_PEDIDOS = [ 1 => "t1.numero", 2 => "t2.nombre", - 3 => "t1.estado", - 4 => "t1.fecha_factura_at", - 5 => "t1.total", + 3 => "t4.cantidad", + 4 => "t2.nombre", + 5 => "t1.estado", + 6 => "t1.fecha_factura_at", + 7 => "t1.total", ]; // Lista de columnas basada en los campos de la tabla, para asignación masiva @@ -71,8 +76,8 @@ class FacturaModel extends \App\Models\BaseModel { protected $updatedField = "updated_at"; public static $labelField = "id"; - - public function getResource(string $search = "", $cliente_id=-1) + + public function getResource(string $search = "", $cliente_id = -1) { $builder = $this->db ->table($this->table . " t1") @@ -88,16 +93,16 @@ class FacturaModel extends \App\Models\BaseModel { $builder->join("clientes t2", "t2.id = t1.cliente_id", "left"); $builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left"); $builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left"); - + $builder->where("t1.deleted_at IS NULL"); - if(auth()->user()->inGroup("cliente-admin") || auth()->user()->inGroup("cliente-editor")) { + if (auth()->user()->inGroup("cliente-admin") || auth()->user()->inGroup("cliente-editor")) { $builder->where("t1.estado", "validada"); } - if($cliente_id != -1) { + if ($cliente_id != -1) { $builder->where("t1.cliente_id", $cliente_id); } - + $builder->groupBy("t1.id"); // Agrupa por id de la factura return empty($search) @@ -109,6 +114,37 @@ class FacturaModel extends \App\Models\BaseModel { ->groupEnd(); } + public function getDatatableQuery($cliente_id): BaseBuilder + { + $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, + t2.nombre AS cliente, 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, + GROUP_CONCAT(DISTINCT t4.nombre ORDER BY t4.nombre ASC SEPARATOR ', ') 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.vencimiento AS dias_vencimiento" + ); + $builder->join("clientes t2", "t2.id = t1.cliente_id", "left"); + $builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left"); + $builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left"); + + $builder->where("t1.deleted_at", null); + + if (auth()->user()->inGroup("cliente-admin") || auth()->user()->inGroup("cliente-editor")) { + $builder->where("t1.estado", "validada"); + } + + if ($cliente_id != -1) { + $builder->where("t1.cliente_id", $cliente_id); + } + + $builder->groupBy("t1.id"); + //$query = $builder->getCompiledSelect(); + return $builder; + } + /** * Get resource data for creating PDFs. @@ -151,6 +187,7 @@ class FacturaModel extends \App\Models\BaseModel { ->table($this->table . " t1") ->select( "t1.id AS id, t1.numero AS numero, t2.nombre AS serie, t1.estado AS estado, + t4.cantidad AS ejemplares, DATE_FORMAT(t1.fecha_factura_at, '%d/%m/%Y') AS fecha_factura_at, t1.total AS total" ); @@ -164,7 +201,7 @@ class FacturaModel extends \App\Models\BaseModel { $builder->where("t6.id", $pedido_id); $builder->groupBy("t1.id"); // Agrupa por id de la factura - + return $builder; } diff --git a/ci4/app/Models/Pedidos/PedidoModel.php b/ci4/app/Models/Pedidos/PedidoModel.php index 9c955f40..7f267388 100644 --- a/ci4/app/Models/Pedidos/PedidoModel.php +++ b/ci4/app/Models/Pedidos/PedidoModel.php @@ -71,10 +71,41 @@ class PedidoModel extends \App\Models\BaseModel $builder->join("clientes t4", "t4.id = t3.cliente_id", "left"); $builder->join("users t5", "t5.id = t4.comercial_id", "left"); + $builder->where("t1.id", $pedido_id); return $builder->get()->getResultObject(); } + public function obtenerDatosForFactura($pedido_id = -1){ + + $builder = $this->db + ->table($this->table . " t1") + ->select(" + t3.cliente_id, t4.nombre as cliente_nombre, t4.cif as cliente_cif, t4.direccion as cliente_direccion, + t5.nombre as cliente_pais, t4.cp as cliente_cp, t4.ciudad as cliente_ciudad, t6.nombre as cliente_provincia + " + ) + ->join("pedidos_linea t2", "t2.pedido_id = t1.id", "left") + ->join("presupuestos t3", "t2.presupuesto_id = t3.id", "left") + ->join("clientes t4", "t4.id = t3.cliente_id", "left") + ->join("lg_paises t5", "t5.id = t4.pais_id", "left") + ->join("lg_provincias t6", "t6.id = t4.provincia_id", "left"); + + $builder->where("t1.id", $pedido_id); + return $builder->get()->getResultObject(); + } + + public function addFacturaPedidoLinea($pedido_id, $factura_id, $cantidad) + { + return $this->db + ->table("facturas_pedidos_lineas") + ->insert([ + "factura_id" => $factura_id, + "pedido_id" => $pedido_id, + "cantidad" => $cantidad + ]); + } + public function obtenerLineasPedido($pedido_id) { $builder = $this->db @@ -90,6 +121,7 @@ class PedidoModel extends \App\Models\BaseModel foreach ($builder->get()->getResultObject() as $row) { array_push($lineasPresupuesto, $model_presupuesto->generarLineaPedido($row->presupuesto_id)[0]); } + $builder->groupBy("t1.id"); return $lineasPresupuesto; } diff --git a/ci4/app/Models/Presupuestos/PresupuestoModel.php b/ci4/app/Models/Presupuestos/PresupuestoModel.php index 341b10b9..de3a817b 100755 --- a/ci4/app/Models/Presupuestos/PresupuestoModel.php +++ b/ci4/app/Models/Presupuestos/PresupuestoModel.php @@ -404,9 +404,9 @@ class PresupuestoModel extends \App\Models\BaseModel $is_cosido = (new TipoPresupuestoModel())->get_isCosido($data['tipo_impresion_id']); $totalCostes = $resumen_totales['totalPapel'] + $resumen_totales['totalImpresion'] + - $resumen_totales['totalServicios'] + $resumen_totales['coste_envio']; + $resumen_totales['totalServicios'] + $resumen_totales['envio_base_coste']; $totalMargenes = $resumen_totales['margenPapel'] + $resumen_totales['margenImpresion'] + - $resumen_totales['margenServicios'] + $resumen_totales['margen_envio']; + $resumen_totales['margenServicios'] + $resumen_totales['envio_base_margen']; $fields = [ 'cliente_id' => $data['clienteId'], @@ -486,9 +486,9 @@ class PresupuestoModel extends \App\Models\BaseModel 'total_descuento' => 0, 'total_descuentoPercent' => 0, - 'total_precio_unidad' => round(($totalCostes + $totalMargenes) / $tirada, 4), - 'total_presupuesto' => round($totalCostes + $totalMargenes, 2), - 'total_aceptado' => round($totalCostes + $totalMargenes, 2), + 'total_precio_unidad' => $resumen_totales['precio_unidad'], + 'total_presupuesto' => round($totalCostes + $totalMargenes + $resumen_totales['coste_envio']+$resumen_totales['margen_envio'], 2), + 'total_aceptado' => round($totalCostes + $totalMargenes + $resumen_totales['coste_envio']+$resumen_totales['margen_envio'], 2), 'total_factor' => round(($totalCostes + $totalMargenes - $resumen_totales['coste_envio'] - $resumen_totales['margen_envio']) / $resumen_totales['sumForFactor'], 2), 'total_factor_ponderado' => round(($totalCostes + $totalMargenes - $resumen_totales['coste_envio'] - $resumen_totales['margen_envio']) / $resumen_totales['sumForFactorPonderado'], 2), diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php index 453074b7..c2db9dba 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php @@ -120,8 +120,7 @@ $('#addNewPedidoImpresion').on('click', function(){ // se ajustan el ancho de las columnas $('#pedidoImpresion').val(null).trigger('change'); // Se actualiza la tabla de lineas de factura - tableLineas.clearPipeline(); - $('#tableOfLineasFactura').DataTable().columns.adjust().draw(); + $('#tableOfLineasFactura').DataTable().clearPipeline().draw(); } }); }); diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php index cf98966d..3ef7a7d4 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php @@ -17,12 +17,12 @@ id - - - - - - + + + + + + @@ -395,6 +395,10 @@ var tableLineas = $('#tableOfLineasFactura').DataTable({ } ], + drawCallback: function() { + $(this.api().table().container()).find('table').css('width', '100%'); + this.api().columns.adjust(); + }, footerCallback: function (row, data, start, end, display) { updateFooterLineas(this.api()); } diff --git a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php index 297cb26e..0736152a 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php @@ -30,7 +30,7 @@ $facturaEntity->id,"type" => "factura"]) ?> -
+
estado =='borrador') : ?> include('themes/_commonPartialsBs/datatables') ?> +include('themes/_commonPartialsBs/datatables') ?> include('themes/_commonPartialsBs/_confirm2delete') ?> -extend('themes/vuexy/main/defaultlayout') ?> -section('content'); ?> +extend('themes/vuexy/main/defaultlayout') ?> +section('content'); ?>
-

-
+

+
- + - - - - - - - - - - + + +
+ + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - -
+ + + + + + + +
+ +
-endSection() ?> +endSection() ?> -section('additionalInlineJs') ?> - - const lastColNr = $('#tableOfFacturas').find("tr:first th").length - 1; - const actionBtns = function(data) { - if(data.estado == 'borrador'){ - return ` - -
- -
- `; - } - else{ - return ` - -
- -
- `; - } - }; - theTable = $('#tableOfFacturas').DataTable({ - processing: true, - serverSide: true, - autoWidth: true, - responsive: true, - scrollX: true, - lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ], - pageLength: 250, - lengthChange: true, - "dom": 'lfBrtip', - buttons: [ - { - text: 'Exportar Excel Contaplus', - action: function (e, dt, button, config) { - var searchValue = theTable.search(); // Captura el valor del campo de búsqueda - var ajaxParams = theTable.ajax.params(); // Captura otros parámetros de la tabla - - console.log(searchValue); - - /* - $.ajax({ - url: '/ruta/exportarExcel', // URL del servidor para manejar la exportación - type: 'POST', - data: { - search: searchValue, - extraParams: ajaxParams - }, - xhrFields: { - responseType: 'blob' // Para manejar la descarga del archivo - }, - success: function(blob, status, xhr) { - // Crear un enlace temporal para descargar el archivo - var link = document.createElement('a'); - var url = window.URL.createObjectURL(blob); - link.href = url; - link.download = 'datos_personalizados.xlsx'; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - window.URL.revokeObjectURL(url); - } - }); - */ - } - }, - { - text: 'Exportar Lineas a Excel', - action: function (e, dt, button, config) { - var searchValue = theTable.search(); // Captura el valor del campo de búsqueda - var ajaxParams = theTable.ajax.params(); // Captura otros parámetros de la tabla - - console.log(searchValue); - - } - }, - { - text: 'Exportar Girosgit ', - action: function (e, dt, button, config) { - var searchValue = theTable.search(); // Captura el valor del campo de búsqueda - var ajaxParams = theTable.ajax.params(); // Captura otros parámetros de la tabla - - console.log(searchValue); - - } - } - ], - stateSave: true, - order: [[0, 'asc']], - language: { - url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" - }, - ajax : $.fn.dataTable.pipeline( { - url: '', - method: 'POST', - data: function(d, settings){ - d.cliente_id = ""; - }, - headers: {'X-Requested-With': 'XMLHttpRequest'}, - async: true, - }), - columnDefs: [ - { - orderable: false, - searchable: false, - targets: [lastColNr] - } - ], - columns : [ - { 'data': 'id' }, - { 'data': 'numero' }, - { 'data': 'fecha_factura_at' }, - { 'data': 'cliente' }, - { 'data': 'base' ,render : (d) => `${d}`}, - { 'data': 'total',render : (d) => `${d}`}, - { 'data': 'pendiente',render : (d) => `${d}` }, - { 'data': 'creditoAsegurado' , - render: function(data, type, row, meta) { - switch(data){ - case "0": - return ''; - break; - - case "1": - return ''; - break; - - default: - return '--'; // Debug - break; - - } - }, - }, - { 'data': 'estado', - render: function(data, type, row, meta) { - switch(data){ - case "borrador": - return ''; - break; - - case "validada": - return ''; - break; - - default: - return '--'; // Debug - break; - - } - } - }, - { 'data': 'estado_pago', - render: function(data, type, row, meta) { - switch(data){ - case "pendiente": - return ''; - break; - - case "pagada": - return ''; - break; - - case "insolvente": - return ''; - break; - - default: - return '--'; // Debug - break; - - } - } - }, - { 'data': 'forma_pago', - render: function(data, type, row, meta) { - switch(data){ - case "cheque": - return ''; - break; - - case "compensada": - return ''; - break; - - case "confirming": - return ''; - break; - - case "giroDomiciliado": - return ''; - break; - - case "pagare": - return ''; - break; - - case "transferencia": - return ''; - break; - - default: - return data; // Debug - break; - - } - } - }, - { 'data': 'vencimiento' }, - { 'data': 'dias_vencimiento' }, - { 'data': actionBtns } - ] - }); - - theTable.on( 'draw.dt', function () { - if( != -1){ - theTable.column(3).visible(false); - theTable.column(7).visible(false); - theTable.column(8).visible(false); - theTable.column(9).visible(false); - theTable.column(10).visible(false); - theTable.column(11).visible(false); - theTable.column(12).visible(false); - } - }); - - - $(document).on('click', '.btn-edit', function(e) { - var url = ''; - url = url.replace(':id', `${$(this).attr('data-id')}` ); - window.location.href = url; - }); - - -endSection() ?> +section('additionalInlineJs') ?> -section('css') ?> - "> -endSection() ?> +window.datepickerLang = ; +window.datepickerLocale =''; + +endSection() ?> + + + +section('css') ?> +"> +"> + +endSection() ?> section('additionalExternalJs') ?> - - - - - - - -endSection() ?> + + + + + + + + + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/_albaranesItems.php b/ci4/app/Views/themes/vuexy/form/pedidos/_albaranesItems.php index d9306818..12049a0f 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/_albaranesItems.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/_albaranesItems.php @@ -10,7 +10,11 @@
- +
@@ -31,6 +35,8 @@ section('additionalInlineJs') ?> + + $('#generar_albaranes').on('click', function(){ var lineasPedido = $('#tableOfLineasPedido').DataTable(); @@ -51,6 +57,7 @@ $('#generar_albaranes').on('click', function(){ generarAlbaran(item); }); } + calcular_cantidades_albaranes(); } }); }) @@ -163,7 +170,7 @@ function generarAlbaran(item){ `; const table = $('', - { id: 'tablaAlbaran' + item.albaran.id, width:'100%', class: 'table table-responsive table-striped table-hover' }) + { id: 'tablaAlbaran' + item.albaran.id, width:'100%', class: 'table table-responsive table-striped table-hover table-albaran' }) .css({ 'width': '100%', }).append( @@ -238,7 +245,6 @@ function generarAlbaran(item){ $('#bonotes_albaranes').before(accordion); - const datatableAlbaran = new DataTable('#tablaAlbaran' + item.albaran.id,{ scrollX: true, searching: false, @@ -264,7 +270,7 @@ function generarAlbaran(item){ var input = $('', { id: 'cantidad_' + row.id, name: 'cantidad_' + row.id, - class: 'lp-cell lp-input albaran_linea', + class: 'lp-cell lp-input albaran_linea cantidad-albaran', albaran: item.albaran.numero_albaran, type: 'text', value: data, @@ -434,38 +440,6 @@ function generarAlbaran(item){ } }, - footerCallback: function (row, data, start, end, display) { - - /* - let api = this.api(); - var numColumns = api.columns().count(); - - if(item.albaran.mostrar_precios == 1){ - - // Remove the formatting to get integer data for summation - let intVal = function (i) { - return typeof i === 'string' - ? i.replace(/[\$,]/g, '') * 1 - : typeof i === 'number' - ? i - : 0; - }; - - // Total over all pages - total = api - .column(9) - .data() - .reduce((a, b) => intVal(a) + intVal(b), 0); - - // Update footer - api.column(numColumns-1).footer().innerHTML = - 'Total: ' + total.toFixed(2); - } - else{ - api.column(numColumns-1).footer().innerHTML = ''; - } - */ - }, }); // Añadir la nueva fila a la tabla @@ -474,6 +448,17 @@ function generarAlbaran(item){ datatableAlbaran.row.add(linea).draw(); }); } + + + $(document).on('change', '#tablaAlbaran' + item.albaran.id + ' .cantidad-albaran', function(){ + let table = $('#tablaAlbaran' + item.albaran.id).DataTable(); + let row = $(this).closest('tr'); // Encuentra la fila actual + let rowIndex = table.row(row).index(); // Obtiene el índice de la fila + let newValue = $(this).val(); // Obtiene el nuevo valor del input + // Actualiza el DataTable + table.cell(rowIndex, 2).data(newValue); + calcular_cantidades_albaranes(); + }); } $(document).on('click', '.accordion-button', function(){ @@ -712,7 +697,6 @@ $(document).on('click', '.imprimir-albaran', function(){ var albaran_id = $(this).attr('id').split('_').slice(-1)[0]; - //NACHO AQUI window.open('' + albaran_id, '_blank'); }); @@ -726,7 +710,37 @@ $.ajax({ Object.values(response.data).forEach(function(item){ generarAlbaran(item); }); + + calcular_cantidades_albaranes(); } } }); + + +function calcular_cantidades_albaranes(){ + let cantidad_albaranes = 0; + const tablas = $('.table.table-albaran'); + for(var i = 0; i < tablas.length; i++){ + var table = $(tablas[i]).DataTable(); + table.rows().every(function(){ + cantidad_albaranes += parseInt(this.data().cantidad) || 0; + }); + } + check_cantidad_albaranes(cantidad_albaranes); +} + +function check_cantidad_albaranes(unidades_albaranes){ + if(unidades_albaranes != parseInt($('#total_tirada').val()) ){ + $('#alert-albaranes').removeClass('d-none'); + $('#error-albaranes'). + html('' + .replace('{0}', unidades_albaranes) + .replace('{1}', $('#total_tirada').val())); + } + else{ + $('#alert-albaranes').addClass('d-none'); + $('#error-albaranes').html(''); + } +} + endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/_cabeceraItems.php b/ci4/app/Views/themes/vuexy/form/pedidos/_cabeceraItems.php index 3f255b31..9af77005 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/_cabeceraItems.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/_cabeceraItems.php @@ -152,6 +152,12 @@ + estado == 'validacion' && auth()->user()->can('pedidos-gestion.toprod')) : ?> +
+ + +
+ diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php b/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php index 03c61bc5..75d792a8 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php @@ -10,12 +10,19 @@
+ estado == 'finalizado') : ?> +
+ +
+ +
+ @@ -43,7 +50,7 @@ const actionBtns_facturas = function(data) { `; }; -tablaFacturasPedido = $('#tableOfFacturas').DataTable({ +window.tablaFacturasPedido = $('#tableOfFacturas').DataTable({ processing: true, serverSide: true, autoWidth: true, @@ -75,6 +82,7 @@ tablaFacturasPedido = $('#tableOfFacturas').DataTable({ { 'data': actionBtns_facturas }, { 'data': 'id' }, { 'data': 'numero' }, + { 'data': 'ejemplares'}, { 'data': 'serie' }, { 'data': 'estado', render: function(data, type, row, meta) { diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php b/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php index 89399796..3f23051b 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php @@ -96,6 +96,10 @@ var tableOfLineasPedido = new DataTable('#tableOfLineasPedido',{ orderable: false, }, ], + drawCallback: function(){ + $(this.api().table().container()).find('table').css('width', '100%'); + this.api().columns.adjust(); + }, footerCallback: function (row, data, start, end, display) { let api = this.api(); @@ -124,7 +128,7 @@ var tableOfLineasPedido = new DataTable('#tableOfLineasPedido',{ $(document).on('click', '.btn-view', function(e) { - user()->inGroup('admin') || auth()->user()->inGroup('beta')): ?> + user()->inGroup('cliente-admin') && !auth()->user()->inGroup('cliente-editor')): ?> var url = ''; var url = ''; diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php index d9c4e92c..be518321 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidoForm.php @@ -31,11 +31,6 @@
"btn btn-secondary float-start"]) ?>
- estado == 'finalizado') : ?> -
- -
-
@@ -70,6 +65,7 @@ href=""> + endSection() ?> @@ -89,4 +85,6 @@ + + endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/admin/_datosPresupuestoItems.php b/ci4/app/Views/themes/vuexy/form/presupuestos/admin/_datosPresupuestoItems.php index f99d60a1..615b2da0 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/admin/_datosPresupuestoItems.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/admin/_datosPresupuestoItems.php @@ -143,6 +143,7 @@
diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/items/_resumen.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/items/_resumen.php index 7eb9dee7..3f447a46 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/items/_resumen.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/items/_resumen.php @@ -5,9 +5,11 @@
Precio unidad:
-

Total base: € -

Iva (%): € -

Total: € +

Total base:

+

Envío:

+

Total antes de I.V.A:

+

Iva (%):

+

Total:

diff --git a/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php b/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php index 4a12a566..23abe408 100644 --- a/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php +++ b/ci4/app/Views/themes/vuexy/form/soporte/viewTicketForm.php @@ -86,13 +86,13 @@
diff --git a/ci4/app/Views/themes/vuexy/main/menus/presupuesto_menu.php b/ci4/app/Views/themes/vuexy/main/menus/presupuesto_menu.php index 0b253bdb..52af9ab7 100644 --- a/ci4/app/Views/themes/vuexy/main/menus/presupuesto_menu.php +++ b/ci4/app/Views/themes/vuexy/main/menus/presupuesto_menu.php @@ -23,27 +23,23 @@ if (auth()->user()->can('presupuesto.menu')) { - - - + \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/cliente/cliente.js b/httpdocs/assets/js/safekat/pages/cliente/cliente.js index a49e68ca..329c7726 100644 --- a/httpdocs/assets/js/safekat/pages/cliente/cliente.js +++ b/httpdocs/assets/js/safekat/pages/cliente/cliente.js @@ -61,9 +61,12 @@ class Cliente { document.addEventListener('DOMContentLoaded', function () { - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); - - + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['ClienteContactos', 'ClientePrecios'] }, {}, function(translations) { diff --git a/httpdocs/assets/js/safekat/pages/cliente/clienteList.js b/httpdocs/assets/js/safekat/pages/cliente/clienteList.js index 69b67ea9..6170c326 100644 --- a/httpdocs/assets/js/safekat/pages/cliente/clienteList.js +++ b/httpdocs/assets/js/safekat/pages/cliente/clienteList.js @@ -147,7 +147,12 @@ class ClienteList { document.addEventListener('DOMContentLoaded', function () { - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['Clientes', 'FormasPago', 'Users'] }, {}, function (translations) { diff --git a/httpdocs/assets/js/safekat/pages/facturas/facturasList.js b/httpdocs/assets/js/safekat/pages/facturas/facturasList.js new file mode 100644 index 00000000..d0c66bf1 --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/facturas/facturasList.js @@ -0,0 +1,199 @@ +$(() => { + + $(document).on('click', '.btn-edit', function (e) { + window.location.href = '/facturas/edit/' + $(this).attr('data-id'); + }); + + const lastColNr = $('#tableOfFacturas').find("tr:first th").length - 1; + + let datatableColumns = []; + if ($('#cliente_id').val() == -1) { + datatableColumns = [ + { 'data': 'id' }, + { 'data': 'numero' }, + { 'data': 'fecha_factura_at', searchable: false }, + { 'data': 'cliente' }, + { 'data': 'base', render: (d) => `${d}` }, + { 'data': 'total', render: (d) => `${d}` }, + { 'data': 'pendiente', render: (d) => `${d}` }, + { 'data': 'creditoAsegurado' }, + { 'data': 'estado' }, + { 'data': 'estado_pago' }, + { 'data': 'forma_pago' }, + { 'data': 'vencimiento' }, + { 'data': 'dias_vencimiento' }, + { 'data': 'action' } + ]; + } else { + datatableColumns = [ + { 'data': 'id' }, + { 'data': 'numero' }, + { 'data': 'fecha_factura_at', searchable: false }, + { 'data': 'base', render: (d) => `${d}` }, + { 'data': 'total', render: (d) => `${d}` }, + { 'data': 'pendiente', render: (d) => `${d}` }, + { 'data': 'action' } + ]; + } + + $('#tableOfFacturas').DataTable({ + processing: true, + serverSide: true, + autoWidth: true, + responsive: true, + scrollX: true, + orderCellsTop: true, + lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500], + pageLength: 250, + "dom": 'lBrtip', + buttons: [ + { + text: 'Exportar Excel Contaplus', + action: function (e, dt, button, config) { + var searchValue = theTable.search(); // Captura el valor del campo de búsqueda + var ajaxParams = theTable.ajax.params(); // Captura otros parámetros de la tabla + + console.log(searchValue); + + /* + $.ajax({ + url: '/ruta/exportarExcel', // URL del servidor para manejar la exportación + type: 'POST', + data: { + search: searchValue, + extraParams: ajaxParams + }, + xhrFields: { + responseType: 'blob' // Para manejar la descarga del archivo + }, + success: function(blob, status, xhr) { + // Crear un enlace temporal para descargar el archivo + var link = document.createElement('a'); + var url = window.URL.createObjectURL(blob); + link.href = url; + link.download = 'datos_personalizados.xlsx'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + } + }); + */ + } + }, + { + text: 'Exportar Lineas a Excel', + action: function (e, dt, button, config) { + var searchValue = theTable.search(); // Captura el valor del campo de búsqueda + var ajaxParams = theTable.ajax.params(); // Captura otros parámetros de la tabla + + console.log(searchValue); + + } + }, + { + text: 'Exportar Girosgit ', + action: function (e, dt, button, config) { + var searchValue = theTable.search(); // Captura el valor del campo de búsqueda + var ajaxParams = theTable.ajax.params(); // Captura otros parámetros de la tabla + + console.log(searchValue); + + } + } + ], + order: [[0, 'asc']], + language: { + url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" + }, + ajax: { + url: '/facturas/datatable', + type: 'GET', + data: function (d) { + d.cliente_id = $('#cliente_id').val(); + d.fecha_factura = getDate(); + } + }, + columnDefs: [ + { + orderable: false, + searchable: false, + targets: [lastColNr] + }, + ], + columns: datatableColumns, + }); + + $(document).on("keyup", ".factura-filter", (event) => { + //console.log(this.datatablePlanningRot.column($(event.currentTarget).attr("name"))) + let columnName = $(event.currentTarget).attr("name"); + let columnIndex = $('#tableOfFacturas').DataTable().columns().eq(0).filter(function (index) { + return $('#tableOfFacturas').DataTable().column(index).dataSrc() === columnName; + })[0]; + $('#tableOfFacturas').DataTable().column(columnIndex).search($(event.currentTarget).val()).draw() + }) + + $(document).on("change", ".factura-filter-select", (event) => { + let columnName = $(event.currentTarget).attr("name"); + let columnIndex = $('#tableOfFacturas').DataTable().columns().eq(0).filter(function (index) { + return $('#tableOfFacturas').DataTable().column(index).dataSrc() === columnName; + })[0]; + $('#tableOfFacturas').DataTable().column(columnIndex).search($(event.currentTarget).val()).draw(); + }); + + + + let bsRangePickerRange = $('#' + 'fechaFactura'); + bsRangePickerRange.daterangepicker({ + ranges: { + [window.datepickerLang.hoy]: [moment(), moment()], + [window.datepickerLang.ayer]: [moment().subtract(1, 'days'), moment().subtract(1, 'days')], + [window.datepickerLang.ultimos7]: [moment().subtract(6, 'days'), moment()], + [window.datepickerLang.ultimos30]: [moment().subtract(29, 'days'), moment()], + [window.datepickerLang.esteMes]: [moment().startOf('month'), moment().endOf('month')], + [window.datepickerLang.ultimoMes]: [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')] + }, + opens: 'right', + language: window.datepickerLocale, + "locale": { + "customRangeLabel": window.datepickerLang.rangoPersonalizado, + "format": "YYYY-MM-DD", + "separator": " ", + "applyLabel": window.datepickerLang.aplicar, + "cancelLabel": window.datepickerLang.limpiar, + + }, + "alwaysShowCalendars": true, + autoUpdateInput: false, + + }); + + + function getDate() { + + let picker = bsRangePickerRange.data('daterangepicker'); + + if (!picker || !picker.startDate || !picker.endDate || $('#fechaFactura').val() == '') { + return ''; + } + + let startDate = picker.startDate.format('YYYY-MM-DD'); + let endDate = picker.endDate.format('YYYY-MM-DD'); + + return startDate + "|" + endDate; + + } + + bsRangePickerRange.on('apply.daterangepicker', function (ev, picker) { + + $(this).val(picker.startDate.format('DD/MM/YYYY') + ' ' + picker.endDate.format('DD/MM/YYYY')); + let table = $('#tableOfFacturas').DataTable(); + table.column(2).draw(); + }); + + bsRangePickerRange.on('cancel.daterangepicker', function (ev, picker) { + $(this).val(''); + $('#tableOfFacturas').DataTable().column(2).search('').draw(); + }); + +}) \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/maquinas/maquinasList.js b/httpdocs/assets/js/safekat/pages/maquinas/maquinasList.js index da6760c3..8dac7849 100644 --- a/httpdocs/assets/js/safekat/pages/maquinas/maquinasList.js +++ b/httpdocs/assets/js/safekat/pages/maquinas/maquinasList.js @@ -182,7 +182,12 @@ class MaquinasList { document.addEventListener('DOMContentLoaded', function () { - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['Maquinas'] }, {}, function (translations) { diff --git a/httpdocs/assets/js/safekat/pages/pedidos/pedidos.js b/httpdocs/assets/js/safekat/pages/pedidos/pedidos.js new file mode 100644 index 00000000..555634b9 --- /dev/null +++ b/httpdocs/assets/js/safekat/pages/pedidos/pedidos.js @@ -0,0 +1,145 @@ +import Ajax from "../../components/ajax.js" + +class Pedidos { + + constructor() { + + this.total_ejemplares = 0; + this.total_facturado = 0; + + this.tableFacturas = $('#tableOfFacturas').DataTable(); + this.tablePedidos = $('#tableOfLineasPedido').DataTable(); + this.btnAddFactura = $('#add-factura'); + } + + init() { + + if (this.btnAddFactura) { + this.tableFacturas.on('draw', function () { + this.total_facturado = 0; + for (let i = 0; i < this.tableFacturas.rows().count(); i++) { + this.total_facturado += parseFloat(this.tableFacturas.row(i).data().ejemplares); + } + this.checkAddFactura(); + }.bind(this)); + + this.tablePedidos.on('draw', function () { + this.total_ejemplares = 0; + for (let i = 0; i < this.tablePedidos.rows().count(); i++) { + this.total_ejemplares += parseInt(this.tablePedidos.row(i).data().unidades); + } + this.checkAddFactura(); + }.bind(this)); + + this.btnAddFactura.on('click', this.addFacturaAction.bind(this)); + } + } + + addFacturaAction() { + + Swal.fire({ + title: 'Seleccione serie de facturación', + html: `
+
+ +
+
`, + showCancelButton: true, + cancelButtonText: 'Cancelar', + showDenyButton: false, + confirmButtonText: 'Ok', + showDenyButton: false, + buttonsStyling: false, + customClass: { + confirmButton: 'btn btn-primary', + cancelButton: 'btn btn-danger' + }, + didOpen: function () { + $('.serie-facturacion-select').select2({ + allowClear: false, + minimumResultsForSearch: -1, + //dropdownParent: $('#swal2-html-container'), + ajax: { + url: '/configuracion/series-facturas/menuitemsFacturas', + type: 'post', + dataType: 'json', + + data: function (params) { + return { + id: 'id', + text: 'nombre', + searchTerm: params.term, + + }; + }, + delay: 60, + processResults: function (response) { + return { + results: response.menu + }; + }, + cache: true + } + }); + }, + preConfirm: () => { + return $('#select-serie').val(); + } + }).then(result => { + if (result.isConfirmed) { + if (result.value != null && result.value != '' && result.value != 0) { + let id = window.location.pathname.split('/').pop(); + const ajax = new Ajax(`/pedidos/insertfactura`, + { + pedido_id: id, + serie_id: result.value, + + }, + null, + () => { + this.tableFacturas.clearPipeline().draw(); + }, + (error) => { + console.log("Error:", error); + } + ) + ajax.post(); + } + } + }); + } + + checkAddFactura() { + + if (this.total_facturado == this.total_ejemplares) { + this.btnAddFactura.addClass('d-none'); + } + else { + this.btnAddFactura.removeClass('d-none'); + } + }; +} + +$(document).ready(function () { + + /* + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } + new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['Presupuestos', 'PresupuestosDirecciones'] }, {}, + function (translations) { + window.language = JSON.parse(translations); + new PresupuestoAdminEdit().init(); + }, + function (error) { + console.log("Error getting translations:", error); + } + ).post();*/ + + new Pedidos().init(); +}); + +export default Pedidos; \ No newline at end of file diff --git a/httpdocs/assets/js/safekat/pages/plantillasTarifasCliente/edit.js b/httpdocs/assets/js/safekat/pages/plantillasTarifasCliente/edit.js index fdabc5ab..81d5952f 100644 --- a/httpdocs/assets/js/safekat/pages/plantillasTarifasCliente/edit.js +++ b/httpdocs/assets/js/safekat/pages/plantillasTarifasCliente/edit.js @@ -775,10 +775,13 @@ class PlantillasTarifasClienteForm { document.addEventListener('DOMContentLoaded', function () { - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); - - - + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } + new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['ClientePrecios'] }, {}, function (translations) { window.language = JSON.parse(translations); diff --git a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminAdd.js b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminAdd.js index 03f8cf38..d911e1dc 100644 --- a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminAdd.js +++ b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminAdd.js @@ -152,7 +152,7 @@ class PresupuestoAdminAdd { datos.papel_formato_alto = this.altoPersonalizado.val() } datos.selectedTirada = this.tirada.val(); - + return datos; } @@ -161,9 +161,9 @@ class PresupuestoAdminAdd { const tirada = parseInt($('#tirada').val()); const POD = parseInt($('#POD').val()); let merma = 0; - + merma = tirada * 0.1 <= POD ? tirada * 0.1 : POD; - + $('#mermacubierta').val(parseInt(merma)) $('#merma').val(parseInt(merma)) } @@ -172,8 +172,13 @@ class PresupuestoAdminAdd { document.addEventListener('DOMContentLoaded', function () { - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); - + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } + new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['Presupuestos', 'PresupuestosDirecciones'] }, {}, function (translations) { window.language = JSON.parse(translations); diff --git a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminEdit.js b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminEdit.js index 60ffaa21..1784b657 100644 --- a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminEdit.js +++ b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/presupuestoAdminEdit.js @@ -640,7 +640,12 @@ class PresupuestoAdminEdit { document.addEventListener('DOMContentLoaded', function () { - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } $(document).on("keydown", "textarea", function (event) { if (event.key === "Enter" && !event.shiftKey) { diff --git a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/datosGenerales.js b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/datosGenerales.js index f981d106..742aac2d 100644 --- a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/datosGenerales.js +++ b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/datosGenerales.js @@ -15,6 +15,8 @@ class DatosGenerales{ this.coleccion = this.domItem.find('#coleccion'); this.numeroEdicion = this.domItem.find('#numeroEdicion'); this.isbn = this.domItem.find('#isbn'); + + this.openCliente = this.domItem.find('#openCliente'); this.cliente = new ClassSelect($('#clienteId'), '/clientes/cliente/getSelect2', 'Seleccione cliente'); @@ -31,6 +33,11 @@ class DatosGenerales{ this.inc_rei.select2({ allowClear: false, }); + + this.openCliente.click(()=>{ + const urlObj = new URL(window.location.href); + window.open(`${urlObj.origin}` + '/clientes/cliente/edit/' + this.cliente.getVal()); + }); } cargarDatos(datos){ diff --git a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/resumen.js b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/resumen.js index cbc1c042..1e152889 100644 --- a/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/resumen.js +++ b/httpdocs/assets/js/safekat/pages/presupuestoAdmin/sections/resumen.js @@ -18,7 +18,7 @@ class Resumen { await self.updateTotales(); $(document).trigger('update-totales-completed'); }); - $("#totalDespuesDecuento").on('change',this.updateToastSummary.bind(this)) + $("#totalDespuesDecuento").on('change', this.updateToastSummary.bind(this)) } cargar(resumen) { @@ -26,7 +26,7 @@ class Resumen { // Mapear los valores a los elementos HTML por ID $("#totalCostePapel").text(resumen.total_coste_papel.toString().replace('.', ',') + "€" || "0€"); $("#porcentajeMargenPapel").text(resumen.total_margenPercent_papel ? resumen.total_margenPercent_papel.toString().replace('.', ',') + "%" : "0%"); - $("#margenPapel").text(resumen.total_margen_papel.toString().replace('.', ',')+ "€" || "0€"); + $("#margenPapel").text(resumen.total_margen_papel.toString().replace('.', ',') + "€" || "0€"); $("#totalCosteImpresion").text(resumen.total_coste_impresion.toString().replace('.', ',') + "€" || "0€"); $("#porcentajeMargenImpresion").text(resumen.total_margenPercent_impresion ? resumen.total_margenPercent_impresion.toString().replace('.', ',') + "%" : "0%"); @@ -56,7 +56,7 @@ class Resumen { $("#totalAceptado").val(resumen.total_aceptado.toString().replace('.', ',') + "€" || "0€"); } - $('#ivaReducido').val(resumen.iva_reducido ? 1: 0); + $('#ivaReducido').val(resumen.iva_reducido ? 1 : 0); } @@ -100,6 +100,7 @@ class Resumen { let margenServicios = parseFloat(0); let totalEnvios = 0; + let totalEnvios_base = 0; let margenEnvios = 0; let sumForFactor = 0.0; @@ -134,7 +135,7 @@ class Resumen { if (rowData.maquinaTipo == 'inkjet') { totalImpresion += parseFloat(rowData.totalTinta) - totalImpresion += parseFloat(rowData.totalCorte)?? 0; + totalImpresion += parseFloat(rowData.totalCorte) ?? 0; //sumForFactor += (parseFloat(rowData.totalTinta) + parseFloat(rowData.totalCorte)) } @@ -189,7 +190,7 @@ class Resumen { let margen_servicio = parseFloat(rowData.margen); totalServicios += total_servicio let base = self.roundToTwoDecimals(total_servicio / (1 + margen_servicio / 100.0)); - base = self.roundToTwoDecimals(base / parseInt($('#tirada').val()))*parseInt($('#tirada').val()); + base = self.roundToTwoDecimals(base / parseInt($('#tirada').val())) * parseInt($('#tirada').val()); margenServicios += self.roundToTwoDecimals(parseFloat(total_servicio - base)); }); } @@ -201,7 +202,7 @@ class Resumen { let margen_servicio = parseFloat(rowData.margen); totalServicios += total_servicio let base = self.roundToTwoDecimals(total_servicio / (1 + margen_servicio / 100.0)); - base = self.roundToTwoDecimals(base / parseInt($('#tirada').val()))*parseInt($('#tirada').val()); + base = self.roundToTwoDecimals(base / parseInt($('#tirada').val())) * parseInt($('#tirada').val()); margenServicios += self.roundToTwoDecimals(parseFloat(total_servicio - base)); }); } @@ -211,7 +212,7 @@ class Resumen { let rowData = this.data(); let total_servicio = self.roundToTwoDecimals(parseFloat(rowData.precio)); let base = (parseFloat(rowData.precio / (1 + parseFloat(rowData.margen) / 100.0)).toFixed(2)); - base = self.roundToTwoDecimals(base / parseInt($('#tirada').val()))*parseInt($('#tirada').val()); + base = self.roundToTwoDecimals(base / parseInt($('#tirada').val())) * parseInt($('#tirada').val()); margenServicios += self.roundToTwoDecimals(parseFloat(total_servicio - base)); totalServicios += total_servicio }); @@ -222,7 +223,7 @@ class Resumen { let rowData = this.data(); let total_servicio = self.roundToTwoDecimals(parseFloat(rowData.precio)); let base = (parseFloat(rowData.precio / (1 + parseFloat(rowData.margen) / 100.0)).toFixed(2)); - base = self.roundToTwoDecimals(base / parseInt($('#tirada').val()))*parseInt($('#tirada').val()); + base = self.roundToTwoDecimals(base / parseInt($('#tirada').val())) * parseInt($('#tirada').val()); margenServicios += self.roundToTwoDecimals(parseFloat(total_servicio - base)); totalServicios += total_servicio; }); @@ -235,7 +236,7 @@ class Resumen { let margen_servicio = parseFloat(rowData.margen); totalServicios += total_servicio let base = self.roundToTwoDecimals(total_servicio / (1 + margen_servicio / 100.0)); - base = self.roundToTwoDecimals(base / parseInt($('#tirada').val()))*parseInt($('#tirada').val()); + base = self.roundToTwoDecimals(base / parseInt($('#tirada').val())) * parseInt($('#tirada').val()); margenServicios += self.roundToTwoDecimals(parseFloat(total_servicio - base)); }); } @@ -262,15 +263,16 @@ class Resumen { if (updateEnvio) { - totalEnvios = parseFloat($('#envio_base').val()); + totalEnvios_base = parseFloat($('#envio_base').val()); if (typeof $('#tableOfDireccionesEnvio').DataTable() !== 'undefined' && $('#tableOfDireccionesEnvio').DataTable().rows().count() > 0) { $('#tableOfDireccionesEnvio').DataTable().rows().every(function (rowIdx, tableLoop, rowLoop) { - if (rowIdx == 0) { - return; + // el primer envio es el base, y no se debe de cobrar + if (rowIdx != 0) { + + let data = this.data() + totalEnvios += parseFloat(data.precio) + margenEnvios += parseFloat((data.precio) * data.margen / 100) } - let data = this.data() - totalEnvios += parseFloat(data.precio) - margenEnvios += parseFloat((data.precio) * data.margen / 100) }); } @@ -298,10 +300,11 @@ class Resumen { if ($('#total_descuentoPercent').val() < 0) { $('#total_descuentoPercent').val(0) } - let totalAntesDescuento = totalCostes + totalMargenes + let totalAntesDescuento = totalCostes + totalMargenes - parseFloat(totalEnvios.toFixed(2)) + totalEnvios_base; let totalDescuento = totalAntesDescuento * parseInt($('#total_descuentoPercent').val() || 0) / 100 - let totalPresupuesto = totalAntesDescuento - totalDescuento + let totalPresupuesto = totalAntesDescuento - totalDescuento; // para el calculo del precio_u solo se tiene en cuenta el base let precioUnidad = totalPresupuesto / parseInt($('#tirada').val()) + totalPresupuesto += totalEnvios; $('#totalAntesDescuento').text((this.addSeparatorsNF(totalAntesDescuento.toFixed(2), ".", ",", ".")) + "€") $('#descuentoTotal').text((this.addSeparatorsNF(totalDescuento.toFixed(2), ".", ",", ".")) + "€") @@ -313,15 +316,15 @@ class Resumen { $('#precioUnidadPresupuesto').attr('val', (precioUnidad).toFixed(4)) $('#totalDespuesDecuento').trigger("change") - $('#factor').text(this.addSeparatorsNF(((totalPresupuesto - totalEnvios - margenEnvios) / sumForFactor).toFixed(2), ".", ",", ".")) - $('#factor').attr('val', ((totalPresupuesto - totalEnvios - margenEnvios) / sumForFactor).toFixed(2)) - $('#factor_ponderado').text(this.addSeparatorsNF(((totalPresupuesto - totalEnvios - margenEnvios) / sumForFactorPonderado).toFixed(2), ".", ",", ".")) - $('#factor_ponderado').attr('val', ((totalPresupuesto - totalEnvios - margenEnvios) / sumForFactorPonderado).toFixed(2)) + $('#factor').text(this.addSeparatorsNF(((totalPresupuesto - totalEnvios - totalEnvios_base - margenEnvios) / sumForFactor).toFixed(2), ".", ",", ".")) + $('#factor').attr('val', ((totalPresupuesto - totalEnvios - totalEnvios_base - margenEnvios) / sumForFactor).toFixed(2)) + $('#factor_ponderado').text(this.addSeparatorsNF(((totalPresupuesto - totalEnvios - totalEnvios_base - margenEnvios) / sumForFactorPonderado).toFixed(2), ".", ",", ".")) + $('#factor_ponderado').attr('val', ((totalPresupuesto - totalEnvios - totalEnvios_base - margenEnvios) / sumForFactorPonderado).toFixed(2)) } - getData(){ + getData() { let data = { 'total_coste_papel': $('#totalCostePapel').text().replace('€', '').replace(',', '.'), @@ -354,7 +357,7 @@ class Resumen { 'iva_reducido': $('#ivaReducido').val() }; - if($('#confirmar_presupuesto').prop('checked')){ + if ($('#confirmar_presupuesto').prop('checked')) { data.confirmar = '1'; data.total_aceptado = $('#totalDespuesDecuento').text().replace('€', '').replace(',', '.'); } @@ -365,15 +368,14 @@ class Resumen { roundToTwoDecimals(num) { return parseFloat(num.toFixed(2)); } - updateToastSummary() - { - if(this.toastPresupuestoTotal){ + updateToastSummary() { + if (this.toastPresupuestoTotal) { this.toastPresupuestoTotal.close() } this.toastPresupuestoTotal = toastPresupuestoSummary($("#totalDespuesDecuento").text() ?? 0) this.toastPresupuestoTotal.fire().then((result) => { - if(result.isDismissed && result.dismiss == 'close'){ + if (result.isDismissed && result.dismiss == 'close') { this.updateToastSummary() $('html, body').animate( { diff --git a/httpdocs/assets/js/safekat/pages/presupuestoCliente/presupuestoCliente.js b/httpdocs/assets/js/safekat/pages/presupuestoCliente/presupuestoCliente.js index 8965dea4..f7d474c9 100644 --- a/httpdocs/assets/js/safekat/pages/presupuestoCliente/presupuestoCliente.js +++ b/httpdocs/assets/js/safekat/pages/presupuestoCliente/presupuestoCliente.js @@ -622,7 +622,8 @@ class PresupuestoCliente { ('precio-tiradas-' + response.tiradas[i]), response.tiradas[i], precio, - response.precio_u[i] + response.precio_u[i], + response.coste_envio[i] ); if (this.actualizarTiradasEnvio) { @@ -895,7 +896,10 @@ class PresupuestoCliente { $('#menu_resumen_button').trigger('click'); setTimeout(() => { self.resumen.init_dropzone(); - self.resumen.generate_total(response.data.resumen.base, response.data.resumen.precio_unidad, response.data.datosGenerales.ivaReducido); + self.resumen.generate_total(response.data.resumen.base, + response.data.resumen.precio_unidad, + response.data.resumen.total_envio, + response.data.datosGenerales.ivaReducido); }, 0); } }, 0); @@ -988,7 +992,12 @@ document.addEventListener('DOMContentLoaded', function () { } } - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } new Ajax('/translate/getTranslation', { locale: locale, translationFile: 'Presupuestos' }, {}, initialize, diff --git a/httpdocs/assets/js/safekat/pages/presupuestoCliente/resumen.js b/httpdocs/assets/js/safekat/pages/presupuestoCliente/resumen.js index 4c297776..0ccd5839 100644 --- a/httpdocs/assets/js/safekat/pages/presupuestoCliente/resumen.js +++ b/httpdocs/assets/js/safekat/pages/presupuestoCliente/resumen.js @@ -48,6 +48,8 @@ class Resumen { this.precio_unidad = $(this.domItem.find("#resumenPrecioU")); this.total_base = $(this.domItem.find("#resumenTotalBase")); + this.total_envios = $(this.domItem.find("#resumenTotalEnvio")); + this.total_antes_iva = $(this.domItem.find("#resumenTotalAntesIVA")); this.iva_porcentaje = $(this.domItem.find("#resumenIvaPorcentaje")); this.iva = $(this.domItem.find("#resumenIva")); this.total = $(this.domItem.find("#resumenTotal")); @@ -308,19 +310,26 @@ class Resumen { return parseInt($(this).find('.tarjeta-tiradas-precios-tirada').attr('data')) == unidades; }); + + let envios = tarjetaPrecio.find('.tarjeta-tiradas-precios-envio').val(); + this.total_envios.text(this.#changeDecimalFormat(parseFloat(envios).toFixed(2))); + let precio_u_text = tarjetaPrecio.find('.tarjeta-tiradas-precios-precio-unidad').text(); precio_u_text = precio_u_text.replace('€/ud', ''); const base = tarjetaPrecio.find('.tarjeta-tiradas-precios-precio').attr('data'); let base_text = this.#changeDecimalFormat(parseFloat(base).toFixed(2)); + const total_antes_iva_text = this.#changeDecimalFormat((parseFloat(base) + parseFloat(envios)).toFixed(2)); + const iva_porcentaje = parseInt(this.datosGenerales.ivaReducido.find('option:selected').val()) == 1 ? 0.04 : 0.21; - const iva = (parseFloat(base) * iva_porcentaje).toFixed(2); + const iva = ((parseFloat(base) + parseFloat(envios))* iva_porcentaje).toFixed(2); let iva_text = this.#changeDecimalFormat(iva); - const total = (parseFloat(base) + parseFloat(iva)).toFixed(2); + const total = (parseFloat(base) + parseFloat(envios) +parseFloat(iva)).toFixed(2); let total_text = this.#changeDecimalFormat(total); + this.precio_unidad.text(precio_u_text); this.total_base.text(base_text); this.iva_porcentaje.text(this.datosGenerales.ivaReducido.find('option:selected').val() == 1 ? '4' : '21'); @@ -329,23 +338,28 @@ class Resumen { } - generate_total(base, precio_u, iva_reducido) { + generate_total(base, precio_u, total_envio, iva_reducido) { let precio_u_text = String(precio_u); precio_u_text = precio_u_text.replace('€/u', ''); precio_u_text = this.#changeDecimalFormat(precio_u_text); let base_text = this.#changeDecimalFormat(String(base)); + let envios_text = this.#changeDecimalFormat(total_envio.toFixed(2)); + let total_antes_iva = parseFloat(base) + parseFloat(total_envio); + let total_antes_iva_text = this.#changeDecimalFormat(total_antes_iva.toFixed(2)); const iva_porcentaje = !iva_reducido? 0.21 : 0.04; - const iva = (parseFloat(base) * iva_porcentaje).toFixed(2); + const iva = ((parseFloat(base) + parseFloat(total_envio)) * iva_porcentaje).toFixed(2); let iva_text = this.#changeDecimalFormat(iva); - const total = (parseFloat(base) + parseFloat(iva)).toFixed(2); + const total = (parseFloat(base) + parseFloat(total_envio) + parseFloat(iva)).toFixed(2); let total_text = this.#changeDecimalFormat(total); this.precio_unidad.text(precio_u_text); this.total_base.text(base_text); + this.total_envios.text(envios_text); + this.total_antes_iva.text(total_antes_iva_text); this.iva_porcentaje.text(!iva_reducido? '21' : '4'); this.iva.text(iva_text); this.total.text(total_text); diff --git a/httpdocs/assets/js/safekat/pages/presupuestoCliente/tarjetaTiradasPrecio.js b/httpdocs/assets/js/safekat/pages/presupuestoCliente/tarjetaTiradasPrecio.js index 25e11ef5..1fbeead7 100644 --- a/httpdocs/assets/js/safekat/pages/presupuestoCliente/tarjetaTiradasPrecio.js +++ b/httpdocs/assets/js/safekat/pages/presupuestoCliente/tarjetaTiradasPrecio.js @@ -1,13 +1,14 @@ class tarjetaTiradasPrecio { - constructor(domItem, id, tirada, precio, precio_unidad) { + constructor(domItem, id, tirada, precio, precio_unidad, envio) { this.domItem = domItem; this.id = id; this.tirada = tirada; this.precio = precio; this.precio_unidad = precio_unidad; + this.envio = envio; - this.card = this.#generateHTML(id, tirada, precio, precio_unidad); + this.card = this.#generateHTML(id, tirada, precio, precio_unidad, envio); this.domItem.append(this.card); } @@ -15,7 +16,7 @@ class tarjetaTiradasPrecio { return value.toLocaleString("de-DE", { minimumFractionDigits: digits, maximumFractionDigits: digits }); } - #generateHTML(id, tirada, precio, precio_unidad) { + #generateHTML(id, tirada, precio, precio_unidad, envio) { let $html = $('
', { id: id, @@ -37,6 +38,7 @@ class tarjetaTiradasPrecio { const formattedPrecio = this.formatNumber(precio, 2); const formattedPrecioUnidad = this.formatNumber(precio_unidad, 4); + $listContent.append($('', { id: 'ud_' + id, @@ -56,6 +58,12 @@ class tarjetaTiradasPrecio { text: formattedPrecioUnidad + '€/ud' }).attr('data', precio_unidad)); + $listContent.append($('', { + id: 'envio_' + id, + type: 'hidden', + class: 'mb-1 tarjeta-tiradas-precios-envio', + }).val(envio)); + $liWrapper.append($listContent); $link.append($liWrapper); $html.append($link); diff --git a/httpdocs/assets/js/safekat/pages/soporte/tickets.js b/httpdocs/assets/js/safekat/pages/soporte/tickets.js index c442772f..f140db83 100644 --- a/httpdocs/assets/js/safekat/pages/soporte/tickets.js +++ b/httpdocs/assets/js/safekat/pages/soporte/tickets.js @@ -293,7 +293,12 @@ class Ticket { document.addEventListener('DOMContentLoaded', function () { - const locale = document.querySelector('meta[name="locale"]').getAttribute('content'); + const dropdown = document.querySelector(".dropdown-language"); + const activeItem = dropdown.querySelector(".dropdown-menu .dropdown-item"); + let locale = 'es'; + if (activeItem) { + locale = activeItem.getAttribute("data-language"); + } new Ajax('/translate/getTranslation', { locale: locale, translationFile: ['Tickets', 'datePicker'] }, {}, function (translations) { diff --git a/httpdocs/themes/vuexy/css/pedidos.css b/httpdocs/themes/vuexy/css/pedidos.css new file mode 100644 index 00000000..8e5e190c --- /dev/null +++ b/httpdocs/themes/vuexy/css/pedidos.css @@ -0,0 +1,9 @@ +.swal2-container { + overflow-y: visible !important; +} +.swal2-html-container { + overflow: visible !important; +} +.select2-dropdown { + z-index: 999999999 !important; +} \ No newline at end of file
ID