From 3783cdeed4313fe907d48842d90841f89c8348bd Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Wed, 26 Mar 2025 12:03:46 +0100
Subject: [PATCH 01/23] fix: fixed buttons disabled when there are no changes

---
 src/pages/Customer/components/CustomerAddressEdit.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index f852c160a..88abcaa77 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -180,7 +180,7 @@ function handleLocation(data, location) {
     <FetchData @on-fetch="getData" auto-load url="ObservationTypes" />
 
     <FormModel
-        :observe-form-changes="false"
+        observe-form-changes
         :url-update="urlUpdate"
         :url="`Addresses/${route.params.addressId}`"
         :save-fn="handleDialog"

From ae9cc49addbf7617e33ff8fd664e8b9c67e0bb48 Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Wed, 26 Mar 2025 12:32:22 +0100
Subject: [PATCH 02/23] refactor: manage every nullable option

---
 .../Customer/components/CustomerAddressEdit.vue      | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index 88abcaa77..1f7b4c1e8 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -93,10 +93,20 @@ const updateAddressTicket = async () => {
 };
 
 const updateObservations = async (payload) => {
+    if (isPayloadEmpty(payload)) return;
     await axios.post('AddressObservations/crud', payload);
     notes.value = [];
     deletes.value = [];
 };
+
+function isPayloadEmpty(payload) {
+    return ['creates', 'deletes', 'updates'].every(
+        (prop) =>
+            !payload[prop] ||
+            payload[prop].length === 0 ||
+            payload[prop].every((item) => item === undefined || item === null),
+    );
+}
 async function updateAll({ data, payload }) {
     await updateObservations(payload);
     await updateAddress(data);
@@ -180,7 +190,7 @@ function handleLocation(data, location) {
     <FetchData @on-fetch="getData" auto-load url="ObservationTypes" />
 
     <FormModel
-        observe-form-changes
+        :observe-form-changes="false"
         :url-update="urlUpdate"
         :url="`Addresses/${route.params.addressId}`"
         :save-fn="handleDialog"

From a3b109595205b0bfc556ac8c5b1621c1e966ad79 Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Wed, 26 Mar 2025 13:51:03 +0100
Subject: [PATCH 03/23] refactor: clean payload

---
 .../components/CustomerAddressEdit.vue        | 24 ++++++++++++-------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index 1f7b4c1e8..c89e7e2e9 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -93,20 +93,28 @@ const updateAddressTicket = async () => {
 };
 
 const updateObservations = async (payload) => {
-    if (isPayloadEmpty(payload)) return;
+    cleanPayload(payload);
     await axios.post('AddressObservations/crud', payload);
     notes.value = [];
     deletes.value = [];
 };
 
-function isPayloadEmpty(payload) {
-    return ['creates', 'deletes', 'updates'].every(
-        (prop) =>
-            !payload[prop] ||
-            payload[prop].length === 0 ||
-            payload[prop].every((item) => item === undefined || item === null),
-    );
+function cleanPayload(payload) {
+    ['creates', 'deletes', 'updates'].forEach((prop) => {
+        if (prop === 'creates' || prop === 'updates') {
+            payload[prop] = payload[prop].filter(
+                (item) => item.description !== '' && item.observationTypeFk !== '',
+            );
+        }
+        if (prop === 'deletes') {
+            payload[prop] = payload[prop].filter(
+                (item) => item !== null && item !== undefined,
+            );
+        }
+        return payload[prop];
+    });
 }
+
 async function updateAll({ data, payload }) {
     await updateObservations(payload);
     await updateAddress(data);

From e353f7916af14d781fc5eb23bead0a231bba20e9 Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Wed, 26 Mar 2025 14:15:01 +0100
Subject: [PATCH 04/23] perf: clean payload

---
 src/pages/Customer/components/CustomerAddressEdit.vue | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index c89e7e2e9..31a930341 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -105,8 +105,7 @@ function cleanPayload(payload) {
             payload[prop] = payload[prop].filter(
                 (item) => item.description !== '' && item.observationTypeFk !== '',
             );
-        }
-        if (prop === 'deletes') {
+        } else {
             payload[prop] = payload[prop].filter(
                 (item) => item !== null && item !== undefined,
             );

From 60899ef2d255f6bf9443121de25ece33fdc64316 Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Thu, 27 Mar 2025 15:03:11 +0100
Subject: [PATCH 05/23] perf: clean payload

---
 src/pages/Customer/components/CustomerAddressEdit.vue | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index 31a930341..bc76f5985 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -93,8 +93,7 @@ const updateAddressTicket = async () => {
 };
 
 const updateObservations = async (payload) => {
-    cleanPayload(payload);
-    await axios.post('AddressObservations/crud', payload);
+    await axios.post('AddressObservations/crud', cleanPayload(payload));
     notes.value = [];
     deletes.value = [];
 };
@@ -110,8 +109,8 @@ function cleanPayload(payload) {
                 (item) => item !== null && item !== undefined,
             );
         }
-        return payload[prop];
     });
+    return payload;
 }
 
 async function updateAll({ data, payload }) {

From 36f142800f04b6549b599ebc6633cc1dad5a8165 Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Mon, 31 Mar 2025 09:51:36 +0200
Subject: [PATCH 06/23] refactor: simplify data fetching logic in VnCard.vue

---
 src/components/common/VnCard.vue | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 21cdc9df5..569fdfe87 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -26,11 +26,7 @@ const route = useRoute();
 const stateStore = useStateStore();
 const router = useRouter();
 const entityId = computed(() => props.id || route?.params?.id);
-const arrayData = useArrayData(props.dataKey, {
-    url: props.url,
-    userFilter: props.filter,
-    oneRecord: true,
-});
+let arrayData = getArrayData();
 
 onBeforeRouteLeave(() => {
     stateStore.cardDescriptorChangeValue(null);
@@ -61,16 +57,31 @@ onBeforeRouteUpdate(async (to, from) => {
 });
 
 async function fetch(id, append = false) {
-    const regex = /\/(\d+)/;
     if (props.idInWhere) arrayData.store.filter.where = { id };
-    else if (!regex.test(props.url)) arrayData.store.url = `${props.url}/${id}`;
-    else arrayData.store.url = props.url.replace(regex, `/${id}`);
+    else {
+        arrayData = getArrayData();
+    }
     await arrayData.fetch({ append, updateRouter: false });
     emit('onFetch', arrayData.store.data);
 }
 function hasRouteParam(params, valueToCheck = ':addressId') {
     return Object.values(params).includes(valueToCheck);
 }
+
+function formatUrl(id) {
+    const newId = id || entityId.value;
+    const regex = /\/(\d+)/;
+    if (!regex.test(props.url)) return `${props.url}/${newId}`;
+    return props.url.replace(regex, `/${newId}`);
+}
+
+function getArrayData() {
+    return useArrayData(props.dataKey, {
+        url: formatUrl(),
+        userFilter: props.filter,
+        oneRecord: true,
+    });
+}
 </script>
 <template>
     <template v-if="visual">

From 95950b748540e0d8cf074e95c3c735819e386681 Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Mon, 31 Mar 2025 13:27:28 +0200
Subject: [PATCH 07/23] refactor(VnCard): use prop.url when init

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

diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 569fdfe87..39c0b2e00 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -26,7 +26,7 @@ const route = useRoute();
 const stateStore = useStateStore();
 const router = useRouter();
 const entityId = computed(() => props.id || route?.params?.id);
-let arrayData = getArrayData();
+let arrayData = getArrayData(props.url);
 
 onBeforeRouteLeave(() => {
     stateStore.cardDescriptorChangeValue(null);
@@ -75,9 +75,9 @@ function formatUrl(id) {
     return props.url.replace(regex, `/${newId}`);
 }
 
-function getArrayData() {
+function getArrayData(url = formatUrl()) {
     return useArrayData(props.dataKey, {
-        url: formatUrl(),
+        url,
         userFilter: props.filter,
         oneRecord: true,
     });

From 5ade9fd13332fe89388d6c3206c6cea86fb25f9e Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Mon, 31 Mar 2025 14:43:00 +0200
Subject: [PATCH 08/23] fix: add trycatch to handle notifications

---
 src/pages/Ticket/Card/TicketSale.vue | 148 +++++++++++++++------------
 1 file changed, 84 insertions(+), 64 deletions(-)

diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 96a2dc43f..abcc2196d 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, computed, watch } from 'vue';
+import { onMounted, ref, computed, watch, inject } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter, useRoute } from 'vue-router';
 import { useQuasar } from 'quasar';
@@ -25,7 +25,7 @@ import VnTable from 'src/components/VnTable/VnTable.vue';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import TicketProblems from 'src/components/TicketProblems.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
-
+const app = inject('app');
 const route = useRoute();
 const router = useRouter();
 const { t } = useI18n();
@@ -196,13 +196,17 @@ const changeQuantity = async (sale) => {
     if (!sale.itemFk || sale.quantity == null || sale?.originalQuantity === sale.quantity)
         return;
     else sale.originalQuantity = sale.quantity;
-    if (!sale.id) return addSale(sale);
+    try {
+        if (!sale.id) await addSale(sale);
+    } catch (e) {
+        app.config.errorHandler(e);
+        return;
+    }
 
     if (await isSalePrepared(sale)) {
         await confirmUpdate(() => updateQuantity(sale));
     } else await updateQuantity(sale);
 };
-
 const updateQuantity = async (sale) => {
     try {
         let { quantity, id } = sale;
@@ -215,7 +219,7 @@ const updateQuantity = async (sale) => {
             (s) => s.id === sale.id,
         );
         sale.quantity = quantity;
-        throw e;
+        app.config.errorHandler(e);
     }
 };
 
@@ -224,24 +228,27 @@ const addSale = async (sale) => {
         barcode: sale.itemFk,
         quantity: sale.quantity,
     };
+    try {
+        const { data } = await axios.post(`tickets/${route.params.id}/addSale`, params);
 
-    const { data } = await axios.post(`tickets/${route.params.id}/addSale`, params);
+        if (!data) return;
 
-    if (!data) return;
+        const newSale = data;
+        sale.id = newSale.id;
+        sale.image = newSale.item.image;
+        sale.subName = newSale.item.subName;
+        sale.concept = newSale.concept;
+        sale.quantity = newSale.quantity;
+        sale.discount = newSale.discount;
+        sale.price = newSale.price;
+        sale.item = newSale.item;
 
-    const newSale = data;
-    sale.id = newSale.id;
-    sale.image = newSale.item.image;
-    sale.subName = newSale.item.subName;
-    sale.concept = newSale.concept;
-    sale.quantity = newSale.quantity;
-    sale.discount = newSale.discount;
-    sale.price = newSale.price;
-    sale.item = newSale.item;
-
-    notify('globals.dataSaved', 'positive');
-    sale.isNew = false;
-    resetChanges();
+        notify('globals.dataSaved', 'positive');
+        sale.isNew = false;
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 const changeConcept = async (sale) => {
     if (await isSalePrepared(sale)) {
@@ -250,10 +257,14 @@ const changeConcept = async (sale) => {
 };
 
 const updateConcept = async (sale) => {
-    const data = { newConcept: sale.concept };
-    await axios.post(`Sales/${sale.id}/updateConcept`, data);
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        const data = { newConcept: sale.concept };
+        await axios.post(`Sales/${sale.id}/updateConcept`, data);
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const DEFAULT_EDIT = {
@@ -264,18 +275,6 @@ const DEFAULT_EDIT = {
     oldQuantity: null,
 };
 const edit = ref({ ...DEFAULT_EDIT });
-const usesMana = ref(null);
-
-const getUsesMana = async () => {
-    const { data } = await axios.get('Sales/usesMana');
-    usesMana.value = data;
-};
-
-const getMana = async () => {
-    const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`);
-    mana.value = data;
-    await getUsesMana();
-};
 
 const selectedValidSales = computed(() => {
     if (!sales.value) return;
@@ -312,11 +311,15 @@ const changePrice = async (sale) => {
     }
 };
 const updatePrice = async (sale, newPrice) => {
-    await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
-    sale.price = newPrice;
-    edit.value = { ...DEFAULT_EDIT };
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
+        sale.price = newPrice;
+        edit.value = { ...DEFAULT_EDIT };
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const changeDiscount = async (sale) => {
@@ -339,15 +342,20 @@ const updateDiscounts = async (sales, newDiscount) => {
 };
 
 const updateDiscount = async (sales, newDiscount = 0) => {
-    const salesIds = sales.map(({ id }) => id);
-    const params = {
-        salesIds,
-        newDiscount,
-        manaCode: manaCode.value,
-    };
-    await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        const salesIds = sales.map(({ id }) => id);
+        const params = {
+            salesIds,
+            newDiscount,
+            manaCode: manaCode.value,
+        };
+        await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+        return;
+    }
 };
 
 const getNewPrice = computed(() => {
@@ -369,11 +377,15 @@ const getNewPrice = computed(() => {
 });
 
 const newOrderFromTicket = async () => {
-    const { data } = await axios.post(`Orders/newFromTicket`, {
-        ticketFk: Number(route.params.id),
-    });
-    const routeData = router.resolve({ name: 'OrderCatalog', params: { id: data } });
-    window.open(routeData.href, '_blank');
+    try {
+        const { data } = await axios.post(`Orders/newFromTicket`, {
+            ticketFk: Number(route.params.id),
+        });
+        const routeData = router.resolve({ name: 'OrderCatalog', params: { id: data } });
+        window.open(routeData.href, '_blank');
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const goToLog = (saleId) => {
@@ -388,11 +400,15 @@ const goToLog = (saleId) => {
 };
 
 const changeTicketState = async (val) => {
-    stateBtnDropdownRef.value.hide();
-    const params = { ticketFk: route.params.id, code: val };
-    await axios.post('Tickets/state', params);
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        stateBtnDropdownRef.value.hide();
+        const params = { ticketFk: route.params.id, code: val };
+        await axios.post('Tickets/state', params);
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const removeSelectedSales = () => {
@@ -412,10 +428,14 @@ const removeSales = async () => {
         .forEach((sale) => tableRef.value.CrudModelRef.formData.splice(sale.$index, 1));
 
     if (params.sales.length == 0) return;
-    await axios.post('Sales/deleteSales', params);
-    removeSelectedSales();
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        await axios.post('Sales/deleteSales', params);
+        removeSelectedSales();
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const setTransferParams = async () => {

From a81f8fcdafe7dd3aab520716c11f10515b9e0d66 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Mon, 31 Mar 2025 14:43:15 +0200
Subject: [PATCH 09/23] feat: add noOne

---
 src/pages/Customer/CustomerFilter.vue | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index 2ace6dd02..58bc18344 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -73,6 +73,7 @@ const exprBuilder = (param, value) => {
                         option-value="id"
                         option-label="name"
                         url="Departments"
+                        no-one="true"
                     />
                 </QItemSection>
             </QItem>

From 79fdaffbc8bd03740fbcf70178daea87671cc496 Mon Sep 17 00:00:00 2001
From: PAU ROVIRA ROSALENY <provira@verdnatura.es>
Date: Tue, 1 Apr 2025 07:42:30 +0000
Subject: [PATCH 10/23] fix: fixed CustomerTicket table order

---
 src/pages/Customer/components/CustomerSummaryTable.vue | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue
index 09c7e714c..8d921ae69 100644
--- a/src/pages/Customer/components/CustomerSummaryTable.vue
+++ b/src/pages/Customer/components/CustomerSummaryTable.vue
@@ -49,7 +49,6 @@ const filter = {
         },
     ],
     where: { clientFk: $props.id ?? route.params.id },
-    order: ['shipped DESC', 'id'],
     limit: 30,
 };
 
@@ -191,7 +190,7 @@ const getItemPackagingType = (ticketSales) => {
         :without-header="true"
         auto-load
         :row-click="rowClick"
-        order="shipped DESC, id"
+        order="shipped DESC, id DESC"
         :disable-option="{ card: true, table: true }"
         class="full-width"
         :disable-infinite-scroll="true"

From 35886999e465e124c8cbffbfb16e9167c846f419 Mon Sep 17 00:00:00 2001
From: PAU ROVIRA ROSALENY <provira@verdnatura.es>
Date: Tue, 1 Apr 2025 07:54:41 +0000
Subject: [PATCH 11/23] fix: rollback

---
 src/pages/Customer/components/CustomerSummaryTable.vue | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue
index 8d921ae69..feb137065 100644
--- a/src/pages/Customer/components/CustomerSummaryTable.vue
+++ b/src/pages/Customer/components/CustomerSummaryTable.vue
@@ -49,6 +49,7 @@ const filter = {
         },
     ],
     where: { clientFk: $props.id ?? route.params.id },
+    order: ['shipped DESC', 'id'],
     limit: 30,
 };
 

From 246e4429bde5b8e41d3996b0a400e8403bbde14e Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Tue, 1 Apr 2025 11:04:36 +0200
Subject: [PATCH 12/23] refactor: update getArrayData function to accept
 entityId for improved data fetching

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

diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 390906ab6..0b9cc2cce 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -26,7 +26,7 @@ const route = useRoute();
 const stateStore = useStateStore();
 const router = useRouter();
 const entityId = computed(() => props.id || route?.params?.id);
-let arrayData = getArrayData(props.url);
+let arrayData = getArrayData(entityId.value, props.url);
 
 onBeforeRouteLeave(() => {
     stateStore.cardDescriptorChangeValue(null);
@@ -59,7 +59,7 @@ onBeforeRouteUpdate(async (to, from) => {
 async function fetch(id, append = false) {
     if (props.idInWhere) arrayData.store.filter.where = { id };
     else {
-        arrayData = getArrayData();
+        arrayData = getArrayData(id);
     }
     await arrayData.fetch({ append, updateRouter: false });
     emit('onFetch', arrayData.store.data);
@@ -75,9 +75,9 @@ function formatUrl(id) {
     return props.url.replace(regex, `/${newId}`);
 }
 
-function getArrayData(url = formatUrl()) {
+function getArrayData(id, url) {
     return useArrayData(props.dataKey, {
-        url,
+        url: url ?? formatUrl(id),
         userFilter: props.filter,
         oneRecord: true,
     });

From 06e5188146b31b383314f28b626c9e5cc98e73e7 Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Tue, 1 Apr 2025 13:02:49 +0200
Subject: [PATCH 13/23] refactor: remove keepData property from components and
 update related logic

---
 src/components/common/VnSection.vue            | 5 -----
 src/components/ui/VnPaginate.vue               | 2 +-
 src/composables/useArrayData.js                | 3 +--
 src/pages/Supplier/Card/SupplierDescriptor.vue | 2 +-
 src/pages/Travel/Card/TravelDescriptor.vue     | 2 +-
 src/stores/useArrayDataStore.js                | 1 -
 6 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/components/common/VnSection.vue b/src/components/common/VnSection.vue
index 4bd17124f..34eb14601 100644
--- a/src/components/common/VnSection.vue
+++ b/src/components/common/VnSection.vue
@@ -40,10 +40,6 @@ const $props = defineProps({
         type: Boolean,
         default: true,
     },
-    keepData: {
-        type: Boolean,
-        default: true,
-    },
 });
 
 const route = useRoute();
@@ -61,7 +57,6 @@ onBeforeMount(() => {
     if ($props.dataKey)
         arrayData = useArrayData($props.dataKey, {
             searchUrl: 'table',
-            keepData: $props.keepData,
             ...$props.arrayDataProps,
             navigate: $props.redirect,
         });
diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue
index 7facb7916..8fbfb067f 100644
--- a/src/components/ui/VnPaginate.vue
+++ b/src/components/ui/VnPaginate.vue
@@ -115,7 +115,7 @@ onMounted(async () => {
 });
 
 onBeforeUnmount(() => {
-    if (!store.keepData) arrayData.reset(['data']);
+    arrayData.reset(['data']);
     arrayData.resetPagination();
 });
 
diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js
index 363580148..a17730754 100644
--- a/src/composables/useArrayData.js
+++ b/src/composables/useArrayData.js
@@ -56,7 +56,6 @@ export function useArrayData(key, userOptions) {
             'searchUrl',
             'navigate',
             'mapKey',
-            'keepData',
             'oneRecord',
         ];
         if (typeof userOptions === 'object') {
@@ -108,7 +107,7 @@ export function useArrayData(key, userOptions) {
         store.hasMoreData = limit && response.data.length >= limit;
 
         if (!append && !isDialogOpened() && updateRouter) {
-            if (updateStateParams(response.data)?.redirect && !store.keepData) return;
+            if (updateStateParams(response.data)?.redirect) return;
         }
         store.isLoading = false;
         canceller = null;
diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue
index 2863784ab..2511edf11 100644
--- a/src/pages/Supplier/Card/SupplierDescriptor.vue
+++ b/src/pages/Supplier/Card/SupplierDescriptor.vue
@@ -106,7 +106,7 @@ const getEntryQueryParams = (supplier) => {
                 <QBtn
                     :to="{
                         name: 'EntryList',
-                        query: { params: JSON.stringify(getEntryQueryParams(entity)) },
+                        query: { table: JSON.stringify(getEntryQueryParams(entity)) },
                     }"
                     size="md"
                     icon="vn:entry"
diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue
index d4903f794..d57046bae 100644
--- a/src/pages/Travel/Card/TravelDescriptor.vue
+++ b/src/pages/Travel/Card/TravelDescriptor.vue
@@ -66,7 +66,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
                     :to="{
                         name: 'TravelList',
                         query: {
-                            params: JSON.stringify({
+                            table: JSON.stringify({
                                 agencyModeFk: entity.agencyModeFk,
                             }),
                         },
diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js
index b3996d1e3..569ff1c7e 100644
--- a/src/stores/useArrayDataStore.js
+++ b/src/stores/useArrayDataStore.js
@@ -18,7 +18,6 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
         navigate: null,
         page: 1,
         mapKey: 'id',
-        keepData: false,
         oneRecord: false,
     };
 

From 2e6963d505e14a1c6fb3886439022cfb4ecaba6f Mon Sep 17 00:00:00 2001
From: jorgep <jorgep@verdnatura.es>
Date: Wed, 2 Apr 2025 11:38:44 +0200
Subject: [PATCH 14/23] refactor: refs #8326 conditionally render
 vn-card-content based on advancedSummary

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

diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue
index 40787613c..1da2b7d11 100644
--- a/src/pages/Worker/Card/WorkerSummary.vue
+++ b/src/pages/Worker/Card/WorkerSummary.vue
@@ -94,7 +94,7 @@ onBeforeMount(async () => {
                             </template>
                         </VnLv>
                     </div>
-                    <div class="vn-card-content">
+                    <div class="vn-card-content" v-if="advancedSummary">
                         <VnLv
                             :label="t('worker.summary.fiDueDate')"
                             :value="toDate(advancedSummary.fiDueDate)"

From 87e56d9ff1a669a9bbf6243e121f1e3e040e0fe8 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Wed, 2 Apr 2025 11:39:02 +0200
Subject: [PATCH 15/23] fix: customer missing i18n

---
 src/pages/Customer/CustomerFilter.vue                      | 2 ++
 src/pages/Customer/Notifications/CustomerNotifications.vue | 1 +
 2 files changed, 3 insertions(+)

diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index 58bc18344..4c8624102 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -162,6 +162,7 @@ en:
         city: City
         phone: Phone
         email: Email
+        departmentFk: Department
         isToBeMailed: Mailed
         isEqualizated: Equailized
         businessTypeFk: Business type
@@ -177,6 +178,7 @@ es:
         search: Contiene
         fi: NIF
         isActive: Activo
+        departmentFk: Departamento
         isToBeMailed: A enviar
         isEqualizated:  Recargo de equivalencia
         businessTypeFk: Tipo de negocio
diff --git a/src/pages/Customer/Notifications/CustomerNotifications.vue b/src/pages/Customer/Notifications/CustomerNotifications.vue
index b30ed6f76..cbbd6d205 100644
--- a/src/pages/Customer/Notifications/CustomerNotifications.vue
+++ b/src/pages/Customer/Notifications/CustomerNotifications.vue
@@ -127,6 +127,7 @@ es:
     Identifier: Identificador
     Social name: Razón social
     Phone: Teléfono
+    Postcode: Código postal
     City: Población
     Email: Email
     Campaign consumption: Consumo campaña

From 74033a7bdf1532e737f35aa450d0d7dfd1ae5cb8 Mon Sep 17 00:00:00 2001
From: pablone <pablone@verdnatura.es>
Date: Wed, 2 Apr 2025 11:51:03 +0200
Subject: [PATCH 16/23] refactor: improve layout and styling in
 ExtraCommunity.vue

---
 src/pages/Travel/ExtraCommunity.vue | 32 ++++++++++++++---------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/pages/Travel/ExtraCommunity.vue b/src/pages/Travel/ExtraCommunity.vue
index ec898719d..849eeee5b 100644
--- a/src/pages/Travel/ExtraCommunity.vue
+++ b/src/pages/Travel/ExtraCommunity.vue
@@ -505,7 +505,6 @@ watch(route, () => {
                         :props="props"
                         @click="stopEventPropagation($event, col)"
                         :style="col.style"
-                        style="padding-left: 5px"
                     >
                         <component
                             :is="tableColumnComponents[col.name].component"
@@ -581,19 +580,20 @@ watch(route, () => {
                         <QBtn dense flat class="link">{{ entry.id }} </QBtn>
                         <EntryDescriptorProxy :id="entry.id" />
                     </QTd>
-                    <QTd>
-                        <QBtn flat class="link" dense>{{ entry.supplierName }}</QBtn>
-                        <SupplierDescriptorProxy :id="entry.supplierFk" />
-                    </QTd>
-                    <QTd class="text-center">
-                        <QIcon
-                            v-if="entry.isCustomInspectionRequired"
-                            name="warning"
-                            color="negative"
-                            size="md"
-                            :title="t('extraCommunity.requiresInspection')"
-                        >
-                        </QIcon>
+                    <QTd :colspan="2">
+                        <div style="display: flex">
+                            <span class="link">
+                                {{ entry.supplierName }}
+                                <SupplierDescriptorProxy :id="entry.supplierFk" />
+                            </span>
+                            <QIcon
+                                v-if="entry.isCustomInspectionRequired"
+                                name="warning"
+                                color="negative"
+                                size="md"
+                                :title="t('extraCommunity.requiresInspection')"
+                            />
+                        </div>
                     </QTd>
                     <QTd class="text-right">
                         <span>{{ toCurrency(entry.invoiceAmount) }}</span>
@@ -639,9 +639,7 @@ watch(route, () => {
         &:nth-child(1) {
             max-width: 65px;
         }
-        &:nth-child(4) {
-            padding: 0;
-        }
+        padding: 0 5px 0;
     }
     thead > tr > th {
         padding: 3px;

From 1e1715df1aadef727528bfa4a41e7e811a8f2b0d Mon Sep 17 00:00:00 2001
From: jorgep <jorgep@verdnatura.es>
Date: Wed, 2 Apr 2025 12:37:16 +0200
Subject: [PATCH 17/23] test: refs #8441 enable invoice deletion test in
 invoiceInDescriptor.spec.js

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

diff --git a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
index fdaa01876..7058e154c 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.skip('should delete the invoice properly', () => {
+        it('should delete the invoice properly', () => {
             cy.visit('/#/invoice-in/2/summary');
             cy.selectDescriptorOption(2);
             cy.clickConfirm();

From 6debb64b2bb00c62b97177aa359a8f84080bdca5 Mon Sep 17 00:00:00 2001
From: pablone <pablone@verdnatura.es>
Date: Wed, 2 Apr 2025 12:52:51 +0200
Subject: [PATCH 18/23] test: skip VnShortcuts and WorkerList test suites

---
 test/cypress/integration/vnComponent/VnShortcut.spec.js | 4 ++--
 test/cypress/integration/worker/workerList.spec.js      | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/test/cypress/integration/vnComponent/VnShortcut.spec.js b/test/cypress/integration/vnComponent/VnShortcut.spec.js
index fa05e2e3d..cc5cacbe4 100644
--- a/test/cypress/integration/vnComponent/VnShortcut.spec.js
+++ b/test/cypress/integration/vnComponent/VnShortcut.spec.js
@@ -1,6 +1,6 @@
 /// <reference types="cypress" />
-
-describe('VnShortcuts', () => {
+// https://redmine.verdnatura.es/issues/8848
+describe.skip('VnShortcuts', () => {
     const modules = {
         item: 'a',
         customer: 'c',
diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js
index 0a45441c1..d964c3dc8 100644
--- a/test/cypress/integration/worker/workerList.spec.js
+++ b/test/cypress/integration/worker/workerList.spec.js
@@ -1,4 +1,5 @@
-describe('WorkerList', () => {
+// https://redmine.verdnatura.es/issues/8848
+describe.skip('WorkerList', () => {
     const inputName = '.q-drawer .q-form input[aria-label="First Name"]';
     const searchBtn = '.q-drawer button:nth-child(3)';
     const descriptorTitle = '.descriptor .title span';
@@ -13,7 +14,7 @@ describe('WorkerList', () => {
         cy.intercept('GET', /\/api\/Workers\/summary+/).as('worker');
         cy.get(searchBtn).click();
         cy.wait('@worker').then(() =>
-            cy.get(descriptorTitle).should('include.text', 'Jessica')
+            cy.get(descriptorTitle).should('include.text', 'Jessica'),
         );
     });
 });

From 6fd01a4d099b9432518cb2f376baa33e38413eee Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Wed, 2 Apr 2025 14:20:58 +0200
Subject: [PATCH 19/23] fix: remove duplicate departmentFk entries in
 CustomerFilter.vue

---
 src/pages/Customer/CustomerFilter.vue | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index 03033fd8e..c30b11528 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -158,7 +158,6 @@ en:
         departmentFk: Department
         isToBeMailed: Mailed
         isEqualizated: Equailized
-        departmentFk: Department
         businessTypeFk: Business type
         sageTaxTypeFk: Sage Tax Type
         sageTransactionTypeFk: Sage Tax Type
@@ -173,7 +172,6 @@ es:
         search: Contiene
         fi: NIF
         isActive: Activo
-        departmentFk: Departamento
         isToBeMailed: A enviar
         isEqualizated:  Recargo de equivalencia
         businessTypeFk: Tipo de negocio

From a780786a2c30dfd6452089bda677e1a8188fc4b4 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Wed, 2 Apr 2025 14:27:07 +0200
Subject: [PATCH 20/23] style: select needs filled

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

diff --git a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
index aea47aa08..1cadd4cb4 100644
--- a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
+++ b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
@@ -198,7 +198,7 @@ const getLocale = (label) => {
                 <QItemSection>
                     <VnSelect
                         dense
-                        rounded
+                        filled
                         :label="t('globals.params.packing')"
                         v-model="params.packing"
                         url="ItemPackingTypes"

From 00ed955577b7daeb8f801b86053b307be05bfa2a Mon Sep 17 00:00:00 2001
From: alexm <alexm@verdnatura.es>
Date: Wed, 2 Apr 2025 14:39:23 +0200
Subject: [PATCH 21/23] fix: refs #8449 reset pagination in VnLog and bind all
 attributes in AccountDescriptorProxy

---
 src/components/common/VnLog.vue                   | 1 +
 src/pages/Account/Card/AccountDescriptorProxy.vue | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue
index 0f5a162e3..e2f18866a 100644
--- a/src/components/common/VnLog.vue
+++ b/src/components/common/VnLog.vue
@@ -219,6 +219,7 @@ function filterByRecord(modelLog) {
 }
 
 async function applyFilter(params = {}) {
+    paginate.value.arrayData.resetPagination();
     paginate.value.arrayData.applyFilter({
         filter: {},
         params: { originFk: route.params.id, ...params },
diff --git a/src/pages/Account/Card/AccountDescriptorProxy.vue b/src/pages/Account/Card/AccountDescriptorProxy.vue
index de3220fea..6a4b3e267 100644
--- a/src/pages/Account/Card/AccountDescriptorProxy.vue
+++ b/src/pages/Account/Card/AccountDescriptorProxy.vue
@@ -6,7 +6,7 @@ import AccountSummary from './AccountSummary.vue';
     <QPopupProxy style="max-width: 10px">
         <AccountDescriptor
             v-if="$attrs.id"
-            v-bind="$attrs.id"
+            v-bind="$attrs"
             :summary="AccountSummary"
             :proxy-render="true"
         />

From 832646638be001f67ad2f1e1b9bd669825ac3d05 Mon Sep 17 00:00:00 2001
From: jorgep <jorgep@verdnatura.es>
Date: Wed, 2 Apr 2025 14:50:17 +0200
Subject: [PATCH 22/23] fix: refs #5835 update ticket references to invoices in
 InvoiceInDescriptor and localization files

---
 src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue | 8 ++++----
 src/pages/InvoiceIn/locale/en.yml                | 1 +
 src/pages/InvoiceIn/locale/es.yml                | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index 3843f5bf7..a097d9610 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -26,7 +26,7 @@ const routes = reactive({
     getSupplier: (id) => {
         return { name: 'SupplierCard', params: { id } };
     },
-    getTickets: (id) => {
+    getInvoices: (id) => {
         return {
             name: 'InvoiceInList',
             query: {
@@ -135,11 +135,11 @@ async function setInvoiceCorrection(id) {
                 </QBtn>
                 <QBtn
                     size="md"
-                    icon="vn:ticket"
+                    icon="vn:invoice"
                     color="primary"
-                    :to="routes.getTickets(entity.supplierFk)"
+                    :to="routes.getInvoices(entity.supplierFk)"
                 >
-                    <QTooltip>{{ t('globals.ticketList') }}</QTooltip>
+                    <QTooltip>{{ t('invoiceIn.descriptor.invoices') }}</QTooltip>
                 </QBtn>
                 <QBtn
                     v-if="
diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml
index 548e6c201..0ab12e14c 100644
--- a/src/pages/InvoiceIn/locale/en.yml
+++ b/src/pages/InvoiceIn/locale/en.yml
@@ -14,6 +14,7 @@ invoiceIn:
         amount: Amount
     descriptor:
         ticketList: Ticket list
+        invoices: Supplier invoices
     descriptorMenu:
         book: Book
         unbook: Unbook
diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml
index 142d95f92..e91f00a60 100644
--- a/src/pages/InvoiceIn/locale/es.yml
+++ b/src/pages/InvoiceIn/locale/es.yml
@@ -13,7 +13,7 @@ invoiceIn:
         awb: AWB
         amount: Importe
     descriptor:
-        ticketList: Listado de tickets
+        invoices: Facturas de proveedor
     descriptorMenu:
         book: Contabilizar
         unbook: Descontabilizar

From b2ce75d2f6cd1c79bf72d9055be860c4db1c1896 Mon Sep 17 00:00:00 2001
From: jorgep <jorgep@verdnatura.es>
Date: Wed, 2 Apr 2025 15:54:55 +0200
Subject: [PATCH 23/23] fix: refs #5835 update icon for invoice button in
 InvoiceInDescriptor

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

diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index a097d9610..a6a8f922d 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -135,7 +135,7 @@ async function setInvoiceCorrection(id) {
                 </QBtn>
                 <QBtn
                     size="md"
-                    icon="vn:invoice"
+                    icon="vn:invoice-in"
                     color="primary"
                     :to="routes.getInvoices(entity.supplierFk)"
                 >