diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index f55032f7..9ddf7463 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -70,7 +70,6 @@ $routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion'] /* Series Factura */ $routes->group('series-facturas', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) { - $routes->get('', 'SeriesFacturas::index', ['as' => 'seriesFacturasList']); $routes->match(['get', 'post'], 'add', 'SeriesFacturas::add', ['as' => 'seriesFacturasAdd']); $routes->match(['get', 'post'], 'edit/(:num)', 'SeriesFacturas::edit/$1', ['as' => 'seriesFacturasEdit']); @@ -79,6 +78,15 @@ $routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion'] $routes->post('menuitemsFacturas', 'SeriesFacturas::menuItemsFacturas', ['as' => 'menuItemsOfSeriesFacturas']); }); + /* Formas de Pago */ + $routes->group('formas-pago', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) { + $routes->get('', 'FormasPago::index', ['as' => 'formasPagoList']); + $routes->match(['get', 'post'], 'add', 'FormasPago::add', ['as' => 'formasPagoAdd']); + $routes->match(['get', 'post'], 'edit/(:num)', 'FormasPago::edit/$1', ['as' => 'formasPagoEdit']); + $routes->get('delete/(:num)', 'FormasPago::delete/$1', ['as' => 'formasPagoDelete']); + $routes->post('datatable', 'FormasPago::datatable', ['as' => 'formasPagoDT']); + }); + }); @@ -655,13 +663,22 @@ $routes->group('facturas', ['namespace' => 'App\Controllers\Facturacion'], funct $routes->get('add', 'Facturas::add', ['as' => 'newFactura']); $routes->post('add', 'Facturas::add', ['as' => 'createFactura']); $routes->get('edit/(:any)', 'Facturas::edit/$1', ['as' => 'editarFactura']); + $routes->get('validar/(:any)', 'Facturas::validar/$1', ['as' => 'validarFactura']); $routes->post('update/(:any)', 'Facturas::update/$1', ['as' => 'actualizarFactura']); + $routes->post('duplicate/(:any)', 'Facturas::duplicate/$1', ['as' => 'duplicarFactura']); $routes->post('datatable/(:any)', 'FacturasLineas::datatable/$1', ['as' => 'dataTableOfLineasFacturas']); $routes->post('menuPedidosPendientes/(:num)', 'Facturas::menuPedidosPendientes/$1', ['as' => 'menuPedidosPendientesImpresion']); $routes->post('addLineaPedidoImpresion/(:num)', 'Facturas::addLineaPedidoImpresion/$1', ['as' => 'addLineaPedidoImpresion2Factura']); - $routes->post('addLineaPedidoImpresion/(:num)', 'Facturas::addLineaPedidoImpresion/$1', ['as' => 'addLineaPedidoImpresion2Factura']); + $routes->post('addExcedentes/(:any)', 'Facturas::addExcedentes/$1', ['as' => 'addLineaExcedentes']); $routes->get('deleteLinea/(:any)', 'FacturasLineas::deleteLinea/$1', ['as' => 'deleteLineaFactura']); + $routes->get('delete/(:any)', 'Facturas::delete/$1', ['as' => 'borrarFactura']); + $routes->post('deleteFacturaLineaPedido', 'Facturas::deleteLineaPedidoImpresion', ['as' => 'deleteLineaPedidoImpresion']); $routes->post('editorLineas', 'FacturasLineas::datatable_editor', ['as' => 'editorOfLineasFacturas']); + $routes->post('updateTotales/(:any)', 'Facturas::updateTotales/$1', ['as' => 'updateFacturaTotales']); + $routes->post('updateCabecera/(:any)', 'Facturas::updateCabecera/$1', ['as' => 'updateCabecera']); + $routes->post('datatablePagos/(:any)', 'FacturasPagos::datatable/$1', ['as' => 'dataTableOfPagosFacturas']); + $routes->post('editorPagos', 'FacturasPagos::datatable_editor', ['as' => 'editorOfPagosFacturas']); + $routes->post('datatablePedidos', 'Facturas::datatablePedidos', ['as' => 'dataTableOfFacturasPedido']); }); diff --git a/ci4/app/Controllers/Clientes/Cliente.php b/ci4/app/Controllers/Clientes/Cliente.php index 2f7faefa..678532c9 100755 --- a/ci4/app/Controllers/Clientes/Cliente.php +++ b/ci4/app/Controllers/Clientes/Cliente.php @@ -395,7 +395,7 @@ class Cliente extends \App\Controllers\BaseResourceController protected function getFormaDePagoListItems($selId = null) { - $data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('FormasPagoes.formaDePago'))])]; + $data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('FormasPago.formaDePago'))])]; if (!empty($selId)) : $formaPagoModel = model('App\Models\Configuracion\FormaPagoModel'); diff --git a/ci4/app/Controllers/Configuracion/Formaspagos.php b/ci4/app/Controllers/Configuracion/FormasPago.php old mode 100755 new mode 100644 similarity index 87% rename from ci4/app/Controllers/Configuracion/Formaspagos.php rename to ci4/app/Controllers/Configuracion/FormasPago.php index ef027110..a2867c59 --- a/ci4/app/Controllers/Configuracion/Formaspagos.php +++ b/ci4/app/Controllers/Configuracion/FormasPago.php @@ -9,7 +9,7 @@ use App\Entities\Configuracion\FormaPagoEntity; use App\Models\Configuracion\FormaPagoModel; -class Formaspagos extends \App\Controllers\BaseResourceController +class FormasPago extends \App\Controllers\BaseResourceController { protected $modelName = FormaPagoModel::class; @@ -22,15 +22,22 @@ class Formaspagos extends \App\Controllers\BaseResourceController protected static $controllerSlug = 'formas-pagos'; - protected static $viewPath = 'themes/vuexy/form/configuracion/formasPagoViews/'; + protected static $viewPath = 'themes/vuexy/form/configuracion/formas-pago/'; protected $indexRoute = 'formaDePagoList'; public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger) { - $this->viewData['pageTitle'] = lang('FormasPagoes.moduleTitle'); + $this->viewData['pageTitle'] = lang('FormasPago.moduleTitle'); $this->viewData['usingSweetAlert'] = true; + + // Breadcrumbs (IMN) + $this->viewData['breadcrumb'] = [ + ['title' => lang("App.menu_configuration"), 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("App.menu_formas_pago"), 'route' => route_to('formasPagoList'), 'active' => true] + ]; + parent::initController($request, $response, $logger); } @@ -40,7 +47,7 @@ class Formaspagos extends \App\Controllers\BaseResourceController $viewData = [ 'currentModule' => static::$controllerSlug, - 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('FormasPagoes.formaDePago')]), + 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('FormasPago.formaDePago')]), 'formaPagoEntity' => new FormaPagoEntity(), 'usingServerSideDataTable' => true, @@ -55,22 +62,15 @@ class Formaspagos extends \App\Controllers\BaseResourceController public function add() { - - - if ($this->request->getPost()) : - $nullIfEmpty = true; // !(phpversion() >= '8.1'); - $postData = $this->request->getPost(); - $sanitizedData = $this->sanitized($postData, $nullIfEmpty); - + $sanitizedData = $this->sanitized($postData, true); $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : - if ($this->canValidate()) : try { $successfulResult = $this->model->skipValidation(true)->save($sanitizedData); @@ -93,7 +93,8 @@ class Formaspagos extends \App\Controllers\BaseResourceController if ($thenRedirect) : if (!empty($this->indexRoute)) : - return redirect()->to(route_to($this->indexRoute))->with('sweet-success', $message); + return redirect()->to(site_url('/configuracion/formas-pago/edit/' . $id))->with('sweet-success', $message); + //return redirect()->to(route_to($this->indexRoute))->with('sweet-success', $message); else: return $this->redirect2listView('sweet-success', $message); endif; @@ -106,11 +107,8 @@ class Formaspagos extends \App\Controllers\BaseResourceController endif; // ($requestMethod === 'post') $this->viewData['formaPagoEntity'] = isset($sanitizedData) ? new FormaPagoEntity($sanitizedData) : new FormaPagoEntity(); - - $this->viewData['formAction'] = route_to('createFormaDePago'); - - $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('FormasPagoes.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix'); - + $this->viewData['formAction'] = route_to('formasPagoAdd'); + $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('FormasPago.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix'); return $this->displayForm(__METHOD__); } // end function add() @@ -125,25 +123,18 @@ class Formaspagos extends \App\Controllers\BaseResourceController $formaPagoEntity = $this->model->find($id); if ($formaPagoEntity == false) : - $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('FormasPagoes.formaDePago')), $id]); + $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('FormasPago.formaDePago')), $id]); return $this->redirect2listView('sweet-error', $message); endif; - - if ($this->request->getPost()) : - $nullIfEmpty = true; // !(phpversion() >= '8.1'); - $postData = $this->request->getPost(); - - $sanitizedData = $this->sanitized($postData, $nullIfEmpty); - + $sanitizedData = $this->sanitized($postData, true); $noException = true; if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : - if ($this->canValidate()) : try { $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); @@ -152,13 +143,12 @@ class Formaspagos extends \App\Controllers\BaseResourceController $this->dealWithException($e); } else: - $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('FormasPagoes.formaDePago'))]); + $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('FormasPago.formaDePago'))]); $this->session->setFlashdata('formErrors', $this->model->errors()); endif; $formaPagoEntity->fill($sanitizedData); - $thenRedirect = false; endif; if ($noException && $successfulResult) : @@ -179,11 +169,8 @@ class Formaspagos extends \App\Controllers\BaseResourceController endif; // ($requestMethod === 'post') $this->viewData['formaPagoEntity'] = $formaPagoEntity; - - $this->viewData['formAction'] = route_to('updateFormaDePago', $id); - - $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('FormasPagoes.moduleTitle') . ' ' . lang('Basic.global.edit3'); - + $this->viewData['formAction'] = route_to('formasPagoEdit', $id); + $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('FormasPago.moduleTitle') . ' ' . lang('Basic.global.edit3'); return $this->displayForm(__METHOD__, $id); } // end function edit(...) diff --git a/ci4/app/Controllers/Configuracion/SeriesFacturas.php b/ci4/app/Controllers/Configuracion/SeriesFacturas.php index 6dd1a0dc..f7618629 100644 --- a/ci4/app/Controllers/Configuracion/SeriesFacturas.php +++ b/ci4/app/Controllers/Configuracion/SeriesFacturas.php @@ -66,7 +66,6 @@ class SeriesFacturas extends BaseResourceController $noException = true; if ($successfulResult = $this->canValidate()) : - if ($this->canValidate()) : try { $successfulResult = $this->model->skipValidation(true)->save($sanitizedData); @@ -105,7 +104,6 @@ class SeriesFacturas extends BaseResourceController $this->viewData['formAction'] = route_to('seriesFacturasAdd'); $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('SeriesFacturas.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix'); - return $this->displayForm(__METHOD__); } // end function add() @@ -126,7 +124,6 @@ class SeriesFacturas extends BaseResourceController if ($this->request->getPost()) : $postData = $this->request->getPost(); - $sanitizedData = $this->sanitized($postData, true); if ($this->request->getPost('show_erp') == null) { $sanitizedData['show_erp'] = false; diff --git a/ci4/app/Controllers/Facturacion/Facturas.php b/ci4/app/Controllers/Facturacion/Facturas.php index 7f673e1e..d21c2bf2 100755 --- a/ci4/app/Controllers/Facturacion/Facturas.php +++ b/ci4/app/Controllers/Facturacion/Facturas.php @@ -143,6 +143,11 @@ class Facturas extends \App\Controllers\BaseResourceController helper('form'); + + $this->viewData['breadcrumb'] = [ + ['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; @@ -168,9 +173,15 @@ class Facturas extends \App\Controllers\BaseResourceController $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Facturas.factura')), $id]); return $this->redirect2listView('sweet-error', $message); endif; + $this->obtenerDatosFormulario($factura); + $this->viewData['breadcrumb'] = [ + ['title' => lang("App.menu_facturas"), 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("Facturas.facturaList"), 'route' => route_to('facturasList'), 'active' => true] + ]; + $this->viewData['facturaEntity'] = $factura; $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Facturas.factura') . ' ' . lang('Basic.global.edit3'); @@ -207,6 +218,38 @@ class Facturas extends \App\Controllers\BaseResourceController } } + + public function datatablePedidos(){ + + if ($this->request->isAJAX()) { + + $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_PEDIDOS[$requestedOrder >= 0 ? $requestedOrder : 0]; + $dir = $reqData['order']['0']['dir'] ?? 'asc'; + + $pedido_id = $reqData['pedido_id'] ?? 0; + + $resourceData = $this->model->getResourcePedidos($pedido_id)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject(); + + return $this->respond(Collection::datatable( + $resourceData, + $this->model->getResourcePedidos($pedido_id)->countAllResults(), + $this->model->getResourcePedidos($pedido_id)->countAllResults() + )); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + public function update($id = null){ if ($this->request->isAJAX()) { @@ -313,6 +356,123 @@ class Facturas extends \App\Controllers\BaseResourceController } } + public function duplicate($factura_id = 0){ + if($this->request->isAJAX()){ + + $factura_origen = $this->model->find($factura_id); + // se quita la key "id" del objeto + unset($factura_origen->id); + $factura_origen->estado = 'borrador'; + $factura_origen->estado_pago = 'pendiente'; + $factura_origen->base = 0; + $factura_origen->total = 0; + $factura_origen->pendiente = 0; + $factura_origen->total_pagos = 0; + $factura_origen->user_created_id = auth()->user()->id; + $factura_origen->user_updated_id = null; + + $this->model->insert($factura_origen); + $id = $this->model->getInsertID(); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + 'id' => $id, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + + }else{ + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function updateTotales($factura_id = 0){ + if($this->request->isAJAX()){ + + $postData = $this->request->getPost(); + + $pendiente = $postData['pendiente'] ?? 0; + $total = $postData['total'] ?? 0; + + $data = [ + 'base' => $postData['base'] ?? 0, + 'total' => $total, + 'pendiente' => $pendiente, + 'total_pagos' => $postData['total_pagos'] ?? 0, + 'user_updated_id' => auth()->user()->id, + 'estado_pago' => (intval($pendiente)==0 && intval($total)!=0) ? 'pagada' : 'pendiente', + ]; + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data_ret = [ + $csrfTokenName => $newTokenHash + ]; + + 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->failUnauthorized('Invalid request', 403); + } + } + + public function addExcedentes($factura_id){ + + if ($this->request->isAJAX()) { + $model_factura_linea = model('\App\Models\Facturas\FacturaLineaModel'); + + $postData = $this->request->getPost(); + $cantidad = $postData['cantidad'] ?? 0; + $precio_unidad = $postData['precio_unidad'] ?? 0; + $iva = $postData['iva'] ?? 0; + $descripcion = $postData['descripcion'] ?? ''; + $descuento = $postData['descuento'] ?? 0; + $pedido_linea_impresion_id = $postData['pedido_linea_impresion_id'] ?? null; + $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); + $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, + '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(); + $csrfTokenName = csrf_token(); + $data_ret = [ + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data_ret); + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } public function addLineaPedidoImpresion($factura_id){ @@ -324,48 +484,55 @@ class Facturas extends \App\Controllers\BaseResourceController try{ $pedido_linea_id = $this->request->getPost('lineaPedido') ?? 0; $linea = $model_pedido_linea->find($pedido_linea_id); + + $factura = $this->model->find($factura_id); - 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($this->model->getCantidadLineaPedidoFacturada($linea->id)); - $base = $cantidad * floatval($presupuesto->total_precio_unidad); - $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; + if($factura){ - $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, - ]; + if($linea){ + $presupuesto = $model_presupuesto->find($linea->presupuesto_id); - $model_factura_linea->insert($data); + 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; - $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 + $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, ]; - return $this->respond($data); + + $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); + } } } } @@ -386,6 +553,113 @@ class Facturas extends \App\Controllers\BaseResourceController } } + public function deleteLineaPedidoImpresion(){ + + if ($this->request->isAJAX()) { + + $postData = $this->request->getPost(); + $factura_id = $postData['factura_id'] ?? 0; + $linea_id = $postData['linea_id'] ?? 0; + $cantidad = $postData['cantidad'] ?? 0; + + $model_factura_linea = model('\App\Models\Facturas\FacturaLineaModel'); + $model_factura_linea->deleteFacturasLineasPedido($factura_id, $linea_id, $cantidad); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function validar($factura_id){ + + if($this->request->isAJAX()){ + + $factura = $this->model->find($factura_id); + + if($factura){ + $model_series = model('\App\Models\Configuracion\SeriesFacturasModel'); + $numero = $model_series->getSerieNumerada($factura->serie_id); + + $data = [ + 'estado' => 'validada', + 'numero' => $numero, + 'user_updated_id' => auth()->user()->id, + ]; + + if((strpos($numero, "REC ") === 0)){ + $data['estado_pago'] = 'pagada'; + } + + $this->model->update($factura_id, $data); + } + + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function updateCabecera($factura_id){ + + if($this->request->isAJAX()){ + if($factura_id == 0){ + return; + } + $factura = $this->model->find($factura_id); + if($factura){ + $postData = $this->request->getPost(); + + $dataName = $postData['name'] ?? ''; + $dataValue = $postData['value'] ?? ''; + + 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){ + $data2 = [ + 'factura_rectificada_id' => $factura->numero, + 'user_updated_id' => auth()->user()->id, + ]; + $this->model->update($factura_rectificada->id, $data2); + } + } + + $data = [ + $dataName => $dataValue, + 'user_updated_id' => auth()->user()->id, + ]; + + $this->model->update($factura_id, $data); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + /************************************* * FUNCIONES AUXILIARES ************************************/ @@ -407,6 +681,9 @@ class Facturas extends \App\Controllers\BaseResourceController $serieModel = model('App\Models\Configuracion\SeriesFacturasModel'); $serie = $serieModel->find($factura->serie_id); $factura->serie_nombre = $serie->nombre; + + $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)) : ''; } diff --git a/ci4/app/Controllers/Facturacion/FacturasLineas.php b/ci4/app/Controllers/Facturacion/FacturasLineas.php index 22ae8580..21ae2c0a 100644 --- a/ci4/app/Controllers/Facturacion/FacturasLineas.php +++ b/ci4/app/Controllers/Facturacion/FacturasLineas.php @@ -83,96 +83,100 @@ class FacturasLineas extends \App\Controllers\BaseResourceController include(APPPATH . "ThirdParty/DatatablesEditor/DataTables.php"); - // Build our Editor instance and process the data coming from _POST - $response = Editor::inst( $db, 'cliente_plantilla_precios_lineas' ) + $response = Editor::inst( $db, 'facturas_lineas' ) ->fields( - Field::inst( 'plantilla_id' ), - Field::inst( 'tipo' ), - Field::inst( 'tipo_maquina' ), - Field::inst( 'tipo_impresion' ), + Field::inst( 'id' ), + Field::inst( 'base' ), + Field::inst( 'total_iva' ), + Field::inst( 'total' ), + Field::inst( 'cantidad' ) + ->validator('Validate::numeric', array( + 'message' => lang('Facturas.validation.numerico')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'descripcion' ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'precio_unidad' ) + ->getFormatter( 'Format::toDecimalChar')->setFormatter( 'Format::fromDecimalChar') + ->validator('Validate::numeric', array( + "decimal" => ',', + 'message' => lang('Facturas.validation.decimal')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'iva' ) + ->validator('Validate::numeric', array( + 'message' => lang('Facturas.validation.numerico')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'pedido_linea_impresion_id' ) + ->setFormatter(function($val, $data, $opts) { + return $val === '' ? null : $val; + }), + Field::inst( 'factura_id' ), Field::inst( 'user_updated_id' ), - Field::inst( 'updated_at' ), - Field::inst( 'tiempo_min' ) - ->getFormatter( 'Format::toDecimalChar')->setFormatter( 'Format::fromDecimalChar') - ->validator( 'Validate::notEmpty',array( - 'message' => lang('ClientePrecios.validation.required')) - ) - ->validator('Validate::numeric', array( - "decimal" => ',', - 'message' => lang('ClientePrecios.validation.decimal')) - ), - - Field::inst( 'tiempo_max' ) - ->getFormatter( 'Format::toDecimalChar')->setFormatter( 'Format::fromDecimalChar') - ->validator( 'Validate::notEmpty',array( - 'message' => lang('ClientePrecios.validation.required')) - ) - ->validator('Validate::numeric', array( - "decimal" => ',', - 'message' => lang('ClientePrecios.validation.decimal')) - ), - - Field::inst( 'precio_hora' ) - ->getFormatter( 'Format::toDecimalChar')->setFormatter( 'Format::fromDecimalChar') - ->validator( 'Validate::notEmpty',array( - 'message' => lang('ClientePrecios.validation.required')) - ) - ->validator('Validate::numeric', array( - "decimal" => ',', - 'message' => lang('ClientePrecios.validation.decimal')) - ), - - Field::inst( 'margen' ) - ->getFormatter( 'Format::toDecimalChar')->setFormatter( 'Format::fromDecimalChar') - ->validator( 'Validate::notEmpty',array( - 'message' => lang('ClientePrecios.validation.required')) - ) - ->validator('Validate::numeric', array( - "decimal" => ',', - 'message' => lang('ClientePrecios.validation.decimal')) - ), - ) - ->validator(function ($editor, $action, $data) { - if ($action === Editor::ACTION_CREATE || $action === Editor::ACTION_EDIT) { - foreach ($data['data'] as $pkey => $values) { - // Si no se quiere borrar... - if ($data['data'][$pkey]['is_deleted'] != 1) { - $process_data['tiempo_min'] = $data['data'][$pkey]['tiempo_min']; - $process_data['tiempo_max'] = $data['data'][$pkey]['tiempo_max']; - $process_data['tipo'] = $data['data'][$pkey]['tipo']; - $process_data['tipo_maquina'] = $data['data'][$pkey]['tipo_maquina']; - $process_data['tipo_impresion'] = $data['data'][$pkey]['tipo_impresion']; - - $response = $this->model->checkIntervals($process_data, $pkey, $data['data'][$pkey]['plantilla_id']); - // No se pueden duplicar valores al crear o al editar - if (!empty($response)) { - return $response; - } - } - } - } - }) ->on('preCreate', function ($editor, &$values) { - $session = session(); - $datetime = (new \CodeIgniter\I18n\Time("now")); + $totales = $this->generate_totales( + $values['factura_id'], + $values['pedido_linea_impresion_id'], + $values['precio_unidad'], + $values['iva'], + $values['cantidad'], + $values['old_cantidad']); $editor ->field('user_updated_id') - ->setValue($session->id_user); + ->setValue(auth()->user()->id); $editor - ->field('updated_at') - ->setValue($datetime->format('Y-m-d H:i:s')); + ->field('base') + ->setValue($totales['base']); + $editor + ->field('total_iva') + ->setValue($totales['total_iva']); + $editor + ->field('total') + ->setValue($totales['total']); + $editor + ->field('user_updated_id') + ->setValue(auth()->user()->id); }) - ->on('preEdit', function ($editor, &$values) { - $session = session(); - $datetime = (new \CodeIgniter\I18n\Time("now")); + ->on('preEdit', function ($editor, $id, &$values) { + $totales = $this->generate_totales( + $values['factura_id'], + $values['pedido_linea_impresion_id'], + $values['precio_unidad'], + $values['iva'], + $values['cantidad'], + $values['old_cantidad']); + $editor + ->field('factura_id') + ->setValue($values['factura_id']); + $editor + ->field('pedido_linea_impresion_id') + ->setValue(null); + $editor + ->field('pedido_maquetacion_id') + ->setValue(null); $editor ->field('user_updated_id') - ->setValue($session->id_user); + ->setValue(auth()->user()->id); $editor - ->field('updated_at') - ->setValue($datetime->format('Y-m-d H:i:s')); + ->field('base') + ->setValue($totales['base']); + $editor + ->field('total_iva') + ->setValue($totales['total_iva']); + $editor + ->field('total') + ->setValue($totales['total']); }) ->debug(true) ->process($_POST) @@ -189,4 +193,36 @@ class FacturasLineas extends \App\Controllers\BaseResourceController return $this->failUnauthorized('Invalid request', 403); } } -} \ No newline at end of file + + public function updateTotalesFactura($factura_id = 0){ + if($factura_id == 0){ + return; + } + + $model = model('\App\Models\Facturas\FacturaModel'); + $model->updateTotales($factura_id); + } + + private function generate_totales($factura_id, $pedido_linea_id, $precio_unidad, $iva, $cantidad, $old_cantidad) + { + + // si es una linea que se refiere a pedido + if ($pedido_linea_id != null && $factura_id != null) { + // se actualiza la cantidad de la linea de pedido en la tabla pivote facturas_pedidos_lineas + $this->model->updateFacturaPedidoLinea($factura_id, $pedido_linea_id, $old_cantidad, $cantidad); + } + + // se calcula y se actualiza el subtotal, total_iva y total + // redondeando a 4 decimales el precio_unidad y a dos el resto + $base = round($precio_unidad * $cantidad, 2); + $total_iva = round($base * $iva / 100, 2); + $total = round($base + $total_iva, 2); + $values = []; + $values['base'] = $base; + $values['total_iva'] = $total_iva; + $values['total'] = $total; + + return $values; + } +} + diff --git a/ci4/app/Controllers/Facturacion/FacturasPagos.php b/ci4/app/Controllers/Facturacion/FacturasPagos.php new file mode 100644 index 00000000..a7559933 --- /dev/null +++ b/ci4/app/Controllers/Facturacion/FacturasPagos.php @@ -0,0 +1,142 @@ +request->isAJAX() && $factura_id != null) { + + $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'; + + $resourceData = $this->model->getResource($factura_id)->orderBy(1, $dir)->limit($length, $start)->get()->getResultObject(); + + return $this->respond(Collection::datatable( + $resourceData, + $this->model->getResource($factura_id)->countAllResults(), + $this->model->getResource($factura_id)->countAllResults() + )); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function datatable_editor() { + if ($this->request->isAJAX()) { + + include(APPPATH . "ThirdParty/DatatablesEditor/DataTables.php"); + + // Build our Editor instance and process the data coming from _POST + $response = Editor::inst( $db, 'facturas_pagos' ) + ->fields( + Field::inst( 'id' ), + Field::inst( 'forma_pago_id' ), + Field::inst( 'notes' ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'fecha_pago_at' ) + ->validator( Validate::dateFormat( 'Y-m-d H:i:s' ) ) + ->getFormatter( Format::dateSqlToFormat( 'Y-m-d H:i:s' ) ) + ->setFormatter( Format::dateFormatToSql( 'Y-m-d H:i:s' ) ), + Field::inst( 'fecha_vencimiento_at' ) + ->validator( Validate::dateFormat( 'Y-m-d H:i:s' ) ) + ->getFormatter( Format::dateSqlToFormat( 'Y-m-d H:i:s' ) ) + ->setFormatter( Format::dateFormatToSql( 'Y-m-d H:i:s' ) ), + Field::inst( 'total' ) + ->validator('Validate::numeric', array( + 'message' => lang('Facturas.validation.numerico')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'factura_id' ), + Field::inst( 'user_updated_id' ), + ) + ->on('preCreate', function ($editor, &$values) { + /* + $editor + ->field('user_updated_id') + ->setValue(auth()->user()->id); + $editor + ->field('base') + ->setValue($totales['base']); + $editor + ->field('total_iva') + ->setValue($totales['total_iva']); + $editor + ->field('total') + ->setValue($totales['total']); + $editor + ->field('user_updated_id') + ->setValue(auth()->user()->id); + */ + }) + ->on('preEdit', function ($editor, $id, &$values) { + /* + $editor + ->field('factura_id') + ->setValue($values['factura_id']); + $editor + ->field('pedido_linea_impresion_id') + ->setValue(null); + $editor + ->field('pedido_maquetacion_id') + ->setValue(null); + $editor + ->field('user_updated_id') + ->setValue(auth()->user()->id); + $editor + ->field('base') + ->setValue($totales['base']); + $editor + ->field('total_iva') + ->setValue($totales['total_iva']); + $editor + ->field('total') + ->setValue($totales['total']); + */ + }) + ->debug(true) + ->process($_POST) + ->data(); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + $response[$csrfTokenName] = $newTokenHash; + + echo json_encode($response); + + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + +} \ No newline at end of file diff --git a/ci4/app/Controllers/Pedidos/Pedido.php b/ci4/app/Controllers/Pedidos/Pedido.php index bc8254dd..647ff134 100755 --- a/ci4/app/Controllers/Pedidos/Pedido.php +++ b/ci4/app/Controllers/Pedidos/Pedido.php @@ -245,13 +245,31 @@ class Pedido extends \App\Controllers\BaseResourceController $estado = $reqData['estado'] ?? 'todos'; if($estado == 'todos') $estado = ''; - $model_linea = model('\App\Models\Pedidos\PedidoLineaModel'); - $resourceData = $model_linea->getResource($search, $estado)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject(); + $showTotal = $reqData['showTotal'] ?? false; + $searchValues = get_filter_datatables_columns($reqData); + + $model_linea = model('\App\Models\Pedidos\PedidoLineaModel'); + $resourceData = $model_linea->getResource($searchValues, $estado)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject(); + $totalTirada = $model_linea->getSumOfTirada($searchValues, $estado, $start, $length); + $total = $model_linea->getSumOfTotalAceptado($searchValues, $estado, $start, $length); + $total2 = 0; + if($showTotal){ + $total2 = $model_linea->getTotalOfTotalAceptado(); + } + + if($total2 != 0){ + $total = "" . $total . " \n(" . $total2 . ")"; + } return $this->respond(Collection::datatable( $resourceData, $model_linea->getResource("", $estado)->countAllResults(), - $model_linea->getResource($search, $estado)->countAllResults() + $model_linea->getResource($searchValues, $estado)->countAllResults(), + "", + [ + 'total_tirada' => $totalTirada, + 'total' => $total + ] )); } else { return $this->failUnauthorized('Invalid request', 403); diff --git a/ci4/app/Controllers/Presupuestos/Buscador.php b/ci4/app/Controllers/Presupuestos/Buscador.php index 30b7b53e..edfe067d 100644 --- a/ci4/app/Controllers/Presupuestos/Buscador.php +++ b/ci4/app/Controllers/Presupuestos/Buscador.php @@ -111,7 +111,7 @@ class Buscador extends \App\Controllers\BaseResourceController return $this->respond(Collection::datatable( $resourceData, $this->model->getResource("")->countAllResults(), - $this->model->getResource($search)->countAllResults() + $this->model->getResource($searchValues)->countAllResults() )); } else { return $this->failUnauthorized('Invalid request', 403); diff --git a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php index 6e2a81c7..03ff9410 100755 --- a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php +++ b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php @@ -398,7 +398,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController 'servicios' => $servicios, ); - $return_data = $this->calcular_presupuesto($datos_presupuesto, 0, true); //TRUE FOR DEBUG + $return_data = $this->calcular_presupuesto($datos_presupuesto, 0, false); //TRUE FOR DEBUG array_merge($return_data, [$csrfTokenName => $newTokenHash]); return $this->respond($return_data); @@ -1073,14 +1073,12 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController try { $return_data = []; - if ($extra_info) { - $info = [ - 'merma' => 0, - 'lomo_cubierta' => 0.0, - 'lomo_sobrecubierta' => 0.0, - 'user_id' => auth()->user()->id, - ]; - } + $info = [ + 'merma' => 0, + 'lomo_cubierta' => 0.0, + 'lomo_sobrecubierta' => 0.0, + 'user_id' => auth()->user()->id, + ]; $tirada = $datos_entrada['tirada']; $tamanio = $datos_entrada['tamanio']; @@ -1568,11 +1566,13 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController )); } + $info['lomo_cubierta'] = $lomo; + $info['lomo_sobrecubierta'] = $lomo_sobrecubierta; + $return_data['info'] = $info; + + if ($extra_info) { // && $tirada[$t] == $selected_tirada) { - $info['lomo_cubierta'] = $lomo; - $info['lomo_sobrecubierta'] = $lomo_sobrecubierta; - $return_data['info'] = $info; $return_data['info']['interior'] = $interior; $return_data['info']['cubierta'] = $cubierta; $return_data['info']['sobrecubierta'] = $linea_sobrecubierta; diff --git a/ci4/app/Controllers/Test.php b/ci4/app/Controllers/Test.php index 972808b2..eb68eaba 100755 --- a/ci4/app/Controllers/Test.php +++ b/ci4/app/Controllers/Test.php @@ -25,12 +25,7 @@ class Test extends BaseController $data = $model->obtenerLineasPedidoSinFacturar(999); */ - $model = model("\App\Models\Facturas\FacturaLineaModel"); - $data = $model->getResource(9)->get()->getResultObject(); - - echo('
');
-        var_dump($data);
-        echo('
'); + xdebug_info(); diff --git a/ci4/app/Entities/Facturas/FacturaEntity.php b/ci4/app/Entities/Facturas/FacturaEntity.php index 131ac828..99f923b5 100644 --- a/ci4/app/Entities/Facturas/FacturaEntity.php +++ b/ci4/app/Entities/Facturas/FacturaEntity.php @@ -8,8 +8,8 @@ class FacturaEntity extends \CodeIgniter\Entity\Entity protected $attributes = [ 'id' => null, 'pedido_id' => null, - 'factura_retificada_id' => null, - 'factura_retificativa_id' => null, + 'factura_rectificada_id' => null, + 'factura_rectificativa_id' => null, 'cliente_id' => null, 'serie_id' => null, 'numero' => null, @@ -33,14 +33,12 @@ class FacturaEntity extends \CodeIgniter\Entity\Entity 'updated_at' => null, 'deleted_at' => null, 'user_created_id' => null, - 'user_update_id' => null, + 'user_updated_id' => null, ]; protected $casts = [ 'id' => 'int', 'pedido_id' => 'int', - 'factura_retificada_id' => 'int', - 'factura_retificativa_id' => 'int', 'cliente_id' => 'int', 'serie_id' => 'int', 'base' => 'float', diff --git a/ci4/app/Entities/Facturas/FacturaPagoEntity.php b/ci4/app/Entities/Facturas/FacturaPagoEntity.php index a47ce19a..84f065cb 100644 --- a/ci4/app/Entities/Facturas/FacturaPagoEntity.php +++ b/ci4/app/Entities/Facturas/FacturaPagoEntity.php @@ -14,7 +14,7 @@ class FacturaPagoEntity extends \CodeIgniter\Entity\Entity 'forma_pago_id' => null, 'total' => null, 'deleted_at' => null, - 'user_update_id' => null, + 'user_updated_id' => null, ]; diff --git a/ci4/app/Language/en/App.php b/ci4/app/Language/en/App.php index 8a54743e..be8505b2 100755 --- a/ci4/app/Language/en/App.php +++ b/ci4/app/Language/en/App.php @@ -679,7 +679,7 @@ return [ "menu_calendario" => "Calendar", "menu_paises" => "Countries", "menu_correo" => "Mail", - "menu_formaspago" => "Payment methods", + "menu_formas_pago" => "Payment methods", "menu_imposiciones" => "Impositions", "menu_maquina" => "Machines", "menu_papelgenerico" => "Generic paper", diff --git a/ci4/app/Language/en/Basic.php b/ci4/app/Language/en/Basic.php index 4b55be18..4863c32d 100755 --- a/ci4/app/Language/en/Basic.php +++ b/ci4/app/Language/en/Basic.php @@ -89,6 +89,7 @@ return [ 'ok' => 'Ok', 'wait' => 'Wait', 'yes' => 'Yes', + 'back' => 'Back', ], diff --git a/ci4/app/Language/en/Facturas.php b/ci4/app/Language/en/Facturas.php index 762954bb..48c60a51 100644 --- a/ci4/app/Language/en/Facturas.php +++ b/ci4/app/Language/en/Facturas.php @@ -22,6 +22,7 @@ return [ 'serieFacturacion' => 'Billing Series', 'creditoAsegurado' => 'Secured Credit', 'facturaRectificada' => 'Rectified Invoice', + 'facturaRectificativa' => 'Rectifying Invoice', 'razonSocial' => 'Business Name', 'cif' => 'Tax ID', 'direccion' => 'Address', @@ -61,8 +62,23 @@ return [ 'peiddoImpresion' => 'Print Order', 'peiddoMaquetacion' => 'Layout Order', 'nuevaLinea' => 'New Line', + 'validarFactura' => 'Validate Invoice', + 'borrarFactura' => 'Delete Invoice', + 'imprimirFactura' => 'Print', + 'pagos' => 'Payments', + 'notas' => 'Notes', + 'fechaVencimiento' => 'Due Date', + "fechaCobro" => "Collection Date", + "cantidad" => "Quantity", + "addPago" => "Add Payment", + "facturaPagada" => "Rectifying Invoice already paid", 'errors' => [ 'requiredFields' => 'Fields marked with * are required', - ] + ], + 'validation' => [ + 'numerico' => 'Must be numeric', + 'requerido' => 'Required', + 'decimal' => 'Must be decimal', + ], ]; \ No newline at end of file diff --git a/ci4/app/Language/en/FormasPagoes.php b/ci4/app/Language/en/FormasPago.php old mode 100755 new mode 100644 similarity index 95% rename from ci4/app/Language/en/FormasPagoes.php rename to ci4/app/Language/en/FormasPago.php index 7e7e55cf..a2d39cc3 --- a/ci4/app/Language/en/FormasPagoes.php +++ b/ci4/app/Language/en/FormasPago.php @@ -11,7 +11,6 @@ return [ 'formasDePagos' => 'Formas de Pagos', 'formasPago' => 'Formas Pago', 'formasPagoList' => 'Formas Pago List', - 'formasPagoes' => 'Formas Pagoes', 'id' => 'ID', 'moduleTitle' => 'Formas Pagoes', 'nombre' => 'Nombre', diff --git a/ci4/app/Language/en/Pedidos.php b/ci4/app/Language/en/Pedidos.php index 69a30669..553a35c8 100644 --- a/ci4/app/Language/en/Pedidos.php +++ b/ci4/app/Language/en/Pedidos.php @@ -78,6 +78,8 @@ return [ 'facturas' => 'Invoices', + 'showTotal' => 'Show totals', + 'validation' => [ ], diff --git a/ci4/app/Language/es/App.php b/ci4/app/Language/es/App.php index e03fa10d..fbfc1cd4 100755 --- a/ci4/app/Language/es/App.php +++ b/ci4/app/Language/es/App.php @@ -682,7 +682,7 @@ return [ "menu_calendario" => "Calendario", "menu_paises" => "Paises", "menu_correo" => "Correo", - "menu_formaspago" => "Metodos de pago", + "menu_formas_pago" => "Formas de pago", "menu_imposiciones" => "Imposiciones", "menu_maquina" => "Maquinas", "menu_maquina_defecto" => "Maquinas por defecto", diff --git a/ci4/app/Language/es/Basic.php b/ci4/app/Language/es/Basic.php index 1c98ea3d..bb333f54 100755 --- a/ci4/app/Language/es/Basic.php +++ b/ci4/app/Language/es/Basic.php @@ -90,6 +90,7 @@ return [ 'wait' => 'Espere', 'yes' => 'Si', 'no' => 'No', + 'back' => 'Volver', ], diff --git a/ci4/app/Language/es/Facturas.php b/ci4/app/Language/es/Facturas.php index 36bcbcf5..90e6962f 100644 --- a/ci4/app/Language/es/Facturas.php +++ b/ci4/app/Language/es/Facturas.php @@ -22,6 +22,7 @@ return [ 'serieFacturacion' => 'Serie facturación', 'creditoAsegurado' => 'Crédito asegurado', 'facturaRectificada' => 'Factura rectificada', + 'facturaRectificativa' => 'Factura rectificativa', 'razonSocial' => 'Razón Social', 'cif' => 'CIF', 'direccion' => 'Dirección', @@ -61,8 +62,24 @@ return [ 'pedidoImpresion' => 'Pedido Impresión', 'pedidoMaquetacion' => 'Pedido Maquetación', 'nuevaLinea' => 'Nueva Línea', - + 'validarFactura' => 'Validar Factura', + 'borrarFactura' => 'Borrar Factura', + 'imprimirFactura' => 'Imprimir', + 'pagos' => 'Pagos', + 'notas' => 'Notas', + "fechaVencimiento" => "Fecha Vencimiento", + "fechaCobro" => "Fecha Cobro", + "cantidad" => "Cantidad", + "addPago" => "Añadir Pago", + "facturaPagada" => "Factura rectificativa ya abonada", + 'errors' => [ 'requiredFields' => 'Los campos marcados con * son obligatorios', + ], + 'validation' => [ + "requerido" => "El campo es obligatorio.", + "numerico" => "El campo debe ser numérico.", + "decimal" => "El campo debe ser decimal.", ] + ]; \ No newline at end of file diff --git a/ci4/app/Language/es/Pedidos.php b/ci4/app/Language/es/Pedidos.php index f8556058..25de0a9c 100644 --- a/ci4/app/Language/es/Pedidos.php +++ b/ci4/app/Language/es/Pedidos.php @@ -78,6 +78,8 @@ return [ 'facturas' => 'Facturas', + 'showTotal' => 'Mostrar totales', + 'validation' => [ ], diff --git a/ci4/app/Language/es/RolesPermisos.php b/ci4/app/Language/es/RolesPermisos.php index d09ccf35..6c631c16 100644 --- a/ci4/app/Language/es/RolesPermisos.php +++ b/ci4/app/Language/es/RolesPermisos.php @@ -37,6 +37,7 @@ return [ 'tarifaExtraSection' => 'Tarifas extra', 'proveedoresSection' => 'Proveedores', 'paisesSection' => 'Países', + 'formasPagoSection' => 'Formas de Pago', 'maquinasSection' => 'Máquinas', 'maquinasDefectoSection' => 'Máquinas por defecto', 'papelGenericoSection' => 'Papel genérico', diff --git a/ci4/app/Models/Clientes/ClienteModel.php b/ci4/app/Models/Clientes/ClienteModel.php index 741a736a..85df9782 100755 --- a/ci4/app/Models/Clientes/ClienteModel.php +++ b/ci4/app/Models/Clientes/ClienteModel.php @@ -257,7 +257,7 @@ class ClienteModel extends \App\Models\BaseModel LEFT JOIN lg_paises t4 ON t1.pais_id = t4.id LEFT JOIN users t5 ON t1.comercial_id = t5.id LEFT JOIN users t6 ON t1.soporte_id = t6.id - LEFT JOIN lg_formas_pago t7 ON t1.forma_pago_id = t7.id"; + LEFT JOIN formas_pago t7 ON t1.forma_pago_id = t7.id"; if (!is_null($limit) && intval($limit) > 0) { $sql .= " LIMIT " . intval($limit); } @@ -287,7 +287,7 @@ class ClienteModel extends \App\Models\BaseModel ) ->where("is_deleted", 0);; $builder->join("users t5", "t1.comercial_id = t5.id", "left"); - $builder->join("lg_formas_pago t7", "t1.forma_pago_id = t7.id", "left"); + $builder->join("formas_pago t7", "t1.forma_pago_id = t7.id", "left"); return empty($search) diff --git a/ci4/app/Models/Collection.php b/ci4/app/Models/Collection.php index 773ae680..af469083 100755 --- a/ci4/app/Models/Collection.php +++ b/ci4/app/Models/Collection.php @@ -15,7 +15,7 @@ class Collection * * @return array */ - public static function datatable(array $data, int $recordsTotal, int $recordsFiltered, string $error = null) + public static function datatable(array $data, int $recordsTotal, int $recordsFiltered, string $error = null, $extra_data = []) { $draw = 1; $req = service('request'); @@ -38,6 +38,10 @@ class Collection $response['error'] = $error; } + if (count($extra_data)>0) { + $response['extra'] = $extra_data; + } + return $response; } } \ No newline at end of file diff --git a/ci4/app/Models/Configuracion/FormaPagoModel.php b/ci4/app/Models/Configuracion/FormaPagoModel.php index 69833688..2a7374bb 100755 --- a/ci4/app/Models/Configuracion/FormaPagoModel.php +++ b/ci4/app/Models/Configuracion/FormaPagoModel.php @@ -3,7 +3,7 @@ namespace App\Models\Configuracion; class FormaPagoModel extends \App\Models\BaseModel { - protected $table = "lg_formas_pago"; + protected $table = "formas_pago"; /** * Whether primary key uses auto increment. @@ -15,8 +15,6 @@ class FormaPagoModel extends \App\Models\BaseModel const SORTABLE = [ 1 => "t1.id", 2 => "t1.nombre", - 3 => "t1.created_at", - 4 => "t1.updated_at", ]; protected $allowedFields = ["nombre"]; @@ -26,18 +24,30 @@ class FormaPagoModel extends \App\Models\BaseModel protected $validationRules = [ "nombre" => [ - "label" => "FormasPagoes.nombre", + "label" => "FormasPago.nombre", "rules" => "trim|required|max_length[255]", ], ]; protected $validationMessages = [ "nombre" => [ - "max_length" => "FormasPagoes.validation.nombre.max_length", - "required" => "FormasPagoes.validation.nombre.required", + "max_length" => "FormasPago.validation.nombre.max_length", + "required" => "FormasPago.validation.nombre.required", ], ]; + public function getMenuItems(){ + $items = $this->findAll(); + $menuItems = []; + foreach ($items as $item) { + $menuItems[] = [ + "value" => $item->id, + "label" => $item->nombre, + ]; + } + return $menuItems; + } + /** * Get resource data. * @@ -49,7 +59,7 @@ class FormaPagoModel extends \App\Models\BaseModel { $builder = $this->db ->table($this->table . " t1") - ->select("t1.id AS id, t1.nombre AS nombre, t1.created_at AS created_at, t1.updated_at AS updated_at"); + ->select("t1.id AS id, t1.nombre AS nombre"); return empty($search) ? $builder @@ -57,12 +67,6 @@ class FormaPagoModel extends \App\Models\BaseModel ->groupStart() ->like("t1.id", $search) ->orLike("t1.nombre", $search) - ->orLike("t1.created_at", $search) - ->orLike("t1.updated_at", $search) - ->orLike("t1.id", $search) - ->orLike("t1.nombre", $search) - ->orLike("t1.created_at", $search) - ->orLike("t1.updated_at", $search) ->groupEnd(); } } diff --git a/ci4/app/Models/Configuracion/SeriesFacturasModel.php b/ci4/app/Models/Configuracion/SeriesFacturasModel.php index 5b914953..701ddf05 100644 --- a/ci4/app/Models/Configuracion/SeriesFacturasModel.php +++ b/ci4/app/Models/Configuracion/SeriesFacturasModel.php @@ -108,4 +108,19 @@ class SeriesFacturasModel extends \App\Models\BaseModel return $result; } + + public function getSerieNumerada($id) + { + $number = $this->db->table($this->table) + ->select("next, formato") + ->where("id", $id) + ->get()->getFirstRow(); + + $this->db->table($this->table) + ->where("id", $id) + ->set("next", $number->next + 1, false) + ->update(); + + return str_replace("{number}", $number->next, $number->formato); + } } diff --git a/ci4/app/Models/Facturas/FacturaLineaModel.php b/ci4/app/Models/Facturas/FacturaLineaModel.php index a9d4d901..b808ac8c 100644 --- a/ci4/app/Models/Facturas/FacturaLineaModel.php +++ b/ci4/app/Models/Facturas/FacturaLineaModel.php @@ -38,12 +38,16 @@ class FacturaLineaModel extends \App\Models\BaseModel { ->select( "t1.id AS id, t1.factura_id AS factura_id, t1.pedido_linea_impresion_id AS pedido_linea_impresion_id, t1.pedido_maquetacion_id AS pedido_maquetacion_id, - t1.descripcion AS concepto, t1.cantidad as unidades, t1.precio_unidad AS precio_unidad, t1.iva AS iva, - t1.base AS subtotal, t1.total_iva AS total_iva, t1.total AS total, t1.data AS data, t2.pedido_id AS pedido_id, - t3.total_aceptado AS total_aceptado" + t1.descripcion AS descripcion, t1.cantidad as cantidad, t1.precio_unidad AS precio_unidad, t1.iva AS iva, + t1.base AS base, t1.total_iva AS total_iva, t1.total AS total, t1.data AS data, t2.pedido_id AS pedido_id, + t3.total_aceptado AS total_aceptado, t4.tirada_flexible AS tirada_flexible, t4.descuento_tirada_flexible AS descuento_tirada_flexible, + t6.cantidad AS cantidad_albaran" ) ->join("pedidos_linea t2", "t2.id = t1.pedido_linea_impresion_id", "left") ->join("presupuestos t3", "t3.id = t2.presupuesto_id", "left") + ->join("clientes t4", "t4.id = t3.cliente_id", "left") + ->join("albaranes t5", "t5.pedido_id = t2.pedido_id", "left") + ->join("albaranes_lineas t6", "t6.albaran_id = t5.id", "left") ->where("t1.factura_id", $factura_id) ->where("t1.deleted_at", null); @@ -68,5 +72,30 @@ class FacturaLineaModel extends \App\Models\BaseModel { ->where("pedido_linea_id", $pedido_linea_id) ->where("cantidad", $cantidad) ->delete(); - } + } + + public function updateFacturaPedidoLinea($factura_id, $pedido_linea_id, $cantidad, $cantidad_new) + { + // Obtener la ID del registro que queremos actualizar + $record = $this->db->table("facturas_pedidos_lineas") + ->select('id') + ->where("factura_id", $factura_id) + ->where("pedido_linea_id", $pedido_linea_id) + ->where("cantidad", $cantidad) + ->limit(1) + ->get() + ->getRow(); + + // Si existe el registro + if ($record) { + $data = [ + "cantidad" => $cantidad_new + ]; + + // Actualizar el registro especificado por su ID + $this->db->table("facturas_pedidos_lineas") + ->where("id", $record->id) + ->update($data); + } + } } \ No newline at end of file diff --git a/ci4/app/Models/Facturas/FacturaModel.php b/ci4/app/Models/Facturas/FacturaModel.php index 30e61341..ccdf7f43 100644 --- a/ci4/app/Models/Facturas/FacturaModel.php +++ b/ci4/app/Models/Facturas/FacturaModel.php @@ -23,11 +23,19 @@ class FacturaModel extends \App\Models\BaseModel { 11 => "DAFEDIFF(days, NOW(), t3.fecha_vencimiento_at)", ]; + const SORTABLE_PEDIDOS = [ + 1 => "t1.numero", + 2 => "t2.nombre", + 3 => "t1.estado", + 4 => "t1.fecha_factura_at", + 5 => "t1.total", + ]; + // Lista de columnas basada en los campos de la tabla, para asignación masiva protected $allowedFields = [ 'pedido_id', - 'factura_retificada_id', - 'factura_retificativa_id', + 'factura_rectificada_id', + 'factura_rectificativa_id', 'cliente_id', 'serie_id', 'numero', @@ -51,7 +59,7 @@ class FacturaModel extends \App\Models\BaseModel { 'updated_at', 'deleted_at', 'user_created_id', - 'user_update_id' + 'user_updated_id' ]; protected $returnType = "App\Entities\Facturas\FacturaEntity"; @@ -72,13 +80,17 @@ class FacturaModel extends \App\Models\BaseModel { "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, - t4.nombre AS forma_pago, DATE_FORMAT(t3.fecha_vencimiento_at, '%d/%m/%Y') AS vencimiento" + 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 IS NULL"); + $builder->groupBy("t1.id"); // Agrupa por id de la factura return empty($search) ? $builder @@ -89,6 +101,30 @@ class FacturaModel extends \App\Models\BaseModel { ->groupEnd(); } + + public function getResourcePedidos($pedido_id) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.numero AS numero, t2.nombre AS serie, t1.estado AS estado, + DATE_FORMAT(t1.fecha_factura_at, '%d/%m/%Y') AS fecha_factura_at, t1.total AS total" + ); + + $builder->join("series t2", "t2.id = t1.serie_id", "left"); + $builder->join("facturas_lineas t3", "t1.id = t3.factura_id", "left"); + $builder->join("facturas_pedidos_lineas t4", "t1.id = t4.factura_id", "left"); + $builder->join("pedidos_linea t5", "t4.pedido_linea_id = t5.id", "left"); + $builder->join("pedidos t6", "t5.pedido_id = t6.id", "left"); + + $builder->where("t1.deleted_at IS NULL"); + $builder->where("t6.id", $pedido_id); + + $builder->groupBy("t1.id"); // Agrupa por id de la factura + + return $builder; + } + public function getCantidadLineaPedidoFacturada($linea_pedido_id) { $builder = $this->db @@ -98,5 +134,14 @@ class FacturaModel extends \App\Models\BaseModel { return $builder->get()->getRow()->cantidad; } - + + public function deleteFacturasLineasPedido($factura_id, $pedido_linea_id, $cantidad) + { + $this->db->table("facturas_pedidos_lineas") + ->where("factura_id", $factura_id) + ->where("pedido_linea_id", $pedido_linea_id) + ->where("cantidad", $cantidad) + ->delete(); + } + } \ No newline at end of file diff --git a/ci4/app/Models/Facturas/FacturaPagoModel.php b/ci4/app/Models/Facturas/FacturaPagoModel.php index 1a17f9fb..82e06cdb 100644 --- a/ci4/app/Models/Facturas/FacturaPagoModel.php +++ b/ci4/app/Models/Facturas/FacturaPagoModel.php @@ -14,7 +14,7 @@ class FacturaPagoModel extends \App\Models\BaseModel { 'forma_pago_id', 'total', 'deleted_at', - 'user_update_id' + 'user_updated_id' ]; protected $returnType = "App\Entities\Facturas\FacturaPagoEntity"; @@ -23,4 +23,20 @@ class FacturaPagoModel extends \App\Models\BaseModel { protected $useSoftDeletes = true; public static $labelField = "id"; + + public function getResource($factura_id) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.factura_id AS factura_id, + t1.notes AS notes, t1.fecha_pago_at AS fecha_pago_at, t1.fecha_vencimiento_at AS fecha_vencimiento_at, + t1.forma_pago_id AS forma_pago_id, t2.nombre as forma_pago, t1.total AS total" + ) + ->join("formas_pago t2", "t2.id = t1.forma_pago_id", "left") + ->where("t1.factura_id", $factura_id) + ->where("t1.deleted_at", null); + + return $builder; + } } \ No newline at end of file diff --git a/ci4/app/Models/Pedidos/PedidoLineaModel.php b/ci4/app/Models/Pedidos/PedidoLineaModel.php index 8aee0c2a..52284cb4 100644 --- a/ci4/app/Models/Pedidos/PedidoLineaModel.php +++ b/ci4/app/Models/Pedidos/PedidoLineaModel.php @@ -14,12 +14,20 @@ class PedidoLineaModel extends \App\Models\BaseModel protected $useAutoIncrement = true; const SORTABLE = [ - 0 => "t1.id", - 1 => "t1.estado", - 2 => "t1.total_precio", - 3 => "t1.total_tirada", + 0 => "t2.id", + 1 => "t2.updated_at", + 2 => "t2.fecha_entrega_real", + 3 => "t4.nombre", + 4 => "CONCAT(t5.first_name, ' ', t5.last_name)", + 5 => "t3.titulo", + 6 => "t6.nombre", + 7 => "t3.inc_rei", + 8 => "t3.paginas", + 9 => "t3.tirada", + 10 => "t3.total_aceptado", + 11 => "t2.estado" ]; - + protected $allowedFields = [ "pedido_id", "presupuesto_id", @@ -40,7 +48,7 @@ class PedidoLineaModel extends \App\Models\BaseModel public static $labelField = "id"; - public function getResource(string $search = "", $estado="") + public function getResource($search = [], $estado="") { $builder = $this->db ->table($this->table . " t1") @@ -67,49 +75,146 @@ class PedidoLineaModel extends \App\Models\BaseModel } } - // Falta implementar la busqueda por grupos - return empty($search) - ? $builder - : $builder - ->groupStart() - ->like("t1.id", $search) - ->orLike("t1.id", $search) - ->groupEnd(); + if (empty($search)) + return $builder; + else { + $builder->groupStart(); + foreach ($search as $col_search) { + if ($col_search[0] != 1 && $col_search[0] != 2) + $builder->like(self::SORTABLE[$col_search[0]], $col_search[2]); + else { + $dates = explode(" ", $col_search[2]); + $builder->where(self::SORTABLE[$col_search[0]] . ">=", $dates[0]); + $builder->where(self::SORTABLE[$col_search[0]] . "<=", $dates[1]); + } + } + $builder->groupEnd(); + return $builder; + } } - - public function obtenerLineasPedidoSinFacturar($cliente_id){ - - $resultaArray = []; + public function getSumOfTirada(array $search, $estado = '', $start = 0, $length = 5) + { $builder = $this->db ->table($this->table . " t1") - ->select("t1.id AS id, t1.pedido_id AS pedido_id, t3.titulo AS titulo, t4.codigo AS tipo_impresion"); + ->selectSum('t3.tirada', 'total_tirada'); - $builder->join("pedidos t2", "t2.id = t1.pedido_id", "left"); - $builder->join("presupuestos t3", "t3.id = t1.presupuesto_id", "left"); - $builder->join("tipos_presupuestos t4", "t4.id = t3.tipo_impresion_id", "left"); + $builder->join("pedidos t2", "t2.id = t1.pedido_id", "left"); + $builder->join("presupuestos t3", "t1.presupuesto_id = t3.id", "left"); - $builder->join("facturas_pedidos_lineas fpl", "fpl.pedido_linea_id = t1.id", "left"); + - $builder->where("t3.cliente_id", $cliente_id); - $builder->where("t2.estado", "finalizado"); + // Aplica los filtros de búsqueda y estado + if (!empty($search)) { + $builder->groupStart(); + foreach ($search as $col_search) { + if ($col_search[0] != 1 && $col_search[0] != 2) + $builder->like(self::SORTABLE[$col_search[0]], $col_search[2]); + else { + $dates = explode(" ", $col_search[2]); + $builder->where(self::SORTABLE[$col_search[0]] . ">=", $dates[0]); + $builder->where(self::SORTABLE[$col_search[0]] . "<=", $dates[1]); + } + } + $builder->groupEnd(); + } + if ($estado !== '') { + $builder->where('estado', $estado); + } + + // Aplicar el orden y el límite + $builder->limit($length, $start); + + return $builder->get()->getRow()->total_tirada; + } + + public function getSumOfTotalAceptado(array $search, $estado = '', $start = 0, $length = 5) + { + + $builder = $this->db + ->table($this->table . " t1") + ->selectSum('t3.total_aceptado', 'total'); + + $builder->join("pedidos t2", "t2.id = t1.pedido_id", "left"); + $builder->join("presupuestos t3", "t1.presupuesto_id = t3.id", "left"); - $builder->where("(`t3`.`tirada` > `fpl`.`cantidad` OR fpl.pedido_linea_id IS NULL)"); - + + + // Aplica los filtros de búsqueda y estado + if (!empty($search)) { + $builder->groupStart(); + foreach ($search as $col_search) { + if ($col_search[0] != 1 && $col_search[0] != 2) + $builder->like(self::SORTABLE[$col_search[0]], $col_search[2]); + else { + $dates = explode(" ", $col_search[2]); + $builder->where(self::SORTABLE[$col_search[0]] . ">=", $dates[0]); + $builder->where(self::SORTABLE[$col_search[0]] . "<=", $dates[1]); + } + } + $builder->groupEnd(); + } + + if ($estado !== '') { + $builder->where('estado', $estado); + } + + // Aplicar el orden y el límite + $builder + ->limit($length, $start); + + return $builder->get()->getRow()->total; + } + + public function getTotalOfTotalAceptado() + { + + $builder = $this->db + ->table($this->table . " t1") + ->selectSum('t3.total_aceptado', 'total'); + + $builder->join("pedidos t2", "t2.id = t1.pedido_id", "left"); + $builder->join("presupuestos t3", "t1.presupuesto_id = t3.id", "left"); + + + return $builder->get()->getRow()->total; + } + + public function obtenerLineasPedidoSinFacturar($cliente_id) { + $resultaArray = []; + + $subquery = $this->db + ->table('facturas_pedidos_lineas') + ->select('pedido_linea_id, SUM(cantidad) AS total_cantidad') + ->groupBy('pedido_linea_id') + ->getCompiledSelect(); + + $builder = $this->db + ->table($this->table . " t1") + ->select("t1.id AS id, t1.pedido_id AS pedido_id, t3.titulo AS titulo, t4.codigo AS tipo_impresion") + ->join("pedidos t2", "t2.id = t1.pedido_id", "left") + ->join("presupuestos t3", "t3.id = t1.presupuesto_id", "left") + ->join("tipos_presupuestos t4", "t4.id = t3.tipo_impresion_id", "left") + ->join("($subquery) fpl", "fpl.pedido_linea_id = t1.id", "left") + ->where("t3.cliente_id", $cliente_id) + ->where("t2.estado", "finalizado") + ->where("(t3.tirada > IFNULL(fpl.total_cantidad, 0))"); + // Ejecutar la consulta y devolver resultados $query = $builder->get(); $data = $query->getResult(); - - foreach($data as $register){ + + foreach($data as $register) { $item = (object)[ 'id' => $register->id, 'text' => '['. lang('Pedidos.pedido') . ' ' . $register->pedido_id . '] ' . $register->titulo . ' - ' . lang('Presupuestos.' . $register->tipo_impresion), ]; array_push($resultaArray, $item); } - + return $resultaArray; } + } \ No newline at end of file diff --git a/ci4/app/Models/Presupuestos/PresupuestoModel.php b/ci4/app/Models/Presupuestos/PresupuestoModel.php index dc8c3ad3..424ba107 100755 --- a/ci4/app/Models/Presupuestos/PresupuestoModel.php +++ b/ci4/app/Models/Presupuestos/PresupuestoModel.php @@ -215,7 +215,7 @@ class PresupuestoModel extends \App\Models\BaseModel ", t2.nombre AS cliente, t3.nombre AS forma_pago, t4.nombre AS tipo_impresion, t5.nombre AS tipologia, t6.nombre AS pais, t7.estado AS estado, t8.id AS papel_formato, t9.first_name AS total_confirmado_user, t10.first_name AS aprobado_user FROM " . $this->table . " t1 LEFT JOIN clientes - t2 ON t1.cliente_id = t2.id LEFT JOIN lg_formas_pago + t2 ON t1.cliente_id = t2.id LEFT JOIN formas_pago t3 ON t1.forma_pago_id = t3.id LEFT JOIN lg_tipos_impresion t4 ON t1.tipo_impresion_id = t4.id LEFT JOIN lg_tipologias_libros t5 ON t1.tipologia_id = t5.id LEFT JOIN lg_paises diff --git a/ci4/app/Views/themes/vuexy/form/clientes/cliente/viewClienteList.php b/ci4/app/Views/themes/vuexy/form/clientes/cliente/viewClienteList.php index ecb9a1e5..f2448cbc 100644 --- a/ci4/app/Views/themes/vuexy/form/clientes/cliente/viewClienteList.php +++ b/ci4/app/Views/themes/vuexy/form/clientes/cliente/viewClienteList.php @@ -21,7 +21,7 @@ - + diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/_formaDePagoFormItems.php b/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/_formaDePagoFormItems.php index 27eed497..9d218e2d 100644 --- a/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/_formaDePagoFormItems.php +++ b/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/_formaDePagoFormItems.php @@ -1,12 +1,11 @@ -
-
-
- - -
- -
- -
\ No newline at end of file +
+
+
+ + +
+
+
\ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoForm.php b/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoForm.php index c91e868e..965dd75f 100644 --- a/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoForm.php +++ b/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoForm.php @@ -1,26 +1,45 @@ -include("themes_commonPartialsBs/select2bs5") ?> -include("themes_commonPartialsBs/sweetalert") ?> +include("themes/_commonPartialsBs/sweetalert") ?> extend('themes/vuexy/main/defaultlayout') ?> section("content") ?>
-
-
-

-
-
- -
- - getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> - -
- -
-
+
+
+

+
+
+ +
+ + getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> + +
+
+ " + /> + "btn btn-secondary float-start",] + ) ?> +
+
+
endSection() ?> + + +section('additionalExternalJs') ?> + + + + + + + +endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoList.php b/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoList.php index c2124231..912b0085 100644 --- a/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoList.php +++ b/ci4/app/Views/themes/vuexy/form/configuracion/formas-pago/viewFormaDePagoList.php @@ -1,25 +1,23 @@ -include('themes_commonPartialsBs/datatables') ?> -include('themes_commonPartialsBs/sweetalert') ?> -extend('themes'.config('Basics')->theme['name'].'/AdminLayout/defaultLayout') ?> +include('themes/_commonPartialsBs/datatables') ?> +include('themes/_commonPartialsBs/sweetalert') ?> +include('themes/_commonPartialsBs/_confirm2delete') ?> +extend('themes/vuexy/main/defaultlayout') ?> section('content'); ?>
-

+

+ 'btn btn-primary float-end']); ?>
- + - - - - - + @@ -29,7 +27,7 @@
@@ -40,125 +38,83 @@ section('additionalInlineJs') ?> - const lastColNr = $('#tableOfFormasdepagos').find("tr:first th").length - 1; - const actionBtns = function(data) { - return ` -
- - -
- `; - }; - theTable = $('#tableOfFormasdepagos').DataTable({ - processing: true, - serverSide: true, - autoWidth: true, - responsive: true, - scrollX: true, - lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ], - pageLength: 10, - lengthChange: true, - "dom": 'lfrtipB', // 'lfBrtip', // you can try different layout combinations by uncommenting one or the other - // "dom": '<"top"lf><"clear">rt<"bottom"ipB><"clear">', // remember to comment this line if you uncomment the above - "buttons": [ - 'copy', 'csv', 'excel', 'print', { - extend: 'pdfHtml5', - orientation: 'landscape', - pageSize: 'A4' - } - ], - stateSave: true, - order: [[1, 'asc']], - language: { - url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" - }, - ajax : $.fn.dataTable.pipeline( { - url: '', - method: 'POST', - headers: {'X-Requested-With': 'XMLHttpRequest'}, - async: true, - }), - columnDefs: [ - { - orderable: false, - searchable: false, - targets: [0,lastColNr] - } - ], - columns : [ - { 'data': actionBtns }, - { 'data': 'id' }, - { 'data': 'nombre' }, - { 'data': 'created_at' }, - { 'data': 'updated_at' }, - { 'data': actionBtns } - ] - }); + const lastColNr = $('#tableOfFormasdepagos').find("tr:first th").length - 1; + const actionBtns = function(data) { + return ` +
+ + +
+ `; + }; - - theTable.on( 'draw.dt', function () { - - const dateCols = [3, 4]; - const shortDateFormat = ''; - const dateTimeFormat = ''; - - for (let coln of dateCols) { - theTable.column(coln, { page: 'current' }).nodes().each( function (cell, i) { - const datestr = cell.innerHTML; - const dateStrLen = datestr.toString().trim().length; - if (dateStrLen > 0) { - let dateTimeParts= datestr.split(/[- :]/); // regular expression split that creates array with: year, month, day, hour, minutes, seconds values - dateTimeParts[1]--; // monthIndex begins with 0 for January and ends with 11 for December so we need to decrement by one - const d = new Date(...dateTimeParts); // new Date(datestr); - const md = moment(d); - const usingThisFormat = dateStrLen > 11 ? dateTimeFormat : shortDateFormat; - const formattedDateStr = md.format(usingThisFormat); - cell.innerHTML = formattedDateStr; - } - }); + theTable = $('#tableOfFormasdepagos').DataTable({ + processing: true, + serverSide: true, + autoWidth: true, + responsive: true, + scrollX: true, + lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ], + pageLength: 10, + lengthChange: true, + "dom": 'lfBrtip', + "buttons": [ + 'copy', 'csv', 'excel', 'print', { + extend: 'pdfHtml5', + orientation: 'landscape', + pageSize: 'A4' } + ], + stateSave: true, + order: [[1, 'asc']], + language: { + url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" + }, + ajax : $.fn.dataTable.pipeline( { + url: '', + method: 'POST', + headers: {'X-Requested-With': 'XMLHttpRequest'}, + async: true, + }), + columnDefs: [ + { + orderable: false, + searchable: false, + targets: [0,lastColNr] + } + ], + columns : [ + { 'data': 'nombre' }, + { 'data': actionBtns } + ] }); -$(document).on('click', '.btn-edit', function(e) { - window.location.href = `/${$(this).attr('data-id')}/edit`; + $(document).on('click', '.btn-edit', function(e) { + window.location.href = `/configuracion/formas-pago/edit/${$(this).attr('data-id')}`; }); - -$(document).on('click', '.btn-delete', function(e) { - Swal.fire({ - title: '', - text: '', - icon: 'warning', - showCancelButton: true, - confirmButtonColor: '#3085d6', - confirmButtonText: '', - cancelButtonText: '', - cancelButtonColor: '#d33' - }) - .then((result) => { - const dataId = $(this).data('id'); - const row = $(this).closest('tr'); - if (result.value) { - $.ajax({ - url: `/${dataId}`, - method: 'DELETE', - }).done((data, textStatus, jqXHR) => { - Toast.fire({ - icon: 'success', - title: data.msg ?? jqXHR.statusText, - }); - - theTable.clearPipeline(); - theTable.row($(row)).invalidate().draw(); - }).fail((jqXHR, textStatus, errorThrown) => { - Toast.fire({ - icon: 'error', - title: jqXHR.responseJSON.messages.error, - }); - }) - } - }); + + + $(document).on('click', '.btn-delete', function(e) { + $(".btn-remove").attr('data-id', $(this).attr('data-id')); + }); + + $(document).on('click', '.btn-remove', function(e) { + const dataId = $(this).attr('data-id'); + const row = $(this).closest('tr'); + if ($.isNumeric(dataId)) { + $.ajax({ + url: `/configuracion/formas-pago/delete/${dataId}`, + method: 'GET', + }).done((data, textStatus, jqXHR) => { + $('#confirm2delete').modal('toggle'); + theTable.clearPipeline(); + theTable.row($(row)).invalidate().draw(); + popSuccessAlert(data.msg ?? jqXHR.statusText); + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) + } }); - diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasForm.php b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasForm.php index cd4eaf81..fe46f704 100644 --- a/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasForm.php +++ b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasForm.php @@ -6,26 +6,29 @@ section("content") ?>
-
-
-

-
-
- - - getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> - -
- " - /> - "btn btn-secondary float-start",]) ?> - -
-
-
+
+
+

+
+
+ + + getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> + +
+ " + /> + "btn btn-secondary float-start",] + ) ?> +
+
+
@@ -33,20 +36,22 @@ -section('css') ?> - - "> -endSection() ?> +section('css') ?> + +"> +endSection() ?> section('additionalExternalJs') ?> - - - - - - - - -endSection() ?> + + + + + + + + +endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasList.php b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasList.php index 85ca4f23..1ffca01a 100644 --- a/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasList.php +++ b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasList.php @@ -112,7 +112,7 @@ const row = $(this).closest('tr'); if ($.isNumeric(dataId)) { $.ajax({ - url: `/configuracion/series-facturas//delete/${dataId}`, + url: `/configuracion/series-facturas/delete/${dataId}`, method: 'GET', }).done((data, textStatus, jqXHR) => { $('#confirm2delete').modal('toggle'); diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php index cae8922e..453074b7 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php @@ -117,13 +117,11 @@ $('#addNewPedidoImpresion').on('click', function(){ success: function(response) { yeniden(response.); - // Se actualiza la tabla de lineas de factura - $('#tableOfLineasFactura').DataTable().clearPipeline(); - $('#tableOfLineasFactura').DataTable().ajax.reload(); // se ajustan el ancho de las columnas - $('#tableOfLineasFactura').DataTable().columns.adjust().draw(); $('#pedidoImpresion').val(null).trigger('change'); - + // Se actualiza la tabla de lineas de factura + tableLineas.clearPipeline(); + $('#tableOfLineasFactura').DataTable().columns.adjust().draw(); } }); }); diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php index 47754d47..4bba5e7f 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php @@ -11,7 +11,11 @@
-

estado)?>

+

+ ;"> estado)?> + estado != 'borrador')? " / ":""?> + ;estado == 'borrador')? "display:none;":""?>"> estado_pago)?> +

@@ -38,7 +42,7 @@ - estado != 'borrador')?'disabled ':''?> id="serie_id" tabindex="2" name="serie_id" class="form-control select2bs2 update-cabecera" style="width: 100%;">
@@ -50,7 +54,7 @@ - estado != 'borrador')?'disabled ':''?> id="creditoAsegurado" tabindex="3" name="creditoAsegurado" class="form-control select2bs2 update-cabecera" style="width: 100%;"> @@ -63,7 +67,7 @@ - + estado != 'borrador')?'disabled ':''?> type="text" value="" tabindex="4" id="fecha_factura_at" name="fecha_factura_at" tabindex="1" maxLength="11" class="form-control update-cabecera" value="fecha_factura_at) ?>" >
@@ -76,7 +80,7 @@ - estado != 'borrador')?'disabled ':''?> id="cliente_id" tabindex="5" name="cliente_id" class="form-control select2bs2 update-cabecera" style="width: 100%;"> @@ -86,12 +90,29 @@
-
+ +
serie_id == 7 || $facturaEntity->serie_id == 9 || $facturaEntity->factura_rectificada_id != null) ? "":"style='display:none;'" ?> class="col-md-12 col-lg-2 px-4 factura-R"> +
+ + estado!='borrador')? "disabled":"" ?> id="facturaR" name="factura_rectificada_id != null) ? 'factura_rectificada_id' : 'factura_rectificativa_id' ?>" tabindex="" maxLength="25" class="form-control update-cabecera factura-R" + + factura_rectificada_id == null && $facturaEntity->factura_rectificativa_id == null): ?> + value="" + + value="factura_rectificada_id != null) ? old('factura_rectificada_id', $facturaEntity->factura_rectificada_id): old('factura_rectificativa_id', $facturaEntity->factura_rectificativa_id)?>" + + > +
+
+ +
px-4">
- + estado != 'borrador')?'disabled ':''?> id="cliente_nombre" name="cliente_nombre" tabindex="6" class="form-control update-cabecera" value="cliente_nombre) ?>">
@@ -100,7 +121,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_cif" name="cliente_cif" tabindex="7" class="form-control update-cabecera" value="cliente_cif) ?>">
@@ -109,7 +130,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_pais" name="cliente_pais" tabindex="8" class="form-control update-cabecera" value="cliente_pais) ?>"> @@ -122,7 +143,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_direccion" name="cliente_address" tabindex="6" class="form-control update-cabecera" value="cliente_address) ?>"> @@ -131,7 +152,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_cp" name="cliente_cp" tabindex="7" class="form-control update-cabecera" value="cliente_cp) ?>"> @@ -140,7 +161,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_ciudad" name="cliente_ciudad" tabindex="8" class="form-control update-cabecera" value="cliente_ciudad) ?>"> @@ -149,7 +170,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_provincia" name="cliente_provincia" tabindex="8" class="form-control update-cabecera" value="cliente_provincia) ?>"> @@ -163,11 +184,11 @@ estado === 'validada' && (auth()->user()->inGroup('beta') || auth()->user()->inGroup('admin'))) : ?> @@ -304,4 +325,66 @@ $('#cliente_id').select2({ } }); + +$('#editarValidada').on('click', function(){ + + $('.update-cabecera').prop('disabled', false); +}); + + +$('#duplicar').on('click', function() { + var id = id ?>; + var url = ''; + url = url.replace(':id', id ); + $.ajax({ + url: url, + type: 'POST', + data: { + : v, + }, + success: function(response){ + if('error' in response){ + + } else { + var url = ''; + url = url.replace(':id', response.id); + + window.location.href = url; + } + } + }); +}); + + +$(".update-cabecera").on("change", function(){ + + if($(this).attr('id') == 'serie_id'){ + var id = $(this).val(); + if(id == 7 || id == 9){ + // se muestra el campo de factura rectificada que tiene como clase factura-R + $('.factura-R').show(); + $('#div_cliente').removeClass('col-lg-6').addClass('col-lg-4'); + } else { + // se oculta el campo de factura rectificada + $('.factura-R').hide(); + $('#div_cliente').removeClass('col-lg-4').addClass('col-lg-6'); + } + } + + $.ajax({ + url: 'id) ?>', + type: 'POST', + data: { + : v, + name: this.name, + value: $(this).val() + }, + success: function(response){ + if('error' in response){ + + } + } + }); +}); + endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php index 09798fba..1c8dcbaf 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php @@ -13,7 +13,7 @@ - + @@ -31,26 +31,26 @@ - + - + - + - - + + @@ -81,33 +81,54 @@ const actionBtns = function(data) { // se comprueba si data es null - if (data.pedido_id === null) { + estado != 'borrador') :?> + if (data.pedido_id != null) { return ` - `; - } - else{ + + `; + } + else + { + return ``; + } + + + if (data.pedido_id === null) { return ` `; + } + else{ + return ` +
+
+
+ + +
- `; +
+ `; } + }; + var editor_lineas = new $.fn.dataTable.Editor( { ajax: { url: "", @@ -119,23 +140,57 @@ var editor_lineas = new $.fn.dataTable.Editor( { idSrc: 'id', fields: [ { - name: "unidades", + name: "cantidad", }, { - name: "concepto" + name: "descripcion", + type: "textarea", + attr: { + rows: 5, + style: "height: 120px;" + } }, { name: "precio_unidad", - } + attr: { + style: "min-width: 65px;" + } + }, { + name: "iva", + }, { + name: "pedido_linea_impresion_id", + type: "hidden" + }, { + name: "pedido_maquetacion_id", + type: "hidden" + }, { + name: "id", + type: "hidden" + }, { + name: "base", + type: "hidden" + }, ] } ); + +var old_cantidad = 0; + +editor_lineas.on( 'preEdit', function ( e, json, data, id ) { + + old_cantidad = data.cantidad; + +}); + editor_lineas.on( 'preSubmit', function ( e, d, type ) { + if ( type === 'create'){ d.data[0]['factura_id'] = id ?>; + d.data[0]['old_cantidad'] = null; } else if(type === 'edit' ) { for (v in d.data){ d.data[v]['factura_id'] = id ?>; + d.data[v]['old_cantidad'] = old_cantidad; } } }); @@ -155,9 +210,10 @@ editor_lineas.on( 'submitSuccess', function ( e, json, data, action ) { // Activate an inline edit on click of a table cell $('#tableOfLineasFactura').on( 'click', 'tbody span.edit', function (e) { - editor_lineas.inline( - tableLineas.cells(this.parentNode.parentNode, '*').nodes(), - { + + editor_lineas.inline(tableLineas.cells(this.closest('tr'), '*').nodes(), + { + cancelHtml: '', cancelTrigger: 'span.cancel', submitHtml: '', @@ -175,45 +231,102 @@ var tableLineas = $('#tableOfLineasFactura').DataTable({ responsive: true, scrollX: true, columns: [ - {data: null, render: actionBtns}, + { + data: actionBtns, + className: 'row-edit dt-center' + }, {data: "id"}, {data: "pedido_linea_impresion_id"}, {data: "pedido_maquetacion_id"}, {data: "pedido_id"}, - {data: "unidades"}, + {data: "cantidad"}, { - data: "concepto", + data: "descripcion", render: function (data, type, row, meta) { - // se convierten a float data.total_aceptado y subtotal - var total_aceptado = parseFloat(row.total_aceptado); - var subtotal = parseFloat(row.subtotal); + if(row.pedido_linea_impresion_id != null){ + + // se convierten a float data.total_aceptado y subtotal + var total_aceptado = parseFloat(row.total_aceptado); + var subtotal = parseFloat(row.base); - var error_text = ''; - if(total_aceptado != subtotal){ - error_text = 'El total del pedido ('+ total_aceptado + '€) no coincide con la línea ('+ subtotal + '€)'; + var error_text = ''; + if(total_aceptado != subtotal){ + error_text = 'El total del pedido ('+ total_aceptado + '€) no coincide con la línea ('+ subtotal + '€)'; + } + + var returned_data = ` +
+ ${data} +
+ +
+ + ${error_text} +
+ +
+
+ + +
+ `; + + if (row.tirada_flexible === "1"){ + returned_data += ` +
+ + +
+
+ + +
+ `; + if(row.cantidad + +
+ + `; + } + else{ + returned_data += ` + + `; + } + } + else{ + returned_data += ` + + `; + } + + return returned_data; + } + else{ + return ` +
+ ${data} +
+ `; } - - return ` -
- ${data} -
- -
- - ${error_text} -
- -
- - -
- `; } }, {data: "precio_unidad"}, {data: "iva"}, - {data: "subtotal"}, + {data: "base"}, {data: "total_iva"}, {data: "total"}, ], @@ -241,67 +354,123 @@ var tableLineas = $('#tableOfLineasFactura').DataTable({ ], footerCallback: function (row, data, start, end, display) { - var api = this.api(); - - // Remove the formatting to get integer data for summation - var intVal = function (i) { - return typeof i === 'string' ? - i.replace(/[\$,]/g, '')*1 : - typeof i === 'number' ? - i : 0; - }; - - // Total over all pages - var totalSubtotal = api - .column(8) - .data() - .reduce(function (a, b) { - return intVal(a) + intVal(b); - }, 0); - - var totalIVA = api - .column(9) - .data() - .reduce(function (a, b) { - return intVal(a) + intVal(b); - }, 0); - - var totalTotal = api - .column(10) - .data() - .reduce(function (a, b) { - return intVal(a) + intVal(b); - }, 0); - - // Update footer - $('#subtotal-sum').html(totalSubtotal.toFixed(2)); - $('#total-iva-sum').html(totalIVA.toFixed(2)); - $('#total-sum').html(totalTotal.toFixed(2)); - - // Assuming pendiente de pago is totalTotal - totalIVA for this example - var pendientePago = totalTotal ;//- totalIVA; - $('#pendiente-pago').html(pendientePago.toFixed(2)); + updateFooterLineas(this.api()); } }); +function updateFooterLineas(table){ + + // Remove the formatting to get integer data for summation + var intVal = function (i) { + return typeof i === 'string' ? + i.replace(/[\$,]/g, '')*1 : + typeof i === 'number' ? + i : 0; + }; + + // Total over all pages + var totalSubtotal = table + .column(9) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + var totalIVA = table + .column(10) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + var totalTotal = table + .column(11) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + // Update footer + $('#subtotal-sum').html(totalSubtotal.toFixed(2)); + $('#total-iva-sum').html(totalIVA.toFixed(2)); + $('#total-sum').html(totalTotal.toFixed(2)); + + // Assuming pendiente de pago is totalTotal - totalIVA for this example + estado == 'borrador') :?> + var pendientePago = totalTotal ; + var total_pagos = 0; + + var total_pagos = parseFloat($('#totalCobrado-sum').html()).toFixed(2); + var pendientePago = totalTotal - total_pagos; + + if(isNaN(pendientePago)){ + pendientePago = 0; + } + $('#pendiente-pago').html(pendientePago.toFixed(2)); + + $.ajax({ + url: 'id) ?>', + method: 'POST', + data: { + base: totalSubtotal, + total: totalTotal, + total_pagos: total_pagos, + pendiente: pendientePago, + : v + } + }).done((data, textStatus, jqXHR) => { + if(data.estado_pago == 'pagada'){ + $('#estado_pago_text').text(''); + $('#estado_pago_text').css('color', 'green'); + } + else{ + $('#estado_pago_text').text(''); + $('#estado_pago_text').css('color', 'red'); + } + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) +} + // Delete row $(document).on('click', '.btn-delete', function(e) { - //$(".btn-remove").attr('data-id', $(this).attr('data-id')); + const dataId = $(this).attr('data-id'); const row = $(this).closest('tr'); if ($.isNumeric(dataId)) { asyncConfirmDialogWithParams( "Borrar Linea de Factura", "¿Está seguro de borrar la línea? Esta acción no se puede deshacer.", - deleteConfirmed, null, [dataId, row]) + deleteConfirmedLinea, function(){}, [dataId, row]) } }); -function deleteConfirmed(params){ +function deleteConfirmedLinea(params){ var factura_linea_id = params[0]; var row = params[1]; + const row_data = tableLineas.row($(row)).data(); + + if(row_data.pedido_linea_impresion_id != null){ + var url = ''; + $.ajax({ + url: url, + method: 'POST', + data: { + factura_id: id ?>, + pedido_linea_impresion_id: row_data.pedido_linea_impresion_id, + cantidad: row_data.cantidad, + : v + } + }).done((data, textStatus, jqXHR) => { + + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) + } + + var url = ''; url = url.replace(':id', factura_linea_id ); $.ajax({ @@ -324,4 +493,57 @@ $(document).on('click', '.btn-view_pedido', function(e) { }); +$('#addLineaFactura').on('click', function() { + const formOptions= { + submitTrigger: 0, + submitHtml: '' + + }; + editor_lineas.inlineCreate('end', formOptions); +}); + + +$(document).on('click', '.btn-excedentes', function(e) { + const row = $(this).data('row'); + const row_data = tableLineas.row(row).data(); + + const pedido_id = row_data.pedido_id; + + var pedido_linea_impresion_id = null; + var pedido_linea_maquetacion_id = null; + + if(row_data.pedido_linea_impresion_id != null){ + pedido_linea_impresion_id = row_data.pedido_linea_impresion_id + } + else{ + pedido_linea_maquetacion_id = row_data.pedido_maquetacion_id + } + + var factura_id = id ?>; + + var url = ''; + url = url.replace(':factura_id', factura_id ); + + $.ajax({ + url: url, + method: 'POST', + data: { + pedido_id: pedido_id, + pedido_linea_impresion_id: pedido_linea_impresion_id, + pedido_linea_maquetacion_id: pedido_linea_maquetacion_id, + precio_unidad: row_data.precio_unidad, + descripcion: row_data.descripcion, + iva: row_data.iva, + descuento: row_data.descuento_tirada_flexible, + cantidad: parseInt(row_data.cantidad_albaran)-parseInt(row_data.cantidad), + : v + } + }).done((data, textStatus, jqXHR) => { + $('#tableOfLineasFactura').DataTable().clearPipeline(); + $('#tableOfLineasFactura').DataTable().draw(); + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) +}); + endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php new file mode 100644 index 00000000..19911667 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php @@ -0,0 +1,352 @@ +
+
+

+ +

+
+
+
id
Subtotal:Subtotal:
I.V.A.:I.V.A.:
Total:Total:
Pendiente de pago:serie_id == 7 || $facturaEntity->serie_id == 9)? "style='display:none;'":"" ?> colspan="9" style="text-align:right">Pendiente de pago:serie_id == 7 || $facturaEntity->serie_id == 9)? "style='display:none;'":"" ?> id="pendiente-pago">
-
-
- - -
+
+
+
-
+ +
+
+
+ + + + + + + + + + + + + + + + + + +
Total:
+ +
+
+ +
+
+ + + + + + + +section('additionalInlineJs') ?> + +const formas_pago = formas_pago) ?>; +var formaPagoLookup = {}; +formas_pago.forEach(function(pago) { + formaPagoLookup[pago.value] = pago.label; +}); + +const actionBtns_pagos = function(data) { + return ` +
+ + + +
`; +} + +var editor_pagos = new $.fn.dataTable.Editor( { + ajax: { + url: "", + headers: { + : v, + }, + }, + table : "#tableOfLineasPagos", + idSrc: 'id', + fields: [ + { + name: "forma_pago_id", + type: "select", + options: formas_pago, + }, + { + name: "notes", + type: "textarea", + attr: { + rows: 5, + style: "height: 120px;" + } + }, + { + name: "total", + attr: { + style: "min-width: 65px;" + } + }, + { + name: "fecha_pago_at", + type: "datetime", + def: function () { + return new Date().toISOString().split('T')[0]; // YYYY-MM-DD + }, + wireFormat: 'YYYY-MM-DD HH:mm:ss', + displayFormat: 'DD/MM/YYYY', + }, + { + name: "fecha_vencimiento_at", + type: "datetime", + def: () => new Date(), + def: function () { + return new Date().toISOString().split('T')[0]; // YYYY-MM-DD + }, + wireFormat: 'YYYY-MM-DD HH:mm:ss', + displayFormat: 'DD/MM/YYYY', + }, + { + name: "id", + type: "hidden" + }, + { + name: "factura_id", + type: "hidden" + }, + ] +}); + + + +editor_pagos.on( 'preSubmit', function ( e, d, type ) { + + if ( type === 'create'){ + d.data[0]['factura_id'] = id ?>; + } + else if(type === 'edit' ) { + for (v in d.data){ + d.data[v]['factura_id'] = id ?>; + } + } +}); + + +editor_pagos.on( 'postSubmit', function ( e, json, data, action ) { + + yeniden(json.); + tablePagos.clearPipeline(); + tablePagos.draw(); +}); + + +var tablePagos = $('#tableOfLineasPagos').DataTable({ + processing: true, + serverSide: true, + autoWidth: true, + responsive: true, + scrollX: true, + columns: [ + { + data: null, + render: actionBtns_pagos, + className: 'row-edit dt-center' + }, + {data: "id"}, + { + data: "forma_pago_id", + render: function(data, type, row) { + return formaPagoLookup[data] || data; + } + }, + {data: "notes"}, + { + data: "fecha_vencimiento_at", + render: function(data, type, row) { + if(data == null){ + return ''; + } + return data!='0000-00-00 00:00:00' ? moment(data).format('DD/MM/YYYY') : ''; + } + }, + { + data: "fecha_pago_at", + render: function(data, type, row) { + if(data == null){ + return ''; + } + return data!='0000-00-00 00:00:00' ? moment(data).format('DD/MM/YYYY') : ''; + } + }, + {data: "total"}, + ], + order: [[1, "asc"]], + dom: 't', + language: { + url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" + }, + ajax: { + url: 'id) ?>', + method: 'POST', + headers: {'X-Requested-With': 'XMLHttpRequest'}, + async: true, + }, + columnDefs: [ + { + orderable: false, + searchable: false, + targets: [0] + }, + { + visible: false, + targets: [1] + }, + { + width: '40%', // Ajusta el ancho para la columna de notas + targets: 3 + }, + { + width: '10%', // Ajusta el ancho para la columna de notas + targets: [4, 5, 6] + }, + + ], + footerCallback: function (row, data, start, end, display) { + var api = this.api(); + + // Remove the formatting to get integer data for summation + var intVal = function (i) { + return typeof i === 'string' ? i.replace(/[\$,]/g, '')*1 : typeof i === 'number' ? i : 0; + }; + + // Total over all pages + var totalPagos = api + .column(6) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + // Update footer + $('#totalCobrado-sum').html(totalPagos.toFixed(2)); + + // call footerCallback of the other table + if (typeof tableLineas !== 'undefined') { + updateFooterLineas(tableLineas); + } + } +}); + +function updateFooterLineas(table){ + + // Remove the formatting to get integer data for summation + var intVal = function (i) { + return typeof i === 'string' ? + i.replace(/[\$,]/g, '')*1 : + typeof i === 'number' ? + i : 0; + }; + + // Total over all pages + var totalSubtotal = table + .column(9) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + var totalIVA = table + .column(10) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + var totalTotal = table + .column(11) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + // Update footer + $('#subtotal-sum').html(totalSubtotal.toFixed(2)); + $('#total-iva-sum').html(totalIVA.toFixed(2)); + $('#total-sum').html(totalTotal.toFixed(2)); + + // Assuming pendiente de pago is totalTotal - totalIVA for this example + estado == 'borrador') :?> + var pendientePago = totalTotal ; + var total_pagos = 0; + + var total_pagos = parseFloat($('#totalCobrado-sum').html()).toFixed(2); + var pendientePago = totalTotal - total_pagos; + + // Se comprueba si pendientePago es un numero o NAN + if(isNaN(pendientePago)){ + pendientePago = 0; + } + $('#pendiente-pago').html(pendientePago.toFixed(2)); + + $.ajax({ + url: 'id) ?>', + method: 'POST', + data: { + base: totalSubtotal, + total: totalTotal, + total_pagos: total_pagos, + pendiente: pendientePago + } + }).done((data, textStatus, jqXHR) => { + if($('#pendiente-pago').html() == '0.00'){ + $('#addPagoRow').hide(); + } else { + $('#validarFactura').show(); + } + if(data.estado_pago == 'pagada'){ + $('#estado_pago_text').text(''); + $('#estado_pago_text').css('color', 'green'); + } + else{ + $('#estado_pago_text').text(''); + $('#estado_pago_text').css('color', 'red'); + } + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) +} + + +$('#addPagoFactura').on('click', function () { + const formOptions= { + submitTrigger: 0, + submitHtml: '' + + }; + editor_pagos.inlineCreate('end', formOptions); +}); + + +// Activate an inline edit on click of a table cell +$('#tableOfLineasPagos').on( 'click', 'tbody span.edit-pago', function (e) { + + editor_pagos.inline(tablePagos.cells(this.closest('tr'), '*').nodes(), + { + + cancelHtml: '', + cancelTrigger: 'span.cancel-pago', + submitHtml: '', + submitTrigger: 'span.edit-pago', + submit: 'allIfChanged' + } + ); +} ); + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_rectificadaFacturasItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_rectificadaFacturasItems.php new file mode 100644 index 00000000..1b0f5d4b --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/_rectificadaFacturasItems.php @@ -0,0 +1,22 @@ +
+
+

+ +

+
+
+ +

+ +
+
+
+
+ + +section('additionalInlineJs') ?> + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php index 4f3cf2cd..2b381c07 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php @@ -22,14 +22,35 @@ + estado !='borrador' && (strpos($facturaEntity->numero, "REC ") !== 0) ) : ?> + + + estado !='borrador' && (strpos($facturaEntity->numero, "REC ") === 0) ) : ?> + +
- " - /> - "btn btn-secondary float-start"]) ?> + estado =='borrador') : ?> + " + /> + " + /> + + " + /> + "btn btn-secondary float-start"]) ?>
@@ -41,8 +62,46 @@ endSection() ?> + section("additionalInlineJs") ?> +$("#borrarFactura").on("click", function(){ + + asyncConfirmDialog( + "Borrar Factura", + "¿Está seguro de borrar la factura? Esta acción no se puede deshacer.", + deleteConfirmed, null) +}); + +function deleteConfirmed(){ + $.ajax({ + url: "id) ?>", + type: 'GET', + success: function(response){ + window.location.href = ""; + } + }); +} + +$("#validarFactura").on("click", function(){ + +asyncConfirmDialog( + "Validar Factura", + "¿Está seguro de pasar la factura a validada? Esta acción no se puede deshacer.", + validatedConfirmed, null) +}); + +function validatedConfirmed(){ + $.ajax({ + url: "id) ?>", + type: 'GET', + success: function(response){ + window.location.href = "id) ?>"; + } + }); +} + + endSection() ?> @@ -51,6 +110,7 @@ "> + endSection() ?> section('additionalExternalJs') ?> @@ -64,6 +124,9 @@ + + + endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php index d92ce5a8..6e277b1f 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php @@ -27,6 +27,7 @@ + @@ -110,7 +111,24 @@ { 'data': 'base' }, { 'data': 'total' }, { 'data': 'pendiente' }, - { 'data': 'creditoAsegurado' }, + { '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){ @@ -179,13 +197,14 @@ break; default: - return '--'; // Debug + return data; // Debug break; } } }, { 'data': 'vencimiento' }, + { 'data': 'dias_vencimiento' }, { 'data': actionBtns } ] }); diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php b/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php index c3871138..03c61bc5 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php @@ -10,6 +10,21 @@
+ + + + + + + + + + + + + + +
ID
@@ -19,6 +34,77 @@ section('additionalInlineJs') ?> +const actionBtns_facturas = function(data) { + return ` + +
+ +
+ `; +}; +tablaFacturasPedido = $('#tableOfFacturas').DataTable({ + processing: true, + serverSide: true, + autoWidth: true, + responsive: true, + scrollX: true, + "dom": 't', + stateSave: true, + order: [[1, 'asc']], + language: { + url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" + }, + ajax : $.fn.dataTable.pipeline( { + url: '', + method: 'POST', + data: function ( d ) { + d.pedido_id = id ?>; + }, + headers: {'X-Requested-With': 'XMLHttpRequest'}, + async: true, + }), + columnDefs: [ + { + orderable: false, + searchable: false, + targets: [0] + } + ], + columns : [ + { 'data': actionBtns_facturas }, + { 'data': 'id' }, + { 'data': 'numero' }, + { 'data': 'serie' }, + { 'data': 'estado', + render: function(data, type, row, meta) { + switch(data){ + case "borrador": + return ''; + break; + + case "validada": + return ''; + break; + + default: + return '--'; // Debug + break; + + } + } + }, + { 'data': 'fecha_factura_at' }, + { 'data': 'total' }, + ] +}); + +$(document).on('click', '.btn-view-factura', function(e) { + var pedido_id = $(this).data('id'); + var url = ''; + url = url.replace(':id', pedido_id ); + + window.open(url, '_blank'); +}); endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidosList.php b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidosList.php index 1a169428..6a395ff5 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidosList.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/viewPedidosList.php @@ -11,6 +11,14 @@
+
+
+ + +
+
@@ -23,11 +31,11 @@ - - - + + + - + @@ -57,24 +65,130 @@ `; }; - theTable = $('#tableOfPedidos').DataTable({ +// Setup - add a text input to each footer cell +$('#tableOfPedidos thead tr').clone(true).appendTo('#tableOfPedidos thead'); +$('#tableOfPedidos thead tr:eq(1) th').each(function (i) { + if (!$(this).hasClass("noFilter")) { + var title = $(this).text(); + if($(this).hasClass("totalizador")){ + if(i==9){ + $(this).html('