Merge branch 'main' into feat/pedidos-export

This commit is contained in:
amazuecos
2024-08-10 21:11:10 +02:00
49 changed files with 2337 additions and 599 deletions

View File

@ -70,7 +70,6 @@ $routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion']
/* Series Factura */ /* Series Factura */
$routes->group('series-facturas', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) { $routes->group('series-facturas', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) {
$routes->get('', 'SeriesFacturas::index', ['as' => 'seriesFacturasList']); $routes->get('', 'SeriesFacturas::index', ['as' => 'seriesFacturasList']);
$routes->match(['get', 'post'], 'add', 'SeriesFacturas::add', ['as' => 'seriesFacturasAdd']); $routes->match(['get', 'post'], 'add', 'SeriesFacturas::add', ['as' => 'seriesFacturasAdd']);
$routes->match(['get', 'post'], 'edit/(:num)', 'SeriesFacturas::edit/$1', ['as' => 'seriesFacturasEdit']); $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']); $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->get('add', 'Facturas::add', ['as' => 'newFactura']);
$routes->post('add', 'Facturas::add', ['as' => 'createFactura']); $routes->post('add', 'Facturas::add', ['as' => 'createFactura']);
$routes->get('edit/(:any)', 'Facturas::edit/$1', ['as' => 'editarFactura']); $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('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('datatable/(:any)', 'FacturasLineas::datatable/$1', ['as' => 'dataTableOfLineasFacturas']);
$routes->post('menuPedidosPendientes/(:num)', 'Facturas::menuPedidosPendientes/$1', ['as' => 'menuPedidosPendientesImpresion']); $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('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('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('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']);
}); });

View File

@ -395,7 +395,7 @@ class Cliente extends \App\Controllers\BaseResourceController
protected function getFormaDePagoListItems($selId = null) 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)) : if (!empty($selId)) :
$formaPagoModel = model('App\Models\Configuracion\FormaPagoModel'); $formaPagoModel = model('App\Models\Configuracion\FormaPagoModel');

View File

@ -9,7 +9,7 @@ use App\Entities\Configuracion\FormaPagoEntity;
use App\Models\Configuracion\FormaPagoModel; use App\Models\Configuracion\FormaPagoModel;
class Formaspagos extends \App\Controllers\BaseResourceController class FormasPago extends \App\Controllers\BaseResourceController
{ {
protected $modelName = FormaPagoModel::class; protected $modelName = FormaPagoModel::class;
@ -22,15 +22,22 @@ class Formaspagos extends \App\Controllers\BaseResourceController
protected static $controllerSlug = 'formas-pagos'; 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'; protected $indexRoute = 'formaDePagoList';
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger) 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; $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); parent::initController($request, $response, $logger);
} }
@ -40,7 +47,7 @@ class Formaspagos extends \App\Controllers\BaseResourceController
$viewData = [ $viewData = [
'currentModule' => static::$controllerSlug, 'currentModule' => static::$controllerSlug,
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('FormasPagoes.formaDePago')]), 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('FormasPago.formaDePago')]),
'formaPagoEntity' => new FormaPagoEntity(), 'formaPagoEntity' => new FormaPagoEntity(),
'usingServerSideDataTable' => true, 'usingServerSideDataTable' => true,
@ -55,22 +62,15 @@ class Formaspagos extends \App\Controllers\BaseResourceController
public function add() public function add()
{ {
if ($this->request->getPost()) : if ($this->request->getPost()) :
$nullIfEmpty = true; // !(phpversion() >= '8.1');
$postData = $this->request->getPost(); $postData = $this->request->getPost();
$sanitizedData = $this->sanitized($postData, $nullIfEmpty); $sanitizedData = $this->sanitized($postData, true);
$noException = true; $noException = true;
if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :
if ($this->canValidate()) : if ($this->canValidate()) :
try { try {
$successfulResult = $this->model->skipValidation(true)->save($sanitizedData); $successfulResult = $this->model->skipValidation(true)->save($sanitizedData);
@ -93,7 +93,8 @@ class Formaspagos extends \App\Controllers\BaseResourceController
if ($thenRedirect) : if ($thenRedirect) :
if (!empty($this->indexRoute)) : 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: else:
return $this->redirect2listView('sweet-success', $message); return $this->redirect2listView('sweet-success', $message);
endif; endif;
@ -106,11 +107,8 @@ class Formaspagos extends \App\Controllers\BaseResourceController
endif; // ($requestMethod === 'post') endif; // ($requestMethod === 'post')
$this->viewData['formaPagoEntity'] = isset($sanitizedData) ? new FormaPagoEntity($sanitizedData) : new FormaPagoEntity(); $this->viewData['formaPagoEntity'] = isset($sanitizedData) ? new FormaPagoEntity($sanitizedData) : new FormaPagoEntity();
$this->viewData['formAction'] = route_to('formasPagoAdd');
$this->viewData['formAction'] = route_to('createFormaDePago'); $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('FormasPago.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix');
$this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('FormasPagoes.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix');
return $this->displayForm(__METHOD__); return $this->displayForm(__METHOD__);
} // end function add() } // end function add()
@ -125,25 +123,18 @@ class Formaspagos extends \App\Controllers\BaseResourceController
$formaPagoEntity = $this->model->find($id); $formaPagoEntity = $this->model->find($id);
if ($formaPagoEntity == false) : 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); return $this->redirect2listView('sweet-error', $message);
endif; endif;
if ($this->request->getPost()) : if ($this->request->getPost()) :
$nullIfEmpty = true; // !(phpversion() >= '8.1');
$postData = $this->request->getPost(); $postData = $this->request->getPost();
$sanitizedData = $this->sanitized($postData, true);
$sanitizedData = $this->sanitized($postData, $nullIfEmpty);
$noException = true; $noException = true;
if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :
if ($this->canValidate()) : if ($this->canValidate()) :
try { try {
$successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData);
@ -152,13 +143,12 @@ class Formaspagos extends \App\Controllers\BaseResourceController
$this->dealWithException($e); $this->dealWithException($e);
} }
else: 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()); $this->session->setFlashdata('formErrors', $this->model->errors());
endif; endif;
$formaPagoEntity->fill($sanitizedData); $formaPagoEntity->fill($sanitizedData);
$thenRedirect = false; $thenRedirect = false;
endif; endif;
if ($noException && $successfulResult) : if ($noException && $successfulResult) :
@ -179,11 +169,8 @@ class Formaspagos extends \App\Controllers\BaseResourceController
endif; // ($requestMethod === 'post') endif; // ($requestMethod === 'post')
$this->viewData['formaPagoEntity'] = $formaPagoEntity; $this->viewData['formaPagoEntity'] = $formaPagoEntity;
$this->viewData['formAction'] = route_to('formasPagoEdit', $id);
$this->viewData['formAction'] = route_to('updateFormaDePago', $id); $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('FormasPago.moduleTitle') . ' ' . lang('Basic.global.edit3');
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('FormasPagoes.moduleTitle') . ' ' . lang('Basic.global.edit3');
return $this->displayForm(__METHOD__, $id); return $this->displayForm(__METHOD__, $id);
} // end function edit(...) } // end function edit(...)

View File

@ -66,7 +66,6 @@ class SeriesFacturas extends BaseResourceController
$noException = true; $noException = true;
if ($successfulResult = $this->canValidate()) : if ($successfulResult = $this->canValidate()) :
if ($this->canValidate()) : if ($this->canValidate()) :
try { try {
$successfulResult = $this->model->skipValidation(true)->save($sanitizedData); $successfulResult = $this->model->skipValidation(true)->save($sanitizedData);
@ -105,7 +104,6 @@ class SeriesFacturas extends BaseResourceController
$this->viewData['formAction'] = route_to('seriesFacturasAdd'); $this->viewData['formAction'] = route_to('seriesFacturasAdd');
$this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('SeriesFacturas.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix'); $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('SeriesFacturas.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix');
return $this->displayForm(__METHOD__); return $this->displayForm(__METHOD__);
} // end function add() } // end function add()
@ -126,7 +124,6 @@ class SeriesFacturas extends BaseResourceController
if ($this->request->getPost()) : if ($this->request->getPost()) :
$postData = $this->request->getPost(); $postData = $this->request->getPost();
$sanitizedData = $this->sanitized($postData, true); $sanitizedData = $this->sanitized($postData, true);
if ($this->request->getPost('show_erp') == null) { if ($this->request->getPost('show_erp') == null) {
$sanitizedData['show_erp'] = false; $sanitizedData['show_erp'] = false;

View File

@ -143,6 +143,11 @@ class Facturas extends \App\Controllers\BaseResourceController
helper('form'); 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; $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]); $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Facturas.factura')), $id]);
return $this->redirect2listView('sweet-error', $message); return $this->redirect2listView('sweet-error', $message);
endif; endif;
$this->obtenerDatosFormulario($factura); $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['facturaEntity'] = $factura;
$this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Facturas.factura') . ' ' . lang('Basic.global.edit3'); $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){ public function update($id = null){
if ($this->request->isAJAX()) { 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){ public function addLineaPedidoImpresion($factura_id){
@ -324,48 +484,55 @@ class Facturas extends \App\Controllers\BaseResourceController
try{ try{
$pedido_linea_id = $this->request->getPost('lineaPedido') ?? 0; $pedido_linea_id = $this->request->getPost('lineaPedido') ?? 0;
$linea = $model_pedido_linea->find($pedido_linea_id); $linea = $model_pedido_linea->find($pedido_linea_id);
$factura = $this->model->find($factura_id);
if($linea){ if($factura){
$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;
$data = (object)[ if($linea){
'factura_id'=>$factura_id, $presupuesto = $model_presupuesto->find($linea->presupuesto_id);
'pedido_linea_impresion_id'=>$linea->pedido_id,
'descripcion'=>$descripcion[0]->concepto,
'cantidad'=>$cantidad,
'precio_unidad'=>$presupuesto->total_precio_unidad,
'iva' => $presupuesto->iva_reducido==1 ? 4 : 21,
'base' => $base,
'total_iva' => $total_iva,
'total' => $total,
'user_updated_id' => auth()->user()->id,
];
$model_factura_linea->insert($data); 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(); $data = (object)[
'factura_id'=>$factura_id,
if($id){ 'pedido_linea_impresion_id'=>$linea->pedido_id,
'descripcion'=>$descripcion[0]->concepto,
$model_factura_linea->addFacturaPedidoLinea($factura_id, $linea->id, $cantidad); 'cantidad'=>$cantidad,
'precio_unidad'=>$presupuesto->total_precio_unidad,
$newTokenHash = csrf_hash(); 'iva' => $presupuesto->iva_reducido==1 ? 4 : 21,
$csrfTokenName = csrf_token(); 'base' => $base,
$data = [ 'total_iva' => $total_iva,
'error' => 0, 'total' => $total,
'id' => $id, 'user_updated_id' => auth()->user()->id,
$csrfTokenName => $newTokenHash
]; ];
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 * FUNCIONES AUXILIARES
************************************/ ************************************/
@ -407,6 +681,9 @@ class Facturas extends \App\Controllers\BaseResourceController
$serieModel = model('App\Models\Configuracion\SeriesFacturasModel'); $serieModel = model('App\Models\Configuracion\SeriesFacturasModel');
$serie = $serieModel->find($factura->serie_id); $serie = $serieModel->find($factura->serie_id);
$factura->serie_nombre = $serie->nombre; $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)) : ''; $factura->fecha_factura_at_text = $factura->fecha_factura_at ? date('d/m/Y', strtotime($factura->fecha_factura_at)) : '';
} }

View File

@ -83,96 +83,100 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
include(APPPATH . "ThirdParty/DatatablesEditor/DataTables.php"); include(APPPATH . "ThirdParty/DatatablesEditor/DataTables.php");
// Build our Editor instance and process the data coming from _POST // 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( ->fields(
Field::inst( 'plantilla_id' ), Field::inst( 'id' ),
Field::inst( 'tipo' ), Field::inst( 'base' ),
Field::inst( 'tipo_maquina' ), Field::inst( 'total_iva' ),
Field::inst( 'tipo_impresion' ), 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( '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) { ->on('preCreate', function ($editor, &$values) {
$session = session(); $totales = $this->generate_totales(
$datetime = (new \CodeIgniter\I18n\Time("now")); $values['factura_id'],
$values['pedido_linea_impresion_id'],
$values['precio_unidad'],
$values['iva'],
$values['cantidad'],
$values['old_cantidad']);
$editor $editor
->field('user_updated_id') ->field('user_updated_id')
->setValue($session->id_user); ->setValue(auth()->user()->id);
$editor $editor
->field('updated_at') ->field('base')
->setValue($datetime->format('Y-m-d H:i:s')); ->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) { ->on('preEdit', function ($editor, $id, &$values) {
$session = session(); $totales = $this->generate_totales(
$datetime = (new \CodeIgniter\I18n\Time("now")); $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 $editor
->field('user_updated_id') ->field('user_updated_id')
->setValue($session->id_user); ->setValue(auth()->user()->id);
$editor $editor
->field('updated_at') ->field('base')
->setValue($datetime->format('Y-m-d H:i:s')); ->setValue($totales['base']);
$editor
->field('total_iva')
->setValue($totales['total_iva']);
$editor
->field('total')
->setValue($totales['total']);
}) })
->debug(true) ->debug(true)
->process($_POST) ->process($_POST)
@ -189,4 +193,36 @@ class FacturasLineas extends \App\Controllers\BaseResourceController
return $this->failUnauthorized('Invalid request', 403); return $this->failUnauthorized('Invalid request', 403);
} }
} }
}
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;
}
}

View File

@ -0,0 +1,142 @@
<?php
namespace App\Controllers\Facturacion;
use App\Models\Facturas\FacturaPagoModel;
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
{
protected $modelName = FacturaPagoModel::class;
protected $format = 'json';
protected static $controllerSlug = 'factura-pagos';
public function datatable($factura_id = null){
if ($this->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);
}
}
}

View File

@ -245,13 +245,31 @@ class Pedido extends \App\Controllers\BaseResourceController
$estado = $reqData['estado'] ?? 'todos'; $estado = $reqData['estado'] ?? 'todos';
if($estado == 'todos') $estado = ''; if($estado == 'todos') $estado = '';
$model_linea = model('\App\Models\Pedidos\PedidoLineaModel'); $showTotal = $reqData['showTotal'] ?? false;
$resourceData = $model_linea->getResource($search, $estado)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject();
$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( return $this->respond(Collection::datatable(
$resourceData, $resourceData,
$model_linea->getResource("", $estado)->countAllResults(), $model_linea->getResource("", $estado)->countAllResults(),
$model_linea->getResource($search, $estado)->countAllResults() $model_linea->getResource($searchValues, $estado)->countAllResults(),
"",
[
'total_tirada' => $totalTirada,
'total' => $total
]
)); ));
} else { } else {
return $this->failUnauthorized('Invalid request', 403); return $this->failUnauthorized('Invalid request', 403);

View File

@ -111,7 +111,7 @@ class Buscador extends \App\Controllers\BaseResourceController
return $this->respond(Collection::datatable( return $this->respond(Collection::datatable(
$resourceData, $resourceData,
$this->model->getResource("")->countAllResults(), $this->model->getResource("")->countAllResults(),
$this->model->getResource($search)->countAllResults() $this->model->getResource($searchValues)->countAllResults()
)); ));
} else { } else {
return $this->failUnauthorized('Invalid request', 403); return $this->failUnauthorized('Invalid request', 403);

View File

@ -398,7 +398,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
'servicios' => $servicios, '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]); array_merge($return_data, [$csrfTokenName => $newTokenHash]);
return $this->respond($return_data); return $this->respond($return_data);
@ -1073,14 +1073,12 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController
try { try {
$return_data = []; $return_data = [];
if ($extra_info) { $info = [
$info = [ 'merma' => 0,
'merma' => 0, 'lomo_cubierta' => 0.0,
'lomo_cubierta' => 0.0, 'lomo_sobrecubierta' => 0.0,
'lomo_sobrecubierta' => 0.0, 'user_id' => auth()->user()->id,
'user_id' => auth()->user()->id, ];
];
}
$tirada = $datos_entrada['tirada']; $tirada = $datos_entrada['tirada'];
$tamanio = $datos_entrada['tamanio']; $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) { 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']['interior'] = $interior;
$return_data['info']['cubierta'] = $cubierta; $return_data['info']['cubierta'] = $cubierta;
$return_data['info']['sobrecubierta'] = $linea_sobrecubierta; $return_data['info']['sobrecubierta'] = $linea_sobrecubierta;

View File

@ -25,12 +25,7 @@ class Test extends BaseController
$data = $model->obtenerLineasPedidoSinFacturar(999); $data = $model->obtenerLineasPedidoSinFacturar(999);
*/ */
$model = model("\App\Models\Facturas\FacturaLineaModel"); xdebug_info();
$data = $model->getResource(9)->get()->getResultObject();
echo('<pre>');
var_dump($data);
echo('</pre>');

View File

@ -8,8 +8,8 @@ class FacturaEntity extends \CodeIgniter\Entity\Entity
protected $attributes = [ protected $attributes = [
'id' => null, 'id' => null,
'pedido_id' => null, 'pedido_id' => null,
'factura_retificada_id' => null, 'factura_rectificada_id' => null,
'factura_retificativa_id' => null, 'factura_rectificativa_id' => null,
'cliente_id' => null, 'cliente_id' => null,
'serie_id' => null, 'serie_id' => null,
'numero' => null, 'numero' => null,
@ -33,14 +33,12 @@ class FacturaEntity extends \CodeIgniter\Entity\Entity
'updated_at' => null, 'updated_at' => null,
'deleted_at' => null, 'deleted_at' => null,
'user_created_id' => null, 'user_created_id' => null,
'user_update_id' => null, 'user_updated_id' => null,
]; ];
protected $casts = [ protected $casts = [
'id' => 'int', 'id' => 'int',
'pedido_id' => 'int', 'pedido_id' => 'int',
'factura_retificada_id' => 'int',
'factura_retificativa_id' => 'int',
'cliente_id' => 'int', 'cliente_id' => 'int',
'serie_id' => 'int', 'serie_id' => 'int',
'base' => 'float', 'base' => 'float',

View File

@ -14,7 +14,7 @@ class FacturaPagoEntity extends \CodeIgniter\Entity\Entity
'forma_pago_id' => null, 'forma_pago_id' => null,
'total' => null, 'total' => null,
'deleted_at' => null, 'deleted_at' => null,
'user_update_id' => null, 'user_updated_id' => null,
]; ];

View File

@ -679,7 +679,7 @@ return [
"menu_calendario" => "Calendar", "menu_calendario" => "Calendar",
"menu_paises" => "Countries", "menu_paises" => "Countries",
"menu_correo" => "Mail", "menu_correo" => "Mail",
"menu_formaspago" => "Payment methods", "menu_formas_pago" => "Payment methods",
"menu_imposiciones" => "Impositions", "menu_imposiciones" => "Impositions",
"menu_maquina" => "Machines", "menu_maquina" => "Machines",
"menu_papelgenerico" => "Generic paper", "menu_papelgenerico" => "Generic paper",

View File

@ -89,6 +89,7 @@ return [
'ok' => 'Ok', 'ok' => 'Ok',
'wait' => 'Wait', 'wait' => 'Wait',
'yes' => 'Yes', 'yes' => 'Yes',
'back' => 'Back',
], ],

View File

@ -22,6 +22,7 @@ return [
'serieFacturacion' => 'Billing Series', 'serieFacturacion' => 'Billing Series',
'creditoAsegurado' => 'Secured Credit', 'creditoAsegurado' => 'Secured Credit',
'facturaRectificada' => 'Rectified Invoice', 'facturaRectificada' => 'Rectified Invoice',
'facturaRectificativa' => 'Rectifying Invoice',
'razonSocial' => 'Business Name', 'razonSocial' => 'Business Name',
'cif' => 'Tax ID', 'cif' => 'Tax ID',
'direccion' => 'Address', 'direccion' => 'Address',
@ -61,8 +62,23 @@ return [
'peiddoImpresion' => 'Print Order', 'peiddoImpresion' => 'Print Order',
'peiddoMaquetacion' => 'Layout Order', 'peiddoMaquetacion' => 'Layout Order',
'nuevaLinea' => 'New Line', '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' => [ 'errors' => [
'requiredFields' => 'Fields marked with * are required', 'requiredFields' => 'Fields marked with * are required',
] ],
'validation' => [
'numerico' => 'Must be numeric',
'requerido' => 'Required',
'decimal' => 'Must be decimal',
],
]; ];

View File

@ -11,7 +11,6 @@ return [
'formasDePagos' => 'Formas de Pagos', 'formasDePagos' => 'Formas de Pagos',
'formasPago' => 'Formas Pago', 'formasPago' => 'Formas Pago',
'formasPagoList' => 'Formas Pago List', 'formasPagoList' => 'Formas Pago List',
'formasPagoes' => 'Formas Pagoes',
'id' => 'ID', 'id' => 'ID',
'moduleTitle' => 'Formas Pagoes', 'moduleTitle' => 'Formas Pagoes',
'nombre' => 'Nombre', 'nombre' => 'Nombre',

View File

@ -78,6 +78,8 @@ return [
'facturas' => 'Invoices', 'facturas' => 'Invoices',
'showTotal' => 'Show totals',
'validation' => [ 'validation' => [
], ],

View File

@ -682,7 +682,7 @@ return [
"menu_calendario" => "Calendario", "menu_calendario" => "Calendario",
"menu_paises" => "Paises", "menu_paises" => "Paises",
"menu_correo" => "Correo", "menu_correo" => "Correo",
"menu_formaspago" => "Metodos de pago", "menu_formas_pago" => "Formas de pago",
"menu_imposiciones" => "Imposiciones", "menu_imposiciones" => "Imposiciones",
"menu_maquina" => "Maquinas", "menu_maquina" => "Maquinas",
"menu_maquina_defecto" => "Maquinas por defecto", "menu_maquina_defecto" => "Maquinas por defecto",

View File

@ -90,6 +90,7 @@ return [
'wait' => 'Espere', 'wait' => 'Espere',
'yes' => 'Si', 'yes' => 'Si',
'no' => 'No', 'no' => 'No',
'back' => 'Volver',
], ],

View File

@ -22,6 +22,7 @@ return [
'serieFacturacion' => 'Serie facturación', 'serieFacturacion' => 'Serie facturación',
'creditoAsegurado' => 'Crédito asegurado', 'creditoAsegurado' => 'Crédito asegurado',
'facturaRectificada' => 'Factura rectificada', 'facturaRectificada' => 'Factura rectificada',
'facturaRectificativa' => 'Factura rectificativa',
'razonSocial' => 'Razón Social', 'razonSocial' => 'Razón Social',
'cif' => 'CIF', 'cif' => 'CIF',
'direccion' => 'Dirección', 'direccion' => 'Dirección',
@ -61,8 +62,24 @@ return [
'pedidoImpresion' => 'Pedido Impresión', 'pedidoImpresion' => 'Pedido Impresión',
'pedidoMaquetacion' => 'Pedido Maquetación', 'pedidoMaquetacion' => 'Pedido Maquetación',
'nuevaLinea' => 'Nueva Línea', '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' => [ 'errors' => [
'requiredFields' => 'Los campos marcados con * son obligatorios', '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.",
] ]
]; ];

View File

@ -78,6 +78,8 @@ return [
'facturas' => 'Facturas', 'facturas' => 'Facturas',
'showTotal' => 'Mostrar totales',
'validation' => [ 'validation' => [
], ],

View File

@ -37,6 +37,7 @@ return [
'tarifaExtraSection' => 'Tarifas extra', 'tarifaExtraSection' => 'Tarifas extra',
'proveedoresSection' => 'Proveedores', 'proveedoresSection' => 'Proveedores',
'paisesSection' => 'Países', 'paisesSection' => 'Países',
'formasPagoSection' => 'Formas de Pago',
'maquinasSection' => 'Máquinas', 'maquinasSection' => 'Máquinas',
'maquinasDefectoSection' => 'Máquinas por defecto', 'maquinasDefectoSection' => 'Máquinas por defecto',
'papelGenericoSection' => 'Papel genérico', 'papelGenericoSection' => 'Papel genérico',

View File

@ -257,7 +257,7 @@ class ClienteModel extends \App\Models\BaseModel
LEFT JOIN lg_paises t4 ON t1.pais_id = t4.id LEFT JOIN lg_paises t4 ON t1.pais_id = t4.id
LEFT JOIN users t5 ON t1.comercial_id = t5.id LEFT JOIN users t5 ON t1.comercial_id = t5.id
LEFT JOIN users t6 ON t1.soporte_id = t6.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) { if (!is_null($limit) && intval($limit) > 0) {
$sql .= " LIMIT " . intval($limit); $sql .= " LIMIT " . intval($limit);
} }
@ -287,7 +287,7 @@ class ClienteModel extends \App\Models\BaseModel
) )
->where("is_deleted", 0);; ->where("is_deleted", 0);;
$builder->join("users t5", "t1.comercial_id = t5.id", "left"); $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) return empty($search)

View File

@ -15,7 +15,7 @@ class Collection
* *
* @return array * @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; $draw = 1;
$req = service('request'); $req = service('request');
@ -38,6 +38,10 @@ class Collection
$response['error'] = $error; $response['error'] = $error;
} }
if (count($extra_data)>0) {
$response['extra'] = $extra_data;
}
return $response; return $response;
} }
} }

View File

@ -3,7 +3,7 @@ namespace App\Models\Configuracion;
class FormaPagoModel extends \App\Models\BaseModel class FormaPagoModel extends \App\Models\BaseModel
{ {
protected $table = "lg_formas_pago"; protected $table = "formas_pago";
/** /**
* Whether primary key uses auto increment. * Whether primary key uses auto increment.
@ -15,8 +15,6 @@ class FormaPagoModel extends \App\Models\BaseModel
const SORTABLE = [ const SORTABLE = [
1 => "t1.id", 1 => "t1.id",
2 => "t1.nombre", 2 => "t1.nombre",
3 => "t1.created_at",
4 => "t1.updated_at",
]; ];
protected $allowedFields = ["nombre"]; protected $allowedFields = ["nombre"];
@ -26,18 +24,30 @@ class FormaPagoModel extends \App\Models\BaseModel
protected $validationRules = [ protected $validationRules = [
"nombre" => [ "nombre" => [
"label" => "FormasPagoes.nombre", "label" => "FormasPago.nombre",
"rules" => "trim|required|max_length[255]", "rules" => "trim|required|max_length[255]",
], ],
]; ];
protected $validationMessages = [ protected $validationMessages = [
"nombre" => [ "nombre" => [
"max_length" => "FormasPagoes.validation.nombre.max_length", "max_length" => "FormasPago.validation.nombre.max_length",
"required" => "FormasPagoes.validation.nombre.required", "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. * Get resource data.
* *
@ -49,7 +59,7 @@ class FormaPagoModel extends \App\Models\BaseModel
{ {
$builder = $this->db $builder = $this->db
->table($this->table . " t1") ->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) return empty($search)
? $builder ? $builder
@ -57,12 +67,6 @@ class FormaPagoModel extends \App\Models\BaseModel
->groupStart() ->groupStart()
->like("t1.id", $search) ->like("t1.id", $search)
->orLike("t1.nombre", $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(); ->groupEnd();
} }
} }

View File

@ -108,4 +108,19 @@ class SeriesFacturasModel extends \App\Models\BaseModel
return $result; 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);
}
} }

View File

@ -38,12 +38,16 @@ class FacturaLineaModel extends \App\Models\BaseModel {
->select( ->select(
"t1.id AS id, t1.factura_id AS factura_id, "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.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.descripcion AS descripcion, t1.cantidad as cantidad, 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.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" 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("pedidos_linea t2", "t2.id = t1.pedido_linea_impresion_id", "left")
->join("presupuestos t3", "t3.id = t2.presupuesto_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.factura_id", $factura_id)
->where("t1.deleted_at", null); ->where("t1.deleted_at", null);
@ -68,5 +72,30 @@ class FacturaLineaModel extends \App\Models\BaseModel {
->where("pedido_linea_id", $pedido_linea_id) ->where("pedido_linea_id", $pedido_linea_id)
->where("cantidad", $cantidad) ->where("cantidad", $cantidad)
->delete(); ->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);
}
}
} }

View File

@ -23,11 +23,19 @@ class FacturaModel extends \App\Models\BaseModel {
11 => "DAFEDIFF(days, NOW(), t3.fecha_vencimiento_at)", 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 // Lista de columnas basada en los campos de la tabla, para asignación masiva
protected $allowedFields = [ protected $allowedFields = [
'pedido_id', 'pedido_id',
'factura_retificada_id', 'factura_rectificada_id',
'factura_retificativa_id', 'factura_rectificativa_id',
'cliente_id', 'cliente_id',
'serie_id', 'serie_id',
'numero', 'numero',
@ -51,7 +59,7 @@ class FacturaModel extends \App\Models\BaseModel {
'updated_at', 'updated_at',
'deleted_at', 'deleted_at',
'user_created_id', 'user_created_id',
'user_update_id' 'user_updated_id'
]; ];
protected $returnType = "App\Entities\Facturas\FacturaEntity"; 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, "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, 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, 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("clientes t2", "t2.id = t1.cliente_id", "left");
$builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left"); $builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left");
$builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left"); $builder->join("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) return empty($search)
? $builder ? $builder
@ -89,6 +101,30 @@ class FacturaModel extends \App\Models\BaseModel {
->groupEnd(); ->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) public function getCantidadLineaPedidoFacturada($linea_pedido_id)
{ {
$builder = $this->db $builder = $this->db
@ -98,5 +134,14 @@ class FacturaModel extends \App\Models\BaseModel {
return $builder->get()->getRow()->cantidad; 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();
}
} }

View File

@ -14,7 +14,7 @@ class FacturaPagoModel extends \App\Models\BaseModel {
'forma_pago_id', 'forma_pago_id',
'total', 'total',
'deleted_at', 'deleted_at',
'user_update_id' 'user_updated_id'
]; ];
protected $returnType = "App\Entities\Facturas\FacturaPagoEntity"; protected $returnType = "App\Entities\Facturas\FacturaPagoEntity";
@ -23,4 +23,20 @@ class FacturaPagoModel extends \App\Models\BaseModel {
protected $useSoftDeletes = true; protected $useSoftDeletes = true;
public static $labelField = "id"; 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;
}
} }

View File

@ -14,12 +14,20 @@ class PedidoLineaModel extends \App\Models\BaseModel
protected $useAutoIncrement = true; protected $useAutoIncrement = true;
const SORTABLE = [ const SORTABLE = [
0 => "t1.id", 0 => "t2.id",
1 => "t1.estado", 1 => "t2.updated_at",
2 => "t1.total_precio", 2 => "t2.fecha_entrega_real",
3 => "t1.total_tirada", 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 = [ protected $allowedFields = [
"pedido_id", "pedido_id",
"presupuesto_id", "presupuesto_id",
@ -40,7 +48,7 @@ class PedidoLineaModel extends \App\Models\BaseModel
public static $labelField = "id"; public static $labelField = "id";
public function getResource(string $search = "", $estado="") public function getResource($search = [], $estado="")
{ {
$builder = $this->db $builder = $this->db
->table($this->table . " t1") ->table($this->table . " t1")
@ -67,49 +75,146 @@ class PedidoLineaModel extends \App\Models\BaseModel
} }
} }
// Falta implementar la busqueda por grupos if (empty($search))
return empty($search) return $builder;
? $builder else {
: $builder $builder->groupStart();
->groupStart() foreach ($search as $col_search) {
->like("t1.id", $search) if ($col_search[0] != 1 && $col_search[0] != 2)
->orLike("t1.id", $search) $builder->like(self::SORTABLE[$col_search[0]], $col_search[2]);
->groupEnd(); 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 getSumOfTirada(array $search, $estado = '', $start = 0, $length = 5)
public function obtenerLineasPedidoSinFacturar($cliente_id){ {
$resultaArray = [];
$builder = $this->db $builder = $this->db
->table($this->table . " t1") ->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("pedidos t2", "t2.id = t1.pedido_id", "left");
$builder->join("presupuestos t3", "t3.id = t1.presupuesto_id", "left"); $builder->join("presupuestos t3", "t1.presupuesto_id = t3.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); // Aplica los filtros de búsqueda y estado
$builder->where("t2.estado", "finalizado"); 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 // Ejecutar la consulta y devolver resultados
$query = $builder->get(); $query = $builder->get();
$data = $query->getResult(); $data = $query->getResult();
foreach($data as $register){ foreach($data as $register) {
$item = (object)[ $item = (object)[
'id' => $register->id, 'id' => $register->id,
'text' => '['. lang('Pedidos.pedido') . ' ' . $register->pedido_id . '] ' . $register->titulo . ' - ' . lang('Presupuestos.' . $register->tipo_impresion), 'text' => '['. lang('Pedidos.pedido') . ' ' . $register->pedido_id . '] ' . $register->titulo . ' - ' . lang('Presupuestos.' . $register->tipo_impresion),
]; ];
array_push($resultaArray, $item); array_push($resultaArray, $item);
} }
return $resultaArray; return $resultaArray;
} }
} }

View File

@ -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 " . ", 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 . $this->table .
" t1 LEFT JOIN clientes " 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 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 t4 ON t1.tipo_impresion_id = t4.id LEFT JOIN lg_tipologias_libros
t5 ON t1.tipologia_id = t5.id LEFT JOIN lg_paises t5 ON t1.tipologia_id = t5.id LEFT JOIN lg_paises

View File

@ -21,7 +21,7 @@
<th><?= lang('Clientes.cif') ?></th> <th><?= lang('Clientes.cif') ?></th>
<th><?= lang('Clientes.email') ?></th> <th><?= lang('Clientes.email') ?></th>
<th><?= lang('Users.comercial') ?></th> <th><?= lang('Users.comercial') ?></th>
<th><?= lang('FormasPagoes.formaDePago') ?></th> <th><?= lang('FormasPago.formaDePago') ?></th>
<th><?= lang('Clientes.vencimiento') ?></th> <th><?= lang('Clientes.vencimiento') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th> <th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr> </tr>

View File

@ -1,12 +1,11 @@
<div class="row"> <div class="row">
<div class="col-md-12 col-lg-12 px-4"> <div class="col-md-12 col-lg-12 px-4">
<div class="mb-3"> <div class="mb-3">
<label for="nombre" class="form-label"> <label for="nombre" class="form-label">
<?=lang('FormasPagoes.nombre') ?>* <?= lang('FormasPago.nombre') ?>*
</label> </label>
<input type="text" id="nombre" name="nombre" required maxLength="255" class="form-control" value="<?=old('nombre', $formaPagoEntity->nombre) ?>"> <input type="text" id="nombre" name="nombre" required maxLength="255" class="form-control"
</div><!--//.mb-3 --> value="<?= old('nombre', $formaPagoEntity->nombre) ?>">
</div><!--//.mb-3 -->
</div><!--//.col --> </div><!--//.col -->
</div><!-- //.row -->
</div><!-- //.row -->

View File

@ -1,26 +1,45 @@
<?= $this->include("themes_commonPartialsBs/select2bs5") ?> <?= $this->include("themes/_commonPartialsBs/sweetalert") ?>
<?= $this->include("themes_commonPartialsBs/sweetalert") ?>
<?= $this->extend('themes/vuexy/main/defaultlayout') ?> <?= $this->extend('themes/vuexy/main/defaultlayout') ?>
<?= $this->section("content") ?> <?= $this->section("content") ?>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="card card-info"> <div class="card card-info">
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><?= $boxTitle ?? $pageTitle ?></h3> <h3 class="card-title"><?= $boxTitle ?? $pageTitle ?></h3>
</div><!--//.card-header --> </div><!--//.card-header -->
<form id="formaDePagoForm" method="post" action="<?= $formAction ?>"> <form id="formaDePagoForm" class="card-body" method="post" action="<?= $formAction ?>">
<?= csrf_field() ?> <?= csrf_field() ?>
<div class="card-body"> <div class="card-body">
<?= view("themes_commonPartialsBs/_alertBoxes") ?> <?= view("themes/_commonPartialsBs/_alertBoxes") ?>
<?= !empty($validation->getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> <?= !empty($validation->getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?>
<?= view("themes/vuexy/form/configuracion/formasPagoViews/_formaDePagoFormItems") ?> <?= view("themes/vuexy/form/configuracion/formas-pago/_formaDePagoFormItems") ?>
</div><!-- /.card-body --> </div><!-- /.card-body -->
<div class="card-footer"> <div class="pt-4">
<?= anchor(route_to("formaDePagoList"), lang("Basic.global.Cancel"), ["class" => "btn btn-secondary float-start"]) ?> <input type="submit"
<input type="submit" class="btn btn-primary float-end" name="save" value="<?= lang("Basic.global.Save") ?>"> class="btn btn-primary float-start me-sm-3 me-1"
</div><!-- /.card-footer --> name="save"
</form> value="<?= lang("Basic.global.Save") ?>"
</div><!-- //.card --> />
<?= anchor(
route_to("formasPagoList"),
lang("Basic.global.Cancel"),
["class" => "btn btn-secondary float-start",]
) ?>
</div>
</form>
</div><!-- //.card -->
</div><!--//.col --> </div><!--//.col -->
</div><!--//.row --> </div><!--//.row -->
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('additionalExternalJs') ?>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>"
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script>
<?= $this->endSection() ?>

View File

@ -1,25 +1,23 @@
<?=$this->include('themes_commonPartialsBs/datatables') ?> <?=$this->include('themes/_commonPartialsBs/datatables') ?>
<?=$this->include('themes_commonPartialsBs/sweetalert') ?> <?=$this->include('themes/_commonPartialsBs/sweetalert') ?>
<?=$this->extend('themes'.config('Basics')->theme['name'].'/AdminLayout/defaultLayout') ?> <?= $this->include('themes/_commonPartialsBs/_confirm2delete') ?>
<?= $this->extend('themes/vuexy/main/defaultlayout') ?>
<?=$this->section('content'); ?> <?=$this->section('content'); ?>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="card card-info"> <div class="card card-info">
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><?=lang('FormasPagoes.formaDePagoList') ?></h3> <h3 class="card-title"><?=lang('FormasPago.formaPagoList') ?></h3>
<?=anchor(route_to('formasPagoAdd'), lang('Basic.global.addNew').' '.lang('FormasPago.formaPago'), ['class'=>'btn btn-primary float-end']); ?>
</div><!--//.card-header --> </div><!--//.card-header -->
<div class="card-body"> <div class="card-body">
<?= view('themes_commonPartialsBs/_alertBoxes'); ?> <?= view('themes/_commonPartialsBs/_alertBoxes'); ?>
<table id="tableOfFormasdepagos" class="table table-striped table-hover" style="width: 100%;"> <table id="tableOfFormasdepagos" class="table table-striped table-hover" style="width: 100%;">
<thead> <thead>
<tr> <tr>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th> <th><?= lang('FormasPago.nombre') ?></th>
<th><?=lang('FormasPagoes.id')?></th>
<th><?= lang('FormasPagoes.nombre') ?></th>
<th><?= lang('FormasPagoes.createdAt') ?></th>
<th><?= lang('FormasPagoes.updatedAt') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th> <th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr> </tr>
</thead> </thead>
@ -29,7 +27,7 @@
</table> </table>
</div><!--//.card-body --> </div><!--//.card-body -->
<div class="card-footer"> <div class="card-footer">
<?=anchor(route_to('newFormaDePago'), lang('Basic.global.addNew').' '.lang('FormasPagoes.formaDePago'), ['class'=>'btn btn-primary float-end']); ?>
</div><!--//.card-footer --> </div><!--//.card-footer -->
</div><!--//.card --> </div><!--//.card -->
</div><!--//.col --> </div><!--//.col -->
@ -40,125 +38,83 @@
<?=$this->section('additionalInlineJs') ?> <?=$this->section('additionalInlineJs') ?>
const lastColNr = $('#tableOfFormasdepagos').find("tr:first th").length - 1; const lastColNr = $('#tableOfFormasdepagos').find("tr:first th").length - 1;
const actionBtns = function(data) { const actionBtns = function(data) {
return `<td class="text-right py-0 align-middle"> return `<td class="text-right py-0 align-middle">
<div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm">
<button class="btn btn-sm btn-warning btn-edit me-1" data-id="${data.id}"><?= lang('Basic.global.edit') ?></button> <a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="${data.id}"></i></a>
<button class="btn btn-sm btn-danger btn-delete ms-1" data-id="${data.id}"><?= lang('Basic.global.Delete') ?></button> <a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete mx-2" data-id="${data.id}" data-bs-toggle="modal" data-bs-target="#confirm2delete"></i></a>
</div> </div>
</td>`; </td>`;
}; };
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: '<?= route_to('dataTableOfFormasDePagos') ?>',
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 }
]
});
theTable = $('#tableOfFormasdepagos').DataTable({
theTable.on( 'draw.dt', function () { processing: true,
serverSide: true,
const dateCols = [3, 4]; autoWidth: true,
const shortDateFormat = '<?= convertPhpDateToMomentFormat('mm/dd/YYYY')?>'; responsive: true,
const dateTimeFormat = '<?= convertPhpDateToMomentFormat('mm/dd/YYYY h:i a')?>'; scrollX: true,
lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ],
for (let coln of dateCols) { pageLength: 10,
theTable.column(coln, { page: 'current' }).nodes().each( function (cell, i) { lengthChange: true,
const datestr = cell.innerHTML; "dom": 'lfBrtip',
const dateStrLen = datestr.toString().trim().length; "buttons": [
if (dateStrLen > 0) { 'copy', 'csv', 'excel', 'print', {
let dateTimeParts= datestr.split(/[- :]/); // regular expression split that creates array with: year, month, day, hour, minutes, seconds values extend: 'pdfHtml5',
dateTimeParts[1]--; // monthIndex begins with 0 for January and ends with 11 for December so we need to decrement by one orientation: 'landscape',
const d = new Date(...dateTimeParts); // new Date(datestr); pageSize: 'A4'
const md = moment(d);
const usingThisFormat = dateStrLen > 11 ? dateTimeFormat : shortDateFormat;
const formattedDateStr = md.format(usingThisFormat);
cell.innerHTML = formattedDateStr;
}
});
} }
],
stateSave: true,
order: [[1, 'asc']],
language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
},
ajax : $.fn.dataTable.pipeline( {
url: '<?= route_to('formasPagoDT') ?>',
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) { $(document).on('click', '.btn-edit', function(e) {
window.location.href = `<?= route_to('formaDePagoList') ?>/${$(this).attr('data-id')}/edit`; window.location.href = `/configuracion/formas-pago/edit/${$(this).attr('data-id')}`;
}); });
$(document).on('click', '.btn-delete', function(e) {
Swal.fire({ $(document).on('click', '.btn-delete', function(e) {
title: '<?= lang('Basic.global.sweet.sureToDeleteTitle', [mb_strtolower(lang('FormasPagoes.forma de pago'))]) ?>', $(".btn-remove").attr('data-id', $(this).attr('data-id'));
text: '<?= lang('Basic.global.sweet.sureToDeleteText') ?>', });
icon: 'warning',
showCancelButton: true, $(document).on('click', '.btn-remove', function(e) {
confirmButtonColor: '#3085d6', const dataId = $(this).attr('data-id');
confirmButtonText: '<?= lang('Basic.global.sweet.deleteConfirmationButton') ?>', const row = $(this).closest('tr');
cancelButtonText: '<?= lang('Basic.global.Cancel') ?>', if ($.isNumeric(dataId)) {
cancelButtonColor: '#d33' $.ajax({
}) url: `/configuracion/formas-pago/delete/${dataId}`,
.then((result) => { method: 'GET',
const dataId = $(this).data('id'); }).done((data, textStatus, jqXHR) => {
const row = $(this).closest('tr'); $('#confirm2delete').modal('toggle');
if (result.value) { theTable.clearPipeline();
$.ajax({ theTable.row($(row)).invalidate().draw();
url: `<?= route_to('formaDePagoList') ?>/${dataId}`, popSuccessAlert(data.msg ?? jqXHR.statusText);
method: 'DELETE', }).fail((jqXHR, textStatus, errorThrown) => {
}).done((data, textStatus, jqXHR) => { popErrorAlert(jqXHR.responseJSON.messages.error)
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,
});
})
}
});
}); });

View File

@ -6,26 +6,29 @@
<?= $this->section("content") ?> <?= $this->section("content") ?>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="card card-info"> <div class="card card-info">
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><?= $boxTitle ?? $pageTitle ?></h3> <h3 class="card-title"><?= $boxTitle ?? $pageTitle ?></h3>
</div><!--//.card-header --> </div><!--//.card-header -->
<form id="seriesFacturasForm" class="card-body" method="post" action="<?= $formAction ?>"> <form id="seriesFacturasForm" class="card-body" method="post" action="<?= $formAction ?>">
<?= csrf_field() ?> <?= csrf_field() ?>
<?= view("themes/_commonPartialsBs/_alertBoxes") ?> <?= view("themes/_commonPartialsBs/_alertBoxes") ?>
<?= !empty($validation->getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> <?= !empty($validation->getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?>
<?= view("themes/vuexy/form/configuracion/series-facturas/_seriesFacturasFormItems") ?> <?= view("themes/vuexy/form/configuracion/series-facturas/_seriesFacturasFormItems") ?>
<div class="pt-4"> <div class="pt-4">
<input type="submit" <input type="submit"
class="btn btn-primary float-start me-sm-3 me-1" class="btn btn-primary float-start me-sm-3 me-1"
name="save" name="save"
value="<?= lang("Basic.global.Save") ?>" value="<?= lang("Basic.global.Save") ?>"
/> />
<?= anchor(route_to("seriesFacturasList"), lang("Basic.global.Cancel"), ["class" => "btn btn-secondary float-start",]) ?> <?= anchor(
route_to("seriesFacturasList"),
</div><!-- /.card-footer --> lang("Basic.global.Cancel"),
</form> ["class" => "btn btn-secondary float-start",]
</div><!-- //.card --> ) ?>
</div>
</form>
</div><!-- //.card -->
</div><!--//.col --> </div><!--//.col -->
</div><!--//.row --> </div><!--//.row -->
@ -33,20 +36,22 @@
<?=$this->section('css') ?> <?= $this->section('css') ?>
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/datatables-editor/editor.dataTables.min.css') ?>"> <link rel="stylesheet" href="<?= site_url('themes/vuexy/css/datatables-editor/editor.dataTables.min.css') ?>">
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>"> <link rel="stylesheet"
<?=$this->endSection() ?> href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
<?= $this->endSection() ?>
<?= $this->section('additionalExternalJs') ?> <?= $this->section('additionalExternalJs') ?>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>"
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script> crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?= site_url('themes/vuexy/js/datatables-editor/dataTables.editor.min.js') ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script>
<?=$this->endSection() ?> <script src="<?= site_url('themes/vuexy/js/datatables-editor/dataTables.editor.min.js') ?>"></script>
<?= $this->endSection() ?>

View File

@ -112,7 +112,7 @@
const row = $(this).closest('tr'); const row = $(this).closest('tr');
if ($.isNumeric(dataId)) { if ($.isNumeric(dataId)) {
$.ajax({ $.ajax({
url: `/configuracion/series-facturas//delete/${dataId}`, url: `/configuracion/series-facturas/delete/${dataId}`,
method: 'GET', method: 'GET',
}).done((data, textStatus, jqXHR) => { }).done((data, textStatus, jqXHR) => {
$('#confirm2delete').modal('toggle'); $('#confirm2delete').modal('toggle');

View File

@ -117,13 +117,11 @@ $('#addNewPedidoImpresion').on('click', function(){
success: function(response) { success: function(response) {
yeniden(response.<?= csrf_token() ?>); yeniden(response.<?= csrf_token() ?>);
// Se actualiza la tabla de lineas de factura
$('#tableOfLineasFactura').DataTable().clearPipeline();
$('#tableOfLineasFactura').DataTable().ajax.reload();
// se ajustan el ancho de las columnas // se ajustan el ancho de las columnas
$('#tableOfLineasFactura').DataTable().columns.adjust().draw();
$('#pedidoImpresion').val(null).trigger('change'); $('#pedidoImpresion').val(null).trigger('change');
// Se actualiza la tabla de lineas de factura
tableLineas.clearPipeline();
$('#tableOfLineasFactura').DataTable().columns.adjust().draw();
} }
}); });
}); });

View File

@ -11,7 +11,11 @@
<div class="accordion-body"> <div class="accordion-body">
<div class="row"> <div class="row">
<h4><?= lang('Facturas.factura') . ': '?> <span style="color:red;"> <?= lang('Facturas.' . $facturaEntity->estado)?> </span></h4> <h4><?= lang('Facturas.factura') . ': '?>
<span style="color:<?=($facturaEntity->estado === 'borrador')?"red":"green"?>;"> <?= lang('Facturas.' . $facturaEntity->estado)?></span>
<span class="factura-validada"> <?= ($facturaEntity->estado != 'borrador')? " / ":""?></span>
<span id="estado_pago_text" class="factura-validada" style="color:<?=($facturaEntity->estado_pago === 'pendiente')?"red":"green"?>;<?= ($facturaEntity->estado == 'borrador')? "display:none;":""?>"> <?= lang('Facturas.' . $facturaEntity->estado_pago)?></span>
</h4>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
@ -38,7 +42,7 @@
<label for="serie_id" class="form-label"> <label for="serie_id" class="form-label">
<?= lang('Facturas.serieFacturacion') ?> <?= lang('Facturas.serieFacturacion') ?>
</label> </label>
<select id="serie_id" tabindex="2" name="serie_id" class="form-control select2bs2" style="width: 100%;"> <select <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="serie_id" tabindex="2" name="serie_id" class="form-control select2bs2 update-cabecera" style="width: 100%;">
<option value="<?= old('serie_id', $facturaEntity->serie_id) ?>" selected><?= old('serie_nombre', $facturaEntity->serie_nombre) ?></option> <option value="<?= old('serie_id', $facturaEntity->serie_id) ?>" selected><?= old('serie_nombre', $facturaEntity->serie_nombre) ?></option>
</select> </select>
</div> </div>
@ -50,7 +54,7 @@
<label for="creditoAsegurado" class="form-label"> <label for="creditoAsegurado" class="form-label">
<?= lang('Facturas.creditoAsegurado') ?> <?= lang('Facturas.creditoAsegurado') ?>
</label> </label>
<select id="creditoAsegurado" tabindex="3" name="creditoAsegurado" class="form-control select2bs2" style="width: 100%;"> <select <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="creditoAsegurado" tabindex="3" name="creditoAsegurado" class="form-control select2bs2 update-cabecera" style="width: 100%;">
<option value="0" <?= ($facturaEntity->creditoAsegurado == 0)?'selected':'' ?>> <?= lang('Basic.global.no') ?> </option> <option value="0" <?= ($facturaEntity->creditoAsegurado == 0)?'selected':'' ?>> <?= lang('Basic.global.no') ?> </option>
<option value="1" <?= ($facturaEntity->creditoAsegurado == 1)?'selected':'' ?>> <?= lang('Basic.global.yes') ?> </option> <option value="1" <?= ($facturaEntity->creditoAsegurado == 1)?'selected':'' ?>> <?= lang('Basic.global.yes') ?> </option>
</select> </select>
@ -63,7 +67,7 @@
<label for="fecha_factura_at" class="form-label"> <label for="fecha_factura_at" class="form-label">
<?= lang('Facturas.fechaFactura') ?> <?= lang('Facturas.fechaFactura') ?>
</label> </label>
<input type="text" value="" tabindex="4" id="fecha_factura_at" name="fecha_factura_at" tabindex="1" maxLength="11" class="form-control" value="<?= old('fecha_factura_at', $facturaEntity->fecha_factura_at) ?>" > <input <?= ($facturaEntity->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="<?= old('fecha_factura_at', $facturaEntity->fecha_factura_at) ?>" >
</div> </div>
</div> </div>
@ -76,7 +80,7 @@
<a href="<?= route_to('editarCliente', $facturaEntity->cliente_id); ?>" target="_blank" ><i class="ti ti-file-search ti-sm btn-edit mx-2" data-id="${data.id}"></i></a> <a href="<?= route_to('editarCliente', $facturaEntity->cliente_id); ?>" target="_blank" ><i class="ti ti-file-search ti-sm btn-edit mx-2" data-id="${data.id}"></i></a>
</div> </div>
</label> </label>
<select id="cliente_id" tabindex="5" name="tabindex="5"" class="form-control select2bs2" style="width: 100%;"> <select <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_id" tabindex="5" name="cliente_id" class="form-control select2bs2 update-cabecera" style="width: 100%;">
<option value="<?= old('cliente_id', $facturaEntity->cliente_id) ?>" selected><?= old('cliente_alias', $facturaEntity->cliente_alias) ?></option> <option value="<?= old('cliente_id', $facturaEntity->cliente_id) ?>" selected><?= old('cliente_alias', $facturaEntity->cliente_alias) ?></option>
</select> </select>
</div> </div>
@ -86,12 +90,29 @@
<div class="row mb-2"> <div class="row mb-2">
<div class="col-md-12 col-lg-6 px-4">
<div <?= ($facturaEntity->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">
<div class="mb-1">
<label for="facturaR" class="form-label factura-R">
<?= ($facturaEntity->factura_rectificada_id != null) ? lang('Facturas.facturaRectificada') : lang('Facturas.facturaRectificativa') ?>:
</label>
<input <?= ($facturaEntity->estado!='borrador')? "disabled":"" ?> id="facturaR" name="<?= ($facturaEntity->factura_rectificada_id != null) ? 'factura_rectificada_id' : 'factura_rectificativa_id' ?>" tabindex="" maxLength="25" class="form-control update-cabecera factura-R"
<?php if($facturaEntity->factura_rectificada_id == null && $facturaEntity->factura_rectificativa_id == null): ?>
value=""
<?php else: ?>
value="<?= ($facturaEntity->factura_rectificada_id != null) ? old('factura_rectificada_id', $facturaEntity->factura_rectificada_id): old('factura_rectificativa_id', $facturaEntity->factura_rectificativa_id)?>"
<?php endif; ?>
>
</div>
</div>
<div id="div_cliente" class="col-md-12 col-lg-<?= ($facturaEntity->factura_rectificada_id != null || $facturaEntity->factura_rectificativa_id != null)?"4":"6" ?> px-4">
<div class="mb-1"> <div class="mb-1">
<label for="cliente_nombre" class="form-label"> <label for="cliente_nombre" class="form-label">
<?= lang('Facturas.razonSocial') ?> <?= lang('Facturas.razonSocial') ?>
</label> </label>
<input id="cliente_nombre" name="cliente_nombre" tabindex="6" class="form-control"" value="<?= old('cliente_nombre', $facturaEntity->cliente_nombre) ?>"></input> <input <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_nombre" name="cliente_nombre" tabindex="6" class="form-control update-cabecera" value="<?= old('cliente_nombre', $facturaEntity->cliente_nombre) ?>"></input>
</div> </div>
</div> </div>
@ -100,7 +121,7 @@
<label for="cliente_cif" class="form-label"> <label for="cliente_cif" class="form-label">
<?= lang('Facturas.cif') ?> <?= lang('Facturas.cif') ?>
</label> </label>
<input id="cliente_cif" name="cliente_cif" tabindex="7" class="form-control" value="<?= old('cliente_cif', $facturaEntity->cliente_cif) ?>"></input> <input <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_cif" name="cliente_cif" tabindex="7" class="form-control update-cabecera" value="<?= old('cliente_cif', $facturaEntity->cliente_cif) ?>"></input>
</div> </div>
</div> </div>
@ -109,7 +130,7 @@
<label for="cliente_pais" class="form-label"> <label for="cliente_pais" class="form-label">
<?= lang('Facturas.pais') ?> <?= lang('Facturas.pais') ?>
</label> </label>
<input id="cliente_pais" name="cliente_pais" tabindex="8" class="form-control"" value="<?= old('cliente_pais', $facturaEntity->cliente_pais) ?>"></input> <input <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_pais" name="cliente_pais" tabindex="8" class="form-control update-cabecera" value="<?= old('cliente_pais', $facturaEntity->cliente_pais) ?>"></input>
</div> </div>
</div> </div>
@ -122,7 +143,7 @@
<label for="cliente_direccion" class="form-label"> <label for="cliente_direccion" class="form-label">
<?= lang('Facturas.direccion') ?> <?= lang('Facturas.direccion') ?>
</label> </label>
<input id="cliente_direccion" name="cliente_direccion" tabindex="6" class="form-control"" value="<?= old('cliente_address', $facturaEntity->cliente_address) ?>"></input> <input <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_direccion" name="cliente_address" tabindex="6" class="form-control update-cabecera" value="<?= old('cliente_address', $facturaEntity->cliente_address) ?>"></input>
</div> </div>
</div> </div>
@ -131,7 +152,7 @@
<label for="cliente_cp" class="form-label"> <label for="cliente_cp" class="form-label">
<?= lang('Facturas.cp') ?> <?= lang('Facturas.cp') ?>
</label> </label>
<input id="cliente_cp" name="cliente_cp" tabindex="7" class="form-control" value="<?= old('cliente_cp', $facturaEntity->cliente_cp) ?>"></input> <input <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_cp" name="cliente_cp" tabindex="7" class="form-control update-cabecera" value="<?= old('cliente_cp', $facturaEntity->cliente_cp) ?>"></input>
</div> </div>
</div> </div>
@ -140,7 +161,7 @@
<label for="cliente_ciudad" class="form-label"> <label for="cliente_ciudad" class="form-label">
<?= lang('Facturas.localidad') ?> <?= lang('Facturas.localidad') ?>
</label> </label>
<input id="cliente_ciudad" name="cliente_ciudad" tabindex="8" class="form-control"" value="<?= old('cliente_ciudad', $facturaEntity->cliente_ciudad) ?>"></input> <input <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_ciudad" name="cliente_ciudad" tabindex="8" class="form-control update-cabecera" value="<?= old('cliente_ciudad', $facturaEntity->cliente_ciudad) ?>"></input>
</div> </div>
</div> </div>
@ -149,7 +170,7 @@
<label for="cliente_provincia" class="form-label"> <label for="cliente_provincia" class="form-label">
<?= lang('Facturas.provincia') ?> <?= lang('Facturas.provincia') ?>
</label> </label>
<input id="cliente_provincia" name="cliente_provincia" tabindex="8" class="form-control"" value="<?= old('cliente_provincia', $facturaEntity->cliente_provincia) ?>"></input> <input <?= ($facturaEntity->estado != 'borrador')?'disabled ':''?> id="cliente_provincia" name="cliente_provincia" tabindex="8" class="form-control update-cabecera" value="<?= old('cliente_provincia', $facturaEntity->cliente_provincia) ?>"></input>
</div> </div>
</div> </div>
@ -163,11 +184,11 @@
<?php if ($facturaEntity->estado === 'validada' && (auth()->user()->inGroup('beta') || auth()->user()->inGroup('admin'))) : ?> <?php if ($facturaEntity->estado === 'validada' && (auth()->user()->inGroup('beta') || auth()->user()->inGroup('admin'))) : ?>
<button <button
type="button" type="button"
class="btn btn-label-primary float-start me-sm-3 me-1" class="btn btn-label-danger float-start me-sm-3 me-1"
name="pasarBorrador" name="editarValidada"
id="pasarBorrador" > id="editarValidada" >
<span class="ti-xs ti ti-save me-1"></span> <span class="ti-xs ti ti-save me-1"></span>
<?= lang("Facturas.pasarBorrador") ?> <?= lang("Basic.global.edit") ?>
</button> </button>
<?php endif; ?> <?php endif; ?>
@ -304,4 +325,66 @@ $('#cliente_id').select2({
} }
}); });
$('#editarValidada').on('click', function(){
$('.update-cabecera').prop('disabled', false);
});
$('#duplicar').on('click', function() {
var id = <?=$facturaEntity->id ?>;
var url = '<?= route_to('duplicarFactura', ':id') ?>';
url = url.replace(':id', id );
$.ajax({
url: url,
type: 'POST',
data: {
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
},
success: function(response){
if('error' in response){
} else {
var url = '<?= route_to('editarFactura', ':id') ?>';
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: '<?= route_to('updateCabecera', $facturaEntity->id) ?>',
type: 'POST',
data: {
<?= csrf_token() ?? "token" ?>: <?= csrf_token() ?>v,
name: this.name,
value: $(this).val()
},
success: function(response){
if('error' in response){
}
}
});
});
<?=$this->endSection() ?> <?=$this->endSection() ?>

View File

@ -13,7 +13,7 @@
<table id="tableOfLineasFactura" class="table table-striped table-hover" style="width: 100%;grid-template-columns: 1fr 1fr 6fr 1fr 1fr 1fr;"> <table id="tableOfLineasFactura" class="table table-striped table-hover" style="width: 100%;grid-template-columns: 1fr 1fr 6fr 1fr 1fr 1fr;">
<thead> <thead>
<tr> <tr>
<th></th> <th style="max-width:60px;"></th>
<th>id</th> <th>id</th>
<th></th> <th></th>
<th></th> <th></th>
@ -31,26 +31,26 @@
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="8" style="text-align:right">Subtotal:</td> <td colspan="9" style="text-align:right">Subtotal:</td>
<td id="subtotal-sum"></td> <td id="subtotal-sum"></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td colspan="8" style="text-align:right">I.V.A.:</td> <td colspan="9" style="text-align:right">I.V.A.:</td>
<td id="total-iva-sum"></td> <td id="total-iva-sum"></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td colspan="8" style="text-align:right">Total:</td> <td colspan="9" style="text-align:right">Total:</td>
<td id="total-sum"></td> <td id="total-sum"></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td colspan="8" style="text-align:right">Pendiente de pago:</td> <td <?= ($facturaEntity->serie_id == 7 || $facturaEntity->serie_id == 9)? "style='display:none;'":"" ?> colspan="9" style="text-align:right">Pendiente de pago:</td>
<td id="pendiente-pago"></td> <td <?= ($facturaEntity->serie_id == 7 || $facturaEntity->serie_id == 9)? "style='display:none;'":"" ?> id="pendiente-pago"></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
@ -81,33 +81,54 @@
const actionBtns = function(data) { const actionBtns = function(data) {
// se comprueba si data es null // se comprueba si data es null
if (data.pedido_id === null) { <?php if($facturaEntity->estado != 'borrador') :?>
if (data.pedido_id != null) {
return ` return `
<td class="text-right py-0 align-middle"> <div class="text-right py-0 align-middle">
<div class="row mb-2"> <div class="row">
<div class="btn-group btn-group-sm"><span class="edit"><a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="${data.id}"></i></a></span> <button type="button" class="btn btn-sm btn-primary btn-view_pedido" data-id="${data.pedido_id}">Ver pedido</button>
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete mx-2" data-id="${data.id}"></i></a>
<span class="edit"><a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="${data.id}"></i></a></span>
</div>
</div> </div>
</td>`; </div>
} `;
else{ }
else
{
return ``;
}
<?php else: ?>
if (data.pedido_id === null) {
return ` return `
<td class="text-right py-0 align-middle"> <td class="text-right py-0 align-middle">
<div class="row mb-2"> <div class="row mb-2">
<div class="btn-group btn-group-sm"> <div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete mx-2" data-id="${data.id}"></i></a> <a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete mx-2" data-id="${data.id}"></i></a>
<span class="edit"><a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="${data.id}"></i></a></span> <span class="edit"><a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="${data.id}"></i></a></span>
<span class="cancel"></span>
</div>
</div>
</td>`;
}
else{
return `
<div class="text-right py-0 align-middle">
<div class="row mb-2 align-middle">
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete mx-2" data-id="${data.id}"></i></a>
<span class="edit"><a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit mx-2" data-id="${data.id}"></i></a></span>
<span class="cancel"></span>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<button type="button" class="btn btn-sm btn-primary btn-view_pedido" data-id="${data.pedido_id}">Ver pedido</button> <button type="button" class="btn btn-sm btn-primary btn-view_pedido" data-id="${data.pedido_id}">Ver pedido</button>
</div> </div>
</td>`; </div>
`;
} }
<?php endif; ?>
}; };
var editor_lineas = new $.fn.dataTable.Editor( { var editor_lineas = new $.fn.dataTable.Editor( {
ajax: { ajax: {
url: "<?= route_to('editorOfLineasFacturas') ?>", url: "<?= route_to('editorOfLineasFacturas') ?>",
@ -119,23 +140,57 @@ var editor_lineas = new $.fn.dataTable.Editor( {
idSrc: 'id', idSrc: 'id',
fields: [ fields: [
{ {
name: "unidades", name: "cantidad",
}, { }, {
name: "concepto" name: "descripcion",
type: "textarea",
attr: {
rows: 5,
style: "height: 120px;"
}
}, { }, {
name: "precio_unidad", 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 ) { editor_lineas.on( 'preSubmit', function ( e, d, type ) {
if ( type === 'create'){ if ( type === 'create'){
d.data[0]['factura_id'] = <?= $facturaEntity->id ?>; d.data[0]['factura_id'] = <?= $facturaEntity->id ?>;
d.data[0]['old_cantidad'] = null;
} }
else if(type === 'edit' ) { else if(type === 'edit' ) {
for (v in d.data){ for (v in d.data){
d.data[v]['factura_id'] = <?= $facturaEntity->id ?>; d.data[v]['factura_id'] = <?= $facturaEntity->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 // Activate an inline edit on click of a table cell
$('#tableOfLineasFactura').on( 'click', 'tbody span.edit', function (e) { $('#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: '<a href="javascript:void(0);"><i class="ti ti-x"></i></a>', cancelHtml: '<a href="javascript:void(0);"><i class="ti ti-x"></i></a>',
cancelTrigger: 'span.cancel', cancelTrigger: 'span.cancel',
submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>', submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>',
@ -175,45 +231,102 @@ var tableLineas = $('#tableOfLineasFactura').DataTable({
responsive: true, responsive: true,
scrollX: true, scrollX: true,
columns: [ columns: [
{data: null, render: actionBtns}, {
data: actionBtns,
className: 'row-edit dt-center'
},
{data: "id"}, {data: "id"},
{data: "pedido_linea_impresion_id"}, {data: "pedido_linea_impresion_id"},
{data: "pedido_maquetacion_id"}, {data: "pedido_maquetacion_id"},
{data: "pedido_id"}, {data: "pedido_id"},
{data: "unidades"}, {data: "cantidad"},
{ {
data: "concepto", data: "descripcion",
render: function (data, type, row, meta) { render: function (data, type, row, meta) {
// se convierten a float data.total_aceptado y subtotal if(row.pedido_linea_impresion_id != null){
var total_aceptado = parseFloat(row.total_aceptado);
var subtotal = parseFloat(row.subtotal); // se convierten a float data.total_aceptado y subtotal
var total_aceptado = parseFloat(row.total_aceptado);
var subtotal = parseFloat(row.base);
var error_text = ''; var error_text = '';
if(total_aceptado != subtotal){ if(total_aceptado != subtotal){
error_text = 'El total del pedido ('+ total_aceptado + '€) no coincide con la línea ('+ subtotal + '€)'; error_text = 'El total del pedido ('+ total_aceptado + '€) no coincide con la línea ('+ subtotal + '€)';
}
var returned_data = `
<div>
${data}
</div>
<div class="mt-5">
<span style="color: red;" id="error-${meta.row}">${error_text}</span>
</div>
<div class="row mt-2">
<div style="margin-top: auto;" class="col-md-12 col-lg-2 px-4">
<label for="total-aceptado_-${meta.row}">Total aceptado</label>
<input readonly style="max-width: 110px;" type="text" id="total-aceptado_${meta.row}" value="${row.total_aceptado}">
</div>
`;
if (row.tirada_flexible === "1"){
returned_data += `
<div style="margin-top: auto;" class="col-md-12 col-lg-2 px-4">
<label for="descuento-tf_${meta.row}">Descuento tirada flexible</label>
<input readonly style="max-width: 110px;" type="text" id="descuento-tf_${meta.row}" value="${row.descuento_tirada_flexible}">
</div>
<div style="margin-top: auto;" class="col-md-12 col-lg-2 px-4">
<label for="tirada-albaran_${meta.row}">Tirada albarán</label>
<input readonly style="max-width: 110px;" type="text" id="tirada-albaran_${meta.row}" value="${row.cantidad_albaran}">
</div>
`;
if(row.cantidad<row.cantidad_albaran){
returned_data += `
<div style="margin-top: auto;" class="col-md-12 col-lg-2 px-4">
<button
type="button"
class="btn btn-label-primary float-start me-sm-3 me-1 btn-excedentes"
name="btn-excedentes_${meta.row}"
id="btn-excedentes_${meta.row}"
data-row="${meta.row}"
>
<span class="ti-xs ti ti-circle-plus me-1"></span>
Excedentes
</button>
</div>
</div>
`;
}
else{
returned_data += `
</div>
`;
}
}
else{
returned_data += `
</div>
`;
}
return returned_data;
}
else{
return `
<div>
${data}
</div>
`;
} }
return `
<div>
${data}
</div>
<div class="mt-5">
<span style="color: red;" id="error-${meta.row}">${error_text}</span>
</div>
<div class="mt-2">
<label for="input-${meta.row}">Total aceptado</label>
<input readonly type="text" id="input-${meta.row}" value="${row.total_aceptado}">
</div>
`;
} }
}, },
{data: "precio_unidad"}, {data: "precio_unidad"},
{data: "iva"}, {data: "iva"},
{data: "subtotal"}, {data: "base"},
{data: "total_iva"}, {data: "total_iva"},
{data: "total"}, {data: "total"},
], ],
@ -241,67 +354,123 @@ var tableLineas = $('#tableOfLineasFactura').DataTable({
], ],
footerCallback: function (row, data, start, end, display) { footerCallback: function (row, data, start, end, display) {
var api = this.api(); updateFooterLineas(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));
} }
}); });
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
<?php if($facturaEntity->estado == 'borrador') :?>
var pendientePago = totalTotal ;
var total_pagos = 0;
<?php else: ?>
var total_pagos = parseFloat($('#totalCobrado-sum').html()).toFixed(2);
var pendientePago = totalTotal - total_pagos;
<?php endif; ?>
if(isNaN(pendientePago)){
pendientePago = 0;
}
$('#pendiente-pago').html(pendientePago.toFixed(2));
$.ajax({
url: '<?= route_to('updateFacturaTotales', $facturaEntity->id) ?>',
method: 'POST',
data: {
base: totalSubtotal,
total: totalTotal,
total_pagos: total_pagos,
pendiente: pendientePago,
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
}
}).done((data, textStatus, jqXHR) => {
if(data.estado_pago == 'pagada'){
$('#estado_pago_text').text('<?= lang('Facturas.pagada') ?>');
$('#estado_pago_text').css('color', 'green');
}
else{
$('#estado_pago_text').text('<?= lang('Facturas.pendiente') ?>');
$('#estado_pago_text').css('color', 'red');
}
}).fail((jqXHR, textStatus, errorThrown) => {
popErrorAlert(jqXHR.responseJSON.messages.error)
})
}
// Delete row // Delete row
$(document).on('click', '.btn-delete', function(e) { $(document).on('click', '.btn-delete', function(e) {
//$(".btn-remove").attr('data-id', $(this).attr('data-id'));
const dataId = $(this).attr('data-id'); const dataId = $(this).attr('data-id');
const row = $(this).closest('tr'); const row = $(this).closest('tr');
if ($.isNumeric(dataId)) { if ($.isNumeric(dataId)) {
asyncConfirmDialogWithParams( asyncConfirmDialogWithParams(
"Borrar Linea de Factura", "Borrar Linea de Factura",
"¿Está seguro de borrar la línea? Esta acción no se puede deshacer.", "¿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 factura_linea_id = params[0];
var row = params[1]; var row = params[1];
const row_data = tableLineas.row($(row)).data();
if(row_data.pedido_linea_impresion_id != null){
var url = '<?= route_to('deleteLineaPedidoImpresion') ?>';
$.ajax({
url: url,
method: 'POST',
data: {
factura_id: <?= $facturaEntity->id ?>,
pedido_linea_impresion_id: row_data.pedido_linea_impresion_id,
cantidad: row_data.cantidad,
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
}
}).done((data, textStatus, jqXHR) => {
}).fail((jqXHR, textStatus, errorThrown) => {
popErrorAlert(jqXHR.responseJSON.messages.error)
})
}
var url = '<?= route_to('deleteLineaFactura', ':id') ?>'; var url = '<?= route_to('deleteLineaFactura', ':id') ?>';
url = url.replace(':id', factura_linea_id ); url = url.replace(':id', factura_linea_id );
$.ajax({ $.ajax({
@ -324,4 +493,57 @@ $(document).on('click', '.btn-view_pedido', function(e) {
}); });
$('#addLineaFactura').on('click', function() {
const formOptions= {
submitTrigger: 0,
submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>'
};
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 = <?= $facturaEntity->id ?>;
var url = '<?= route_to('addLineaExcedentes', ':factura_id') ?>';
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),
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
}
}).done((data, textStatus, jqXHR) => {
$('#tableOfLineasFactura').DataTable().clearPipeline();
$('#tableOfLineasFactura').DataTable().draw();
}).fail((jqXHR, textStatus, errorThrown) => {
popErrorAlert(jqXHR.responseJSON.messages.error)
})
});
<?=$this->endSection() ?> <?=$this->endSection() ?>

View File

@ -0,0 +1,352 @@
<div class="accordion accordion-bordered mt-3" id="pagosFacturas">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingPagosFacturas">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionPagosFacturaTip" aria-expanded="false" aria-controls="accordionPagosFacturaTip">
<h3><?= lang("Facturas.pagos") ?></h3>
</button>
</h2>
<div id="accordionPagosFacturaTip" class="accordion-collapse collapse show" data-bs-parent="#pagosFacturas">
<div class="accordion-body">
<table id="tableOfLineasPagos" class="table table-striped table-hover" style="width: 100%; grid-template-columns: 1fr 2fr 6fr 1fr 1fr 1fr;"">
<thead>
<tr>
<th style="max-width:30px;"></th>
<th></th>
<th><?= lang('Facturas.formaPago') ?></th>
<th><?= lang('Facturas.notas') ?></th>
<th><?= lang('Facturas.fechaVencimiento') ?></th>
<th><?= lang('Facturas.fechaCobro') ?></th>
<th><?= lang('Facturas.cantidad') ?></th>
</tr>
</thead>
<tbody></tbody>
<tfoot>
<tr>
<td colspan="6" style="text-align:right">Total:</td>
<td id="totalCobrado-sum"></td>
</tr>
</tfoot>
</table>
<div id="addPagoRow" class="row">
<div class="col-md-12 col-lg-2">
<button
type="button"
class="btn btn-label-primary float-start me-sm-3 me-1"
name="addPagoFactura"
id="addPagoFactura" >
<?= lang("Facturas.addPago") ?>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<?=$this->section('additionalInlineJs') ?>
const formas_pago = <?= json_encode($facturaEntity->formas_pago) ?>;
var formaPagoLookup = {};
formas_pago.forEach(function(pago) {
formaPagoLookup[pago.value] = pago.label;
});
const actionBtns_pagos = function(data) {
return `
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete-pago mx-2" data-id="${data.id}"></i></a>
<span class="edit-pago"><a href="javascript:void(0);"><i class="ti ti-pencil ti-sm btn-edit-pago mx-2" data-id="${data.id}"></i></a></span>
<span class="cancel-pago"></span>
</div>`;
}
var editor_pagos = new $.fn.dataTable.Editor( {
ajax: {
url: "<?= route_to('editorOfPagosFacturas') ?>",
headers: {
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>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'] = <?= $facturaEntity->id ?>;
}
else if(type === 'edit' ) {
for (v in d.data){
d.data[v]['factura_id'] = <?= $facturaEntity->id ?>;
}
}
});
editor_pagos.on( 'postSubmit', function ( e, json, data, action ) {
yeniden(json.<?= csrf_token() ?>);
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: '<?= route_to('dataTableOfPagosFacturas', $facturaEntity->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
<?php if($facturaEntity->estado == 'borrador') :?>
var pendientePago = totalTotal ;
var total_pagos = 0;
<?php else: ?>
var total_pagos = parseFloat($('#totalCobrado-sum').html()).toFixed(2);
var pendientePago = totalTotal - total_pagos;
<?php endif; ?>
// Se comprueba si pendientePago es un numero o NAN
if(isNaN(pendientePago)){
pendientePago = 0;
}
$('#pendiente-pago').html(pendientePago.toFixed(2));
$.ajax({
url: '<?= route_to('updateFacturaTotales', $facturaEntity->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('<?= lang('Facturas.pagada') ?>');
$('#estado_pago_text').css('color', 'green');
}
else{
$('#estado_pago_text').text('<?= lang('Facturas.pendiente') ?>');
$('#estado_pago_text').css('color', 'red');
}
}).fail((jqXHR, textStatus, errorThrown) => {
popErrorAlert(jqXHR.responseJSON.messages.error)
})
}
$('#addPagoFactura').on('click', function () {
const formOptions= {
submitTrigger: 0,
submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>'
};
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: '<a href="javascript:void(0);"><i class="ti ti-x"></i></a>',
cancelTrigger: 'span.cancel-pago',
submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>',
submitTrigger: 'span.edit-pago',
submit: 'allIfChanged'
}
);
} );
<?=$this->endSection() ?>

View File

@ -0,0 +1,22 @@
<div class="accordion accordion-bordered mt-3" id="rectificadaFactura">
<div class="card accordion-item active">
<h2 class="accordion-header" id="headingrectificadaFactura">
<button type="button" class="accordion-button" data-bs-toggle="collapse" data-bs-target="#accordionRectificadaFacturaTip" aria-expanded="false" aria-controls="accordionRectificadaFacturaTip">
<h3><?= lang("Facturas.facturaRectificada") ?></h3>
</button>
</h2>
<div id="accordionRectificadaFacturaTip" class="accordion-collapse collapse show" data-bs-parent="#rectificadaFactura">
<div class="accordion-body">
<p><?= lang("Facturas.facturaPagada") ?></p>
</div>
</div>
</div>
</div>
<?=$this->section('additionalInlineJs') ?>
<?=$this->endSection() ?>

View File

@ -22,14 +22,35 @@
<?php endif; ?> <?php endif; ?>
<?= view("themes/vuexy/form/facturas/_facturaLineasItems") ?> <?= view("themes/vuexy/form/facturas/_facturaLineasItems") ?>
<?php if($facturaEntity->estado !='borrador' && (strpos($facturaEntity->numero, "REC ") !== 0) ) : ?>
<?= view("themes/vuexy/form/facturas/_pagosFacturasItems") ?>
<?php endif; ?>
<?php if($facturaEntity->estado !='borrador' && (strpos($facturaEntity->numero, "REC ") === 0) ) : ?>
<?= view("themes/vuexy/form/facturas/_rectificadaFacturasItems") ?>
<?php endif; ?>
<div class="pt-4"> <div class="pt-4">
<input type="submit" <?php if($facturaEntity->estado =='borrador') : ?>
class="btn btn-primary float-start me-sm-3 me-1" <input type="button"
name="save" class="btn btn-success float-start me-sm-3 me-1"
value="<?= lang("Basic.global.Save") ?>" id="validarFactura"
/> name="validarFactura"
<?= anchor(route_to("tarifaAcabadoList"), lang("Basic.global.Cancel"), ["class" => "btn btn-secondary float-start"]) ?> value="<?= lang("Facturas.validarFactura") ?>"
/>
<input type="button"
class="btn btn-danger float-start me-sm-3 me-1"
id="borrarFactura"
name="borrarFactura"
value="<?= lang("Facturas.borrarFactura") ?>"
/>
<?php endif; ?>
<input type="button"
class="btn btn-info float-start me-sm-3 me-1"
id="imprimirFactura"
name="imprimirFactura"
value="<?= lang("Facturas.imprimirFactura") ?>"
/>
<?= anchor(route_to("facturasList"), lang("Basic.global.back"), ["class" => "btn btn-secondary float-start"]) ?>
</div><!-- /.card-footer --> </div><!-- /.card-footer -->
</form> </form>
</div><!-- //.card --> </div><!-- //.card -->
@ -41,8 +62,46 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section("additionalInlineJs") ?> <?= $this->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: "<?= route_to("borrarFactura", $facturaEntity->id) ?>",
type: 'GET',
success: function(response){
window.location.href = "<?= route_to("facturasList") ?>";
}
});
}
$("#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: "<?= route_to("validarFactura", $facturaEntity->id) ?>",
type: 'GET',
success: function(response){
window.location.href = "<?= route_to("editarFactura", $facturaEntity->id) ?>";
}
});
}
<?= $this->endSection() ?> <?= $this->endSection() ?>
@ -51,6 +110,7 @@
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>"> <link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/sk-datatables.css') ?>"> <link rel="stylesheet" href="<?= site_url('themes/vuexy/css/sk-datatables.css') ?>">
<link rel="stylesheet" href="<?= site_url('themes/vuexy/css/datatables-editor/editor.dataTables.min.css') ?>"> <link rel="stylesheet" href="<?= site_url('themes/vuexy/css/datatables-editor/editor.dataTables.min.css') ?>">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/datetime/1.5.2/css/dataTables.dateTime.min.css">
<?=$this->endSection() ?> <?=$this->endSection() ?>
<?= $this->section('additionalExternalJs') ?> <?= $this->section('additionalExternalJs') ?>
@ -64,6 +124,9 @@
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script>
<script src="<?= site_url('themes/vuexy/js/datatables-editor/dataTables.editor.min.js') ?>"></script> <script src="<?= site_url('themes/vuexy/js/datatables-editor/dataTables.editor.min.js') ?>"></script>
<script type="text/javascript" src="https://cdn.datatables.net/datetime/1.5.2/js/dataTables.dateTime.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<?=$this->endSection() ?> <?=$this->endSection() ?>

View File

@ -27,6 +27,7 @@
<th><?= lang('Facturas.estadoPago') ?></th> <th><?= lang('Facturas.estadoPago') ?></th>
<th><?= lang('Facturas.formaPago') ?></th> <th><?= lang('Facturas.formaPago') ?></th>
<th><?= lang('Facturas.vencimiento') ?></th> <th><?= lang('Facturas.vencimiento') ?></th>
<th><?= lang('Facturas.dias') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th> <th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr> </tr>
</thead> </thead>
@ -110,7 +111,24 @@
{ 'data': 'base' }, { 'data': 'base' },
{ 'data': 'total' }, { 'data': 'total' },
{ 'data': 'pendiente' }, { 'data': 'pendiente' },
{ 'data': 'creditoAsegurado' }, { 'data': 'creditoAsegurado' ,
render: function(data, type, row, meta) {
switch(data){
case "0":
return '<?= lang('Basic.global.no') ?>';
break;
case "1":
return '<?= lang('Basic.global.yes') ?>';
break;
default:
return '--'; // Debug
break;
}
},
},
{ 'data': 'estado', { 'data': 'estado',
render: function(data, type, row, meta) { render: function(data, type, row, meta) {
switch(data){ switch(data){
@ -179,13 +197,14 @@
break; break;
default: default:
return '--'; // Debug return data; // Debug
break; break;
} }
} }
}, },
{ 'data': 'vencimiento' }, { 'data': 'vencimiento' },
{ 'data': 'dias_vencimiento' },
{ 'data': actionBtns } { 'data': actionBtns }
] ]
}); });

View File

@ -10,6 +10,21 @@
<div id="accordionFacturasTip" class="accordion-collapse collapse show" data-bs-parent="#accordioFacturas"> <div id="accordionFacturasTip" class="accordion-collapse collapse show" data-bs-parent="#accordioFacturas">
<div class="accordion-body"> <div class="accordion-body">
<table id="tableOfFacturas" class="table table-striped table-hover" style="width: 100%;grid-template-columns: 1fr 1fr 6fr 1fr 1fr 1fr;">
<thead>
<tr>
<th style="max-width:60px;"></th>
<th>ID</th>
<th><?= lang('Facturas.numeroFactura') ?></th>
<th><?= lang('Facturas.serieFacturacion') ?></th>
<th><?= lang('Facturas.estado') ?></th>
<th><?= lang('Facturas.fechaFactura') ?></th>
<th><?= lang('Facturas.total') ?></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> <!-- /.accordion-body --> </div> <!-- /.accordion-body -->
</div> </div>
@ -19,6 +34,77 @@
<?=$this->section('additionalInlineJs') ?> <?=$this->section('additionalInlineJs') ?>
const actionBtns_facturas = function(data) {
return `
<td class="text-right py-0 align-middle">
<div class="btn-group btn-group-sm">
<a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-view-factura mx-2" data-id="${data.id}"></i></a>
</div>
</td>`;
};
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: '<?= route_to('dataTableOfFacturasPedido') ?>',
method: 'POST',
data: function ( d ) {
d.pedido_id = <?= $pedidoEntity->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 '<?= lang('Facturas.borrador') ?>';
break;
case "validada":
return '<?= lang('Facturas.validada') ?>';
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 = '<?= route_to('editarFactura', ':id') ?>';
url = url.replace(':id', pedido_id );
window.open(url, '_blank');
});
<?=$this->endSection() ?> <?=$this->endSection() ?>

View File

@ -11,6 +11,14 @@
</div><!--//.card-header --> </div><!--//.card-header -->
<div class="card-body"> <div class="card-body">
<?= view('themes/_commonPartialsBs/_alertBoxes'); ?> <?= view('themes/_commonPartialsBs/_alertBoxes'); ?>
<div class="row">
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" id="showTotal" name="showTotal">
<label for="showTotal" class="form-check-label">
<?= lang('Pedidos.showTotal') ?>
</label>
</div>
</div>
<table id="tableOfPedidos" class="table table-striped table-hover" style="width: 100%;"> <table id="tableOfPedidos" class="table table-striped table-hover" style="width: 100%;">
<thead> <thead>
@ -23,11 +31,11 @@
<th><?= lang('Pedidos.titulo') ?></th> <th><?= lang('Pedidos.titulo') ?></th>
<th><?= lang('Pedidos.ubicacion') ?></th> <th><?= lang('Pedidos.ubicacion') ?></th>
<th><?= lang('Pedidos.inc_rei') ?></th> <th><?= lang('Pedidos.inc_rei') ?></th>
<th><?= lang('Pedidos.num_paginas') ?></th> <th class='noFilter'><?= lang('Pedidos.num_paginas') ?></th>
<th><?= lang('Pedidos.tiradas') ?></th> <th class='totalizador'><?= lang('Pedidos.tiradas') ?></th>
<th><?= lang('Pedidos.total_presupuesto') ?></th> <th class='totalizador'><?= lang('Pedidos.total_presupuesto') ?></th>
<th><?= lang('Pedidos.estado') ?></th> <th><?= lang('Pedidos.estado') ?></th>
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th> <th class="noFilter text-nowrap"><?= lang('Basic.global.Action') ?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -57,24 +65,130 @@
</td>`; </td>`;
}; };
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('<label id="total_tirada" />');
}
else if(i==10){
$(this).html('<label id="total_aceptado" />');
}
}
else{
if(i==1 || i==2){
name = 'bs-rangepicker-range_' + i;
$(this).html('<input id="'+name+'" type="text" class="form-control " style="min-width:100px;max-width:120px;font-size:0.8rem !important;" />');
var bsRangePickerRange = $('#' + name);
bsRangePickerRange.daterangepicker({
ranges: {
'<?= lang('datePicker.hoy') ?>': [moment(), moment()],
'<?= lang('datePicker.ayer') ?>': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'<?= lang('datePicker.ultimos7') ?>': [moment().subtract(6, 'days'), moment()],
'<?= lang('datePicker.ultimos30') ?>': [moment().subtract(29, 'days'), moment()],
'<?= lang('datePicker.esteMes') ?>': [moment().startOf('month'), moment().endOf('month')],
'<?= lang('datePicker.ultimoMes') ?>': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
},
opens: 'right',
language: '<?= config('Basics')->i18n ?>',
"locale": {
"customRangeLabel": "<?= lang('datePicker.personalizar') ?>",
"format": "YYYY-MM-DD",
"separator": " ",
"applyLabel": "<?= lang('datePicker.aplicar') ?>",
"cancelLabel": "<?= lang('datePicker.limpiar') ?>",
},
"alwaysShowCalendars": true,
autoUpdateInput: false,
});
bsRangePickerRange.on('apply.daterangepicker', function(ev, picker) {
$(this).val(picker.startDate.format('YYYY-MM-DD') + ' ' + picker.endDate.format('YYYY-MM-DD'));
theTable
.column(i)
.search(this.value)
.draw();
});
bsRangePickerRange.on('cancel.daterangepicker', function(ev, picker) {
$(this).val('');
theTable
.column(i)
.search(this.value)
.draw();
});
}
else if (i == 11) {
// Agregar un selector en la tercera columna
$(this).html('<select class="form-control" style="min-width:100px;max-width:120px;font-size:0.8rem !important;"></select>');
// Agregar opciones al selector
var selector = $('select', this);
selector.append('<option value="">Todos</option>'); // Opción vacía
selector.append('<option value="validacion"><?= lang('Pedidos.validacion') ?></option>');
selector.append('<option value="produccion"><?= lang('Pedidos.produccion') ?></option>');
selector.append('<option value="finalizado"><?= lang('Pedidos.finalizado') ?></option>');
selector.append('<option value="enviado"><?= lang('Pedidos.enviado') ?></option>');
selector.append('<option value="cancelado"><?= lang('Pedidos.cancelado') ?></option>');
selector.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
theTable.column(i).search(val).draw();
});
}
else{
$(this).html('<input type="text" class="form-control " style="min-width:100px;max-width:120px;font-size:0.8rem !important;" />');
$('input', this).on('change clear', function () {
if (theTable.column(i).search() !== this.value) {
theTable
.column(i)
.search(this.value)
.draw();
}
});
}
}
}
else {
$(this).html('<span></span>');
}
});
var theTable = $('#tableOfPedidos').DataTable({
select: {
style: 'multi',
info: false
},
orderCellsTop: true,
fixedHeader: true,
processing: true, processing: true,
serverSide: true, serverSide: true,
autoWidth: true, autoWidth: true,
responsive: true, responsive: true,
searching: true,
scrollX: true, scrollX: true,
lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ], lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ],
pageLength: 50, pageLength: 100,
lengthChange: true, lengthChange: true,
"dom": 'lfBrtip', "dom": '<"mb-3"l>Brtip',
"buttons": [ "buttons": [
'copy', 'csv', 'excel', 'print', { 'colvis', 'copy', 'csv', 'excel', 'print', {
extend: 'pdfHtml5', extend: 'pdfHtml5',
orientation: 'landscape', orientation: 'landscape',
pageSize: 'A4' pageSize: 'A4'
} }
], ],
stateSave: true, stateSave: false,
order: [[0, 'asc']], order: [[0, 'asc']],
language: { language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
@ -82,8 +196,9 @@
ajax : $.fn.dataTable.pipeline( { ajax : $.fn.dataTable.pipeline( {
url: '<?= route_to('dataTableOfPedidos') ?>', url: '<?= route_to('dataTableOfPedidos') ?>',
method: 'POST', method: 'POST',
data: { data: function(d, settings){
estado: "<?= $estadoPedidos ?>", d.estado= "<?= $estadoPedidos ?>";
d.showTotal= $('#showTotal').is(':checked')? "1":"0";
}, },
headers: {'X-Requested-With': 'XMLHttpRequest'}, headers: {'X-Requested-With': 'XMLHttpRequest'},
async: true, async: true,
@ -91,7 +206,7 @@
columnDefs: [ columnDefs: [
{ {
orderable: false, orderable: false,
searchable: false, searchable: true,
targets: [lastColNr] targets: [lastColNr]
} }
], ],
@ -138,39 +253,76 @@
} }
}, },
{ 'data': actionBtns } { 'data': actionBtns }
] ],
drawCallback: function (settings) {
$('#total_tirada').text(settings.json.extra.total_tirada);
$('#total_aceptado').text(settings.json.extra.total);
}
}); });
theTable.on( 'draw.dt', function () { theTable.on( 'draw.dt', function () {
const boolCols = []; const dateCols = [1,2];
for (let coln of boolCols) { const priceCols = [10];
for (let coln of dateCols) {
theTable.column(coln, { page: 'current' }).nodes().each( function (cell, i) { theTable.column(coln, { page: 'current' }).nodes().each( function (cell, i) {
cell.innerHTML = cell.innerHTML == '1' ? '<i class="ti ti-check"></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);
cell.innerHTML = d.toLocaleDateString();
}
});
}
for (let coln of priceCols) {
theTable.column(coln, { page: 'current' }).nodes().each( function (cell, i) {
cell.innerHTML = parseFloat(cell.innerHTML).toFixed(2);
}); });
} }
}); });
$(document).on('click', '.btn-edit', function(e) { $(document).on('click', '.btn-edit', function(e) {
var url = '<?= route_to('editarPedido', ':id') ?>'; var url = '<?= route_to('editarPedido', ':id') ?>';
url = url.replace(':id', `${$(this).attr('data-id')}` ); url = url.replace(':id', `${$(this).attr('data-id')}` );
window.location.href = url; window.location.href = url;
}); });
theTable.on('click', 'tbody tr', function (e) {
e.currentTarget.classList.toggle('selected');
});
$('#showTotal').on('change', function() {
theTable.clearPipeline();
theTable.ajax.reload(null, false);
//theTable.draw();
});
<?=$this->endSection() ?> <?=$this->endSection() ?>
<?=$this->section('css') ?> <?=$this->section('css') ?>
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>"> <link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.css") ?>">
<link rel="stylesheet" href="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/fixedheader/fixedHeader.dataTables.min.css") ?>">
<link rel="stylesheet" href="<?= site_url('themes/vuexy/vendor/libs/bootstrap-daterangepicker/bootstrap-daterangepicker.css') ?>" />
<?=$this->endSection() ?> <?=$this->endSection() ?>
<?= $this->section('additionalExternalJs') ?> <?= $this->section('additionalExternalJs') ?>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/dataTables.buttons.min.js") ?>"></script>
<script src="<?= site_url("themes/vuexy/vendor/libs/datatables-sk/plugins/select/dataTables.select.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.bootstrap5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.html5.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.print.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/buttons/buttons.colVis.min.js") ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/libs/moment/moment.js') ?>"></script>
<script src="<?= site_url('themes/vuexy/vendor/libs/bootstrap-daterangepicker/bootstrap-daterangepicker.js') ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/jszip/jszip.min.js") ?>"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/pdfmake.min.js") ?>" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script> <script src="<?= site_url("/themes/vuexy/vendor/libs/datatables-sk/plugins/pdfmake/vfs_fonts.js") ?>"></script>

View File

@ -4,14 +4,15 @@
*/ */
if ( if (
auth()->user()->can('paises.menu') || auth()->user()->can('paises.menu') ||
auth()->user()->can('papeles-genericos.menu') || auth()->user()->can('formas-pago.menu') ||
auth()->user()->can('papeles-impresion.menu') || auth()->user()->can('papel-genericosk .menu') ||
auth()->user()->can('papel-impresion.menu') ||
auth()->user()->can('maquinas.menu') || auth()->user()->can('maquinas.menu') ||
auth()->user()->can('maquinas-defecto.menu') || auth()->user()->can('maquinas-defecto.menu') ||
auth()->user()->can('usuarios.menu') || auth()->user()->can('usuarios.menu') ||
auth()->user()->can('roles-permisos.menu') auth()->user()->can('roles-permisos.menu')
) { ) {
?> ?>
<li class="menu-item"> <li class="menu-item">
<a href="javascript:void(0);" class="menu-link menu-toggle"> <a href="javascript:void(0);" class="menu-link menu-toggle">
<i class="menu-icon tf-icons ti ti-adjustments-horizontal"></i> <i class="menu-icon tf-icons ti ti-adjustments-horizontal"></i>
@ -25,14 +26,21 @@ if (
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
<?php if (auth()->user()->can('papeles-genericos.menu')) { ?> <?php if (auth()->user()->can('formas-pago.menu')) { ?>
<li class="menu-item">
<a href="<?= route_to('formasPagoList') ?>" class="menu-link">
<?= lang("App.menu_formas_pago") ?>
</a>
</li>
<?php } ?>
<?php if (auth()->user()->can('papel-generico.menu')) { ?>
<li class="menu-item"> <li class="menu-item">
<a href="<?= site_url("configuracion/papelesgenericos") ?>" class="menu-link"> <a href="<?= site_url("configuracion/papelesgenericos") ?>" class="menu-link">
<?= lang("App.menu_papelgenerico") ?> <?= lang("App.menu_papelgenerico") ?>
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
<?php if (auth()->user()->can('papeles-impresion.menu')) { ?> <?php if (auth()->user()->can('papel-impresion.menu')) { ?>
<li class="menu-item"> <li class="menu-item">
<a href="<?= site_url("configuracion/papelesimpresion") ?>" class="menu-link"> <a href="<?= site_url("configuracion/papelesimpresion") ?>" class="menu-link">
<?= lang("App.menu_papelimpresion") ?> <?= lang("App.menu_papelimpresion") ?>
@ -40,32 +48,32 @@ if (
</li> </li>
<?php } ?> <?php } ?>
<?php if (auth()->user()->can('maquinas.menu')) { ?> <?php if (auth()->user()->can('maquinas.menu')) { ?>
<li class="menu-item"> <li class="menu-item">
<a href="<?= site_url("configuracion/maquinas") ?>" class="menu-link"> <a href="<?= site_url("configuracion/maquinas") ?>" class="menu-link">
<?= lang("App.menu_maquina") ?> <?= lang("App.menu_maquina") ?>
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
<?php if (auth()->user()->can('maquinas-defecto.menu')) { ?> <?php if (auth()->user()->can('maquinas-defecto.menu')) { ?>
<li class="menu-item"> <li class="menu-item">
<a href="<?= site_url("configuracion/maquinasdefecto") ?>" class="menu-link"> <a href="<?= site_url("configuracion/maquinasdefecto") ?>" class="menu-link">
<?= lang("App.menu_maquina_defecto") ?> <?= lang("App.menu_maquina_defecto") ?>
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
<?php if (auth()->user()->can('usuarios.menu')) { ?> <?php if (auth()->user()->can('usuarios.menu')) { ?>
<li class="menu-item"> <li class="menu-item">
<a href="<?= site_url("configuracion/users") ?>" class="menu-link"> <a href="<?= site_url("configuracion/users") ?>" class="menu-link">
<?= lang("App.menu_users") ?> <?= lang("App.menu_users") ?>
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
<?php if (auth()->user()->can('roles-permisos.menu')) { ?> <?php if (auth()->user()->can('roles-permisos.menu')) { ?>
<li class="menu-item"> <li class="menu-item">
<a href="<?= site_url("configuracion/group") ?>" class="menu-link"> <a href="<?= site_url("configuracion/group") ?>" class="menu-link">
<?= lang("App.menu_permission_group") ?> <?= lang("App.menu_permission_group") ?>
</a> </a>
</li> </li>
<?php } ?> <?php } ?>
<?php if (auth()->user()->can('ubicaciones.menu')) { ?> <?php if (auth()->user()->can('ubicaciones.menu')) { ?>
<li class="menu-item"> <li class="menu-item">

30
ci4/packages.txt Normal file
View File

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