From 71976fd3386d09b57be5ea8ef41477c77a014f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20S=C3=A1nchez?= Date: Fri, 5 Jun 2026 10:04:19 +0200 Subject: [PATCH 1/4] =?UTF-8?q?Actualiza=20ServicioAT=20y=20a=C3=B1ade=20n?= =?UTF-8?q?uevas=20vistas=20para=20direcci=C3=B3n,=20ciudad,=20c=C3=B3digo?= =?UTF-8?q?=20postal=20y=20provincia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Modificado ServicioAT.php para mejorar la lógica de guardado de datos de dirección. - Añadido archivo EditServicioAT.xml para la configuración de la vista de edición. - Creado ListServicioAT.php con la función para crear vistas de lista. - Añadido archivo ListServicioAT.xml para la configuración de la vista de lista. - Añadido archivo serviciosat.xml para definir la estructura de la tabla de datos. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b12bd4f3ad..7c0b3a9f21 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /vendor/ .DS_Store .htaccess +.user.ini config.php config-mysql.php config-postgresql.php From 4df7bbefb1f40a969273cd6c2e4b6894065ffd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20S=C3=A1nchez?= Date: Tue, 9 Jun 2026 18:43:18 +0200 Subject: [PATCH 2/4] =?UTF-8?q?A=C3=B1ade=20b=C3=BAsqueda=20por=20referenc?= =?UTF-8?q?ia=20del=20proveedor=20en=20PurchaseDocument=20y=20PurchasesCon?= =?UTF-8?q?troller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://facturascripts.com/roadmap/3586 - Modificado PurchaseDocument.php para incluir la búsqueda de productos por referencia del proveedor si no se encuentra por referencia o código de barras. - Actualizado PurchasesController.php para permitir la búsqueda de referencias de proveedor en la lista de productos. Estos cambios mejoran la funcionalidad de búsqueda de productos, facilitando la localización de artículos a partir de referencias de proveedor. --- Core/Lib/AjaxForms/PurchasesController.php | 26 ++++++++++++++++++++++ Core/Model/Base/PurchaseDocument.php | 14 +++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Core/Lib/AjaxForms/PurchasesController.php b/Core/Lib/AjaxForms/PurchasesController.php index dce39d33ee..c9975cd16c 100644 --- a/Core/Lib/AjaxForms/PurchasesController.php +++ b/Core/Lib/AjaxForms/PurchasesController.php @@ -20,6 +20,7 @@ namespace FacturaScripts\Core\Lib\AjaxForms; use FacturaScripts\Core\Base\DataBase\DataBaseWhere; +use FacturaScripts\Core\Where; use FacturaScripts\Core\DataSrc\Series; use FacturaScripts\Core\Lib\Calculator; use FacturaScripts\Core\Lib\ExtendedController\BaseView; @@ -30,6 +31,7 @@ use FacturaScripts\Core\Model\Base\PurchaseDocument; use FacturaScripts\Core\Tools; use FacturaScripts\Dinamic\Lib\AssetManager; +use FacturaScripts\Dinamic\Model\ProductoProveedor; use FacturaScripts\Dinamic\Model\Proveedor; use FacturaScripts\Dinamic\Model\Variante; use Throwable; @@ -128,6 +130,30 @@ protected function autocompleteProductAction(): bool ]; } + // buscar también por referencia del proveedor + if (!empty($query)) { + $addedRefs = array_column($list, 'key'); + $whereProv = [Where::like('refproveedor', $query . '%')]; + foreach (ProductoProveedor::all($whereProv, [], 0, 10) as $prodProv) { + if (in_array($prodProv->referencia, $addedRefs)) { + continue; + } + $variant2 = new Variante(); + if (!$variant2->loadWhere([Where::eq('referencia', $prodProv->referencia)])) { + continue; + } + $product = $variant2->getProducto(); + if ($product->bloqueado || !$product->secompra) { + continue; + } + $addedRefs[] = $prodProv->referencia; + $list[] = [ + 'key' => Tools::fixHtml($prodProv->referencia), + 'value' => Tools::fixHtml($variant2->description()) + ]; + } + } + if (empty($list)) { $list[] = ['key' => null, 'value' => Tools::trans('no-data')]; } diff --git a/Core/Model/Base/PurchaseDocument.php b/Core/Model/Base/PurchaseDocument.php index 3c4113be27..b88f6533a8 100644 --- a/Core/Model/Base/PurchaseDocument.php +++ b/Core/Model/Base/PurchaseDocument.php @@ -85,7 +85,19 @@ public function getNewProductLine($reference) $variant = new Variante(); $where1 = [Where::eq('referencia', Tools::noHtml($reference))]; $where2 = [Where::eq('codbarras', Tools::noHtml($reference))]; - if ($variant->loadWhere($where1) || $variant->loadWhere($where2)) { + $found = $variant->loadWhere($where1) || $variant->loadWhere($where2); + if (!$found) { + // buscar por referencia del proveedor + $whereProv = [Where::eq('refproveedor', Tools::noHtml($reference))]; + if (!empty($this->codproveedor)) { + $whereProv[] = Where::eq('codproveedor', $this->codproveedor); + } + $provList = ProductoProveedor::all($whereProv, [], 0, 1); + if (!empty($provList)) { + $found = $variant->loadWhere([Where::eq('referencia', $provList[0]->referencia)]); + } + } + if ($found) { $product = $variant->getProducto(); $newLine->codimpuesto = $product->getTax()->codimpuesto; From e8b732af6a9be562dd924725128ea768fcd99a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20S=C3=A1nchez?= Date: Tue, 9 Jun 2026 18:45:34 +0200 Subject: [PATCH 3/4] =?UTF-8?q?A=C3=B1ade=20b=C3=BAsqueda=20por=20referenc?= =?UTF-8?q?ia=20del=20proveedor=20en=20PurchaseDocument=20y=20PurchasesCon?= =?UTF-8?q?troller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://facturascripts.com/roadmap/3586 - Modificado PurchaseDocument.php para incluir la búsqueda de productos por referencia del proveedor si no se encuentra por referencia o código de barras. - Actualizado PurchasesController.php para permitir la búsqueda de referencias de proveedor en la lista de productos. Estos cambios mejoran la funcionalidad de búsqueda de productos, facilitando la localización de artículos a partir de referencias de proveedor. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7c0b3a9f21..b12bd4f3ad 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ /vendor/ .DS_Store .htaccess -.user.ini config.php config-mysql.php config-postgresql.php From 7848aaec6195da913bc7731f281502198aacdf72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20S=C3=A1nchez?= Date: Fri, 26 Jun 2026 19:51:18 +0200 Subject: [PATCH 4/4] =?UTF-8?q?Refactoriza=20b=C3=BAsqueda=20por=20referen?= =?UTF-8?q?cia=20del=20proveedor=20en=20PurchaseDocument=20y=20PurchasesCo?= =?UTF-8?q?ntroller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Se revierte la lógica de búsqueda por referencia del proveedor en PurchaseDocument. - Se añade la función resolveSupplierRef para resolver referencias de proveedores. - Se actualiza PurchasesController para incluir la búsqueda por referencia del proveedor en las consultas. - Se modifica PurchasesDocument.html.twig para enviar el código del proveedor en la solicitud de autocompletado. Este cambio mejora la eficiencia de las búsquedas y la gestión de referencias de proveedores. --- Core/Lib/AjaxForms/PurchasesController.php | 79 +++++++++++++++++----- Core/Model/Base/PurchaseDocument.php | 14 +--- Core/View/Tab/PurchasesDocument.html.twig | 2 +- 3 files changed, 63 insertions(+), 32 deletions(-) diff --git a/Core/Lib/AjaxForms/PurchasesController.php b/Core/Lib/AjaxForms/PurchasesController.php index c9975cd16c..d7d8137ec4 100644 --- a/Core/Lib/AjaxForms/PurchasesController.php +++ b/Core/Lib/AjaxForms/PurchasesController.php @@ -19,8 +19,6 @@ namespace FacturaScripts\Core\Lib\AjaxForms; -use FacturaScripts\Core\Base\DataBase\DataBaseWhere; -use FacturaScripts\Core\Where; use FacturaScripts\Core\DataSrc\Series; use FacturaScripts\Core\Lib\Calculator; use FacturaScripts\Core\Lib\ExtendedController\BaseView; @@ -30,7 +28,9 @@ use FacturaScripts\Core\Model\Base\BusinessDocumentLine; use FacturaScripts\Core\Model\Base\PurchaseDocument; use FacturaScripts\Core\Tools; +use FacturaScripts\Core\Where; use FacturaScripts\Dinamic\Lib\AssetManager; +use FacturaScripts\Dinamic\Model\Producto; use FacturaScripts\Dinamic\Model\ProductoProveedor; use FacturaScripts\Dinamic\Model\Proveedor; use FacturaScripts\Dinamic\Model\Variante; @@ -120,8 +120,8 @@ protected function autocompleteProductAction(): bool $variante = new Variante(); $query = (string)$this->request->queryOrInput('term'); $where = [ - new DataBaseWhere('p.bloqueado', 0), - new DataBaseWhere('p.secompra', 1) + Where::eq('p.bloqueado', 0), + Where::eq('p.secompra', 1) ]; foreach ($variante->codeModelSearch($query, 'referencia', $where) as $value) { $list[] = [ @@ -133,23 +133,29 @@ protected function autocompleteProductAction(): bool // buscar también por referencia del proveedor if (!empty($query)) { $addedRefs = array_column($list, 'key'); - $whereProv = [Where::like('refproveedor', $query . '%')]; - foreach (ProductoProveedor::all($whereProv, [], 0, 10) as $prodProv) { - if (in_array($prodProv->referencia, $addedRefs)) { - continue; - } - $variant2 = new Variante(); - if (!$variant2->loadWhere([Where::eq('referencia', $prodProv->referencia)])) { - continue; - } - $product = $variant2->getProducto(); - if ($product->bloqueado || !$product->secompra) { + $codproveedor = $this->request->queryOrInput('codproveedor'); + $whereProv = [ + Where::like('LOWER(pp.refproveedor)', strtolower($query) . '%'), + Where::eq('p.bloqueado', 0), + Where::eq('p.secompra', 1) + ]; + if (!empty($codproveedor)) { + $whereProv[] = Where::eq('pp.codproveedor', $codproveedor); + } + $sql = 'SELECT pp.referencia, pp.refproveedor, p.descripcion' + . ' FROM ' . ProductoProveedor::tableName() . ' pp' + . ' INNER JOIN ' . Variante::tableName() . ' v ON v.referencia = pp.referencia' + . ' INNER JOIN ' . Producto::tableName() . ' p ON p.idproducto = v.idproducto' + . Where::multiSql($whereProv) + . ' ORDER BY pp.refproveedor ASC'; + foreach ($this->db()->selectLimit($sql, 10) as $row) { + if (in_array($row['referencia'], $addedRefs)) { continue; } - $addedRefs[] = $prodProv->referencia; + $addedRefs[] = $row['referencia']; $list[] = [ - 'key' => Tools::fixHtml($prodProv->referencia), - 'value' => Tools::fixHtml($variant2->description()) + 'key' => Tools::fixHtml($row['referencia']), + 'value' => Tools::fixHtml($row['refproveedor'] . ' - ' . $row['descripcion']) ]; } } @@ -372,6 +378,7 @@ protected function recalculateAction(bool $renderLines): bool $formData = json_decode($this->request->input('data'), true); PurchasesHeaderHTML::apply($model, $formData); PurchasesFooterHTML::apply($model, $formData); + $this->resolveSupplierRefs($formData, $model->codproveedor); PurchasesLineHTML::apply($model, $lines, $formData); Calculator::calculate($model, $lines, false); @@ -541,6 +548,42 @@ protected function saveStatusAction(): bool return false; } + private function resolveSupplierRef(string $reference, string $codproveedor): string + { + $variant = new Variante(); + if ($variant->loadWhere([Where::eq('referencia', $reference)])) { + return $reference; + } + + $where = [Where::eq('refproveedor', $reference)]; + if (!empty($codproveedor)) { + $where[] = Where::eq('codproveedor', $codproveedor); + } + $rows = ProductoProveedor::all($where, [], 0, 1); + return empty($rows) ? $reference : $rows[0]->referencia; + } + + private function resolveSupplierRefs(array &$formData, string $codproveedor): void + { + foreach ($formData as $key => $value) { + if (!empty($value) && str_starts_with($key, 'referencia_n')) { + $formData[$key] = $this->resolveSupplierRef((string)$value, $codproveedor); + } + } + + if (!empty($formData['selectedLine'])) { + $formData['selectedLine'] = $this->resolveSupplierRef((string)$formData['selectedLine'], $codproveedor); + } + + if (($formData['action'] ?? '') === 'fast-line' && !empty($formData['fastli'])) { + $resolved = $this->resolveSupplierRef((string)$formData['fastli'], $codproveedor); + if ($resolved !== $formData['fastli']) { + $formData['action'] = 'fast-product'; + $formData['selectedLine'] = $resolved; + } + } + } + private function sendJsonWithLogs(array $data): void { $data['messages'] = Tools::log()::read('master', $this->logLevels); diff --git a/Core/Model/Base/PurchaseDocument.php b/Core/Model/Base/PurchaseDocument.php index b88f6533a8..3c4113be27 100644 --- a/Core/Model/Base/PurchaseDocument.php +++ b/Core/Model/Base/PurchaseDocument.php @@ -85,19 +85,7 @@ public function getNewProductLine($reference) $variant = new Variante(); $where1 = [Where::eq('referencia', Tools::noHtml($reference))]; $where2 = [Where::eq('codbarras', Tools::noHtml($reference))]; - $found = $variant->loadWhere($where1) || $variant->loadWhere($where2); - if (!$found) { - // buscar por referencia del proveedor - $whereProv = [Where::eq('refproveedor', Tools::noHtml($reference))]; - if (!empty($this->codproveedor)) { - $whereProv[] = Where::eq('codproveedor', $this->codproveedor); - } - $provList = ProductoProveedor::all($whereProv, [], 0, 1); - if (!empty($provList)) { - $found = $variant->loadWhere([Where::eq('referencia', $provList[0]->referencia)]); - } - } - if ($found) { + if ($variant->loadWhere($where1) || $variant->loadWhere($where2)) { $product = $variant->getProducto(); $newLine->codimpuesto = $product->getTax()->codimpuesto; diff --git a/Core/View/Tab/PurchasesDocument.html.twig b/Core/View/Tab/PurchasesDocument.html.twig index 922c1e9887..daf6b158c4 100644 --- a/Core/View/Tab/PurchasesDocument.html.twig +++ b/Core/View/Tab/PurchasesDocument.html.twig @@ -37,7 +37,7 @@ $.ajax({ method: "POST", url: '{{ fsc.url() }}', - data: {action: 'autocomplete-product', term: request.term}, + data: {action: 'autocomplete-product', term: request.term, codproveedor: document.forms['purchasesForm']['codproveedor'] ? document.forms['purchasesForm']['codproveedor'].value : ''}, dataType: "json", success: function (results) { let values = [];