diff --git a/ci4/app/Config/Auth.php b/ci4/app/Config/Auth.php index c917571c..57efc4ca 100644 --- a/ci4/app/Config/Auth.php +++ b/ci4/app/Config/Auth.php @@ -13,6 +13,7 @@ declare(strict_types=1); namespace Config; +use App\Entities\Usuarios\UsersEntity; use App\Models\UserModel; use CodeIgniter\Shield\Authentication\Passwords\ValidationRules; use CodeIgniter\Shield\Config\Auth as ShieldAuth; diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php index 3abe4e05..8a97a21c 100644 --- a/ci4/app/Config/Routes.php +++ b/ci4/app/Config/Routes.php @@ -76,7 +76,7 @@ $routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion'] $routes->match(['get', 'post'], 'edit/(:num)', 'SeriesFacturas::edit/$1', ['as' => 'seriesFacturasEdit']); $routes->get('delete/(:num)', 'SeriesFacturas::delete/$1', ['as' => 'seriesFacturasDelete']); $routes->post('datatable', 'SeriesFacturas::datatable', ['as' => 'seriesFacturasDT']); - + $routes->post('menuitemsFacturas', 'SeriesFacturas::menuItemsFacturas', ['as' => 'menuItemsOfSeriesFacturas']); }); }); @@ -652,8 +652,28 @@ $routes->group('facturas', ['namespace' => 'App\Controllers\Facturacion'], funct $routes->get('list', 'Facturas::list', ['as' => 'facturasList']); $routes->post('datatable', 'Facturas::datatable', ['as' => 'dataTableOfFacturas']); + $routes->get('add', 'Facturas::add', ['as' => 'newFactura']); + $routes->post('add', 'Facturas::add', ['as' => 'createFactura']); + $routes->get('edit/(:any)', 'Facturas::edit/$1', ['as' => 'editarFactura']); + $routes->get('validar/(:any)', 'Facturas::validar/$1', ['as' => 'validarFactura']); + $routes->post('update/(:any)', 'Facturas::update/$1', ['as' => 'actualizarFactura']); + $routes->post('duplicate/(:any)', 'Facturas::duplicate/$1', ['as' => 'duplicarFactura']); + $routes->post('datatable/(:any)', 'FacturasLineas::datatable/$1', ['as' => 'dataTableOfLineasFacturas']); + $routes->post('menuPedidosPendientes/(:num)', 'Facturas::menuPedidosPendientes/$1', ['as' => 'menuPedidosPendientesImpresion']); + $routes->post('addLineaPedidoImpresion/(:num)', 'Facturas::addLineaPedidoImpresion/$1', ['as' => 'addLineaPedidoImpresion2Factura']); + $routes->post('addLineaPedidoImpresion/(:num)', 'Facturas::addLineaPedidoImpresion/$1', ['as' => 'addLineaPedidoImpresion2Factura']); + $routes->get('deleteLinea/(:any)', 'FacturasLineas::deleteLinea/$1', ['as' => 'deleteLineaFactura']); + $routes->get('delete/(:any)', 'Facturas::delete/$1', ['as' => 'borrarFactura']); + $routes->post('deleteFacturaLineaPedido', 'Facturas::deleteLineaPedidoImpresion', ['as' => 'deleteLineaPedidoImpresion']); + $routes->post('editorLineas', 'FacturasLineas::datatable_editor', ['as' => 'editorOfLineasFacturas']); + $routes->post('updateTotales/(:any)', 'Facturas::updateTotales/$1', ['as' => 'updateFacturaTotales']); + $routes->post('updateCabecera/(:any)', 'Facturas::updateCabecera/$1', ['as' => 'updateCabecera']); + $routes->post('datatablePagos/(:any)', 'FacturasPagos::datatable/$1', ['as' => 'dataTableOfPagosFacturas']); + $routes->post('editorPagos', 'FacturasPagos::datatable_editor', ['as' => 'editorOfPagosFacturas']); + $routes->post('datatablePedidos', 'Facturas::datatablePedidos', ['as' => 'dataTableOfFacturasPedido']); }); + $routes->group( 'printpresupuestos', ['namespace' => 'App\Controllers\Pdf'], diff --git a/ci4/app/Controllers/Clientes/Cliente.php b/ci4/app/Controllers/Clientes/Cliente.php index f41401c1..2f7faefa 100755 --- a/ci4/app/Controllers/Clientes/Cliente.php +++ b/ci4/app/Controllers/Clientes/Cliente.php @@ -312,10 +312,6 @@ class Cliente extends \App\Controllers\BaseResourceController $onlyActiveOnes = false; try{ $menu = $this->model->getSelect2MenuItems($columns2select, $columns2select[1], $onlyActiveOnes, $searchStr); - $nonItem = new \stdClass; - $nonItem->id = ''; - $nonItem->text = '- ' . lang('Basic.global.None') . ' -'; - array_unshift($menu, $nonItem); } catch(Exception $e){ $menu = []; diff --git a/ci4/app/Controllers/Configuracion/SeriesFacturas.php b/ci4/app/Controllers/Configuracion/SeriesFacturas.php index b5e0faef..6dd1a0dc 100644 --- a/ci4/app/Controllers/Configuracion/SeriesFacturas.php +++ b/ci4/app/Controllers/Configuracion/SeriesFacturas.php @@ -238,10 +238,24 @@ class SeriesFacturas extends BaseResourceController $onlyActiveOnes = false; $menu = $this->model->getSelect2MenuItems($columns2select, $columns2select[1], $onlyActiveOnes, $searchStr); $nonItem = new \stdClass; - $nonItem->id = ''; - $nonItem->text = '- ' . lang('Basic.global.None') . ' -'; - array_unshift($menu, $nonItem); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + 'menu' => $menu, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + public function menuItemsFacturas() + { + if ($this->request->isAJAX()) { + $menu = $this->model->getMenuItemsFacturas(); + $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); $data = [ diff --git a/ci4/app/Controllers/Configuracion/Users.php b/ci4/app/Controllers/Configuracion/Users.php index a669d1d3..a48c1b28 100755 --- a/ci4/app/Controllers/Configuracion/Users.php +++ b/ci4/app/Controllers/Configuracion/Users.php @@ -1,4 +1,4 @@ -group_model = new GroupModel(); $this->group_user_model = new GroupsUsersModel(); @@ -46,72 +48,80 @@ class Users extends \App\Controllers\GoBaseController { ]; parent::initController($request, $response, $logger); - + } - public function index() { - + public function index() + { $this->viewData['usingClientSideDataTable'] = true; - $this->viewData['pageSubTitle'] = lang('Basic.global.ManageAllRecords', [lang('Users.user')]); + $this->viewData['pageSubTitle'] = lang('Basic.global.ManageAllRecords', [lang('Users.user')]); $this->viewData['user_model'] = $this->user_model; - - $this->viewData['userList2'] = $this->user_model->getUsersList(); + $this->viewData['userList2'] = auth()->getProvider()->findAll(); parent::index(); - } - public function add() { + public function add() + { if ($this->request->getPost()) : $postData = $this->request->getPost(); - $currentGroups = $postData['group']??[]; + // Obtener contraseña nueva si se ha introducido en texto plano + if (empty($postData['new_pwd'])) { + $postData['password'] = 'Safekat2024'; // Contraseña por defecto + }else{ + $postData['password'] = $postData['new_pwd']; + } + // Obtener los grupos a los que pertenece + $currentGroups = $postData['group'] ?? []; unset($postData['group']); + // Generar el nombre de usuario $postData['username'] = strstr($postData['email'], '@', true); - $sanitizedData = $this->sanitized($postData, true); + $sanitizedData = $this->sanitized($postData, true); $noException = true; + // Obtener proveedor de usuarios $users = auth()->getProvider(); - if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : + if ($successfulResult = $this->canValidate()) : if ($this->canValidate()) : - try { + try { $user = new User([ 'username' => $sanitizedData['username'], 'first_name' => $sanitizedData['first_name'], 'last_name' => $sanitizedData['last_name'], - 'email' => $sanitizedData['email'], - 'password' => 'Safekat2024', - 'status' => $sanitizedData['status']??0, - 'active' => $sanitizedData['active']??0, + 'email' => $sanitizedData['email'], + 'password' => $sanitizedData['password'], + 'status' => $sanitizedData['status'] ?? 0, + 'active' => $sanitizedData['active'] ?? 0, ]); $users->save($user); $successfulResult = true; // Hacked - } catch (\Exception $e) { - $noException = false; - //$this->dealWithException($e); + } catch (\Exception $e) { + $noException = false; + //$this->dealWithException($e); if (strpos($e->getMessage(), 'correo duplicado') !== false) { $this->viewData['errorMessage'] = "El correo electrónico ya está registrado en el sistema"; $this->session->setFlashdata('formErrors', $this->model->errors()); } - - } - else: - $this->viewData['errorMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Users.user'))]); + + } + else: + $this->viewData['errorMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Users.user'))]); $this->session->setFlashdata('formErrors', $this->model->errors()); - endif; - - $thenRedirect = true; // Change this to false if you want your user to stay on the form after submission + endif; + + $thenRedirect = true; // Change this to false if you want your user to stay on the form after submission endif; if ($noException && $successfulResult) : $id = $users->getInsertID(); $this->group_user_model->where('user_id', $id)->delete(); - foreach($currentGroups as $group){ + foreach ($currentGroups as $group) { $group_user_data = [ 'user_id' => $id, 'group' => $group @@ -119,8 +129,7 @@ class Users extends \App\Controllers\GoBaseController { $this->group_user_model->insert($group_user_data); } - $message = lang('Basic.global.saveSuccess', [mb_strtolower(lang('Users.user'))]) . 'Downloads'; - $message .= anchor(route_to('editUser', $id), lang('Basic.global.continueEditing').'?'); + $message = lang('Basic.global.saveSuccess', [mb_strtolower(lang('Users.user'))]) . '.'; $message = ucfirst(str_replace("'", "\'", $message)); if ($thenRedirect) : @@ -141,88 +150,92 @@ class Users extends \App\Controllers\GoBaseController { $this->viewData['clienteList'] = $this->getClienteListItems(); $this->viewData['formAction'] = route_to('createUser'); $this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll(); - $this->viewData['boxTitle'] = lang('Basic.global.addNew') .lang('Users.user').' '.lang('Basic.global.addNewSuffix'); - + $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.addNewSuffix'); + return $this->displayForm(__METHOD__); } // end function add() - public function edit($requestedId = null) { - - if ($requestedId == null) : + public function edit($requestedId = null) + { + if ($requestedId == null) { return $this->redirect2listView(); - endif; + } $id = filter_var($requestedId, FILTER_SANITIZE_URL); - $user = $this->model->find($id); + $users = auth()->getProvider(); + $user = $users->findById($id); if ($user == false) : $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Users.user')), $id]); return $this->redirect2listView('errorMessage', $message); endif; - if ($this->request->getPost()) : $postData = $this->request->getPost(); - $currentGroups = $postData['group']; + $currentGroups = $postData['group'] ?? []; unset($postData['group']); + + // Obtener contraseña nueva si se ha introducido en texto plano + // Obtener contraseña nueva si se ha introducido en texto plano + if (!empty($postData['new_pwd'])) { + $postData['password'] = $postData['new_pwd']; + } + $sanitizedData = $this->sanitized($postData, true); - if ($this->request->getPost('status') == 0 ) { + if ($this->request->getPost('status') == 0) { $sanitizedData['status'] = null; } $noException = true; - if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : + if ($successfulResult = $this->canValidate()) : + + if ($this->canValidate()) : + try { - if ($this->canValidate()) : - try { if (in_array('cliente-editor', $currentGroups) || in_array('cliente-administrador', $currentGroups)) { - if(!array_key_exists('cliente_id', $sanitizedData) || is_null($sanitizedData['cliente_id'])) { + if (!array_key_exists('cliente_id', $sanitizedData) || is_null($sanitizedData['cliente_id'])) { $this->viewData['errorMessage'] = lang('Users.errors.cliente_sin_clienteID'); $this->session->setFlashdata('formErrors', $this->model->errors()); - $successfulResult = false; + } else { + $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); } - else{ - $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); - } - } - else { + } else { $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); } - - } catch (\Exception $e) { - $noException = false; - $this->dealWithException($e); - } - else: - $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Users.user'))]); - $this->session->setFlashdata('formErrors', $this->model->errors()); - - endif; + } catch (\Exception $e) { + $noException = false; + $this->dealWithException($e); + } + else: + $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Users.user'))]); + $this->session->setFlashdata('formErrors', $this->model->errors()); - $user->fill($sanitizedData); - $thenRedirect = false; + endif; + + $user->fill($sanitizedData); + $users->save($user); + $thenRedirect = false; endif; if ($noException && $successfulResult) : $this->group_user_model->where('user_id', $user->id)->delete(); - foreach($currentGroups as $group){ + foreach ($currentGroups as $group) { $group_user_data = [ 'user_id' => $user->id, 'group' => $group ]; $this->group_user_model->insert($group_user_data); } - + $id = $user->id ?? $id; - $message = lang('Basic.global.updateSuccess', [mb_strtolower(lang('Users.user'))]) . 'Downloads'; - $message .= anchor(route_to('editUser', $id), lang('Basic.global.continueEditing').'?'); + $message = lang('Basic.global.updateSuccess', [mb_strtolower(lang('Users.user'))]) . '.'; $message = ucfirst(str_replace("'", "\'", $message)); if ($thenRedirect) : @@ -234,7 +247,7 @@ class Users extends \App\Controllers\GoBaseController { else: $this->session->setFlashData('sweet-success', $message); endif; - + endif; // $noException && $successfulResult endif; // ($requestMethod === 'post') @@ -243,13 +256,14 @@ class Users extends \App\Controllers\GoBaseController { $this->viewData['formAction'] = route_to('updateUser', $id); $this->viewData['selectedGroups'] = $this->group_model->getUsersRoles($requestedId); $this->viewData['groups'] = $this->group_model->select('keyword, title')->findAll(); - $this->viewData['boxTitle'] = lang('Basic.global.edit2') .lang('Users.user').' '.lang('Basic.global.edit3'); + $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Users.user') . ' ' . lang('Basic.global.edit3'); return $this->displayForm(__METHOD__, $id); } // end function edit(...) - public function delete($requestedId = null, bool $deletePermanently = true) { + public function delete($requestedId = null, bool $deletePermanently = true) + { if ($requestedId == null) : return $this->redirect2listView(); @@ -264,26 +278,25 @@ class Users extends \App\Controllers\GoBaseController { endif; $users = auth()->getProvider(); - $users->delete($user->id, $deletePermanently); + $users->delete($user->id); $message = "Usuario eliminado correctamente"; return $this->redirect2listView('successMessage', $message); - } // end function delete(...) - - - public function allItemsSelect() { + + public function allItemsSelect() + { if ($this->request->isAJAX()) { $onlyActiveOnes = true; $reqVal = $this->request->getPost('val') ?? 'id_user'; - $menu = $this->model->getAllForMenu($reqVal.', first_name', 'first_name', $onlyActiveOnes, false); + $menu = $this->model->getAllForMenu($reqVal . ', first_name', 'first_name', $onlyActiveOnes, false); $nonItem = new \stdClass; $nonItem->id_user = ''; - $nonItem->first_name = '- '.lang('Basic.global.None').' -'; - array_unshift($menu , $nonItem); + $nonItem->first_name = '- ' . lang('Basic.global.None') . ' -'; + array_unshift($menu, $nonItem); $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); @@ -296,8 +309,9 @@ class Users extends \App\Controllers\GoBaseController { return $this->failUnauthorized('Invalid request', 403); } } - - public function menuItems() { + + public function menuItems() + { if ($this->request->isAJAX()) { $searchStr = goSanitize($this->request->getPost('searchTerm'))[0]; $reqId = goSanitize($this->request->getPost('id'))[0]; @@ -308,8 +322,8 @@ class Users extends \App\Controllers\GoBaseController { $menu = $this->model->getSelect2MenuItems($columns2select, $columns2select[1], $onlyActiveOnes, $searchStr); $nonItem = new \stdClass; $nonItem->id = ''; - $nonItem->text = '- '.lang('Basic.global.None').' -'; - array_unshift($menu , $nonItem); + $nonItem->text = '- ' . lang('Basic.global.None') . ' -'; + array_unshift($menu, $nonItem); $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); @@ -323,10 +337,11 @@ class Users extends \App\Controllers\GoBaseController { } } - public function getMenuComerciales(){ + public function getMenuComerciales() + { if ($this->request->isAJAX()) { $comerciales = $this->model->getComerciales(); - + $newTokenHash = csrf_hash(); $csrfTokenName = csrf_token(); $data = [ @@ -339,15 +354,16 @@ class Users extends \App\Controllers\GoBaseController { } } - - protected function getPaisListItems() { - $data = [''=>lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Pais.pais'))])]; + + protected function getPaisListItems() + { + $data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Pais.pais'))])]; $paisModel = model('App\Models\Configuracion\PaisModel'); $registers = $paisModel->findAll(); - return $registers; - } + return $registers; + } protected function getClienteListItems($selId = null) { @@ -362,5 +378,5 @@ class Users extends \App\Controllers\GoBaseController { endif; return $data; } - + } diff --git a/ci4/app/Controllers/Facturacion/Facturas.php b/ci4/app/Controllers/Facturacion/Facturas.php index ae61b3af..abf1db51 100755 --- a/ci4/app/Controllers/Facturacion/Facturas.php +++ b/ci4/app/Controllers/Facturacion/Facturas.php @@ -3,6 +3,8 @@ namespace App\Controllers\Facturacion; use App\Models\Facturas\FacturaModel; +use App\Entities\Facturas\FacturaEntity; +use App\Models\Clientes\ClienteModel; use App\Models\Collection; @@ -22,14 +24,14 @@ class Facturas extends \App\Controllers\BaseResourceController public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger) { - $this->viewData['pageTitle'] = lang('Pedidos.moduleTitle'); + $this->viewData['pageTitle'] = lang('Facturas.facturas'); // Se indica que este controlador trabaja con soft_delete $this->viewData = ['usingServerSideDataTable' => true]; // Breadcrumbs $this->viewData['breadcrumb'] = [ - ['title' => lang("App.menu_pedidos"), 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("App.menu_facturas"), 'route' => "javascript:void(0);", 'active' => false], ]; parent::initController($request, $response, $logger); @@ -51,10 +53,9 @@ class Facturas extends \App\Controllers\BaseResourceController $viewData = [ 'currentModule' => static::$controllerSlug, - 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Pedidos.pedido')]), + 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Facturas.facturas')]), 'usingServerSideDataTable' => true, 'pageTitle' => lang('Facturas.facturas'), - 'estadoPedidos' => 'todos', ['title' => lang("App.menu_facturas"), 'route' => site_url('facturas/list'), 'active' => true] ]; @@ -66,6 +67,128 @@ class Facturas extends \App\Controllers\BaseResourceController return view(static::$viewPath . 'viewFacturasList', $viewData); } + + public function add() + { + if ($this->request->getPost()) : + + $nullIfEmpty = true; // !(phpversion() >= '8.1'); + + $postData = $this->request->getPost(); + + $noException = true; + $allData = true; + + if( !isset($postData['cliente_id']) || !isset($postData['serie_id']) ) { + + $this->viewData['errorMessage'] = lang('Facturas.errors.requiredFields'); + $this->session->setFlashdata('formErrors', $this->model->errors()); + + $allData = false; + $noException = false; + } + + try { + $clienteModel = model('App\Models\Clientes\ClienteModel'); + $datosCliente = $clienteModel->getClienteDataFacturas($postData['cliente_id']); + if(count($datosCliente)>0){ + // add array data datosCliente to postData + $postData = array_merge($postData, $datosCliente[0]); + } + } catch (\Exception $e) { + $noException = false; + $this->dealWithException($e); + } + + + $sanitizedData = $this->sanitized($postData, $nullIfEmpty); + + $sanitizedData['user_updated_id'] = auth()->user()->id; + $sanitizedData['user_created_id'] = auth()->user()->id; + + if ($allData && $successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : + + + if ($this->canValidate()) : + try { + $successfulResult = $this->model->skipValidation(true)->save($sanitizedData); + } catch (\Exception $e) { + $noException = false; + $this->dealWithException($e); + } + else: + $this->viewData['errorMessage'] = lang('Basic.global.formErr1', [lang('Basic.global.record')]); + $this->session->setFlashdata('formErrors', $this->model->errors()); + endif; + + endif; + if ($noException && $successfulResult) : + + $id = $this->model->db->insertID(); + + $message = lang('Basic.global.saveSuccess', [lang('Basic.global.record')]) . '.'; + + return redirect()->to(route_to('editarFactura', $id))->with('sweet-success', $message); + + + endif; // $noException && $successfulResult + + endif; // ($requestMethod === 'post') + + $this->viewData['factura'] = isset($sanitizedData) ? new FacturaEntity($sanitizedData) : new FacturaEntity(); + + $this->viewData['formAction'] = route_to('createFactura'); + + $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Facturas.facturas') . ' ' . lang('Basic.global.addNewSuffix'); + + + 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; + + $validation = \Config\Services::validation(); + + $this->viewData['validation'] = $validation; + + $viewFilePath = static::$viewPath . 'viewAddFactura'; + + return view($viewFilePath, $this->viewData); + } // end function add() + + + public function edit($id=null){ + + if ($id == null) : + return $this->redirect2listView(); + endif; + $id = filter_var($id, FILTER_SANITIZE_URL); + $factura = $this->model->find($id); + + if ($factura == false) : + $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Facturas.factura')), $id]); + return $this->redirect2listView('sweet-error', $message); + endif; + + + $this->obtenerDatosFormulario($factura); + + $this->viewData['breadcrumb'] = [ + ['title' => lang("App.menu_facturas"), 'route' => "javascript:void(0);", 'active' => false], + ['title' => lang("Facturas.facturaList"), 'route' => route_to('facturasList'), 'active' => true] + ]; + + $this->viewData['facturaEntity'] = $factura; + + $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Facturas.factura') . ' ' . lang('Basic.global.edit3'); + + return $this->displayForm(__METHOD__, $id); + } + public function datatable(){ if ($this->request->isAJAX()) { @@ -87,13 +210,425 @@ class Facturas extends \App\Controllers\BaseResourceController return $this->respond(Collection::datatable( $resourceData, - $model_linea->getResource("")->countAllResults(), - $model_linea->getResource($search)->countAllResults() + $this->model->getResource("")->countAllResults(), + $this->model->getResource($search)->countAllResults() )); } else { return $this->failUnauthorized('Invalid request', 403); } } + + public function datatablePedidos(){ + + if ($this->request->isAJAX()) { + + $reqData = $this->request->getPost(); + if (!isset($reqData['draw']) || !isset($reqData['columns']) ) { + $errstr = 'No data available in response to this specific request.'; + $response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr); + return $response; + } + $start = $reqData['start'] ?? 0; + $length = $reqData['length'] ?? 5; + $search = $reqData['search']['value']; + $requestedOrder = $reqData['order']['0']['column'] ?? 0; + $order = FacturaModel::SORTABLE_PEDIDOS[$requestedOrder >= 0 ? $requestedOrder : 0]; + $dir = $reqData['order']['0']['dir'] ?? 'asc'; + + $pedido_id = $reqData['pedido_id'] ?? 0; + + $resourceData = $this->model->getResourcePedidos($pedido_id)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject(); + + return $this->respond(Collection::datatable( + $resourceData, + $this->model->getResourcePedidos($pedido_id)->countAllResults(), + $this->model->getResourcePedidos($pedido_id)->countAllResults() + )); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function update($id = null){ + + if ($this->request->isAJAX()) { + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + if ($id == null) : + $data = [ + 'error' => 2, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + endif; + $id = filter_var($id, FILTER_SANITIZE_URL); + $facturaEntity = $this->model->find($id); + + if ($facturaEntity == false) : + $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Factura.factura')), $id]); + $data = [ + 'error' => $message, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + endif; + + if ($this->request->getPost()) : + + $nullIfEmpty = true; // !(phpversion() >= '8.1'); + + $postData = $this->request->getPost(); + + $sanitizedData = $this->sanitized($postData, $nullIfEmpty); + + // JJO + $sanitizedData['user_updated_id'] = auth()->user()->id; + + $noException = true; + if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) : + + if ($this->canValidate()) : + try { + $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData); + } catch (\Exception $e) { + $noException = false; + $this->dealWithException($e); + } + else: + $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Facturas.factura'))]); + $this->session->setFlashdata('formErrors', $this->model->errors()); + + endif; + + $facturaEntity->fill($sanitizedData); + + endif; + if ($noException && $successfulResult) : + $id = $facturaEntity->id ?? $id; + $message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.'; + + $data = [ + 'error' => 0, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + + endif; // $noException && $successfulResult + endif; // ($requestMethod === 'post') + + $data = [ + 'error' => 1, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function menuPedidosPendientes($cliente_id){ + + if ($this->request->isAJAX()) { + $model = model('\App\Models\Pedidos\PedidoLineaModel'); + + $pedidos = []; + try{ + $pedidos = $model->obtenerLineasPedidoSinFacturar($cliente_id); + } + catch(Exception $e){ + + } + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + 'menu' => $pedidos, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function duplicate($factura_id = 0){ + if($this->request->isAJAX()){ + + $factura_origen = $this->model->find($factura_id); + // se quita la key "id" del objeto + unset($factura_origen->id); + $factura_origen->estado = 'borrador'; + $factura_origen->estado_pago = 'pendiente'; + $factura_origen->base = 0; + $factura_origen->total = 0; + $factura_origen->pendiente = 0; + $factura_origen->total_pagos = 0; + $factura_origen->user_created_id = auth()->user()->id; + $factura_origen->user_updated_id = null; + + $this->model->insert($factura_origen); + $id = $this->model->getInsertID(); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + 'id' => $id, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + + }else{ + return $this->failUnauthorized('Invalid request', 403); + } + } + + public function updateTotales($factura_id = 0){ + if($this->request->isAJAX()){ + + $postData = $this->request->getPost(); + + $data = [ + 'base' => $postData['base'] ?? 0, + 'total' => $postData['total'] ?? 0, + 'pendiente' => $postData['pendiente'] ?? 0, + 'total_pagos' => $postData['total_pagos'] ?? 0, + 'user_updated_id' => auth()->user()->id, + 'estado_pago' => (intval($postData['pendiente'] ?? 0)==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 addLineaPedidoImpresion($factura_id){ + + if ($this->request->isAJAX()) { + $model_pedido_linea = model('\App\Models\Pedidos\PedidoLineaModel'); + $model_presupuesto = model('\App\Models\Presupuestos\PresupuestoModel'); + $model_factura_linea = model('\App\Models\Facturas\FacturaLineaModel'); + + try{ + $pedido_linea_id = $this->request->getPost('lineaPedido') ?? 0; + $linea = $model_pedido_linea->find($pedido_linea_id); + + if($linea){ + $presupuesto = $model_presupuesto->find($linea->presupuesto_id); + if($presupuesto){ + // Se añade la linea de factura + $descripcion = $model_presupuesto->generarLineaPedido($presupuesto->id, true, $linea->pedido_id); + $cantidad = intval($presupuesto->tirada) - intval($this->model->getCantidadLineaPedidoFacturada($linea->id)); + $base = $cantidad * floatval($presupuesto->total_precio_unidad); + $total_iva = $base * ($presupuesto->iva_reducido==1 ? 0.04 : 0.21); + // se redondea a dos decimales + $total_iva = round($total_iva, 2); + $total = $base + $total_iva; + + $data = (object)[ + 'factura_id'=>$factura_id, + 'pedido_linea_impresion_id'=>$linea->pedido_id, + 'descripcion'=>$descripcion[0]->concepto, + 'cantidad'=>$cantidad, + 'precio_unidad'=>$presupuesto->total_precio_unidad, + 'iva' => $presupuesto->iva_reducido==1 ? 4 : 21, + 'base' => $base, + 'total_iva' => $total_iva, + 'total' => $total, + 'user_updated_id' => auth()->user()->id, + ]; + + $model_factura_linea->insert($data); + + $id = $model_factura_linea->getInsertID(); + + if($id){ + + $model_factura_linea->addFacturaPedidoLinea($factura_id, $linea->id, $cantidad); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + 'error' => 0, + 'id' => $id, + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + } + } + } + catch(Exception $e){ + + } + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + $data = [ + $csrfTokenName => $newTokenHash + ]; + return $this->respond($data); + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + 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 + ************************************/ + + private function obtenerDatosFormulario(&$factura){ + + if($factura->estado == 'borrador'){ + $serieModel = model('App\Models\Configuracion\SeriesFacturasModel'); + $serie = $serieModel->find($factura->serie_id); + if($serie){ + $factura->numero = str_replace("{numero}", $serie->next, $serie->formato); + } + } + + $clienteModel = model('App\Models\Clientes\ClienteModel'); + $cliente = $clienteModel->find($factura->cliente_id); + $factura->cliente_alias = $cliente->alias; + + $serieModel = model('App\Models\Configuracion\SeriesFacturasModel'); + $serie = $serieModel->find($factura->serie_id); + $factura->serie_nombre = $serie->nombre; + + $formaPagoModel = model('App\Models\Configuracion\FormaPagoModel'); + $factura->formas_pago = $formaPagoModel->getMenuItems(); + + $factura->fecha_factura_at_text = $factura->fecha_factura_at ? date('d/m/Y', strtotime($factura->fecha_factura_at)) : ''; + } + } \ No newline at end of file diff --git a/ci4/app/Controllers/Facturacion/FacturasLineas.php b/ci4/app/Controllers/Facturacion/FacturasLineas.php new file mode 100644 index 00000000..21ae2c0a --- /dev/null +++ b/ci4/app/Controllers/Facturacion/FacturasLineas.php @@ -0,0 +1,228 @@ +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 deleteLinea($factura_linea_id = 0){ + + if (!empty(static::$pluralObjectNameCc) && !empty(static::$singularObjectNameCc)) { + $objName = mb_strtolower(lang(ucfirst(static::$pluralObjectNameCc).'.'.static::$singularObjectNameCc)); + } else { + $objName = lang('Basic.global.record'); + } + + if($factura_linea_id == 0){ + return $this->failNotFound(lang('Basic.global.deleteError', [$objName])); + } + + $facturaLinea = $this->model->find($factura_linea_id); + if($facturaLinea == null){ + return $this->failNotFound(lang('Basic.global.deleteError', [$objName])); + } + + if($facturaLinea->pedido_linea_impresion_id != null){ + $this->model->deleteFacturasLineasPedido($facturaLinea->factura_id, $facturaLinea->pedido_linea_impresion_id, $facturaLinea->cantidad); + } + + if($facturaLinea->pedido_maquetacion_id != null){ + //$this->model->deleteFacturasLineasPedido($facturaLinea->factura_id, $facturaLinea->pedido_maquetacion_id, $facturaLinea->cantidad); + } + + $facturaLinea = $this->model->delete($factura_linea_id); + $message = lang('Basic.global.deleteSuccess', [lang('Basic.global.record')]); + $response = $this->respondDeleted(['id' => $factura_linea_id, 'msg' => $message]); + return $response; + } + + + 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_lineas' ) + ->fields( + Field::inst( 'id' ), + Field::inst( 'base' ), + Field::inst( 'total_iva' ), + Field::inst( 'total' ), + Field::inst( 'cantidad' ) + ->validator('Validate::numeric', array( + 'message' => lang('Facturas.validation.numerico')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'descripcion' ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'precio_unidad' ) + ->getFormatter( 'Format::toDecimalChar')->setFormatter( 'Format::fromDecimalChar') + ->validator('Validate::numeric', array( + "decimal" => ',', + 'message' => lang('Facturas.validation.decimal')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'iva' ) + ->validator('Validate::numeric', array( + 'message' => lang('Facturas.validation.numerico')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'pedido_linea_impresion_id' ) + ->setFormatter(function($val, $data, $opts) { + return $val === '' ? null : $val; + }), + Field::inst( 'factura_id' ), + Field::inst( 'user_updated_id' ), + ) + ->on('preCreate', function ($editor, &$values) { + $totales = $this->generate_totales( + $values['factura_id'], + $values['pedido_linea_impresion_id'], + $values['precio_unidad'], + $values['iva'], + $values['cantidad'], + $values['old_cantidad']); + $editor + ->field('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) { + $totales = $this->generate_totales( + $values['factura_id'], + $values['pedido_linea_impresion_id'], + $values['precio_unidad'], + $values['iva'], + $values['cantidad'], + $values['old_cantidad']); + $editor + ->field('factura_id') + ->setValue($values['factura_id']); + $editor + ->field('pedido_linea_impresion_id') + ->setValue(null); + $editor + ->field('pedido_maquetacion_id') + ->setValue(null); + $editor + ->field('user_updated_id') + ->setValue(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); + } + } + + public function updateTotalesFactura($factura_id = 0){ + if($factura_id == 0){ + return; + } + + $model = model('\App\Models\Facturas\FacturaModel'); + $model->updateTotales($factura_id); + } + + private function generate_totales($factura_id, $pedido_linea_id, $precio_unidad, $iva, $cantidad, $old_cantidad) + { + + // si es una linea que se refiere a pedido + if ($pedido_linea_id != null && $factura_id != null) { + // se actualiza la cantidad de la linea de pedido en la tabla pivote facturas_pedidos_lineas + $this->model->updateFacturaPedidoLinea($factura_id, $pedido_linea_id, $old_cantidad, $cantidad); + } + + // se calcula y se actualiza el subtotal, total_iva y total + // redondeando a 4 decimales el precio_unidad y a dos el resto + $base = round($precio_unidad * $cantidad, 2); + $total_iva = round($base * $iva / 100, 2); + $total = round($base + $total_iva, 2); + $values = []; + $values['base'] = $base; + $values['total_iva'] = $total_iva; + $values['total'] = $total; + + return $values; + } +} + diff --git a/ci4/app/Controllers/Facturacion/FacturasPagos.php b/ci4/app/Controllers/Facturacion/FacturasPagos.php new file mode 100644 index 00000000..a7559933 --- /dev/null +++ b/ci4/app/Controllers/Facturacion/FacturasPagos.php @@ -0,0 +1,142 @@ +request->isAJAX() && $factura_id != null) { + + $reqData = $this->request->getPost(); + if (!isset($reqData['draw']) || !isset($reqData['columns']) ) { + $errstr = 'No data available in response to this specific request.'; + $response = $this->respond(Collection::datatable( [], 0, 0, $errstr ), 400, $errstr); + return $response; + } + $start = $reqData['start'] ?? 0; + $length = $reqData['length'] ?? 5; + $search = $reqData['search']['value']; + $requestedOrder = $reqData['order']['0']['column'] ?? 0; + //$order = FacturaModel::SORTABLE[$requestedOrder >= 0 ? $requestedOrder : 0]; + $dir = $reqData['order']['0']['dir'] ?? 'asc'; + + $resourceData = $this->model->getResource($factura_id)->orderBy(1, $dir)->limit($length, $start)->get()->getResultObject(); + + return $this->respond(Collection::datatable( + $resourceData, + $this->model->getResource($factura_id)->countAllResults(), + $this->model->getResource($factura_id)->countAllResults() + )); + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + + + public function datatable_editor() { + if ($this->request->isAJAX()) { + + include(APPPATH . "ThirdParty/DatatablesEditor/DataTables.php"); + + // Build our Editor instance and process the data coming from _POST + $response = Editor::inst( $db, 'facturas_pagos' ) + ->fields( + Field::inst( 'id' ), + Field::inst( 'forma_pago_id' ), + Field::inst( 'notes' ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'fecha_pago_at' ) + ->validator( Validate::dateFormat( 'Y-m-d H:i:s' ) ) + ->getFormatter( Format::dateSqlToFormat( 'Y-m-d H:i:s' ) ) + ->setFormatter( Format::dateFormatToSql( 'Y-m-d H:i:s' ) ), + Field::inst( 'fecha_vencimiento_at' ) + ->validator( Validate::dateFormat( 'Y-m-d H:i:s' ) ) + ->getFormatter( Format::dateSqlToFormat( 'Y-m-d H:i:s' ) ) + ->setFormatter( Format::dateFormatToSql( 'Y-m-d H:i:s' ) ), + Field::inst( 'total' ) + ->validator('Validate::numeric', array( + 'message' => lang('Facturas.validation.numerico')) + ) + ->validator('Validate::notEmpty', array( + 'message' => lang('Facturas.validation.requerido')) + ), + Field::inst( 'factura_id' ), + Field::inst( 'user_updated_id' ), + ) + ->on('preCreate', function ($editor, &$values) { + /* + $editor + ->field('user_updated_id') + ->setValue(auth()->user()->id); + $editor + ->field('base') + ->setValue($totales['base']); + $editor + ->field('total_iva') + ->setValue($totales['total_iva']); + $editor + ->field('total') + ->setValue($totales['total']); + $editor + ->field('user_updated_id') + ->setValue(auth()->user()->id); + */ + }) + ->on('preEdit', function ($editor, $id, &$values) { + /* + $editor + ->field('factura_id') + ->setValue($values['factura_id']); + $editor + ->field('pedido_linea_impresion_id') + ->setValue(null); + $editor + ->field('pedido_maquetacion_id') + ->setValue(null); + $editor + ->field('user_updated_id') + ->setValue(auth()->user()->id); + $editor + ->field('base') + ->setValue($totales['base']); + $editor + ->field('total_iva') + ->setValue($totales['total_iva']); + $editor + ->field('total') + ->setValue($totales['total']); + */ + }) + ->debug(true) + ->process($_POST) + ->data(); + + $newTokenHash = csrf_hash(); + $csrfTokenName = csrf_token(); + + $response[$csrfTokenName] = $newTokenHash; + + echo json_encode($response); + + } else { + return $this->failUnauthorized('Invalid request', 403); + } + } + +} \ No newline at end of file diff --git a/ci4/app/Controllers/Pedidos/Pedido.php b/ci4/app/Controllers/Pedidos/Pedido.php index 93e41170..bc8254dd 100755 --- a/ci4/app/Controllers/Pedidos/Pedido.php +++ b/ci4/app/Controllers/Pedidos/Pedido.php @@ -258,6 +258,17 @@ class Pedido extends \App\Controllers\BaseResourceController } } + + public function obtenerPedidosForFacturas(){ + if ($this->request->isAJAX()) { + $reqData = $this->request->getPost(); + $start = $reqData['start'] ?? 0; + } + else { + return $this->failUnauthorized('Invalid request', 403); + } + } + public function getlineas(){ if ($this->request->isAJAX()) { diff --git a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php index dd0b609c..aa2cdbdf 100755 --- a/ci4/app/Controllers/Presupuestos/Presupuestocliente.php +++ b/ci4/app/Controllers/Presupuestos/Presupuestocliente.php @@ -192,7 +192,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController $this->viewData['presupuestoEntity'] = $presupuestoEntity; $this->viewData['datosPresupuesto'] = $datosPresupuesto; - $this->viewData['clienteId'] = $clienteId; + $this->viewData['clienteId'] = $presupuestoEntity->cliente_id; // En el caso del edit, se mantiene el clienteId del presupuesto // Si se ha llamado a esta funcion porque se ha duplicado el presupuesto // se actualiza la bbdd para que sólo ejecute algunas funciones una vez @@ -398,7 +398,7 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController 'servicios' => $servicios, ); - $return_data = $this->calcular_presupuesto($datos_presupuesto, 0, true); //TRUE FOR DEBUG + $return_data = $this->calcular_presupuesto($datos_presupuesto, 0, false); //TRUE FOR DEBUG array_merge($return_data, [$csrfTokenName => $newTokenHash]); return $this->respond($return_data); @@ -1449,9 +1449,18 @@ class Presupuestocliente extends \App\Controllers\BaseResourceController } // Servicios - if ($datos_guardas > 0) { - array_push($servicios, 62); // Plegado de guardas + // se comprueba si $datos guardas es un array + if(is_array($datos_guardas)){ + if(count($datos_guardas) > 0){ + array_push($servicios, 62); // Plegado de guardas + } } + else{ + if ($datos_guardas > 0) { + array_push($servicios, 62); // Plegado de guardas + } + } + /* 'retractilado' => 3, 'retractilado5' => 5, diff --git a/ci4/app/Controllers/Profile.php b/ci4/app/Controllers/Profile.php index d18708e8..67449c84 100755 --- a/ci4/app/Controllers/Profile.php +++ b/ci4/app/Controllers/Profile.php @@ -7,91 +7,81 @@ use App\Models\UserModel; class Profile extends BaseController { - private $user_model; - private $id_user; - function __construct() { - $this->user_model = new UserModel(); - $this->id_user = auth()->user()->id; } public function index() { - helper('file'); - helper('form'); - helper('text'); - - $data['title'] = [ - 'module' => lang("App.profile_title"), - 'page' => lang("App.profile_subtitle"), - 'icon' => 'fas fa-user' - ]; $data['breadcrumb'] = [ ['title' => lang("App.menu_dashboard"), 'route' => "/home", 'active' => false], ['title' => lang("App.profile_title"), 'route' => "", 'active' => true] ]; - $data['btn_return'] = [ - 'title' => lang("App.global_come_back"), - 'route' => '/', - 'class' => 'btn btn-dark mr-1', - 'icon' => 'fas fa-angle-left' - ]; + // Get the User Provider (UserModel by default) + $users = auth()->getProvider(); - $data['btn_submit'] = [ - 'title' => lang("App.global_save"), - 'route' => '', - 'class' => 'btn btn-primary mr-1', - 'icon' => 'fas fa-save' - ]; + // Find by the user_id + $data['obj'] = $users->findById(auth()->id()); - $session = session(); - - $data['obj'] = $this->user_model->where('id', $this->id_user)->first(); - - - echo view(getenv('theme.path') . 'form/profile/index', $data); + echo view(getenv('theme.path') . 'form/profile/profileDetails', $data); } public function store() { - $session = session(); helper('form'); $rules = [ 'first_name' => 'required', 'last_name' => 'required', + 'new_pwd' => 'permit_empty|min_length[8]', + 'new_pwd_confirm' => 'required_with[new_pwd]|matches[new_pwd]' ]; + // Definir los mensajes de error personalizados $rules_error = [ 'first_name' => ['required' => lang("App.profile_rules_first_name_r")], 'last_name' => ['required' => lang("App.profile_rules_last_name_r")], + 'new_pwd' => ['min_length' => lang("App.profile_rules_password_m")], + 'new_pwd_confirm' => [ + 'matches' => lang("App.profile_rules_password_confirm_m") + ] ]; - - if ($this->validate($rules ?? [], $rules_error ?? [])) { - if (!empty($this->id_user)) { - $this->user_model->save([ - 'id' => $this->id_user, - 'first_name' => $this->request->getPost('first_name'), - 'last_name' => $this->request->getPost('last_name') - ]); - $session->setFlashdata('sweet', ['success', lang("App.global_alert_save_success")]); - } else { - $session->setFlashdata('sweet', ['error', lang("App.global_alert_save_error")]); - } - } else { - - $session->setFlashdata('error', 'error'); - return $this->index(); + // Validar la entrada + if (!$this->validate($rules, $rules_error)) { + // Si la validación falla, redirigir de vuelta con errores + return redirect()->back()->withInput()->with('errors', $this->validator->getErrors()); } - return redirect()->to('/profile'); + // Obtener los valores de los campos + $firstName = $this->request->getPost('first_name'); + $lastName = $this->request->getPost('last_name'); + $newPwd = $this->request->getPost('new_pwd'); + + $update_data = [ + 'first_name' => $firstName, + 'last_name' => $lastName, + 'password' => $newPwd, + ]; + + if(empty($newPwd)){ + unset($update_data['password']); + } + + // Aquí debes obtener el usuario actual, por ejemplo, desde la sesión + $users = auth()->getProvider(); + $user = $users->findById(auth()->id()); + $user->fill($update_data); + $users->save($user); + + // Redirigir con un mensaje de éxito + return redirect()->back()->with('success', lang('App.profile_updated_successfully')); + } } diff --git a/ci4/app/Entities/Facturas/FacturaEntity.php b/ci4/app/Entities/Facturas/FacturaEntity.php index 8d4e97a5..99f923b5 100644 --- a/ci4/app/Entities/Facturas/FacturaEntity.php +++ b/ci4/app/Entities/Facturas/FacturaEntity.php @@ -8,8 +8,8 @@ class FacturaEntity extends \CodeIgniter\Entity\Entity protected $attributes = [ 'id' => null, 'pedido_id' => null, - 'factura_retificada_id' => null, - 'factura_retificativa_id' => null, + 'factura_rectificada_id' => null, + 'factura_rectificativa_id' => null, 'cliente_id' => null, 'serie_id' => null, 'numero' => null, @@ -33,18 +33,14 @@ class FacturaEntity extends \CodeIgniter\Entity\Entity 'updated_at' => null, 'deleted_at' => null, 'user_created_id' => null, - 'user_update_id' => null, + 'user_updated_id' => null, ]; protected $casts = [ 'id' => 'int', 'pedido_id' => 'int', - 'factura_retificada_id' => 'int', - 'factura_retificativa_id' => 'int', 'cliente_id' => 'int', 'serie_id' => 'int', - 'estado' => 'int', - 'estado_pago' => 'int', 'base' => 'float', 'total' => 'float', 'pendiente' => 'float', diff --git a/ci4/app/Entities/Facturas/FacturaLineaEntity.php b/ci4/app/Entities/Facturas/FacturaLineaEntity.php index f9df393a..7ce467bb 100644 --- a/ci4/app/Entities/Facturas/FacturaLineaEntity.php +++ b/ci4/app/Entities/Facturas/FacturaLineaEntity.php @@ -8,7 +8,7 @@ class FacturaLineaEntity extends \CodeIgniter\Entity\Entity protected $attributes = [ 'id' => null, 'factura_id' => null, - 'pedido_impresion_id' => null, + 'pedido_linea_impresion_id' => null, 'pedido_maquetacion_id' => null, 'descripcion' => null, 'cantidad' => null, @@ -19,14 +19,14 @@ class FacturaLineaEntity extends \CodeIgniter\Entity\Entity 'total' => null, 'data' => null, 'deleted_at' => null, - 'user_update_id' => null, + 'user_updated_id' => null, ]; protected $casts = [ 'id' => 'int', 'factura_id' => 'int', - 'pedido_impresion_id' => 'int', + 'pedido_linea_impresion_id' => 'int', 'pedido_maquetacion_id' => 'int', 'cantidad' => 'float', 'precio_unidad' => 'float', diff --git a/ci4/app/Entities/Facturas/FacturaPagoEntity.php b/ci4/app/Entities/Facturas/FacturaPagoEntity.php index a47ce19a..84f065cb 100644 --- a/ci4/app/Entities/Facturas/FacturaPagoEntity.php +++ b/ci4/app/Entities/Facturas/FacturaPagoEntity.php @@ -14,7 +14,7 @@ class FacturaPagoEntity extends \CodeIgniter\Entity\Entity 'forma_pago_id' => null, 'total' => null, 'deleted_at' => null, - 'user_update_id' => null, + 'user_updated_id' => null, ]; diff --git a/ci4/app/Entities/Usuarios/UserEntity.php b/ci4/app/Entities/Usuarios/UserEntity.php index 0c1d5383..61f750ce 100755 --- a/ci4/app/Entities/Usuarios/UserEntity.php +++ b/ci4/app/Entities/Usuarios/UserEntity.php @@ -24,18 +24,25 @@ class UserEntity extends \CodeIgniter\Entity\Entity "cliente_id" => "int", "active" => "boolean", ]; + /** - * Returns a full name: "first last" + * Get the full name of the user * - * @return string + * If the first name and last name are available, the full name is generated as "{first name} {last name}". + * If the first name or last name is missing, only the available name is used. + * If both the first name and last name are missing, the username is used as the full name. + * + * @return string The full name of the user */ public function getFullName() { - $fullName = - (!empty($this->attributes["first_name"]) ? trim($this->attributes["first_name"]) . " " : "") . - (!empty($this->attributes["last_name"]) ? trim($this->attributes["last_name"]) : ""); - $name = empty($fullName) ? $this->attributes["username"] : $fullName; - return $name; + $firstName = trim($this->attributes["first_name"] ?? ""); + $lastName = trim($this->attributes["last_name"] ?? ""); + $fullName = $firstName . ' ' . $lastName; + $fullName = trim($fullName); // In case first name is empty, this will remove the leading space + + // Use the username attribute if the full name is still empty after trimming + return $fullName ?: $this->attributes["username"]; } /** diff --git a/ci4/app/Entities/Usuarios/UsersEntity.php b/ci4/app/Entities/Usuarios/UsersEntity.php index 7ff93bb7..51da0555 100644 --- a/ci4/app/Entities/Usuarios/UsersEntity.php +++ b/ci4/app/Entities/Usuarios/UsersEntity.php @@ -1,16 +1,30 @@ null, - "last_name" => null + 'first_name' => null, + 'last_name'=> null, + 'cliente_id' => null, + 'comments' => null, ]; protected $casts = [ - + "cliente_id" => "int", ]; + + public function getFullName() + { + $firstName = trim($this->attributes["first_name"] ?? ""); + $lastName = trim($this->attributes["last_name"] ?? ""); + $fullName = $firstName . ' ' . $lastName; + $fullName = trim($fullName); // In case first name is empty, this will remove the leading space + + // Use the username attribute if the full name is still empty after trimming + return $fullName ?: $this->attributes["username"]; + } + + } diff --git a/ci4/app/Language/en/Basic.php b/ci4/app/Language/en/Basic.php index 4b55be18..4863c32d 100755 --- a/ci4/app/Language/en/Basic.php +++ b/ci4/app/Language/en/Basic.php @@ -89,6 +89,7 @@ return [ 'ok' => 'Ok', 'wait' => 'Wait', 'yes' => 'Yes', + 'back' => 'Back', ], diff --git a/ci4/app/Language/en/Facturas.php b/ci4/app/Language/en/Facturas.php index 2645b729..48c60a51 100644 --- a/ci4/app/Language/en/Facturas.php +++ b/ci4/app/Language/en/Facturas.php @@ -1,6 +1,7 @@ 'ID', 'factura' => 'Invoice', 'facturaList' => 'Invoice List', 'facturas' => 'Invoices', @@ -21,6 +22,7 @@ return [ 'serieFacturacion' => 'Billing Series', 'creditoAsegurado' => 'Secured Credit', 'facturaRectificada' => 'Rectified Invoice', + 'facturaRectificativa' => 'Rectifying Invoice', 'razonSocial' => 'Business Name', 'cif' => 'Tax ID', 'direccion' => 'Address', @@ -54,4 +56,29 @@ return [ 'giroDocimiliado' => 'Direct Debit', 'pagare' => 'Promissory Note', 'transferencia' => 'Transfer', + 'datosFactura' => 'Invoice Data', + 'addPedidosImpresion' => 'Add Print Orders', + 'addPedidosMaquetacion' => 'Add Layout Orders', + 'peiddoImpresion' => 'Print Order', + 'peiddoMaquetacion' => 'Layout Order', + 'nuevaLinea' => 'New Line', + 'validarFactura' => 'Validate Invoice', + 'borrarFactura' => 'Delete Invoice', + 'imprimirFactura' => 'Print', + 'pagos' => 'Payments', + 'notas' => 'Notes', + 'fechaVencimiento' => 'Due Date', + "fechaCobro" => "Collection Date", + "cantidad" => "Quantity", + "addPago" => "Add Payment", + "facturaPagada" => "Rectifying Invoice already paid", + + 'errors' => [ + 'requiredFields' => 'Fields marked with * are required', + ], + 'validation' => [ + 'numerico' => 'Must be numeric', + 'requerido' => 'Required', + 'decimal' => 'Must be decimal', + ], ]; \ No newline at end of file diff --git a/ci4/app/Language/en/Pedidos.php b/ci4/app/Language/en/Pedidos.php index 0e58640a..69a30669 100644 --- a/ci4/app/Language/en/Pedidos.php +++ b/ci4/app/Language/en/Pedidos.php @@ -52,7 +52,9 @@ return [ 'dosCaras' => '2 sides', 'lineasTemplates' =>[ - 'libro' => "[BUDGET %s] Printing of %s copies of %s pages.\nTitle: %s. Author: %s. ISBN: %s.Size: %smm.\n", + 'presupuesto' => '[BUDGET %s] ', + 'pedido' => '[ORDER %s] ', + 'libro' => "Printing of %s copies of %s pages.\nTitle: %s. Author: %s. ISBN: %s.Size: %smm.\n", 'libro_linea_interior' => "%s black pages on %s paper of %s grams", 'libro_linea_cubierta' => "\nCover printed on %s on %s paper of %s grams", 'libro_linea_sobrecubierta' => "\nDust jacket on %s paper of %s grams", diff --git a/ci4/app/Language/es/App.php b/ci4/app/Language/es/App.php index 5e607b58..e03fa10d 100755 --- a/ci4/app/Language/es/App.php +++ b/ci4/app/Language/es/App.php @@ -137,9 +137,9 @@ return [ "profile_mobile" => "Teléfono Móvil", "profile_mobile_ph" => "Escriba su número de celular", "profile_password" => "Cambiar Contraseña", - "profile_password_ph" => "Escribe tu contraseña", - "profile_confirm_password" => "Confirmar seña", - "profile_confirm_password_ph" => "Confirma tu contraseña anterior", + "profile_password_ph" => "Escribe nueva contraseña para cambiarla", + "profile_confirm_password" => "Confirmar contraseña", + "profile_confirm_password_ph" => "Confirma tu contraseña anterior para cambiarla", "profile_date_birth" => "Fecha de Nacimiento", "profile_date_birth_ph" => "Seleccionar fecha de nacimiento", "profile_address" => "Dirección", diff --git a/ci4/app/Language/es/Basic.php b/ci4/app/Language/es/Basic.php index 01e547a1..bb333f54 100755 --- a/ci4/app/Language/es/Basic.php +++ b/ci4/app/Language/es/Basic.php @@ -89,6 +89,8 @@ return [ 'ok' => 'Ok', 'wait' => 'Espere', 'yes' => 'Si', + 'no' => 'No', + 'back' => 'Volver', ], diff --git a/ci4/app/Language/es/Facturas.php b/ci4/app/Language/es/Facturas.php index 39bc6aa9..90e6962f 100644 --- a/ci4/app/Language/es/Facturas.php +++ b/ci4/app/Language/es/Facturas.php @@ -1,6 +1,7 @@ 'ID', 'factura' => 'Factura', 'facturaList' => 'Listado de Facturas', 'facturas' => 'Facturas', @@ -21,6 +22,7 @@ return [ 'serieFacturacion' => 'Serie facturación', 'creditoAsegurado' => 'Crédito asegurado', 'facturaRectificada' => 'Factura rectificada', + 'facturaRectificativa' => 'Factura rectificativa', 'razonSocial' => 'Razón Social', 'cif' => 'CIF', 'direccion' => 'Dirección', @@ -54,4 +56,30 @@ return [ 'giroDomiciliado' => 'Giro domiciliado', 'pagare' => 'Pagaré', 'transferencia' => 'Transferencia', + 'datosFactura' => 'Datos Factura', + 'addPedidosImpresion' => 'Añadir Pedidos Impresión', + 'addPedidosMaquetacion' => 'Añadir Pedidos Maquetación', + 'pedidoImpresion' => 'Pedido Impresión', + 'pedidoMaquetacion' => 'Pedido Maquetación', + 'nuevaLinea' => 'Nueva Línea', + 'validarFactura' => 'Validar Factura', + 'borrarFactura' => 'Borrar Factura', + 'imprimirFactura' => 'Imprimir', + 'pagos' => 'Pagos', + 'notas' => 'Notas', + "fechaVencimiento" => "Fecha Vencimiento", + "fechaCobro" => "Fecha Cobro", + "cantidad" => "Cantidad", + "addPago" => "Añadir Pago", + "facturaPagada" => "Factura rectificativa ya abonada", + + 'errors' => [ + 'requiredFields' => 'Los campos marcados con * son obligatorios', + ], + 'validation' => [ + "requerido" => "El campo es obligatorio.", + "numerico" => "El campo debe ser numérico.", + "decimal" => "El campo debe ser decimal.", + ] + ]; \ No newline at end of file diff --git a/ci4/app/Language/es/Pedidos.php b/ci4/app/Language/es/Pedidos.php index 5e790760..f8556058 100644 --- a/ci4/app/Language/es/Pedidos.php +++ b/ci4/app/Language/es/Pedidos.php @@ -51,7 +51,9 @@ return [ 'dosCaras' => '2 caras', 'lineasTemplates' =>[ - 'libro' => "[PRESUPUESTO %s] Impresión de %s ejemplares de %s páginas.\nTítulo: %s. Autor: %s. ISBN: %s.Tamaño: %smm.\n", + 'presupuesto' => '[PRESUPUESTO %s] ', + 'pedido' => '[PEDIDO %s] ', + 'libro' => "Impresión de %s ejemplares de %s páginas.\nTítulo: %s. Autor: %s. ISBN: %s.Tamaño: %smm.\n", 'libro_linea_interior' => "%s páginas en negro sobre papel %s de %s gramos", 'libro_linea_cubierta' => "\nCubierta impresa a %s sobre papel %s de %s gramos", 'libro_linea_sobrecubierta' => "\nSobrecubierta sobre papel %s de %s gramos", diff --git a/ci4/app/Language/es/Presupuestos.php b/ci4/app/Language/es/Presupuestos.php index 5fc672eb..e61122b3 100755 --- a/ci4/app/Language/es/Presupuestos.php +++ b/ci4/app/Language/es/Presupuestos.php @@ -210,6 +210,8 @@ return [ 'confirmar' => 'Confirmar presupuesto', 'confirmado' => 'Presupuesto confirmado', + 'totalAceptado' => 'Total aceptado', + // Preview 'preview' => 'Previsualización de configuraciones', 'preview-conf-bn' => 'Configuración Blanco y Negro', diff --git a/ci4/app/Language/es/Users.php b/ci4/app/Language/es/Users.php index 3417f937..98e0c86f 100755 --- a/ci4/app/Language/es/Users.php +++ b/ci4/app/Language/es/Users.php @@ -153,18 +153,6 @@ return [ ], - 'tfa_code' => [ - 'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.', - 'required' => 'El campo {field} es obligatorio.', - - ], - - 'tfa_secret' => [ - 'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.', - 'required' => 'El campo {field} es obligatorio.', - - ], - 'email' => [ 'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.', 'required' => 'El campo {field} es obligatorio.', diff --git a/ci4/app/Models/Clientes/ClienteModel.php b/ci4/app/Models/Clientes/ClienteModel.php index f6e09af2..741a736a 100755 --- a/ci4/app/Models/Clientes/ClienteModel.php +++ b/ci4/app/Models/Clientes/ClienteModel.php @@ -315,4 +315,21 @@ class ClienteModel extends \App\Models\BaseModel public function creditoDisponible($cliente_id){ return true; } + + public function getClienteDataFacturas($cliente_id){ + $builder = $this->db + ->table($this->table . " t1") + ->select( + " + t1.nombre AS cliente_nombre, t1.direccion AS cliente_address, t1.cif AS cliente_cif, + t2.nombre AS cliente_pais, t1.cp AS cliente_cp, t1.ciudad AS cliente_ciudad, + t3.nombre AS cliente_provincia, t1.credito_asegurado AS creditoAsegurado" + ) + ->where("t1.is_deleted", 0) + ->where("t1.id", $cliente_id); + $builder->join("lg_paises t2", "t1.pais_id = t2.id", "left"); + $builder->join("lg_provincias t3", "t1.provincia_id = t3.id", "left"); + + return $builder->get()->getResultArray(); + } } diff --git a/ci4/app/Models/Configuracion/FormaPagoModel.php b/ci4/app/Models/Configuracion/FormaPagoModel.php index 69833688..d22a1bd5 100755 --- a/ci4/app/Models/Configuracion/FormaPagoModel.php +++ b/ci4/app/Models/Configuracion/FormaPagoModel.php @@ -3,7 +3,7 @@ namespace App\Models\Configuracion; class FormaPagoModel extends \App\Models\BaseModel { - protected $table = "lg_formas_pago"; + protected $table = "formas_pago"; /** * Whether primary key uses auto increment. @@ -38,6 +38,18 @@ class FormaPagoModel extends \App\Models\BaseModel ], ]; + public function getMenuItems(){ + $items = $this->findAll(); + $menuItems = []; + foreach ($items as $item) { + $menuItems[] = [ + "value" => $item->id, + "label" => $item->nombre, + ]; + } + return $menuItems; + } + /** * Get resource data. * diff --git a/ci4/app/Models/Configuracion/SeriesFacturasModel.php b/ci4/app/Models/Configuracion/SeriesFacturasModel.php index 0999b0a4..701ddf05 100644 --- a/ci4/app/Models/Configuracion/SeriesFacturasModel.php +++ b/ci4/app/Models/Configuracion/SeriesFacturasModel.php @@ -91,4 +91,36 @@ class SeriesFacturasModel extends \App\Models\BaseModel ->orLike("t1.grupo", $search) ->groupEnd(); } + + public function getMenuItemsFacturas(){ + + $resultSorting = $this->getPrimaryKeyName(); + + $id = 'id AS id'; + $text = 'nombre AS text'; + + $queryBuilder = $this->db->table($this->table); + $queryBuilder->select([$id, $text]); + $queryBuilder->where('tipo', 'facturacion'); + $queryBuilder->where('grupo', '1'); + $queryBuilder->orderBy($resultSorting); + $result = $queryBuilder->get()->getResult(); + + return $result; + } + + public function getSerieNumerada($id) + { + $number = $this->db->table($this->table) + ->select("next, formato") + ->where("id", $id) + ->get()->getFirstRow(); + + $this->db->table($this->table) + ->where("id", $id) + ->set("next", $number->next + 1, false) + ->update(); + + return str_replace("{number}", $number->next, $number->formato); + } } diff --git a/ci4/app/Models/Facturas/FacturaLineaModel.php b/ci4/app/Models/Facturas/FacturaLineaModel.php index f53cf805..757f4bad 100644 --- a/ci4/app/Models/Facturas/FacturaLineaModel.php +++ b/ci4/app/Models/Facturas/FacturaLineaModel.php @@ -10,7 +10,7 @@ class FacturaLineaModel extends \App\Models\BaseModel { // Lista de columnas basada en los campos de la tabla, para asignación masiva protected $allowedFields = [ 'factura_id', - 'pedido_impresion_id', + 'pedido_linea_impresion_id', 'pedido_maquetacion_id', 'descripcion', 'cantidad', @@ -21,7 +21,7 @@ class FacturaLineaModel extends \App\Models\BaseModel { 'total', 'data', 'deleted_at', - 'user_update_id' + 'user_updated_id' ]; protected $returnType = "App\Entities\Facturas\FacturaLineaEntity"; @@ -30,4 +30,68 @@ class FacturaLineaModel extends \App\Models\BaseModel { protected $useSoftDeletes = true; public static $labelField = "id"; + + public function getResource($factura_id) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.factura_id AS factura_id, + t1.pedido_linea_impresion_id AS pedido_linea_impresion_id, t1.pedido_maquetacion_id AS pedido_maquetacion_id, + t1.descripcion AS descripcion, t1.cantidad as cantidad, t1.precio_unidad AS precio_unidad, t1.iva AS iva, + t1.base AS base, t1.total_iva AS total_iva, t1.total AS total, t1.data AS data, t2.pedido_id AS pedido_id, + t3.total_aceptado AS total_aceptado" + ) + ->join("pedidos_linea t2", "t2.id = t1.pedido_linea_impresion_id", "left") + ->join("presupuestos t3", "t3.id = t2.presupuesto_id", "left") + ->where("t1.factura_id", $factura_id) + ->where("t1.deleted_at", null); + + return $builder; + } + + public function addFacturaPedidoLinea($factura_id, $pedido_linea_id, $cantidad) + { + $data = [ + "factura_id" => $factura_id, + "pedido_linea_id" => $pedido_linea_id, + "cantidad" => $cantidad + ]; + + return $this->db->table("facturas_pedidos_lineas")->insert($data); + } + + 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(); + } + + public function updateFacturaPedidoLinea($factura_id, $pedido_linea_id, $cantidad, $cantidad_new) + { + // Obtener la ID del registro que queremos actualizar + $record = $this->db->table("facturas_pedidos_lineas") + ->select('id') + ->where("factura_id", $factura_id) + ->where("pedido_linea_id", $pedido_linea_id) + ->where("cantidad", $cantidad) + ->limit(1) + ->get() + ->getRow(); + + // Si existe el registro + if ($record) { + $data = [ + "cantidad" => $cantidad_new + ]; + + // Actualizar el registro especificado por su ID + $this->db->table("facturas_pedidos_lineas") + ->where("id", $record->id) + ->update($data); + } + } } \ No newline at end of file diff --git a/ci4/app/Models/Facturas/FacturaModel.php b/ci4/app/Models/Facturas/FacturaModel.php index 94895a80..ccdf7f43 100644 --- a/ci4/app/Models/Facturas/FacturaModel.php +++ b/ci4/app/Models/Facturas/FacturaModel.php @@ -23,12 +23,20 @@ class FacturaModel extends \App\Models\BaseModel { 11 => "DAFEDIFF(days, NOW(), t3.fecha_vencimiento_at)", ]; + const SORTABLE_PEDIDOS = [ + 1 => "t1.numero", + 2 => "t2.nombre", + 3 => "t1.estado", + 4 => "t1.fecha_factura_at", + 5 => "t1.total", + ]; + // Lista de columnas basada en los campos de la tabla, para asignación masiva protected $allowedFields = [ 'pedido_id', - 'factura_retificada_id', - 'factura_retificativa_id', - 'customer_id', + 'factura_rectificada_id', + 'factura_rectificativa_id', + 'cliente_id', 'serie_id', 'numero', 'estado', @@ -40,18 +48,18 @@ class FacturaModel extends \App\Models\BaseModel { 'pendiente', 'total_pagos', 'creditoAsegurado', - 'customer_nombre', - 'customer_address', - 'customer_cif', - 'customer_pais', - 'customer_cp', - 'customer_ciudad', - 'customer_provincia', + 'cliente_nombre', + 'cliente_address', + 'cliente_cif', + 'cliente_pais', + 'cliente_cp', + 'cliente_ciudad', + 'cliente_provincia', 'created_at', 'updated_at', 'deleted_at', 'user_created_id', - 'user_update_id' + 'user_updated_id' ]; protected $returnType = "App\Entities\Facturas\FacturaEntity"; @@ -69,16 +77,20 @@ class FacturaModel extends \App\Models\BaseModel { $builder = $this->db ->table($this->table . " t1") ->select( - "t1.id AS id, t1.numero AS numero, t1.fecha_factura_at 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, t1.creditoAsegurado AS creditoAsegurado, t1.estado AS estado, t1.estado_pago AS estado_pago, - t4.nombre AS forma_pago, t3.fecha_vencimiento_at AS venciemento" + GROUP_CONCAT(DISTINCT t4.nombre ORDER BY t4.nombre ASC SEPARATOR ', ') AS forma_pago, + DATE_FORMAT(MIN(CASE WHEN t3.fecha_vencimiento_at != '0000-00-00 00:00:00' THEN t3.fecha_vencimiento_at ELSE NULL END), '%d/%m/%Y') AS vencimiento, + t2.vencimiento AS dias_vencimiento" ); $builder->join("clientes t2", "t2.id = t1.cliente_id", "left"); $builder->join("facturas_pagos t3", "t3.factura_id = t1.id", "left"); $builder->join("formas_pago t4", "t3.forma_pago_id = t4.id", "left"); + $builder->where("t1.deleted_at IS NULL"); + $builder->groupBy("t1.id"); // Agrupa por id de la factura return empty($search) ? $builder @@ -88,4 +100,48 @@ class FacturaModel extends \App\Models\BaseModel { ->orLike("t1.id", $search) ->groupEnd(); } + + + public function getResourcePedidos($pedido_id) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.numero AS numero, t2.nombre AS serie, t1.estado AS estado, + DATE_FORMAT(t1.fecha_factura_at, '%d/%m/%Y') AS fecha_factura_at, t1.total AS total" + ); + + $builder->join("series t2", "t2.id = t1.serie_id", "left"); + $builder->join("facturas_lineas t3", "t1.id = t3.factura_id", "left"); + $builder->join("facturas_pedidos_lineas t4", "t1.id = t4.factura_id", "left"); + $builder->join("pedidos_linea t5", "t4.pedido_linea_id = t5.id", "left"); + $builder->join("pedidos t6", "t5.pedido_id = t6.id", "left"); + + $builder->where("t1.deleted_at IS NULL"); + $builder->where("t6.id", $pedido_id); + + $builder->groupBy("t1.id"); // Agrupa por id de la factura + + return $builder; + } + + public function getCantidadLineaPedidoFacturada($linea_pedido_id) + { + $builder = $this->db + ->table("facturas_pedidos_lineas t1") + ->select("SUM(t1.cantidad) AS cantidad") + ->where("t1.pedido_linea_id", $linea_pedido_id); + + return $builder->get()->getRow()->cantidad; + } + + public function deleteFacturasLineasPedido($factura_id, $pedido_linea_id, $cantidad) + { + $this->db->table("facturas_pedidos_lineas") + ->where("factura_id", $factura_id) + ->where("pedido_linea_id", $pedido_linea_id) + ->where("cantidad", $cantidad) + ->delete(); + } + } \ No newline at end of file diff --git a/ci4/app/Models/Facturas/FacturaPagoModel.php b/ci4/app/Models/Facturas/FacturaPagoModel.php index 1a17f9fb..82e06cdb 100644 --- a/ci4/app/Models/Facturas/FacturaPagoModel.php +++ b/ci4/app/Models/Facturas/FacturaPagoModel.php @@ -14,7 +14,7 @@ class FacturaPagoModel extends \App\Models\BaseModel { 'forma_pago_id', 'total', 'deleted_at', - 'user_update_id' + 'user_updated_id' ]; protected $returnType = "App\Entities\Facturas\FacturaPagoEntity"; @@ -23,4 +23,20 @@ class FacturaPagoModel extends \App\Models\BaseModel { protected $useSoftDeletes = true; public static $labelField = "id"; + + public function getResource($factura_id) + { + $builder = $this->db + ->table($this->table . " t1") + ->select( + "t1.id AS id, t1.factura_id AS factura_id, + t1.notes AS notes, t1.fecha_pago_at AS fecha_pago_at, t1.fecha_vencimiento_at AS fecha_vencimiento_at, + t1.forma_pago_id AS forma_pago_id, t2.nombre as forma_pago, t1.total AS total" + ) + ->join("formas_pago t2", "t2.id = t1.forma_pago_id", "left") + ->where("t1.factura_id", $factura_id) + ->where("t1.deleted_at", null); + + return $builder; + } } \ No newline at end of file diff --git a/ci4/app/Models/Pedidos/PedidoLineaModel.php b/ci4/app/Models/Pedidos/PedidoLineaModel.php index 13308f06..d7eb4699 100644 --- a/ci4/app/Models/Pedidos/PedidoLineaModel.php +++ b/ci4/app/Models/Pedidos/PedidoLineaModel.php @@ -76,4 +76,41 @@ class PedidoLineaModel extends \App\Models\BaseModel ->orLike("t1.id", $search) ->groupEnd(); } + + + public function obtenerLineasPedidoSinFacturar($cliente_id) { + $resultaArray = []; + + $subquery = $this->db + ->table('facturas_pedidos_lineas') + ->select('pedido_linea_id, SUM(cantidad) AS total_cantidad') + ->groupBy('pedido_linea_id') + ->getCompiledSelect(); + + $builder = $this->db + ->table($this->table . " t1") + ->select("t1.id AS id, t1.pedido_id AS pedido_id, t3.titulo AS titulo, t4.codigo AS tipo_impresion") + ->join("pedidos t2", "t2.id = t1.pedido_id", "left") + ->join("presupuestos t3", "t3.id = t1.presupuesto_id", "left") + ->join("tipos_presupuestos t4", "t4.id = t3.tipo_impresion_id", "left") + ->join("($subquery) fpl", "fpl.pedido_linea_id = t1.id", "left") + ->where("t3.cliente_id", $cliente_id) + ->where("t2.estado", "finalizado") + ->where("(t3.tirada > IFNULL(fpl.total_cantidad, 0))"); + + // Ejecutar la consulta y devolver resultados + $query = $builder->get(); + $data = $query->getResult(); + + foreach($data as $register) { + $item = (object)[ + 'id' => $register->id, + 'text' => '['. lang('Pedidos.pedido') . ' ' . $register->pedido_id . '] ' . $register->titulo . ' - ' . lang('Presupuestos.' . $register->tipo_impresion), + ]; + array_push($resultaArray, $item); + } + + return $resultaArray; + } + } \ No newline at end of file diff --git a/ci4/app/Models/Presupuestos/PresupuestoModel.php b/ci4/app/Models/Presupuestos/PresupuestoModel.php index b9e48761..dc8c3ad3 100755 --- a/ci4/app/Models/Presupuestos/PresupuestoModel.php +++ b/ci4/app/Models/Presupuestos/PresupuestoModel.php @@ -142,7 +142,7 @@ class PresupuestoModel extends \App\Models\BaseModel ], "titulo" => [ "label" => "Presupuestos.titulo", - "rules" => "trim|required|max_length[30]", + "rules" => "trim|required|max_length[300]", ], "inc_rei" => [ "label" => "Presupuestos.incRei", @@ -538,7 +538,7 @@ class PresupuestoModel extends \App\Models\BaseModel return $json; } - public function generarLineaPedido($presupuesto_id) + public function generarLineaPedido($presupuesto_id, $forFactura = false, $pedido_id = 0) { $builder = $this->db ->table($this->table . " t1") @@ -565,13 +565,18 @@ class PresupuestoModel extends \App\Models\BaseModel $presupuesto = $presupuesto[0]; // Libro - if($presupuesto->tipo < 10){ + if($presupuesto->tipo < 10 || $presupuesto->tipo==20 || $presupuesto->tipo==21){ if($presupuesto->papel_formato_personalizado == 1){ $presupuesto->tamanio= $presupuesto->papel_formato_ancho . "x" . $presupuesto->papel_formato_alto; } - $presupuesto->concepto = sprintf(lang('Pedidos.lineasTemplates.libro'), - $presupuesto->numero, + if($forFactura){ + $presupuesto->concepto = sprintf(lang('Pedidos.lineasTemplates.pedido'), $pedido_id); + } + else{ + $presupuesto->concepto = sprintf(lang('Pedidos.lineasTemplates.presupuesto'), $presupuesto->numero); + } + $presupuesto->concepto .= sprintf(lang('Pedidos.lineasTemplates.libro'), $presupuesto->unidades, $presupuesto->paginas, $presupuesto->titulo, diff --git a/ci4/app/Models/UserModel.php b/ci4/app/Models/UserModel.php index 934604ff..ccc79a9c 100644 --- a/ci4/app/Models/UserModel.php +++ b/ci4/app/Models/UserModel.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Models; +use App\Entities\Usuarios\UsersEntity; use CodeIgniter\Shield\Models\UserModel as ShieldUserModel; class UserModel extends ShieldUserModel @@ -17,26 +18,51 @@ class UserModel extends ShieldUserModel 'first_name', // Añadido 'last_name', // Añadido 'cliente_id', // Añadido + 'comments', // Añadido ]; } + protected $returnType = UsersEntity::class; + protected $useSoftDeletes = true; protected $useTimestamps = true; protected $createdField = 'created_at'; protected $updatedField = 'updated_at'; - protected $deletedField = 'deleted_at'; + protected $deletedField = 'deleted_at'; + - protected $validationRules = [ - "username" => [ - "label" => "correo duplicado", - "rules" => "is_unique[users.username]", - ] + "first_name" => "required|trim|max_length[150]", + "last_name" => "required|trim|max_length[150]", + 'new_pwd' => 'permit_empty|min_length[8]', + 'new_pwd_confirm' => 'permit_empty|required_with[new_pwd]|matches[new_pwd]', + "comments" => "permit_empty|trim|max_length[512]" + ]; + + protected $validationMessages = [ + 'first_name' => [ + "max_length" => "Users.validation.first_name.max_length", + "required" => "Users.validation.first_name.required" + ], + 'last_name' => [ + "max_length" => "Users.validation.last_name.max_length", + "required" => "Users.validation.last_name.required" + ], + 'new_pwd' => [ + 'min_length' => "App.profile_rules_password_m" + ], + 'new_pwd_confirm' => [ + 'matches' => "App.profile_rules_password_confirm_m" + ], + 'comments' => [ + "max_length" => "Users.validation.last_name.max_length", + ], ]; - public function getComerciales(){ - + public function getComerciales() + { + $builder = $this->db ->table("users" . " t1") ->select( @@ -51,17 +77,5 @@ class UserModel extends ShieldUserModel } - public function getUsersList(){ - $builder = $this->db - ->table("users" . " t1") - ->select( - "t1.id AS id, t1.first_name AS first_name, t1.last_name AS last_name, t1.last_active AS last_active, t2.group AS group" - ); - $builder->where('t1.deleted_at', null); - $builder->join("auth_groups_users t2", "t1.id = t2.user_id", "left"); - - return $builder->get()->getResult(); - - } } diff --git a/ci4/app/Views/themes/_commonPartialsBs/_modalConfirmDialog.php b/ci4/app/Views/themes/_commonPartialsBs/_modalConfirmDialog.php index e2b6d8c3..37339425 100755 --- a/ci4/app/Views/themes/_commonPartialsBs/_modalConfirmDialog.php +++ b/ci4/app/Views/themes/_commonPartialsBs/_modalConfirmDialog.php @@ -26,20 +26,34 @@ function asyncConfirmDialog(title, msg, yesCallbackFn, noCallbackFn) { - var $confirmDialog = $("#modalConfirmYesNo"); - $confirmDialog.modal('show'); - $("#labelTitleConfirmDialog").html(title); - $("#labelMsgConfirmDialog").html(msg); - $("#btnYesConfirmDialog").off('click').click(function () { - yesCallbackFn(); - $confirmDialog.modal("hide"); - }); - $("#btnNoConfirmDialog").off('click').click(function () { - noCallbackFn(); - $confirmDialog.modal("hide"); - }); - } + var $confirmDialog = $("#modalConfirmYesNo"); + $confirmDialog.modal('show'); + $("#labelTitleConfirmDialog").html(title); + $("#labelMsgConfirmDialog").html(msg); + $("#btnYesConfirmDialog").off('click').click(function () { + yesCallbackFn(); + $confirmDialog.modal("hide"); + }); + $("#btnNoConfirmDialog").off('click').click(function () { + noCallbackFn(); + $confirmDialog.modal("hide"); + }); +} +function asyncConfirmDialogWithParams(title, msg, yesCallbackFn, noCallbackFn, params) { + var $confirmDialog = $("#modalConfirmYesNo"); + $confirmDialog.modal('show'); + $("#labelTitleConfirmDialog").html(title); + $("#labelMsgConfirmDialog").html(msg); + $("#btnYesConfirmDialog").off('click').click(function () { + yesCallbackFn(params); + $confirmDialog.modal("hide"); + }); + $("#btnNoConfirmDialog").off('click').click(function () { + noCallbackFn(params); + $confirmDialog.modal("hide"); + }); +} endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php new file mode 100644 index 00000000..1b616980 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/_addPedidosItems.php @@ -0,0 +1,138 @@ +
+
+
+ +

+ +

+ +
+
+
+
+ +
+ +
+ +
+
+ +
+
+
+
+ + +
+
+ +

+ +

+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+
+
+ +section('additionalInlineJs') ?> + +$('#pedidoImpresion').select2({ + placeholder: "", + allowClear: true, + ajax: { + url: 'cliente_id) ?>', + type: 'post', + dataType: 'json', + + data: function (params) { + return { + id: 'id', + text: 'nombre', + searchTerm: params.term, + : v + }; + }, + delay: 60, + processResults: function (response) { + + yeniden(response.); + + return { + results: response.menu + }; + }, + + cache: true + } +}); + +$('#addNewPedidoImpresion').on('click', function(){ + var lineaPedido = $('#pedidoImpresion').val(); + if(lineaPedido == null) { + return; + } + $.ajax({ + url: 'id) ?>', + type: 'post', + data: { + lineaPedido: lineaPedido, + : v + }, + success: function(response) { + yeniden(response.); + + // se ajustan el ancho de las columnas + $('#tableOfLineasFactura').DataTable().columns.adjust().draw(); + $('#pedidoImpresion').val(null).trigger('change'); + // Se actualiza la tabla de lineas de factura + tableLineas.clearPipeline(); + tableLineas.draw(); + } + }); +}); + + + +$('#pedidoMaquetacion').select2({ + placeholder: "", + allowClear: true, + width: '100%' +}); + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php new file mode 100644 index 00000000..4bba5e7f --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/_facturaCabeceraItems.php @@ -0,0 +1,390 @@ +
+ +
+

+ +

+ +
+
+ +
+

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

+
+
+ +
+ estado === 'borrador') : ?> +
+ + +
+ +
+ + +
+ +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + estado != 'borrador')?'disabled ':''?> type="text" value="" tabindex="4" id="fecha_factura_at" name="fecha_factura_at" tabindex="1" maxLength="11" class="form-control update-cabecera" value="fecha_factura_at) ?>" > +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
serie_id == 7 || $facturaEntity->serie_id == 9 || $facturaEntity->factura_rectificada_id != null) ? "":"style='display:none;'" ?> class="col-md-12 col-lg-2 px-4 factura-R"> +
+ + estado!='borrador')? "disabled":"" ?> id="facturaR" name="factura_rectificada_id != null) ? 'factura_rectificada_id' : 'factura_rectificativa_id' ?>" tabindex="" maxLength="25" class="form-control update-cabecera factura-R" + + factura_rectificada_id == null && $facturaEntity->factura_rectificativa_id == null): ?> + value="" + + value="factura_rectificada_id != null) ? old('factura_rectificada_id', $facturaEntity->factura_rectificada_id): old('factura_rectificativa_id', $facturaEntity->factura_rectificativa_id)?>" + + > +
+
+ +
px-4"> +
+ + estado != 'borrador')?'disabled ':''?> id="cliente_nombre" name="cliente_nombre" tabindex="6" class="form-control update-cabecera" value="cliente_nombre) ?>"> +
+
+ +
+
+ + estado != 'borrador')?'disabled ':''?> id="cliente_cif" name="cliente_cif" tabindex="7" class="form-control update-cabecera" value="cliente_cif) ?>"> +
+
+ +
+
+ + estado != 'borrador')?'disabled ':''?> id="cliente_pais" name="cliente_pais" tabindex="8" class="form-control update-cabecera" value="cliente_pais) ?>"> +
+
+ +
+ +
+ +
+
+ + estado != 'borrador')?'disabled ':''?> id="cliente_direccion" name="cliente_address" tabindex="6" class="form-control update-cabecera" value="cliente_address) ?>"> +
+
+ +
+
+ + estado != 'borrador')?'disabled ':''?> id="cliente_cp" name="cliente_cp" tabindex="7" class="form-control update-cabecera" value="cliente_cp) ?>"> +
+
+ +
+
+ + estado != 'borrador')?'disabled ':''?> id="cliente_ciudad" name="cliente_ciudad" tabindex="8" class="form-control update-cabecera" value="cliente_ciudad) ?>"> +
+
+ +
+
+ + estado != 'borrador')?'disabled ':''?> id="cliente_provincia" name="cliente_provincia" tabindex="8" class="form-control update-cabecera" value="cliente_provincia) ?>"> +
+
+ +
+ +
+ +
+
+ + estado === 'validada' && (auth()->user()->inGroup('beta') || auth()->user()->inGroup('admin'))) : ?> + + + + + + + +
+
+ +
+ +
+
+
+
+ + +section('additionalInlineJs') ?> + +$("#fecha_factura_at").flatpickr({ + defaultDate: fecha_factura_at_text ? "'".$facturaEntity->fecha_factura_at_text."'" : 'null' ?>, + dateFormat: "d/m/Y", + locale: { + firstDayOfWeek: 1, + weekdays: { + shorthand: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'], + longhand: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'], + }, + months: { + shorthand: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Оct', 'Nov', 'Dic'], + longhand: ['Enero', 'Febreo', 'Мarzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'], + }, + }, + onChange: function(selectedDates, dateStr, instance) { + estado == 'borrador'): ?> + updateDate('fecha_entrega_at', dateStr); + + } +}); + + +function updateDate(elementId, dateStr) { + var id = id ?>; + + data = { + : v, + }; + var parts = dateStr.split('/'); + var newFormat = parts[2] + '-' + parts[1] + '-' + parts[0]; // Asume dateStr en formato d/m/Y. + + data[elementId] = newFormat; + + var url = ''; + url = url.replace(':id', id ); + + $.ajax({ + url: url, + type: 'POST', + data: data, + success: function(response){ + + if('error' in response){ + + } + } + }); +} + +$('#serie_id').select2({ + allowClear: false, + minimumResultsForSearch: -1, + ajax: { + url: '', + type: 'post', + dataType: 'json', + + data: function(params) { + return { + id: 'id', + text: 'nombre', + searchTerm: params.term, + : v + }; + }, + delay: 60, + processResults: function(response) { + yeniden(response.); + return { + results: response.menu + }; + }, + cache: true + } +}); + +$('#cliente_id').select2({ + allowClear: false, + ajax: { + url: '', + type: 'post', + dataType: 'json', + + data: function(params) { + return { + id: 'id', + text: 'alias', + searchTerm: params.term, + : v + }; + }, + delay: 60, + processResults: function(response) { + yeniden(response.); + return { + results: response.menu + }; + }, + cache: true + } +}); + + +$('#editarValidada').on('click', function(){ + + $('.update-cabecera').prop('disabled', false); +}); + + +$('#duplicar').on('click', function() { + var id = id ?>; + var url = ''; + url = url.replace(':id', id ); + $.ajax({ + url: url, + type: 'POST', + data: { + : v, + }, + success: function(response){ + if('error' in response){ + + } else { + var url = ''; + url = url.replace(':id', response.id); + + window.location.href = url; + } + } + }); +}); + + +$(".update-cabecera").on("change", function(){ + + if($(this).attr('id') == 'serie_id'){ + var id = $(this).val(); + if(id == 7 || id == 9){ + // se muestra el campo de factura rectificada que tiene como clase factura-R + $('.factura-R').show(); + $('#div_cliente').removeClass('col-lg-6').addClass('col-lg-4'); + } else { + // se oculta el campo de factura rectificada + $('.factura-R').hide(); + $('#div_cliente').removeClass('col-lg-4').addClass('col-lg-6'); + } + } + + $.ajax({ + url: 'id) ?>', + type: 'POST', + data: { + : v, + name: this.name, + value: $(this).val() + }, + success: function(response){ + if('error' in response){ + + } + } + }); +}); + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php new file mode 100644 index 00000000..2a4142f8 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/_facturaLineasItems.php @@ -0,0 +1,460 @@ +
+ +
+

+ +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
id
Subtotal:
I.V.A.:
Total:
serie_id == 7 || $facturaEntity->serie_id == 9)? "style='display:none;'":"" ?> colspan="9" style="text-align:right">Pendiente de pago:serie_id == 7 || $facturaEntity->serie_id == 9)? "style='display:none;'":"" ?> id="pendiente-pago">
+ estado =='borrador') : ?> +
+
+ +
+
+ +
+
+
+
+ + +section('additionalInlineJs') ?> + +const actionBtns = function(data) { + + // se comprueba si data es null + estado != 'borrador') :?> + if (data.pedido_id != null) { + return ` +
+
+ +
+
+ `; + } + else + { + return ``; + } + + + if (data.pedido_id === null) { + return ` + +
+
+ + + +
+
+ `; + } + else{ + return ` +
+
+
+ + + +
+
+
+ +
+
+ `; + } + +}; + + +var editor_lineas = new $.fn.dataTable.Editor( { + ajax: { + url: "", + headers: { + : v, + }, + }, + table : "#tableOfLineasFactura", + idSrc: 'id', + fields: [ + { + name: "cantidad", + + }, { + name: "descripcion", + type: "textarea", + attr: { + rows: 5, + style: "height: 120px;" + } + }, { + name: "precio_unidad", + attr: { + style: "min-width: 65px;" + } + }, { + name: "iva", + }, { + name: "pedido_linea_impresion_id", + type: "hidden" + }, { + name: "pedido_maquetacion_id", + type: "hidden" + }, { + name: "id", + type: "hidden" + }, { + name: "base", + type: "hidden" + }, + ] +} ); + + +var old_cantidad = 0; + +editor_lineas.on( 'preEdit', function ( e, json, data, id ) { + + old_cantidad = data.cantidad; + +}); + +editor_lineas.on( 'preSubmit', function ( e, d, type ) { + + if ( type === 'create'){ + d.data[0]['factura_id'] = id ?>; + d.data[0]['old_cantidad'] = null; + } + else if(type === 'edit' ) { + for (v in d.data){ + d.data[v]['factura_id'] = id ?>; + d.data[v]['old_cantidad'] = old_cantidad; + } + } +}); + + +editor_lineas.on( 'postSubmit', function ( e, json, data, action ) { + + yeniden(json.); +}); + +editor_lineas.on( 'submitSuccess', function ( e, json, data, action ) { + + tableLineas.clearPipeline(); + tableLineas.draw(); +}); + + +// Activate an inline edit on click of a table cell +$('#tableOfLineasFactura').on( 'click', 'tbody span.edit', function (e) { + + editor_lineas.inline(tableLineas.cells(this.closest('tr'), '*').nodes(), + { + + cancelHtml: '', + cancelTrigger: 'span.cancel', + submitHtml: '', + submitTrigger: 'span.edit', + submit: 'allIfChanged' + } + ); +} ); + + +var tableLineas = $('#tableOfLineasFactura').DataTable({ + processing: true, + serverSide: true, + autoWidth: true, + responsive: true, + scrollX: true, + columns: [ + { + data: actionBtns, + className: 'row-edit dt-center' + }, + {data: "id"}, + {data: "pedido_linea_impresion_id"}, + {data: "pedido_maquetacion_id"}, + {data: "pedido_id"}, + {data: "cantidad"}, + { + data: "descripcion", + render: function (data, type, row, meta) { + + if(row.pedido_linea_impresion_id != null){ + + // se convierten a float data.total_aceptado y subtotal + var total_aceptado = parseFloat(row.total_aceptado); + var subtotal = parseFloat(row.base); + + var error_text = ''; + if(total_aceptado != subtotal){ + error_text = 'El total del pedido ('+ total_aceptado + '€) no coincide con la línea ('+ subtotal + '€)'; + } + + return ` +
+ ${data} +
+ +
+ + ${error_text} +
+ +
+ + +
+ `; + } + else{ + return ` +
+ ${data} +
+ `; + } + } + }, + {data: "precio_unidad"}, + {data: "iva"}, + {data: "base"}, + {data: "total_iva"}, + {data: "total"}, + ], + order: [[1, "asc"]], + dom: 't', + language: { + url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" + }, + ajax : $.fn.dataTable.pipeline( { + url: 'id) ?>', + method: 'POST', + headers: {'X-Requested-With': 'XMLHttpRequest'}, + async: true, + }), + columnDefs: [ + { + orderable: false, + searchable: false, + targets: [0] + }, + { + visible: false, + targets: [1, 2, 3, 4, 10, 11] + } + + ], + footerCallback: function (row, data, start, end, display) { + updateFooterLineas(this.api()); + } +}); + + +function updateFooterLineas(table){ + + // Remove the formatting to get integer data for summation + var intVal = function (i) { + return typeof i === 'string' ? + i.replace(/[\$,]/g, '')*1 : + typeof i === 'number' ? + i : 0; + }; + + // Total over all pages + var totalSubtotal = table + .column(9) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + var totalIVA = table + .column(10) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + var totalTotal = table + .column(11) + .data() + .reduce(function (a, b) { + return intVal(a) + intVal(b); + }, 0); + + // Update footer + $('#subtotal-sum').html(totalSubtotal.toFixed(2)); + $('#total-iva-sum').html(totalIVA.toFixed(2)); + $('#total-sum').html(totalTotal.toFixed(2)); + + // Assuming pendiente de pago is totalTotal - totalIVA for this example + estado == 'borrador') :?> + var pendientePago = totalTotal ; + var total_pagos = 0; + + var total_pagos = parseFloat($('#totalCobrado-sum').html()).toFixed(2); + var pendientePago = totalTotal - total_pagos; + + if(isNaN(pendientePago)){ + pendientePago = 0; + } + $('#pendiente-pago').html(pendientePago.toFixed(2)); + + $.ajax({ + url: 'id) ?>', + method: 'POST', + data: { + base: totalSubtotal, + total: totalTotal, + total_pagos: total_pagos, + pendiente: pendientePago + } + }).done((data, textStatus, jqXHR) => { + if(data.estado_pago == 'pagada'){ + $('#estado_pago_text').text(''); + $('#estado_pago_text').css('color', 'green'); + } + else{ + $('#estado_pago_text').text(''); + $('#estado_pago_text').css('color', 'red'); + } + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) +} + +// Delete row +$(document).on('click', '.btn-delete', function(e) { + + const dataId = $(this).attr('data-id'); + const row = $(this).closest('tr'); + if ($.isNumeric(dataId)) { + asyncConfirmDialogWithParams( + "Borrar Linea de Factura", + "¿Está seguro de borrar la línea? Esta acción no se puede deshacer.", + deleteConfirmed, function(){}, [dataId, row]) + } +}); + + +function deleteConfirmed(params){ + var factura_linea_id = params[0]; + var row = params[1]; + const row_data = tableLineas.row($(row)).data(); + + if(row_data.pedido_linea_impresion_id != null){ + var url = ''; + $.ajax({ + url: url, + method: 'POST', + data: { + factura_id: id ?>, + pedido_linea_impresion_id: row_data.pedido_linea_impresion_id, + cantidad: row_data.cantidad + } + }).done((data, textStatus, jqXHR) => { + + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) + } + + + var url = ''; + url = url.replace(':id', factura_linea_id ); + $.ajax({ + url: url, + method: 'GET', + }).done((data, textStatus, jqXHR) => { + $('#tableOfLineasFactura').DataTable().clearPipeline(); + $('#tableOfLineasFactura').DataTable().row($(row)).invalidate().draw(); + }).fail((jqXHR, textStatus, errorThrown) => { + popErrorAlert(jqXHR.responseJSON.messages.error) + }) +} + +$(document).on('click', '.btn-view_pedido', function(e) { + var pedido_id = $(this).data('id'); + var url = ''; + url = url.replace(':id', pedido_id ); + + window.open(url, '_blank'); +}); + + +$('#addLineaFactura').on('click', function() { + const formOptions= { + submitTrigger: 0, + submitHtml: '' + + }; + editor_lineas.inlineCreate('end', formOptions); +}); + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php b/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php new file mode 100644 index 00000000..19911667 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/_pagosFacturasItems.php @@ -0,0 +1,352 @@ +
+
+

+ +

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

+ +

+
+
+ +

+ +
+
+
+
+ + +section('additionalInlineJs') ?> + + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/viewAddFactura.php b/ci4/app/Views/themes/vuexy/form/facturas/viewAddFactura.php index e69de29b..727d7ced 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewAddFactura.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewAddFactura.php @@ -0,0 +1,118 @@ +include('themes/_commonPartialsBs/datatables') ?> +include("themes/_commonPartialsBs/select2bs5") ?> +include("themes/_commonPartialsBs/sweetalert") ?> +include('themes/_commonPartialsBs/_confirm2delete') ?> +extend('themes/vuexy/main/defaultlayout') ?> + +section("content") ?> +
+
+
+
+

+
+
+ + + getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> + +
+ +
+
+ + +
+
+ +
+ +
+ +
+
+ + +
+
+ +
+ + +
+ " + /> + "btn btn-secondary float-start"]) ?> +
+
+
+
+ +
+ +endSection() ?> + +section("additionalInlineJs") ?> + +$('#cliente_id').select2({ + allowClear: false, + ajax: { + url: '', + type: 'post', + dataType: 'json', + + data: function(params) { + return { + id: 'id', + text: 'nombre', + searchTerm: params.term, + : v + }; + }, + delay: 60, + processResults: function(response) { + yeniden(response.); + return { + results: response.menu + }; + }, + cache: true + } +}); + + +$('#serie_id').select2({ + allowClear: false, + minimumResultsForSearch: -1, + ajax: { + url: '', + type: 'post', + dataType: 'json', + + data: function(params) { + return { + id: 'id', + text: 'nombre', + searchTerm: params.term, + : v + }; + }, + delay: 60, + processResults: function(response) { + yeniden(response.); + return { + results: response.menu + }; + }, + cache: true + } +}); + +endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php new file mode 100644 index 00000000..2b381c07 --- /dev/null +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturaForm.php @@ -0,0 +1,132 @@ +include('themes/_commonPartialsBs/datatables') ?> +include("themes/_commonPartialsBs/select2bs5") ?> +include("themes/_commonPartialsBs/sweetalert") ?> +include('themes/_commonPartialsBs/_confirm2delete') ?> +extend('themes/vuexy/main/defaultlayout') ?> + +section("content") ?> +
+
+
+
+

+
+
+ + + getErrors()) ? $validation->listErrors("bootstrap_style") : "" ?> + + + estado =='borrador') : ?> + + + + + estado !='borrador' && (strpos($facturaEntity->numero, "REC ") !== 0) ) : ?> + + + estado !='borrador' && (strpos($facturaEntity->numero, "REC ") === 0) ) : ?> + + + +
+ estado =='borrador') : ?> + " + /> + " + /> + + " + /> + "btn btn-secondary float-start"]) ?> +
+
+
+
+ + + +
+ +endSection() ?> + + +section("additionalInlineJs") ?> + +$("#borrarFactura").on("click", function(){ + + asyncConfirmDialog( + "Borrar Factura", + "¿Está seguro de borrar la factura? Esta acción no se puede deshacer.", + deleteConfirmed, null) +}); + +function deleteConfirmed(){ + $.ajax({ + url: "id) ?>", + type: 'GET', + success: function(response){ + window.location.href = ""; + } + }); +} + +$("#validarFactura").on("click", function(){ + +asyncConfirmDialog( + "Validar Factura", + "¿Está seguro de pasar la factura a validada? Esta acción no se puede deshacer.", + validatedConfirmed, null) +}); + +function validatedConfirmed(){ + $.ajax({ + url: "id) ?>", + type: 'GET', + success: function(response){ + window.location.href = "id) ?>"; + } + }); +} + + +endSection() ?> + + +section('css') ?> + "> + "> + + + +endSection() ?> + +section('additionalExternalJs') ?> + + + + + + + + + + + + + +endSection() ?> + + diff --git a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php index 3ebdfc4b..6e277b1f 100644 --- a/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php +++ b/ci4/app/Views/themes/vuexy/form/facturas/viewFacturasList.php @@ -27,6 +27,7 @@ + @@ -49,12 +50,22 @@ const lastColNr = $('#tableOfFacturas').find("tr:first th").length - 1; const actionBtns = function(data) { - return ` + if(data.estado == 'borrador'){ + return ` + +
+ +
+ `; + } + else{ + return `
`; + } }; theTable = $('#tableOfFacturas').DataTable({ @@ -100,7 +111,24 @@ { 'data': 'base' }, { 'data': 'total' }, { 'data': 'pendiente' }, - { 'data': 'creditoAsegurado' }, + { 'data': 'creditoAsegurado' , + render: function(data, type, row, meta) { + switch(data){ + case "0": + return ''; + break; + + case "1": + return ''; + break; + + default: + return '--'; // Debug + break; + + } + }, + }, { 'data': 'estado', render: function(data, type, row, meta) { switch(data){ @@ -141,8 +169,7 @@ } } }, - { 'data': 'total_presupuesto' }, - { 'data': forma_pago, + { 'data': 'forma_pago', render: function(data, type, row, meta) { switch(data){ case "cheque": @@ -170,20 +197,21 @@ break; default: - return '--'; // Debug + return data; // Debug break; } } }, - { 'data': vencimiento }, + { 'data': 'vencimiento' }, + { 'data': 'dias_vencimiento' }, { 'data': actionBtns } ] }); $(document).on('click', '.btn-edit', function(e) { - var url = ''; + var url = ''; url = url.replace(':id', `${$(this).attr('data-id')}` ); window.location.href = url; }); diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php b/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php index c3871138..03c61bc5 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/_facturasItems.php @@ -10,6 +10,21 @@
+ + + + + + + + + + + + + + +
ID
@@ -19,6 +34,77 @@ section('additionalInlineJs') ?> +const actionBtns_facturas = function(data) { + return ` + +
+ +
+ `; +}; +tablaFacturasPedido = $('#tableOfFacturas').DataTable({ + processing: true, + serverSide: true, + autoWidth: true, + responsive: true, + scrollX: true, + "dom": 't', + stateSave: true, + order: [[1, 'asc']], + language: { + url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json" + }, + ajax : $.fn.dataTable.pipeline( { + url: '', + method: 'POST', + data: function ( d ) { + d.pedido_id = id ?>; + }, + headers: {'X-Requested-With': 'XMLHttpRequest'}, + async: true, + }), + columnDefs: [ + { + orderable: false, + searchable: false, + targets: [0] + } + ], + columns : [ + { 'data': actionBtns_facturas }, + { 'data': 'id' }, + { 'data': 'numero' }, + { 'data': 'serie' }, + { 'data': 'estado', + render: function(data, type, row, meta) { + switch(data){ + case "borrador": + return ''; + break; + + case "validada": + return ''; + break; + + default: + return '--'; // Debug + break; + + } + } + }, + { 'data': 'fecha_factura_at' }, + { 'data': 'total' }, + ] +}); + +$(document).on('click', '.btn-view-factura', function(e) { + var pedido_id = $(this).data('id'); + var url = ''; + url = url.replace(':id', pedido_id ); + + window.open(url, '_blank'); +}); endSection() ?> \ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php b/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php index 9665e763..be7f622a 100644 --- a/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php +++ b/ci4/app/Views/themes/vuexy/form/pedidos/_lineasItems.php @@ -130,7 +130,6 @@ $(document).on('click', '.btn-view', function(e) { var url = ''; url = url.replace(':id', `${$(this).attr('data-id')}` ); - console.log(url); window.open( url, '_blank' // <- This is what makes it open in a new window. diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/_disenioLibroItems.php b/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/_disenioLibroItems.php index 66de6299..442b8694 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/_disenioLibroItems.php +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cliente/_disenioLibroItems.php @@ -16,7 +16,7 @@
- + estado_id == 2): ?> +
+
+ + > +
+
+
diff --git a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_resumenPresupuestos.js b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_resumenPresupuestos.js index 6cfb891e..a7351f3f 100644 --- a/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_resumenPresupuestos.js +++ b/ci4/app/Views/themes/vuexy/form/presupuestos/cosidotapablanda/_resumenPresupuestos.js @@ -177,8 +177,8 @@ function updateTotales(updateLP=true, updateServicios=true, updateEnvio=true){ margenEnvios = parseFloat($('#margenEnvios').attr('val')) } - var totalCostes = totalPapel + totalImpresion + totalServicios + totalEnvios - var totalMargenes = margenPapel + margenImpresion + margenServicios + margenEnvios + var totalCostes = parseFloat(totalPapel.toFixed(2)) + parseFloat(totalImpresion.toFixed(2)) + parseFloat(totalServicios.toFixed(2)) + parseFloat(totalEnvios.toFixed(2)) + var totalMargenes = parseFloat(margenPapel.toFixed(2)) + parseFloat(margenImpresion.toFixed(2)) + parseFloat(margenServicios.toFixed(2)) + parseFloat(margenEnvios.toFixed(2)) $('#totalCostes').text((addSeparatorsNF(totalCostes.toFixed(2), ".", ",", ".")) + "€") $('#totalMargenes').text((addSeparatorsNF(totalMargenes.toFixed(2), ".", ",", ".")) + "€") $('#totalCostes').attr('val',(totalCostes).toFixed(2) + '€') @@ -251,11 +251,13 @@ function getValuesResumenForm(){ formResumen += '&total_presupuesto=' + $('#totalDespuesDecuento').attr('val'); formResumen += '&total_precio_unidad=' + $('#precioUnidadPresupuesto').attr('val'); - formResumen += '&total_factor=' + $('#total_factor').text(); - formResumen += '&total_factor_ponderado=' + $('#total_factor_ponderado').text(); + // replace , for . in the values + formResumen += '&total_factor=' + $('#factor').text().replace(/,/g, '.'); + formResumen += '&total_factor_ponderado=' + $('#factor_ponderado').text().replace(/,/g, '.'); if($('#confirmar_presupuesto').prop('checked')){ - formResumen += '&confirmar=1'; + formResumen += '&confirmar=1'; + formResumen += '&total_aceptado=' + $('#totalDespuesDecuento').attr('val'); } return formResumen diff --git a/ci4/app/Views/themes/vuexy/form/profile/index_old.php b/ci4/app/Views/themes/vuexy/form/profile/index_old.php deleted file mode 100644 index c0aadbd7..00000000 --- a/ci4/app/Views/themes/vuexy/form/profile/index_old.php +++ /dev/null @@ -1,444 +0,0 @@ - -" - rel="stylesheet"> - - -
-
-
-
-
-

- -
-
-
- -
-
-
-
-
-
-

-
-
- -
" method="post"> - -
-
-
- -
-
-
- - " - value="first_name : set_value('first_name'); ?>"> -
-
-
-
- - " - value="last_name : set_value('last_name'); ?>"> -
-
-
-
- - " - id="date_birth" name="date_birth" - value="date_birth : set_value('date_birth'); ?>"> -
-
-
-
- - " - value="email : set_value('email'); ?>" - disabled> -
-
-
-
- - " - value="mobile : set_value('mobile'); ?>"> -
-
-
-
- - "> -
-
-
-
- - "> -
-
-
-
-
- -
-
-
- - " - value="address : set_value('address'); ?>"> -
-
-
-
- - " - value="city : set_value('city'); ?>"> -
-
-
-
- - " - value="state : set_value('state'); ?>"> -
-
-
-
- - country ?? [] : set_value('country'); ?> - -
-
-
-
- - language ?? [] : set_value('language'); ?> - -
-
-
-
-
- - - - -
-
-
-
-
-
-
-
-

-
-
-
-
- -
-
- first_name ?? '' ?>
- email ?? '' ?> -
-
- -
- - -
-
-
-
-
- get('settings'); ?> - - -
" method="post" id="sendFormTFA"> - -
-
-
-
-
-
-

-
-
-
- > - -
-
-
-
-
-
- GetQR("{$settings['title']} ({$name})", $tfa_secret); - } else { - $tfa_secret = $tfa->createSecret(); - $qrcode = $tfa->GetQR("{$settings['title']} ({$name})", $tfa_secret); - } - ?> -
-
-

- -
-
-

- ' . $item . ''; - } - } else { - $codes = array(); - for ($i = 1; $i <= 8; $i++) { - $code = random_string('numeric', 6); - $codes[] = $code; - echo '' . $code . ''; - } - } - ?> -


- - - -
-
-
-
-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - diff --git a/ci4/app/Views/themes/vuexy/form/profile/index.php b/ci4/app/Views/themes/vuexy/form/profile/profileDetails.php similarity index 58% rename from ci4/app/Views/themes/vuexy/form/profile/index.php rename to ci4/app/Views/themes/vuexy/form/profile/profileDetails.php index 58eee725..4a9fc610 100644 --- a/ci4/app/Views/themes/vuexy/form/profile/index.php +++ b/ci4/app/Views/themes/vuexy/form/profile/profileDetails.php @@ -1,5 +1,4 @@ -include("themes/_commonPartialsBs/select2bs5") ?> -extend('themes/vuexy/main/general_settings_layout') ?> +extend('themes/vuexy/main/defaultlayout') ?> section('content'); ?> @@ -12,10 +11,11 @@
">
-
- +
+
-
- +
+
-
+
" value="email : set_value('email'); ?>" />
+
+ + " + value="" + /> +
+
+ + " + value="" + /> +
- - + + "btn btn-dark"]) ?>
- - - -
get('settings'); ?> @@ -96,12 +95,7 @@ section('additionalInlineJs') ?> "use strict"; $(document).ready(function () { -$('#first_name').focus(); + $('#first_name').focus(); }); -$('.file-upload').on('click', function (e) { -e.preventDefault(); -$('#file').trigger('click'); -}); - endSection() ?> diff --git a/ci4/app/Views/themes/vuexy/form/user/_userFormItems.php b/ci4/app/Views/themes/vuexy/form/user/_userFormItems.php index ba0c3c02..d394dc4e 100644 --- a/ci4/app/Views/themes/vuexy/form/user/_userFormItems.php +++ b/ci4/app/Views/themes/vuexy/form/user/_userFormItems.php @@ -1,26 +1,41 @@ -
-
+
+
+
+
+ + +
+
-
- - -
+
+
+ + +
+
-
- - -
+
+
+ + +
+
+
+
-
-
- - -
-
- -
- - -
- -
- - status); ?> -
- -
- - active); ?> - -
- -
-
- $v) : ?> -
-
+
+ +
+
+
+ + status); ?> + +
+
+ +
+
+ + active); ?> + +
+
+
+ +
+
+
+ + +
+
+ +
+
+ + +
+
+
+ +
+
+ + +
+
+ +
+ + -
\ No newline at end of file diff --git a/ci4/app/Views/themes/vuexy/form/user/viewUserList.php b/ci4/app/Views/themes/vuexy/form/user/viewUserList.php index 63935bc1..b22a4c76 100644 --- a/ci4/app/Views/themes/vuexy/form/user/viewUserList.php +++ b/ci4/app/Views/themes/vuexy/form/user/viewUserList.php @@ -17,8 +17,8 @@ - - + + @@ -46,11 +46,10 @@ last_name) || strlen($item->last_name) < 51 ? esc($item->last_name) : character_limiter(esc($item->last_name), 50) ?> - - group) ? "" : character_limiter(esc(lang('Users.' . $item->group)), 50) ?> - - - + + email) ? "" : character_limiter(esc(lang($item->email)), 50) ?> + + last_active) ? '' : date('d/m/Y H:m:s', strtotime($item->last_active)) ?> diff --git a/ci4/app/Views/themes/vuexy/main/activities_layout.php b/ci4/app/Views/themes/vuexy/main/activities_layout.php deleted file mode 100644 index a5534604..00000000 --- a/ci4/app/Views/themes/vuexy/main/activities_layout.php +++ /dev/null @@ -1,357 +0,0 @@ -get('token') ?? ''; -$tfa = $session->get('tfa') ?? false; -$settings = $session->get('settings'); - -$picture = "/assets/img/default-user.png"; -$pulse = session()->get('pulse'); -$notification = session()->get('notification'); - -if (!empty($token) && $tfa == false) { - //echo ""; -} -?> - - - - - - - - - - <?= config('Safekat')->appName ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - renderSection('css') ?> - - - - - - - - - - - -
-
- - - - -
- - - - - - -
- - -
-
- -
- - renderSection('content') ?> - -
- - - - - - -
-
- -
- -
- - -
- - -
-
- - -renderSection('footerAdditions') ?> - - - - - - - - - - - - -renderSection('additionalExternalJs') ?> - - - - - - - - - - - - - - diff --git a/ci4/app/Views/themes/vuexy/main/all.php b/ci4/app/Views/themes/vuexy/main/all.php deleted file mode 100644 index fd8f2ef2..00000000 --- a/ci4/app/Views/themes/vuexy/main/all.php +++ /dev/null @@ -1,570 +0,0 @@ -get('settings'); -$picture = "/assets/img/default-user.png"; -?> - - - - - - - - - <?= config('Safekat')->appName ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - -
- - - - - - -
- -
-
- -
-

- Sample page. -

-
- - - - - - -
-
- -
- -
- - -
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ci4/app/Views/themes/vuexy/main/defaultlayout.php b/ci4/app/Views/themes/vuexy/main/defaultlayout.php index 5f8ecdd7..4d03e697 100644 --- a/ci4/app/Views/themes/vuexy/main/defaultlayout.php +++ b/ci4/app/Views/themes/vuexy/main/defaultlayout.php @@ -133,7 +133,6 @@ $picture = "/assets/img/default-user.png"; title="Acceso directo a buscador de presupuestos" > - @@ -232,8 +231,8 @@ $picture = "/assets/img/default-user.png";
- get('first_name') . ' ' . $session->get('last_name') ?> - Admin + user()->getFullName(); ?> + user()->getEmail(); ?>
@@ -247,13 +246,6 @@ $picture = "/assets/img/default-user.png"; - - - - - - -
  • diff --git a/ci4/app/Views/themes/vuexy/main/demo_view.php b/ci4/app/Views/themes/vuexy/main/demo_view.php deleted file mode 100644 index e69defe8..00000000 --- a/ci4/app/Views/themes/vuexy/main/demo_view.php +++ /dev/null @@ -1,297 +0,0 @@ -get('token') ?? ''; -$tfa = $session->get('tfa') ?? false; -$settings = $session->get('settings'); - -$picture = "/assets/img/default-user.png"; -$pulse = session()->get('pulse'); -$notification = session()->get('notification'); - -if (!empty($token) && $tfa == false) { - //echo ""; -} -?> - - - - - - - - - <?= config('Safekat')->appName ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - -
    - - - - - - -
    - - -
    -

    - Safekat / - -

    -
    - -
    -
    -
    Prueba privilegios
    -
    -
    - - - -
    -
    - -
    -
    -
    - -
    - - - - - - -
    -
    - -
    - -
    - - -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ci4/app/Views/themes/vuexy/main/general_settings_layout.php b/ci4/app/Views/themes/vuexy/main/general_settings_layout.php deleted file mode 100644 index b1b9aa2b..00000000 --- a/ci4/app/Views/themes/vuexy/main/general_settings_layout.php +++ /dev/null @@ -1,359 +0,0 @@ -get('token') ?? ''; -$tfa = $session->get('tfa') ?? false; -$settings = $session->get('settings'); - -$picture = "/assets/img/default-user.png"; -$pulse = session()->get('pulse'); -$notification = session()->get('notification'); - -if (!empty($token) && $tfa == false) { - //echo ""; -} -?> - - - - - - - - - - <?= config('Safekat')->appName ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - renderSection('css') ?> - - - - - - - - - - - -
    -
    - - - - -
    - - - - - - -
    - - -
    -
    - -
    - - renderSection('content') ?> - -
    - - - - - - -
    -
    - -
    - -
    - - -
    - - -
    -
    - - -renderSection('footerAdditions') ?> - - - - - - - - - - - - -renderSection('additionalExternalJs') ?> - - - - - - - - - - - - - diff --git a/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php b/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php index c061363c..e26b620b 100644 --- a/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php +++ b/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php @@ -4,8 +4,8 @@ */ if ( auth()->user()->can('paises.menu') || - auth()->user()->can('papeles-genericos.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-defecto.menu') || auth()->user()->can('usuarios.menu') || @@ -25,14 +25,14 @@ if ( - user()->can('papeles-genericos.menu')) { ?> + user()->can('papel-generico.menu')) { ?> - user()->can('papeles-impresion.menu')) { ?> + user()->can('papel-impresion.menu')) { ?>