From 67fbc2589f10e24d63c83cb31e9703587adeb0c4 Mon Sep 17 00:00:00 2001 From: Jaime Jimenez Date: Tue, 16 Jul 2024 22:11:21 +0200 Subject: [PATCH 1/5] trabajando en pagos (datepicker) --- ci4/app/Config/Routes.php | 9 + ci4/app/Controllers/Facturacion/Facturas.php | 150 +++++++++ .../Facturacion/FacturasLineas.php | 194 ++++++----- .../Controllers/Facturacion/FacturasPagos.php | 144 +++++++++ .../Presupuestos/Presupuestocliente.php | 2 +- ci4/app/Controllers/Test.php | 2 +- ci4/app/Entities/Facturas/FacturaEntity.php | 2 +- .../Entities/Facturas/FacturaPagoEntity.php | 2 +- ci4/app/Language/en/Basic.php | 1 + ci4/app/Language/en/Facturas.php | 16 +- ci4/app/Language/es/Basic.php | 1 + ci4/app/Language/es/Facturas.php | 17 +- .../Models/Configuracion/FormaPagoModel.php | 12 + .../Configuracion/SeriesFacturasModel.php | 15 + ci4/app/Models/Facturas/FacturaLineaModel.php | 31 +- ci4/app/Models/Facturas/FacturaModel.php | 14 +- ci4/app/Models/Facturas/FacturaPagoModel.php | 18 +- ci4/app/Models/Pedidos/PedidoLineaModel.php | 41 +-- .../vuexy/form/facturas/_addPedidosItems.php | 7 +- .../form/facturas/_facturaCabeceraItems.php | 81 ++++- .../form/facturas/_facturaLineasItems.php | 299 +++++++++++------ .../form/facturas/_pagosFacturasItems.php | 304 ++++++++++++++++++ .../vuexy/form/facturas/viewFacturaForm.php | 72 ++++- .../vuexy/form/facturas/viewFacturasList.php | 19 +- 24 files changed, 1225 insertions(+), 228 deletions(-) create mode 100644 ci4/app/Controllers/Facturacion/FacturasPagos.php create mode 100644 ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index f55032f7..8a92468c 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -655,13 +655,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->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']); + }); diff --git a/ci4/app/Controllers/Facturacion/Facturas.php b/ci4/app/Controllers/Facturacion/Facturas.php index 7f673e1e..4980bd96 100755 --- a/ci4/app/Controllers/Facturacion/Facturas.php +++ b/ci4/app/Controllers/Facturacion/Facturas.php @@ -313,6 +313,62 @@ 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(); + + $data = [ + 'base' => $postData['base'] ?? 0, + 'total' => $postData['total'] ?? 0, + 'pendiente' => $postData['pendiente'] ?? 0, + 'total_pagos' => $postData['total_pagos'] ?? 0, + 'user_updated_id' => auth()->user()->id, + ]; + + if($factura_id == 0){ + return; + } + + $model = model('\App\Models\Facturas\FacturaModel'); + $model->update($factura_id, $data); + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + public function addLineaPedidoImpresion($factura_id){ @@ -386,6 +442,97 @@ 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, + ]; + + $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'] ?? ''; + + $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 +554,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..67d0e499 --- /dev/null +++ b/ci4/app/Controllers/Facturacion/FacturasPagos.php @@ -0,0 +1,144 @@ +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' ) + ->set( function ($val, $data, $field) { + // Convierte la fecha de formato DD/MM/YYYY a YYYY-MM-DD + $date = DateTime::createFromFormat('d/m/Y', $val)->format('Y-m-d'); + return DateTime::createFromFormat('d/m/Y', $val)->format('Y-m-d'); + }), + Field::inst( 'fecha_vencimiento_at' ) + ->set( function ($val, $data, $field) { + // Convierte la fecha de formato DD/MM/YYYY a YYYY-MM-DD + return DateTime::createFromFormat('d/m/Y', $val)->format('Y-m-d'); + }), + 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/Presupuestos/Presupuestocliente.php b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php index 6e2a81c7..aa2cdbdf 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); diff --git a/ci4/app/Controllers/Test.php b/ci4/app/Controllers/Test.php index 972808b2..3650cbda 100755 --- a/ci4/app/Controllers/Test.php +++ b/ci4/app/Controllers/Test.php @@ -25,7 +25,7 @@ class Test extends BaseController $data = $model->obtenerLineasPedidoSinFacturar(999); */ - $model = model("\App\Models\Facturas\FacturaLineaModel"); + $model = model("\App\Models\Facturas\FacturaPagoModel"); $data = $model->getResource(9)->get()->getResultObject(); echo('
');
diff --git a/ci4/app/Entities/Facturas/FacturaEntity.php b/ci4/app/Entities/Facturas/FacturaEntity.php
index 131ac828..fc6c50ef 100644
--- a/ci4/app/Entities/Facturas/FacturaEntity.php
+++ b/ci4/app/Entities/Facturas/FacturaEntity.php
@@ -33,7 +33,7 @@ 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 = [
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/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..801b96c5 100644
--- a/ci4/app/Language/en/Facturas.php
+++ b/ci4/app/Language/en/Facturas.php
@@ -61,8 +61,22 @@ 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",
 
     '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/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..a4278db9 100644
--- a/ci4/app/Language/es/Facturas.php
+++ b/ci4/app/Language/es/Facturas.php
@@ -61,8 +61,23 @@ 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",
+        
         '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/Models/Configuracion/FormaPagoModel.php b/ci4/app/Models/Configuracion/FormaPagoModel.php
index 69833688..6c370437 100755
--- a/ci4/app/Models/Configuracion/FormaPagoModel.php
+++ b/ci4/app/Models/Configuracion/FormaPagoModel.php
@@ -38,6 +38,18 @@ class FormaPagoModel extends \App\Models\BaseModel
         ],
     ];
 
+    public function getMenuItems(){
+        $items = $this->findAll();
+        $menuItems = [];
+        foreach ($items as $item) {
+            $menuItems[] = [
+                "value" => $item->id,
+                "label" => $item->nombre,
+            ];
+        }
+        return $menuItems;
+    }
+
     /**
      * Get resource data.
      *
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..757f4bad 100644
--- a/ci4/app/Models/Facturas/FacturaLineaModel.php
+++ b/ci4/app/Models/Facturas/FacturaLineaModel.php
@@ -38,8 +38,8 @@ 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,
+                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"
             )
             ->join("pedidos_linea t2", "t2.id = t1.pedido_linea_impresion_id", "left")
@@ -68,5 +68,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..165a386d 100644
--- a/ci4/app/Models/Facturas/FacturaModel.php
+++ b/ci4/app/Models/Facturas/FacturaModel.php
@@ -51,7 +51,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";
@@ -79,6 +79,7 @@ class FacturaModel extends \App\Models\BaseModel {
         $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");
    
         return empty($search)
             ? $builder
@@ -98,5 +99,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..d7eb4699 100644
--- a/ci4/app/Models/Pedidos/PedidoLineaModel.php
+++ b/ci4/app/Models/Pedidos/PedidoLineaModel.php
@@ -78,38 +78,39 @@ class PedidoLineaModel extends \App\Models\BaseModel
     }
 
 
-    public function obtenerLineasPedidoSinFacturar($cliente_id){
-
+    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");
-            
-        $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("facturas_pedidos_lineas fpl", "fpl.pedido_linea_id = t1.id", "left");
-
-        $builder->where("t3.cliente_id", $cliente_id);
-        $builder->where("t2.estado", "finalizado");
-
-        
-        $builder->where("(`t3`.`tirada` > `fpl`.`cantidad` OR fpl.pedido_linea_id IS NULL)");
-           
+            ->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/Views/themes/vuexy/form/facturas/_addPedidosItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php
index cae8922e..1b616980 100644
--- a/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php
+++ b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php
@@ -117,13 +117,12 @@ $('#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();
+            tableLineas.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..6b172315 100644
--- a/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php
+++ b/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php
@@ -11,7 +11,7 @@
             
-

estado)?>

+

;"> estado)?>

@@ -38,7 +38,7 @@ - estado != 'borrador')?'disabled ':''?> id="serie_id" tabindex="2" name="serie_id" class="form-control select2bs2 update-cabecera" style="width: 100%;">
@@ -50,7 +50,7 @@ - estado != 'borrador')?'disabled ':''?> id="creditoAsegurado" tabindex="3" name="creditoAsegurado" class="form-control select2bs2 update-cabecera" style="width: 100%;"> @@ -63,7 +63,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 +76,7 @@ - estado != 'borrador')?'disabled ':''?> id="cliente_id" tabindex="5" name="cliente_id" class="form-control select2bs2 update-cabecera" style="width: 100%;"> @@ -91,7 +91,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_nombre" name="cliente_nombre" tabindex="6" class="form-control update-cabecera" value="cliente_nombre) ?>"> @@ -100,7 +100,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_cif" name="cliente_cif" tabindex="7" class="form-control update-cabecera" value="cliente_cif) ?>"> @@ -109,7 +109,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_pais" name="cliente_pais" tabindex="8" class="form-control update-cabecera" value="cliente_pais) ?>"> @@ -122,7 +122,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_direccion" name="cliente_address" tabindex="6" class="form-control update-cabecera" value="cliente_address) ?>"> @@ -131,7 +131,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_cp" name="cliente_cp" tabindex="7" class="form-control update-cabecera" value="cliente_cp) ?>"> @@ -140,7 +140,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_ciudad" name="cliente_ciudad" tabindex="8" class="form-control update-cabecera" value="cliente_ciudad) ?>"> @@ -149,7 +149,7 @@ - + estado != 'borrador')?'disabled ':''?> id="cliente_provincia" name="cliente_provincia" tabindex="8" class="form-control update-cabecera" value="cliente_provincia) ?>"> @@ -163,11 +163,11 @@ estado === 'validada' && (auth()->user()->inGroup('beta') || auth()->user()->inGroup('admin'))) : ?> @@ -304,4 +304,53 @@ $('#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(){ + + $.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..a392c655 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,25 +31,25 @@ - + - + - + - + @@ -81,33 +81,50 @@ const actionBtns = function(data) { // se comprueba si data es null - if (data.pedido_id === null) { + estado != 'borrador') :?> + if (data.pedido_id != null) { return ` - `; - } - else{ + + `; + } + + + if (data.pedido_id === null) { return ` `; + } + else{ + return ` +
+
+
+ + +
- `; +
+ `; } + }; + var editor_lineas = new $.fn.dataTable.Editor( { ajax: { url: "", @@ -119,23 +136,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 +206,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 +227,58 @@ 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 + '€)'; + } + + return ` +
+ ${data} +
+ +
+ + ${error_text} +
+ +
+ + +
+ `; + } + else{ + return ` +
+ ${data} +
+ `; } - - return ` -
- ${data} -
- -
- - ${error_text} -
- -
- - -
- `; } }, {data: "precio_unidad"}, {data: "iva"}, - {data: "subtotal"}, + {data: "base"}, {data: "total_iva"}, {data: "total"}, ], @@ -241,60 +306,84 @@ 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; + + $('#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) => { + //console.log(data); + }).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]) + deleteConfirmed, function(){}, [dataId, row]) } }); @@ -302,6 +391,26 @@ $(document).on('click', '.btn-delete', function(e) { function deleteConfirmed(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 + } + }).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 +433,14 @@ $(document).on('click', '.btn-view_pedido', function(e) { }); +$('#addLineaFactura').on('click', function() { + const formOptions= { + submitTrigger: 0, + submitHtml: '' + + }; + editor_lineas.inlineCreate('end', formOptions); +}); + + 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..46065ad0 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php @@ -0,0 +1,304 @@ +
+
+

+ +

+
+
+
id
Subtotal:Subtotal:
I.V.A.:I.V.A.:
Total:Total:
Pendiente de pago:Pendiente de pago: -
-
- - -
+
+
+
-
+ +
+
+
+ + + + + + + + + + + + + + + + + + +
Total:
+ +
+
+ +
+
+ + + + + + + +section('additionalInlineJs') ?> + +const formas_pago = formas_pago) ?>; + +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", + format: "DD/MM/YYYY" + }, + { + name: "fecha_vencimiento_at", + type: "datetime", + format: "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"}, + {data: "notes"}, + { + data: "fecha_vencimiento_at", + render: function(data, type, row) { + return data!='0000-00-00 00:00:00' ? moment(data).format('DD/MM/YYYY') : ''; + } + }, + { + data: "fecha_pago_at", + render: function(data, type, row) { + + 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] + } + ], + 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; + + $('#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) => { + //console.log(data); + }).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/viewFacturaForm.php b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php index 4f3cf2cd..1af0c041 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php @@ -22,14 +22,32 @@ + estado !='borrador') : ?> + +
- " - /> - "btn btn-secondary float-start"]) ?> + estado =='borrador') : ?> + " + /> + " + /> + " + /> + + "btn btn-secondary float-start"]) ?>
@@ -41,8 +59,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 +107,7 @@ "> + endSection() ?> section('additionalExternalJs') ?> @@ -64,6 +121,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..a882f829 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php @@ -110,7 +110,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){ From 4c3316776446dca2d921cad25ef1c870093bf778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Jim=C3=A9nez?= Date: Wed, 17 Jul 2024 14:51:47 +0200 Subject: [PATCH 2/5] casi terminado --- .../Controllers/Facturacion/FacturasPagos.php | 16 +++---- .../Models/Configuracion/FormaPagoModel.php | 2 +- ci4/app/Models/Facturas/FacturaModel.php | 5 ++- .../form/facturas/_pagosFacturasItems.php | 43 ++++++++++++++++--- .../vuexy/form/facturas/viewFacturasList.php | 4 +- 5 files changed, 52 insertions(+), 18 deletions(-) diff --git a/ci4/app/Controllers/Facturacion/FacturasPagos.php b/ci4/app/Controllers/Facturacion/FacturasPagos.php index 67d0e499..a7559933 100644 --- a/ci4/app/Controllers/Facturacion/FacturasPagos.php +++ b/ci4/app/Controllers/Facturacion/FacturasPagos.php @@ -7,6 +7,7 @@ use App\Models\Collection; use DataTables\Editor; use DataTables\Editor\Field; use DataTables\Editor\Validate; +use DataTables\Editor\Format; class FacturasPagos extends \App\Controllers\BaseResourceController { @@ -61,16 +62,13 @@ class FacturasPagos extends \App\Controllers\BaseResourceController 'message' => lang('Facturas.validation.requerido')) ), Field::inst( 'fecha_pago_at' ) - ->set( function ($val, $data, $field) { - // Convierte la fecha de formato DD/MM/YYYY a YYYY-MM-DD - $date = DateTime::createFromFormat('d/m/Y', $val)->format('Y-m-d'); - return DateTime::createFromFormat('d/m/Y', $val)->format('Y-m-d'); - }), + ->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' ) - ->set( function ($val, $data, $field) { - // Convierte la fecha de formato DD/MM/YYYY a YYYY-MM-DD - return DateTime::createFromFormat('d/m/Y', $val)->format('Y-m-d'); - }), + ->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')) diff --git a/ci4/app/Models/Configuracion/FormaPagoModel.php b/ci4/app/Models/Configuracion/FormaPagoModel.php index 6c370437..d22a1bd5 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. diff --git a/ci4/app/Models/Facturas/FacturaModel.php b/ci4/app/Models/Facturas/FacturaModel.php index 165a386d..a6d96e43 100644 --- a/ci4/app/Models/Facturas/FacturaModel.php +++ b/ci4/app/Models/Facturas/FacturaModel.php @@ -72,7 +72,9 @@ 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"); @@ -80,6 +82,7 @@ class FacturaModel extends \App\Models\BaseModel { $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 diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php index 46065ad0..fa036223 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php @@ -28,7 +28,7 @@ -
+
+ +
+
+ +

+ +
+
+
+
+ + +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 31283148..2b381c07 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php @@ -22,9 +22,12 @@ - estado !='borrador' && (strpos($facturaEntity->numero, "REC ") === 0) ) : ?> + estado !='borrador' && (strpos($facturaEntity->numero, "REC ") !== 0) ) : ?> + estado !='borrador' && (strpos($facturaEntity->numero, "REC ") === 0) ) : ?> + +
estado =='borrador') : ?> diff --git a/ci4/packages.txt b/ci4/packages.txt new file mode 100644 index 00000000..b56be82b --- /dev/null +++ b/ci4/packages.txt @@ -0,0 +1,30 @@ +ii php-cli 2:8.1+92ubuntu1 all command-line interpreter for the PHP scripting language (default) +ii php-common 2:92ubuntu1 all Common files for PHP packages +ii php-composer-ca-bundle 1.3.1-1 all utility library to find a path to the system CA bundle +ii php-composer-metadata-minifier 1.0.0-2 all Small utility library that handles metadata minification and expansion +ii php-composer-pcre 1.0.1-1 all PCRE wrapping library that offers type-safe preg_* replacements +ii php-composer-semver 3.2.9-1 all utilities, version constraint parsing and validation +ii php-composer-spdx-licenses 1.5.6-1 all SPDX licenses list and validation library +ii php-composer-xdebug-handler 2.0.4-1build1 all Restarts a process without Xdebug +ii php-curl 2:8.1+92ubuntu1 all CURL module for PHP [default] +ii php-intl 2:8.1+92ubuntu1 all Internationalisation module for PHP [default] +ii php-json-schema 5.2.11-1 all implementation of JSON schema +ii php-mbstring 2:8.1+92ubuntu1 all MBSTRING module for PHP [default] +ii php-psr-container 2.0.2-1 all Common Container Interface (PHP FIG PSR-11) +ii php-psr-log 3.0.0-1 all common interface for logging libraries +ii php-react-promise 2.7.0-2 all lightweight implementation of CommonJS Promises/A for PHP +ii php-symfony-console 5.4.4+dfsg-1ubuntu8 all run tasks from the command line +ii php-symfony-deprecation-contracts 2.4.0-1ubuntu2 all A generic function and convention to trigger deprecation notices +ii php-symfony-filesystem 5.4.4+dfsg-1ubuntu8 all basic filesystem utilities +ii php-symfony-finder 5.4.4+dfsg-1ubuntu8 all find files and directories +ii php-symfony-polyfill-php80 1.24.0-1ubuntu2 all Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions +ii php-symfony-process 5.4.4+dfsg-1ubuntu8 all execute commands in sub-processes +ii php-symfony-service-contracts 2.4.0-1ubuntu2 all Generic abstractions related to writing services +ii php-symfony-string 5.4.4+dfsg-1ubuntu8 all object-oriented API to work with strings +ii php8.1-cli 8.1.2-1ubuntu2.18 amd64 command-line interpreter for the PHP scripting language +ii php8.1-common 8.1.2-1ubuntu2.18 amd64 documentation, examples and common module for PHP +ii php8.1-curl 8.1.2-1ubuntu2.18 amd64 CURL module for PHP +ii php8.1-intl 8.1.2-1ubuntu2.18 amd64 Internationalisation module for PHP +ii php8.1-mbstring 8.1.2-1ubuntu2.18 amd64 MBSTRING module for PHP +ii php8.1-opcache 8.1.2-1ubuntu2.18 amd64 Zend OpCache module for PHP +ii php8.1-readline 8.1.2-1ubuntu2.18 amd64 readline module for PHP