From fa5c1643a4d1716f246f22c7761e42d8c2cdbaa7 Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Tue, 4 Mar 2025 12:32:21 +0100
Subject: [PATCH 01/28] test: refs #8717 add integration test for agencyModes

---
 .../integration/route/agency/agencyModes.spec.js  | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 test/cypress/integration/route/agency/agencyModes.spec.js

diff --git a/test/cypress/integration/route/agency/agencyModes.spec.js b/test/cypress/integration/route/agency/agencyModes.spec.js
new file mode 100644
index 000000000..3f5784997
--- /dev/null
+++ b/test/cypress/integration/route/agency/agencyModes.spec.js
@@ -0,0 +1,15 @@
+describe('Agency modes', () => {
+    const name = 'inhouse pickup';
+
+    beforeEach(() => {
+        cy.viewport(1920, 1080);
+        cy.login('developer');
+        cy.visit(`/#/route/agency/1/modes`);
+    });
+
+    it('should display the agency modes page', () => {
+        cy.get('.flex > .title').should('have.text', name);
+        cy.get('.flex > .q-chip > .q-chip__content').should('have.text', 'ID: 1');
+        cy.get('.list-items > :nth-child(1) > .value').should('have.text', name);
+    });
+});

From 1a0df60e06878c3695a7011016ec705a3b19dbaa Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Fri, 14 Mar 2025 14:21:26 +0100
Subject: [PATCH 02/28] fix: remove reserved ticket functionality from
 TicketProblems and TicketSaleMoreActions components

---
 src/components/TicketProblems.vue             | 11 ------
 .../Ticket/Card/TicketSaleMoreActions.vue     | 35 -------------------
 2 files changed, 46 deletions(-)

diff --git a/src/components/TicketProblems.vue b/src/components/TicketProblems.vue
index c11cc2e7b..aee132fe0 100644
--- a/src/components/TicketProblems.vue
+++ b/src/components/TicketProblems.vue
@@ -17,17 +17,6 @@ defineProps({ row: { type: Object, required: true } });
                 </QTooltip>
             </QIcon>
         </router-link>
-        <QIcon
-            v-if="row?.reserved"
-            color="primary"
-            name="vn:reserva"
-            size="xs"
-            data-cy="ticketSaleReservedIcon"
-        >
-            <QTooltip>
-                {{ t('ticketSale.reserved') }}
-            </QTooltip>
-        </QIcon>
         <QIcon
             v-if="row?.isDeleted"
             color="primary"
diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
index 840b62507..a1eaba53f 100644
--- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue
+++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
@@ -62,7 +62,6 @@ const isClaimable = computed(() => {
     }
     return false;
 });
-const hasReserves = computed(() => props.sales.some((sale) => sale.reserved == true));
 
 const sendSms = async (params) => {
     await axios.post(`Tickets/${ticket.value.id}/sendSms`, params);
@@ -144,14 +143,6 @@ const onCreateClaimAccepted = async () => {
     push({ name: 'ClaimBasicData', params: { id: data.id } });
 };
 
-const setReserved = async (reserved) => {
-    const params = { ticketId: ticket.value.id, sales: props.sales, reserved: reserved };
-    await axios.post(`Sales/reserve`, params);
-    props.sales.forEach((sale) => {
-        sale.reserved = reserved;
-    });
-};
-
 const createRefund = async (withWarehouse) => {
     if (!props.ticket) return;
 
@@ -240,30 +231,6 @@ const createRefund = async (withWarehouse) => {
                     <QItemLabel>{{ t('Add claim') }}</QItemLabel>
                 </QItemSection>
             </QItem>
-            <QItem
-                v-if="isTicketEditable"
-                clickable
-                v-close-popup
-                v-ripple
-                @click="setReserved(true)"
-                data-cy="markAsReservedItem"
-            >
-                <QItemSection>
-                    <QItemLabel>{{ t('Mark as reserved') }}</QItemLabel>
-                </QItemSection>
-            </QItem>
-            <QItem
-                v-if="isTicketEditable && hasReserves"
-                clickable
-                v-close-popup
-                v-ripple
-                @click="setReserved(false)"
-                data-cy="unmarkAsReservedItem"
-            >
-                <QItemSection>
-                    <QItemLabel>{{ t('Unmark as reserved') }}</QItemLabel>
-                </QItemSection>
-            </QItem>
             <QItem clickable v-ripple data-cy="ticketSaleRefundItem">
                 <QItemSection>
                     <QItemLabel>{{ t('Refund') }}</QItemLabel>
@@ -309,8 +276,6 @@ es:
     Recalculate price: Recalcular precio
     Update discount: Actualizar descuento
     Add claim: Crear reclamación
-    Mark as reserved: Marcar como reservado
-    Unmark as reserved: Desmarcar como reservado
     Refund: Abono
     with warehouse: con almacén
     without warehouse: sin almacén

From 5f48c9b887a799bf0ada9e7cc36ae6c86393ca9b Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Mon, 24 Mar 2025 08:13:06 +0100
Subject: [PATCH 03/28] refactor: refs #8717 eliminate warnings and add
 component on children routes

---
 src/components/VnTable/VnColumn.vue | 14 ++++++++------
 src/router/modules/route.js         |  6 ++++++
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue
index d0e245388..3ce62c5de 100644
--- a/src/components/VnTable/VnColumn.vue
+++ b/src/components/VnTable/VnColumn.vue
@@ -55,6 +55,8 @@ const $props = defineProps({
     },
 });
 
+const label = $props.showLabel && $props.column.label ? $props.column.label : '';
+
 const defaultSelect = {
     attrs: {
         row: $props.row,
@@ -62,7 +64,7 @@ const defaultSelect = {
         class: 'fit',
     },
     forceAttrs: {
-        label: $props.showLabel && $props.column.label,
+        label,
     },
 };
 
@@ -74,7 +76,7 @@ const defaultComponents = {
             class: 'fit',
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     number: {
@@ -84,7 +86,7 @@ const defaultComponents = {
             class: 'fit',
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     date: {
@@ -96,7 +98,7 @@ const defaultComponents = {
             class: 'fit',
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     time: {
@@ -105,7 +107,7 @@ const defaultComponents = {
             disable: !$props.isEditable,
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     checkbox: {
@@ -125,7 +127,7 @@ const defaultComponents = {
             return defaultAttrs;
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
             autofocus: true,
         },
         events: {
diff --git a/src/router/modules/route.js b/src/router/modules/route.js
index 62765a49c..0bf3a6eff 100644
--- a/src/router/modules/route.js
+++ b/src/router/modules/route.js
@@ -229,6 +229,7 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
+                            component: () => import('src/pages/Route/RouteList.vue'),
                         },
                         routeCard,
                     ],
@@ -277,6 +278,7 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
+                            component: () => import('src/pages/Route/RouteRoadmap.vue'),
                         },
                         roadmapCard,
                     ],
@@ -307,6 +309,8 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
+                            component: () =>
+                                import('src/pages/Route/Agency/AgencyList.vue'),
                         },
                         agencyCard,
                     ],
@@ -328,6 +332,8 @@ export default {
                                 title: 'vehicleList',
                                 icon: 'directions_car',
                             },
+                            component: () =>
+                                import('src/pages/Route/Vehicle/VehicleList.vue'),
                         },
                         vehicleCard,
                     ],

From 26f20440972b8fd42d032e49c580c58bc8b3edb0 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Mon, 24 Mar 2025 09:08:18 +0100
Subject: [PATCH 04/28] test: update order creation test and remove reserved
 ticket tests

---
 test/cypress/integration/order/orderList.spec.js |  2 +-
 .../integration/ticket/ticketSale.spec.js        | 16 ----------------
 2 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/test/cypress/integration/order/orderList.spec.js b/test/cypress/integration/order/orderList.spec.js
index 1c954622f..024517bbf 100644
--- a/test/cypress/integration/order/orderList.spec.js
+++ b/test/cypress/integration/order/orderList.spec.js
@@ -6,7 +6,7 @@ describe('OrderList', () => {
         cy.visit('/#/order/list');
     });
 
-    it('create order', () => {
+    it.only('create order', () => {
         cy.get('[data-cy="vnTableCreateBtn"]').click();
         cy.get('[data-cy="Client_select"]').type('1101');
         cy.get('.q-menu').contains('Bruce Wayne').click();
diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js
index 61ba9fe4f..514c50281 100644
--- a/test/cypress/integration/ticket/ticketSale.spec.js
+++ b/test/cypress/integration/ticket/ticketSale.spec.js
@@ -152,22 +152,6 @@ describe('TicketSale', () => {
             cy.checkNotification('Future ticket date not allowed');
         });
 
-        it('marks row as reserved', () => {
-            selectFirstRow();
-            cy.dataCy('ticketSaleMoreActionsDropdown').click();
-            cy.waitForElement('[data-cy="markAsReservedItem"]');
-            cy.dataCy('markAsReservedItem').click();
-            cy.dataCy('ticketSaleReservedIcon').should('exist');
-        });
-
-        it('unmarks row as reserved', () => {
-            selectFirstRow();
-            cy.dataCy('ticketSaleMoreActionsDropdown').click();
-            cy.waitForElement('[data-cy="unmarkAsReservedItem"]');
-            cy.dataCy('unmarkAsReservedItem').click();
-            cy.dataCy('ticketSaleReservedIcon').should('not.exist');
-        });
-
         it('refunds row with warehouse', () => {
             selectFirstRow();
             cy.dataCy('ticketSaleMoreActionsDropdown').click();

From 17b784e4d107711f329a84324be5706b406b0d11 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Mon, 24 Mar 2025 09:46:10 +0100
Subject: [PATCH 05/28] test: rename account descriptor test and enable claim
 notes test

---
 .../integration/account/accountDescriptorMenu.spec.js        | 5 ++++-
 test/cypress/integration/claim/claimNotes.spec.js            | 2 +-
 test/cypress/integration/ticket/ticketSale.spec.js           | 2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/test/cypress/integration/account/accountDescriptorMenu.spec.js b/test/cypress/integration/account/accountDescriptorMenu.spec.js
index 67a7d8ef6..04fc57040 100644
--- a/test/cypress/integration/account/accountDescriptorMenu.spec.js
+++ b/test/cypress/integration/account/accountDescriptorMenu.spec.js
@@ -1,4 +1,4 @@
-describe('ClaimNotes', () => {
+describe('Account descriptor', () => {
     const descriptorOptions = '[data-cy="descriptor-more-opts-menu"] > .q-list';
     const url = '/#/account/1/summary';
 
@@ -7,6 +7,9 @@ describe('ClaimNotes', () => {
         cy.visit(url);
         cy.dataCy('descriptor-more-opts').click();
         cy.get(descriptorOptions)
+            .should('exist')
+            .should('be.visible')
+
             .find('.q-item')
             .its('length')
             .then((count) => {
diff --git a/test/cypress/integration/claim/claimNotes.spec.js b/test/cypress/integration/claim/claimNotes.spec.js
index ae8b4186c..fa4a214a1 100644
--- a/test/cypress/integration/claim/claimNotes.spec.js
+++ b/test/cypress/integration/claim/claimNotes.spec.js
@@ -1,4 +1,4 @@
-describe.skip('ClaimNotes', () => {
+describe('ClaimNotes', () => {
     const saveBtn = '.q-field__append > .q-btn > .q-btn__content > .q-icon';
     const firstNote = '.q-infinite-scroll :nth-child(1) > .q-card__section--vert';
     beforeEach(() => {
diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js
index 514c50281..6d84f214c 100644
--- a/test/cypress/integration/ticket/ticketSale.spec.js
+++ b/test/cypress/integration/ticket/ticketSale.spec.js
@@ -23,7 +23,7 @@ describe('TicketSale', () => {
 
             cy.get('[data-col-field="price"]')
                 .find('.q-btn > .q-btn__content')
-                .should('have.text', `€${price}`);
+                .should('contain.text', `€${price}`);
         });
         it('update discount', () => {
             const discount = Math.floor(Math.random() * 100) + 1;

From fb00824ee38a257669f297b7a9bafdfe0b628ddd Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Mon, 24 Mar 2025 09:55:03 +0100
Subject: [PATCH 06/28] refactor: refs #8717 change toModule prop type from
 String to Object

---
 src/components/ui/VnDescriptor.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/ui/VnDescriptor.vue b/src/components/ui/VnDescriptor.vue
index 47da98d74..878adcadc 100644
--- a/src/components/ui/VnDescriptor.vue
+++ b/src/components/ui/VnDescriptor.vue
@@ -30,7 +30,7 @@ const $props = defineProps({
         default: null,
     },
     toModule: {
-        type: String,
+        type: Object,
         default: null,
     },
 });

From feabf9c7be8793f881fd0b7abba8426ce0fe62dd Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Mon, 24 Mar 2025 11:19:26 +0100
Subject: [PATCH 07/28] refactor: refs #8717 use markRaw for cardDescriptor in
 VnCard component

---
 src/components/common/VnCard.vue | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 21cdc9df5..50b041060 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onBeforeMount, computed } from 'vue';
+import { onBeforeMount, computed, markRaw } from 'vue';
 import { useRoute, useRouter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router';
 import { useArrayData } from 'src/composables/useArrayData';
 import { useStateStore } from 'stores/useStateStore';
@@ -37,7 +37,7 @@ onBeforeRouteLeave(() => {
 });
 
 onBeforeMount(async () => {
-    stateStore.cardDescriptorChangeValue(props.descriptor);
+    stateStore.cardDescriptorChangeValue(markRaw(props.descriptor));
 
     const route = router.currentRoute.value;
     try {

From 9a2c7c8012b586803437c4ed3e3654c56556ee19 Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Tue, 25 Mar 2025 14:02:13 +0100
Subject: [PATCH 08/28] fix: refs #8717 streamline field filling logic in tests

---
 .../integration/route/routeExtendedList.spec.js | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/test/cypress/integration/route/routeExtendedList.spec.js b/test/cypress/integration/route/routeExtendedList.spec.js
index a183c08cb..fce4753f1 100644
--- a/test/cypress/integration/route/routeExtendedList.spec.js
+++ b/test/cypress/integration/route/routeExtendedList.spec.js
@@ -53,17 +53,20 @@ describe('Route extended list', () => {
     function fillField(selector, type, value) {
         switch (type) {
             case 'select':
-                cy.get(selector).should('be.visible').click();
-                cy.dataCy('null_select').clear().type(value);
+                cy.get(selector).should('be.visible').click().clear().type(value);
                 cy.get('.q-item').contains(value).click();
                 break;
             case 'input':
-                cy.get(selector).should('be.visible').click();
-                cy.dataCy('null_input').clear().type(`${value}`);
+                cy.get(selector)
+                    .should('be.visible')
+                    .click()
+                    .type(`{selectall}{backspace}${value}`);
                 break;
             case 'date':
-                cy.get(selector).should('be.visible').click();
-                cy.dataCy('null_inputDate').clear().type(`${value}`);
+                cy.get(selector)
+                    .should('be.visible')
+                    .click()
+                    .type(`{selectall}{backspace}${value}`);
                 break;
             case 'checkbox':
                 cy.get(selector).should('be.visible').click().click();
@@ -177,7 +180,7 @@ describe('Route extended list', () => {
                 const [month, day, year] = value.split('/');
                 value = `${day}/${month}/${year}`;
             }
-            cy.validateContent(selector, value);
+            cy.get(selector).should('contain', value);
         });
     });
 

From c5a05917c0a990d71470d5e33bce6c74424d0087 Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Wed, 26 Mar 2025 08:50:25 +0100
Subject: [PATCH 09/28] fix: refs #8717 enable RouteAutonomous tests and adjust
 notification check in RouteExtendedList

---
 test/cypress/integration/route/routeAutonomous.spec.js   | 4 ++--
 test/cypress/integration/route/routeExtendedList.spec.js | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js
index 08fd7d7ea..72562259a 100644
--- a/test/cypress/integration/route/routeAutonomous.spec.js
+++ b/test/cypress/integration/route/routeAutonomous.spec.js
@@ -1,4 +1,4 @@
-describe.skip('RouteAutonomous', () => {
+describe('RouteAutonomous', () => {
     const getLinkSelector = (colField) =>
         `tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`;
 
@@ -49,12 +49,12 @@ describe.skip('RouteAutonomous', () => {
         cy.get(selectors.firstRowCheckbox).click();
         cy.get(selectors.createInvoiceBtn).click();
         cy.dataCy(selectors.reference).type(data.reference);
+        cy.dataCy('attachFile').click();
         cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', {
             force: true,
         });
         cy.dataCy(selectors.saveFormBtn).click();
         cy.checkNotification(dataSaved);
-        cy.typeSearchbar('{enter}');
     });
 
     it('Should display the total price of the selected rows', () => {
diff --git a/test/cypress/integration/route/routeExtendedList.spec.js b/test/cypress/integration/route/routeExtendedList.spec.js
index fce4753f1..e6c873d5e 100644
--- a/test/cypress/integration/route/routeExtendedList.spec.js
+++ b/test/cypress/integration/route/routeExtendedList.spec.js
@@ -106,8 +106,8 @@ describe('Route extended list', () => {
         cy.fillInForm(data);
 
         cy.dataCy(selectors.saveFormBtn).click();
-        cy.checkNotification(dataCreated);
         cy.url().should('include', '/summary');
+        cy.checkNotification(dataCreated);
     });
 
     it('Should reset changed values when click reset button', () => {
@@ -143,7 +143,7 @@ describe('Route extended list', () => {
         const downloadsFolder = Cypress.config('downloadsFolder');
         cy.get(selectors.lastRowSelectCheckBox).click();
         cy.get(selectors.downloadBtn).click();
-        cy.wait(5000);
+        cy.wait(3000);
 
         const fileName = 'download.zip';
         cy.readFile(`${downloadsFolder}/${fileName}`).should('exist');

From dd4e872fcca53e22418a9dbf7b3bbec2daea65d7 Mon Sep 17 00:00:00 2001
From: jorgep <jorgep@verdnatura.es>
Date: Wed, 26 Mar 2025 16:00:50 +0100
Subject: [PATCH 10/28] refactor: refs #8718 simplify VnAccountNumber component
 and remove obsolete tests

---
 src/components/common/VnAccountNumber.vue     | 25 +------------
 .../vnComponent/VnAccountNumber.spec.js       | 37 -------------------
 2 files changed, 2 insertions(+), 60 deletions(-)
 delete mode 100644 test/cypress/integration/vnComponent/VnAccountNumber.spec.js

diff --git a/src/components/common/VnAccountNumber.vue b/src/components/common/VnAccountNumber.vue
index 56add7329..8bff3e261 100644
--- a/src/components/common/VnAccountNumber.vue
+++ b/src/components/common/VnAccountNumber.vue
@@ -1,35 +1,14 @@
 <script setup>
-import { nextTick, ref } from 'vue';
 import VnInput from './VnInput.vue';
 import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard';
 
-const $props = defineProps({
-    insertable: {
-        type: Boolean,
-        default: false,
-    },
-});
-
-const emit = defineEmits(['update:modelValue', 'accountShortToStandard']);
 const model = defineModel({ prop: 'modelValue' });
-const inputRef = ref(false);
-
-function setCursorPosition(pos) {
-    const input = inputRef.value.vnInputRef.$el.querySelector('input');
-    input.focus();
-    input.setSelectionRange(pos, pos);
-}
-
-async function handleUpdateModel(val) {
-    model.value = val?.at(-1) === '.' ? useAccountShortToStandard(val) : val;
-    await nextTick(() => setCursorPosition(0));
-}
 </script>
 <template>
     <VnInput
         v-model="model"
         ref="inputRef"
-        :insertable
-        @update:model-value="handleUpdateModel"
+        @keydown.tab="model = useAccountShortToStandard($event.target.value) ?? model"
+        @input="model = $event.target.value.replace(/[^\d.]/g, '')"
     />
 </template>
diff --git a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
deleted file mode 100644
index 053902f35..000000000
--- a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-describe('VnAccountNumber', () => {
-    const accountInput = 'input[data-cy="supplierFiscalDataAccount_input"]';
-    beforeEach(() => {
-        cy.login('developer');
-        cy.viewport(1920, 1080);
-        cy.visit('/#/supplier/1/fiscal-data');
-    });
-
-    describe('VnInput handleInsertMode()', () => {
-        it('should replace character at cursor position in insert mode', () => {
-            cy.get(accountInput).type('{selectall}4100000001');
-            cy.get(accountInput).type('{movetostart}');
-            cy.get(accountInput).type('999');
-            cy.get(accountInput).should('have.value', '9990000001');
-        });
-
-        it('should replace character at cursor position in insert mode', () => {
-            cy.get(accountInput).clear();
-            cy.get(accountInput).type('4100000001');
-            cy.get(accountInput).type('{movetostart}');
-            cy.get(accountInput).type('999');
-            cy.get(accountInput).should('have.value', '9990000001');
-        });
-
-        it('should respect maxlength prop', () => {
-            cy.get(accountInput).clear();
-            cy.get(accountInput).type('123456789012345');
-            cy.get(accountInput).should('have.value', '1234567890');
-        });
-    });
-
-    it('should convert short account number to standard format', () => {
-        cy.get(accountInput).clear();
-        cy.get(accountInput).type('123.');
-        cy.get(accountInput).should('have.value', '1230000000');
-    });
-});

From 67e0791f3480ff279d82c76fa8553bda73cec391 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Thu, 27 Mar 2025 09:03:40 +0100
Subject: [PATCH 11/28] fix: update order list tests to remove only and skip
 modifiers

---
 test/cypress/integration/order/orderList.spec.js | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/test/cypress/integration/order/orderList.spec.js b/test/cypress/integration/order/orderList.spec.js
index 0f04d256b..ee011ea05 100644
--- a/test/cypress/integration/order/orderList.spec.js
+++ b/test/cypress/integration/order/orderList.spec.js
@@ -10,7 +10,7 @@ describe('OrderList', () => {
         cy.visit('/#/order/list');
     });
 
-    it.only('create order', () => {
+    it('create order', () => {
         cy.get('[data-cy="vnTableCreateBtn"]').click();
         cy.selectOption(clientCreateSelect, 1101);
         cy.get(addressCreateSelect).click();
@@ -30,9 +30,11 @@ describe('OrderList', () => {
         cy.url().should('include', `/order`);
     });
 
-    it.skip('filter list and create order', () => {
+    it('filter list and create order', () => {
         cy.dataCy('Customer ID_input').type('1101{enter}');
+        cy.intercept('GET', /\/api\/Clients/).as('clientFilter');
         cy.dataCy('vnTableCreateBtn').click();
+        cy.wait('@clientFilter');
         cy.dataCy('landedDate').find('input').type('06/01/2001');
         cy.selectOption(agencyCreateSelect, 1);
 

From a91a0146fe294d01717a394380e94a9bc9362a35 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Thu, 27 Mar 2025 13:03:21 +0100
Subject: [PATCH 12/28] fix: hasChanges

---
 src/pages/Ticket/Card/TicketSale.vue | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 2fb305cc3..666b5fefe 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -187,7 +187,9 @@ const getRowUpdateInputEvents = (sale) => {
 
 const resetChanges = async () => {
     arrayData.fetch({ append: false });
+    tableRef.value.CrudModelRef.hasChanges = false;
     tableRef.value.reload();
+
     selectedRows.value = [];
 };
 const changeQuantity = async (sale) => {
@@ -390,7 +392,7 @@ const changeTicketState = async (val) => {
     const params = { ticketFk: route.params.id, code: val };
     await axios.post('Tickets/state', params);
     notify('globals.dataSaved', 'positive');
-    await resetChanges();
+    resetChanges();
 };
 
 const removeSelectedSales = () => {

From 6e84341aeade6662684dcbb3292d5bcf3fab8b3e Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Thu, 27 Mar 2025 13:06:29 +0100
Subject: [PATCH 13/28] perf: add await

---
 src/pages/Ticket/Card/TicketSale.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 666b5fefe..96a2dc43f 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -188,7 +188,7 @@ const getRowUpdateInputEvents = (sale) => {
 const resetChanges = async () => {
     arrayData.fetch({ append: false });
     tableRef.value.CrudModelRef.hasChanges = false;
-    tableRef.value.reload();
+    await tableRef.value.reload();
 
     selectedRows.value = [];
 };

From c4ab00ffd21bbffdd3b99ae1b579fd47ae18bf82 Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Thu, 27 Mar 2025 14:56:22 +0100
Subject: [PATCH 14/28] fix: update filter in TravelCard to include route
 parameter

---
 src/pages/Travel/Card/TravelCard.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue
index 479b47fb9..d452f5287 100644
--- a/src/pages/Travel/Card/TravelCard.vue
+++ b/src/pages/Travel/Card/TravelCard.vue
@@ -8,6 +8,6 @@ import filter from './TravelFilter.js';
         data-key="Travel"
         url="Travels"
         :descriptor="TravelDescriptor"
-        :filter="filter"
+        :filter="{ ...filter, where: { id: $route.params.id } }"
     />
 </template>

From 34c18d2baaf2f74db5d6fdb990bf2308471f3460 Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Thu, 27 Mar 2025 15:31:55 +0100
Subject: [PATCH 15/28] test: refs #8717 update invoice creation test to ensure
 save button visibility

---
 test/cypress/integration/route/routeAutonomous.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js
index 72562259a..11d591bdd 100644
--- a/test/cypress/integration/route/routeAutonomous.spec.js
+++ b/test/cypress/integration/route/routeAutonomous.spec.js
@@ -53,7 +53,7 @@ describe('RouteAutonomous', () => {
         cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', {
             force: true,
         });
-        cy.dataCy(selectors.saveFormBtn).click();
+        cy.dataCy(selectors.saveFormBtn).should('be.visible').click();
         cy.checkNotification(dataSaved);
     });
 

From 0aa4c1c527d0bc63ed38e810ce97d3b0fcc8764f Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Thu, 27 Mar 2025 16:12:03 +0100
Subject: [PATCH 16/28] test: refs #8717 skip RouteAutonomous test suite

---
 test/cypress/integration/route/routeAutonomous.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js
index 11d591bdd..d77584c04 100644
--- a/test/cypress/integration/route/routeAutonomous.spec.js
+++ b/test/cypress/integration/route/routeAutonomous.spec.js
@@ -1,4 +1,4 @@
-describe('RouteAutonomous', () => {
+describe.skip('RouteAutonomous', () => {
     const getLinkSelector = (colField) =>
         `tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`;
 

From 2a3e072b1bd95c2484099b04e7e7c24b0bb6d9ab Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Fri, 28 Mar 2025 01:25:38 +0100
Subject: [PATCH 17/28] feat: add departmentFk to user data and filter clients
 by department

---
 src/composables/useRole.js           | 1 +
 src/pages/Monitor/MonitorClients.vue | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/composables/useRole.js b/src/composables/useRole.js
index ff54b409c..e700b1f2e 100644
--- a/src/composables/useRole.js
+++ b/src/composables/useRole.js
@@ -13,6 +13,7 @@ export function useRole() {
             name: data.user.name,
             nickname: data.user.nickname,
             lang: data.user.lang || 'es',
+            departmentFk: data.user.worker.department.departmentFk,
         };
         state.setUser(userData);
         state.setRoles(roles);
diff --git a/src/pages/Monitor/MonitorClients.vue b/src/pages/Monitor/MonitorClients.vue
index c814d623e..99110df16 100644
--- a/src/pages/Monitor/MonitorClients.vue
+++ b/src/pages/Monitor/MonitorClients.vue
@@ -9,12 +9,14 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnRow from 'src/components/ui/VnRow.vue';
 import { dateRange } from 'src/filters';
 import useOpenURL from 'src/composables/useOpenURL';
+import { useState } from 'src/composables/useState';
 const { t } = useI18n();
 
 const dates = dateRange(Date.vnNew());
 const from = ref(dates[0]);
 const to = ref(dates[1]);
 
+const state = useState();
 const filter = computed(() => {
     const obj = {};
     const formatFrom = setHours(from.value, 'from');
@@ -25,7 +27,9 @@ const filter = computed(() => {
     else if (formatFrom && !formatTo) stamp = { gte: formatFrom };
     else if (formatFrom && formatTo) stamp = { between: [formatFrom, formatTo] };
 
-    return Object.assign(obj, { where: { 'v.stamp': stamp } });
+    return Object.assign(obj, {
+        where: { 'v.stamp': stamp, departmentFk: state.getUser().departmentFk },
+    });
 });
 
 function exprBuilder(param, value) {

From c03a56f69fb774c3399f8147bf8e5521da9769ea Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Fri, 28 Mar 2025 09:28:24 +0100
Subject: [PATCH 18/28] feat: refs #7995 added hasAcl to check only one acl

---
 src/composables/useAcl.js                             | 11 +++++++++++
 src/pages/Account/Card/AccountDescriptorMenu.vue      | 10 +++-------
 src/pages/Customer/Card/CustomerBalance.vue           |  6 ++----
 .../Ticket/Card/BasicData/TicketBasicDataForm.vue     |  4 +---
 src/pages/Ticket/Card/TicketSaleMoreActions.vue       |  4 +---
 src/pages/Travel/Card/TravelDescriptorMenuItems.vue   |  2 +-
 src/pages/Worker/Card/WorkerCalendar.vue              |  4 +---
 src/pages/Worker/Card/WorkerLocker.vue                |  8 ++------
 src/pages/Worker/Card/WorkerTimeControl.vue           |  8 ++------
 9 files changed, 24 insertions(+), 33 deletions(-)

diff --git a/src/composables/useAcl.js b/src/composables/useAcl.js
index ede359186..581e553aa 100644
--- a/src/composables/useAcl.js
+++ b/src/composables/useAcl.js
@@ -30,9 +30,20 @@ export function useAcl() {
         return false;
     }
 
+    function hasAcl(model, props, accessType) {
+        const modelAcl = state.getAcls().value[model];
+        const access = modelAcl[props];
+        if (!modelAcl || !access) return false;
+        if (access[accessType] || access['*']) {
+            return true;
+        }
+        return false;
+    }
+
     return {
         fetch,
         hasAny,
         state,
+        hasAcl,
     };
 }
diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue
index eafd62df6..f3eabb531 100644
--- a/src/pages/Account/Card/AccountDescriptorMenu.vue
+++ b/src/pages/Account/Card/AccountDescriptorMenu.vue
@@ -100,12 +100,8 @@ const onChangePass = (oldPass) => {
 };
 
 onMounted(() => {
-    hasitManagementAccess.value = useAcl().hasAny([
-        { model: 'VnUser', props: 'higherPrivileges', accessType: 'WRITE' },
-    ]);
-    hasSysadminAccess.value = useAcl().hasAny([
-        { model: 'VnUser', props: 'adminUser', accessType: 'WRITE' },
-    ]);
+    hasitManagementAccess.value = useAcl().hasAcl('VnUser', 'higherPrivileges', 'WRITE');
+    hasSysadminAccess.value = useAcl().hasAcl('VnUser', 'adminUser', 'WRITE');
 });
 </script>
 <template>
@@ -227,7 +223,7 @@ onMounted(() => {
         <QItemSection>{{ t('account.card.actions.deactivateUser.name') }}</QItemSection>
     </QItem>
     <QItem
-        v-if="useAcl().hasAny([{ model: 'VnRole', props: '*', accessType: 'WRITE' }])"
+        v-if="useAcl().hasAcl('VnRole', '*', 'WRITE')"
         v-ripple
         clickable
         @click="showSyncDialog = true"
diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue
index 11db92eab..eea532de6 100644
--- a/src/pages/Customer/Card/CustomerBalance.vue
+++ b/src/pages/Customer/Card/CustomerBalance.vue
@@ -24,7 +24,7 @@ import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescr
 const { openConfirmationModal } = useVnConfirm();
 const { sendEmail, openReport } = usePrintService();
 const { t } = useI18n();
-const { hasAny } = useAcl();
+const { hasAcl } = useAcl();
 
 const quasar = useQuasar();
 const route = useRoute();
@@ -276,9 +276,7 @@ const showBalancePdf = ({ id }) => {
             >
                 <VnInput
                     v-model="scope.value"
-                    :disable="
-                        !hasAny([{ model: 'Receipt', props: '*', accessType: 'WRITE' }])
-                    "
+                    :disable="!hasAcl('Receipt', '*', 'WRITE')"
                     @keypress.enter="scope.set"
                     autofocus
                 />
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
index 9d70fea38..61932468c 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
@@ -25,9 +25,7 @@ const { validate } = useValidator();
 const { notify } = useNotify();
 const router = useRouter();
 const { t } = useI18n();
-const canEditZone = useAcl().hasAny([
-    { model: 'Ticket', props: 'editZone', accessType: 'WRITE' },
-]);
+const canEditZone = useAcl().hasAcl('Ticket', 'editZone', 'WRITE');
 
 const agencyFetchRef = ref();
 const warehousesOptions = ref([]);
diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
index 773b0807f..864bfd03f 100644
--- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue
+++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
@@ -55,9 +55,7 @@ const isClaimable = computed(() => {
     if (ticket.value) {
         const landedPlusWeek = new Date(ticket.value.landed);
         landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
-        const createAfterDeadline = acl.hasAny([
-            { model: 'Claim', props: 'createAfterDeadline', accessType: 'WRITE' },
-        ]);
+        const createAfterDeadline = acl.hasAcl('Claim', 'createAfterDeadline', 'WRITE');
         return landedPlusWeek >= Date.vnNew() || createAfterDeadline;
     }
     return false;
diff --git a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
index 14d824b86..f8828bffe 100644
--- a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
+++ b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
@@ -37,7 +37,7 @@ const cloneTravelWithEntries = async () => {
     router.push({ name: 'TravelBasicData', params: { id: data.id } });
 };
 
-const canDelete = computed(() => useAcl().hasAny('Travel', '*', 'WRITE'));
+const canDelete = computed(() => useAcl().hasAcl('Travel', '*', 'WRITE'));
 
 const openDeleteEntryDialog = (id) => {
     quasar
diff --git a/src/pages/Worker/Card/WorkerCalendar.vue b/src/pages/Worker/Card/WorkerCalendar.vue
index df4616011..05ebb4687 100644
--- a/src/pages/Worker/Card/WorkerCalendar.vue
+++ b/src/pages/Worker/Card/WorkerCalendar.vue
@@ -18,9 +18,7 @@ const router = useRouter();
 const route = useRoute();
 const { t } = useI18n();
 const acl = useAcl();
-const canSeeNotes = computed(() =>
-    acl.hasAny([{ model: 'Worker', props: '__get__business', accessType: 'READ' }]),
-);
+const canSeeNotes = computed(() => acl.hasAcl('Worker', '__get__business', 'READ'));
 const workerIsFreelance = ref();
 const WorkerFreelanceRef = ref();
 const workerCalendarFilterRef = ref(null);
diff --git a/src/pages/Worker/Card/WorkerLocker.vue b/src/pages/Worker/Card/WorkerLocker.vue
index 015bced35..62891070d 100644
--- a/src/pages/Worker/Card/WorkerLocker.vue
+++ b/src/pages/Worker/Card/WorkerLocker.vue
@@ -9,7 +9,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import { useArrayData } from 'src/composables/useArrayData';
 import FetchData from 'components/FetchData.vue';
 
-const { hasAny } = useAcl();
+const { hasAcl } = useAcl();
 const { t } = useI18n();
 const fetchData = ref();
 const originaLockerId = ref();
@@ -58,11 +58,7 @@ const init = async (data) => {
                 option-label="code"
                 option-value="id"
                 hide-selected
-                :readonly="
-                    !hasAny([
-                        { model: 'Worker', props: '__get__locker', accessType: 'READ' },
-                    ])
-                "
+                :readonly="!hasAcl('Worker', '__get__locker', 'READ')"
             />
         </template>
     </FormModel>
diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue
index 9c0fa6758..b64166c7d 100644
--- a/src/pages/Worker/Card/WorkerTimeControl.vue
+++ b/src/pages/Worker/Card/WorkerTimeControl.vue
@@ -68,13 +68,9 @@ const arrayData = useArrayData('Worker');
 const acl = useAcl();
 const selectedDateYear = computed(() => moment(selectedDate.value).isoWeekYear());
 const worker = computed(() => arrayData.store?.data);
-const canSend = computed(() =>
-    acl.hasAny([{ model: 'WorkerTimeControl', props: 'sendMail', accessType: 'WRITE' }]),
-);
+const canSend = computed(() => acl.hasAcl('WorkerTimeControl', 'sendMail', 'WRITE'));
 const canUpdate = computed(() =>
-    acl.hasAny([
-        { model: 'WorkerTimeControl', props: 'updateMailState', accessType: 'WRITE' },
-    ]),
+    acl.hasAcl('WorkerTimeControl', 'updateMailState', 'WRITE'),
 );
 const isHimself = computed(() => user.value.id === Number(route.params.id));
 

From a49c8891a743d0e73162e1dbea0e05a385eb91cc Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Fri, 28 Mar 2025 10:22:08 +0100
Subject: [PATCH 19/28] fix: params.departmentFk i18n and
 ticketFilter.groupedStates

---
 src/pages/Claim/ClaimFilter.vue               |  2 ++
 src/pages/Customer/CustomerFilter.vue         |  2 ++
 .../Defaulter/CustomerDefaulterFilter.vue     |  2 ++
 src/pages/Order/Card/OrderFilter.vue          |  2 ++
 src/pages/Ticket/TicketFilter.vue             | 29 +++++--------------
 src/pages/Worker/WorkerFilter.vue             |  3 ++
 6 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/src/pages/Claim/ClaimFilter.vue b/src/pages/Claim/ClaimFilter.vue
index 37146865c..d86a233b5 100644
--- a/src/pages/Claim/ClaimFilter.vue
+++ b/src/pages/Claim/ClaimFilter.vue
@@ -122,6 +122,7 @@ const props = defineProps({
 <i18n>
 en:
     params:
+        departmentFk: Department
         search: Contains
         clientFk: Customer
         clientName: Customer
@@ -134,6 +135,7 @@ en:
         zoneFk: Zone
 es:
     params:
+        departmentFk: Departamento
         search: Contiene
         clientFk: Cliente
         clientName: Cliente
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index 2ace6dd02..6231036c0 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -163,6 +163,7 @@ en:
         email: Email
         isToBeMailed: Mailed
         isEqualizated: Equailized
+        departmentFk: Department
         businessTypeFk: Business type
         sageTaxTypeFk: Sage Tax Type
         sageTransactionTypeFk: Sage Tax Type
@@ -173,6 +174,7 @@ en:
         postcode: Postcode
 es:
     params:
+        departmentFk: Departamento
         search: Contiene
         fi: NIF
         isActive: Activo
diff --git a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue
index 0eab7b7c5..c391e4c64 100644
--- a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue
+++ b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue
@@ -196,8 +196,10 @@ en:
         date: L. O. Date
         credit: Credit I.
         defaulterSinced: From
+        departmentFk: Department
 es:
     params:
+        departmentFk: Departamento
         clientFk: Cliente
         countryFk: País
         paymentMethod: F. Pago
diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue
index 42578423f..362afd044 100644
--- a/src/pages/Order/Card/OrderFilter.vue
+++ b/src/pages/Order/Card/OrderFilter.vue
@@ -141,8 +141,10 @@ en:
     myTeam: My Team
     isConfirmed: Order Confirmed
     showEmpty: Show Empty
+    departmentFk: Department
 es:
     params:
+        departmentFk: Departamento
         search: Búsqueda
         clientFk: Cliente
         agencyModeFk: Agencia
diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue
index f959157f6..318b27b13 100644
--- a/src/pages/Ticket/TicketFilter.vue
+++ b/src/pages/Ticket/TicketFilter.vue
@@ -22,16 +22,6 @@ const states = ref([]);
 const agencies = ref([]);
 const warehouses = ref([]);
 const groupedStates = ref([]);
-
-const getGroupedStates = (data) => {
-    for (const state of data) {
-        groupedStates.value.push({
-            id: state.id,
-            name: t(`${state.code}`),
-            code: state.code,
-        });
-    }
-};
 </script>
 
 <template>
@@ -39,12 +29,11 @@ const getGroupedStates = (data) => {
     <FetchData url="States" @on-fetch="(data) => (states = data)" auto-load />
     <FetchData
         url="AlertLevels"
-        @on-fetch="
-            (data) => {
-                getGroupedStates(data);
-            }
-        "
         auto-load
+        @on-fetch="
+            (data) =>
+                (groupedStates = data.map((x) => Object.assign(x, { code: t(x.code) })))
+        "
     />
     <FetchData
         url="AgencyModes"
@@ -136,19 +125,17 @@ const getGroupedStates = (data) => {
                 </QItemSection>
                 <QItemSection v-if="groupedStates">
                     <VnSelect
-                        :label="t('Grouped state')"
+                        :label="t('params.groupedStates')"
                         v-model="params.groupedStates"
                         @update:model-value="searchFn()"
                         :options="groupedStates"
-                        option-value="id"
-                        option-label="name"
+                        option-label="code"
                         emit-value
                         map-options
                         use-input
                         dense
                         outlined
                         rounded
-                        sort-by="name ASC"
                     />
                 </QItemSection>
             </QItem>
@@ -326,7 +313,7 @@ en:
     ON_PREPARATION: On preparation
     PACKED: Packed
     DELIVERED: Delivered
-    ON_PREVIOUS: ON_PREVIOUS
+    ON_PREVIOUS: On previous
 es:
     params:
         search: Contiene
@@ -371,7 +358,7 @@ es:
     ON_PREPARATION: En preparación
     PACKED: Encajado
     DELIVERED: Servido
-    ON_PREVIOUS: ON_PREVIOUS
+    ON_PREVIOUS: En previa
     Collection: Colección
     Nickname: Nombre mostrado
 </i18n>
diff --git a/src/pages/Worker/WorkerFilter.vue b/src/pages/Worker/WorkerFilter.vue
index 8210ba0e3..adddacd28 100644
--- a/src/pages/Worker/WorkerFilter.vue
+++ b/src/pages/Worker/WorkerFilter.vue
@@ -119,8 +119,11 @@ en:
         lastName: Last name
         userName: User
         extension: Extension
+        departmentFk: Department
 es:
+
     params:
+        departmentFk: Departamento
         search: Contiene
         firstName: Nombre
         lastName: Apellidos

From 50fb8a31a68c83e6adfa0b16e59eb8bdf88e5d20 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Fri, 28 Mar 2025 12:03:15 +0100
Subject: [PATCH 20/28] test: fix test

---
 src/composables/__tests__/useRole.spec.js    | 7 ++++---
 src/composables/__tests__/useSession.spec.js | 7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/composables/__tests__/useRole.spec.js b/src/composables/__tests__/useRole.spec.js
index d0bca5342..54d983a13 100644
--- a/src/composables/__tests__/useRole.spec.js
+++ b/src/composables/__tests__/useRole.spec.js
@@ -23,18 +23,19 @@ describe('useRole', () => {
                 name: `T'Challa`,
                 nickname: 'Black Panther',
                 lang: 'en',
+                worker: { department: { departmentFk: 155 } },
             };
             const expectedUser = {
                 id: 999,
                 name: `T'Challa`,
                 nickname: 'Black Panther',
                 lang: 'en',
+                departmentFk: 155,
             };
             const expectedRoles = ['salesPerson', 'admin'];
-            vi.spyOn(axios, 'get')
-            .mockResolvedValueOnce({
+            vi.spyOn(axios, 'get').mockResolvedValueOnce({
                 data: { roles: rolesData, user: fetchedUser },
-            })
+            });
 
             vi.spyOn(role.state, 'setUser');
             vi.spyOn(role.state, 'setRoles');
diff --git a/src/composables/__tests__/useSession.spec.js b/src/composables/__tests__/useSession.spec.js
index 789b149ec..cae33f893 100644
--- a/src/composables/__tests__/useSession.spec.js
+++ b/src/composables/__tests__/useSession.spec.js
@@ -75,6 +75,7 @@ describe('session', () => {
                 userConfig: {
                     darkMode: false,
                 },
+                worker: { department: { departmentFk: 155 } },
             };
             const rolesData = [
                 {
@@ -143,7 +144,7 @@ describe('session', () => {
                 await session.destroy(); // this clears token and user for any other test
             });
         },
-        {}
+        {},
     );
 
     describe('RenewToken', () => {
@@ -175,7 +176,7 @@ describe('session', () => {
             await session.checkValidity();
             expect(sessionStorage.getItem('token')).toEqual(expectedToken);
             expect(sessionStorage.getItem('tokenMultimedia')).toEqual(
-                expectedTokenMultimedia
+                expectedTokenMultimedia,
             );
         });
         it('Should renewToken', async () => {
@@ -204,7 +205,7 @@ describe('session', () => {
             await session.checkValidity();
             expect(sessionStorage.getItem('token')).not.toEqual(expectedToken);
             expect(sessionStorage.getItem('tokenMultimedia')).not.toEqual(
-                expectedTokenMultimedia
+                expectedTokenMultimedia,
             );
         });
     });

From 4fbcb822347040044e28a92ec7e55bf3fc391cc6 Mon Sep 17 00:00:00 2001
From: jtubau <jtubau@verdnatura.es>
Date: Fri, 28 Mar 2025 13:20:02 +0100
Subject: [PATCH 21/28] fix: refs #8717 update AgencyCard to include filter by
 agency ID and correct locale key casing

---
 src/pages/Route/Agency/Card/AgencyCard.vue | 2 +-
 src/pages/Route/locale/en.yml              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pages/Route/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue
index c21298470..9fd3fe5e5 100644
--- a/src/pages/Route/Agency/Card/AgencyCard.vue
+++ b/src/pages/Route/Agency/Card/AgencyCard.vue
@@ -3,5 +3,5 @@ import AgencyDescriptor from 'pages/Route/Agency/Card/AgencyDescriptor.vue';
 import VnCard from 'src/components/common/VnCard.vue';
 </script>
 <template>
-    <VnCard data-key="Agency" url="Agencies" :descriptor="AgencyDescriptor" />
+    <VnCard data-key="Agency" url="Agencies" :descriptor="AgencyDescriptor" :filter="{ where: { id: $route.params.id } }" />
 </template>
diff --git a/src/pages/Route/locale/en.yml b/src/pages/Route/locale/en.yml
index 283b61855..e7e2d691e 100644
--- a/src/pages/Route/locale/en.yml
+++ b/src/pages/Route/locale/en.yml
@@ -50,7 +50,7 @@ route:
         agencyAgreement: Agency agreement
         agencyModeName: Agency route
         isOwn: Own
-        isAnyVolumeallowed: Any volume allowed
+        isAnyVolumeAllowed: Any volume allowed
     Worker: Worker
     Agency: Agency
     Vehicle: Vehicle

From d60d7da33c756b36c0dc1bdb2390c20eca5f0b84 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Fri, 28 Mar 2025 14:31:11 +0100
Subject: [PATCH 22/28] fix: improve monitorClient.department

---
 src/pages/Monitor/MonitorClients.vue | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/src/pages/Monitor/MonitorClients.vue b/src/pages/Monitor/MonitorClients.vue
index 99110df16..2ba5f4c0b 100644
--- a/src/pages/Monitor/MonitorClients.vue
+++ b/src/pages/Monitor/MonitorClients.vue
@@ -26,9 +26,11 @@ const filter = computed(() => {
     if (!formatFrom && formatTo) stamp = { lte: formatTo };
     else if (formatFrom && !formatTo) stamp = { gte: formatFrom };
     else if (formatFrom && formatTo) stamp = { between: [formatFrom, formatTo] };
-
     return Object.assign(obj, {
-        where: { 'v.stamp': stamp, departmentFk: state.getUser().departmentFk },
+        where: {
+            'v.stamp': stamp,
+            'c.departmentFk': state.getUser().value.departmentFk,
+        },
     });
 });
 
@@ -36,8 +38,6 @@ function exprBuilder(param, value) {
     switch (param) {
         case 'clientFk':
             return { [`c.id`]: value };
-        case 'departmentFk':
-            return { [`c.${param}`]: value };
     }
 }
 
@@ -70,9 +70,13 @@ const columns = computed(() => [
         align: 'left',
         name: 'departmentFk',
         label: t('customer.summary.team'),
-        component: 'select',
-        attrs: {
-            url: 'Departments',
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'Departments',
+            },
+            alias: 'c',
+            inWhere: true,
         },
         columnField: {
             component: null,

From f8cc7b95abe28463859b7e02e7daf705330f38e5 Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Mon, 31 Mar 2025 09:51:40 +0200
Subject: [PATCH 23/28] refactor: refs #7995 modified hasAcl function

---
 src/composables/useAcl.js | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/composables/useAcl.js b/src/composables/useAcl.js
index 581e553aa..4033ee9a6 100644
--- a/src/composables/useAcl.js
+++ b/src/composables/useAcl.js
@@ -32,12 +32,13 @@ export function useAcl() {
 
     function hasAcl(model, props, accessType) {
         const modelAcl = state.getAcls().value[model];
-        const access = modelAcl[props];
-        if (!modelAcl || !access) return false;
-        if (access[accessType] || access['*']) {
-            return true;
-        }
-        return false;
+        const propAcl = modelAcl[props] || {};
+        return !!(
+            propAcl[accessType] ||
+            modelAcl['*']?.[accessType] ||
+            propAcl['*'] ||
+            modelAcl['*']?.['*']
+        );
     }
 
     return {

From ba2084e90686d6467438ea97992b5d8efbea38db Mon Sep 17 00:00:00 2001
From: pablone <pablone@verdnatura.es>
Date: Mon, 31 Mar 2025 12:30:16 +0200
Subject: [PATCH 24/28] refactor: update TravelSummary and TravelList
 components for improved data fetching and summary view

---
 src/pages/Travel/Card/TravelSummary.vue | 29 ++++++++++---------------
 src/pages/Travel/TravelList.vue         |  2 +-
 2 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index 5a824ddc3..dbb997ccb 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -268,13 +268,6 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
 </script>
 
 <template>
-    <FetchData
-        url="Warehouses"
-        :filter="{ fields: ['id', 'name'] }"
-        order="name"
-        @on-fetch="(data) => (warehouses = data)"
-        auto-load
-    />
     <CardSummary
         ref="summaryRef"
         :url="`Travels/${entityId}/getTravel`"
@@ -414,18 +407,18 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
                     </template>
                 </QTable>
             </QCard>
-
             <QCard class="full-width" v-if="thermographs.length > 0">
-                <RouterLink
-                    class="header header-link"
-                    :to="{
-                        name: 'TravelThermographsIndex',
-                        params: { id: travel.id },
-                    }"
-                >
-                    {{ t('travel.summary.thermographs') }}
-                    <QIcon name="open_in_new" />
-                </RouterLink>
+                <FetchData
+                    url="Warehouses"
+                    :filter="{ fields: ['id', 'name'] }"
+                    order="name"
+                    @on-fetch="(data) => (warehouses = data)"
+                    auto-load
+                />
+                <VnTitle
+                    :url="getLink('thermographs')"
+                    :text="t('travel.summary.thermographs')"
+                />
                 <QTable
                     :rows="thermographs"
                     :columns="thermographsTableColumns"
diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue
index b227afcb2..32ddc639a 100644
--- a/src/pages/Travel/TravelList.vue
+++ b/src/pages/Travel/TravelList.vue
@@ -201,7 +201,7 @@ const columns = computed(() => [
             {
                 title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
-                action: (row) => viewSummary(row.id, TravelSummary),
+                action: (row) => viewSummary(row.id, TravelSummary, 'lg-width'),
                 isPrimary: true,
             },
         ],

From 044c60740598262ff5df383b53a63415d18bb401 Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Tue, 1 Apr 2025 08:32:58 +0200
Subject: [PATCH 25/28] chore: update version to 25.16.0 in package.json

---
 package.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index 017412ef2..366e4bd36 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "salix-front",
-    "version": "25.14.0",
+    "version": "25.16.0",
     "description": "Salix frontend",
     "productName": "Salix",
     "author": "Verdnatura",
@@ -76,4 +76,4 @@
         "vite": "^6.0.11",
         "vitest": "^0.31.1"
     }
-}
\ No newline at end of file
+}

From b00d89a4bee022b8810ff7b308332e8691cce30f Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Tue, 1 Apr 2025 09:34:38 +0200
Subject: [PATCH 26/28] perf: refs #7995 has acl function

---
 src/composables/useAcl.js | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/src/composables/useAcl.js b/src/composables/useAcl.js
index 4033ee9a6..52704fee9 100644
--- a/src/composables/useAcl.js
+++ b/src/composables/useAcl.js
@@ -30,15 +30,10 @@ export function useAcl() {
         return false;
     }
 
-    function hasAcl(model, props, accessType) {
+    function hasAcl(model, prop, accessType) {
         const modelAcl = state.getAcls().value[model];
-        const propAcl = modelAcl[props] || {};
-        return !!(
-            propAcl[accessType] ||
-            modelAcl['*']?.[accessType] ||
-            propAcl['*'] ||
-            modelAcl['*']?.['*']
-        );
+        const propAcl = modelAcl?.[prop] || modelAcl?.['*'];
+        return !!(propAcl?.[accessType] || propAcl?.['*']);
     }
 
     return {

From da148c54352a7f8284e73cd628f2b2e47ae5469d Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Tue, 1 Apr 2025 11:56:05 +0200
Subject: [PATCH 27/28] test: skip invoice deletion test and add spinner waits
 in VnShortcuts

---
 test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js | 2 +-
 test/cypress/integration/vnComponent/VnShortcut.spec.js        | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
index 7058e154c..fdaa01876 100644
--- a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
@@ -13,7 +13,7 @@ describe('InvoiceInDescriptor', () => {
             cy.validateCheckbox(checkbox, false);
         });
 
-        it('should delete the invoice properly', () => {
+        it.skip('should delete the invoice properly', () => {
             cy.visit('/#/invoice-in/2/summary');
             cy.selectDescriptorOption(2);
             cy.clickConfirm();
diff --git a/test/cypress/integration/vnComponent/VnShortcut.spec.js b/test/cypress/integration/vnComponent/VnShortcut.spec.js
index e08c44635..fa05e2e3d 100644
--- a/test/cypress/integration/vnComponent/VnShortcut.spec.js
+++ b/test/cypress/integration/vnComponent/VnShortcut.spec.js
@@ -27,12 +27,15 @@ describe('VnShortcuts', () => {
                 code: `Key${shortcut.toUpperCase()}`,
             });
 
+            cy.waitSpinner();
             cy.url().should('include', module);
             if (['monitor', 'claim'].includes(module)) {
                 return;
             }
             cy.waitForElement('.q-page').should('exist');
             cy.dataCy('vnTableCreateBtn').should('exist');
+            cy.waitSpinner();
+
             cy.get('.q-page').trigger('keydown', {
                 ctrlKey: true,
                 altKey: true,

From 590afaba93afe428ab754552b8ac860083097d20 Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Tue, 1 Apr 2025 12:39:26 +0200
Subject: [PATCH 28/28] fix: update condition for rendering QChip in VnOrder
 component

---
 src/components/VnTable/VnOrder.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/VnTable/VnOrder.vue b/src/components/VnTable/VnOrder.vue
index d39fc8641..fe071a57f 100644
--- a/src/components/VnTable/VnOrder.vue
+++ b/src/components/VnTable/VnOrder.vue
@@ -70,7 +70,7 @@ function textAlignToFlex(textAlign) {
         :style="textAlignToFlex(align)"
     >
         <span :title="label">{{ label }}</span>
-        <div v-if="name">
+        <div v-if="name && (model?.index || vertical)">
             <QChip
                 :label="!vertical ? model?.index : ''"
                 :icon="