From 3a9a9bd517f15f2d2f59e4a71351cfb247297b78 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Mon, 24 Feb 2025 15:30:30 +0100
Subject: [PATCH 1/3] fix: check type variable

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

diff --git a/src/pages/Ticket/Card/TicketEditMana.vue b/src/pages/Ticket/Card/TicketEditMana.vue
index 14eec9db93d..c1bc2639bfe 100644
--- a/src/pages/Ticket/Card/TicketEditMana.vue
+++ b/src/pages/Ticket/Card/TicketEditMana.vue
@@ -48,7 +48,7 @@ defineExpose({ save });
 <template>
     <QPopupProxy ref="QPopupProxyRef" data-cy="ticketEditManaProxy">
         <div class="container">
-            <QSpinner v-if="!mana" color="primary" size="md" />
+            <QSpinner v-if="typeof mana === 'number' && mana" color="primary" size="md" />
             <div v-else>
                 <div class="header">Mana: {{ toCurrency(mana) }}</div>
                 <div class="q-pa-md">

From ab5ae580b3bfbfb2291b492d25317864c52bdb2c Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Mon, 24 Feb 2025 16:08:40 +0100
Subject: [PATCH 2/3] fix: check type variable

---
 src/pages/Ticket/Card/TicketEditMana.vue | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/pages/Ticket/Card/TicketEditMana.vue b/src/pages/Ticket/Card/TicketEditMana.vue
index 14eec9db93d..b3ba870fb57 100644
--- a/src/pages/Ticket/Card/TicketEditMana.vue
+++ b/src/pages/Ticket/Card/TicketEditMana.vue
@@ -48,7 +48,11 @@ defineExpose({ save });
 <template>
     <QPopupProxy ref="QPopupProxyRef" data-cy="ticketEditManaProxy">
         <div class="container">
-            <QSpinner v-if="!mana" color="primary" size="md" />
+            <QSpinner
+                v-if="!(typeof mana === 'number' && mana >= 0)"
+                color="primary"
+                size="md"
+            />
             <div v-else>
                 <div class="header">Mana: {{ toCurrency(mana) }}</div>
                 <div class="q-pa-md">

From 223a1ea4490ea6ad2a00c60297fd3c74cd713338 Mon Sep 17 00:00:00 2001
From: Javier Segarra <jsegarra@verdnatura.es>
Date: Mon, 24 Feb 2025 15:52:21 +0000
Subject: [PATCH 3/3] revert 1015acefb7e400be2d8b5958dba69b4d98276b34

revert Merge branch 'test' into master
---
 cypress.config.js                             |    4 +-
 package.json                                  |  144 +-
 quasar.config.js                              |    1 +
 src/boot/defaults/constants.js                |    2 -
 src/boot/keyShortcut.js                       |   17 +-
 src/boot/qformMixin.js                        |   23 +-
 src/boot/quasar.js                            |    1 -
 src/components/CreateBankEntityForm.vue       |    2 +-
 src/components/CrudModel.vue                  |   16 +-
 src/components/FilterTravelForm.vue           |    4 +-
 src/components/FormModel.vue                  |   46 +-
 src/components/FormModelPopup.vue             |   52 +-
 src/components/ItemsFilterPanel.vue           |    4 +-
 src/components/LeftMenu.vue                   |   69 +-
 src/components/LeftMenuItem.vue               |    1 -
 src/components/RefundInvoiceForm.vue          |   15 +-
 src/components/TicketProblems.vue             |   84 +-
 src/components/TransferInvoiceForm.vue        |   15 +-
 src/components/VnTable/VnColumn.vue           |   51 +-
 src/components/VnTable/VnFilter.vue           |   58 +-
 src/components/VnTable/VnOrder.vue            |  101 +-
 src/components/VnTable/VnTable.vue            |  573 ++------
 src/components/VnTable/VnTableFilter.vue      |   57 +-
 src/components/VnTable/VnVisibleColumn.vue    |   19 +-
 src/components/__tests__/FormModel.spec.js    |   12 +-
 src/components/__tests__/Leftmenu.spec.js     |  372 +----
 src/components/__tests__/UserPanel.spec.js    |  100 +-
 src/components/common/VnCard.vue              |   39 +-
 src/components/common/VnCardBeta.vue          |   61 +-
 src/components/common/VnCheckbox.vue          |   43 -
 src/components/common/VnColor.vue             |   32 -
 src/components/common/VnComponent.vue         |    6 +-
 src/components/common/VnDmsList.vue           |   12 +-
 src/components/common/VnInput.vue             |   22 +-
 src/components/common/VnInputDate.vue         |    8 +-
 src/components/common/VnInputNumber.vue       |    2 -
 src/components/common/VnPopupProxy.vue        |   38 -
 src/components/common/VnSection.vue           |    9 +-
 src/components/common/VnSelect.vue            |   22 +-
 src/components/common/VnSelectCache.vue       |    4 +-
 src/components/common/VnSelectDialog.vue      |    2 +
 src/components/common/VnSelectSupplier.vue    |    6 +-
 .../common/VnSelectTravelExtended.vue         |   50 -
 .../common/__tests__/VnNotes.spec.js          |  151 +--
 src/components/ui/CardDescriptor.vue          |   52 +-
 src/components/ui/CardSummary.vue             |   14 +-
 src/components/ui/SkeletonDescriptor.vue      |   65 +-
 src/components/ui/VnConfirm.vue               |    3 +-
 src/components/ui/VnFilterPanel.vue           |   16 +-
 src/components/ui/VnMoreOptions.vue           |    2 +-
 src/components/ui/VnNotes.vue                 |   94 +-
 src/components/ui/VnStockValueDisplay.vue     |   41 -
 src/components/ui/VnSubToolbar.vue            |   11 +-
 .../ui/__tests__/CardSummary.spec.js          |   14 +-
 .../__tests__/useArrayData.spec.js            |   29 +-
 src/composables/checkEntryLock.js             |   65 -
 src/composables/getColAlign.js                |   22 -
 src/composables/useArrayData.js               |   13 +-
 src/composables/useRole.js                    |   10 -
 src/css/app.scss                              |   28 +-
 src/css/quasar.variables.scss                 |    6 +-
 src/filters/toDate.js                         |   11 +-
 src/i18n/locale/en.yml                        |  117 --
 src/i18n/locale/es.yml                        |  225 +---
 src/layouts/MainLayout.vue                    |    2 +-
 src/layouts/OutLayout.vue                     |    5 +-
 src/pages/Account/AccountAliasList.vue        |   10 +-
 src/pages/Account/AccountExprBuilder.js       |   18 -
 src/pages/Account/AccountList.vue             |   26 +-
 src/pages/Account/Alias/AliasExprBuilder.js   |    8 -
 src/pages/Account/Alias/Card/AliasCard.vue    |   10 +-
 .../Account/Alias/Card/AliasDescriptor.vue    |   11 +-
 src/pages/Account/Alias/Card/AliasSummary.vue |   19 +-
 src/pages/Account/Card/AccountBasicData.vue   |   38 +-
 src/pages/Account/Card/AccountCard.vue        |   10 +-
 src/pages/Account/Card/AccountDescriptor.vue  |   43 +-
 .../Account/Card/AccountDescriptorMenu.vue    |   27 +-
 src/pages/Account/Card/AccountFilter.js       |    3 -
 src/pages/Account/Card/AccountMailAlias.vue   |    7 +-
 src/pages/Account/Card/AccountSummary.vue     |   41 +-
 src/pages/Account/Role/AccountRoles.vue       |   18 +-
 src/pages/Account/Role/Card/RoleBasicData.vue |   14 +-
 src/pages/Account/Role/Card/RoleCard.vue      |    7 +-
 .../Account/Role/Card/RoleDescriptor.vue      |   16 +-
 src/pages/Account/Role/Card/RoleSummary.vue   |   23 +-
 src/pages/Account/Role/Card/SubRoles.vue      |    6 +-
 src/pages/Account/Role/RoleExprBuilder.js     |   16 -
 src/pages/Claim/Card/ClaimBasicData.vue       |    1 +
 src/pages/Claim/Card/ClaimCard.vue            |    9 +-
 src/pages/Claim/Card/ClaimDescriptor.vue      |   17 +-
 src/pages/Claim/Card/ClaimLines.vue           |    8 +-
 src/pages/Claim/Card/ClaimNotes.vue           |    3 +-
 src/pages/Claim/Card/ClaimPhoto.vue           |    4 +-
 src/pages/Claim/ClaimList.vue                 |    2 +-
 src/pages/Customer/Card/CustomerAddress.vue   |    8 +-
 src/pages/Customer/Card/CustomerBalance.vue   |    4 +-
 src/pages/Customer/Card/CustomerBasicData.vue |    4 +-
 .../Customer/Card/CustomerBillingData.vue     |    2 +-
 src/pages/Customer/Card/CustomerCard.vue      |    4 +-
 .../Customer/Card/CustomerConsumption.vue     |   95 +-
 src/pages/Customer/Card/CustomerContacts.vue  |    2 +-
 .../Customer/Card/CustomerCreditContracts.vue |    2 +-
 .../Customer/Card/CustomerDescriptor.vue      |   42 +-
 .../Customer/Card/CustomerDescriptorMenu.vue  |   17 -
 .../Customer/Card/CustomerFileManagement.vue  |    2 +-
 .../Customer/Card/CustomerFiscalData.vue      |   32 +-
 src/pages/Customer/Card/CustomerNotes.vue     |    1 -
 src/pages/Customer/Card/CustomerSamples.vue   |    2 +-
 src/pages/Customer/Card/CustomerWebAccess.vue |    2 +-
 src/pages/Customer/CustomerFilter.vue         |    6 +-
 src/pages/Customer/CustomerList.vue           |    4 +-
 .../Customer/Defaulter/CustomerDefaulter.vue  |    2 +-
 .../components/CustomerAddressEdit.vue        |    4 +-
 .../components/CustomerNewPayment.vue         |    6 +-
 .../components/CustomerSamplesCreate.vue      |    9 +-
 src/pages/Customer/locale/en.yml              |    3 -
 src/pages/Customer/locale/es.yml              |    3 -
 .../Department/Card/DepartmentBasicData.vue   |   35 +-
 .../Department/Card/DepartmentCard.vue        |    4 +-
 .../Department/Card/DepartmentDescriptor.vue  |   23 +-
 .../Card/DepartmentDescriptorProxy.vue        |    0
 .../Department/Card/DepartmentSummary.vue     |    2 +-
 .../Card/DepartmentSummaryDialog.vue          |    0
 src/pages/Entry/Card/EntryBasicData.vue       |   63 +-
 src/pages/Entry/Card/EntryBuys.vue            | 1196 ++++++-----------
 src/pages/Entry/Card/EntryCard.vue            |    6 +-
 src/pages/Entry/Card/EntryDescriptor.vue      |  158 +--
 src/pages/Entry/Card/EntryFilter.js           |   17 +-
 src/pages/Entry/Card/EntryNotes.vue           |    4 +-
 src/pages/Entry/Card/EntrySummary.vue         |  392 ++++--
 src/pages/Entry/EntryFilter.vue               |  277 ++--
 src/pages/Entry/EntryList.vue                 |  372 ++---
 src/pages/Entry/EntryStockBought.vue          |   18 +-
 src/pages/Entry/EntryStockBoughtDetail.vue    |   22 +-
 src/pages/Entry/locale/en.yml                 |   82 +-
 src/pages/Entry/locale/es.yml                 |  105 +-
 .../InvoiceIn/Card/InvoiceInBasicData.vue     |    6 +-
 src/pages/InvoiceIn/Card/InvoiceInCard.vue    |   41 +-
 .../InvoiceIn/Card/InvoiceInDescriptor.vue    |   33 +-
 .../Card/InvoiceInDescriptorMenu.vue          |    4 +-
 src/pages/InvoiceIn/Card/InvoiceInDueDay.vue  |   26 +-
 src/pages/InvoiceIn/Card/InvoiceInFilter.js   |   33 -
 .../InvoiceIn/Card/InvoiceInIntrastat.vue     |    2 +-
 src/pages/InvoiceIn/Card/InvoiceInSummary.vue |   13 +-
 src/pages/InvoiceIn/Card/InvoiceInVat.vue     |   78 +-
 src/pages/InvoiceIn/InvoiceInList.vue         |    5 +-
 src/pages/InvoiceIn/InvoiceInToBook.vue       |   56 +-
 src/pages/InvoiceIn/locale/en.yml             |    5 +-
 src/pages/InvoiceIn/locale/es.yml             |    9 +-
 src/pages/InvoiceOut/Card/InvoiceOutCard.vue  |    4 +-
 .../InvoiceOut/Card/InvoiceOutDescriptor.vue  |   28 +-
 src/pages/InvoiceOut/Card/InvoiceOutFilter.js |   16 -
 .../{components => Card}/CreateGenusForm.vue  |    0
 .../{components => Card}/CreateSpecieForm.vue |    0
 src/pages/Item/Card/ItemBarcode.vue           |    2 +-
 src/pages/Item/Card/ItemBasicData.vue         |   42 +-
 src/pages/Item/Card/ItemBotanical.vue         |    4 +-
 src/pages/Item/Card/ItemCard.vue              |    2 +-
 src/pages/Item/Card/ItemDescriptor.vue        |   26 +-
 src/pages/Item/Card/ItemDescriptorProxy.vue   |    6 +-
 src/pages/Item/Card/ItemShelving.vue          |   10 +-
 src/pages/Item/Card/ItemTags.vue              |    2 +-
 src/pages/Item/ItemFixedPrice.vue             |   16 +-
 .../Item/ItemType/Card/ItemTypeBasicData.vue  |    7 +-
 src/pages/Item/ItemType/Card/ItemTypeCard.vue |    6 +-
 .../Item/ItemType/Card/ItemTypeDescriptor.vue |   40 +-
 .../Item/ItemType/Card/ItemTypeFilter.js      |    8 -
 .../Item/ItemType/Card/ItemTypeSummary.vue    |   15 +-
 src/pages/Item/components/ItemProposal.vue    |  332 -----
 .../Item/components/ItemProposalProxy.vue     |   56 -
 src/pages/Item/locale/en.yml                  |   24 +-
 src/pages/Item/locale/es.yml                  |   31 +-
 src/pages/Monitor/MonitorOrders.vue           |    2 +-
 src/pages/Monitor/locale/en.yml               |    1 -
 src/pages/Monitor/locale/es.yml               |    1 -
 .../Order/Card/CatalogFilterValueDialog.vue   |    2 +-
 src/pages/Order/Card/OrderBasicData.vue       |    6 +-
 src/pages/Order/Card/OrderCard.vue            |    4 +-
 src/pages/Order/Card/OrderCatalogFilter.vue   |    4 +-
 .../Order/Card/OrderCatalogItemDialog.vue     |    8 +-
 src/pages/Order/Card/OrderDescriptor.vue      |   38 +-
 src/pages/Order/Card/OrderFilter.js           |   26 -
 src/pages/Order/Card/OrderLines.vue           |    4 +-
 src/pages/Order/Card/OrderSummary.vue         |    2 +-
 src/pages/Order/OrderList.vue                 |    7 +-
 .../Parking/Card/ParkingBasicData.vue         |   18 +-
 .../Parking/Card/ParkingCard.vue              |    6 +-
 .../Parking/Card/ParkingDescriptor.vue        |   16 +-
 .../Parking/Card/ParkingLog.vue               |    0
 .../Parking/Card/ParkingSummary.vue           |    0
 .../{Shelving => }/Parking/ParkingFilter.vue  |    0
 .../{Shelving => }/Parking/ParkingList.vue    |   13 +-
 .../{Shelving => }/Parking/locale/en.yml      |    0
 .../{Shelving => }/Parking/locale/es.yml      |    0
 src/pages/Route/Agency/AgencyList.vue         |    4 +-
 .../Route/Agency/Card/AgencyBasicData.vue     |    2 +-
 src/pages/Route/Agency/Card/AgencyCard.vue    |    2 +-
 .../Route/Agency/Card/AgencyDescriptor.vue    |    1 +
 .../Route/Agency/Card/AgencyWorkcenter.vue    |    2 +-
 src/pages/Route/Card/RouteCard.vue            |    5 +-
 src/pages/Route/Card/RouteDescriptor.vue      |   70 +-
 src/pages/Route/Card/RouteFilter.js           |   39 -
 src/pages/Route/Card/RouteFilter.vue          |    2 +-
 src/pages/Route/Card/RouteForm.vue            |   54 +-
 src/pages/Route/Roadmap/RoadmapBasicData.vue  |    5 +-
 src/pages/Route/Roadmap/RoadmapCard.vue       |    2 +-
 src/pages/Route/Roadmap/RoadmapDescriptor.vue |   18 +-
 src/pages/Route/Roadmap/RoadmapFilter.js      |    3 -
 src/pages/Route/Roadmap/RoadmapStops.vue      |    2 +-
 src/pages/Route/Roadmap/RoadmapSummary.vue    |    3 +-
 src/pages/Route/RouteExtendedList.vue         |  152 +--
 src/pages/Route/RouteList.vue                 |   31 -
 src/pages/Route/RouteTickets.vue              |   18 +-
 .../Route/Vehicle/Card/VehicleBasicData.vue   |  162 ---
 src/pages/Route/Vehicle/Card/VehicleCard.vue  |   13 -
 .../Route/Vehicle/Card/VehicleDescriptor.vue  |   49 -
 .../Route/Vehicle/Card/VehicleSummary.vue     |  127 --
 src/pages/Route/Vehicle/VehicleFilter.js      |   76 --
 src/pages/Route/Vehicle/VehicleList.vue       |  224 ---
 src/pages/Route/Vehicle/locale/en.yml         |   20 -
 src/pages/Route/Vehicle/locale/es.yml         |   20 -
 src/pages/Shelving/Card/ShelvingCard.vue      |    4 +-
 .../Shelving/Card/ShelvingDescriptor.vue      |   30 +-
 src/pages/Shelving/Card/ShelvingFilter.js     |   15 -
 src/pages/Shelving/Card/ShelvingForm.vue      |   32 +-
 src/pages/Shelving/Card/ShelvingSearchbar.vue |    8 +-
 src/pages/Shelving/Card/ShelvingSummary.vue   |   37 +-
 .../Shelving/Parking/Card/ParkingFilter.js    |    4 -
 .../Shelving/Parking/ParkingExprBuilder.js    |   10 -
 src/pages/Shelving/ShelvingExprBuilder.js     |   10 -
 src/pages/Shelving/ShelvingList.vue           |   26 +-
 src/pages/Supplier/Card/SupplierAccounts.vue  |    6 +-
 src/pages/Supplier/Card/SupplierAddresses.vue |    2 +-
 .../Supplier/Card/SupplierAgencyTerm.vue      |    2 +-
 src/pages/Supplier/Card/SupplierBasicData.vue |    3 +-
 src/pages/Supplier/Card/SupplierCard.vue      |   16 +-
 .../Supplier/Card/SupplierConsumption.vue     |  103 +-
 src/pages/Supplier/Card/SupplierContacts.vue  |    2 +-
 .../Supplier/Card/SupplierDescriptor.vue      |   49 +-
 src/pages/Supplier/Card/SupplierFilter.js     |   35 -
 .../Supplier/Card/SupplierFiscalData.vue      |   22 +-
 src/pages/Supplier/SupplierList.vue           |   91 +-
 src/pages/Supplier/SupplierListFilter.vue     |  122 ++
 .../Ticket/Card/BasicData/TicketBasicData.vue |   16 +-
 .../Card/BasicData/TicketBasicDataForm.vue    |    4 +-
 .../Card/BasicData/TicketBasicDataView.vue    |  116 +-
 src/pages/Ticket/Card/TicketCard.vue          |    8 +-
 src/pages/Ticket/Card/TicketComponents.vue    |    2 +-
 src/pages/Ticket/Card/TicketDescriptor.vue    |  139 +-
 src/pages/Ticket/Card/TicketExpedition.vue    |    2 +-
 src/pages/Ticket/Card/TicketFilter.js         |   72 -
 src/pages/Ticket/Card/TicketNotes.vue         |    4 +-
 src/pages/Ticket/Card/TicketPackage.vue       |    4 +-
 src/pages/Ticket/Card/TicketSale.vue          |   60 +-
 src/pages/Ticket/Card/TicketService.vue       |    6 +-
 src/pages/Ticket/Card/TicketSplit.vue         |   37 -
 src/pages/Ticket/Card/TicketSummary.vue       |   81 +-
 src/pages/Ticket/Card/TicketTracking.vue      |    4 +-
 src/pages/Ticket/Card/TicketTransfer.vue      |  131 +-
 src/pages/Ticket/Card/TicketTransferProxy.vue |   54 -
 src/pages/Ticket/Card/components/split.js     |   22 -
 .../Ticket/Negative/TicketLackDetail.vue      |  198 ---
 .../Ticket/Negative/TicketLackFilter.vue      |  175 ---
 src/pages/Ticket/Negative/TicketLackList.vue  |  227 ----
 src/pages/Ticket/Negative/TicketLackTable.vue |  356 -----
 .../Negative/components/ChangeItemDialog.vue  |   90 --
 .../components/ChangeQuantityDialog.vue       |   84 --
 .../Negative/components/ChangeStateDialog.vue |   91 --
 src/pages/Ticket/TicketFuture.vue             |  561 +++++---
 src/pages/Ticket/TicketFutureFilter.vue       |    4 +-
 src/pages/Ticket/locale/en.yml                |   87 +-
 src/pages/Ticket/locale/es.yml                |   83 --
 src/pages/Travel/Card/TravelBasicData.vue     |   19 +-
 src/pages/Travel/Card/TravelCard.vue          |   36 +-
 src/pages/Travel/Card/TravelDescriptor.vue    |    1 +
 src/pages/Travel/Card/TravelFilter.js         |    1 -
 src/pages/Travel/Card/TravelSummary.vue       |    8 -
 src/pages/Travel/Card/TravelThermographs.vue  |    2 +-
 src/pages/Travel/ExtraCommunityFilter.vue     |    2 +-
 src/pages/Travel/TravelList.vue               |   24 -
 src/pages/Wagon/Card/WagonCard.vue            |    2 +-
 src/pages/Wagon/Type/WagonTypeList.vue        |    8 +-
 src/pages/Worker/Card/WorkerBasicData.vue     |   17 +-
 src/pages/Worker/Card/WorkerCalendar.vue      |   32 +-
 .../Worker/Card/WorkerCalendarFilter.vue      |    2 +
 src/pages/Worker/Card/WorkerCard.vue          |    7 +-
 src/pages/Worker/Card/WorkerDescriptor.vue    |    9 +-
 .../Worker/Card/WorkerDescriptorProxy.vue     |    7 +-
 src/pages/Worker/Card/WorkerFormation.vue     |    3 +-
 src/pages/Worker/Card/WorkerMedical.vue       |   16 -
 src/pages/Worker/Card/WorkerOperator.vue      |   19 +-
 src/pages/Worker/Card/WorkerPda.vue           |   10 +-
 src/pages/Worker/Card/WorkerPit.vue           |    2 +-
 src/pages/Worker/Card/WorkerSummary.vue       |    2 +-
 src/pages/Worker/Card/WorkerTimeControl.vue   |   16 +-
 src/pages/Worker/WorkerDepartmentTree.vue     |    4 +-
 src/pages/Zone/Card/ZoneBasicData.vue         |   33 +-
 src/pages/Zone/Card/ZoneCard.vue              |   12 +-
 src/pages/Zone/Card/ZoneDescriptor.vue        |   44 +-
 src/pages/Zone/Card/ZoneEvents.vue            |    4 +-
 src/pages/Zone/Card/ZoneFilter.js             |   10 -
 src/pages/Zone/Card/ZoneSearchbar.vue         |   41 +-
 src/pages/Zone/Card/ZoneSummary.vue           |   18 +-
 src/pages/Zone/Card/ZoneWarehouses.vue        |    2 +-
 src/pages/Zone/Delivery/ZoneDeliveryList.vue  |    2 +-
 src/pages/Zone/Upcoming/ZoneUpcomingList.vue  |    2 +-
 src/pages/Zone/ZoneList.vue                   |   29 +-
 src/router/modules/account/aliasCard.js       |    2 +-
 src/router/modules/account/roleCard.js        |    1 -
 src/router/modules/entry.js                   |   17 +-
 src/router/modules/route.js                   |   52 -
 src/router/modules/shelving.js                |   11 +-
 src/router/modules/supplier.js                |  315 ++---
 src/router/modules/ticket.js                  |   34 +-
 src/router/modules/worker.js                  |    9 +-
 .../__tests__/useNavigationStore.spec.js      |  153 ---
 src/stores/useArrayDataStore.js               |    1 -
 src/utils/notifyResults.js                    |   19 -
 .../integration/Order/orderCatalog.spec.js    |    1 +
 .../integration/entry/entryList.spec.js       |  224 ---
 .../integration/entry/stockBought.spec.js     |   37 +-
 .../invoiceIn/invoiceInBasicData.spec.js      |   27 +-
 .../invoiceIn/invoiceInVat.spec.js            |    2 +-
 .../invoiceOutNegativeBases.spec.js           |    4 +-
 .../integration/item/ItemProposal.spec.js     |   11 -
 test/cypress/integration/item/itemTag.spec.js |    5 +-
 .../parking/parkingBasicData.spec.js          |    4 +-
 .../route/agency/agencyWorkCenter.spec.js     |    1 -
 .../integration/route/routeList.spec.js       |   19 +-
 .../route/vehicle/vehicleDescriptor.spec.js   |   13 -
 .../ticket/negative/TicketLackDetail.spec.js  |  147 --
 .../ticket/negative/TicketLackList.spec.js    |   36 -
 .../integration/ticket/ticketList.spec.js     |   25 -
 .../vnComponent/VnShortcut.spec.js            |   11 -
 .../wagon/wagonType/wagonTypeCreate.spec.js   |    2 +-
 .../integration/zone/zoneBasicData.spec.js    |   16 +-
 test/cypress/support/commands.js              |   71 +-
 test/cypress/support/waitUntil.js             |    2 +-
 338 files changed, 4377 insertions(+), 9582 deletions(-)
 delete mode 100644 src/boot/defaults/constants.js
 delete mode 100644 src/components/common/VnCheckbox.vue
 delete mode 100644 src/components/common/VnColor.vue
 delete mode 100644 src/components/common/VnPopupProxy.vue
 delete mode 100644 src/components/common/VnSelectTravelExtended.vue
 delete mode 100644 src/components/ui/VnStockValueDisplay.vue
 delete mode 100644 src/composables/checkEntryLock.js
 delete mode 100644 src/composables/getColAlign.js
 delete mode 100644 src/pages/Account/AccountExprBuilder.js
 delete mode 100644 src/pages/Account/Alias/AliasExprBuilder.js
 delete mode 100644 src/pages/Account/Card/AccountFilter.js
 delete mode 100644 src/pages/Account/Role/RoleExprBuilder.js
 rename src/pages/{Worker => }/Department/Card/DepartmentBasicData.vue (73%)
 rename src/pages/{Worker => }/Department/Card/DepartmentCard.vue (70%)
 rename src/pages/{Worker => }/Department/Card/DepartmentDescriptor.vue (84%)
 rename src/pages/{Worker => }/Department/Card/DepartmentDescriptorProxy.vue (100%)
 rename src/pages/{Worker => }/Department/Card/DepartmentSummary.vue (99%)
 rename src/pages/{Worker => }/Department/Card/DepartmentSummaryDialog.vue (100%)
 delete mode 100644 src/pages/InvoiceIn/Card/InvoiceInFilter.js
 delete mode 100644 src/pages/InvoiceOut/Card/InvoiceOutFilter.js
 rename src/pages/Item/{components => Card}/CreateGenusForm.vue (100%)
 rename src/pages/Item/{components => Card}/CreateSpecieForm.vue (100%)
 delete mode 100644 src/pages/Item/ItemType/Card/ItemTypeFilter.js
 delete mode 100644 src/pages/Item/components/ItemProposal.vue
 delete mode 100644 src/pages/Item/components/ItemProposalProxy.vue
 delete mode 100644 src/pages/Order/Card/OrderFilter.js
 rename src/pages/{Shelving => }/Parking/Card/ParkingBasicData.vue (68%)
 rename src/pages/{Shelving => }/Parking/Card/ParkingCard.vue (53%)
 rename src/pages/{Shelving => }/Parking/Card/ParkingDescriptor.vue (58%)
 rename src/pages/{Shelving => }/Parking/Card/ParkingLog.vue (100%)
 rename src/pages/{Shelving => }/Parking/Card/ParkingSummary.vue (100%)
 rename src/pages/{Shelving => }/Parking/ParkingFilter.vue (100%)
 rename src/pages/{Shelving => }/Parking/ParkingList.vue (90%)
 rename src/pages/{Shelving => }/Parking/locale/en.yml (100%)
 rename src/pages/{Shelving => }/Parking/locale/es.yml (100%)
 delete mode 100644 src/pages/Route/Card/RouteFilter.js
 delete mode 100644 src/pages/Route/Roadmap/RoadmapFilter.js
 delete mode 100644 src/pages/Route/Vehicle/Card/VehicleBasicData.vue
 delete mode 100644 src/pages/Route/Vehicle/Card/VehicleCard.vue
 delete mode 100644 src/pages/Route/Vehicle/Card/VehicleDescriptor.vue
 delete mode 100644 src/pages/Route/Vehicle/Card/VehicleSummary.vue
 delete mode 100644 src/pages/Route/Vehicle/VehicleFilter.js
 delete mode 100644 src/pages/Route/Vehicle/VehicleList.vue
 delete mode 100644 src/pages/Route/Vehicle/locale/en.yml
 delete mode 100644 src/pages/Route/Vehicle/locale/es.yml
 delete mode 100644 src/pages/Shelving/Card/ShelvingFilter.js
 delete mode 100644 src/pages/Shelving/Parking/Card/ParkingFilter.js
 delete mode 100644 src/pages/Shelving/Parking/ParkingExprBuilder.js
 delete mode 100644 src/pages/Shelving/ShelvingExprBuilder.js
 delete mode 100644 src/pages/Supplier/Card/SupplierFilter.js
 create mode 100644 src/pages/Supplier/SupplierListFilter.vue
 delete mode 100644 src/pages/Ticket/Card/TicketFilter.js
 delete mode 100644 src/pages/Ticket/Card/TicketSplit.vue
 delete mode 100644 src/pages/Ticket/Card/TicketTransferProxy.vue
 delete mode 100644 src/pages/Ticket/Card/components/split.js
 delete mode 100644 src/pages/Ticket/Negative/TicketLackDetail.vue
 delete mode 100644 src/pages/Ticket/Negative/TicketLackFilter.vue
 delete mode 100644 src/pages/Ticket/Negative/TicketLackList.vue
 delete mode 100644 src/pages/Ticket/Negative/TicketLackTable.vue
 delete mode 100644 src/pages/Ticket/Negative/components/ChangeItemDialog.vue
 delete mode 100644 src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue
 delete mode 100644 src/pages/Ticket/Negative/components/ChangeStateDialog.vue
 delete mode 100644 src/pages/Zone/Card/ZoneFilter.js
 delete mode 100644 src/stores/__tests__/useNavigationStore.spec.js
 delete mode 100644 src/utils/notifyResults.js
 delete mode 100644 test/cypress/integration/entry/entryList.spec.js
 delete mode 100644 test/cypress/integration/item/ItemProposal.spec.js
 delete mode 100644 test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js
 delete mode 100644 test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
 delete mode 100644 test/cypress/integration/ticket/negative/TicketLackList.spec.js

diff --git a/cypress.config.js b/cypress.config.js
index a9e27fcfdcb..1924144f624 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -14,8 +14,8 @@ export default defineConfig({
         downloadsFolder: 'test/cypress/downloads',
         video: false,
         specPattern: 'test/cypress/integration/**/*.spec.js',
-        experimentalRunAllSpecs: false,
-        watchForFileChanges: false,
+        experimentalRunAllSpecs: true,
+        watchForFileChanges: true,
         reporter: 'cypress-mochawesome-reporter',
         reporterOptions: {
             charts: true,
diff --git a/package.json b/package.json
index d23ed0cedd3..17f39cad710 100644
--- a/package.json
+++ b/package.json
@@ -1,74 +1,74 @@
 {
-    "name": "salix-front",
-    "version": "25.08.0",
-    "description": "Salix frontend",
-    "productName": "Salix",
-    "author": "Verdnatura",
-    "private": true,
-    "packageManager": "pnpm@8.15.1",
-    "type": "module",
-    "scripts": {
-        "resetDatabase": "cd ../salix && gulp docker",
-        "lint": "eslint --ext .js,.vue ./",
-        "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
-        "test:e2e": "cypress open",
-        "test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
-        "test": "echo \"See package.json => scripts for available tests.\" && exit 0",
-        "test:unit": "vitest",
-        "test:unit:ci": "vitest run",
-        "commitlint": "commitlint --edit",
-        "prepare": "npx husky install",
-        "addReferenceTag": "node .husky/addReferenceTag.js",
-        "docs:dev": "vitepress dev docs",
-        "docs:build": "vitepress build docs",
-        "docs:preview": "vitepress preview docs"
-    },
-    "dependencies": {
-        "@quasar/cli": "^2.4.1",
-        "@quasar/extras": "^1.16.16",
-        "axios": "^1.4.0",
-        "chromium": "^3.0.3",
-        "croppie": "^2.6.5",
-        "moment": "^2.30.1",
-        "pinia": "^2.1.3",
-        "quasar": "^2.17.7",
-        "validator": "^13.9.0",
-        "vue": "^3.5.13",
-        "vue-i18n": "^9.3.0",
-        "vue-router": "^4.2.5"
-    },
-    "devDependencies": {
-        "@commitlint/cli": "^19.2.1",
-        "@commitlint/config-conventional": "^19.1.0",
-        "@intlify/unplugin-vue-i18n": "^0.8.2",
-        "@pinia/testing": "^0.1.2",
-        "@quasar/app-vite": "^2.0.8",
-        "@quasar/quasar-app-extension-qcalendar": "^4.0.2",
-        "@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
-        "@vue/test-utils": "^2.4.4",
-        "autoprefixer": "^10.4.14",
-        "cypress": "^13.6.6",
-        "cypress-mochawesome-reporter": "^3.8.2",
-        "eslint": "^9.18.0",
-        "eslint-config-prettier": "^10.0.1",
-        "eslint-plugin-cypress": "^4.1.0",
-        "eslint-plugin-vue": "^9.32.0",
-        "husky": "^8.0.0",
-        "postcss": "^8.4.23",
-        "prettier": "^3.4.2",
-        "sass": "^1.83.4",
-        "vitepress": "^1.6.3",
-        "vitest": "^0.34.0"
-    },
-    "engines": {
-        "node": "^20 || ^18 || ^16",
-        "npm": ">= 8.1.2",
-        "yarn": ">= 1.21.1",
-        "bun": ">= 1.0.25"
-    },
-    "overrides": {
-        "@vitejs/plugin-vue": "^5.2.1",
-        "vite": "^6.0.11",
-        "vitest": "^0.31.1"
-    }
+  "name": "salix-front",
+  "version": "25.06.0",
+  "description": "Salix frontend",
+  "productName": "Salix",
+  "author": "Verdnatura",
+  "private": true,
+  "packageManager": "pnpm@8.15.1",
+  "type": "module",
+  "scripts": {
+    "resetDatabase": "cd ../salix && gulp docker",
+    "lint": "eslint --ext .js,.vue ./",
+    "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
+    "test:e2e": "cypress open",
+    "test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
+    "test": "echo \"See package.json => scripts for available tests.\" && exit 0",
+    "test:unit": "vitest",
+    "test:unit:ci": "vitest run",
+    "commitlint": "commitlint --edit",
+    "prepare": "npx husky install",
+    "addReferenceTag": "node .husky/addReferenceTag.js",
+    "docs:dev": "vitepress dev docs",
+    "docs:build": "vitepress build docs",
+    "docs:preview": "vitepress preview docs"
+  },
+  "dependencies": {
+    "@quasar/cli": "^2.4.1",
+    "@quasar/extras": "^1.16.16",
+    "axios": "^1.4.0",
+    "chromium": "^3.0.3",
+    "croppie": "^2.6.5",
+    "moment": "^2.30.1",
+    "pinia": "^2.1.3",
+    "quasar": "^2.17.7",
+    "validator": "^13.9.0",
+    "vue": "^3.5.13",
+    "vue-i18n": "^9.3.0",
+    "vue-router": "^4.2.5"
+  },
+  "devDependencies": {
+    "@commitlint/cli": "^19.2.1",
+    "@commitlint/config-conventional": "^19.1.0",
+    "@intlify/unplugin-vue-i18n": "^0.8.2",
+    "@pinia/testing": "^0.1.2",
+    "@quasar/app-vite": "^2.0.8",
+    "@quasar/quasar-app-extension-qcalendar": "^4.0.2",
+    "@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
+    "@vue/test-utils": "^2.4.4",
+    "autoprefixer": "^10.4.14",
+    "cypress": "^13.6.6",
+    "cypress-mochawesome-reporter": "^3.8.2",
+    "eslint": "^9.18.0",
+    "eslint-config-prettier": "^10.0.1",
+    "eslint-plugin-cypress": "^4.1.0",
+    "eslint-plugin-vue": "^9.32.0",
+    "husky": "^8.0.0",
+    "postcss": "^8.4.23",
+    "prettier": "^3.4.2",
+    "sass": "^1.83.4",
+    "vitepress": "^1.6.3",
+    "vitest": "^0.34.0"
+  },
+  "engines": {
+    "node": "^20 || ^18 || ^16",
+    "npm": ">= 8.1.2",
+    "yarn": ">= 1.21.1",
+    "bun": ">= 1.0.25"
+  },
+  "overrides": {
+    "@vitejs/plugin-vue": "^5.2.1",
+    "vite": "^6.0.11",
+    "vitest": "^0.31.1"
+  }
 }
\ No newline at end of file
diff --git a/quasar.config.js b/quasar.config.js
index 9467c92af45..6d545c02658 100644
--- a/quasar.config.js
+++ b/quasar.config.js
@@ -30,6 +30,7 @@ export default configure(function (/* ctx */) {
         // --> boot files are part of "main.js"
         // https://v2.quasar.dev/quasar-cli/boot-files
         boot: ['i18n', 'axios', 'vnDate', 'validations', 'quasar', 'quasar.defaults'],
+
         // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
         css: ['app.scss'],
 
diff --git a/src/boot/defaults/constants.js b/src/boot/defaults/constants.js
deleted file mode 100644
index c96ceb2d185..00000000000
--- a/src/boot/defaults/constants.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export const langs = ['en', 'es'];
-export const decimalPlaces = 2;
diff --git a/src/boot/keyShortcut.js b/src/boot/keyShortcut.js
index 6da06c8bf0d..5afb5b74a36 100644
--- a/src/boot/keyShortcut.js
+++ b/src/boot/keyShortcut.js
@@ -1,6 +1,6 @@
 export default {
-    mounted(el, binding) {
-        const shortcut = binding.value || '+';
+    mounted: function (el, binding) {
+        const shortcut = binding.value ?? '+';
 
         const { key, ctrl, alt, callback } =
             typeof shortcut === 'string'
@@ -8,24 +8,25 @@ export default {
                       key: shortcut,
                       ctrl: true,
                       alt: true,
-                      callback: () => el?.click(),
+                      callback: () =>
+                          document
+                              .querySelector(`button[shortcut="${shortcut}"]`)
+                              ?.click(),
                   }
                 : binding.value;
 
-        if (!el.hasAttribute('shortcut')) {
-            el.setAttribute('shortcut', key);
-        }
-
         const handleKeydown = (event) => {
             if (event.key === key && (!ctrl || event.ctrlKey) && (!alt || event.altKey)) {
                 callback();
             }
         };
 
+        // Attach the event listener to the window
         window.addEventListener('keydown', handleKeydown);
+
         el._handleKeydown = handleKeydown;
     },
-    unmounted(el) {
+    unmounted: function (el) {
         if (el._handleKeydown) {
             window.removeEventListener('keydown', el._handleKeydown);
         }
diff --git a/src/boot/qformMixin.js b/src/boot/qformMixin.js
index 182c51e4793..97d80c670d0 100644
--- a/src/boot/qformMixin.js
+++ b/src/boot/qformMixin.js
@@ -9,19 +9,19 @@ export default {
         if (!form) return;
         try {
             const inputsFormCard = form.querySelectorAll(
-                `input:not([disabled]):not([type="checkbox"])`,
+                `input:not([disabled]):not([type="checkbox"])`
             );
             if (inputsFormCard.length) {
                 focusFirstInput(inputsFormCard[0]);
             }
             const textareas = document.querySelectorAll(
-                'textarea:not([disabled]), [contenteditable]:not([disabled])',
+                'textarea:not([disabled]), [contenteditable]:not([disabled])'
             );
             if (textareas.length) {
                 focusFirstInput(textareas[textareas.length - 1]);
             }
             const inputs = document.querySelectorAll(
-                'form#formModel input:not([disabled]):not([type="checkbox"])',
+                'form#formModel input:not([disabled]):not([type="checkbox"])'
             );
             const input = inputs[0];
             if (!input) return;
@@ -30,5 +30,22 @@ export default {
         } catch (error) {
             console.error(error);
         }
+        form.addEventListener('keyup', function (evt) {
+            if (evt.key === 'Enter' && !that.$attrs['prevent-submit']) {
+                const input = evt.target;
+                if (input.type == 'textarea' && evt.shiftKey) {
+                    evt.preventDefault();
+                    let { selectionStart, selectionEnd } = input;
+                    input.value =
+                        input.value.substring(0, selectionStart) +
+                        '\n' +
+                        input.value.substring(selectionEnd);
+                    selectionStart = selectionEnd = selectionStart + 1;
+                    return;
+                }
+                evt.preventDefault();
+                that.onSubmit();
+            }
+        });
     },
 };
diff --git a/src/boot/quasar.js b/src/boot/quasar.js
index a8c397b8391..54751768235 100644
--- a/src/boot/quasar.js
+++ b/src/boot/quasar.js
@@ -51,5 +51,4 @@ export default boot(({ app }) => {
 
         await useCau(response, message);
     };
-    app.provide('app', app);
 });
diff --git a/src/components/CreateBankEntityForm.vue b/src/components/CreateBankEntityForm.vue
index 7c4b94a6abc..2da3aa9940f 100644
--- a/src/components/CreateBankEntityForm.vue
+++ b/src/components/CreateBankEntityForm.vue
@@ -14,7 +14,7 @@ const { t } = useI18n();
 const bicInputRef = ref(null);
 const state = useState();
 
-const customer = computed(() => state.get('Customer'));
+const customer = computed(() => state.get('customer'));
 
 const countriesFilter = {
     fields: ['id', 'name', 'code'],
diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index 93a2ac96a79..d569dfda1a8 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -64,10 +64,6 @@ const $props = defineProps({
         type: Function,
         default: null,
     },
-    beforeSaveFn: {
-        type: Function,
-        default: null,
-    },
     goTo: {
         type: String,
         default: '',
@@ -180,11 +176,7 @@ async function saveChanges(data) {
         hasChanges.value = false;
         return;
     }
-    let changes = data || getChanges();
-    if ($props.beforeSaveFn) {
-        changes = await $props.beforeSaveFn(changes, getChanges);
-    }
-
+    const changes = data || getChanges();
     try {
         await axios.post($props.saveUrl || $props.url + '/crud', changes);
     } finally {
@@ -237,12 +229,12 @@ async function remove(data) {
                 componentProps: {
                     title: t('globals.confirmDeletion'),
                     message: t('globals.confirmDeletionMessage'),
-                    data: { deletes: ids },
+                    newData,
                     ids,
-                    promise: saveChanges,
                 },
             })
             .onOk(async () => {
+                await saveChanges({ deletes: ids });
                 newData = newData.filter((form) => !ids.some((id) => id == form[pk]));
                 fetch(newData);
             });
@@ -382,8 +374,6 @@ watch(formUrl, async () => {
                 @click="onSubmit"
                 :disable="!hasChanges"
                 :title="t('globals.save')"
-                v-shortcut="'s'"
-                shortcut="s"
                 data-cy="crudModelDefaultSaveBtn"
             />
             <slot name="moreAfterActions" />
diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue
index 765d97763f0..4d43c38100c 100644
--- a/src/components/FilterTravelForm.vue
+++ b/src/components/FilterTravelForm.vue
@@ -181,7 +181,6 @@ const selectTravel = ({ id }) => {
                     color="primary"
                     :disabled="isLoading"
                     :loading="isLoading"
-                    data-cy="save-filter-travel-form"
                 />
             </div>
             <QTable
@@ -192,10 +191,9 @@ const selectTravel = ({ id }) => {
                 :no-data-label="t('Enter a new search')"
                 class="q-mt-lg"
                 @row-click="(_, row) => selectTravel(row)"
-                data-cy="table-filter-travel-form"
             >
                 <template #body-cell-id="{ row }">
-                    <QTd auto-width @click.stop data-cy="travelFk-travel-form">
+                    <QTd auto-width @click.stop>
                         <QBtn flat color="blue">{{ row.id }}</QBtn>
                         <TravelDescriptorProxy :id="row.id" />
                     </QTd>
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index 04ef13d45c3..3842ff94781 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -1,6 +1,6 @@
 <script setup>
 import axios from 'axios';
-import { onMounted, onUnmounted, computed, ref, watch, nextTick, useAttrs } from 'vue';
+import { onMounted, onUnmounted, computed, ref, watch, nextTick } from 'vue';
 import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { useQuasar } from 'quasar';
@@ -22,7 +22,6 @@ const { validate } = useValidator();
 const { notify } = useNotify();
 const route = useRoute();
 const myForm = ref(null);
-const attrs = useAttrs();
 const $props = defineProps({
     url: {
         type: String,
@@ -85,7 +84,7 @@ const $props = defineProps({
     },
     reload: {
         type: Boolean,
-        default: true,
+        default: false,
     },
     defaultTrim: {
         type: Boolean,
@@ -106,15 +105,15 @@ const isLoading = ref(false);
 // Si elegimos observar los cambios del form significa que inicialmente las actions estaran deshabilitadas
 const isResetting = ref(false);
 const hasChanges = ref(!$props.observeFormChanges);
-const originalData = computed(() => state.get(modelValue));
-const formData = ref();
+const originalData = ref({});
+const formData = computed(() => state.get(modelValue));
 const defaultButtons = computed(() => ({
     save: {
         dataCy: 'saveDefaultBtn',
         color: 'primary',
         icon: 'save',
         label: 'globals.save',
-        click: async () => await save(),
+        click: () => myForm.value.submit(),
         type: 'submit',
     },
     reset: {
@@ -128,6 +127,8 @@ const defaultButtons = computed(() => ({
 }));
 
 onMounted(async () => {
+    originalData.value = JSON.parse(JSON.stringify($props.formInitialData ?? {}));
+
     nextTick(() => (componentIsRendered.value = true));
 
     // Podemos enviarle al form la estructura de data inicial sin necesidad de fetchearla
@@ -159,18 +160,10 @@ if (!$props.url)
         (val) => updateAndEmit('onFetch', { val }),
     );
 
-watch(
-    originalData,
-    (val) => {
-        if (val) formData.value = JSON.parse(JSON.stringify(val));
-    },
-    { immediate: true },
-);
-
 watch(
     () => [$props.url, $props.filter],
     async () => {
-        state.set(modelValue, null);
+        originalData.value = null;
         reset();
         await fetch();
     },
@@ -205,6 +198,7 @@ async function fetch() {
         updateAndEmit('onFetch', { val: data });
     } catch (e) {
         state.set(modelValue, {});
+        originalData.value = {};
         throw e;
     }
 }
@@ -247,7 +241,6 @@ async function saveAndGo() {
 }
 
 function reset() {
-    formData.value = JSON.parse(JSON.stringify(originalData.value));
     updateAndEmit('onFetch', { val: originalData.value });
     if ($props.observeFormChanges) {
         hasChanges.value = false;
@@ -272,6 +265,7 @@ function filter(value, update, filterOptions) {
 
 function updateAndEmit(evt, { val, res, old } = { val: null, res: null, old: null }) {
     state.set(modelValue, val);
+    originalData.value = val && JSON.parse(JSON.stringify(val));
     if (!$props.url) arrayData.store.data = val;
 
     emit(evt, state.get(modelValue), res, old);
@@ -285,22 +279,6 @@ function trimData(data) {
     return data;
 }
 
-async function onKeyup(evt) {
-    if (evt.key === 'Enter' && !('prevent-submit' in attrs)) {
-        const input = evt.target;
-        if (input.type == 'textarea' && evt.shiftKey) {
-            let { selectionStart, selectionEnd } = input;
-            input.value =
-                input.value.substring(0, selectionStart) +
-                '\n' +
-                input.value.substring(selectionEnd);
-            selectionStart = selectionEnd = selectionStart + 1;
-            return;
-        }
-        await save();
-    }
-}
-
 defineExpose({
     save,
     isLoading,
@@ -315,12 +293,12 @@ defineExpose({
         <QForm
             ref="myForm"
             v-if="formData"
-            @submit.prevent
-            @keyup.prevent="onKeyup"
+            @submit="save"
             @reset="reset"
             class="q-pa-md"
             :style="maxWidth ? 'max-width: ' + maxWidth : ''"
             id="formModel"
+            :prevent-submit="$attrs['prevent-submit']"
         >
             <QCard>
                 <slot
diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue
index 85943e91e5f..afdc6efca71 100644
--- a/src/components/FormModelPopup.vue
+++ b/src/components/FormModelPopup.vue
@@ -1,13 +1,12 @@
 <script setup>
-import { ref, computed, useAttrs, nextTick } from 'vue';
+import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useState } from 'src/composables/useState';
 
 import FormModel from 'components/FormModel.vue';
 
 const emit = defineEmits(['onDataSaved', 'onDataCanceled']);
 
-const props = defineProps({
+defineProps({
     title: {
         type: String,
         default: '',
@@ -16,41 +15,23 @@ const props = defineProps({
         type: String,
         default: '',
     },
-    showSaveAndContinueBtn: {
-        type: Boolean,
-        default: false,
-    },
 });
 
 const { t } = useI18n();
-const attrs = useAttrs();
-const state = useState();
+
 const formModelRef = ref(null);
 const closeButton = ref(null);
-const isSaveAndContinue = ref(props.showSaveAndContinueBtn);
-const isLoading = computed(() => formModelRef.value?.isLoading);
-const reset = computed(() => formModelRef.value?.reset);
 
-const onDataSaved = async (formData, requestResponse) => {
-    if (!isSaveAndContinue.value) closeButton.value?.click();
-    if (isSaveAndContinue.value) {
-        await nextTick();
-        state.set(attrs.model, attrs.formInitialData);
-    }
-    isSaveAndContinue.value = props.showSaveAndContinueBtn;
+const onDataSaved = (formData, requestResponse) => {
+    if (closeButton.value) closeButton.value.click();
     emit('onDataSaved', formData, requestResponse);
 };
 
-const onClick = async (saveAndContinue) => {
-    isSaveAndContinue.value = saveAndContinue;
-    await formModelRef.value.save();
-};
+const isLoading = computed(() => formModelRef.value?.isLoading);
 
 defineExpose({
     isLoading,
     onDataSaved,
-    isSaveAndContinue,
-    reset,
 });
 </script>
 
@@ -78,16 +59,15 @@ defineExpose({
                     flat
                     :disabled="isLoading"
                     :loading="isLoading"
-                    data-cy="FormModelPopup_cancel"
-                    v-close-popup
-                    z-max
                     @click="emit('onDataCanceled')"
+                    v-close-popup
+                    data-cy="FormModelPopup_cancel"
+                    z-max
                 />
                 <QBtn
-                    :flat="showSaveAndContinueBtn"
                     :label="t('globals.save')"
                     :title="t('globals.save')"
-                    @click="onClick(false)"
+                    type="submit"
                     color="primary"
                     class="q-ml-sm"
                     :disabled="isLoading"
@@ -95,18 +75,6 @@ defineExpose({
                     data-cy="FormModelPopup_save"
                     z-max
                 />
-                <QBtn
-                    v-if="showSaveAndContinueBtn"
-                    :label="t('globals.isSaveAndContinue')"
-                    :title="t('globals.isSaveAndContinue')"
-                    color="primary"
-                    class="q-ml-sm"
-                    :disabled="isLoading"
-                    :loading="isLoading"
-                    data-cy="FormModelPopup_isSaveAndContinue"
-                    z-max
-                    @click="onClick(true)"
-                />
             </div>
         </template>
     </FormModel>
diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue
index f73753a6bcc..36123b8345e 100644
--- a/src/components/ItemsFilterPanel.vue
+++ b/src/components/ItemsFilterPanel.vue
@@ -281,7 +281,7 @@ const setCategoryList = (data) => {
             <QItem class="q-mt-lg">
                 <QBtn
                     icon="add_circle"
-                    v-shortcut="'+'"
+                    shortcut="+"
                     flat
                     class="fill-icon-on-hover q-px-xs"
                     color="primary"
@@ -327,6 +327,7 @@ en:
         active: Is active
         visible: Is visible
         floramondo: Is floramondo
+        salesPersonFk: Buyer
         categoryFk: Category
 
 es:
@@ -337,6 +338,7 @@ es:
         active: Activo
         visible: Visible
         floramondo: Floramondo
+        salesPersonFk: Comprador
         categoryFk: Categoría
     Plant: Planta natural
     Flower: Flor fresca
diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue
index 9a994949943..644f831d44d 100644
--- a/src/components/LeftMenu.vue
+++ b/src/components/LeftMenu.vue
@@ -41,6 +41,7 @@ const filteredItems = computed(() => {
         return locale.includes(normalizedSearch);
     });
 });
+
 const filteredPinnedModules = computed(() => {
     if (!search.value) return pinnedModules.value;
     const normalizedSearch = search.value
@@ -71,7 +72,7 @@ watch(
         items.value = [];
         getRoutes();
     },
-    { deep: true },
+    { deep: true }
 );
 
 function findMatches(search, item) {
@@ -103,40 +104,33 @@ function addChildren(module, route, parent) {
 }
 
 function getRoutes() {
-    const handleRoutes = {
-        main: getMainRoutes,
-        card: getCardRoutes,
-    };
-    try {
-        handleRoutes[props.source]();
-    } catch (error) {
-        throw new Error(`Method is not defined`);
-    }
-}
-function getMainRoutes() {
-    const modules = Object.assign([], navigation.getModules().value);
+    if (props.source === 'main') {
+        const modules = Object.assign([], navigation.getModules().value);
 
-    for (const item of modules) {
-        const moduleDef = routes.find(
-            (route) => toLowerCamel(route.name) === item.module,
+        for (const item of modules) {
+            const moduleDef = routes.find(
+                (route) => toLowerCamel(route.name) === item.module
+            );
+            if (!moduleDef) continue;
+            item.children = [];
+
+            addChildren(item.module, moduleDef, item.children);
+        }
+
+        items.value = modules;
+    }
+
+    if (props.source === 'card') {
+        const currentRoute = route.matched[1];
+        const currentModule = toLowerCamel(currentRoute.name);
+        let moduleDef = routes.find(
+            (route) => toLowerCamel(route.name) === currentModule
         );
-        if (!moduleDef) continue;
-        item.children = [];
 
-        addChildren(item.module, moduleDef, item.children);
+        if (!moduleDef) return;
+        if (!moduleDef?.menus) moduleDef = betaGetRoutes();
+        addChildren(currentModule, moduleDef, items.value);
     }
-
-    items.value = modules;
-}
-
-function getCardRoutes() {
-    const currentRoute = route.matched[1];
-    const currentModule = toLowerCamel(currentRoute.name);
-    let moduleDef = routes.find((route) => toLowerCamel(route.name) === currentModule);
-
-    if (!moduleDef) return;
-    if (!moduleDef?.menus) moduleDef = betaGetRoutes();
-    addChildren(currentModule, moduleDef, items.value);
 }
 
 function betaGetRoutes() {
@@ -229,16 +223,9 @@ const searchModule = () => {
                 </template>
                 <template v-for="(item, index) in filteredItems" :key="item.name">
                     <template
-                        v-if="
-                            search ||
-                            (item.children && !filteredPinnedModules.has(item.name))
-                        "
+                        v-if="search ||item.children && !filteredPinnedModules.has(item.name)"
                     >
-                        <LeftMenuItem
-                            :item="item"
-                            group="modules"
-                            :class="search && index === 0 ? 'searched' : ''"
-                        >
+                        <LeftMenuItem :item="item" group="modules" :class="search && index === 0 ? 'searched' : ''">
                             <template #side>
                                 <QBtn
                                     v-if="item.isPinned === true"
@@ -355,7 +342,7 @@ const searchModule = () => {
 .header {
     color: var(--vn-label-color);
 }
-.searched {
+.searched{
     background-color: var(--vn-section-hover-color);
 }
 </style>
diff --git a/src/components/LeftMenuItem.vue b/src/components/LeftMenuItem.vue
index c0cee44fe86..a3112b17fd3 100644
--- a/src/components/LeftMenuItem.vue
+++ b/src/components/LeftMenuItem.vue
@@ -26,7 +26,6 @@ const itemComputed = computed(() => {
         :to="{ name: itemComputed.name }"
         clickable
         v-ripple
-        :data-cy="`${itemComputed.name}-menu-item`"
     >
         <QItemSection avatar v-if="itemComputed.icon">
             <QIcon :name="itemComputed.icon" />
diff --git a/src/components/RefundInvoiceForm.vue b/src/components/RefundInvoiceForm.vue
index 6dcb8b3903e..590acede005 100644
--- a/src/components/RefundInvoiceForm.vue
+++ b/src/components/RefundInvoiceForm.vue
@@ -9,7 +9,6 @@ import VnSelect from 'components/common/VnSelect.vue';
 import FormPopup from './FormPopup.vue';
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
-import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const $props = defineProps({
     invoiceOutData: {
@@ -132,11 +131,15 @@ const refund = async () => {
                         :required="true"
                     /> </VnRow
                 ><VnRow>
-                    <VnCheckbox
-                        v-model="invoiceParams.inheritWarehouse"
-                        :label="t('Inherit warehouse')"
-                        :info="t('Inherit warehouse tooltip')"
-                    />
+                    <div>
+                        <QCheckbox
+                            :label="t('Inherit warehouse')"
+                            v-model="invoiceParams.inheritWarehouse"
+                        />
+                        <QIcon name="info" class="cursor-info q-ml-sm" size="sm">
+                            <QTooltip>{{ t('Inherit warehouse tooltip') }}</QTooltip>
+                        </QIcon>
+                    </div>
                 </VnRow>
             </template>
         </FormPopup>
diff --git a/src/components/TicketProblems.vue b/src/components/TicketProblems.vue
index 783f2556fe8..934b13a1c1d 100644
--- a/src/components/TicketProblems.vue
+++ b/src/components/TicketProblems.vue
@@ -4,21 +4,26 @@ import { toCurrency } from 'src/filters';
 defineProps({ row: { type: Object, required: true } });
 </script>
 <template>
-    <span class="q-gutter-x-xs">
-        <router-link
-            v-if="row.claim?.claimFk"
-            :to="{ name: 'ClaimBasicData', params: { id: row.claim?.claimFk } }"
-            class="link"
-        >
-            <QIcon name="vn:claims" size="xs">
-                <QTooltip>
-                    {{ t('ticketSale.claim') }}:
-                    {{ row.claim?.claimFk }}
-                </QTooltip>
-            </QIcon>
-        </router-link>
+    <span>
         <QIcon
-            v-if="row?.risk"
+            v-if="row.isTaxDataChecked === 0"
+            name="vn:no036"
+            color="primary"
+            size="xs"
+        >
+            <QTooltip>{{ $t('salesTicketsTable.noVerifiedData') }}</QTooltip>
+        </QIcon>
+        <QIcon v-if="row.hasTicketRequest" name="vn:buyrequest" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
+        </QIcon>
+        <QIcon v-if="row.itemShortage" name="vn:unavailable" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.notVisible') }}</QTooltip>
+        </QIcon>
+        <QIcon v-if="row.isFreezed" name="vn:frozen" color="primary" size="xs">
+            <QTooltip>{{ $t('salesTicketsTable.clientFrozen') }}</QTooltip>
+        </QIcon>
+        <QIcon
+            v-if="row.risk"
             name="vn:risk"
             :color="row.hasHighRisk ? 'negative' : 'primary'"
             size="xs"
@@ -28,57 +33,10 @@ defineProps({ row: { type: Object, required: true } });
                 {{ toCurrency(row.risk - row.credit) }}
             </QTooltip>
         </QIcon>
-        <QIcon
-            v-if="row?.hasComponentLack"
-            name="vn:components"
-            color="primary"
-            size="xs"
-        >
+        <QIcon v-if="row.hasComponentLack" name="vn:components" color="primary" size="xs">
             <QTooltip>{{ $t('salesTicketsTable.componentLack') }}</QTooltip>
         </QIcon>
-        <QIcon v-if="row?.hasItemDelay" color="primary" size="xs" name="vn:hasItemDelay">
-            <QTooltip>
-                {{ $t('ticket.summary.hasItemDelay') }}
-            </QTooltip>
-        </QIcon>
-        <QIcon v-if="row?.hasItemLost" color="primary" size="xs" name="vn:hasItemLost">
-            <QTooltip>
-                {{ $t('salesTicketsTable.hasItemLost') }}
-            </QTooltip>
-        </QIcon>
-        <QIcon
-            v-if="row?.hasItemShortage"
-            name="vn:unavailable"
-            color="primary"
-            size="xs"
-        >
-            <QTooltip>{{ $t('salesTicketsTable.notVisible') }}</QTooltip>
-        </QIcon>
-        <QIcon v-if="row?.hasRounding" color="primary" name="sync_problem" size="xs">
-            <QTooltip>
-                {{ $t('ticketList.rounding') }}
-            </QTooltip>
-        </QIcon>
-        <QIcon
-            v-if="row?.hasTicketRequest"
-            name="vn:buyrequest"
-            color="primary"
-            size="xs"
-        >
-            <QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
-        </QIcon>
-        <QIcon
-            v-if="row?.isTaxDataChecked !== 0"
-            name="vn:no036"
-            color="primary"
-            size="xs"
-        >
-            <QTooltip>{{ $t('salesTicketsTable.noVerifiedData') }}</QTooltip>
-        </QIcon>
-        <QIcon v-if="row?.isFreezed" name="vn:frozen" color="primary" size="xs">
-            <QTooltip>{{ $t('salesTicketsTable.clientFrozen') }}</QTooltip>
-        </QIcon>
-        <QIcon v-if="row?.isTooLittle" name="vn:isTooLittle" color="primary" size="xs">
+        <QIcon v-if="row.isTooLittle" name="vn:isTooLittle" color="primary" size="xs">
             <QTooltip>{{ $t('salesTicketsTable.tooLittle') }}</QTooltip>
         </QIcon>
     </span>
diff --git a/src/components/TransferInvoiceForm.vue b/src/components/TransferInvoiceForm.vue
index c4ef1454ad8..aa71070d6cd 100644
--- a/src/components/TransferInvoiceForm.vue
+++ b/src/components/TransferInvoiceForm.vue
@@ -10,7 +10,6 @@ import VnSelect from 'components/common/VnSelect.vue';
 import FormPopup from './FormPopup.vue';
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
-import VnCheckbox from './common/VnCheckbox.vue';
 
 const $props = defineProps({
     invoiceOutData: {
@@ -187,11 +186,15 @@ const makeInvoice = async () => {
                     />
                 </VnRow>
                 <VnRow>
-                    <VnCheckbox
-                        v-model="checked"
-                        :label="t('Bill destination client')"
-                        :info="t('transferInvoiceInfo')"
-                    />
+                    <div>
+                        <QCheckbox
+                            :label="t('Bill destination client')"
+                            v-model="checked"
+                        />
+                        <QIcon name="info" class="cursor-info q-ml-sm" size="sm">
+                            <QTooltip>{{ t('transferInvoiceInfo') }}</QTooltip>
+                        </QIcon>
+                    </div>
                 </VnRow>
             </template>
         </FormPopup>
diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue
index d0e24538880..9e9bfad6982 100644
--- a/src/components/VnTable/VnColumn.vue
+++ b/src/components/VnTable/VnColumn.vue
@@ -1,8 +1,9 @@
 <script setup>
 import { markRaw, computed } from 'vue';
-import { QIcon, QToggle } from 'quasar';
+import { QIcon, QCheckbox } from 'quasar';
 import { dashIfEmpty } from 'src/filters';
 
+/* basic input */
 import VnSelect from 'components/common/VnSelect.vue';
 import VnSelectCache from 'components/common/VnSelectCache.vue';
 import VnInput from 'components/common/VnInput.vue';
@@ -11,11 +12,8 @@ import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInputTime from 'components/common/VnInputTime.vue';
 import VnComponent from 'components/common/VnComponent.vue';
 import VnUserLink from 'components/ui/VnUserLink.vue';
-import VnSelectEnum from '../common/VnSelectEnum.vue';
-import VnCheckbox from '../common/VnCheckbox.vue';
 
 const model = defineModel(undefined, { required: true });
-const emit = defineEmits(['blur']);
 const $props = defineProps({
     column: {
         type: Object,
@@ -41,18 +39,10 @@ const $props = defineProps({
         type: Object,
         default: null,
     },
-    autofocus: {
-        type: Boolean,
-        default: false,
-    },
     showLabel: {
         type: Boolean,
         default: null,
     },
-    eventHandlers: {
-        type: Object,
-        default: null,
-    },
 });
 
 const defaultSelect = {
@@ -109,8 +99,7 @@ const defaultComponents = {
         },
     },
     checkbox: {
-        ref: 'checkbox',
-        component: markRaw(VnCheckbox),
+        component: markRaw(QCheckbox),
         attrs: ({ model }) => {
             const defaultAttrs = {
                 disable: !$props.isEditable,
@@ -126,10 +115,6 @@ const defaultComponents = {
         },
         forceAttrs: {
             label: $props.showLabel && $props.column.label,
-            autofocus: true,
-        },
-        events: {
-            blur: () => emit('blur'),
         },
     },
     select: {
@@ -140,19 +125,12 @@ const defaultComponents = {
         component: markRaw(VnSelect),
         ...defaultSelect,
     },
-    selectEnum: {
-        component: markRaw(VnSelectEnum),
-        ...defaultSelect,
-    },
     icon: {
         component: markRaw(QIcon),
     },
     userLink: {
         component: markRaw(VnUserLink),
     },
-    toggle: {
-        component: markRaw(QToggle),
-    },
 };
 
 const value = computed(() => {
@@ -182,28 +160,7 @@ const col = computed(() => {
     return newColumn;
 });
 
-const components = computed(() => {
-    const sourceComponents = $props.components ?? defaultComponents;
-
-    return Object.keys(sourceComponents).reduce((acc, key) => {
-        const component = sourceComponents[key];
-
-        if (!component || typeof component !== 'object') {
-            acc[key] = component;
-            return acc;
-        }
-
-        acc[key] = {
-            ...component,
-            attrs: {
-                ...(component.attrs || {}),
-                autofocus: $props.autofocus,
-            },
-            event: { ...component?.event, ...$props?.eventHandlers },
-        };
-        return acc;
-    }, {});
-});
+const components = computed(() => $props.components ?? defaultComponents);
 </script>
 <template>
     <div class="row no-wrap">
diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue
index 0de3834eadb..426f5c716fe 100644
--- a/src/components/VnTable/VnFilter.vue
+++ b/src/components/VnTable/VnFilter.vue
@@ -1,12 +1,14 @@
 <script setup>
 import { markRaw, computed } from 'vue';
-import { QCheckbox, QToggle } from 'quasar';
+import { QCheckbox } from 'quasar';
 import { useArrayData } from 'composables/useArrayData';
+
+/* basic input */
 import VnSelect from 'components/common/VnSelect.vue';
 import VnInput from 'components/common/VnInput.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInputTime from 'components/common/VnInputTime.vue';
-import VnColumn from 'components/VnTable/VnColumn.vue';
+import VnTableColumn from 'components/VnTable/VnColumn.vue';
 
 const $props = defineProps({
     column: {
@@ -25,10 +27,6 @@ const $props = defineProps({
         type: String,
         default: 'table',
     },
-    customClass: {
-        type: String,
-        default: '',
-    },
 });
 
 defineExpose({ addFilter, props: $props });
@@ -36,7 +34,7 @@ defineExpose({ addFilter, props: $props });
 const model = defineModel(undefined, { required: true });
 const arrayData = useArrayData(
     $props.dataKey,
-    $props.searchUrl ? { searchUrl: $props.searchUrl } : null,
+    $props.searchUrl ? { searchUrl: $props.searchUrl } : null
 );
 const columnFilter = computed(() => $props.column?.columnFilter);
 
@@ -48,18 +46,19 @@ const enterEvent = {
 
 const defaultAttrs = {
     filled: !$props.showTitle,
+    class: 'q-px-xs q-pb-xs q-pt-none fit',
     dense: true,
 };
 
 const forceAttrs = {
-    label: $props.showTitle ? '' : (columnFilter.value?.label ?? $props.column.label),
+    label: $props.showTitle ? '' : columnFilter.value?.label ?? $props.column.label,
 };
 
 const selectComponent = {
     component: markRaw(VnSelect),
     event: updateEvent,
     attrs: {
-        class: `q-pt-none fit ${$props.customClass}`,
+        class: 'q-px-sm q-pb-xs q-pt-none fit',
         dense: true,
         filled: !$props.showTitle,
     },
@@ -110,24 +109,14 @@ const components = {
         component: markRaw(QCheckbox),
         event: updateEvent,
         attrs: {
-            class: $props.showTitle ? 'q-py-sm' : 'q-px-md q-py-xs fit',
+            dense: true,
+            class: $props.showTitle ? 'q-py-sm q-mt-md' : 'q-px-md q-py-xs fit',
             'toggle-indeterminate': true,
-            size: 'sm',
         },
         forceAttrs,
     },
     select: selectComponent,
     rawSelect: selectComponent,
-    toggle: {
-        component: markRaw(QToggle),
-        event: updateEvent,
-        attrs: {
-            class: $props.showTitle ? 'q-py-sm' : 'q-px-md q-py-xs fit',
-            'toggle-indeterminate': true,
-            size: 'sm',
-        },
-        forceAttrs,
-    },
 };
 
 async function addFilter(value, name) {
@@ -143,8 +132,19 @@ async function addFilter(value, name) {
     await arrayData.addFilter({ params: { [field]: value } });
 }
 
+function alignRow() {
+    switch ($props.column.align) {
+        case 'left':
+            return 'justify-start items-start';
+        case 'right':
+            return 'justify-end items-end';
+        default:
+            return 'flex-center';
+    }
+}
+
 const showFilter = computed(
-    () => $props.column?.columnFilter !== false && $props.column.name != 'tableActions',
+    () => $props.column?.columnFilter !== false && $props.column.name != 'tableActions'
 );
 
 const onTabPressed = async () => {
@@ -152,8 +152,13 @@ const onTabPressed = async () => {
 };
 </script>
 <template>
-    <div v-if="showFilter" class="full-width" style="overflow: hidden">
-        <VnColumn
+    <div
+        v-if="showFilter"
+        class="full-width"
+        :class="alignRow()"
+        style="max-height: 45px; overflow: hidden"
+    >
+        <VnTableColumn
             :column="$props.column"
             default="input"
             v-model="model"
@@ -163,8 +168,3 @@ const onTabPressed = async () => {
         />
     </div>
 </template>
-<style lang="scss" scoped>
-label.vn-label-padding > .q-field__inner > .q-field__control {
-    padding: inherit !important;
-}
-</style>
diff --git a/src/components/VnTable/VnOrder.vue b/src/components/VnTable/VnOrder.vue
index 47ed9acf4ff..8ffdfe2bc3e 100644
--- a/src/components/VnTable/VnOrder.vue
+++ b/src/components/VnTable/VnOrder.vue
@@ -23,10 +23,6 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
-    align: {
-        type: String,
-        default: 'end',
-    },
 });
 const hover = ref();
 const arrayData = useArrayData($props.dataKey, { searchUrl: $props.searchUrl });
@@ -45,78 +41,55 @@ async function orderBy(name, direction) {
             break;
     }
     if (!direction) return await arrayData.deleteOrder(name);
-
     await arrayData.addOrder(name, direction);
 }
 
 defineExpose({ orderBy });
-
-function textAlignToFlex(textAlign) {
-    return `justify-content: ${
-        {
-            'text-center': 'center',
-            'text-left': 'start',
-            'text-right': 'end',
-        }[textAlign] || 'start'
-    };`;
-}
 </script>
 <template>
     <div
         @mouseenter="hover = true"
         @mouseleave="hover = false"
         @click="orderBy(name, model?.direction)"
-        class="items-center no-wrap cursor-pointer title"
-        :style="textAlignToFlex(align)"
+        class="row items-center no-wrap cursor-pointer"
     >
         <span :title="label">{{ label }}</span>
-        <div v-if="name && model?.index">
-            <QChip
-                :label="!vertical ? model?.index : ''"
-                :icon="
-                    (model?.index || hover) && !vertical
-                        ? model?.direction == 'DESC'
-                            ? 'arrow_downward'
-                            : 'arrow_upward'
-                        : undefined
-                "
-                :size="vertical ? '' : 'sm'"
-                :class="[
-                    model?.index ? 'color-vn-text' : 'bg-transparent',
-                    vertical ? 'q-px-none' : '',
-                ]"
-                class="no-box-shadow"
-                :clickable="true"
-                style="min-width: 40px; max-height: 30px"
+        <QChip
+            v-if="name"
+            :label="!vertical ? model?.index : ''"
+            :icon="
+                (model?.index || hover) && !vertical
+                    ? model?.direction == 'DESC'
+                        ? 'arrow_downward'
+                        : 'arrow_upward'
+                    : undefined
+            "
+            :size="vertical ? '' : 'sm'"
+            :class="[
+                model?.index ? 'color-vn-text' : 'bg-transparent',
+                vertical ? 'q-px-none' : '',
+            ]"
+            class="no-box-shadow"
+            :clickable="true"
+            style="min-width: 40px"
+        >
+            <div
+                class="column flex-center"
+                v-if="vertical"
+                :style="!model?.index && 'color: #5d5d5d'"
             >
-                <div
-                    class="column flex-center"
-                    v-if="vertical"
-                    :style="!model?.index && 'color: #5d5d5d'"
-                >
-                    {{ model?.index }}
-                    <QIcon
-                        :name="
-                            model?.index
-                                ? model?.direction == 'DESC'
-                                    ? 'arrow_downward'
-                                    : 'arrow_upward'
-                                : 'swap_vert'
-                        "
-                        size="xs"
-                    />
-                </div>
-            </QChip>
-        </div>
+                {{ model?.index }}
+                <QIcon
+                    :name="
+                        model?.index
+                            ? model?.direction == 'DESC'
+                                ? 'arrow_downward'
+                                : 'arrow_upward'
+                            : 'swap_vert'
+                    "
+                    size="xs"
+                />
+            </div>
+        </QChip>
     </div>
 </template>
-<style lang="scss" scoped>
-.title {
-    display: flex;
-    align-items: center;
-    height: 30px;
-    width: 100%;
-    color: var(--vn-label-color);
-    white-space: nowrap;
-}
-</style>
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index 7ff56860f8b..6e5f9fef4c6 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -1,38 +1,22 @@
 <script setup>
-import {
-    ref,
-    onBeforeMount,
-    onMounted,
-    onUnmounted,
-    computed,
-    watch,
-    h,
-    render,
-    inject,
-    useAttrs,
-    nextTick,
-} from 'vue';
-import { useArrayData } from 'src/composables/useArrayData';
+import { ref, onBeforeMount, onMounted, computed, watch, useAttrs } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
-import { useQuasar, date } from 'quasar';
+import { useQuasar } from 'quasar';
 import { useStateStore } from 'stores/useStateStore';
 import { useFilterParams } from 'src/composables/useFilterParams';
-import { dashIfEmpty, toDate } from 'src/filters';
 
 import CrudModel from 'src/components/CrudModel.vue';
 import FormModelPopup from 'components/FormModelPopup.vue';
 
-import VnColumn from 'components/VnTable/VnColumn.vue';
+import VnTableColumn from 'components/VnTable/VnColumn.vue';
 import VnFilter from 'components/VnTable/VnFilter.vue';
 import VnTableChip from 'components/VnTable/VnChip.vue';
 import VnVisibleColumn from 'src/components/VnTable/VnVisibleColumn.vue';
 import VnLv from 'components/ui/VnLv.vue';
 import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
 import VnTableFilter from './VnTableFilter.vue';
-import { getColAlign } from 'src/composables/getColAlign';
 
-const arrayData = useArrayData(useAttrs()['data-key']);
 const $props = defineProps({
     columns: {
         type: Array,
@@ -58,6 +42,10 @@ const $props = defineProps({
         type: [Function, Boolean],
         default: null,
     },
+    rowCtrlClick: {
+        type: [Function, Boolean],
+        default: null,
+    },
     redirect: {
         type: String,
         default: null,
@@ -126,19 +114,7 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
-    withFilters: {
-        type: Boolean,
-        default: true,
-    },
-    overlay: {
-        type: Boolean,
-        default: false,
-    },
-    createComplement: {
-        type: Object,
-    },
 });
-
 const { t } = useI18n();
 const stateStore = useStateStore();
 const route = useRoute();
@@ -156,18 +132,10 @@ const showForm = ref(false);
 const splittedColumns = ref({ columns: [] });
 const columnsVisibilitySkipped = ref();
 const createForm = ref();
-const createRef = ref(null);
 const tableRef = ref();
 const params = ref(useFilterParams($attrs['data-key']).params);
 const orders = ref(useFilterParams($attrs['data-key']).orders);
-const app = inject('app');
 
-const editingRow = ref(null);
-const editingField = ref(null);
-const isTableMode = computed(() => mode.value == TABLE_MODE);
-const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
-const selectRegex = /select/;
-const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
 const tableModes = [
     {
         icon: 'view_column',
@@ -188,8 +156,7 @@ onBeforeMount(() => {
     hasParams.value = urlParams && Object.keys(urlParams).length !== 0;
 });
 
-onMounted(async () => {
-    if ($props.isEditable) document.addEventListener('click', clickHandler);
+onMounted(() => {
     mode.value =
         quasar.platform.is.mobile && !$props.disableOption?.card
             ? CARD_MODE
@@ -211,25 +178,14 @@ onMounted(async () => {
     }
 });
 
-onUnmounted(async () => {
-    if ($props.isEditable) document.removeEventListener('click', clickHandler);
-});
-
 watch(
     () => $props.columns,
     (value) => splitColumns(value),
     { immediate: true },
 );
 
-defineExpose({
-    create: createForm,
-    reload,
-    redirect: redirectFn,
-    selected,
-    CrudModelRef,
-    params,
-    tableRef,
-});
+const isTableMode = computed(() => mode.value == TABLE_MODE);
+const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
 
 function splitColumns(columns) {
     splittedColumns.value = {
@@ -275,6 +231,16 @@ const rowClickFunction = computed(() => {
     return () => {};
 });
 
+const rowCtrlClickFunction = computed(() => {
+    if ($props.rowCtrlClick != undefined) return $props.rowCtrlClick;
+    if ($props.redirect)
+        return (evt, { id }) => {
+            stopEventPropagation(evt);
+            window.open(`/#/${$props.redirect}/${id}`, '_blank');
+        };
+    return () => {};
+});
+
 function redirectFn(id) {
     router.push({ path: `/${$props.redirect}/${id}` });
 }
@@ -296,6 +262,21 @@ function columnName(col) {
     return name;
 }
 
+function getColAlign(col) {
+    return 'text-' + (col.align ?? 'left');
+}
+
+const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
+defineExpose({
+    create: createForm,
+    reload,
+    redirect: redirectFn,
+    selected,
+    CrudModelRef,
+    params,
+    tableRef,
+});
+
 function handleOnDataSaved(_) {
     if (_.onDataSaved) _.onDataSaved({ CrudModelRef: CrudModelRef.value });
     else $props.create.onDataSaved(_);
@@ -324,237 +305,6 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
     }
 }
 
-function isEditableColumn(column) {
-    const isEditableCol = column?.isEditable ?? true;
-    const isVisible = column?.visible ?? true;
-    const hasComponent = column?.component;
-
-    return $props.isEditable && isVisible && hasComponent && isEditableCol;
-}
-
-function hasEditableFormat(column) {
-    if (isEditableColumn(column)) return 'editable-text';
-}
-
-const clickHandler = async (event) => {
-    const clickedElement = event.target.closest('td');
-
-    const isDateElement = event.target.closest('.q-date');
-    const isTimeElement = event.target.closest('.q-time');
-    const isQselectDropDown = event.target.closest('.q-select__dropdown-icon');
-
-    if (isDateElement || isTimeElement || isQselectDropDown) return;
-
-    if (clickedElement === null) {
-        await destroyInput(editingRow.value, editingField.value);
-        return;
-    }
-    const rowIndex = clickedElement.getAttribute('data-row-index');
-    const colField = clickedElement.getAttribute('data-col-field');
-    const column = $props.columns.find((col) => col.name === colField);
-
-    if (editingRow.value !== null && editingField.value !== null) {
-        if (editingRow.value == rowIndex && editingField.value == colField) return;
-
-        await destroyInput(editingRow.value, editingField.value);
-    }
-
-    if (isEditableColumn(column)) {
-        await renderInput(Number(rowIndex), colField, clickedElement);
-    }
-};
-
-async function handleTabKey(event, rowIndex, colField) {
-    if (editingRow.value == rowIndex && editingField.value == colField)
-        await destroyInput(editingRow.value, editingField.value);
-
-    const direction = event.shiftKey ? -1 : 1;
-    const { nextRowIndex, nextColumnName } = await handleTabNavigation(
-        rowIndex,
-        colField,
-        direction,
-    );
-
-    if (nextRowIndex < 0 || nextRowIndex >= arrayData.store.data.length) return;
-
-    event.preventDefault();
-    await renderInput(nextRowIndex, nextColumnName, null);
-}
-
-async function renderInput(rowId, field, clickedElement) {
-    editingField.value = field;
-    editingRow.value = rowId;
-
-    const originalColumn = $props.columns.find((col) => col.name === field);
-    const column = { ...originalColumn, ...{ label: '' } };
-    const row = CrudModelRef.value.formData[rowId];
-    const oldValue = CrudModelRef.value.formData[rowId][column?.name];
-
-    if (!clickedElement)
-        clickedElement = document.querySelector(
-            `[data-row-index="${rowId}"][data-col-field="${field}"]`,
-        );
-
-    Array.from(clickedElement.childNodes).forEach((child) => {
-        child.style.visibility = 'hidden';
-        child.style.position = 'relative';
-    });
-
-    const isSelect = selectRegex.test(column?.component);
-    if (isSelect) column.attrs = { ...column.attrs, 'emit-value': false };
-
-    const node = h(VnColumn, {
-        row: row,
-        class: 'temp-input',
-        column: column,
-        modelValue: row[column.name],
-        componentProp: 'columnField',
-        autofocus: true,
-        focusOnMount: true,
-        eventHandlers: {
-            'update:modelValue': async (value) => {
-                if (isSelect && value) {
-                    row[column.name] = value[column.attrs?.optionValue ?? 'id'];
-                    row[column?.name + 'TextValue'] =
-                        value[column.attrs?.optionLabel ?? 'name'];
-                    await column?.cellEvent?.['update:modelValue']?.(
-                        value,
-                        oldValue,
-                        row,
-                    );
-                } else row[column.name] = value;
-                await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
-            },
-            keyup: async (event) => {
-                if (event.key === 'Enter')
-                    await destroyInput(rowIndex, field, clickedElement);
-            },
-            keydown: async (event) => {
-                switch (event.key) {
-                    case 'Tab':
-                        await handleTabKey(event, rowId, field);
-                        event.stopPropagation();
-                        break;
-                    case 'Escape':
-                        await destroyInput(rowId, field, clickedElement);
-                        break;
-                    default:
-                        break;
-                }
-            },
-            click: (event) => {
-                column?.cellEvent?.['click']?.(event, row);
-            },
-        },
-    });
-
-    node.appContext = app._context;
-    render(node, clickedElement);
-
-    if (['toggle'].includes(column?.component))
-        node.el?.querySelector('span > div').focus();
-
-    if (['checkbox', undefined].includes(column?.component))
-        node.el?.querySelector('span > div > div').focus();
-}
-
-async function destroyInput(rowIndex, field, clickedElement) {
-    if (!clickedElement)
-        clickedElement = document.querySelector(
-            `[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
-        );
-    if (clickedElement) {
-        await nextTick();
-        render(null, clickedElement);
-        Array.from(clickedElement.childNodes).forEach((child) => {
-            child.style.visibility = 'visible';
-            child.style.position = '';
-        });
-    }
-    if (editingRow.value !== rowIndex || editingField.value !== field) return;
-    editingRow.value = null;
-    editingField.value = null;
-}
-
-async function handleTabNavigation(rowIndex, colName, direction) {
-    const columns = $props.columns;
-    const totalColumns = columns.length;
-    let currentColumnIndex = columns.findIndex((col) => col.name === colName);
-
-    let iterations = 0;
-    let newColumnIndex = currentColumnIndex;
-
-    do {
-        iterations++;
-        newColumnIndex = (newColumnIndex + direction + totalColumns) % totalColumns;
-
-        if (isEditableColumn(columns[newColumnIndex])) break;
-    } while (iterations < totalColumns);
-
-    if (iterations >= totalColumns + 1) return;
-
-    if (direction === 1 && newColumnIndex <= currentColumnIndex) {
-        rowIndex++;
-    } else if (direction === -1 && newColumnIndex >= currentColumnIndex) {
-        rowIndex--;
-    }
-    return { nextRowIndex: rowIndex, nextColumnName: columns[newColumnIndex].name };
-}
-
-function getCheckboxIcon(value) {
-    switch (typeof value) {
-        case 'boolean':
-            return value ? 'check' : 'close';
-        case 'number':
-            return value === 0 ? 'close' : 'check';
-        case 'undefined':
-            return 'indeterminate_check_box';
-        default:
-            return 'indeterminate_check_box';
-    }
-}
-
-function getToggleIcon(value) {
-    if (value === null) return 'help_outline';
-    return value ? 'toggle_on' : 'toggle_off';
-}
-
-function formatColumnValue(col, row, dashIfEmpty) {
-    if (col?.format || row[col?.name + 'TextValue']) {
-        if (selectRegex.test(col?.component) && row[col?.name + 'TextValue']) {
-            return dashIfEmpty(row[col?.name + 'TextValue']);
-        } else {
-            return col.format(row, dashIfEmpty);
-        }
-    }
-
-    if (col?.component === 'date') return dashIfEmpty(toDate(row[col?.name]));
-
-    if (col?.component === 'time')
-        return row[col?.name] >= 5
-            ? dashIfEmpty(date.formatDate(new Date(row[col?.name]), 'HH:mm'))
-            : row[col?.name];
-
-    if (selectRegex.test(col?.component) && $props.isEditable) {
-        const { find, url } = col.attrs;
-        const urlRelation = url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1);
-
-        if (col?.attrs.options) {
-            const find = col?.attrs.options.find((option) => option.id === row[col.name]);
-            if (!col.attrs?.optionLabel || !find) return dashIfEmpty(row[col?.name]);
-            return dashIfEmpty(find[col.attrs?.optionLabel ?? 'name']);
-        }
-
-        if (typeof row[urlRelation] == 'object') {
-            if (typeof find == 'object')
-                return dashIfEmpty(row[urlRelation][find?.label ?? 'name']);
-
-            return dashIfEmpty(row[urlRelation][col?.attrs.optionLabel ?? 'name']);
-        }
-        if (typeof row[urlRelation] == 'string') return dashIfEmpty(row[urlRelation]);
-    }
-    return dashIfEmpty(row[col?.name]);
-}
 function cardClick(_, row) {
     if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` });
 }
@@ -565,7 +315,7 @@ function cardClick(_, row) {
         v-model="stateStore.rightDrawer"
         side="right"
         :width="256"
-        :overlay="$props.overlay"
+        show-if-above
     >
         <QScrollArea class="fit">
             <VnTableFilter
@@ -586,7 +336,7 @@ function cardClick(_, row) {
     <CrudModel
         v-bind="$attrs"
         :class="$attrs['class'] ?? 'q-px-md'"
-        :limit="$attrs['limit'] ?? 100"
+        :limit="$attrs['limit'] ?? 20"
         ref="CrudModelRef"
         @on-fetch="(...args) => emit('onFetch', ...args)"
         :search-url="searchUrl"
@@ -602,12 +352,8 @@ function cardClick(_, row) {
             <QTable
                 ref="tableRef"
                 v-bind="table"
-                :class="[
-                    'vnTable',
-                    table ? 'selection-cell' : '',
-                    $props.footer ? 'last-row-sticky' : '',
-                ]"
-                wrap-cells
+                class="vnTable"
+                :class="{ 'last-row-sticky': $props.footer }"
                 :columns="splittedColumns.columns"
                 :rows="rows"
                 v-model:selected="selected"
@@ -621,13 +367,11 @@ function cardClick(_, row) {
                 @row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
                 @update:selected="emit('update:selected', $event)"
                 @selection="(details) => handleSelection(details, rows)"
-                :hide-selected-banner="true"
             >
                 <template #top-left v-if="!$props.withoutHeader">
-                    <slot name="top-left"> </slot>
+                    <slot name="top-left"></slot>
                 </template>
                 <template #top-right v-if="!$props.withoutHeader">
-                    <slot name="top-right"></slot>
                     <VnVisibleColumn
                         v-if="isTableMode"
                         v-model="splittedColumns.columns"
@@ -641,7 +385,6 @@ function cardClick(_, row) {
                         dense
                         :options="tableModes.filter((mode) => !mode.disable)"
                     />
-
                     <QBtn
                         v-if="showRightIcon"
                         icon="filter_alt"
@@ -653,39 +396,32 @@ function cardClick(_, row) {
                 <template #header-cell="{ col }">
                     <QTh
                         v-if="col.visible ?? true"
-                        v-bind:class="col.headerClass"
-                        class="body-cell"
-                        :style="col?.width ? `max-width: ${col?.width}` : ''"
+                        :style="col.headerStyle"
+                        :class="col.headerClass"
                     >
                         <div
-                            class="no-padding"
-                            :style="[
-                                withFilters && $props.columnSearch ? 'height: 75px' : '',
-                            ]"
+                            class="column ellipsis"
+                            :class="`text-${col?.align ?? 'left'}`"
+                            :style="$props.columnSearch ? 'height: 75px' : ''"
                         >
-                            <div style="height: 30px">
+                            <div class="row items-center no-wrap" style="height: 30px">
                                 <QTooltip v-if="col.toolTip">{{ col.toolTip }}</QTooltip>
                                 <VnTableOrder
                                     v-model="orders[col.orderBy ?? col.name]"
                                     :name="col.orderBy ?? col.name"
-                                    :label="col?.labelAbbreviation ?? col?.label"
+                                    :label="col?.label"
                                     :data-key="$attrs['data-key']"
                                     :search-url="searchUrl"
-                                    :align="getColAlign(col)"
                                 />
                             </div>
                             <VnFilter
-                                v-if="
-                                    $props.columnSearch &&
-                                    col.columnSearch !== false &&
-                                    withFilters
-                                "
+                                v-if="$props.columnSearch"
                                 :column="col"
                                 :show-title="true"
                                 :data-key="$attrs['data-key']"
                                 v-model="params[columnName(col)]"
                                 :search-url="searchUrl"
-                                customClass="header-filter"
+                                class="full-width"
                             />
                         </div>
                     </QTh>
@@ -703,67 +439,32 @@ function cardClick(_, row) {
                     </QTd>
                 </template>
                 <template #body-cell="{ col, row, rowIndex }">
+                    <!-- Columns -->
                     <QTd
-                        class="no-margin q-px-xs"
+                        auto-width
+                        class="no-margin"
+                        :class="[getColAlign(col), col.columnClass]"
+                        :style="col.style"
                         v-if="col.visible ?? true"
-                        :style="{
-                            'max-width': col?.width ?? false,
-                            position: 'relative',
-                        }"
-                        :class="[
-                            col.columnClass,
-                            'body-cell no-margin no-padding',
-                            getColAlign(col),
-                        ]"
-                        :data-row-index="rowIndex"
-                        :data-col-field="col?.name"
+                        @click.ctrl="
+                            ($event) =>
+                                rowCtrlClickFunction && rowCtrlClickFunction($event, row)
+                        "
                     >
-                        <div
-                            class="no-padding no-margin peter"
-                            style="
-                                overflow: hidden;
-                                text-overflow: ellipsis;
-                                white-space: nowrap;
-                            "
+                        <slot
+                            :name="`column-${col.name}`"
+                            :col="col"
+                            :row="row"
+                            :row-index="rowIndex"
                         >
-                            <slot
-                                :name="`column-${col.name}`"
-                                :col="col"
+                            <VnTableColumn
+                                :column="col"
                                 :row="row"
-                                :row-index="rowIndex"
-                            >
-                                <QIcon
-                                    v-if="col?.component === 'toggle'"
-                                    :name="
-                                        col?.getIcon
-                                            ? col.getIcon(row[col?.name])
-                                            : getToggleIcon(row[col?.name])
-                                    "
-                                    style="color: var(--vn-text-color)"
-                                    :class="hasEditableFormat(col)"
-                                    size="14px"
-                                />
-                                <QIcon
-                                    v-else-if="col?.component === 'checkbox'"
-                                    :name="getCheckboxIcon(row[col?.name])"
-                                    style="color: var(--vn-text-color)"
-                                    :class="hasEditableFormat(col)"
-                                    size="14px"
-                                />
-                                <span
-                                    v-else
-                                    :class="hasEditableFormat(col)"
-                                    :style="
-                                        typeof col?.style == 'function'
-                                            ? col.style(row)
-                                            : col?.style
-                                    "
-                                    style="bottom: 0"
-                                >
-                                    {{ formatColumnValue(col, row, dashIfEmpty) }}
-                                </span>
-                            </slot>
-                        </div>
+                                :is-editable="col.isEditable ?? isEditable"
+                                v-model="row[col.name]"
+                                component-prop="columnField"
+                            />
+                        </slot>
                     </QTd>
                 </template>
                 <template #body-cell-tableActions="{ col, row }">
@@ -784,7 +485,7 @@ function cardClick(_, row) {
                             flat
                             dense
                             :class="
-                                btn.isPrimary ? 'text-primary-light' : 'color-vn-label'
+                                btn.isPrimary ? 'text-primary-light' : 'color-vn-text '
                             "
                             :style="`visibility: ${
                                 ((btn.show && btn.show(row)) ?? true)
@@ -792,7 +493,6 @@ function cardClick(_, row) {
                                     : 'hidden'
                             }`"
                             @click="btn.action(row)"
-                            :data-cy="btn?.name ?? `tableAction-${index}`"
                         />
                     </QTd>
                 </template>
@@ -841,7 +541,7 @@ function cardClick(_, row) {
                                 </QCardSection>
                                 <!-- Fields -->
                                 <QCardSection
-                                    class="q-pl-sm q-py-xs"
+                                    class="q-pl-sm q-pr-lg q-py-xs"
                                     :class="$props.cardClass"
                                 >
                                     <div
@@ -862,7 +562,7 @@ function cardClick(_, row) {
                                                         :row="row"
                                                         :row-index="index"
                                                     >
-                                                        <VnColumn
+                                                        <VnTableColumn
                                                             :column="col"
                                                             :row="row"
                                                             :is-editable="false"
@@ -889,12 +589,12 @@ function cardClick(_, row) {
                                     :title="btn.title"
                                     :icon="btn.icon"
                                     class="q-pa-xs"
+                                    flat
                                     :class="
                                         btn.isPrimary
                                             ? 'text-primary-light'
-                                            : 'color-vn-label'
+                                            : 'color-vn-text '
                                     "
-                                    flat
                                     @click="btn.action(row)"
                                 />
                             </QCardSection>
@@ -902,17 +602,14 @@ function cardClick(_, row) {
                     </component>
                 </template>
                 <template #bottom-row="{ cols }" v-if="$props.footer">
-                    <QTr v-if="rows.length" style="height: 45px">
-                        <QTh v-if="table.selection" />
+                    <QTr v-if="rows.length" style="height: 30px">
                         <QTh
                             v-for="col of cols.filter((cols) => cols.visible ?? true)"
                             :key="col?.id"
+                            class="text-center"
                             :class="getColAlign(col)"
                         >
-                            <slot
-                                :name="`column-footer-${col.name}`"
-                                :isEditableColumn="isEditableColumn(col)"
-                            />
+                            <slot :name="`column-footer-${col.name}`" />
                         </QTh>
                     </QTr>
                 </template>
@@ -931,7 +628,7 @@ function cardClick(_, row) {
                     size="md"
                     round
                     flat
-                    v-shortcut="'+'"
+                    shortcut="+"
                     :disabled="!disabledAttr"
                 />
                 <QTooltip>
@@ -949,52 +646,39 @@ function cardClick(_, row) {
             color="primary"
             fab
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
             data-cy="vnTableCreateBtn"
         />
         <QTooltip self="top right">
             {{ createForm?.title }}
         </QTooltip>
     </QPageSticky>
-    <QDialog
-        v-model="showForm"
-        transition-show="scale"
-        transition-hide="scale"
-        :full-width="createComplement?.isFullWidth ?? false"
-        data-cy="vn-table-create-dialog"
-    >
+    <QDialog v-model="showForm" transition-show="scale" transition-hide="scale">
         <FormModelPopup
-            ref="createRef"
             v-bind="createForm"
             :model="$attrs['data-key'] + 'Create'"
             @on-data-saved="(_, res) => createForm.onDataSaved(res)"
         >
             <template #form-inputs="{ data }">
-                <div :style="createComplement?.containerStyle">
-                    <div>
-                        <slot name="previous-create-dialog" :data="data" />
-                    </div>
-                    <div class="grid-create" :style="createComplement?.columnGridStyle">
-                        <slot
-                            v-for="column of splittedColumns.create"
-                            :key="column.name"
-                            :name="`column-create-${column.name}`"
-                            :data="data"
-                            :column-name="column.name"
-                            :label="column.label"
-                        >
-                            <VnColumn
-                                :column="column"
-                                :row="{}"
-                                default="input"
-                                v-model="data[column.name]"
-                                :show-label="true"
-                                component-prop="columnCreate"
-                                :data-cy="`${column.name}-create-popup`"
-                            />
-                        </slot>
-                        <slot name="more-create-dialog" :data="data" />
-                    </div>
+                <div class="grid-create">
+                    <slot
+                        v-for="column of splittedColumns.create"
+                        :key="column.name"
+                        :name="`column-create-${column.name}`"
+                        :data="data"
+                        :column-name="column.name"
+                        :label="column.label"
+                    >
+                        <VnTableColumn
+                            :column="column"
+                            :row="{}"
+                            default="input"
+                            v-model="data[column.name]"
+                            :show-label="true"
+                            component-prop="columnCreate"
+                        />
+                    </slot>
+                    <slot name="more-create-dialog" :data="data" />
                 </div>
             </template>
         </FormModelPopup>
@@ -1012,42 +696,6 @@ es:
 </i18n>
 
 <style lang="scss">
-.selection-cell {
-    table td:first-child {
-        padding: 0px;
-    }
-}
-.side-padding {
-    padding-left: 1px;
-    padding-right: 1px;
-}
-.editable-text:hover {
-    border-bottom: 1px dashed var(--q-primary);
-    @extend .side-padding;
-}
-.editable-text {
-    border-bottom: 1px dashed var(--vn-label-color);
-    @extend .side-padding;
-}
-.cell-input {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    padding-top: 0px !important;
-}
-.q-field--labeled .q-field__native,
-.q-field--labeled .q-field__prefix,
-.q-field--labeled .q-field__suffix {
-    padding-top: 20px;
-}
-
-.body-cell {
-    padding-left: 4px !important;
-    padding-right: 4px !important;
-    position: relative;
-}
 .bg-chip-secondary {
     background-color: var(--vn-page-color);
     color: var(--vn-text-color);
@@ -1064,8 +712,8 @@ es:
 
 .grid-three {
     display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(300px, max-content));
-    width: 100%;
+    grid-template-columns: repeat(auto-fit, minmax(350px, max-content));
+    max-width: 100%;
     grid-gap: 20px;
     margin: 0 auto;
 }
@@ -1073,6 +721,7 @@ es:
 .grid-create {
     display: grid;
     grid-template-columns: repeat(auto-fit, minmax(150px, max-content));
+    max-width: 100%;
     grid-gap: 20px;
     margin: 0 auto;
 }
@@ -1088,9 +737,7 @@ es:
         }
     }
 }
-.q-table tbody tr td {
-    position: relative;
-}
+
 .q-table {
     th {
         padding: 0;
@@ -1139,7 +786,6 @@ es:
 .vn-label-value {
     display: flex;
     flex-direction: row;
-    align-items: center;
     color: var(--vn-text-color);
     .value {
         overflow: hidden;
@@ -1191,15 +837,4 @@ es:
 .q-table__middle.q-virtual-scroll.q-virtual-scroll--vertical.scroll {
     background-color: var(--vn-section-color);
 }
-.temp-input {
-    top: 0;
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    display: flex;
-}
-
-label.header-filter > .q-field__inner > .q-field__control {
-    padding: inherit;
-}
 </style>
diff --git a/src/components/VnTable/VnTableFilter.vue b/src/components/VnTable/VnTableFilter.vue
index 79b903e547a..732605ce5ed 100644
--- a/src/components/VnTable/VnTableFilter.vue
+++ b/src/components/VnTable/VnTableFilter.vue
@@ -27,36 +27,31 @@ function columnName(col) {
 </script>
 <template>
     <VnFilterPanel v-bind="$attrs" :search-button="true" :disable-submit-event="true">
-        <template #body="{ params, orders, searchFn }">
+        <template #body="{ params, orders }">
             <div
-                class="container"
+                class="row no-wrap flex-center"
                 v-for="col of columns.filter((c) => c.columnFilter ?? true)"
                 :key="col.id"
             >
-                <div class="filter">
-                    <VnFilter
-                        ref="tableFilterRef"
-                        :column="col"
-                        :data-key="$attrs['data-key']"
-                        v-model="params[columnName(col)]"
-                        :search-url="searchUrl"
-                    />
-                </div>
-                <div class="order">
-                    <VnTableOrder
-                        v-if="col?.columnFilter !== false && col?.name !== 'tableActions'"
-                        v-model="orders[col.orderBy ?? col.name]"
-                        :name="col.orderBy ?? col.name"
-                        :data-key="$attrs['data-key']"
-                        :search-url="searchUrl"
-                        :vertical="true"
-                    />
-                </div>
+                <VnFilter
+                    ref="tableFilterRef"
+                    :column="col"
+                    :data-key="$attrs['data-key']"
+                    v-model="params[columnName(col)]"
+                    :search-url="searchUrl"
+                />
+                <VnTableOrder
+                    v-if="col?.columnFilter !== false && col?.name !== 'tableActions'"
+                    v-model="orders[col.orderBy ?? col.name]"
+                    :name="col.orderBy ?? col.name"
+                    :data-key="$attrs['data-key']"
+                    :search-url="searchUrl"
+                    :vertical="true"
+                />
             </div>
             <slot
                 name="moreFilterPanel"
                 :params="params"
-                :search-fn="searchFn"
                 :orders="orders"
                 :columns="columns"
             />
@@ -72,21 +67,3 @@ function columnName(col) {
         </template>
     </VnFilterPanel>
 </template>
-<style lang="scss" scoped>
-.container {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    height: 45px;
-    gap: 10px;
-}
-
-.filter {
-    width: 70%;
-    height: 40px;
-    text-align: center;
-}
-.order {
-    width: 10%;
-}
-</style>
diff --git a/src/components/VnTable/VnVisibleColumn.vue b/src/components/VnTable/VnVisibleColumn.vue
index 6d15c585e0e..dad950d739c 100644
--- a/src/components/VnTable/VnVisibleColumn.vue
+++ b/src/components/VnTable/VnVisibleColumn.vue
@@ -32,21 +32,16 @@ const areAllChecksMarked = computed(() => {
 
 function setUserConfigViewData(data, isLocal) {
     if (!data) return;
+    // Importante: El name de las columnas de la tabla debe conincidir con el name de las variables que devuelve la view config
     if (!isLocal) localColumns.value = [];
-
+    // Array to Object
     const skippeds = $props.skip.reduce((a, v) => ({ ...a, [v]: v }), {});
 
     for (let column of columns.value) {
-        const { label, name, labelAbbreviation } = column;
+        const { label, name } = column;
         if (skippeds[name]) continue;
         column.visible = data[name] ?? true;
-        if (!isLocal)
-            localColumns.value.push({
-                name,
-                label,
-                labelAbbreviation,
-                visible: column.visible,
-            });
+        if (!isLocal) localColumns.value.push({ name, label, visible: column.visible });
     }
 }
 
@@ -157,11 +152,7 @@ onMounted(async () => {
                     <QCheckbox
                         v-for="col in localColumns"
                         :key="col.name"
-                        :label="
-                            col?.labelAbbreviation
-                                ? col.labelAbbreviation + ` (${col.label ?? col.name})`
-                                : (col.label ?? col.name)
-                        "
+                        :label="col.label ?? col.name"
                         v-model="col.visible"
                     />
                 </div>
diff --git a/src/components/__tests__/FormModel.spec.js b/src/components/__tests__/FormModel.spec.js
index 3dce043749d..e35684bc338 100644
--- a/src/components/__tests__/FormModel.spec.js
+++ b/src/components/__tests__/FormModel.spec.js
@@ -57,7 +57,6 @@ describe('FormModel', () => {
             vm.state.set(model, formInitialData);
             expect(vm.hasChanges).toBe(false);
 
-            await vm.$nextTick();
             vm.formData.mockKey = 'newVal';
             await vm.$nextTick();
             expect(vm.hasChanges).toBe(true);
@@ -94,13 +93,9 @@ describe('FormModel', () => {
 
         it('should call axios.patch with the right data', async () => {
             const spy = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
-            const { vm } = mount({ propsData: { url, model } });
-
-            vm.formData = {};
+            const { vm } = mount({ propsData: { url, model, formInitialData } });
+            vm.formData.mockKey = 'newVal';
             await vm.$nextTick();
-            vm.formData = { mockKey: 'newVal' };
-            await vm.$nextTick();
-
             await vm.save();
             expect(spy).toHaveBeenCalled();
             vm.formData.mockKey = 'mockVal';
@@ -111,7 +106,6 @@ describe('FormModel', () => {
             const { vm } = mount({
                 propsData: { url, model, formInitialData, urlCreate: 'mockUrlCreate' },
             });
-            await vm.$nextTick();
             vm.formData.mockKey = 'newVal';
             await vm.$nextTick();
             await vm.save();
@@ -125,7 +119,7 @@ describe('FormModel', () => {
             });
             const spyPatch = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
             const spySaveFn = vi.spyOn(vm.$props, 'saveFn');
-            await vm.$nextTick();
+
             vm.formData.mockKey = 'newVal';
             await vm.$nextTick();
             await vm.save();
diff --git a/src/components/__tests__/Leftmenu.spec.js b/src/components/__tests__/Leftmenu.spec.js
index 4ab8b527fdf..10d9d66fbfb 100644
--- a/src/components/__tests__/Leftmenu.spec.js
+++ b/src/components/__tests__/Leftmenu.spec.js
@@ -1,11 +1,8 @@
-import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest';
+import { vi, describe, expect, it, beforeAll } from 'vitest';
 import { createWrapper, axios } from 'app/test/vitest/helper';
 import Leftmenu from 'components/LeftMenu.vue';
-import * as vueRouter from 'vue-router';
-import { useNavigationStore } from 'src/stores/useNavigationStore';
 
-let vm;
-let navigation;
+import { useNavigationStore } from 'src/stores/useNavigationStore';
 
 vi.mock('src/router/modules', () => ({
     default: [
@@ -24,16 +21,6 @@ vi.mock('src/router/modules', () => ({
                 {
                     path: '',
                     name: 'CustomerMain',
-                    meta: {
-                        menu: 'Customer',
-                        menuChildren: [
-                            {
-                                name: 'CustomerCreditContracts',
-                                title: 'creditContracts',
-                                icon: 'vn:solunion',
-                            },
-                        ],
-                    },
                     children: [
                         {
                             path: 'list',
@@ -41,13 +28,6 @@ vi.mock('src/router/modules', () => ({
                             meta: {
                                 title: 'list',
                                 icon: 'view_list',
-                                menuChildren: [
-                                    {
-                                        name: 'CustomerCreditContracts',
-                                        title: 'creditContracts',
-                                        icon: 'vn:solunion',
-                                    },
-                                ],
                             },
                         },
                         {
@@ -64,325 +44,51 @@ vi.mock('src/router/modules', () => ({
         },
     ],
 }));
-vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
-    matched: [
-        {
-            path: '/',
-            redirect: {
-                name: 'Dashboard',
+
+describe('Leftmenu', () => {
+    let vm;
+    let navigation;
+    beforeAll(() => {
+        vi.spyOn(axios, 'get').mockResolvedValue({
+            data: [],
+        });
+
+        vm = createWrapper(Leftmenu, {
+            propsData: {
+                source: 'main',
             },
-            name: 'Main',
-            meta: {},
-            props: {
-                default: false,
-            },
-            children: [
+        }).vm;
+
+        navigation = useNavigationStore();
+        navigation.fetchPinned = vi.fn().mockReturnValue(Promise.resolve(true));
+        navigation.getModules = vi.fn().mockReturnValue({
+            value: [
                 {
-                    path: '/dashboard',
-                    name: 'Dashboard',
-                    meta: {
-                        title: 'dashboard',
-                        icon: 'dashboard',
-                    },
+                    name: 'customer',
+                    title: 'customer.pageTitles.customers',
+                    icon: 'vn:customer',
+                    module: 'customer',
                 },
             ],
-        },
-        {
-            path: '/customer',
-            redirect: {
-                name: 'CustomerMain',
-            },
-            name: 'Customer',
-            meta: {
-                title: 'customers',
-                icon: 'vn:client',
-                moduleName: 'Customer',
-                keyBinding: 'c',
-                menu: 'customer',
-            },
-        },
-    ],
-    query: {},
-    params: {},
-    meta: { moduleName: 'mockName' },
-    path: 'mockName/1',
-    name: 'Customer',
-});
-function mount(source = 'main') {
-    vi.spyOn(axios, 'get').mockResolvedValue({
-        data: [],
-    });
-    const wrapper = createWrapper(Leftmenu, {
-        propsData: {
-            source,
-        },
-    });
-
-    navigation = useNavigationStore();
-    navigation.fetchPinned = vi.fn().mockReturnValue(Promise.resolve(true));
-    navigation.getModules = vi.fn().mockReturnValue({
-        value: [
-            {
-                name: 'customer',
-                title: 'customer.pageTitles.customers',
-                icon: 'vn:customer',
-                module: 'customer',
-            },
-        ],
-    });
-    return wrapper;
-}
-
-describe('getRoutes', () => {
-    afterEach(() => vi.clearAllMocks());
-    const getRoutes = vi.fn().mockImplementation((props, getMethodA, getMethodB) => {
-        const handleRoutes = {
-            methodA: getMethodA,
-            methodB: getMethodB,
-        };
-        try {
-            handleRoutes[props.source]();
-        } catch (error) {
-            throw Error('Method not defined');
-        }
-    });
-
-    const getMethodA = vi.fn();
-    const getMethodB = vi.fn();
-    const fn = (props) => getRoutes(props, getMethodA, getMethodB);
-
-    it('should call getMethodB when source is card', () => {
-        let props = { source: 'methodB' };
-        fn(props);
-
-        expect(getMethodB).toHaveBeenCalled();
-        expect(getMethodA).not.toHaveBeenCalled();
-    });
-    it('should call getMethodA when source is main', () => {
-        let props = { source: 'methodA' };
-        fn(props);
-
-        expect(getMethodA).toHaveBeenCalled();
-        expect(getMethodB).not.toHaveBeenCalled();
-    });
-
-    it('should call getMethodA when source is not exists or undefined', () => {
-        let props = { source: 'methodC' };
-        expect(() => fn(props)).toThrowError('Method not defined');
-
-        expect(getMethodA).not.toHaveBeenCalled();
-        expect(getMethodB).not.toHaveBeenCalled();
-    });
-});
-
-describe('Leftmenu as card', () => {
-    beforeAll(() => {
-        vm = mount('card').vm;
-    });
-
-    it('should get routes for card source', async () => {
-        vm.getRoutes();
-    });
-});
-describe('Leftmenu as main', () => {
-    beforeEach(() => {
-        vm = mount().vm;
-    });
-
-    it('should initialize with default props', () => {
-        expect(vm.source).toBe('main');
-    });
-
-    it('should filter items based on search input', async () => {
-        vm.search = 'cust';
-        await vm.$nextTick();
-        expect(vm.filteredItems[0].name).toEqual('customer');
-        expect(vm.filteredItems[0].module).toEqual('customer');
-    });
-    it('should filter items based on search input', async () => {
-        vm.search = 'Rou';
-        await vm.$nextTick();
-        expect(vm.filteredItems).toEqual([]);
-    });
-
-    it('should return pinned items', () => {
-        vm.items = [
-            { name: 'Item 1', isPinned: false },
-            { name: 'Item 2', isPinned: true },
-        ];
-        expect(vm.pinnedModules).toEqual(
-            new Map([['Item 2', { name: 'Item 2', isPinned: true }]]),
-        );
-    });
-
-    it('should find matches in routes', () => {
-        const search = 'child1';
-        const item = {
-            children: [
-                { name: 'child1', children: [] },
-                { name: 'child2', children: [] },
-            ],
-        };
-        const matches = vm.findMatches(search, item);
-        expect(matches).toEqual([{ name: 'child1', children: [] }]);
-    });
-    it('should not proceed if event is already prevented', async () => {
-        const item = { module: 'testModule', isPinned: false };
-        const event = {
-            preventDefault: vi.fn(),
-            stopPropagation: vi.fn(),
-            defaultPrevented: true,
-        };
-
-        await vm.togglePinned(item, event);
-
-        expect(event.preventDefault).not.toHaveBeenCalled();
-        expect(event.stopPropagation).not.toHaveBeenCalled();
-    });
-
-    it('should call quasar.notify with success message', async () => {
-        const item = { module: 'testModule', isPinned: false };
-        const event = {
-            preventDefault: vi.fn(),
-            stopPropagation: vi.fn(),
-            defaultPrevented: false,
-        };
-        const response = { data: { id: 1 } };
-
-        vi.spyOn(axios, 'post').mockResolvedValue(response);
-        vi.spyOn(vm.quasar, 'notify');
-
-        await vm.togglePinned(item, event);
-
-        expect(vm.quasar.notify).toHaveBeenCalledWith({
-            message: 'Data saved',
-            type: 'positive',
         });
     });
 
-    it('should handle a single matched route with a menu', () => {
-        const route = {
-            matched: [{ meta: { menu: 'customer' } }],
-        };
-
-        const result = vm.betaGetRoutes();
-
-        expect(result.meta.menu).toEqual(route.matched[0].meta.menu);
-    });
-    it('should get routes for main source', () => {
-        vm.props.source = 'main';
-        vm.getRoutes();
-        expect(navigation.getModules).toHaveBeenCalled();
-    });
-
-    it('should find direct child matches', () => {
-        const search = 'child1';
-        const item = {
-            children: [{ name: 'child1' }, { name: 'child2' }],
-        };
-        const result = vm.findMatches(search, item);
-        expect(result).toEqual([{ name: 'child1' }]);
-    });
-
-    it('should find nested child matches', () => {
-        const search = 'child3';
-        const item = {
-            children: [
-                { name: 'child1' },
-                {
-                    name: 'child2',
-                    children: [{ name: 'child3' }],
-                },
-            ],
-        };
-        const result = vm.findMatches(search, item);
-        expect(result).toEqual([{ name: 'child3' }]);
-    });
-});
-
-describe('normalize', () => {
-    beforeAll(() => {
-        vm = mount('card').vm;
-    });
-    it('should normalize and lowercase text', () => {
-        const input = 'ÁÉÍÓÚáéíóú';
-        const expected = 'aeiouaeiou';
-        expect(vm.normalize(input)).toBe(expected);
-    });
-
-    it('should handle empty string', () => {
-        const input = '';
-        const expected = '';
-        expect(vm.normalize(input)).toBe(expected);
-    });
-
-    it('should handle text without diacritics', () => {
-        const input = 'hello';
-        const expected = 'hello';
-        expect(vm.normalize(input)).toBe(expected);
-    });
-
-    it('should handle mixed text', () => {
-        const input = 'Héllo Wórld!';
-        const expected = 'hello world!';
-        expect(vm.normalize(input)).toBe(expected);
-    });
-});
-
-describe('addChildren', () => {
-    const module = 'testModule';
-    beforeEach(() => {
-        vm = mount().vm;
-        vi.clearAllMocks();
-    });
-
-    it('should add menu items to parent if matches are found', () => {
-        const parent = 'testParent';
-        const route = {
-            meta: {
-                menu: 'testMenu',
+    it('should return a proper formated object with two child items', async () => {
+        const expectedMenuItem = [
+            {
+                children: null,
+                name: 'CustomerList',
+                title: 'globals.pageTitles.list',
+                icon: 'view_list',
             },
-            children: [{ name: 'child1' }, { name: 'child2' }],
-        };
-        vm.addChildren(module, route, parent);
-
-        expect(navigation.addMenuItem).toHaveBeenCalled();
-    });
-
-    it('should handle routes with no meta menu', () => {
-        const route = {
-            meta: {},
-            menus: {},
-        };
-
-        const parent = [];
-
-        vm.addChildren(module, route, parent);
-        expect(navigation.addMenuItem).toHaveBeenCalled();
-    });
-
-    it('should handle empty parent array', () => {
-        const parent = [];
-        const route = {
-            meta: {
-                menu: 'child11',
+            {
+                children: null,
+                name: 'CustomerCreate',
+                title: 'globals.pageTitles.createCustomer',
+                icon: 'vn:addperson',
             },
-            children: [
-                {
-                    name: 'child1',
-                    meta: {
-                        menuChildren: [
-                            {
-                                name: 'CustomerCreditContracts',
-                                title: 'creditContracts',
-                                icon: 'vn:solunion',
-                            },
-                        ],
-                    },
-                },
-            ],
-        };
-        vm.addChildren(module, route, parent);
-        expect(navigation.addMenuItem).toHaveBeenCalled();
+        ];
+        const firstMenuItem = vm.items[0];
+        expect(firstMenuItem.children).toEqual(expect.arrayContaining(expectedMenuItem));
     });
 });
diff --git a/src/components/__tests__/UserPanel.spec.js b/src/components/__tests__/UserPanel.spec.js
index 9e449745a89..ac20f911e7f 100644
--- a/src/components/__tests__/UserPanel.spec.js
+++ b/src/components/__tests__/UserPanel.spec.js
@@ -1,65 +1,61 @@
-import { vi, describe, expect, it, beforeEach, afterEach } from 'vitest';
+import { vi, describe, expect, it, beforeEach, beforeAll, afterEach } from 'vitest';
 import { createWrapper } from 'app/test/vitest/helper';
 import UserPanel from 'src/components/UserPanel.vue';
 import axios from 'axios';
 import { useState } from 'src/composables/useState';
 
-vi.mock('src/utils/quasarLang', () => ({
-  default: vi.fn(),
-}));
-
 describe('UserPanel', () => {
-  let wrapper;
-  let vm;
-  let state;
+    let wrapper;
+    let vm;
+    let state;
 
-  beforeEach(() => {
-    wrapper = createWrapper(UserPanel, {});
-    state = useState();
-    state.setUser({
-      id: 115,
-      name: 'itmanagement',
-      nickname: 'itManagementNick',
-      lang: 'en',
-      darkMode: false,
-      companyFk: 442,
-      warehouseFk: 1,
+    beforeEach(() => {
+        wrapper = createWrapper(UserPanel, {});
+        state = useState();
+        state.setUser({
+            id: 115,
+            name: 'itmanagement',
+            nickname: 'itManagementNick',
+            lang: 'en',
+            darkMode: false,
+            companyFk: 442,
+            warehouseFk: 1,
+        });
+        wrapper = wrapper.wrapper;
+        vm = wrapper.vm;
     });
-    wrapper = wrapper.wrapper;
-    vm = wrapper.vm;
-  });
 
-  afterEach(() => {
-    vi.clearAllMocks();
-  });
+    afterEach(() => {
+        vi.clearAllMocks();
+    });
 
-  it('should fetch warehouses data on mounted', async () => {
-    const fetchData = wrapper.findComponent({ name: 'FetchData' });
-    expect(fetchData.props('url')).toBe('Warehouses');
-    expect(fetchData.props('autoLoad')).toBe(true);
-  });
+    it('should fetch warehouses data on mounted', async () => {
+        const fetchData = wrapper.findComponent({ name: 'FetchData' });
+        expect(fetchData.props('url')).toBe('Warehouses');
+        expect(fetchData.props('autoLoad')).toBe(true);
+    });
 
-  it('should toggle dark mode correctly and update preferences', async () => {
-    await vm.saveDarkMode(true);
-    expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
-    expect(vm.user.darkMode).toBe(true);
-    await vm.updatePreferences();
-    expect(vm.darkMode).toBe(true);
-  });
+    it('should toggle dark mode correctly and update preferences', async () => {
+        await vm.saveDarkMode(true);
+        expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
+        expect(vm.user.darkMode).toBe(true);
+        vm.updatePreferences();
+        expect(vm.darkMode).toBe(true);
+    });
 
-  it('should change user language and update preferences', async () => {
-    const userLanguage = 'es';
-    await vm.saveLanguage(userLanguage);
-    expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
-    expect(vm.user.lang).toBe(userLanguage);
-    await vm.updatePreferences();
-    expect(vm.locale).toBe(userLanguage);
-  });
+    it('should change user language and update preferences', async () => {
+        const userLanguage = 'es';
+        await vm.saveLanguage(userLanguage);
+        expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
+        expect(vm.user.lang).toBe(userLanguage);
+        vm.updatePreferences();
+        expect(vm.locale).toBe(userLanguage);
+    });
 
-  it('should update user data', async () => {
-    const key = 'name';
-    const value = 'itboss';
-    await vm.saveUserData(key, value);
-    expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value });
-  });
-});
\ No newline at end of file
+    it('should update user data', async () => {
+        const key = 'name';
+        const value = 'itboss';
+        await vm.saveUserData(key, value);
+        expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value });
+    });
+});
diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 44002c22aad..0d80f43ce94 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -10,11 +10,11 @@ import LeftMenu from 'components/LeftMenu.vue';
 import RightMenu from 'components/common/RightMenu.vue';
 const props = defineProps({
     dataKey: { type: String, required: true },
-    url: { type: String, default: undefined },
+    baseUrl: { type: String, default: undefined },
+    customUrl: { type: String, default: undefined },
     filter: { type: Object, default: () => {} },
     descriptor: { type: Object, required: true },
     filterPanel: { type: Object, default: undefined },
-    idInWhere: { type: Boolean, default: false },
     searchDataKey: { type: String, default: undefined },
     searchbarProps: { type: Object, default: undefined },
     redirectOnError: { type: Boolean, default: false },
@@ -23,20 +23,25 @@ const props = defineProps({
 const stateStore = useStateStore();
 const route = useRoute();
 const router = useRouter();
+const url = computed(() => {
+    if (props.baseUrl) {
+        return `${props.baseUrl}/${route.params.id}`;
+    }
+    return props.customUrl;
+});
 const searchRightDataKey = computed(() => {
     if (!props.searchDataKey) return route.name;
     return props.searchDataKey;
 });
-
 const arrayData = useArrayData(props.dataKey, {
-    url: props.url,
-    userFilter: props.filter,
-    oneRecord: true,
+    url: url.value,
+    filter: props.filter,
 });
 
 onBeforeMount(async () => {
     try {
-        await fetch(route.params.id);
+        if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
+        await arrayData.fetch({ append: false, updateRouter: false });
     } catch {
         const { matched: matches } = router.currentRoute.value;
         const { path } = matches.at(-1);
@@ -44,17 +49,13 @@ onBeforeMount(async () => {
     }
 });
 
-onBeforeRouteUpdate(async (to, from) => {
-    const id = to.params.id;
-    if (id !== from.params.id) await fetch(id, true);
-});
-
-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}`);
-    await arrayData.fetch({ append, updateRouter: false });
+if (props.baseUrl) {
+    onBeforeRouteUpdate(async (to, from) => {
+        if (to.params.id !== from.params.id) {
+            arrayData.store.url = `${props.baseUrl}/${to.params.id}`;
+            await arrayData.fetch({ append: false, updateRouter: false });
+        }
+    });
 }
 </script>
 <template>
@@ -82,7 +83,7 @@ async function fetch(id, append = false) {
         <QPage>
             <VnSubToolbar />
             <div :class="[useCardSize(), $attrs.class]">
-                <RouterView :key="$route.path" />
+                <RouterView :key="route.path" />
             </div>
         </QPage>
     </QPageContainer>
diff --git a/src/components/common/VnCardBeta.vue b/src/components/common/VnCardBeta.vue
index 7c82316dc44..f237a300ca3 100644
--- a/src/components/common/VnCardBeta.vue
+++ b/src/components/common/VnCardBeta.vue
@@ -1,6 +1,6 @@
 <script setup>
-import { onBeforeMount } from 'vue';
-import { useRouter, onBeforeRouteUpdate } from 'vue-router';
+import { onBeforeMount, computed } from 'vue';
+import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
 import { useArrayData } from 'src/composables/useArrayData';
 import { useStateStore } from 'stores/useStateStore';
 import useCardSize from 'src/composables/useCardSize';
@@ -9,9 +9,10 @@ import VnSubToolbar from '../ui/VnSubToolbar.vue';
 
 const props = defineProps({
     dataKey: { type: String, required: true },
-    url: { type: String, default: undefined },
-    idInWhere: { type: Boolean, default: false },
+    baseUrl: { type: String, default: undefined },
+    customUrl: { type: String, default: undefined },
     filter: { type: Object, default: () => {} },
+    userFilter: { type: Object, default: () => {} },
     descriptor: { type: Object, required: true },
     filterPanel: { type: Object, default: undefined },
     searchDataKey: { type: String, default: undefined },
@@ -20,42 +21,46 @@ const props = defineProps({
 });
 
 const stateStore = useStateStore();
+const route = useRoute();
 const router = useRouter();
+const url = computed(() => {
+    if (props.baseUrl) {
+        return `${props.baseUrl}/${route.params.id}`;
+    }
+    return props.customUrl;
+});
+
 const arrayData = useArrayData(props.dataKey, {
-    url: props.url,
-    userFilter: props.filter,
-    oneRecord: true,
+    url: url.value,
+    filter: props.filter,
+    userFilter: props.userFilter,
 });
 
 onBeforeMount(async () => {
-    const route = router.currentRoute.value;
     try {
-        await fetch(route.params.id);
+        if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
+        await arrayData.fetch({ append: false, updateRouter: false });
     } catch {
-        const { matched: matches } = route;
+        const { matched: matches } = router.currentRoute.value;
         const { path } = matches.at(-1);
         router.push({ path: path.replace(/:id.*/, '') });
     }
 });
 
-onBeforeRouteUpdate(async (to, from) => {
-    if (hasRouteParam(to.params)) {
-        const { matched } = router.currentRoute.value;
-        const { name } = matched.at(-3);
-        if (name) {
-            router.push({ name, params: to.params });
+if (props.baseUrl) {
+    onBeforeRouteUpdate(async (to, from) => {
+        if (hasRouteParam(to.params)) {
+            const { matched } = router.currentRoute.value;
+            const { name } = matched.at(-3);
+            if (name) {
+                router.push({ name, params: to.params });
+            }
         }
-    }
-    const id = to.params.id;
-    if (id !== from.params.id) await fetch(id, true);
-});
-
-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}`);
-    await arrayData.fetch({ append, updateRouter: false });
+        if (to.params.id !== from.params.id) {
+            arrayData.store.url = `${props.baseUrl}/${to.params.id}`;
+            await arrayData.fetch({ append: false, updateRouter: false });
+        }
+    });
 }
 function hasRouteParam(params, valueToCheck = ':addressId') {
     return Object.values(params).includes(valueToCheck);
@@ -69,6 +74,6 @@ function hasRouteParam(params, valueToCheck = ':addressId') {
     </Teleport>
     <VnSubToolbar />
     <div :class="[useCardSize(), $attrs.class]">
-        <RouterView :key="$route.path" />
+        <RouterView :key="route.path" />
     </div>
 </template>
diff --git a/src/components/common/VnCheckbox.vue b/src/components/common/VnCheckbox.vue
deleted file mode 100644
index 27131d45e2d..00000000000
--- a/src/components/common/VnCheckbox.vue
+++ /dev/null
@@ -1,43 +0,0 @@
-<script setup>
-import { computed } from 'vue';
-
-const model = defineModel({ type: [Number, Boolean] });
-const $props = defineProps({
-    info: {
-        type: String,
-        default: null,
-    },
-});
-
-const checkboxModel = computed({
-    get() {
-        if (typeof model.value === 'number') {
-            return model.value !== 0;
-        }
-        return model.value;
-    },
-    set(value) {
-        if (typeof model.value === 'number') {
-            model.value = value ? 1 : 0;
-        } else {
-            model.value = value;
-        }
-    },
-});
-</script>
-<template>
-    <div>
-        <QCheckbox v-bind="$attrs" v-on="$attrs" v-model="checkboxModel" />
-        <QIcon
-            v-if="info"
-            v-bind="$attrs"
-            class="cursor-info q-ml-sm"
-            name="info"
-            size="sm"
-        >
-            <QTooltip>
-                {{ info }}
-            </QTooltip>
-        </QIcon>
-    </div>
-</template>
diff --git a/src/components/common/VnColor.vue b/src/components/common/VnColor.vue
deleted file mode 100644
index 8a5a787b0ef..00000000000
--- a/src/components/common/VnColor.vue
+++ /dev/null
@@ -1,32 +0,0 @@
-<script setup>
-const $props = defineProps({
-    colors: {
-        type: String,
-        default: '{"value": []}',
-    },
-});
-
-const colorArray = JSON.parse($props.colors)?.value;
-const maxHeight = 30;
-const colorHeight = maxHeight / colorArray?.length;
-</script>
-<template>
-    <div v-if="colors" class="color-div" :style="{ height: `${maxHeight}px` }">
-        <div
-            v-for="(color, index) in colorArray"
-            :key="index"
-            :style="{
-                backgroundColor: `#${color}`,
-                height: `${colorHeight}px`,
-            }"
-        >
-            &nbsp;
-        </div>
-    </div>
-</template>
-<style scoped>
-.color-div {
-    display: flex;
-    flex-direction: column;
-}
-</style>
diff --git a/src/components/common/VnComponent.vue b/src/components/common/VnComponent.vue
index a9e1c8cffc9..580bcf34836 100644
--- a/src/components/common/VnComponent.vue
+++ b/src/components/common/VnComponent.vue
@@ -17,8 +17,6 @@ const $props = defineProps({
     },
 });
 
-const emit = defineEmits(['blur']);
-
 const componentArray = computed(() => {
     if (typeof $props.prop === 'object') return [$props.prop];
     return $props.prop;
@@ -48,8 +46,7 @@ function toValueAttrs(attrs) {
     <span
         v-for="toComponent of componentArray"
         :key="toComponent.name"
-        class="column fit"
-        :class="toComponent?.component == 'checkbox' ? 'flex-center' : ''"
+        class="column flex-center fit"
     >
         <component
             v-if="toComponent?.component"
@@ -57,7 +54,6 @@ function toValueAttrs(attrs) {
             v-bind="mix(toComponent).attrs"
             v-on="mix(toComponent).event ?? {}"
             v-model="model"
-            @blur="emit('blur')"
         />
     </span>
 </template>
diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue
index 424781a2695..36c87bab050 100644
--- a/src/components/common/VnDmsList.vue
+++ b/src/components/common/VnDmsList.vue
@@ -17,7 +17,7 @@ import { useSession } from 'src/composables/useSession';
 const route = useRoute();
 const quasar = useQuasar();
 const { t } = useI18n();
-const rows = ref([]);
+const rows = ref();
 const dmsRef = ref();
 const formDialog = ref({});
 const token = useSession().getTokenMultimedia();
@@ -389,14 +389,6 @@ defineExpose({
                     </div>
                 </template>
             </QTable>
-            <div 
-                v-else 
-                class="info-row q-pa-md text-center"
-            >
-                <h5>
-                    {{ t('No data to display') }}
-                </h5>
-            </div>
         </template>
     </VnPaginate>
     <QDialog v-model="formDialog.show">
@@ -413,7 +405,7 @@ defineExpose({
             fab
             color="primary"
             icon="add"
-            v-shortcut
+            shortcut="+"
             @click="showFormDialog()"
             class="fill-icon"
         >
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index aeb4a31fd4b..78f08a47991 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -11,7 +11,6 @@ const emit = defineEmits([
     'update:options',
     'keyup.enter',
     'remove',
-    'blur',
 ]);
 
 const $props = defineProps({
@@ -137,7 +136,6 @@ const handleUppercase = () => {
             :type="$attrs.type"
             :class="{ required: isRequired }"
             @keyup.enter="emit('keyup.enter')"
-            @blur="emit('blur')"
             @keydown="handleKeydown"
             :clearable="false"
             :rules="mixinRules"
@@ -145,7 +143,7 @@ const handleUppercase = () => {
             hide-bottom-space
             :data-cy="$attrs.dataCy ?? $attrs.label + '_input'"
         >
-            <template #prepend v-if="$slots.prepend">
+            <template #prepend>
                 <slot name="prepend" />
             </template>
             <template #append>
@@ -170,11 +168,11 @@ const handleUppercase = () => {
                         }
                     "
                 ></QIcon>
-
+                
                 <QIcon
                     name="match_case"
                     size="xs"
-                    v-if="!$attrs.disabled && !$attrs.readonly && $props.uppercase"
+                    v-if="!$attrs.disabled && !($attrs.readonly) && $props.uppercase"
                     @click="handleUppercase"
                     class="uppercase-icon"
                 >
@@ -182,7 +180,7 @@ const handleUppercase = () => {
                         {{ t('Convert to uppercase') }}
                     </QTooltip>
                 </QIcon>
-
+                
                 <slot name="append" v-if="$slots.append && !$attrs.disabled" />
                 <QIcon v-if="info" name="info">
                     <QTooltip max-width="350px">
@@ -196,15 +194,13 @@ const handleUppercase = () => {
 
 <style>
 .uppercase-icon {
-    transition:
-        color 0.3s,
-        transform 0.2s;
-    cursor: pointer;
+  transition: color 0.3s, transform 0.2s;
+  cursor: pointer;
 }
 
 .uppercase-icon:hover {
-    color: #ed9937;
-    transform: scale(1.2);
+  color: #ed9937;
+  transform: scale(1.2);
 }
 </style>
 <i18n>
@@ -218,4 +214,4 @@ const handleUppercase = () => {
         maxLength: El valor excede los {value} carácteres
         inputMax: Debe ser menor a {value}
         Convert to uppercase: Convertir a mayúsculas
-</i18n>
+</i18n>
\ No newline at end of file
diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue
index 73c825e1e26..a8888aad84b 100644
--- a/src/components/common/VnInputDate.vue
+++ b/src/components/common/VnInputDate.vue
@@ -42,7 +42,7 @@ const formattedDate = computed({
                 if (value.at(2) == '/') value = value.split('/').reverse().join('/');
                 value = date.formatDate(
                     new Date(value).toISOString(),
-                    'YYYY-MM-DDTHH:mm:ss.SSSZ',
+                    'YYYY-MM-DDTHH:mm:ss.SSSZ'
                 );
             }
             const [year, month, day] = value.split('-').map((e) => parseInt(e));
@@ -55,7 +55,7 @@ const formattedDate = computed({
                     orgDate.getHours(),
                     orgDate.getMinutes(),
                     orgDate.getSeconds(),
-                    orgDate.getMilliseconds(),
+                    orgDate.getMilliseconds()
                 );
             }
         }
@@ -64,7 +64,7 @@ const formattedDate = computed({
 });
 
 const popupDate = computed(() =>
-    model.value ? date.formatDate(new Date(model.value), 'YYYY/MM/DD') : model.value,
+    model.value ? date.formatDate(new Date(model.value), 'YYYY/MM/DD') : model.value
 );
 onMounted(() => {
     // fix quasar bug
@@ -73,7 +73,7 @@ onMounted(() => {
 watch(
     () => model.value,
     (val) => (formattedDate.value = val),
-    { immediate: true },
+    { immediate: true }
 );
 
 const styleAttrs = computed(() => {
diff --git a/src/components/common/VnInputNumber.vue b/src/components/common/VnInputNumber.vue
index 274f78b21a7..165cfae3d06 100644
--- a/src/components/common/VnInputNumber.vue
+++ b/src/components/common/VnInputNumber.vue
@@ -8,7 +8,6 @@ defineProps({
 });
 
 const model = defineModel({ type: [Number, String] });
-const emit = defineEmits(['blur']);
 </script>
 <template>
     <VnInput
@@ -25,6 +24,5 @@ const emit = defineEmits(['blur']);
                     model = parseFloat(val).toFixed(decimalPlaces);
             }
         "
-        @blur="emit('blur')"
     />
 </template>
diff --git a/src/components/common/VnPopupProxy.vue b/src/components/common/VnPopupProxy.vue
deleted file mode 100644
index f386bfff811..00000000000
--- a/src/components/common/VnPopupProxy.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-
-defineProps({
-    label: {
-        type: String,
-        default: '',
-    },
-    icon: {
-        type: String,
-        required: true,
-        default: null,
-    },
-    color: {
-        type: String,
-        default: 'primary',
-    },
-    tooltip: {
-        type: String,
-        default: null,
-    },
-});
-const popupProxyRef = ref(null);
-</script>
-
-<template>
-    <QBtn :color="$props.color" :icon="$props.icon" :label="$t($props.label)">
-        <template #default>
-            <slot name="extraIcon"></slot>
-            <QPopupProxy ref="popupProxyRef" style="max-width: none">
-                <QCard>
-                    <slot :popup="popupProxyRef"></slot>
-                </QCard>
-            </QPopupProxy>
-            <QTooltip>{{ $t($props.tooltip) }}</QTooltip>
-        </template>
-    </QBtn>
-</template>
diff --git a/src/components/common/VnSection.vue b/src/components/common/VnSection.vue
index 4bd17124f3e..ef65b841f07 100644
--- a/src/components/common/VnSection.vue
+++ b/src/components/common/VnSection.vue
@@ -106,14 +106,7 @@ function checkIsMain() {
                     :data-key="dataKey"
                     :array-data="arrayData"
                     :columns="columns"
-                >
-                    <template #moreFilterPanel="{ params, orders, searchFn }">
-                        <slot
-                            name="moreFilterPanel"
-                            v-bind="{ params, orders, searchFn }"
-                        />
-                    </template>
-                </VnTableFilter>
+                />
             </slot>
         </template>
     </RightAdvancedMenu>
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index 339f90e0ef8..95fe80a699e 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -10,12 +10,7 @@ const emit = defineEmits(['update:modelValue', 'update:options', 'remove']);
 const $attrs = useAttrs();
 const { t } = useI18n();
 
-const isRequired = computed(() => {
-    return useRequired($attrs).isRequired;
-});
-const requiredFieldRule = computed(() => {
-    return useRequired($attrs).requiredFieldRule;
-});
+const { isRequired, requiredFieldRule } = useRequired($attrs);
 
 const $props = defineProps({
     modelValue: {
@@ -171,8 +166,7 @@ onMounted(() => {
 });
 
 const arrayDataKey =
-    $props.dataKey ??
-    ($props.url?.length > 0 ? $props.url : ($attrs.name ?? $attrs.label));
+    $props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
 
 const arrayData = useArrayData(arrayDataKey, {
     url: $props.url,
@@ -221,7 +215,7 @@ async function fetchFilter(val) {
         optionFilterValue.value ??
         (new RegExp(/\d/g).test(val)
             ? optionValue.value
-            : (optionFilter.value ?? optionLabel.value));
+            : optionFilter.value ?? optionLabel.value);
 
     let defaultWhere = {};
     if ($props.filterOptions.length) {
@@ -240,7 +234,7 @@ async function fetchFilter(val) {
 
     const { data } = await arrayData.applyFilter(
         { filter: filterOptions },
-        { updateRouter: false },
+        { updateRouter: false }
     );
     setOptions(data);
     return data;
@@ -273,7 +267,7 @@ async function filterHandler(val, update) {
                 ref.setOptionIndex(-1);
                 ref.moveOptionSelection(1, true);
             }
-        },
+        }
     );
 }
 
@@ -309,7 +303,7 @@ function handleKeyDown(event) {
         if (inputValue) {
             const matchingOption = myOptions.value.find(
                 (option) =>
-                    option[optionLabel.value].toLowerCase() === inputValue.toLowerCase(),
+                    option[optionLabel.value].toLowerCase() === inputValue.toLowerCase()
             );
 
             if (matchingOption) {
@@ -321,11 +315,11 @@ function handleKeyDown(event) {
         }
 
         const focusableElements = document.querySelectorAll(
-            'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])',
+            'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])'
         );
         const currentIndex = Array.prototype.indexOf.call(
             focusableElements,
-            event.target,
+            event.target
         );
         if (currentIndex >= 0 && currentIndex < focusableElements.length - 1) {
             focusableElements[currentIndex + 1].focus();
diff --git a/src/components/common/VnSelectCache.vue b/src/components/common/VnSelectCache.vue
index f0f3357f60f..29cf22dc548 100644
--- a/src/components/common/VnSelectCache.vue
+++ b/src/components/common/VnSelectCache.vue
@@ -14,7 +14,7 @@ const $props = defineProps({
     },
 });
 const options = ref([]);
-const emit = defineEmits(['blur']);
+
 onBeforeMount(async () => {
     const { url, optionValue, optionLabel } = useAttrs();
     const findBy = $props.find ?? url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1);
@@ -35,5 +35,5 @@ onBeforeMount(async () => {
 });
 </script>
 <template>
-    <VnSelect v-bind="$attrs" :options="$attrs.options ?? options" @blur="emit('blur')" />
+    <VnSelect v-bind="$attrs" :options="$attrs.options ?? options" />
 </template>
diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue
index 41730b21792..a4cd0011d29 100644
--- a/src/components/common/VnSelectDialog.vue
+++ b/src/components/common/VnSelectDialog.vue
@@ -37,6 +37,7 @@ const isAllowedToCreate = computed(() => {
 
 defineExpose({ vnSelectDialogRef: select });
 </script>
+
 <template>
     <VnSelect
         ref="select"
@@ -66,6 +67,7 @@ defineExpose({ vnSelectDialogRef: select });
         </template>
     </VnSelect>
 </template>
+
 <style lang="scss" scoped>
 .default-icon {
     cursor: pointer;
diff --git a/src/components/common/VnSelectSupplier.vue b/src/components/common/VnSelectSupplier.vue
index 5b52ae75b24..f86db4f2df0 100644
--- a/src/components/common/VnSelectSupplier.vue
+++ b/src/components/common/VnSelectSupplier.vue
@@ -1,7 +1,9 @@
 <script setup>
+import { computed } from 'vue';
 import VnSelect from 'components/common/VnSelect.vue';
 
 const model = defineModel({ type: [String, Number, Object] });
+const url = 'Suppliers';
 </script>
 
 <template>
@@ -9,13 +11,11 @@ const model = defineModel({ type: [String, Number, Object] });
         :label="$t('globals.supplier')"
         v-bind="$attrs"
         v-model="model"
-        url="Suppliers"
+        :url="url"
         option-value="id"
         option-label="nickname"
         :fields="['id', 'name', 'nickname', 'nif']"
-        :filter-options="['id', 'name', 'nickname', 'nif']"
         sort-by="name ASC"
-        data-cy="vnSupplierSelect"
     >
         <template #option="scope">
             <QItem v-bind="scope.itemProps">
diff --git a/src/components/common/VnSelectTravelExtended.vue b/src/components/common/VnSelectTravelExtended.vue
deleted file mode 100644
index 46538f5f91b..00000000000
--- a/src/components/common/VnSelectTravelExtended.vue
+++ /dev/null
@@ -1,50 +0,0 @@
-<script setup>
-import VnSelectDialog from './VnSelectDialog.vue';
-import FilterTravelForm from 'src/components/FilterTravelForm.vue';
-import { useI18n } from 'vue-i18n';
-import { toDate } from 'src/filters';
-const { t } = useI18n();
-
-const $props = defineProps({
-    data: {
-        type: Object,
-        required: true,
-    },
-    onFilterTravelSelected: {
-        type: Function,
-        required: true,
-    },
-});
-</script>
-<template>
-    <VnSelectDialog
-        :label="t('entry.basicData.travel')"
-        v-bind="$attrs"
-        url="Travels/filter"
-        :fields="['id', 'warehouseInName']"
-        option-value="id"
-        option-label="warehouseInName"
-        map-options
-        hide-selected
-        :required="true"
-        action-icon="filter_alt"
-        :roles-allowed-to-create="['buyer']"
-    >
-        <template #form>
-            <FilterTravelForm @travel-selected="onFilterTravelSelected(data, $event)" />
-        </template>
-        <template #option="scope">
-            <QItem v-bind="scope.itemProps">
-                <QItemSection>
-                    <QItemLabel>
-                        {{ scope.opt?.agencyModeName }} -
-                        {{ scope.opt?.warehouseInName }}
-                        ({{ toDate(scope.opt?.shipped) }}) →
-                        {{ scope.opt?.warehouseOutName }}
-                        ({{ toDate(scope.opt?.landed) }})
-                    </QItemLabel>
-                </QItemSection>
-            </QItem>
-        </template>
-    </VnSelectDialog>
-</template>
diff --git a/src/components/common/__tests__/VnNotes.spec.js b/src/components/common/__tests__/VnNotes.spec.js
index 2603bf03c9a..8f24a7f1429 100644
--- a/src/components/common/__tests__/VnNotes.spec.js
+++ b/src/components/common/__tests__/VnNotes.spec.js
@@ -1,78 +1,51 @@
-import {
-    describe,
-    it,
-    expect,
-    vi,
-    beforeAll,
-    afterEach,
-    beforeEach,
-    afterAll,
-} from 'vitest';
+import { describe, it, expect, vi, beforeAll, afterEach, beforeEach } from 'vitest';
 import { createWrapper, axios } from 'app/test/vitest/helper';
 import VnNotes from 'src/components/ui/VnNotes.vue';
-import vnDate from 'src/boot/vnDate';
 
 describe('VnNotes', () => {
     let vm;
     let wrapper;
     let spyFetch;
     let postMock;
-    let patchMock;
-    let expectedInsertBody;
-    let expectedUpdateBody;
-    const defaultOptions = {
-        url: '/test',
-        body: { name: 'Tony', lastName: 'Stark' },
-        selectType: false,
-        saveUrl: null,
-        justInput: false,
-    };
-    function generateWrapper(
-        options = defaultOptions,
-        text = null,
-        observationType = null,
-    ) {
-        vi.spyOn(axios, 'get').mockResolvedValue({ data: [] });
+    let expectedBody;
+    const mockData= {name: 'Tony', lastName: 'Stark', text: 'Test Note', observationTypeFk: 1};
+
+    function generateExpectedBody() {
+        expectedBody = {...vm.$props.body, ...{ text: vm.newNote.text, observationTypeFk: vm.newNote.observationTypeFk }};
+    }
+
+    async function setTestParams(text, observationType, type){
+        vm.newNote.text = text;
+        vm.newNote.observationTypeFk = observationType;
+        wrapper.setProps({ selectType: type });
+    }
+
+    beforeAll(async () => {        
+        vi.spyOn(axios, 'get').mockReturnValue({ data: [] });
+
         wrapper = createWrapper(VnNotes, {
-            propsData: options,
+            propsData: {
+                url: '/test',
+                body: { name: 'Tony', lastName: 'Stark' },
+            }
         });
         wrapper = wrapper.wrapper;
         vm = wrapper.vm;
-        vm.newNote.text = text;
-        vm.newNote.observationTypeFk = observationType;
-    }
-
-    function createSpyFetch() {
-        spyFetch = vi.spyOn(vm.$refs.vnPaginateRef, 'fetch');
-    }
-
-    function generateExpectedBody() {
-        expectedInsertBody = {
-            ...vm.$props.body,
-            ...{ text: vm.newNote.text, observationTypeFk: vm.newNote.observationTypeFk },
-        };
-        expectedUpdateBody = { ...vm.$props.body, ...{ notes: vm.newNote.text } };
-    }
+    });
 
     beforeEach(() => {
-        postMock = vi.spyOn(axios, 'post');
-        patchMock = vi.spyOn(axios, 'patch');
+        postMock = vi.spyOn(axios, 'post').mockResolvedValue(mockData);
+        spyFetch = vi.spyOn(vm.vnPaginateRef, 'fetch').mockImplementation(() => vi.fn());
     });
 
     afterEach(() => {
         vi.clearAllMocks();
-        expectedInsertBody = {};
-        expectedUpdateBody = {};
-    });
-
-    afterAll(() => {
-        vi.restoreAllMocks();
+        expectedBody = {};
     });
 
     describe('insert', () => {
-        it('should not call axios.post and vnPaginateRef.fetch when newNote.text is null', async () => {
-            generateWrapper({ selectType: true });
-            createSpyFetch();
+        it('should not call axios.post and vnPaginateRef.fetch if newNote.text is null', async () => {
+            await setTestParams( null, null, true );
 
             await vm.insert();
 
@@ -80,9 +53,8 @@ describe('VnNotes', () => {
             expect(spyFetch).not.toHaveBeenCalled();
         });
 
-        it('should not call axios.post and vnPaginateRef.fetch when newNote.text is empty', async () => {
-            generateWrapper(null, '');
-            createSpyFetch();
+        it('should not call axios.post and vnPaginateRef.fetch if newNote.text is empty', async () => {
+            await setTestParams( "", null, false );
 
             await vm.insert();
 
@@ -90,9 +62,8 @@ describe('VnNotes', () => {
             expect(spyFetch).not.toHaveBeenCalled();
         });
 
-        it('should not call axios.post and vnPaginateRef.fetch when observationTypeFk is null and selectType is true', async () => {
-            generateWrapper({ selectType: true }, 'Test Note');
-            createSpyFetch();
+        it('should not call axios.post and vnPaginateRef.fetch if observationTypeFk is missing and selectType is true', async () => {
+            await setTestParams( "Test Note", null, true );
 
             await vm.insert();
 
@@ -100,57 +71,37 @@ describe('VnNotes', () => {
             expect(spyFetch).not.toHaveBeenCalled();
         });
 
-        it('should call axios.post and vnPaginateRef.fetch when observationTypeFk is missing and selectType is false', async () => {
-            generateWrapper(null, 'Test Note');
-            createSpyFetch();
+        it('should call axios.post and vnPaginateRef.fetch if observationTypeFk is missing and selectType is false', async () => {
+            await setTestParams( "Test Note", null, false );
+
             generateExpectedBody();
 
             await vm.insert();
 
-            expect(postMock).toHaveBeenCalledWith(vm.$props.url, expectedInsertBody);
+            expect(postMock).toHaveBeenCalledWith(vm.$props.url, expectedBody);
+            expect(spyFetch).toHaveBeenCalled();
+        });
+
+        it('should call axios.post and vnPaginateRef.fetch if observationTypeFk is setted and selectType is false', async () => {            
+            await setTestParams( "Test Note", 1, false );
+
+            generateExpectedBody();
+
+            await vm.insert();
+
+            expect(postMock).toHaveBeenCalledWith(vm.$props.url, expectedBody);
             expect(spyFetch).toHaveBeenCalled();
         });
 
         it('should call axios.post and vnPaginateRef.fetch when newNote is valid', async () => {
-            generateWrapper({ selectType: true }, 'Test Note', 1);
-            createSpyFetch();
-            generateExpectedBody();
+            await setTestParams( "Test Note", 1, true );
 
+            generateExpectedBody();
+            
             await vm.insert();
 
-            expect(postMock).toHaveBeenCalledWith(vm.$props.url, expectedInsertBody);
+            expect(postMock).toHaveBeenCalledWith(vm.$props.url, expectedBody);
             expect(spyFetch).toHaveBeenCalled();
         });
     });
-
-    describe('update', () => {
-        it('should call axios.patch with saveUrl when saveUrl is set and justInput is true', async () => {
-            generateWrapper({
-                url: '/business',
-                justInput: true,
-                saveUrl: '/saveUrlTest',
-            });
-            generateExpectedBody();
-
-            await vm.update();
-
-            expect(patchMock).toHaveBeenCalledWith(vm.$props.saveUrl, expectedUpdateBody);
-        });
-
-        it('should call axios.patch with url when saveUrl is not set and justInput is true', async () => {
-            generateWrapper({
-                url: '/business',
-                body: { workerFk: 1110 },
-                justInput: true,
-            });
-            generateExpectedBody();
-
-            await vm.update();
-
-            expect(patchMock).toHaveBeenCalledWith(
-                `${vm.$props.url}/${vm.$props.body.workerFk}`,
-                expectedUpdateBody,
-            );
-        });
-    });
-});
+});
\ No newline at end of file
diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue
index e6e7e6fa0f1..43dc15e9bfc 100644
--- a/src/components/ui/CardDescriptor.vue
+++ b/src/components/ui/CardDescriptor.vue
@@ -6,7 +6,6 @@ import { useArrayData } from 'composables/useArrayData';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import { useState } from 'src/composables/useState';
 import { useRoute } from 'vue-router';
-import { useClipboard } from 'src/composables/useClipboard';
 import VnMoreOptions from './VnMoreOptions.vue';
 
 const $props = defineProps({
@@ -30,6 +29,10 @@ const $props = defineProps({
         type: String,
         default: null,
     },
+    module: {
+        type: String,
+        default: null,
+    },
     summary: {
         type: Object,
         default: null,
@@ -43,7 +46,6 @@ const $props = defineProps({
 const state = useState();
 const route = useRoute();
 const { t } = useI18n();
-const { copyText } = useClipboard();
 const { viewSummary } = useSummaryDialog();
 let arrayData;
 let store;
@@ -55,13 +57,12 @@ defineExpose({ getData });
 onBeforeMount(async () => {
     arrayData = useArrayData($props.dataKey, {
         url: $props.url,
-        userFilter: $props.filter,
+        filter: $props.filter,
         skip: 0,
-        oneRecord: true,
     });
     store = arrayData.store;
     entity = computed(() => {
-        const data = store.data ?? {};
+        const data = (Array.isArray(store.data) ? store.data[0] : store.data) ?? {};
         if (data) emit('onFetch', data);
         return data;
     });
@@ -72,7 +73,7 @@ onBeforeMount(async () => {
         () => [$props.url, $props.filter],
         async () => {
             if (!isSameDataKey.value) await getData();
-        },
+        }
     );
 });
 
@@ -83,7 +84,7 @@ async function getData() {
     try {
         const { data } = await arrayData.fetch({ append: false, updateRouter: false });
         state.set($props.dataKey, data);
-        emit('onFetch', data);
+        emit('onFetch', Array.isArray(data) ? data[0] : data);
     } finally {
         isLoading.value = false;
     }
@@ -101,21 +102,13 @@ function getValueFromPath(path) {
     return current;
 }
 
-function copyIdText(id) {
-    copyText(id, {
-        component: {
-            copyValue: id,
-        },
-    });
-}
-
 const emit = defineEmits(['onFetch']);
 
 const iconModule = computed(() => route.matched[1].meta.icon);
 const toModule = computed(() =>
     route.matched[1].path.split('/').length > 2
         ? route.matched[1].redirect
-        : route.matched[1].children[0].redirect,
+        : route.matched[1].children[0].redirect
 );
 </script>
 
@@ -154,9 +147,7 @@ const toModule = computed(() =>
                         {{ t('components.smartCard.openSummary') }}
                     </QTooltip>
                 </QBtn>
-                <RouterLink
-                    :to="{ name: `${dataKey}Summary`, params: { id: entity.id } }"
-                >
+                <RouterLink :to="{ name: `${module}Summary`, params: { id: entity.id } }">
                     <QBtn
                         class="link"
                         color="white"
@@ -192,22 +183,9 @@ const toModule = computed(() =>
                             </slot>
                         </div>
                     </QItemLabel>
-                    <QItem>
+                    <QItem dense>
                         <QItemLabel class="subtitle" caption>
                             #{{ getValueFromPath(subtitle) ?? entity.id }}
-                            <QBtn
-                                round
-                                flat
-                                dense
-                                size="sm"
-                                icon="content_copy"
-                                color="primary"
-                                @click.stop="copyIdText(entity.id)"
-                            >
-                                <QTooltip>
-                                    {{ t('globals.copyId') }}
-                                </QTooltip>
-                            </QBtn>
                         </QItemLabel>
                     </QItem>
                 </QList>
@@ -315,11 +293,3 @@ const toModule = computed(() =>
     }
 }
 </style>
-<i18n>
-    en:
-        globals:
-            copyId: Copy ID
-    es:
-        globals:
-            copyId: Copiar ID
-</i18n>
diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue
index 6a61994c1db..c815b8e1602 100644
--- a/src/components/ui/CardSummary.vue
+++ b/src/components/ui/CardSummary.vue
@@ -40,10 +40,9 @@ const arrayData = useArrayData(props.dataKey, {
     filter: props.filter,
     userFilter: props.userFilter,
     skip: 0,
-    oneRecord: true,
 });
 const { store } = arrayData;
-const entity = computed(() => store.data);
+const entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
 const isLoading = ref(false);
 
 defineExpose({
@@ -62,7 +61,7 @@ async function fetch() {
     store.filter = props.filter ?? {};
     isLoading.value = true;
     const { data } = await arrayData.fetch({ append: false, updateRouter: false });
-    emit('onFetch', data);
+    emit('onFetch', Array.isArray(data) ? data[0] : data);
     isLoading.value = false;
 }
 </script>
@@ -209,13 +208,4 @@ async function fetch() {
 .summaryHeader {
     color: $white;
 }
-
-.cardSummary :deep(.q-card__section[content]) {
-    display: flex;
-    flex-wrap: wrap;
-    padding: 0;
-    > * {
-        flex: 1;
-    }
-}
 </style>
diff --git a/src/components/ui/SkeletonDescriptor.vue b/src/components/ui/SkeletonDescriptor.vue
index f9188221a22..9679751f568 100644
--- a/src/components/ui/SkeletonDescriptor.vue
+++ b/src/components/ui/SkeletonDescriptor.vue
@@ -1,32 +1,53 @@
-<script setup>
-defineProps({
-    hasImage: {
-        type: Boolean,
-        default: false,
-    },
-});
-</script>
 <template>
-    <div id="descriptor-skeleton" class="bg-vn-page">
+    <div id="descriptor-skeleton">
         <div class="row justify-between q-pa-sm">
-            <QSkeleton square size="30px" v-for="i in 3" :key="i" />
+            <QSkeleton square size="40px" />
+            <QSkeleton square size="40px" />
+            <QSkeleton square height="40px" width="20px" />
         </div>
-        <div class="q-pa-xs" v-if="hasImage">
-            <QSkeleton square height="200px" width="100%" />
+        <div class="col justify-between q-pa-sm q-gutter-y-xs">
+            <QSkeleton square height="40px" width="150px" />
+            <QSkeleton square height="30px" width="70px" />
         </div>
-        <div class="col justify-between q-pa-md q-gutter-y-xs">
-            <QSkeleton square height="25px" width="150px" />
-            <QSkeleton square height="15px" width="70px" />
-        </div>
-        <div class="q-pl-sm q-pa-sm q-mb-md">
-            <div class="row q-gutter-x-sm q-pa-none q-ma-none" v-for="i in 5" :key="i">
-                <QSkeleton type="text" square height="20px" width="30%" />
-                <QSkeleton type="text" square height="20px" width="60%" />
+        <div class="col q-pl-sm q-pa-sm q-mb-md">
+            <div class="row justify-between">
+                <QSkeleton type="text" square height="30px" width="20%" />
+                <QSkeleton type="text" square height="30px" width="60%" />
+            </div>
+            <div class="row justify-between">
+                <QSkeleton type="text" square height="30px" width="20%" />
+                <QSkeleton type="text" square height="30px" width="60%" />
+            </div>
+            <div class="row justify-between">
+                <QSkeleton type="text" square height="30px" width="20%" />
+                <QSkeleton type="text" square height="30px" width="60%" />
+            </div>
+            <div class="row justify-between">
+                <QSkeleton type="text" square height="30px" width="20%" />
+                <QSkeleton type="text" square height="30px" width="60%" />
+            </div>
+            <div class="row justify-between">
+                <QSkeleton type="text" square height="30px" width="20%" />
+                <QSkeleton type="text" square height="30px" width="60%" />
+            </div>
+            <div class="row justify-between">
+                <QSkeleton type="text" square height="30px" width="20%" />
+                <QSkeleton type="text" square height="30px" width="60%" />
             </div>
         </div>
 
-        <QCardActions class="q-gutter-x-sm justify-between">
-            <QSkeleton size="40px" v-for="i in 5" :key="i" />
+        <QCardActions>
+            <QSkeleton size="40px" />
+            <QSkeleton size="40px" />
+            <QSkeleton size="40px" />
+            <QSkeleton size="40px" />
+            <QSkeleton size="40px" />
         </QCardActions>
     </div>
 </template>
+
+<style lang="scss" scoped>
+#descriptor-skeleton .q-card__actions {
+    justify-content: space-between;
+}
+</style>
diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue
index c6f539879e1..a02b56bdb4e 100644
--- a/src/components/ui/VnConfirm.vue
+++ b/src/components/ui/VnConfirm.vue
@@ -82,7 +82,7 @@ function cancel() {
                     @click="cancel()"
                 />
             </QCardSection>
-            <QCardSection class="q-pb-none" data-cy="VnConfirm_message">
+            <QCardSection class="q-pb-none">
                 <span v-if="message !== false" v-html="message" />
             </QCardSection>
             <QCardSection class="row items-center q-pt-none">
@@ -95,7 +95,6 @@ function cancel() {
                     :disable="isLoading"
                     flat
                     @click="cancel()"
-                    data-cy="VnConfirm_cancel"
                 />
                 <QBtn
                     :label="t('globals.confirm')"
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
index d6b525dc86b..93f069cc6c8 100644
--- a/src/components/ui/VnFilterPanel.vue
+++ b/src/components/ui/VnFilterPanel.vue
@@ -114,7 +114,7 @@ async function clearFilters() {
         arrayData.resetPagination();
         // Filtrar los params no removibles
         const removableFilters = Object.keys(userParams.value).filter((param) =>
-            $props.unremovableParams.includes(param),
+            $props.unremovableParams.includes(param)
         );
         const newParams = {};
         // Conservar solo los params que no son removibles
@@ -162,13 +162,13 @@ const formatTags = (tags) => {
 
 const tags = computed(() => {
     const filteredTags = tagsList.value.filter(
-        (tag) => !($props.customTags || []).includes(tag.label),
+        (tag) => !($props.customTags || []).includes(tag.label)
     );
     return formatTags(filteredTags);
 });
 
 const customTags = computed(() =>
-    tagsList.value.filter((tag) => ($props.customTags || []).includes(tag.label)),
+    tagsList.value.filter((tag) => ($props.customTags || []).includes(tag.label))
 );
 
 async function remove(key) {
@@ -188,13 +188,10 @@ function formatValue(value) {
 const getLocale = (label) => {
     const param = label.split('.').at(-1);
     const globalLocale = `globals.params.${param}`;
-    const moduleName = route.meta.moduleName;
-    const moduleLocale = `${moduleName.toLowerCase()}.${param}`;
     if (te(globalLocale)) return t(globalLocale);
-    else if (te(moduleLocale)) return t(moduleLocale);
+    else if (te(t(`params.${param}`)));
     else {
-        const camelCaseModuleName =
-            moduleName.charAt(0).toLowerCase() + moduleName.slice(1);
+        const camelCaseModuleName = route.meta.moduleName.charAt(0).toLowerCase() + route.meta.moduleName.slice(1);    
         return t(`${camelCaseModuleName}.params.${param}`);
     }
 };
@@ -293,9 +290,6 @@ const getLocale = (label) => {
     />
 </template>
 <style scoped lang="scss">
-.q-field__label.no-pointer-events.absolute.ellipsis {
-    margin-left: 6px !important;
-}
 .list {
     width: 256px;
 }
diff --git a/src/components/ui/VnMoreOptions.vue b/src/components/ui/VnMoreOptions.vue
index 8a1c7a0f2ec..39e84be2bab 100644
--- a/src/components/ui/VnMoreOptions.vue
+++ b/src/components/ui/VnMoreOptions.vue
@@ -11,7 +11,7 @@
         <QTooltip>
             {{ $t('components.cardDescriptor.moreOptions') }}
         </QTooltip>
-        <QMenu ref="menuRef" data-cy="descriptor-more-opts-menu">
+        <QMenu ref="menuRef">
             <QList>
                 <slot name="menu" :menu-ref="$refs.menuRef" />
             </QList>
diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue
index ec6289a67ca..1690a94ba11 100644
--- a/src/components/ui/VnNotes.vue
+++ b/src/components/ui/VnNotes.vue
@@ -1,6 +1,6 @@
 <script setup>
 import axios from 'axios';
-import { ref, reactive, useAttrs, computed } from 'vue';
+import { ref, reactive } from 'vue';
 import { onBeforeRouteLeave } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { useQuasar } from 'quasar';
@@ -16,27 +16,12 @@ import VnSelect from 'components/common/VnSelect.vue';
 import FetchData from 'components/FetchData.vue';
 import VnInput from 'components/common/VnInput.vue';
 
-const emit = defineEmits(['onFetch']);
-
-const originalAttrs = useAttrs();
-
-const $attrs = computed(() => {
-    const { style, ...rest } = originalAttrs;
-    return rest;
-});
-
-const isRequired = computed(() => {
-    return Object.keys($attrs).includes('required')
-});
-
 const $props = defineProps({
     url: { type: String, default: null },
-    saveUrl: {type: String, default: null},
     filter: { type: Object, default: () => {} },
     body: { type: Object, default: () => {} },
     addNote: { type: Boolean, default: false },
     selectType: { type: Boolean, default: false },
-    justInput: { type: Boolean, default: false },
 });
 
 const { t } = useI18n();
@@ -44,13 +29,6 @@ const quasar = useQuasar();
 const newNote = reactive({ text: null, observationTypeFk: null });
 const observationTypes = ref([]);
 const vnPaginateRef = ref();
-let originalText;
-
-function handleClick(e) {
-    if (e.shiftKey && e.key === 'Enter') return;
-    if ($props.justInput) confirmAndUpdate();
-    else insert();
-}
 
 async function insert() {
     if (!newNote.text || ($props.selectType && !newNote.observationTypeFk)) return;
@@ -63,36 +41,8 @@ async function insert() {
     await axios.post($props.url, newBody);
     await vnPaginateRef.value.fetch();
 }
-
-function confirmAndUpdate() {
-    if(!newNote.text && originalText)
-        quasar
-            .dialog({
-                component: VnConfirm,
-                componentProps: {
-                    title: t('New note is empty'),
-                    message: t('Are you sure remove this note?'),
-                },
-            })
-            .onOk(update)
-            .onCancel(() => {
-                newNote.text = originalText;
-            });
-    else update();
-}
-
-async function update() {
-    originalText = newNote.text;
-    const body = $props.body;
-    const newBody = {
-        ...body,
-        ...{ notes: newNote.text },
-    };
-    await axios.patch(`${$props.saveUrl ?? `${$props.url}/${$props.body.workerFk}`}`, newBody);
-}
-
 onBeforeRouteLeave((to, from, next) => {
-    if ((newNote.text && !$props.justInput) || (newNote.text !== originalText) && $props.justInput)
+    if (newNote.text)
         quasar.dialog({
             component: VnConfirm,
             componentProps: {
@@ -103,13 +53,6 @@ onBeforeRouteLeave((to, from, next) => {
         });
     else next();
 });
-
-function fetchData([ data ]) {
-    newNote.text = data?.notes;
-    originalText = data?.notes;
-    emit('onFetch', data);
-}
-
 </script>
 <template>
     <FetchData
@@ -119,19 +62,8 @@ function fetchData([ data ]) {
         auto-load
         @on-fetch="(data) => (observationTypes = data)"
     />
-    <FetchData
-        v-if="justInput"
-        :url="url"
-        :filter="filter"
-        @on-fetch="fetchData"
-        auto-load
-    />
-    <QCard 
-        class="q-pa-xs q-mb-lg full-width" 
-        :class="{ 'just-input': $props.justInput }"
-        v-if="$props.addNote || $props.justInput"
-    >
-        <QCardSection horizontal v-if="!$props.justInput">
+    <QCard class="q-pa-xs q-mb-lg full-width" v-if="$props.addNote">
+        <QCardSection horizontal>
             {{ t('New note') }}
         </QCardSection>
         <QCardSection class="q-px-xs q-my-none q-py-none">
@@ -143,19 +75,19 @@ function fetchData([ data ]) {
                     v-model="newNote.observationTypeFk"
                     option-label="description"
                     style="flex: 0.15"
-                    :required="isRequired"
+                    :required="true"
                     @keyup.enter.stop="insert"
                 />
                 <VnInput
                     v-model.trim="newNote.text"
                     type="textarea"
-                    :label="$props.justInput && newNote.text ? '' : t('Add note here...')"
+                    :label="t('Add note here...')"
                     filled
                     size="lg"
                     autogrow
-                    @keyup.enter.stop="handleClick"
-                    :required="isRequired"
+                    @keyup.enter.stop="insert"
                     clearable
+                    :required="true"
                 >
                     <template #append>
                         <QBtn
@@ -163,7 +95,7 @@ function fetchData([ data ]) {
                             icon="save"
                             color="primary"
                             flat
-                            @click="handleClick"
+                            @click="insert"
                             class="q-mb-xs"
                             dense
                             data-cy="saveNote"
@@ -174,7 +106,6 @@ function fetchData([ data ]) {
         </QCardSection>
     </QCard>
     <VnPaginate
-        v-if="!$props.justInput"
         :data-key="$props.url"
         :url="$props.url"
         order="created DESC"
@@ -267,11 +198,6 @@ function fetchData([ data ]) {
         }
     }
 }
-.just-input {
-    padding-right: 18px;
-    margin-bottom: 2px;
-    box-shadow: none;
-}
 </style>
 <i18n>
     es:
@@ -279,6 +205,4 @@ function fetchData([ data ]) {
         New note: Nueva nota
         Save (Enter): Guardar (Intro)
         Observation type: Tipo de observación
-        New note is empty: La nueva nota esta vacia
-        Are you sure remove this note?: Estas seguro de quitar esta nota?
 </i18n>
diff --git a/src/components/ui/VnStockValueDisplay.vue b/src/components/ui/VnStockValueDisplay.vue
deleted file mode 100644
index d8f43323bb0..00000000000
--- a/src/components/ui/VnStockValueDisplay.vue
+++ /dev/null
@@ -1,41 +0,0 @@
-<script setup>
-import { toPercentage } from 'filters/index';
-
-import { computed } from 'vue';
-
-const props = defineProps({
-    value: {
-        type: Number,
-        required: true,
-    },
-});
-
-const valueClass = computed(() =>
-    props.value === 0 ? 'neutral' : props.value > 0 ? 'positive' : 'negative',
-);
-const iconName = computed(() =>
-    props.value === 0 ? 'equal' : props.value > 0 ? 'arrow_upward' : 'arrow_downward',
-);
-const formattedValue = computed(() => props.value);
-</script>
-<template>
-    <span :class="valueClass">
-        <QIcon :name="iconName" size="sm" class="value-icon" />
-        {{ toPercentage(formattedValue) }}
-    </span>
-</template>
-
-<style lang="scss" scoped>
-.positive {
-    color: $secondary;
-}
-.negative {
-    color: $negative;
-}
-.neutral {
-    color: $primary;
-}
-.value-icon {
-    margin-right: 4px;
-}
-</style>
diff --git a/src/components/ui/VnSubToolbar.vue b/src/components/ui/VnSubToolbar.vue
index 8d4126d1d53..5ded4be001e 100644
--- a/src/components/ui/VnSubToolbar.vue
+++ b/src/components/ui/VnSubToolbar.vue
@@ -19,26 +19,23 @@ onMounted(() => {
     const observer = new MutationObserver(
         () =>
             (hasContent.value =
-                actions.value?.childNodes?.length + data.value?.childNodes?.length),
+                actions.value?.childNodes?.length + data.value?.childNodes?.length)
     );
     if (actions.value) observer.observe(actions.value, opts);
     if (data.value) observer.observe(data.value, opts);
 });
 
-const actionsChildCount = () => !!actions.value?.childNodes?.length;
-
-onBeforeUnmount(() => stateStore.toggleSubToolbar() && hasSubToolbar);
+onBeforeUnmount(() => stateStore.toggleSubToolbar());
 </script>
 
 <template>
     <QToolbar
         id="subToolbar"
-        v-show="hasContent || $slots['st-actions'] || $slots['st-data']"
         class="justify-end sticky"
+        v-show="hasContent || $slots['st-actions'] || $slots['st-data']"
     >
         <slot name="st-data">
-            <div id="st-data" :class="{ 'full-width': !actionsChildCount() }">
-            </div>
+            <div id="st-data"></div>
         </slot>
         <QSpace />
         <slot name="st-actions">
diff --git a/src/components/ui/__tests__/CardSummary.spec.js b/src/components/ui/__tests__/CardSummary.spec.js
index 2f7f90882fa..411ebf9bb60 100644
--- a/src/components/ui/__tests__/CardSummary.spec.js
+++ b/src/components/ui/__tests__/CardSummary.spec.js
@@ -51,6 +51,16 @@ describe('CardSummary', () => {
         expect(vm.store.filter).toEqual('cardFilter');
     });
 
+    it('should compute entity correctly from store data', () => {
+        vm.store.data = [{ id: 1, name: 'Entity 1' }];
+        expect(vm.entity).toEqual({ id: 1, name: 'Entity 1' });
+    });
+
+    it('should handle empty data gracefully', () => {
+        vm.store.data = [];
+        expect(vm.entity).toBeUndefined();
+    });
+
     it('should respond to prop changes and refetch data', async () => {
         const newUrl = 'CardSummary/35';
         const newKey = 'cardSummaryKey/35';
@@ -62,7 +72,7 @@ describe('CardSummary', () => {
         expect(vm.store.filter).toEqual({ key: newKey });
     });
 
-    it('should return true if route path ends with /summary', () => {
+    it('should return true if route path ends with /summary' , () => {
         expect(vm.isSummary).toBe(true);
     });
-});
+});
\ No newline at end of file
diff --git a/src/composables/__tests__/useArrayData.spec.js b/src/composables/__tests__/useArrayData.spec.js
index a610ba9eb79..d4c5d094954 100644
--- a/src/composables/__tests__/useArrayData.spec.js
+++ b/src/composables/__tests__/useArrayData.spec.js
@@ -16,7 +16,7 @@ describe('useArrayData', () => {
         vi.clearAllMocks();
     });
 
-    it('should fetch and replace url with new params', async () => {
+    it('should fetch and repalce url with new params', async () => {
         vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] });
 
         const arrayData = useArrayData('ArrayData', { url: 'mockUrl' });
@@ -33,11 +33,11 @@ describe('useArrayData', () => {
         });
         expect(routerReplace.path).toEqual('mockSection/list');
         expect(JSON.parse(routerReplace.query.params)).toEqual(
-            expect.objectContaining(params),
+            expect.objectContaining(params)
         );
     });
 
-    it('should get data and send new URL without keeping parameters, if there is only one record', async () => {
+    it('Should get data and send new URL without keeping parameters, if there is only one record', async () => {
         vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }] });
 
         const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} });
@@ -56,7 +56,7 @@ describe('useArrayData', () => {
         expect(routerPush.query).toBeUndefined();
     });
 
-    it('should get data and send new URL keeping parameters, if you have more than one record', async () => {
+    it('Should get data and send new URL keeping parameters, if you have more than one record', async () => {
         vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }, { id: 2 }] });
 
         vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
@@ -95,25 +95,4 @@ describe('useArrayData', () => {
         expect(routerPush.path).toEqual('mockName/');
         expect(routerPush.query.params).toBeDefined();
     });
-
-    it('should return one record', async () => {
-        vi.spyOn(axios, 'get').mockReturnValueOnce({
-            data: [
-                { id: 1, name: 'Entity 1' },
-                { id: 2, name: 'Entity 2' },
-            ],
-        });
-        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true });
-        await arrayData.fetch({});
-
-        expect(arrayData.store.data).toEqual({ id: 1, name: 'Entity 1' });
-    });
-
-    it('should handle empty data gracefully if has to return one record', async () => {
-        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] });
-        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true });
-        await arrayData.fetch({});
-
-        expect(arrayData.store.data).toBeUndefined();
-    });
 });
diff --git a/src/composables/checkEntryLock.js b/src/composables/checkEntryLock.js
deleted file mode 100644
index f964dea277f..00000000000
--- a/src/composables/checkEntryLock.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import { useQuasar } from 'quasar';
-import { useI18n } from 'vue-i18n';
-import { useRouter } from 'vue-router';
-import axios from 'axios';
-import VnConfirm from 'components/ui/VnConfirm.vue';
-
-export async function checkEntryLock(entryFk, userFk) {
-    const { t } = useI18n();
-    const quasar = useQuasar();
-    const { push } = useRouter();
-    const { data } = await axios.get(`Entries/${entryFk}`, {
-        params: {
-            filter: JSON.stringify({
-                fields: ['id', 'locked', 'lockerUserFk'],
-                include: { relation: 'user', scope: { fields: ['id', 'nickname'] } },
-            }),
-        },
-    });
-    const entryConfig = await axios.get('EntryConfigs/findOne');
-
-    if (data?.lockerUserFk && data?.locked) {
-        const now = new Date(Date.vnNow()).getTime();
-        const lockedTime = new Date(data.locked).getTime();
-        const timeDiff = (now - lockedTime) / 1000;
-        const isMaxTimeLockExceeded = entryConfig.data.maxLockTime > timeDiff;
-
-        if (data?.lockerUserFk !== userFk && isMaxTimeLockExceeded) {
-            quasar
-                .dialog({
-                    component: VnConfirm,
-                    componentProps: {
-                        'data-cy': 'entry-lock-confirm',
-                        title: t('entry.lock.title'),
-                        message: t('entry.lock.message', {
-                            userName: data?.user?.nickname,
-                            time: timeDiff / 60,
-                        }),
-                    },
-                })
-                .onOk(
-                    async () =>
-                        await axios.patch(`Entries/${entryFk}`, {
-                            locked: Date.vnNow(),
-                            lockerUserFk: userFk,
-                        }),
-                )
-                .onCancel(() => {
-                    push({ path: `summary` });
-                });
-        }
-    } else {
-        await axios
-            .patch(`Entries/${entryFk}`, {
-                locked: Date.vnNow(),
-                lockerUserFk: userFk,
-            })
-            .then(
-                quasar.notify({
-                    message: t('entry.lock.success'),
-                    color: 'positive',
-                    group: false,
-                }),
-            );
-    }
-}
diff --git a/src/composables/getColAlign.js b/src/composables/getColAlign.js
deleted file mode 100644
index a930fd7d86c..00000000000
--- a/src/composables/getColAlign.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export function getColAlign(col) {
-    let align;
-    switch (col.component) {
-        case 'time':
-        case 'date':
-        case 'select':
-            align = 'left';
-            break;
-        case 'number':
-            align = 'right';
-            break;
-        case 'checkbox':
-            align = 'center';
-            break;
-        default:
-            align = col?.align;
-    }
-
-    if (/^is[A-Z]/.test(col.name) || /^has[A-Z]/.test(col.name)) align = 'center';
-
-    return 'text-' + (align ?? 'center');
-}
diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js
index fcc61972a9c..bd3cecf08d6 100644
--- a/src/composables/useArrayData.js
+++ b/src/composables/useArrayData.js
@@ -57,7 +57,6 @@ export function useArrayData(key, userOptions) {
             'navigate',
             'mapKey',
             'keepData',
-            'oneRecord',
         ];
         if (typeof userOptions === 'object') {
             for (const option in userOptions) {
@@ -113,11 +112,7 @@ export function useArrayData(key, userOptions) {
         store.isLoading = false;
         canceller = null;
 
-        processData(response.data, {
-            map: !!store.mapKey,
-            append,
-            oneRecord: store.oneRecord,
-        });
+        processData(response.data, { map: !!store.mapKey, append });
 
         return response;
     }
@@ -319,11 +314,7 @@ export function useArrayData(key, userOptions) {
         return { params, limit };
     }
 
-    function processData(data, { map = true, append = true, oneRecord = false }) {
-        if (oneRecord) {
-            store.data = Array.isArray(data) ? data[0] : data;
-            return;
-        }
+    function processData(data, { map = true, append = true }) {
         if (!append) {
             store.data = [];
             store.map = new Map();
diff --git a/src/composables/useRole.js b/src/composables/useRole.js
index ff54b409cda..3ec65dd0af9 100644
--- a/src/composables/useRole.js
+++ b/src/composables/useRole.js
@@ -27,15 +27,6 @@ export function useRole() {
 
         return false;
     }
-    function likeAny(roles) {
-        const roleStore = state.getRoles();
-        for (const role of roles) {
-            if (!roleStore.value.findIndex((rs) => rs.startsWith(role)) !== -1)
-                return true;
-        }
-
-        return false;
-    }
     function isEmployee() {
         return hasAny(['employee']);
     }
@@ -44,7 +35,6 @@ export function useRole() {
         isEmployee,
         fetch,
         hasAny,
-        likeAny,
         state,
     };
 }
diff --git a/src/css/app.scss b/src/css/app.scss
index 0c5dc97fa7e..7296b079f3c 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -21,10 +21,7 @@ body.body--light {
     .q-header .q-toolbar {
         color: var(--vn-text-color);
     }
-
-    --vn-color-negative: $negative;
 }
-
 body.body--dark {
     --vn-header-color: #5d5d5d;
     --vn-page-color: #222;
@@ -40,8 +37,6 @@ body.body--dark {
     --vn-text-color-contrast: black;
 
     background-color: var(--vn-page-color);
-
-    --vn-color-negative: $negative;
 }
 
 a {
@@ -80,6 +75,7 @@ a {
     text-decoration: underline;
 }
 
+// Removes chrome autofill background
 input:-webkit-autofill,
 select:-webkit-autofill {
     color: var(--vn-text-color);
@@ -153,6 +149,11 @@ select:-webkit-autofill {
     cursor: pointer;
 }
 
+.vn-table-separation-row {
+    height: 16px !important;
+    background-color: var(--vn-section-color) !important;
+}
+
 /* Estilo para el asterisco en campos requeridos */
 .q-field.required .q-field__label:after {
     content: ' *';
@@ -211,10 +212,6 @@ select:-webkit-autofill {
     justify-content: center;
 }
 
-.q-card__section[dense] {
-    padding: 0;
-}
-
 input[type='number'] {
     -moz-appearance: textfield;
 }
@@ -229,12 +226,10 @@ input::-webkit-inner-spin-button {
     max-width: 100%;
 }
 
-.remove-bg {
-    filter: brightness(1.1);
-    mix-blend-mode: multiply;
-}
-
 .q-table__container {
+    /* ===== Scrollbar CSS ===== /
+    / Firefox */
+
     * {
         scrollbar-width: auto;
         scrollbar-color: var(--vn-label-color) transparent;
@@ -275,6 +270,8 @@ input::-webkit-inner-spin-button {
             font-size: 11pt;
         }
         td {
+            font-size: 11pt;
+            border-top: 1px solid var(--vn-page-color);
             border-collapse: collapse;
         }
     }
@@ -318,6 +315,9 @@ input::-webkit-inner-spin-button {
     max-width: fit-content;
 }
 
+.row > .column:has(.q-checkbox) {
+    max-width: fit-content;
+}
 .q-field__inner {
     .q-field__control {
         min-height: auto !important;
diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss
index 22c6d2b56d3..d6e99243769 100644
--- a/src/css/quasar.variables.scss
+++ b/src/css/quasar.variables.scss
@@ -13,7 +13,7 @@
 // Tip: Use the "Theme Builder" on Quasar's documentation website.
 // Tip: to add new colors https://quasar.dev/style/color-palette/#adding-your-own-colors
 $primary: #ec8916;
-$secondary: #89be34;
+$secondary: $primary;
 $positive: #c8e484;
 $negative: #fb5252;
 $info: #84d0e2;
@@ -30,9 +30,7 @@ $color-spacer: #7979794d;
 $border-thin-light: 1px solid $color-spacer-light;
 $primary-light: #f5b351;
 $dark-shadow-color: black;
-$layout-shadow-dark:
-    0 0 10px 2px #00000033,
-    0 0px 10px #0000003d;
+$layout-shadow-dark: 0 0 10px 2px #00000033, 0 0px 10px #0000003d;
 $spacing-md: 16px;
 $color-font-secondary: #777;
 $width-xs: 400px;
diff --git a/src/filters/toDate.js b/src/filters/toDate.js
index 002797af528..8fe8f383662 100644
--- a/src/filters/toDate.js
+++ b/src/filters/toDate.js
@@ -3,8 +3,6 @@ import { useI18n } from 'vue-i18n';
 export default function (value, options = {}) {
     if (!value) return;
 
-    if (!isValidDate(value)) return null;
-
     if (!options.dateStyle && !options.timeStyle) {
         options.day = '2-digit';
         options.month = '2-digit';
@@ -12,12 +10,7 @@ export default function (value, options = {}) {
     }
 
     const { locale } = useI18n();
-    const newDate = new Date(value);
+    const date = new Date(value);
 
-    return new Intl.DateTimeFormat(locale.value, options).format(newDate);
-}
-// handle 0000-00-00
-function isValidDate(date) {
-    const parsedDate = new Date(date);
-    return parsedDate instanceof Date && !isNaN(parsedDate.getTime());
+    return new Intl.DateTimeFormat(locale.value, options).format(date);
 }
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index 9a60e9da138..7d0f3e0b24b 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -33,7 +33,6 @@ globals:
     reset: Reset
     close: Close
     cancel: Cancel
-    isSaveAndContinue: Save and continue
     clone: Clone
     confirm: Confirm
     assign: Assign
@@ -157,7 +156,6 @@ globals:
     changeState: Change state
     raid: 'Raid {daysInForward} days'
     isVies: Vies
-    noData: No data available
     pageTitles:
         logIn: Login
         addressEdit: Update address
@@ -170,7 +168,6 @@ globals:
         workCenters: Work centers
         modes: Modes
         zones: Zones
-        negative: Negative
         zonesList: List
         deliveryDays: Delivery days
         upcomingDeliveries: Upcoming deliveries
@@ -178,7 +175,6 @@ globals:
         alias: Alias
         aliasUsers: Users
         subRoles: Subroles
-        myAccount: Mi cuenta
         inheritedRoles: Inherited Roles
         customers: Customers
         customerCreate: New customer
@@ -337,13 +333,10 @@ globals:
         wasteRecalc: Waste recaclulate
         operator: Operator
         parking: Parking
-        vehicleList: Vehicles
-        vehicle: Vehicle
     unsavedPopup:
         title: Unsaved changes will be lost
         subtitle: Are you sure exit without saving?
     params:
-        description: Description
         clientFk: Client id
         salesPersonFk: Sales person
         warehouseFk: Warehouse
@@ -366,13 +359,7 @@ globals:
         correctingFk: Rectificative
         daysOnward: Days onward
         countryFk: Country
-        countryCodeFk: Country
         companyFk: Company
-    model: Model
-    fuel: Fuel
-    active: Active
-    inactive: Inactive
-    deliveryPoint: Delivery point
 errors:
     statusUnauthorized: Access denied
     statusInternalServerError: An internal server error has ocurred
@@ -411,106 +398,6 @@ cau:
     subtitle: By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.
     inputLabel: Explain why this error should not appear
     askPrivileges: Ask for privileges
-entry:
-    list:
-        newEntry: New entry
-        tableVisibleColumns:
-            isExcludedFromAvailable: Exclude from inventory
-            isOrdered: Ordered
-            isConfirmed: Ready to label
-            isReceived: Received
-            isRaid: Raid
-            landed: Date
-            supplierFk: Supplier
-            reference: Ref/Alb/Guide
-            invoiceNumber: Invoice
-            agencyModeId: Agency
-            isBooked: Booked
-            companyFk: Company
-            evaNotes: Notes
-            warehouseOutFk: Origin
-            warehouseInFk: Destiny
-            entryTypeDescription: Entry type
-            invoiceAmount: Import
-            travelFk: Travel
-    summary:
-        invoiceAmount: Amount
-        commission: Commission
-        currency: Currency
-        invoiceNumber: Invoice number
-        ordered: Ordered
-        booked: Booked
-        excludedFromAvailable: Inventory
-        travelReference: Reference
-        travelAgency: Agency
-        travelShipped: Shipped
-        travelDelivered: Delivered
-        travelLanded: Landed
-        travelReceived: Received
-        buys: Buys
-        stickers: Stickers
-        package: Package
-        packing: Pack.
-        grouping: Group.
-        buyingValue: Buying value
-        import: Import
-        pvp: PVP
-    basicData:
-        travel: Travel
-        currency: Currency
-        commission: Commission
-        observation: Observation
-        booked: Booked
-        excludedFromAvailable: Inventory
-    buys:
-        observations: Observations
-        packagingFk: Box
-        color: Color
-        printedStickers: Printed stickers
-    notes:
-        observationType: Observation type
-    latestBuys:
-        tableVisibleColumns:
-            image: Picture
-            itemFk: Item ID
-            weightByPiece: Weight/Piece
-            isActive: Active
-            family: Family
-            entryFk: Entry
-            freightValue: Freight value
-            comissionValue: Commission value
-            packageValue: Package value
-            isIgnored: Is ignored
-            price2: Grouping
-            price3: Packing
-            minPrice: Min
-            ektFk: Ekt
-            packingOut: Package out
-            landing: Landing
-            isExcludedFromAvailable: Exclude from inventory
-            isRaid: Raid
-            invoiceNumber: Invoice
-            reference: Ref/Alb/Guide
-    params:
-        isExcludedFromAvailable: Excluir del inventario
-        isOrdered: Pedida
-        isConfirmed: Lista para etiquetar
-        isReceived: Recibida
-        isRaid: Redada
-        landed: Fecha
-        supplierFk: Proveedor
-        invoiceNumber: Nº Factura
-        reference: Ref/Alb/Guía
-        agencyModeId: Agencia
-        isBooked: Asentado
-        companyFk: Empresa
-        travelFk: Envio
-        evaNotes: Notas
-        warehouseOutFk: Origen
-        warehouseInFk: Destino
-        entryTypeDescription: Tipo entrada
-        invoiceAmount: Importe
-        dated: Fecha
 ticket:
     params:
         ticketFk: Ticket ID
@@ -740,8 +627,6 @@ wagon:
         name: Name
 
 supplier:
-    search: Search supplier
-    searchInfo: Search supplier by id or name
     list:
         payMethod: Pay method
         account: Account
@@ -831,8 +716,6 @@ travel:
         CloneTravelAndEntries: Clone travel and his entries
         deleteTravel: Delete travel
         AddEntry: Add entry
-        availabled: Availabled
-        availabledHour: Availabled hour
         thermographs: Thermographs
         hb: HB
     basicData:
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index 846c442ea51..7ca9e4b4cac 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -33,11 +33,9 @@ globals:
     reset: Restaurar
     close: Cerrar
     cancel: Cancelar
-    isSaveAndContinue: Guardar y continuar
     clone: Clonar
     confirm: Confirmar
     assign: Asignar
-    replace: Sustituir
     back: Volver
     yes: Si
     no: No
@@ -50,7 +48,6 @@ globals:
     rowRemoved: Fila eliminada
     pleaseWait: Por favor espera...
     noPinnedModules: No has fijado ningún módulo
-    split: Split
     enterToConfirm: Pulsa Enter para confirmar
     summary:
         basicData: Datos básicos
@@ -59,8 +56,8 @@ globals:
     today: Hoy
     yesterday: Ayer
     dateFormat: es-ES
-    noSelectedRows: No tienes ninguna línea seleccionada
     microsip: Abrir en MicroSIP
+    noSelectedRows: No tienes ninguna línea seleccionada
     downloadCSVSuccess: Descarga de CSV exitosa
     reference: Referencia
     agency: Agencia
@@ -80,10 +77,8 @@ globals:
     requiredField: Campo obligatorio
     class: clase
     type: Tipo
-    reason: Motivo
-    removeSelection: Eliminar selección
+    reason: motivo
     noResults: Sin resultados
-    results: resultados
     system: Sistema
     notificationSent: Notificación enviada
     warehouse: Almacén
@@ -161,7 +156,6 @@ globals:
     changeState: Cambiar estado
     raid: 'Redada {daysInForward} días'
     isVies: Vies
-    noData: Datos no disponibles
     pageTitles:
         logIn: Inicio de sesión
         addressEdit: Modificar consignatario
@@ -173,7 +167,6 @@ globals:
         agency: Agencia
         workCenters: Centros de trabajo
         modes: Modos
-        negative: Tickets negativos
         zones: Zonas
         zonesList: Listado
         deliveryDays: Días de entrega
@@ -294,9 +287,9 @@ globals:
         buyRequest: Peticiones de compra
         wasteBreakdown: Deglose de mermas
         itemCreate: Nuevo artículo
-        tax: IVA
-        botanical: Botánico
-        barcode: Código de barras
+        tax: 'IVA'
+        botanical: 'Botánico'
+        barcode: 'Código de barras'
         itemTypeCreate: Nueva familia
         family: Familia
         lastEntries: Últimas entradas
@@ -340,13 +333,10 @@ globals:
         wasteRecalc: Recalcular mermas
         operator: Operario
         parking: Parking
-        vehicleList: Vehículos
-        vehicle: Vehículo
     unsavedPopup:
         title: Los cambios que no haya guardado se perderán
         subtitle: ¿Seguro que quiere salir sin guardar?
     params:
-        description: Descripción
         clientFk: Id cliente
         salesPersonFk: Comercial
         warehouseFk: Almacén
@@ -360,14 +350,13 @@ globals:
         from: Desde
         to: Hasta
         supplierFk: Proveedor
-        supplierRef: Nº factura
+        supplierRef: Ref. proveedor
         serial: Serie
         amount: Importe
         awbCode: AWB
         daysOnward: Días adelante
         packing: ITP
         countryFk: País
-        countryCodeFk: País
         companyFk: Empresa
 errors:
     statusUnauthorized: Acceso denegado
@@ -405,87 +394,6 @@ cau:
     subtitle: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
     inputLabel: Explique el motivo por el que no deberia aparecer este fallo
     askPrivileges: Solicitar permisos
-entry:
-    list:
-        newEntry: Nueva entrada
-        tableVisibleColumns:
-            isExcludedFromAvailable: Excluir del inventario
-            isOrdered: Pedida
-            isConfirmed: Lista para etiquetar
-            isReceived: Recibida
-            isRaid: Redada
-            landed: Fecha
-            supplierFk: Proveedor
-            invoiceNumber: Nº Factura
-            reference: Ref/Alb/Guía
-            agencyModeId: Agencia
-            isBooked: Asentado
-            companyFk: Empresa
-            travelFk: Envio
-            evaNotes: Notas
-            warehouseOutFk: Origen
-            warehouseInFk: Destino
-            entryTypeDescription: Tipo entrada
-            invoiceAmount: Importe
-    summary:
-        invoiceAmount: Importe
-        commission: Comisión
-        currency: Moneda
-        invoiceNumber: Núm. factura
-        ordered: Pedida
-        booked: Contabilizada
-        excludedFromAvailable: Inventario
-        travelReference: Referencia
-        travelAgency: Agencia
-        travelShipped: F. envio
-        travelWarehouseOut: Alm. salida
-        travelDelivered: Enviada
-        travelLanded: F. entrega
-        travelReceived: Recibida
-        buys: Compras
-        stickers: Etiquetas
-        package: Embalaje
-        packing: Pack.
-        grouping: Group.
-        buyingValue: Coste
-        import: Importe
-        pvp: PVP
-    basicData:
-        travel: Envío
-        currency: Moneda
-        observation: Observación
-        commission: Comisión
-        booked: Asentado
-        excludedFromAvailable: Inventario
-    buys:
-        observations: Observaciónes
-        packagingFk: Embalaje
-        color: Color
-        printedStickers: Etiquetas impresas
-    notes:
-        observationType: Tipo de observación
-    latestBuys:
-        tableVisibleColumns:
-            image: Foto
-            itemFk: Id Artículo
-            weightByPiece: Peso (gramos)/tallo
-            isActive: Activo
-            family: Familia
-            entryFk: Entrada
-            freightValue: Porte
-            comissionValue: Comisión
-            packageValue: Embalaje
-            isIgnored: Ignorado
-            price2: Grouping
-            price3: Packing
-            minPrice: Min
-            ektFk: Ekt
-            packingOut: Embalaje envíos
-            landing: Llegada
-            isExcludedFromAvailable: Excluir del inventario
-            isRaid: Redada
-            invoiceNumber: Nº Factura
-            reference: Ref/Alb/Guía
 ticket:
     params:
         ticketFk: ID de ticket
@@ -499,38 +407,6 @@ ticket:
         freightItemName: Nombre
         packageItemName: Embalaje
         longName: Descripción
-    pageTitles:
-        tickets: Tickets
-        list: Listado
-        ticketCreate: Nuevo ticket
-        summary: Resumen
-        basicData: Datos básicos
-        boxing: Encajado
-        sms: Sms
-        notes: Notas
-        sale: Lineas del pedido
-        dms: Gestión documental
-        negative: Tickets negativos
-        volume: Volumen
-        observation: Notas
-        ticketAdvance: Adelantar tickets
-        futureTickets: Tickets a futuro
-        expedition: Expedición
-        purchaseRequest: Petición de compra
-        weeklyTickets: Tickets programados
-        saleTracking: Líneas preparadas
-        services: Servicios
-        tracking: Estados
-        components: Componentes
-        pictures: Fotos
-        packages: Bultos
-    list:
-        nickname: Alias
-        state: Estado
-        shipped: Enviado
-        landed: Entregado
-        salesPerson: Comercial
-        total: Total
     card:
         customerId: ID cliente
         customerCard: Ficha del cliente
@@ -577,48 +453,6 @@ ticket:
         consigneeStreet: Dirección
     create:
         address: Dirección
-invoiceOut:
-    card:
-        issued: Fecha emisión
-        customerCard: Ficha del cliente
-        ticketList: Listado de tickets
-    summary:
-        issued: Fecha
-        dued: Fecha límite
-        booked: Contabilizada
-        taxBreakdown: Desglose impositivo
-        taxableBase: Base imp.
-        rate: Tarifa
-        fee: Cuota
-        tickets: Tickets
-        totalWithVat: Importe
-    globalInvoices:
-        errors:
-            chooseValidClient: Selecciona un cliente válido
-            chooseValidCompany: Selecciona una empresa válida
-            chooseValidPrinter: Selecciona una impresora válida
-            chooseValidSerialType: Selecciona una tipo de serie válida
-            fillDates: La fecha de la factura y la fecha máxima deben estar completas
-            invoiceDateLessThanMaxDate: La fecha de la factura no puede ser menor que la fecha máxima
-            invoiceWithFutureDate: Existe una factura con una fecha futura
-            noTicketsToInvoice: No existen tickets para facturar
-            criticalInvoiceError: Error crítico en la facturación proceso detenido
-            invalidSerialTypeForAll: El tipo de serie debe ser global cuando se facturan todos los clientes
-        table:
-            addressId: Id dirección
-            streetAddress: Dirección fiscal
-        statusCard:
-            percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}'
-            pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs'
-    negativeBases:
-        clientId: Id cliente
-        base: Base
-        active: Activo
-        hasToInvoice: Facturar
-        verifiedData: Datos comprobados
-        comercial: Comercial
-        errors:
-            downloadCsvFailed: Error al descargar CSV
 order:
     field:
         salesPersonFk: Comercial
@@ -629,34 +463,15 @@ order:
     list:
         newOrder: Nuevo Pedido
     summary:
-        basket: Cesta
-        notConfirmed: No confirmada
-        created: Creado
-        createdFrom: Creado desde
-        address: Dirección
-        total: Total
-        vat: IVA
-        state: Estado
-        alias: Alias
-        items: Artículos
-        orderTicketList: Tickets del pedido
-        amount: Monto
-        confirm: Confirmar
-        confirmLines: Confirmar lineas
-shelving:
-    list:
-        parking: Parking
-        priority: Prioridad
-        newShelving: Nuevo Carro
-    summary:
-        recyclable: Reciclable
-parking:
-    pickingOrder: Orden de recogida
-    row: Fila
-    column: Columna
-    searchBar:
-        info: Puedes buscar por código de parking
-        label: Buscar parking...
+        issued: Fecha
+        dued: Fecha límite
+        booked: Contabilizada
+        taxBreakdown: Desglose impositivo
+        taxableBase: Base imp.
+        rate: Tarifa
+        fee: Cuota
+        tickets: Tickets
+        totalWithVat: Importe
 department:
     chat: Chat
     bossDepartment: Jefe de departamento
@@ -817,8 +632,8 @@ wagon:
         volumeNotEmpty: El volumen no puede estar vacío
         typeNotEmpty: El tipo no puede estar vacío
         maxTrays: Has alcanzado el número máximo de bandejas
-        minHeightBetweenTrays: La distancia mínima entre bandejas es
-        maxWagonHeight: La altura máxima del vagón es
+        minHeightBetweenTrays: 'La distancia mínima entre bandejas es '
+        maxWagonHeight: 'La altura máxima del vagón es '
         uncompleteTrays: Hay bandejas sin completar
     params:
         label: Etiqueta
@@ -826,8 +641,6 @@ wagon:
         volume: Volumen
         name: Nombre
 supplier:
-    search: Buscar proveedor
-    searchInfo: Buscar proveedor por id o nombre
     list:
         payMethod: Método de pago
         account: Cuenta
@@ -918,8 +731,6 @@ travel:
         deleteTravel: Eliminar envío
         AddEntry: Añadir entrada
         thermographs: Termógrafos
-        availabled: F. Disponible
-        availabledHour: Hora Disponible
         hb: HB
     basicData:
         daysInForward: Desplazamiento automatico (redada)
@@ -968,7 +779,7 @@ components:
     cardDescriptor:
         mainList: Listado principal
         summary: Resumen
-        moreOptions: Más opciones
+        moreOptions: 'Más opciones'
     leftMenu:
         addToPinned: Añadir a fijados
         removeFromPinned: Eliminar de fijados
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index 3ad1c79bc6a..2a84e5aa154 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -2,7 +2,7 @@
 import Navbar from 'src/components/NavBar.vue';
 </script>
 <template>
-    <QLayout view="hHh LpR fFf">
+    <QLayout view="hHh LpR fFf" v-shortcut>
         <Navbar />
         <RouterView></RouterView>
         <QFooter v-if="$q.platform.is.mobile"></QFooter>
diff --git a/src/layouts/OutLayout.vue b/src/layouts/OutLayout.vue
index eba57c198e4..4ccc6bf9ee9 100644
--- a/src/layouts/OutLayout.vue
+++ b/src/layouts/OutLayout.vue
@@ -1,12 +1,12 @@
 <script setup>
 import { Dark, Quasar } from 'quasar';
-import { computed, onMounted } from 'vue';
+import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { localeEquivalence } from 'src/i18n/index';
 import quasarLang from 'src/utils/quasarLang';
-import { langs } from 'src/boot/defaults/constants.js';
 
 const { t, locale } = useI18n();
+
 const userLocale = computed({
     get() {
         return locale.value;
@@ -28,6 +28,7 @@ const darkMode = computed({
         Dark.set(value);
     },
 });
+const langs = ['en', 'es'];
 </script>
 
 <template>
diff --git a/src/pages/Account/AccountAliasList.vue b/src/pages/Account/AccountAliasList.vue
index 19682286ce5..f6016fb6c18 100644
--- a/src/pages/Account/AccountAliasList.vue
+++ b/src/pages/Account/AccountAliasList.vue
@@ -3,7 +3,6 @@ import { useI18n } from 'vue-i18n';
 import { ref, computed } from 'vue';
 import VnTable from 'components/VnTable/VnTable.vue';
 import VnSection from 'src/components/common/VnSection.vue';
-import exprBuilder from './Alias/AliasExprBuilder';
 
 const tableRef = ref();
 const { t } = useI18n();
@@ -32,6 +31,15 @@ const columns = computed(() => [
         create: true,
     },
 ]);
+
+const exprBuilder = (param, value) => {
+    switch (param) {
+        case 'search':
+            return /^\d+$/.test(value)
+                ? { id: value }
+                : { alias: { like: `%${value}%` } };
+    }
+};
 </script>
 
 <template>
diff --git a/src/pages/Account/AccountExprBuilder.js b/src/pages/Account/AccountExprBuilder.js
deleted file mode 100644
index 6497a9d30d0..00000000000
--- a/src/pages/Account/AccountExprBuilder.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export default (param, value) => {
-    switch (param) {
-        case 'search':
-            return /^\d+$/.test(value)
-                ? { id: value }
-                : {
-                      or: [
-                          { name: { like: `%${value}%` } },
-                          { nickname: { like: `%${value}%` } },
-                      ],
-                  };
-        case 'name':
-        case 'nickname':
-            return { [param]: { like: `%${value}%` } };
-        case 'roleFk':
-            return { [param]: value };
-    }
-};
diff --git a/src/pages/Account/AccountList.vue b/src/pages/Account/AccountList.vue
index 976af1d19f9..ea8daba0d39 100644
--- a/src/pages/Account/AccountList.vue
+++ b/src/pages/Account/AccountList.vue
@@ -4,16 +4,15 @@ import { computed, ref } from 'vue';
 import VnTable from 'components/VnTable/VnTable.vue';
 import AccountSummary from './Card/AccountSummary.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import exprBuilder from './AccountExprBuilder.js';
-import filter from './Card/AccountFilter.js';
 import VnSection from 'src/components/common/VnSection.vue';
 import FetchData from 'src/components/FetchData.vue';
 import VnInputPassword from 'src/components/common/VnInputPassword.vue';
 
 const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
-const tableRef = ref();
-
+const filter = {
+    include: { relation: 'role', scope: { fields: ['id', 'name'] } },
+};
 const dataKey = 'AccountList';
 const roles = ref([]);
 const columns = computed(() => [
@@ -118,6 +117,25 @@ const columns = computed(() => [
         ],
     },
 ]);
+
+function exprBuilder(param, value) {
+    switch (param) {
+        case 'search':
+            return /^\d+$/.test(value)
+                ? { id: value }
+                : {
+                      or: [
+                          { name: { like: `%${value}%` } },
+                          { nickname: { like: `%${value}%` } },
+                      ],
+                  };
+        case 'name':
+        case 'nickname':
+            return { [param]: { like: `%${value}%` } };
+        case 'roleFk':
+            return { [param]: value };
+    }
+}
 </script>
 <template>
     <FetchData url="VnRoles" @on-fetch="(data) => (roles = data)" auto-load />
diff --git a/src/pages/Account/Alias/AliasExprBuilder.js b/src/pages/Account/Alias/AliasExprBuilder.js
deleted file mode 100644
index f7a5a104c07..00000000000
--- a/src/pages/Account/Alias/AliasExprBuilder.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default (param, value) => {
-    switch (param) {
-        case 'search':
-            return /^\d+$/.test(value)
-                ? { id: value }
-                : { alias: { like: `%${value}%` } };
-    }
-};
diff --git a/src/pages/Account/Alias/Card/AliasCard.vue b/src/pages/Account/Alias/Card/AliasCard.vue
index f37bd7d0f4b..3a814edc051 100644
--- a/src/pages/Account/Alias/Card/AliasCard.vue
+++ b/src/pages/Account/Alias/Card/AliasCard.vue
@@ -1,13 +1,21 @@
 <script setup>
+import { useI18n } from 'vue-i18n';
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import AliasDescriptor from './AliasDescriptor.vue';
+const { t } = useI18n();
 </script>
 
 <template>
     <VnCardBeta
         data-key="Alias"
-        url="MailAliases"
+        base-url="MailAliases"
         :descriptor="AliasDescriptor"
         search-data-key="AccountAliasList"
+        :searchbar-props="{
+            url: 'MailAliases',
+            info: t('mailAlias.searchInfo'),
+            label: t('mailAlias.search'),
+            searchUrl: 'table',
+        }"
     />
 </template>
diff --git a/src/pages/Account/Alias/Card/AliasDescriptor.vue b/src/pages/Account/Alias/Card/AliasDescriptor.vue
index 671ef7fbcd0..2e01fad016e 100644
--- a/src/pages/Account/Alias/Card/AliasDescriptor.vue
+++ b/src/pages/Account/Alias/Card/AliasDescriptor.vue
@@ -7,6 +7,7 @@ import { useQuasar } from 'quasar';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 
+import useCardDescription from 'src/composables/useCardDescription';
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
 
@@ -28,6 +29,9 @@ const entityId = computed(() => {
     return $props.id || route.params.id;
 });
 
+const data = ref(useCardDescription());
+const setData = (entity) => (data.value = useCardDescription(entity.alias, entity.id));
+
 const removeAlias = () => {
     quasar
         .dialog({
@@ -51,8 +55,11 @@ const removeAlias = () => {
     <CardDescriptor
         ref="descriptor"
         :url="`MailAliases/${entityId}`"
-        data-key="Alias"
-        title="alias"
+        module="Alias"
+        @on-fetch="setData"
+        data-key="aliasData"
+        :title="data.title"
+        :subtitle="data.subtitle"
     >
         <template #menu>
             <QItem v-ripple clickable @click="removeAlias()">
diff --git a/src/pages/Account/Alias/Card/AliasSummary.vue b/src/pages/Account/Alias/Card/AliasSummary.vue
index b4b9abd25a0..1f76fe7c25c 100644
--- a/src/pages/Account/Alias/Card/AliasSummary.vue
+++ b/src/pages/Account/Alias/Card/AliasSummary.vue
@@ -1,11 +1,13 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 
+import { useArrayData } from 'src/composables/useArrayData';
+
 const route = useRoute();
 const { t } = useI18n();
 
@@ -16,15 +18,20 @@ const $props = defineProps({
     },
 });
 
+const { store } = useArrayData('Alias');
+const alias = ref(store.data);
 const entityId = computed(() => $props.id || route.params.id);
 </script>
 
 <template>
-    <CardSummary ref="summary" :url="`MailAliases/${entityId}`" data-key="Alias">
-        <template #header="{ entity: alias }">
-            {{ alias.id }} - {{ alias.alias }}
-        </template>
-        <template #body="{ entity: alias }">
+    <CardSummary
+        ref="summary"
+        :url="`MailAliases/${entityId}`"
+        @on-fetch="(data) => (alias = data)"
+        data-key="MailAliasesSummary"
+    >
+        <template #header> {{ alias.id }} - {{ alias.alias }} </template>
+        <template #body>
             <QCard class="vn-one">
                 <QCardSection class="q-pa-none">
                     <router-link
diff --git a/src/pages/Account/Card/AccountBasicData.vue b/src/pages/Account/Card/AccountBasicData.vue
index 393f9eb801d..e6c9da6fe74 100644
--- a/src/pages/Account/Card/AccountBasicData.vue
+++ b/src/pages/Account/Card/AccountBasicData.vue
@@ -1,20 +1,46 @@
 <script setup>
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnSelectEnum from 'src/components/common/VnSelectEnum.vue';
 import FormModel from 'components/FormModel.vue';
 import VnInput from 'src/components/common/VnInput.vue';
+import { ref, watch } from 'vue';
+
+const route = useRoute();
+const { t } = useI18n();
+const formModelRef = ref(null);
+
+const accountFilter = {
+    where: { id: route.params.id },
+    fields: ['id', 'email', 'nickname', 'name', 'accountStateFk', 'packages', 'pickup'],
+    include: [],
+};
+
+watch(
+    () => route.params.id,
+    () => formModelRef.value.reset()
+);
 </script>
 <template>
-    <FormModel :url-update="`VnUsers/${$route.params.id}/update-user`" model="Account">
+    <FormModel
+        ref="formModelRef"
+        url="VnUsers/preview"
+        :url-update="`VnUsers/${route.params.id}/update-user`"
+        :filter="accountFilter"
+        model="Accounts"
+        auto-load
+        @on-data-saved="formModelRef.fetch()"
+    >
         <template #form="{ data }">
             <div class="q-gutter-y-sm">
-                <VnInput v-model="data.name" :label="$t('account.card.nickname')" />
-                <VnInput v-model="data.nickname" :label="$t('account.card.alias')" />
-                <VnInput v-model="data.email" :label="$t('globals.params.email')" />
+                <VnInput v-model="data.name" :label="t('account.card.nickname')" />
+                <VnInput v-model="data.nickname" :label="t('account.card.alias')" />
+                <VnInput v-model="data.email" :label="t('globals.params.email')" />
                 <VnSelect
                     url="Languages"
                     v-model="data.lang"
-                    :label="$t('account.card.lang')"
+                    :label="t('account.card.lang')"
                     option-value="code"
                     option-label="code"
                 />
@@ -23,7 +49,7 @@ import VnInput from 'src/components/common/VnInput.vue';
                     table="user"
                     column="twoFactor"
                     v-model="data.twoFactor"
-                    :label="$t('account.card.twoFactor')"
+                    :label="t('account.card.twoFactor')"
                     option-value="code"
                     option-label="code"
                 />
diff --git a/src/pages/Account/Card/AccountCard.vue b/src/pages/Account/Card/AccountCard.vue
index a5037e30136..35ff7e73229 100644
--- a/src/pages/Account/Card/AccountCard.vue
+++ b/src/pages/Account/Card/AccountCard.vue
@@ -1,14 +1,8 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import AccountDescriptor from './AccountDescriptor.vue';
-import filter from './AccountFilter.js';
 </script>
+
 <template>
-    <VnCardBeta
-        url="VnUsers/preview"
-        :id-in-where="true"
-        data-key="Account"
-        :descriptor="AccountDescriptor"
-        :filter="filter"
-    />
+    <VnCardBeta data-key="AccountId" :descriptor="AccountDescriptor" />
 </template>
diff --git a/src/pages/Account/Card/AccountDescriptor.vue b/src/pages/Account/Card/AccountDescriptor.vue
index 49328fe87eb..4e5328de66c 100644
--- a/src/pages/Account/Card/AccountDescriptor.vue
+++ b/src/pages/Account/Card/AccountDescriptor.vue
@@ -1,18 +1,36 @@
 <script setup>
 import { ref, computed, onMounted } from 'vue';
 import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
+import useCardDescription from 'src/composables/useCardDescription';
 import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
 import VnImg from 'src/components/ui/VnImg.vue';
-import filter from './AccountFilter.js';
 import useHasAccount from 'src/composables/useHasAccount.js';
 
-const $props = defineProps({ id: { type: Number, default: null } });
+const $props = defineProps({
+    id: {
+        type: Number,
+        required: false,
+        default: null,
+    },
+});
 
 const route = useRoute();
-const entityId = computed(() => $props.id || route.params.id);
+const { t } = useI18n();
+const entityId = computed(() => {
+    return $props.id || route.params.id;
+});
+const data = ref(useCardDescription());
 const hasAccount = ref();
+const setData = (entity) => (data.value = useCardDescription(entity.nickname, entity.id));
+
+const filter = {
+    where: { id: entityId },
+    fields: ['id', 'nickname', 'name', 'role'],
+    include: { relation: 'role', scope: { fields: ['id', 'name'] } },
+};
 
 onMounted(async () => {
     hasAccount.value = await useHasAccount(entityId.value);
@@ -23,9 +41,12 @@ onMounted(async () => {
     <CardDescriptor
         ref="descriptor"
         :url="`VnUsers/preview`"
-        :filter="{ ...filter, where: { id: entityId } }"
-        data-key="Account"
-        title="nickname"
+        :filter="filter"
+        module="Account"
+        @on-fetch="setData"
+        data-key="AccountId"
+        :title="data.title"
+        :subtitle="data.subtitle"
     >
         <template #menu>
             <AccountDescriptorMenu :entity-id="entityId" />
@@ -41,7 +62,7 @@ onMounted(async () => {
                                 <QIcon name="vn:claims" />
                             </div>
                             <div class="text-grey-5" style="opacity: 0.4">
-                                {{ $t('account.imageNotFound') }}
+                                {{ t('account.imageNotFound') }}
                             </div>
                         </div>
                     </div>
@@ -49,8 +70,8 @@ onMounted(async () => {
             </VnImg>
         </template>
         <template #body="{ entity }">
-            <VnLv :label="$t('account.card.nickname')" :value="entity.name" />
-            <VnLv :label="$t('account.card.role')" :value="entity.role?.name" />
+            <VnLv :label="t('account.card.nickname')" :value="entity.name" />
+            <VnLv :label="t('account.card.role')" :value="entity.role.name" />
         </template>
         <template #actions="{ entity }">
             <QCardActions class="q-gutter-x-md">
@@ -63,7 +84,7 @@ onMounted(async () => {
                     size="sm"
                     class="fill-icon"
                 >
-                    <QTooltip>{{ $t('account.card.deactivated') }}</QTooltip>
+                    <QTooltip>{{ t('account.card.deactivated') }}</QTooltip>
                 </QIcon>
                 <QIcon
                     color="primary"
@@ -74,7 +95,7 @@ onMounted(async () => {
                     size="sm"
                     class="fill-icon"
                 >
-                    <QTooltip>{{ $t('account.card.enabled') }}</QTooltip>
+                    <QTooltip>{{ t('account.card.enabled') }}</QTooltip>
                 </QIcon>
             </QCardActions>
         </template>
diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue
index 30584c61f46..961323d3a73 100644
--- a/src/pages/Account/Card/AccountDescriptorMenu.vue
+++ b/src/pages/Account/Card/AccountDescriptorMenu.vue
@@ -12,7 +12,6 @@ import VnInputPassword from 'src/components/common/VnInputPassword.vue';
 import VnChangePassword from 'src/components/common/VnChangePassword.vue';
 import { useQuasar } from 'quasar';
 import { useRouter } from 'vue-router';
-import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const $props = defineProps({
     hasAccount: {
@@ -30,7 +29,7 @@ const router = useRouter();
 const state = useState();
 const user = state.getUser();
 const { notify } = useQuasar();
-const account = computed(() => useArrayData('Account').store.data[0]);
+const account = computed(() => useArrayData('AccountId').store.data[0]);
 account.value.hasAccount = hasAccount.value;
 const entityId = computed(() => +route.params.id);
 const hasitManagementAccess = ref();
@@ -125,14 +124,18 @@ onMounted(() => {
         :promise="sync"
     >
         <template #customHTML>
-            <VnCheckbox
-                v-model="shouldSyncPassword"
+            {{ shouldSyncPassword }}
+            <QCheckbox
                 :label="t('account.card.actions.sync.checkbox')"
-                :info="t('account.card.actions.sync.tooltip')"
+                v-model="shouldSyncPassword"
+                class="full-width"
                 clearable
                 clear-icon="close"
-                color="primary"
-            />
+            >
+                <QIcon style="padding-left: 10px" color="primary" name="info" size="sm">
+                    <QTooltip>{{ t('account.card.actions.sync.tooltip') }}</QTooltip>
+                </QIcon></QCheckbox
+            >
             <VnInputPassword
                 v-if="shouldSyncPassword"
                 :label="t('login.password')"
@@ -152,7 +155,7 @@ onMounted(() => {
             openConfirmationModal(
                 t('account.card.actions.disableAccount.title'),
                 t('account.card.actions.disableAccount.subtitle'),
-                () => deleteAccount(),
+                () => deleteAccount()
             )
         "
     >
@@ -171,7 +174,7 @@ onMounted(() => {
             openConfirmationModal(
                 t('account.card.actions.enableAccount.title'),
                 t('account.card.actions.enableAccount.subtitle'),
-                () => updateStatusAccount(true),
+                () => updateStatusAccount(true)
             )
         "
     >
@@ -185,7 +188,7 @@ onMounted(() => {
             openConfirmationModal(
                 t('account.card.actions.disableAccount.title'),
                 t('account.card.actions.disableAccount.subtitle'),
-                () => updateStatusAccount(false),
+                () => updateStatusAccount(false)
             )
         "
     >
@@ -200,7 +203,7 @@ onMounted(() => {
             openConfirmationModal(
                 t('account.card.actions.activateUser.title'),
                 t('account.card.actions.activateUser.title'),
-                () => updateStatusUser(true),
+                () => updateStatusUser(true)
             )
         "
     >
@@ -214,7 +217,7 @@ onMounted(() => {
             openConfirmationModal(
                 t('account.card.actions.deactivateUser.title'),
                 t('account.card.actions.deactivateUser.title'),
-                () => updateStatusUser(false),
+                () => updateStatusUser(false)
             )
         "
     >
diff --git a/src/pages/Account/Card/AccountFilter.js b/src/pages/Account/Card/AccountFilter.js
deleted file mode 100644
index 01787656436..00000000000
--- a/src/pages/Account/Card/AccountFilter.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default {
-    include: { relation: 'role', scope: { fields: ['id', 'name'] } },
-};
diff --git a/src/pages/Account/Card/AccountMailAlias.vue b/src/pages/Account/Card/AccountMailAlias.vue
index 7a060cff180..ef1707cf2ee 100644
--- a/src/pages/Account/Card/AccountMailAlias.vue
+++ b/src/pages/Account/Card/AccountMailAlias.vue
@@ -86,7 +86,7 @@ watch(
     () => route.params.id,
     () => {
         getAccountData();
-    },
+    }
 );
 
 onMounted(async () => await getAccountData(false));
@@ -130,8 +130,7 @@ onMounted(async () => await getAccountData(false));
                                             openConfirmationModal(
                                                 t('User will be removed from alias'),
                                                 t('¿Seguro que quieres continuar?'),
-                                                () =>
-                                                    deleteMailAlias(row, rows, rowIndex),
+                                                () => deleteMailAlias(row, rows, rowIndex)
                                             )
                                         "
                                     >
@@ -158,7 +157,7 @@ onMounted(async () => await getAccountData(false));
                 icon="add"
                 color="primary"
                 @click="openCreateMailAliasForm()"
-                v-shortcut="'+'"
+                shortcut="+"
             >
                 <QTooltip>{{ t('warehouses.add') }}</QTooltip>
             </QBtn>
diff --git a/src/pages/Account/Card/AccountSummary.vue b/src/pages/Account/Card/AccountSummary.vue
index f7a16e8c355..ca17c7975bb 100644
--- a/src/pages/Account/Card/AccountSummary.vue
+++ b/src/pages/Account/Card/AccountSummary.vue
@@ -1,41 +1,58 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
-import filter from './AccountFilter.js';
+
+import { useArrayData } from 'src/composables/useArrayData';
 import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
 
-const $props = defineProps({ id: { type: Number, default: 0 } });
-
 const route = useRoute();
+const { t } = useI18n();
+
+const $props = defineProps({
+    id: {
+        type: Number,
+        default: 0,
+    },
+});
+const { store } = useArrayData('Account');
+const account = ref(store.data);
+
 const entityId = computed(() => $props.id || route.params.id);
+const filter = {
+    where: { id: entityId },
+    fields: ['id', 'nickname', 'name', 'role'],
+    include: { relation: 'role', scope: { fields: ['id', 'name'] } },
+};
 </script>
 
 <template>
     <CardSummary
-        data-key="Account"
-        ref="AccountSummary"
+        data-key="AccountId"
         url="VnUsers/preview"
         :filter="filter"
+        @on-fetch="(data) => (account = data)"
     >
-        <template #header="{ entity }">{{ entity.id }} - {{ entity.nickname }}</template>
-        <template #menu>
+        <template #header>{{ account.id }} - {{ account.nickname }}</template>
+        <template #menu="">
             <AccountDescriptorMenu :entity-id="entityId" />
         </template>
-        <template #body="{ entity }">
+        <template #body>
             <QCard class="vn-one">
                 <QCardSection class="q-pa-none">
                     <router-link
                         :to="{ name: 'AccountBasicData', params: { id: entityId } }"
                         class="header header-link"
                     >
-                        {{ $t('globals.pageTitles.basicData') }}
+                        {{ t('globals.pageTitles.basicData') }}
                         <QIcon name="open_in_new" />
                     </router-link>
                 </QCardSection>
-                <VnLv :label="$t('account.card.nickname')" :value="entity.name" />
-                <VnLv :label="$t('account.card.role')" :value="entity.role?.name" />
+                <VnLv :label="t('account.card.nickname')" :value="account.name" />
+                <VnLv :label="t('account.card.role')" :value="account.role.name" />
             </QCard>
         </template>
     </CardSummary>
diff --git a/src/pages/Account/Role/AccountRoles.vue b/src/pages/Account/Role/AccountRoles.vue
index 02f5400c628..3c3d6b243fc 100644
--- a/src/pages/Account/Role/AccountRoles.vue
+++ b/src/pages/Account/Role/AccountRoles.vue
@@ -5,7 +5,6 @@ import VnTable from 'components/VnTable/VnTable.vue';
 import { useRoute } from 'vue-router';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import RoleSummary from './Card/RoleSummary.vue';
-import exprBuilder from './RoleExprBuilder.js';
 import VnSection from 'src/components/common/VnSection.vue';
 
 const route = useRoute();
@@ -67,7 +66,24 @@ const columns = computed(() => [
         ],
     },
 ]);
+const exprBuilder = (param, value) => {
+    switch (param) {
+        case 'search':
+            return /^\d+$/.test(value)
+                ? { id: value }
+                : {
+                      or: [
+                          { name: { like: `%${value}%` } },
+                          { nickname: { like: `%${value}%` } },
+                      ],
+                  };
+        case 'name':
+        case 'description':
+            return { [param]: { like: `%${value}%` } };
+    }
+};
 </script>
+
 <template>
     <VnSection
         :data-key="dataKey"
diff --git a/src/pages/Account/Role/Card/RoleBasicData.vue b/src/pages/Account/Role/Card/RoleBasicData.vue
index de70b0fb695..1de9ff3876f 100644
--- a/src/pages/Account/Role/Card/RoleBasicData.vue
+++ b/src/pages/Account/Role/Card/RoleBasicData.vue
@@ -1,16 +1,24 @@
 <script setup>
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
+const route = useRoute();
+const { t } = useI18n();
 </script>
 <template>
-    <FormModel model="Role" auto-load>
+    <FormModel :url="`VnRoles/${route.params.id}`" model="VnRole" auto-load>
         <template #form="{ data }">
             <VnRow>
-                <VnInput v-model="data.name" :label="$t('globals.name')" />
+                <div class="col">
+                    <VnInput v-model="data.name" :label="t('globals.name')" />
+                </div>
             </VnRow>
             <VnRow>
-                <VnInput v-model="data.description" :label="$t('role.description')" />
+                <div class="col">
+                    <VnInput v-model="data.description" :label="t('role.description')" />
+                </div>
             </VnRow>
         </template>
     </FormModel>
diff --git a/src/pages/Account/Role/Card/RoleCard.vue b/src/pages/Account/Role/Card/RoleCard.vue
index ef5b9db0491..7664deca8da 100644
--- a/src/pages/Account/Role/Card/RoleCard.vue
+++ b/src/pages/Account/Role/Card/RoleCard.vue
@@ -3,10 +3,5 @@ import VnCardBeta from 'components/common/VnCardBeta.vue';
 import RoleDescriptor from './RoleDescriptor.vue';
 </script>
 <template>
-    <VnCardBeta
-        url="VnRoles"
-        data-key="Role"
-        :id-in-where="true"
-        :descriptor="RoleDescriptor"
-    />
+    <VnCardBeta data-key="Role" :descriptor="RoleDescriptor" />
 </template>
diff --git a/src/pages/Account/Role/Card/RoleDescriptor.vue b/src/pages/Account/Role/Card/RoleDescriptor.vue
index 517517af0dd..0a555346d9f 100644
--- a/src/pages/Account/Role/Card/RoleDescriptor.vue
+++ b/src/pages/Account/Role/Card/RoleDescriptor.vue
@@ -1,9 +1,10 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
+import useCardDescription from 'src/composables/useCardDescription';
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
 const $props = defineProps({
@@ -25,6 +26,11 @@ const { t } = useI18n();
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+const data = ref(useCardDescription());
+const setData = (entity) => (data.value = useCardDescription(entity.name, entity.id));
+const filter = {
+    where: { id: entityId },
+};
 const removeRole = async () => {
     await axios.delete(`VnRoles/${entityId.value}`);
     notify(t('Role removed'), 'positive');
@@ -33,9 +39,13 @@ const removeRole = async () => {
 
 <template>
     <CardDescriptor
-        url="VnRoles"
-        :filter="{ where: { id: entityId } }"
+        :url="`VnRoles/${entityId}`"
+        :filter="filter"
+        module="Role"
+        @on-fetch="setData"
         data-key="Role"
+        :title="data.title"
+        :subtitle="data.subtitle"
         :summary="$props.summary"
     >
         <template #menu>
diff --git a/src/pages/Account/Role/Card/RoleSummary.vue b/src/pages/Account/Role/Card/RoleSummary.vue
index 410f90b17cc..f0daa77fb8f 100644
--- a/src/pages/Account/Role/Card/RoleSummary.vue
+++ b/src/pages/Account/Role/Card/RoleSummary.vue
@@ -1,9 +1,10 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
+import { useArrayData } from 'src/composables/useArrayData';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -15,18 +16,24 @@ const $props = defineProps({
     },
 });
 
+const { store } = useArrayData('Role');
+const role = ref(store.data);
 const entityId = computed(() => $props.id || route.params.id);
+const filter = {
+    where: { id: entityId },
+};
 </script>
 
 <template>
     <CardSummary
         ref="summary"
-        url="VnRoles"
-        :filter="{ where: { id: entityId } }"
+        :url="`VnRoles/${entityId}`"
+        :filter="filter"
+        @on-fetch="(data) => (role = data)"
         data-key="Role"
     >
-        <template #header="{ entity }"> {{ entity.id }} - {{ entity.name }} </template>
-        <template #body="{ entity }">
+        <template #header> {{ role.id }} - {{ role.name }} </template>
+        <template #body>
             <QCard class="vn-one">
                 <QCardSection class="q-pa-none">
                     <a
@@ -37,9 +44,9 @@ const entityId = computed(() => $props.id || route.params.id);
                         <QIcon name="open_in_new" />
                     </a>
                 </QCardSection>
-                <VnLv :label="t('role.id')" :value="entity.id" />
-                <VnLv :label="t('globals.name')" :value="entity.name" />
-                <VnLv :label="t('role.description')" :value="entity.description" />
+                <VnLv :label="t('role.id')" :value="role.id" />
+                <VnLv :label="t('globals.name')" :value="role.name" />
+                <VnLv :label="t('role.description')" :value="role.description" />
             </QCard>
         </template>
     </CardSummary>
diff --git a/src/pages/Account/Role/Card/SubRoles.vue b/src/pages/Account/Role/Card/SubRoles.vue
index 99cf5e8f0e0..0077f12b06a 100644
--- a/src/pages/Account/Role/Card/SubRoles.vue
+++ b/src/pages/Account/Role/Card/SubRoles.vue
@@ -63,7 +63,7 @@ watch(
         store.url = urlPath.value;
         store.filter = filter.value;
         fetchSubRoles();
-    },
+    }
 );
 
 const fetchSubRoles = () => paginateRef.value.fetch();
@@ -109,7 +109,7 @@ const redirectToRoleSummary = (id) =>
                                             openConfirmationModal(
                                                 t('El rol va a ser eliminado'),
                                                 t('¿Seguro que quieres continuar?'),
-                                                () => deleteSubRole(row, rows, rowIndex),
+                                                () => deleteSubRole(row, rows, rowIndex)
                                             )
                                         "
                                     >
@@ -131,7 +131,7 @@ const redirectToRoleSummary = (id) =>
             <QBtn
                 fab
                 icon="add"
-                v-shortcut="'+'"
+                shortcut="+"
                 color="primary"
                 @click="openCreateSubRoleForm()"
             >
diff --git a/src/pages/Account/Role/RoleExprBuilder.js b/src/pages/Account/Role/RoleExprBuilder.js
deleted file mode 100644
index cc4fab39983..00000000000
--- a/src/pages/Account/Role/RoleExprBuilder.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export default (param, value) => {
-    switch (param) {
-        case 'search':
-            return /^\d+$/.test(value)
-                ? { id: value }
-                : {
-                      or: [
-                          { name: { like: `%${value}%` } },
-                          { nickname: { like: `%${value}%` } },
-                      ],
-                  };
-        case 'name':
-        case 'description':
-            return { [param]: { like: `%${value}%` } };
-    }
-};
diff --git a/src/pages/Claim/Card/ClaimBasicData.vue b/src/pages/Claim/Card/ClaimBasicData.vue
index 67034da1af8..63b0b7c0d73 100644
--- a/src/pages/Claim/Card/ClaimBasicData.vue
+++ b/src/pages/Claim/Card/ClaimBasicData.vue
@@ -28,6 +28,7 @@ const workersOptions = ref([]);
         model="Claim"
         :url-update="`Claims/updateClaim/${route.params.id}`"
         auto-load
+        :reload="true"
     >
         <template #form="{ data, validate }">
             <VnRow>
diff --git a/src/pages/Claim/Card/ClaimCard.vue b/src/pages/Claim/Card/ClaimCard.vue
index 05f3b53a860..e1e00081571 100644
--- a/src/pages/Claim/Card/ClaimCard.vue
+++ b/src/pages/Claim/Card/ClaimCard.vue
@@ -4,11 +4,10 @@ import ClaimDescriptor from './ClaimDescriptor.vue';
 import filter from './ClaimFilter.js';
 </script>
 <template>
-    <VnCardBeta
-        data-key="Claim"
-        url="Claims"
-        :descriptor="ClaimDescriptor"
-        search-data-key="ClaimList"
+    <VnCardBeta 
+        data-key="Claim" 
+        base-url="Claims" 
+        :descriptor="ClaimDescriptor" 
         :filter="filter"
     />
 </template>
diff --git a/src/pages/Claim/Card/ClaimDescriptor.vue b/src/pages/Claim/Card/ClaimDescriptor.vue
index 4551c58fe33..02b63dd8e7e 100644
--- a/src/pages/Claim/Card/ClaimDescriptor.vue
+++ b/src/pages/Claim/Card/ClaimDescriptor.vue
@@ -3,10 +3,12 @@ import { ref, computed, onMounted } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { toDateHourMinSec, toPercentage } from 'src/filters';
+import { useState } from 'src/composables/useState';
 import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
 import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
+import useCardDescription from 'src/composables/useCardDescription';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import { getUrl } from 'src/composables/getUrl';
 import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
@@ -21,6 +23,7 @@ const $props = defineProps({
 });
 
 const route = useRoute();
+const state = useState();
 const { t } = useI18n();
 const salixUrl = ref();
 const entityId = computed(() => {
@@ -36,7 +39,12 @@ const STATE_COLOR = {
 function stateColor(code) {
     return STATE_COLOR[code];
 }
-
+const data = ref(useCardDescription());
+const setData = (entity) => {
+    if (!entity) return;
+    data.value = useCardDescription(entity?.client?.name, entity.id);
+    state.set('ClaimDescriptor', entity);
+};
 onMounted(async () => {
     salixUrl.value = await getUrl('');
 });
@@ -46,7 +54,9 @@ onMounted(async () => {
     <CardDescriptor
         :url="`Claims/${entityId}`"
         :filter="filter"
+        module="Claim"
         title="client.name"
+        @on-fetch="setData"
         data-key="Claim"
     >
         <template #menu="{ entity }">
@@ -85,7 +95,7 @@ onMounted(async () => {
                     />
                 </template>
             </VnLv>
-            <VnLv v-if="entity.ticket?.zone?.id" :label="t('claim.zone')">
+            <VnLv :label="t('claim.zone')">
                 <template #value>
                     <span class="link">
                         {{ entity.ticket?.zone?.name }}
@@ -97,10 +107,11 @@ onMounted(async () => {
                 :label="t('claim.province')"
                 :value="entity.ticket?.address?.province?.name"
             />
-            <VnLv v-if="entity.ticketFk" :label="t('claim.ticketId')">
+            <VnLv :label="t('claim.ticketId')">
                 <template #value>
                     <span class="link">
                         {{ entity.ticketFk }}
+
                         <TicketDescriptorProxy :id="entity.ticketFk" />
                     </span>
                 </template>
diff --git a/src/pages/Claim/Card/ClaimLines.vue b/src/pages/Claim/Card/ClaimLines.vue
index dee03b95d4f..33fadd02016 100644
--- a/src/pages/Claim/Card/ClaimLines.vue
+++ b/src/pages/Claim/Card/ClaimLines.vue
@@ -317,13 +317,7 @@ async function saveWhenHasChanges() {
     </div>
 
     <QPageSticky position="bottom-right" :offset="[25, 25]">
-        <QBtn
-            fab
-            color="primary"
-            v-shortcut="'+'"
-            icon="add"
-            @click="showImportDialog()"
-        />
+        <QBtn fab color="primary" shortcut="+" icon="add" @click="showImportDialog()" />
     </QPageSticky>
 </template>
 
diff --git a/src/pages/Claim/Card/ClaimNotes.vue b/src/pages/Claim/Card/ClaimNotes.vue
index cc6e33779e3..134ee33abcc 100644
--- a/src/pages/Claim/Card/ClaimNotes.vue
+++ b/src/pages/Claim/Card/ClaimNotes.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { computed, useAttrs } from 'vue';
+import { computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useState } from 'src/composables/useState';
 import VnNotes from 'src/components/ui/VnNotes.vue';
@@ -7,7 +7,6 @@ import VnNotes from 'src/components/ui/VnNotes.vue';
 const route = useRoute();
 const state = useState();
 const user = state.getUser();
-const $attrs = useAttrs();
 
 const $props = defineProps({
     id: { type: [Number, String], default: null },
diff --git a/src/pages/Claim/Card/ClaimPhoto.vue b/src/pages/Claim/Card/ClaimPhoto.vue
index d4acc9bbe27..d4321d8eb82 100644
--- a/src/pages/Claim/Card/ClaimPhoto.vue
+++ b/src/pages/Claim/Card/ClaimPhoto.vue
@@ -61,7 +61,7 @@ watch(
     () => {
         claimDmsFilter.value.where.id = router.currentRoute.value.params.id;
         claimDmsRef.value.fetch();
-    },
+    }
 );
 
 function openDialog(dmsId) {
@@ -248,7 +248,7 @@ function onDrag() {
             <QBtn
                 fab
                 @click="inputFile.nativeEl.click()"
-                v-shortcut="'+'"
+                shortcut="+"
                 icon="add"
                 color="primary"
             >
diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue
index 41d0c559819..63fd035daa5 100644
--- a/src/pages/Claim/ClaimList.vue
+++ b/src/pages/Claim/ClaimList.vue
@@ -132,7 +132,7 @@ const STATE_COLOR = {
         prefix="claim"
         :array-data-props="{
             url: 'Claims/filter',
-            order: 'cs.priority ASC, created ASC',
+            order: ['cs.priority ASC', 'created ASC'],
         }"
     >
         <template #advanced-menu>
diff --git a/src/pages/Customer/Card/CustomerAddress.vue b/src/pages/Customer/Card/CustomerAddress.vue
index f1799d0cc93..1b0d1dde11a 100644
--- a/src/pages/Customer/Card/CustomerAddress.vue
+++ b/src/pages/Customer/Card/CustomerAddress.vue
@@ -61,7 +61,7 @@ watch(
     (newValue) => {
         if (!newValue) return;
         getClientData(newValue);
-    },
+    }
 );
 
 const getClientData = async (id) => {
@@ -137,7 +137,7 @@ const toCustomerAddressEdit = (addressId) => {
                         <QIcon
                             :style="{
                                 'font-variation-settings': `'FILL' ${isDefaultAddress(
-                                    item,
+                                    item
                                 )}`,
                             }"
                             color="primary"
@@ -150,7 +150,7 @@ const toCustomerAddressEdit = (addressId) => {
                                     t(
                                         isDefaultAddress(item)
                                             ? 'Default address'
-                                            : 'Set as default',
+                                            : 'Set as default'
                                     )
                                 }}
                             </QTooltip>
@@ -216,7 +216,7 @@ const toCustomerAddressEdit = (addressId) => {
             color="primary"
             fab
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
         />
         <QTooltip>
             {{ t('New consignee') }}
diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue
index 11db92eab94..04ef5f882ff 100644
--- a/src/pages/Customer/Card/CustomerBalance.vue
+++ b/src/pages/Customer/Card/CustomerBalance.vue
@@ -158,7 +158,7 @@ const columns = computed(() => [
                     openConfirmationModal(
                         t('Send compensation'),
                         t('Do you want to report compensation to the client by mail?'),
-                        () => sendEmail(`Receipts/${id}/balance-compensation-email`),
+                        () => sendEmail(`Receipts/${id}/balance-compensation-email`)
                     ),
             },
         ],
@@ -291,7 +291,7 @@ const showBalancePdf = ({ id }) => {
             color="primary"
             fab
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
         />
         <QTooltip>
             {{ t('New payment') }}
diff --git a/src/pages/Customer/Card/CustomerBasicData.vue b/src/pages/Customer/Card/CustomerBasicData.vue
index 36ec4763e87..e9a349e0b94 100644
--- a/src/pages/Customer/Card/CustomerBasicData.vue
+++ b/src/pages/Customer/Card/CustomerBasicData.vue
@@ -54,10 +54,10 @@ function onBeforeSave(formData, originalData) {
         auto-load
     />
     <FormModel
-        :url-update="`Clients/${route.params.id}`"
+        :url="`Clients/${route.params.id}`"
         auto-load
+        model="customer"
         :mapper="onBeforeSave"
-        model="Customer"
     >
         <template #form="{ data, validate }">
             <VnRow>
diff --git a/src/pages/Customer/Card/CustomerBillingData.vue b/src/pages/Customer/Card/CustomerBillingData.vue
index cc894d01e64..f1e78d9e564 100644
--- a/src/pages/Customer/Card/CustomerBillingData.vue
+++ b/src/pages/Customer/Card/CustomerBillingData.vue
@@ -27,7 +27,7 @@ const getBankEntities = (data, formData) => {
 </script>
 
 <template>
-    <FormModel :url-update="`Clients/${route.params.id}`" auto-load model="Customer">
+    <FormModel :url-update="`Clients/${route.params.id}`" auto-load model="customer">
         <template #form="{ data, validate }">
             <VnRow>
                 <VnSelect
diff --git a/src/pages/Customer/Card/CustomerCard.vue b/src/pages/Customer/Card/CustomerCard.vue
index 75fcb98fa19..f46884834d7 100644
--- a/src/pages/Customer/Card/CustomerCard.vue
+++ b/src/pages/Customer/Card/CustomerCard.vue
@@ -5,8 +5,8 @@ import CustomerDescriptor from './CustomerDescriptor.vue';
 
 <template>
     <VnCardBeta
-        data-key="Customer"
-        :url="`Clients/${$route.params.id}/getCard`"
+        data-key="Client"
+        base-url="Clients"
         :descriptor="CustomerDescriptor"
     />
 </template>
diff --git a/src/pages/Customer/Card/CustomerConsumption.vue b/src/pages/Customer/Card/CustomerConsumption.vue
index f3949bb32d7..f0d8dea47ee 100644
--- a/src/pages/Customer/Card/CustomerConsumption.vue
+++ b/src/pages/Customer/Card/CustomerConsumption.vue
@@ -61,23 +61,6 @@ const columns = computed(() => [
         columnFilter: false,
         cardVisible: true,
     },
-    {
-        align: 'left',
-        name: 'buyerId',
-        label: t('customer.params.buyerId'),
-        component: 'select',
-        attrs: {
-            url: 'TicketRequests/getItemTypeWorker',
-            optionLabel: 'nickname',
-            optionValue: 'id',
-
-            fields: ['id', 'nickname'],
-            sortBy: ['nickname ASC'],
-            optionFilter: 'firstName',
-        },
-        cardVisible: false,
-        visible: false,
-    },
     {
         name: 'description',
         align: 'left',
@@ -91,7 +74,6 @@ const columns = computed(() => [
         name: 'quantity',
         label: t('globals.quantity'),
         cardVisible: true,
-        visible: true,
         columnFilter: {
             inWhere: true,
         },
@@ -137,7 +119,7 @@ const openSendEmailDialog = async () => {
     openConfirmationModal(
         t('The consumption report will be sent'),
         t('Please, confirm'),
-        () => sendCampaignMetricsEmail({ address: arrayData.store.data.email }),
+        () => sendCampaignMetricsEmail({ address: arrayData.store.data.email })
     );
 };
 const sendCampaignMetricsEmail = ({ address }) => {
@@ -156,11 +138,11 @@ const updateDateParams = (value, params) => {
     const campaign = campaignList.value.find((c) => c.id === value);
     if (!campaign) return;
 
-    const { dated, scopeDays } = campaign;
-    const from = new Date(dated);
-    from.setDate(from.getDate() - scopeDays);
-    params.from = from;
-    params.to = dated;
+    const { dated, previousDays, scopeDays } = campaign;
+    const _date = new Date(dated);
+    const [from, to] = dateRange(_date);
+    params.from = new Date(from.setDate(from.getDate() - previousDays)).toISOString();
+    params.to = new Date(to.setDate(to.getDate() + scopeDays)).toISOString();
     return params;
 };
 </script>
@@ -170,7 +152,7 @@ const updateDateParams = (value, params) => {
         v-if="campaignList"
         data-key="CustomerConsumption"
         url="Clients/consumption"
-        :order="['itemTypeFk', 'itemName', 'itemSize', 'description']"
+        :order="['itemTypeFk', 'itemName', 'itemSize', 'description']"        
         :filter="{ where: { clientFk: route.params.id } }"
         :columns="columns"
         search-url="consumption"
@@ -218,60 +200,29 @@ const updateDateParams = (value, params) => {
             <div v-if="row.subName" class="subName">
                 {{ row.subName }}
             </div>
-            <FetchedTags :item="row" />
+            <FetchedTags :item="row" :max-length="3" />
         </template>
         <template #moreFilterPanel="{ params }">
             <div class="column no-wrap flex-center q-gutter-y-md q-mt-xs q-pr-xl">
-                <VnSelect
-                    :filled="true"
-                    class="q-px-sm q-pt-none fit"
-                    url="ItemTypes"
-                    v-model="params.typeId"
-                    :label="t('item.list.typeName')"
-                    :fields="['id', 'name', 'categoryFk']"
-                    :include="'category'"
-                    :sortBy="'name ASC'"
-                    dense
-                >
-                    <template #option="scope">
-                        <QItem v-bind="scope.itemProps">
-                            <QItemSection>
-                                <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
-                                <QItemLabel caption>{{
-                                    scope.opt?.category?.name
-                                }}</QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template>
-                </VnSelect>
-                <VnSelect
-                    :filled="true"
-                    class="q-px-sm q-pt-none fit"
-                    url="ItemCategories"
-                    v-model="params.categoryId"
-                    :label="t('item.list.category')"
-                    :fields="['id', 'name']"
-                    :sortBy="'name ASC'"
-                    dense
-                />
                 <VnSelect
                     v-model="params.campaign"
                     :options="campaignList"
                     :label="t('globals.campaign')"
                     :filled="true"
                     class="q-px-sm q-pt-none fit"
-                    :option-label="(opt) => t(opt.code)"
-                    :fields="['id', 'code', 'dated', 'scopeDays']"
-                    @update:model-value="(data) => updateDateParams(data, params)"
                     dense
+                    option-label="code"
+                    @update:model-value="(data) => updateDateParams(data, params)"
                 >
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
                             <QItemSection>
-                                <QItemLabel> {{ t(scope.opt?.code) }} </QItemLabel>
-                                <QItemLabel caption>
-                                    {{ new Date(scope.opt?.dated).getFullYear() }}
-                                </QItemLabel>
+                                <QItemLabel>
+                                    {{ scope.opt?.code }}
+                                    {{
+                                        new Date(scope.opt?.dated).getFullYear()
+                                    }}</QItemLabel
+                                >
                             </QItemSection>
                         </QItem>
                     </template>
@@ -296,21 +247,7 @@ const updateDateParams = (value, params) => {
 </template>
 
 <i18n>
-en:
-
-    valentinesDay: Valentine's Day
-    mothersDay: Mother's Day
-    allSaints: All Saints' Day
-    frenchMothersDay: Mother's Day in France
 es:
     Enter a new search: Introduce una nueva búsqueda
     Group by items: Agrupar por artículos
-    valentinesDay: Día de San Valentín
-    mothersDay: Día de la Madre
-    allSaints: Día de Todos los Santos
-    frenchMothersDay: (Francia) Día de la Madre
-    Campaign consumption: Consumo campaña
-    Campaign: Campaña
-    From: Desde
-    To: Hasta
 </i18n>
diff --git a/src/pages/Customer/Card/CustomerContacts.vue b/src/pages/Customer/Card/CustomerContacts.vue
index d03f7124466..c420f650e85 100644
--- a/src/pages/Customer/Card/CustomerContacts.vue
+++ b/src/pages/Customer/Card/CustomerContacts.vue
@@ -62,7 +62,7 @@ const customerContactsRef = ref(null);
                                 color="primary"
                                 flat
                                 icon="add"
-                                v-shortcut="'+'"
+                                shortcut="+"
                             >
                                 <QTooltip>
                                     {{ t('Add contact') }}
diff --git a/src/pages/Customer/Card/CustomerCreditContracts.vue b/src/pages/Customer/Card/CustomerCreditContracts.vue
index a49faeb8dc5..7dc53db723f 100644
--- a/src/pages/Customer/Card/CustomerCreditContracts.vue
+++ b/src/pages/Customer/Card/CustomerCreditContracts.vue
@@ -195,7 +195,7 @@ const updateData = () => {
             color="primary"
             fab
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
         />
         <QTooltip>
             {{ t('New contract') }}
diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue
index 89f9d94494f..d7a8a59a140 100644
--- a/src/pages/Customer/Card/CustomerDescriptor.vue
+++ b/src/pages/Customer/Card/CustomerDescriptor.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
@@ -11,15 +11,6 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
-import { useState } from 'src/composables/useState';
-const state = useState();
-
-const customer = ref();
-
-onMounted(async () => {
-    customer.value = state.get('Customer');
-    if (customer.value) customer.value.webAccess = data.value?.account?.isActive;
-});
 
 const customerDebt = ref();
 const customerCredit = ref();
@@ -55,10 +46,13 @@ const debtWarning = computed(() => {
 
 <template>
     <CardDescriptor
+        module="Customer"
         :url="`Clients/${entityId}/getCard`"
-        :summary="$props.summary"
-        data-key="Customer"
+        :title="data.title"
+        :subtitle="data.subtitle"
         @on-fetch="setData"
+        :summary="$props.summary"
+        data-key="customer"
         width="lg-width"
     >
         <template #menu="{ entity }">
@@ -67,7 +61,7 @@ const debtWarning = computed(() => {
         <template #body="{ entity }">
             <VnLv
                 :label="t('customer.summary.payMethod')"
-                :value="entity.payMethod?.name"
+                :value="entity.payMethod.name"
             />
 
             <VnLv
@@ -96,7 +90,7 @@ const debtWarning = computed(() => {
             </VnLv>
             <VnLv
                 :label="t('customer.extendedList.tableVisibleColumns.businessTypeFk')"
-                :value="entity.businessType?.description"
+                :value="entity.businessType.description"
             />
         </template>
         <template #icons="{ entity }">
@@ -109,21 +103,7 @@ const debtWarning = computed(() => {
                 >
                     <QTooltip>{{ t('customer.card.isDisabled') }}</QTooltip>
                 </QIcon>
-
-                <QIcon
-                    v-if="entity?.substitutionAllowed"
-                    name="help"
-                    size="xs"
-                    color="primary"
-                >
-                    <QTooltip>{{ t('Allowed substitution') }}</QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="customer?.isFreezed"
-                    name="vn:frozen"
-                    size="xs"
-                    color="primary"
-                >
+                <QIcon v-if="entity.isFreezed" name="vn:frozen" size="xs" color="primary">
                     <QTooltip>{{ t('customer.card.isFrozen') }}</QTooltip>
                 </QIcon>
                 <QIcon
@@ -163,13 +143,13 @@ const debtWarning = computed(() => {
                         <br />
                         {{
                             t('unpaidDated', {
-                                dated: toDate(customer.unpaid?.dated),
+                                dated: toDate(customer.unpaid.dated),
                             })
                         }}
                         <br />
                         {{
                             t('unpaidAmount', {
-                                amount: toCurrency(customer.unpaid?.amount),
+                                amount: toCurrency(customer.unpaid.amount),
                             })
                         }}
                     </QTooltip>
diff --git a/src/pages/Customer/Card/CustomerDescriptorMenu.vue b/src/pages/Customer/Card/CustomerDescriptorMenu.vue
index aea45721c7a..fb78eab69cc 100644
--- a/src/pages/Customer/Card/CustomerDescriptorMenu.vue
+++ b/src/pages/Customer/Card/CustomerDescriptorMenu.vue
@@ -61,16 +61,6 @@ const openCreateForm = (type) => {
         .join('&');
     useOpenURL(`/#/${type}/list?${params}`);
 };
-const updateSubstitutionAllowed = async () => {
-    try {
-        await axios.patch(`Clients/${route.params.id}`, {
-            substitutionAllowed: !$props.customer.substitutionAllowed,
-        });
-        notify('globals.notificationSent', 'positive');
-    } catch (error) {
-        notify(error.message, 'positive');
-    }
-};
 </script>
 
 <template>
@@ -79,13 +69,6 @@ const updateSubstitutionAllowed = async () => {
             {{ t('globals.pageTitles.createTicket') }}
         </QItemSection>
     </QItem>
-    <QItem v-ripple clickable>
-        <QItemSection @click="updateSubstitutionAllowed()">{{
-            $props.customer.substitutionAllowed
-                ? t('Disable substitution')
-                : t('Allow substitution')
-        }}</QItemSection>
-    </QItem>
     <QItem v-ripple clickable>
         <QItemSection @click="showSmsDialog()">{{ t('Send SMS') }}</QItemSection>
     </QItem>
diff --git a/src/pages/Customer/Card/CustomerFileManagement.vue b/src/pages/Customer/Card/CustomerFileManagement.vue
index b565db6e72c..134d8dbd68a 100644
--- a/src/pages/Customer/Card/CustomerFileManagement.vue
+++ b/src/pages/Customer/Card/CustomerFileManagement.vue
@@ -236,7 +236,7 @@ const toCustomerFileManagementCreate = () => {
             @click.stop="toCustomerFileManagementCreate()"
             color="primary"
             fab
-            v-shortcut="'+'"
+            shortcut="+"
             icon="add"
         />
         <QTooltip>
diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue
index 93909eb9c75..ceeb70bb679 100644
--- a/src/pages/Customer/Card/CustomerFiscalData.vue
+++ b/src/pages/Customer/Card/CustomerFiscalData.vue
@@ -12,7 +12,6 @@ import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnLocation from 'src/components/common/VnLocation.vue';
-import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 import { getDifferences, getUpdatedValues } from 'src/filters';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 
@@ -74,7 +73,7 @@ async function acceptPropagate({ isEqualizated }) {
     <FormModel
         :url-update="`Clients/${route.params.id}/updateFiscalData`"
         auto-load
-        model="Customer"
+        model="customer"
         :mapper="onBeforeSave"
         observe-form-changes
         @on-data-saved="checkEtChanges"
@@ -152,11 +151,14 @@ async function acceptPropagate({ isEqualizated }) {
             </VnRow>
             <VnRow>
                 <QCheckbox :label="t('Has to invoice')" v-model="data.hasToInvoice" />
-                <VnCheckbox
-                    v-model="data.isVies"
-                    :label="t('globals.isVies')"
-                    :info="t('whenActivatingIt')"
-                />
+                <div>
+                    <QCheckbox :label="t('globals.isVies')" v-model="data.isVies" />
+                    <QIcon name="info" class="cursor-info q-ml-sm" size="sm">
+                        <QTooltip>
+                            {{ t('whenActivatingIt') }}
+                        </QTooltip>
+                    </QIcon>
+                </div>
             </VnRow>
 
             <VnRow>
@@ -168,11 +170,17 @@ async function acceptPropagate({ isEqualizated }) {
             </VnRow>
 
             <VnRow>
-                <VnCheckbox
-                    v-model="data.isEqualizated"
-                    :label="t('Is equalizated')"
-                    :info="t('inOrderToInvoice')"
-                />
+                <div>
+                    <QCheckbox
+                        :label="t('Is equalizated')"
+                        v-model="data.isEqualizated"
+                    />
+                    <QIcon class="cursor-info q-ml-sm" name="info" size="sm">
+                        <QTooltip>
+                            {{ t('inOrderToInvoice') }}
+                        </QTooltip>
+                    </QIcon>
+                </div>
                 <QCheckbox :label="t('Daily invoice')" v-model="data.hasDailyInvoice" />
             </VnRow>
 
diff --git a/src/pages/Customer/Card/CustomerNotes.vue b/src/pages/Customer/Card/CustomerNotes.vue
index 189b5990420..b851746963d 100644
--- a/src/pages/Customer/Card/CustomerNotes.vue
+++ b/src/pages/Customer/Card/CustomerNotes.vue
@@ -23,6 +23,5 @@ const noteFilter = computed(() => {
         :body="{ clientFk: route.params.id }"
         style="overflow-y: auto"
         :select-type="true"
-        required
     />
 </template>
diff --git a/src/pages/Customer/Card/CustomerSamples.vue b/src/pages/Customer/Card/CustomerSamples.vue
index 19a7f87594f..f1269111237 100644
--- a/src/pages/Customer/Card/CustomerSamples.vue
+++ b/src/pages/Customer/Card/CustomerSamples.vue
@@ -104,7 +104,7 @@ const tableRef = ref();
             color="primary"
             fab
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
         />
         <QTooltip>
             {{ t('Send sample') }}
diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue
index 809f1091831..3c4106846e9 100644
--- a/src/pages/Customer/Card/CustomerWebAccess.vue
+++ b/src/pages/Customer/Card/CustomerWebAccess.vue
@@ -27,7 +27,7 @@ async function hasCustomerRole() {
     <FormModel
         :url-update="`Clients/${route.params.id}/updateUser`"
         :filter="filter"
-        model="Customer"
+        model="customer"
         :mapper="
             ({ account }) => {
                 const { name, email, active } = account;
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index 1c5a08304ef..9b883daad31 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -51,7 +51,11 @@ const exprBuilder = (param, value) => {
             </QItem>
             <QItem class="q-mb-sm">
                 <QItemSection>
-                    <VnInput :label="t('Name')" v-model="params.name" is-outlined />
+                    <VnInput
+                        :label="t('globals.name')"
+                        v-model="params.name"
+                        is-outlined
+                    />
                 </QItemSection>
             </QItem>
             <QItem class="q-mb-sm">
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index 0bfca7910a3..2f2dd59789e 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -274,7 +274,6 @@ const columns = computed(() => [
         align: 'left',
         name: 'isActive',
         label: t('customer.summary.isActive'),
-        component: 'checkbox',
         chip: {
             color: null,
             condition: (value) => !value,
@@ -313,7 +312,6 @@ const columns = computed(() => [
         align: 'left',
         name: 'isFreezed',
         label: t('customer.extendedList.tableVisibleColumns.isFreezed'),
-        component: 'checkbox',
         chip: {
             color: null,
             condition: (value) => value,
@@ -431,7 +429,7 @@ function handleLocation(data, location) {
             <VnTable
                 ref="tableRef"
                 :data-key="dataKey"
-                url="Clients/extendedListFilter"
+                url="Clients/filter"
                 :create="{
                     urlCreate: 'Clients/createWithUser',
                     title: t('globals.pageTitles.customerCreate'),
diff --git a/src/pages/Customer/Defaulter/CustomerDefaulter.vue b/src/pages/Customer/Defaulter/CustomerDefaulter.vue
index dc4ac9162a2..eca2ad59637 100644
--- a/src/pages/Customer/Defaulter/CustomerDefaulter.vue
+++ b/src/pages/Customer/Defaulter/CustomerDefaulter.vue
@@ -9,7 +9,7 @@ import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.v
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue';
-import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
 import VnTable from 'src/components/VnTable/VnTable.vue';
 import { useArrayData } from 'src/composables/useArrayData';
 
diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index f852c160ac2..d650bbbda32 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -233,7 +233,7 @@ function handleLocation(data, location) {
                             postcode: data.postalCode,
                             city: data.city,
                             province: data.province,
-                            country: data.province?.country,
+                            country: data.province.country,
                         }"
                         @update:model-value="(location) => handleLocation(data, location)"
                     ></VnLocation>
@@ -336,7 +336,7 @@ function handleLocation(data, location) {
                 class="cursor-pointer add-icon q-mt-md"
                 flat
                 icon="add"
-                v-shortcut="'+'"
+                shortcut="+"
             >
                 <QTooltip>
                     {{ t('Add note') }}
diff --git a/src/pages/Customer/components/CustomerNewPayment.vue b/src/pages/Customer/components/CustomerNewPayment.vue
index 8f61bac89ec..c2c38b55a74 100644
--- a/src/pages/Customer/components/CustomerNewPayment.vue
+++ b/src/pages/Customer/components/CustomerNewPayment.vue
@@ -84,7 +84,7 @@ function setPaymentType(accounting) {
     viewReceipt.value = isCash.value;
     if (accountingType.value.daysInFuture)
         initialData.payed.setDate(
-            initialData.payed.getDate() + accountingType.value.daysInFuture,
+            initialData.payed.getDate() + accountingType.value.daysInFuture
         );
     maxAmount.value = accountingType.value && accountingType.value.maxAmount;
 
@@ -114,7 +114,7 @@ function onBeforeSave(data) {
     if (isCash.value && shouldSendEmail.value && !data.email)
         return notify(t('There is no assigned email for this client'), 'negative');
 
-    data.bankFk = data.bankFk?.id;
+    data.bankFk = data.bankFk.id;
     return data;
 }
 
@@ -189,7 +189,7 @@ async function getAmountPaid() {
             :url-create="urlCreate"
             :mapper="onBeforeSave"
             @on-data-saved="onDataSaved"
-            prevent-submit
+            :prevent-submit="true"
         >
             <template #form="{ data, validate }">
                 <span ref="closeButton" class="row justify-end close-icon" v-close-popup>
diff --git a/src/pages/Customer/components/CustomerSamplesCreate.vue b/src/pages/Customer/components/CustomerSamplesCreate.vue
index 1294a5d2554..754693672d3 100644
--- a/src/pages/Customer/components/CustomerSamplesCreate.vue
+++ b/src/pages/Customer/components/CustomerSamplesCreate.vue
@@ -18,7 +18,6 @@ import VnInput from 'src/components/common/VnInput.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import CustomerSamplesPreview from 'src/pages/Customer/components/CustomerSamplesPreview.vue';
 import FormPopup from 'src/components/FormPopup.vue';
-import { useArrayData } from 'src/composables/useArrayData';
 
 const { dialogRef, onDialogOK } = useDialogPluginComponent();
 
@@ -40,7 +39,7 @@ const optionsSamplesVisible = ref([]);
 const sampleType = ref({ hasPreview: false });
 const initialData = reactive({});
 const entityId = computed(() => route.params.id);
-const customer = computed(() => useArrayData('Customer').store?.data);
+const customer = computed(() => state.get('customer'));
 const filterEmailUsers = { where: { userFk: user.value.id } };
 const filterClientsAddresses = {
     include: [
@@ -66,9 +65,9 @@ const filterSamplesVisible = {
 defineEmits(['confirm', ...useDialogPluginComponent.emits]);
 
 onBeforeMount(async () => {
-    initialData.clientFk = customer.value?.id;
-    initialData.recipient = customer.value?.email;
-    initialData.recipientId = customer.value?.id;
+    initialData.clientFk = customer.value.id;
+    initialData.recipient = customer.value.email;
+    initialData.recipientId = customer.value.id;
 });
 
 const setEmailUser = (data) => {
diff --git a/src/pages/Customer/locale/en.yml b/src/pages/Customer/locale/en.yml
index b6d495335f1..118f04a311f 100644
--- a/src/pages/Customer/locale/en.yml
+++ b/src/pages/Customer/locale/en.yml
@@ -107,9 +107,6 @@ customer:
         defaulterSinced: Defaulted Since
         hasRecovery: Has Recovery
         socialName: Social name
-        typeId: Type
-        buyerId: Buyer
-        categoryId: Category
         city: City
         phone: Phone
         postcode: Postcode
diff --git a/src/pages/Customer/locale/es.yml b/src/pages/Customer/locale/es.yml
index f50d049dad1..7c33ffee80f 100644
--- a/src/pages/Customer/locale/es.yml
+++ b/src/pages/Customer/locale/es.yml
@@ -108,9 +108,6 @@ customer:
         hasRecovery: Tiene recobro
         socialName: Razón social
         campaign: Campaña
-        typeId: Familia
-        buyerId: Comprador
-        categoryId: Reino
         city: Ciudad
         phone: Teléfono
         postcode: Código postal
diff --git a/src/pages/Worker/Department/Card/DepartmentBasicData.vue b/src/pages/Department/Card/DepartmentBasicData.vue
similarity index 73%
rename from src/pages/Worker/Department/Card/DepartmentBasicData.vue
rename to src/pages/Department/Card/DepartmentBasicData.vue
index 66210be7b34..b13aed2d3f4 100644
--- a/src/pages/Worker/Department/Card/DepartmentBasicData.vue
+++ b/src/pages/Department/Card/DepartmentBasicData.vue
@@ -1,16 +1,27 @@
 <script setup>
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
+
+const route = useRoute();
+const { t } = useI18n();
 </script>
 <template>
-    <FormModel model="Department" auto-load class="full-width">
+    <FormModel
+        :url="`Departments/${route.params.id}`"
+        model="department"
+        auto-load
+        class="full-width"
+    >
         <template #form="{ data, validate }">
             <VnRow>
                 <VnInput
-                    :label="$t('globals.name')"
+                    :label="t('globals.name')"
                     v-model="data.name"
                     :rules="validate('globals.name')"
                     clearable
@@ -18,33 +29,33 @@ import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
                 />
                 <VnInput
                     v-model="data.code"
-                    :label="$t('globals.code')"
+                    :label="t('globals.code')"
                     :rules="validate('globals.code')"
                     clearable
                 />
             </VnRow>
             <VnRow>
                 <VnInput
-                    :label="$t('department.chat')"
+                    :label="t('department.chat')"
                     v-model="data.chatName"
                     :rules="validate('department.chat')"
                     clearable
                 />
                 <VnInput
                     v-model="data.notificationEmail"
-                    :label="$t('globals.params.email')"
+                    :label="t('globals.params.email')"
                     :rules="validate('globals.params.email')"
                     clearable
                 />
             </VnRow>
             <VnRow>
                 <VnSelectWorker
-                    :label="$t('department.bossDepartment')"
+                    :label="t('department.bossDepartment')"
                     v-model="data.workerFk"
                     :rules="validate('department.bossDepartment')"
                 />
                 <VnSelect
-                    :label="$t('department.selfConsumptionCustomer')"
+                    :label="t('department.selfConsumptionCustomer')"
                     v-model="data.clientFk"
                     url="Clients"
                     option-value="id"
@@ -56,11 +67,11 @@ import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
             </VnRow>
             <VnRow>
                 <QCheckbox
-                    :label="$t('department.telework')"
+                    :label="t('department.telework')"
                     v-model="data.isTeleworking"
                 />
                 <QCheckbox
-                    :label="$t('department.notifyOnErrors')"
+                    :label="t('department.notifyOnErrors')"
                     v-model="data.hasToMistake"
                     :false-value="0"
                     :true-value="1"
@@ -68,17 +79,17 @@ import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
             </VnRow>
             <VnRow>
                 <QCheckbox
-                    :label="$t('department.worksInProduction')"
+                    :label="t('department.worksInProduction')"
                     v-model="data.isProduction"
                 />
                 <QCheckbox
-                    :label="$t('department.hasToRefill')"
+                    :label="t('department.hasToRefill')"
                     v-model="data.hasToRefill"
                 />
             </VnRow>
             <VnRow>
                 <QCheckbox
-                    :label="$t('department.hasToSendMail')"
+                    :label="t('department.hasToSendMail')"
                     v-model="data.hasToSendMail"
                 />
             </VnRow>
diff --git a/src/pages/Worker/Department/Card/DepartmentCard.vue b/src/pages/Department/Card/DepartmentCard.vue
similarity index 70%
rename from src/pages/Worker/Department/Card/DepartmentCard.vue
rename to src/pages/Department/Card/DepartmentCard.vue
index 2e3f1152148..4b9fe419cac 100644
--- a/src/pages/Worker/Department/Card/DepartmentCard.vue
+++ b/src/pages/Department/Card/DepartmentCard.vue
@@ -1,13 +1,13 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
-import DepartmentDescriptor from 'pages/Worker/Department/Card/DepartmentDescriptor.vue';
+import DepartmentDescriptor from 'pages/Department/Card/DepartmentDescriptor.vue';
 </script>
 <template>
     <VnCardBeta
         class="q-pa-md column items-center"
         v-bind="{ ...$attrs }"
         data-key="Department"
-        url="Departments"
+        base-url="Departments"
         :descriptor="DepartmentDescriptor"
     />
 </template>
diff --git a/src/pages/Worker/Department/Card/DepartmentDescriptor.vue b/src/pages/Department/Card/DepartmentDescriptor.vue
similarity index 84%
rename from src/pages/Worker/Department/Card/DepartmentDescriptor.vue
rename to src/pages/Department/Card/DepartmentDescriptor.vue
index 4b7dfd9b80d..b219ccfe12c 100644
--- a/src/pages/Worker/Department/Card/DepartmentDescriptor.vue
+++ b/src/pages/Department/Card/DepartmentDescriptor.vue
@@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import VnLv from 'src/components/ui/VnLv.vue';
 import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
+import useCardDescription from 'src/composables/useCardDescription';
 
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
@@ -31,6 +32,15 @@ const entityId = computed(() => {
     return $props.id || route.params.id;
 });
 
+const department = ref();
+
+const data = ref(useCardDescription());
+
+const setData = (entity) => {
+    if (!entity) return;
+    data.value = useCardDescription(entity.name, entity.id);
+};
+
 const removeDepartment = async () => {
     await axios.post(`/Departments/${entityId.value}/removeChild`, entityId.value);
     router.push({ name: 'WorkerDepartment' });
@@ -42,10 +52,19 @@ const { openConfirmationModal } = useVnConfirm();
 <template>
     <CardDescriptor
         ref="DepartmentDescriptorRef"
+        module="Department"
         :url="`Departments/${entityId}`"
+        :title="data.title"
+        :subtitle="data.subtitle"
         :summary="$props.summary"
         :to-module="{ name: 'WorkerDepartment' }"
-        data-key="Department"
+        @on-fetch="
+            (data) => {
+                department = data;
+                setData(data);
+            }
+        "
+        data-key="department"
     >
         <template #menu="{}">
             <QItem
@@ -55,7 +74,7 @@ const { openConfirmationModal } = useVnConfirm();
                     openConfirmationModal(
                         t('Are you sure you want to delete it?'),
                         t('Delete department'),
-                        removeDepartment,
+                        removeDepartment
                     )
                 "
             >
diff --git a/src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue b/src/pages/Department/Card/DepartmentDescriptorProxy.vue
similarity index 100%
rename from src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue
rename to src/pages/Department/Card/DepartmentDescriptorProxy.vue
diff --git a/src/pages/Worker/Department/Card/DepartmentSummary.vue b/src/pages/Department/Card/DepartmentSummary.vue
similarity index 99%
rename from src/pages/Worker/Department/Card/DepartmentSummary.vue
rename to src/pages/Department/Card/DepartmentSummary.vue
index 3719137e454..3d481601f23 100644
--- a/src/pages/Worker/Department/Card/DepartmentSummary.vue
+++ b/src/pages/Department/Card/DepartmentSummary.vue
@@ -27,7 +27,7 @@ onMounted(async () => {
 
 <template>
     <CardSummary
-        data-key="Department"
+        data-key="DepartmentSummary"
         ref="summary"
         :url="`Departments/${entityId}`"
         class="full-width"
diff --git a/src/pages/Worker/Department/Card/DepartmentSummaryDialog.vue b/src/pages/Department/Card/DepartmentSummaryDialog.vue
similarity index 100%
rename from src/pages/Worker/Department/Card/DepartmentSummaryDialog.vue
rename to src/pages/Department/Card/DepartmentSummaryDialog.vue
diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue
index 6462ed24a99..689eea686ee 100644
--- a/src/pages/Entry/Card/EntryBasicData.vue
+++ b/src/pages/Entry/Card/EntryBasicData.vue
@@ -1,32 +1,30 @@
 <script setup>
-import { onMounted, ref } from 'vue';
+import { ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { useRole } from 'src/composables/useRole';
-import { useState } from 'src/composables/useState';
-import { checkEntryLock } from 'src/composables/checkEntryLock';
 import FetchData from 'components/FetchData.vue';
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
+import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
+import FilterTravelForm from 'src/components/FilterTravelForm.vue';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
-import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
+import { toDate } from 'src/filters';
 import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
 
 const route = useRoute();
 const { t } = useI18n();
 const { hasAny } = useRole();
 const isAdministrative = () => hasAny(['administrative']);
-const state = useState();
-const user = state.getUser().fn();
 
 const companiesOptions = ref([]);
 const currenciesOptions = ref([]);
 
-onMounted(() => {
-    checkEntryLock(route.params.id, user.id);
-});
+const onFilterTravelSelected = (formData, id) => {
+    formData.travelFk = id;
+};
 </script>
 
 <template>
@@ -54,24 +52,46 @@ onMounted(() => {
     >
         <template #form="{ data }">
             <VnRow>
-                <VnSelectTravelExtended
-                    :data="data"
-                    v-model="data.travelFk"
-                    :onFilterTravelSelected="(data, result) => (data.travelFk = result)"
-                />
                 <VnSelectSupplier
                     v-model="data.supplierFk"
                     hide-selected
                     :required="true"
+                    map-options
                 />
+                <VnSelectDialog
+                    :label="t('entry.basicData.travel')"
+                    v-model="data.travelFk"
+                    url="Travels/filter"
+                    :fields="['id', 'warehouseInName']"
+                    option-value="id"
+                    option-label="warehouseInName"
+                    map-options
+                    hide-selected
+                    :required="true"
+                    action-icon="filter_alt"
+                >
+                    <template #form>
+                        <FilterTravelForm
+                            @travel-selected="onFilterTravelSelected(data, $event)"
+                        />
+                    </template>
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel>
+                                    {{ scope.opt?.agencyModeName }} -
+                                    {{ scope.opt?.warehouseInName }}
+                                    ({{ toDate(scope.opt?.shipped) }}) →
+                                    {{ scope.opt?.warehouseOutName }}
+                                    ({{ toDate(scope.opt?.landed) }})
+                                </QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelectDialog>
             </VnRow>
             <VnRow>
                 <VnInput v-model="data.reference" :label="t('globals.reference')" />
-                <VnInputNumber
-                    v-model="data.invoiceAmount"
-                    :label="t('entry.summary.invoiceAmount')"
-                    :positive="false"
-                />
             </VnRow>
             <VnRow>
                 <VnInput
@@ -93,7 +113,8 @@ onMounted(() => {
                 <VnInputNumber
                     :label="t('entry.summary.commission')"
                     v-model="data.commission"
-                    :step="1"
+                    step="1"
+                    autofocus
                     :positive="false"
                 />
                 <VnSelect
@@ -140,7 +161,7 @@ onMounted(() => {
                     :label="t('entry.summary.excludedFromAvailable')"
                 />
                 <QCheckbox
-                    :disable="!isAdministrative()"
+                    v-if="isAdministrative()"
                     v-model="data.isBooked"
                     :label="t('entry.basicData.booked')"
                 />
diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue
index 81578c609e1..6194ce5b8b2 100644
--- a/src/pages/Entry/Card/EntryBuys.vue
+++ b/src/pages/Entry/Card/EntryBuys.vue
@@ -1,806 +1,478 @@
 <script setup>
-import { useStateStore } from 'stores/useStateStore';
-import { useRoute } from 'vue-router';
+import { ref, computed } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { onMounted, ref } from 'vue';
+import { QBtn } from 'quasar';
 
-import { useState } from 'src/composables/useState';
-
-import FetchData from 'src/components/FetchData.vue';
-import VnTable from 'src/components/VnTable/VnTable.vue';
+import VnPaginate from 'src/components/ui/VnPaginate.vue';
+import VnSelect from 'components/common/VnSelect.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import FetchedTags from 'components/ui/FetchedTags.vue';
+import VnConfirm from 'components/ui/VnConfirm.vue';
 import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
-import FetchedTags from 'src/components/ui/FetchedTags.vue';
-import VnColor from 'src/components/common/VnColor.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import ItemDescriptor from 'src/pages/Item/Card/ItemDescriptor.vue';
+import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
+
+import { useQuasar } from 'quasar';
+import { toCurrency } from 'src/filters';
 import axios from 'axios';
-import VnSelectEnum from 'src/components/common/VnSelectEnum.vue';
-import { checkEntryLock } from 'src/composables/checkEntryLock';
+import useNotify from 'src/composables/useNotify.js';
 
-const $props = defineProps({
-    id: {
-        type: Number,
-        default: null,
-    },
-    editableMode: {
-        type: Boolean,
-        default: true,
-    },
-    tableHeight: {
-        type: String,
-        default: null,
-    },
-});
-
-const state = useState();
-const user = state.getUser().fn();
-const stateStore = useStateStore();
-const { t } = useI18n();
+const quasar = useQuasar();
 const route = useRoute();
-const selectedRows = ref([]);
-const entityId = ref($props.id ?? route.params.id);
-const entryBuysRef = ref();
-const footerFetchDataRef = ref();
-const footer = ref({});
-const columns = [
-    {
-        align: 'center',
-        labelAbbreviation: 'NV',
-        label: t('Ignore'),
-        toolTip: t('Ignored for available'),
-        name: 'isIgnored',
-        component: 'checkbox',
-        attrs: {
-            toggleIndeterminate: false,
+const router = useRouter();
+const { t } = useI18n();
+const { notify } = useNotify();
+
+const rowsSelected = ref([]);
+const entryBuysPaginateRef = ref(null);
+const originalRowDataCopy = ref(null);
+
+const getInputEvents = (colField, props) => {
+    return colField === 'packagingFk'
+        ? { 'update:modelValue': () => saveChange(colField, props) }
+        : {
+              'keyup.enter': () => saveChange(colField, props),
+              blur: () => saveChange(colField, props),
+          };
+};
+
+const tableColumnComponents = computed(() => ({
+    item: {
+        component: QBtn,
+        props: {
+            color: 'primary',
+            flat: true,
         },
-        create: true,
-        width: '25px',
+        event: () => ({}),
     },
-    {
-        label: t('Buyer'),
-        name: 'workerFk',
-        component: 'select',
-        attrs: {
-            url: 'Workers/search',
-            fields: ['id', 'nickname'],
-            optionLabel: 'nickname',
-            optionValue: 'id',
+    quantity: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            class: 'input-number',
+            dense: true,
         },
-        visible: false,
+        event: getInputEvents,
     },
-    {
-        label: t('Family'),
-        name: 'itemTypeFk',
-        component: 'select',
-        attrs: {
-            url: 'itemTypes',
-            fields: ['id', 'name'],
-            optionLabel: 'name',
-            optionValue: 'id',
-        },
-        visible: false,
-    },
-    {
-        name: 'id',
-        isId: true,
-        visible: false,
-        isEditable: false,
-        columnFilter: false,
-    },
-    {
-        name: 'entryFk',
-        isId: true,
-        visible: false,
-        isEditable: false,
-        disable: true,
-        create: true,
-        columnFilter: false,
-    },
-    {
-        align: 'center',
-        label: 'Id',
-        name: 'itemFk',
-        component: 'number',
-        isEditable: false,
-        width: '35px',
-    },
-    {
-        labelAbbreviation: '',
-        label: 'Color',
-        name: 'hex',
-        columnSearch: false,
-        isEditable: false,
-        width: '9px',
-        component: 'select',
-        attrs: {
-            url: 'Inks',
-            fields: ['id', 'name'],
-        },
-    },
-    {
-        align: 'center',
-        label: t('Article'),
-        name: 'name',
-        component: 'select',
-        attrs: {
-            url: 'Items',
-            fields: ['id', 'name'],
-            optionLabel: 'name',
-            optionValue: 'id',
-        },
-        width: '85px',
-        isEditable: false,
-    },
-    {
-        align: 'center',
-        label: t('Article'),
-        name: 'itemFk',
-        visible: false,
-        create: true,
-        columnFilter: false,
-    },
-    {
-        align: 'center',
-        labelAbbreviation: t('Siz.'),
-        label: t('Size'),
-        toolTip: t('Size'),
-        component: 'number',
-        name: 'size',
-        width: '35px',
-        isEditable: false,
-        style: () => {
-            return { color: 'var(--vn-label-color)' };
-        },
-    },
-    {
-        align: 'center',
-        labelAbbreviation: t('Sti.'),
-        label: t('Stickers'),
-        toolTip: t('Printed Stickers/Stickers'),
-        name: 'stickers',
-        component: 'input',
-        create: true,
-        attrs: {
-            positive: false,
-        },
-        cellEvent: {
-            'update:modelValue': async (value, oldValue, row) => {
-                row['quantity'] = value * row['packing'];
-                row['amount'] = row['quantity'] * row['buyingValue'];
-            },
-        },
-        width: '35px',
-    },
-    {
-        align: 'center',
-        label: t('Bucket'),
-        name: 'packagingFk',
-        component: 'select',
-        attrs: {
-            url: 'packagings',
+    packagingFk: {
+        component: VnSelect,
+        props: {
+            'option-value': 'id',
+            'option-label': 'id',
+            'emit-value': true,
+            'map-options': true,
+            'use-input': true,
+            'hide-selected': true,
+            url: 'Packagings',
             fields: ['id'],
-            optionLabel: 'id',
-            optionValue: 'id',
+            where: { freightItemFk: true },
+            'sort-by': 'id ASC',
+            dense: true,
         },
-        create: true,
-        width: '40px',
+        event: getInputEvents,
     },
-    {
-        align: 'center',
-        label: 'Kg',
-        name: 'weight',
-        component: 'number',
-        create: true,
-        width: '35px',
-        format: (row) => parseFloat(row['weight']).toFixed(1),
+    stickers: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            class: 'input-number',
+            dense: true,
+        },
+        event: getInputEvents,
     },
-    {
-        labelAbbreviation: 'P',
-        label: 'Packing',
-        toolTip: 'Packing',
-        name: 'packing',
-        component: 'number',
-        create: true,
-        cellEvent: {
-            'update:modelValue': async (value, oldValue, row) => {
-                const oldPacking = oldValue === 1 || oldValue === null ? 1 : oldValue;
-                row['weight'] = (row['weight'] * value) / oldPacking;
-                row['quantity'] = row['stickers'] * value;
-                row['amount'] = row['quantity'] * row['buyingValue'];
-            },
-        },
-        width: '30px',
-        style: (row) => {
-            if (row.groupingMode === 'grouping')
-                return { color: 'var(--vn-label-color)' };
+    printedStickers: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            class: 'input-number',
+            dense: true,
         },
+        event: getInputEvents,
     },
-    {
-        align: 'center',
-        labelAbbreviation: 'GM',
-        label: t('Grouping selector'),
-        toolTip: t('Grouping selector'),
-        name: 'groupingMode',
-        component: 'toggle',
-        attrs: {
-            'toggle-indeterminate': true,
-            trueValue: 'grouping',
-            falseValue: 'packing',
-            indeterminateValue: null,
-        },
-        size: 'xs',
-        width: '25px',
-        create: true,
-        rightFilter: false,
-        getIcon: (value) => {
-            switch (value) {
-                case 'grouping':
-                    return 'toggle_on';
-                case 'packing':
-                    return 'toggle_off';
-                default:
-                    return 'minimize';
-            }
+    weight: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            dense: true,
         },
+        event: getInputEvents,
     },
-    {
-        align: 'center',
-        labelAbbreviation: 'G',
-        label: 'Grouping',
-        toolTip: 'Grouping',
-        name: 'grouping',
-        component: 'number',
-        width: '30px',
-        create: true,
-        style: (row) => {
-            if (row.groupingMode === 'packing') return { color: 'var(--vn-label-color)' };
+    packing: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            dense: true,
         },
+        event: getInputEvents,
     },
-    {
-        align: 'center',
-        label: t('Quantity'),
-        name: 'quantity',
-        component: 'number',
-        attrs: {
-            positive: false,
+    grouping: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            dense: true,
         },
-        cellEvent: {
-            'update:modelValue': async (value, oldValue, row) => {
-                row['amount'] = value * row['buyingValue'];
-            },
-        },
-        width: '45px',
-        create: true,
-        style: getQuantityStyle,
+        event: getInputEvents,
     },
-    {
-        align: 'center',
-        labelAbbreviation: t('Cost'),
-        label: t('Buying value'),
-        toolTip: t('Buying value'),
-        name: 'buyingValue',
-        create: true,
-        component: 'number',
-        attrs: {
-            positive: false,
+    buyingValue: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            dense: true,
         },
-        cellEvent: {
-            'update:modelValue': async (value, oldValue, row) => {
-                row['amount'] = row['quantity'] * value;
-            },
+        event: getInputEvents,
+    },
+    price2: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            dense: true,
         },
-        width: '45px',
-        format: (row) => parseFloat(row['buyingValue']).toFixed(3),
+        event: getInputEvents,
     },
-    {
-        align: 'center',
-        label: t('Amount'),
-        name: 'amount',
-        width: '45px',
-        component: 'number',
-        attrs: {
-            positive: false,
+    price3: {
+        component: VnInput,
+        props: {
+            type: 'number',
+            min: 0,
+            dense: true,
         },
-        isEditable: false,
-        format: (row) => parseFloat(row['amount']).toFixed(2),
-        style: getAmountStyle,
+        event: getInputEvents,
     },
-    {
-        align: 'center',
-        labelAbbreviation: t('Pack.'),
-        label: t('Package'),
-        toolTip: t('Package'),
-        name: 'price2',
-        component: 'number',
-        width: '35px',
-        create: true,
-        format: (row) => parseFloat(row['price2']).toFixed(2),
+    import: {
+        component: 'span',
+        props: {},
+        event: () => ({}),
     },
-    {
-        align: 'center',
-        label: t('Box'),
-        name: 'price3',
-        component: 'number',
-        cellEvent: {
-            'update:modelValue': async (value, oldValue, row) => {
-                row['price2'] = row['price2'] * (value / oldValue);
-            },
-        },
-        width: '35px',
-        create: true,
-        format: (row) => parseFloat(row['price3']).toFixed(2),
-    },
-    {
-        align: 'center',
-        labelAbbreviation: 'CM',
-        label: t('Check min price'),
-        toolTip: t('Check min price'),
-        name: 'hasMinPrice',
-        attrs: {
-            toggleIndeterminate: false,
-        },
-        component: 'checkbox',
-        cellEvent: {
-            'update:modelValue': async (value, oldValue, row) => {
-                await axios.patch(`Items/${row['itemFk']}`, {
-                    hasMinPrice: value,
-                });
-            },
-        },
-        width: '25px',
-    },
-    {
-        align: 'center',
-        labelAbbreviation: 'Min.',
-        label: t('Minimum price'),
-        toolTip: t('Minimum price'),
-        name: 'minPrice',
-        component: 'number',
-        cellEvent: {
-            'update:modelValue': async (value, oldValue, row) => {
-                await axios.patch(`Items/${row['itemFk']}`, {
-                    minPrice: value,
-                });
-            },
-        },
-        width: '35px',
-        style: (row) => {
-            if (!row?.hasMinPrice) return { color: 'var(--vn-label-color)' };
-        },
-        format: (row) => parseFloat(row['minPrice']).toFixed(2),
-    },
-    {
-        align: 'center',
-        labelAbbreviation: t('P.Sen'),
-        label: t('Packing sent'),
-        toolTip: t('Packing sent'),
-        name: 'packingOut',
-        component: 'number',
-        isEditable: false,
-        width: '40px',
-        style: () => {
-            return { color: 'var(--vn-label-color)' };
-        },
-    },
-    {
-        align: 'center',
-        labelAbbreviation: t('Com.'),
-        label: t('Comment'),
-        toolTip: t('Comment'),
-        name: 'comment',
-        component: 'input',
-        isEditable: false,
-        width: '50px',
-    },
-    {
-        align: 'center',
-        labelAbbreviation: 'Prod.',
-        label: t('Producer'),
-        toolTip: t('Producer'),
-        name: 'subName',
-        isEditable: false,
-        width: '45px',
-        style: () => {
-            return { color: 'var(--vn-label-color)' };
-        },
-    },
-    {
-        align: 'center',
-        label: t('Tags'),
-        name: 'tags',
-        width: '125px',
-        columnSearch: false,
-    },
-    {
-        align: 'center',
-        labelAbbreviation: 'Comp.',
-        label: t('Company'),
-        toolTip: t('Company'),
-        name: 'company_name',
-        component: 'input',
-        isEditable: false,
-        width: '35px',
-        style: () => {
-            return { color: 'var(--vn-label-color)' };
-        },
-    },
-];
+}));
 
-function getQuantityStyle(row) {
-    if (row?.quantity !== row?.stickers * row?.packing)
-        return { color: 'var(--q-negative)' };
-}
-function getAmountStyle(row) {
-    if (row?.isChecked) return { color: 'var(--q-positive)' };
-    return { color: 'var(--vn-label-color)' };
-}
-
-async function beforeSave(data, getChanges) {
-    try {
-        const changes = data.updates;
-        if (!changes) return data;
-        const patchPromises = [];
-
-        for (const change of changes) {
-            let patchData = {};
-
-            if ('hasMinPrice' in change.data) {
-                patchData.hasMinPrice = change.data?.hasMinPrice;
-                delete change.data.hasMinPrice;
-            }
-            if ('minPrice' in change.data) {
-                patchData.minPrice = change.data?.minPrice;
-                delete change.data.minPrice;
-            }
-
-            if (Object.keys(patchData).length > 0) {
-                const promise = axios
-                    .get('Buys/findOne', {
-                        params: {
-                            filter: {
-                                fields: ['itemFk'],
-                                where: { id: change.where.id },
-                            },
-                        },
-                    })
-                    .then((buy) => {
-                        return axios.patch(`Items/${buy.data.itemFk}`, patchData);
-                    })
-                    .catch((error) => {
-                        console.error('Error processing change: ', change, error);
-                    });
-
-                patchPromises.push(promise);
-            }
-        }
-
-        await Promise.all(patchPromises);
-
-        data.updates = changes.filter((change) => Object.keys(change.data).length > 0);
-
-        return data;
-    } catch (error) {
-        console.error('Error in beforeSave:', error);
-        throw error;
-    }
-}
-
-function invertQuantitySign(rows, sign) {
-    for (const row of rows) {
-        if (sign > 0) row.quantity = Math.abs(row.quantity);
-        else if (row.quantity > 0) row.quantity = -row.quantity;
-    }
-}
-function setIsChecked(rows, value) {
-    for (const row of rows) {
-        row.isChecked = value;
-    }
-    footerFetchDataRef.value.fetch();
-}
-
-async function setBuyUltimate(itemFk, data) {
-    if (!itemFk) return;
-    const buyUltimate = await axios.get(`Entries/getBuyUltimate`, {
-        params: {
-            itemFk,
-            warehouseFk: user.warehouseFk,
-            date: Date.vnNew(),
+const entriesTableColumns = computed(() => {
+    return [
+        {
+            label: t('globals.item'),
+            field: 'itemFk',
+            name: 'item',
+            align: 'left',
         },
-    });
-    const buyUltimateData = buyUltimate.data[0];
-
-    const allowedKeys = columns
-        .filter((col) => col.create === true)
-        .map((col) => col.name);
-
-    allowedKeys.forEach((key) => {
-        if (buyUltimateData.hasOwnProperty(key) && key !== 'entryFk') {
-            if (!['stickers', 'quantity'].includes(key)) data[key] = buyUltimateData[key];
-        }
-    });
-}
-
-onMounted(() => {
-    stateStore.rightDrawer = false;
-    if ($props.editableMode) checkEntryLock(entityId.value, user.id);
+        {
+            label: t('globals.quantity'),
+            field: 'quantity',
+            name: 'quantity',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.package'),
+            field: 'packagingFk',
+            name: 'packagingFk',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.stickers'),
+            field: 'stickers',
+            name: 'stickers',
+            align: 'left',
+        },
+        {
+            label: t('entry.buys.printedStickers'),
+            field: 'printedStickers',
+            name: 'printedStickers',
+            align: 'left',
+        },
+        {
+            label: t('globals.weight'),
+            field: 'weight',
+            name: 'weight',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.packing'),
+            field: 'packing',
+            name: 'packing',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.grouping'),
+            field: 'grouping',
+            name: 'grouping',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.buyingValue'),
+            field: 'buyingValue',
+            name: 'buyingValue',
+            align: 'left',
+            format: (value) => toCurrency(value),
+        },
+        {
+            label: t('item.fixedPrice.groupingPrice'),
+            field: 'price2',
+            name: 'price2',
+            align: 'left',
+        },
+        {
+            label: t('item.fixedPrice.packingPrice'),
+            field: 'price3',
+            name: 'price3',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.import'),
+            name: 'import',
+            align: 'left',
+            format: (_, row) => toCurrency(row.buyingValue * row.quantity),
+        },
+    ];
 });
+
+const copyOriginalRowsData = (rows) => {
+    originalRowDataCopy.value = JSON.parse(JSON.stringify(rows));
+};
+
+const saveChange = async (field, { rowIndex, row }) => {
+    if (originalRowDataCopy.value[rowIndex][field] == row[field]) return;
+    await axios.patch(`Buys/${row.id}`, row);
+    originalRowDataCopy.value[rowIndex][field] = row[field];
+};
+
+const openRemoveDialog = async () => {
+    quasar
+        .dialog({
+            component: VnConfirm,
+            componentProps: {
+                title: t('Confirm deletion'),
+                message: t(
+                    `Are you sure you want to delete this buy${
+                        rowsSelected.value.length > 1 ? 's' : ''
+                    }?`
+                ),
+                data: rowsSelected.value,
+            },
+        })
+        .onOk(async () => {
+            await deleteBuys();
+            const notifyMessage = t(
+                `Buy${rowsSelected.value.length > 1 ? 's' : ''} deleted`
+            );
+            notify(notifyMessage, 'positive');
+        });
+};
+
+const deleteBuys = async () => {
+    await axios.post('Buys/deleteBuys', { buys: rowsSelected.value });
+    entryBuysPaginateRef.value.fetch();
+};
+
+const importBuys = () => {
+    router.push({ name: 'EntryBuysImport' });
+};
+
+const toggleGroupingMode = async (buy, mode) => {
+    const groupingMode = mode === 'grouping' ? mode : 'packing';
+    const newGroupingMode = buy.groupingMode === groupingMode ? null : groupingMode;
+    const params = {
+        groupingMode: newGroupingMode,
+    };
+    await axios.patch(`Buys/${buy.id}`, params);
+    buy.groupingMode = newGroupingMode;
+};
+
+const lockIconType = (groupingMode, mode) => {
+    if (mode === 'packing') {
+        return groupingMode === 'packing' ? 'lock' : 'lock_open';
+    } else {
+        return groupingMode === 'grouping' ? 'lock' : 'lock_open';
+    }
+};
 </script>
+
 <template>
-    <Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown() && editableMode">
-        <QBtnGroup push style="column-gap: 1px">
-            <QBtnDropdown
-                label="+/-"
-                color="primary"
-                flat
-                :title="t('Invert quantity value')"
-                :disable="!selectedRows.length"
-                data-cy="change-quantity-sign"
-            >
-                <QList>
-                    <QItem>
-                        <QItemSection>
-                            <QBtn
-                                flat
-                                @click="invertQuantitySign(selectedRows, -1)"
-                                data-cy="set-negative-quantity"
-                            >
-                                <span style="font-size: large">-</span>
-                            </QBtn>
-                        </QItemSection>
-                    </QItem>
-                    <QItem>
-                        <QItemSection>
-                            <QBtn
-                                flat
-                                @click="invertQuantitySign(selectedRows, 1)"
-                                data-cy="set-positive-quantity"
-                            >
-                                <span style="font-size: large">+</span>
-                            </QBtn>
-                        </QItemSection>
-                    </QItem>
-                </QList>
-            </QBtnDropdown>
-            <QBtnDropdown
-                icon="price_check"
-                color="primary"
-                flat
-                :title="t('Check buy amount')"
-                :disable="!selectedRows.length"
-                data-cy="check-buy-amount"
-            >
-                <QList>
-                    <QItem>
-                        <QItemSection>
-                            <QBtn
-                                size="sm"
-                                icon="check"
-                                flat
-                                @click="setIsChecked(selectedRows, true)"
-                                data-cy="check-amount"
-                            />
-                        </QItemSection>
-                    </QItem>
-                    <QItem>
-                        <QItemSection>
-                            <QBtn
-                                size="sm"
-                                icon="close"
-                                flat
-                                @click="setIsChecked(selectedRows, false)"
-                                data-cy="uncheck-amount"
-                            />
-                        </QItemSection>
-                    </QItem>
-                </QList>
-            </QBtnDropdown>
-        </QBtnGroup>
-    </Teleport>
-    <FetchData
-        ref="footerFetchDataRef"
-        :url="`Entries/${entityId}/getBuyList`"
-        :params="{ groupBy: 'GROUP BY b.entryFk' }"
-        @on-fetch="(data) => (footer = data[0])"
-        auto-load
-    />
-    <VnTable
-        ref="entryBuysRef"
+    <VnSubToolbar>
+        <template #st-actions>
+            <QBtnGroup push style="column-gap: 10px">
+                <slot name="moreBeforeActions" />
+                <QBtn
+                    :label="t('globals.remove')"
+                    color="primary"
+                    icon="delete"
+                    flat
+                    @click="openRemoveDialog()"
+                    :disable="!rowsSelected?.length"
+                    :title="t('globals.remove')"
+                />
+            </QBtnGroup>
+        </template>
+    </VnSubToolbar>
+    <VnPaginate
+        ref="entryBuysPaginateRef"
         data-key="EntryBuys"
-        :url="`Entries/${entityId}/getBuyList`"
-        save-url="Buys/crud"
-        :disable-option="{ card: true }"
-        v-model:selected="selectedRows"
-        @on-fetch="() => footerFetchDataRef.fetch()"
-        :table="
-            editableMode
-                ? {
-                      'row-key': 'id',
-                      selection: 'multiple',
-                  }
-                : {}
-        "
-        :create="
-            editableMode
-                ? {
-                      urlCreate: 'Buys',
-                      title: t('Create buy'),
-                      onDataSaved: () => {
-                          entryBuysRef.reload();
-                      },
-                      formInitialData: { entryFk: entityId, isIgnored: false },
-                      showSaveAndContinueBtn: true,
-                  }
-                : null
-        "
-        :create-complement="{
-            isFullWidth: true,
-            containerStyle: {
-                display: 'flex',
-                'flex-wrap': 'wrap',
-                gap: '16px',
-                position: 'relative',
-                height: '450px',
-            },
-            columnGridStyle: {
-                'max-width': '50%',
-                flex: 1,
-                'margin-right': '30px',
-            },
-        }"
-        :is-editable="editableMode"
-        :without-header="!editableMode"
-        :with-filters="editableMode"
-        :right-search="true"
-        :right-search-icon="true"
-        :row-click="false"
-        :columns="columns"
-        :beforeSaveFn="beforeSave"
-        class="buyList"
-        :table-height="$props.tableHeight ?? '84vh'"
+        :url="`Entries/${route.params.id}/getBuys`"
+        @on-fetch="copyOriginalRowsData($event)"
         auto-load
-        footer
-        data-cy="entry-buys"
     >
-        <template #column-hex="{ row }">
-            <VnColor :colors="row?.hexJson" style="height: 100%; min-width: 2000px" />
-        </template>
-        <template #column-name="{ row }">
-            <span class="link">
-                {{ row?.name }}
-                <ItemDescriptorProxy :id="row?.itemFk" />
-            </span>
-        </template>
-        <template #column-tags="{ row }">
-            <FetchedTags :item="row" :columns="3" />
-        </template>
-        <template #column-stickers="{ row }">
-            <span :class="editableMode ? 'editable-text' : ''">
-                <span style="color: var(--vn-label-color)">
-                    {{ row.printedStickers }}
-                </span>
-                <span>/{{ row.stickers }}</span>
-            </span>
-        </template>
-        <template #column-footer-stickers>
-            <div>
-                <span style="color: var(--vn-label-color)">
-                    {{ footer?.printedStickers }}</span
-                >
-                <span>/</span>
-                <span data-cy="footer-stickers">{{ footer?.stickers }}</span>
-            </div>
-        </template>
-        <template #column-footer-weight>
-            {{ footer?.weight }}
-        </template>
-        <template #column-footer-quantity>
-            <span :style="getQuantityStyle(footer)" data-cy="footer-quantity">
-                {{ footer?.quantity }}
-            </span>
-        </template>
-        <template #column-footer-amount>
-            <span :style="getAmountStyle(footer)" data-cy="footer-amount">
-                {{ footer?.amount }}
-            </span>
-        </template>
-        <template #column-create-itemFk="{ data }">
-            <VnSelect
-                url="Items/search"
-                v-model="data.itemFk"
-                :label="t('Article')"
-                :fields="['id', 'name', 'size', 'producerName']"
-                :filter-options="['id', 'name', 'size', 'producerName']"
-                option-label="name"
-                option-value="id"
-                @update:modelValue="
-                    async (value) => {
-                        await setBuyUltimate(value, data);
-                    }
-                "
-                :required="true"
-                data-cy="itemFk-create-popup"
-                sort-by="nickname DESC"
+        <template #body="{ rows }">
+            <QTable
+                :rows="rows"
+                :columns="entriesTableColumns"
+                selection="multiple"
+                row-key="id"
+                class="full-width q-mt-md"
+                :grid="$q.screen.lt.md"
+                v-model:selected="rowsSelected"
+                :no-data-label="t('globals.noResults')"
             >
-                <template #option="scope">
-                    <QItem v-bind="scope.itemProps">
-                        <QItemSection>
-                            <QItemLabel>
-                                {{ scope.opt.name }}
-                            </QItemLabel>
-                            <QItemLabel caption>
-                                #{{ scope.opt.id }}, {{ scope.opt?.size }},
-                                {{ scope.opt?.producerName }}
-                            </QItemLabel>
-                        </QItemSection>
-                    </QItem>
+                <template #body="props">
+                    <QTr>
+                        <QTd>
+                            <QCheckbox v-model="props.selected" />
+                        </QTd>
+                        <QTd
+                            v-for="col in props.cols"
+                            :key="col.name"
+                            style="max-width: 100px"
+                        >
+                            <component
+                                :is="tableColumnComponents[col.name].component"
+                                v-bind="tableColumnComponents[col.name].props"
+                                v-model="props.row[col.field]"
+                                v-on="
+                                    tableColumnComponents[col.name].event(
+                                        col.field,
+                                        props
+                                    )
+                                "
+                            >
+                                <template
+                                    v-if="
+                                        col.name === 'grouping' || col.name === 'packing'
+                                    "
+                                    #append
+                                >
+                                    <QBtn
+                                        :icon="
+                                            lockIconType(props.row.groupingMode, col.name)
+                                        "
+                                        @click="toggleGroupingMode(props.row, col.name)"
+                                        class="cursor-pointer"
+                                        size="sm"
+                                        flat
+                                        dense
+                                        unelevated
+                                        push
+                                        :style="{
+                                            'font-variation-settings': `'FILL' ${
+                                                lockIconType(
+                                                    props.row.groupingMode,
+                                                    col.name
+                                                ) === 'lock'
+                                                    ? 1
+                                                    : 0
+                                            }`,
+                                        }"
+                                    />
+                                </template>
+                                <template
+                                    v-if="col.name === 'item' || col.name === 'import'"
+                                >
+                                    {{ col.value }}
+                                </template>
+                                <ItemDescriptorProxy
+                                    v-if="col.name === 'item'"
+                                    :id="props.row.item.id"
+                                />
+                            </component>
+                        </QTd>
+                    </QTr>
+                    <QTr no-hover class="full-width infoRow" style="column-span: all">
+                        <QTd />
+                        <QTd cols>
+                            <span>{{ props.row.item.itemType.code }}</span>
+                        </QTd>
+                        <QTd>
+                            <span>{{ props.row.item.size }}</span>
+                        </QTd>
+                        <QTd>
+                            <span>{{ toCurrency(props.row.item.minPrice) }}</span>
+                        </QTd>
+                        <QTd colspan="7">
+                            <span>{{ props.row.item.concept }}</span>
+                            <span v-if="props.row.item.subName" class="subName">
+                                {{ props.row.item.subName }}
+                            </span>
+                            <FetchedTags :item="props.row.item" />
+                        </QTd>
+                    </QTr>
                 </template>
-            </VnSelect>
+                <template #item="props">
+                    <div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
+                        <QCard bordered flat>
+                            <QCardSection>
+                                <QCheckbox v-model="props.selected" dense />
+                            </QCardSection>
+                            <QSeparator />
+                            <QList dense>
+                                <QItem v-for="col in props.cols" :key="col.name">
+                                    <component
+                                        :is="tableColumnComponents[col.name].component"
+                                        v-bind="tableColumnComponents[col.name].props"
+                                        v-model="props.row[col.field]"
+                                        v-on="
+                                            tableColumnComponents[col.name].event(
+                                                col.field,
+                                                props
+                                            )
+                                        "
+                                        class="full-width"
+                                    >
+                                        <template
+                                            v-if="
+                                                col.name === 'item' ||
+                                                col.name === 'import'
+                                            "
+                                        >
+                                            {{ col.label + ': ' + col.value }}
+                                        </template>
+                                    </component>
+                                </QItem>
+                            </QList>
+                        </QCard>
+                    </div>
+                </template>
+            </QTable>
         </template>
-        <template #column-create-groupingMode="{ data }">
-            <VnSelectEnum
-                :label="t('Grouping mode')"
-                v-model="data.groupingMode"
-                schema="vn"
-                table="buy"
-                column="groupingMode"
-                option-value="groupingMode"
-                option-label="groupingMode"
-            />
-        </template>
-        <template #previous-create-dialog="{ data }">
-            <div
-                style="position: absolute"
-                :class="{ 'centered-container': !data.itemFk }"
-            >
-                <ItemDescriptor :id="data.itemFk" v-if="data.itemFk" />
-                <div v-else>
-                    <span>{{ t('globals.noData') }}</span>
-                </div>
-            </div>
-        </template>
-    </VnTable>
+    </VnPaginate>
+
+    <QPageSticky :offset="[20, 20]">
+        <QBtn fab icon="upload" color="primary" @click="importBuys()" />
+        <QTooltip class="text-no-wrap">
+            {{ t('Import buys') }}
+        </QTooltip>
+    </QPageSticky>
 </template>
-<i18n>
-es:
-    Article: Artículo
-    Siz.: Med.
-    Size: Medida
-    Sti.: Eti.
-    Bucket: Cubo
-    Quantity: Cantidad
-    Amount: Importe
-    Pack.: Paq.
-    Package: Paquete
-    Box: Caja
-    P.Sen: P.Env
-    Packing sent: Packing envíos
-    Com.: Ref.
-    Comment: Referencia
-    Minimum price: Precio mínimo
-    Stickers: Etiquetas
-    Printed Stickers/Stickers: Etiquetas impresas/Etiquetas
-    Cost: Cost.
-    Buying value: Coste
-    Producer: Productor
-    Company: Compañia
-    Tags: Etiquetas
-    Grouping mode: Modo de agrupación
-    C.min: P.min
-    Ignore: Ignorar
-    Ignored for available: Ignorado para disponible
-    Grouping selector: Selector de grouping
-    Check min price: Marcar precio mínimo
-    Create buy: Crear compra
-    Invert quantity value: Invertir valor de cantidad
-    Check buy amount: Marcar como correcta la cantidad de compra
-</i18n>
+
 <style lang="scss" scoped>
-.centered-container {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    position: absolute;
-    width: 40%;
-    height: 100%;
+.q-table--horizontal-separator tbody tr:nth-child(odd) > td {
+    border-bottom-width: 0px;
+    border-top-width: 2px;
+    border-color: var(--vn-text-color);
+}
+.infoRow > td {
+    color: var(--vn-label-color);
 }
 </style>
+
+<i18n>
+es:
+    Import buys: Importar compras
+    Buy deleted: Compra eliminada
+    Buys deleted: Compras eliminadas
+    Confirm deletion: Confirmar eliminación
+    Are you sure you want to delete this buy?: Seguro que quieres eliminar esta compra?
+    Are you sure you want to delete this buys?: Seguro que quieres eliminar estas compras?
+</i18n>
diff --git a/src/pages/Entry/Card/EntryCard.vue b/src/pages/Entry/Card/EntryCard.vue
index be82289f4a5..e00623a21d0 100644
--- a/src/pages/Entry/Card/EntryCard.vue
+++ b/src/pages/Entry/Card/EntryCard.vue
@@ -1,13 +1,13 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import EntryDescriptor from './EntryDescriptor.vue';
-import filter from './EntryFilter.js';
+import filter from './EntryFilter.js'
 </script>
 <template>
     <VnCardBeta
         data-key="Entry"
-        url="Entries"
+        base-url="Entries"
         :descriptor="EntryDescriptor"
-        :filter="filter"
+        :user-filter="filter"
     />
 </template>
diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue
index 69b300cb2a6..19d13e51a50 100644
--- a/src/pages/Entry/Card/EntryDescriptor.vue
+++ b/src/pages/Entry/Card/EntryDescriptor.vue
@@ -1,19 +1,12 @@
 <script setup>
 import { ref, computed, onMounted } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
+import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { toDate } from 'src/filters';
-import { getUrl } from 'src/composables/getUrl';
-import { useQuasar } from 'quasar';
-import { usePrintService } from 'composables/usePrintService';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
-import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
-import axios from 'axios';
-
-const quasar = useQuasar();
-const { push } = useRouter();
-const { openReport } = usePrintService();
+import { toDate } from 'src/filters';
+import { getUrl } from 'src/composables/getUrl';
+import EntryDescriptorMenu from './EntryDescriptorMenu.vue';
 
 const $props = defineProps({
     id: {
@@ -90,63 +83,12 @@ const getEntryRedirectionFilter = (entry) => {
         to,
     });
 };
-
-function showEntryReport() {
-    openReport(`Entries/${entityId.value}/entry-order-pdf`);
-}
-
-function showNotification(type, message) {
-    quasar.notify({
-        type: type,
-        message: t(message),
-    });
-}
-
-async function recalculateRates(entity) {
-    try {
-        const entryConfig = await axios.get('EntryConfigs/findOne');
-        if (entryConfig.data?.inventorySupplierFk === entity.supplierFk) {
-            showNotification(
-                'negative',
-                'Cannot recalculate prices because this is an inventory entry',
-            );
-            return;
-        }
-
-        await axios.post(`Entries/${entityId.value}/recalcEntryPrices`);
-        showNotification('positive', 'Entry prices recalculated');
-    } catch (error) {
-        showNotification('negative', 'Failed to recalculate rates');
-        console.error(error);
-    }
-}
-
-async function cloneEntry() {
-    try {
-        const response = await axios.post(`Entries/${entityId.value}/cloneEntry`);
-        push({ path: `/entry/${response.data}` });
-        showNotification('positive', 'Entry cloned');
-    } catch (error) {
-        showNotification('negative', 'Failed to clone entry');
-        console.error(error);
-    }
-}
-
-async function deleteEntry() {
-    try {
-        await axios.post(`Entries/${entityId.value}/deleteEntry`);
-        push({ path: `/entry/list` });
-        showNotification('positive', 'Entry deleted');
-    } catch (error) {
-        showNotification('negative', 'Failed to delete entry');
-        console.error(error);
-    }
-}
 </script>
 
 <template>
     <CardDescriptor
         ref="entryDescriptorRef"
+        module="Entry"
         :url="`Entries/${entityId}`"
         :userFilter="entryFilter"
         title="supplier.nickname"
@@ -154,56 +96,15 @@ async function deleteEntry() {
         width="lg-width"
     >
         <template #menu="{ entity }">
-            <QItem
-                v-ripple
-                clickable
-                @click="showEntryReport(entity)"
-                data-cy="show-entry-report"
-            >
-                <QItemSection>{{ t('Show entry report') }}</QItemSection>
-            </QItem>
-            <QItem
-                v-ripple
-                clickable
-                @click="recalculateRates(entity)"
-                data-cy="recalculate-rates"
-            >
-                <QItemSection>{{ t('Recalculate rates') }}</QItemSection>
-            </QItem>
-            <QItem v-ripple clickable @click="cloneEntry(entity)" data-cy="clone-entry">
-                <QItemSection>{{ t('Clone') }}</QItemSection>
-            </QItem>
-            <QItem v-ripple clickable @click="deleteEntry(entity)" data-cy="delete-entry">
-                <QItemSection>{{ t('Delete') }}</QItemSection>
-            </QItem>
+            <EntryDescriptorMenu :id="entity.id" />
         </template>
         <template #body="{ entity }">
-            <VnLv :label="t('Travel')">
-                <template #value>
-                    <span class="link" v-if="entity?.travelFk">
-                        {{ entity.travel?.agency?.name }}
-                        {{ entity.travel?.warehouseOut?.code }} &rarr;
-                        {{ entity.travel?.warehouseIn?.code }}
-                        <TravelDescriptorProxy :id="entity?.travelFk" />
-                    </span>
-                </template>
-            </VnLv>
+            <VnLv :label="t('globals.agency')" :value="entity.travel?.agency?.name" />
+            <VnLv :label="t('shipped')" :value="toDate(entity.travel?.shipped)" />
+            <VnLv :label="t('landed')" :value="toDate(entity.travel?.landed)" />
             <VnLv
-                :label="t('entry.summary.travelShipped')"
-                :value="toDate(entity.travel?.shipped)"
-            />
-            <VnLv
-                :label="t('entry.summary.travelLanded')"
-                :value="toDate(entity.travel?.landed)"
-            />
-            <VnLv :label="t('entry.summary.currency')" :value="entity?.currency?.code" />
-            <VnLv
-                :label="t('entry.summary.invoiceAmount')"
-                :value="entity?.invoiceAmount"
-            />
-            <VnLv
-                :label="t('entry.summary.entryType')"
-                :value="entity?.entryType?.description"
+                :label="t('globals.warehouseOut')"
+                :value="entity.travel?.warehouseOut?.name"
             />
         </template>
         <template #icons="{ entity }">
@@ -230,14 +131,6 @@ async function deleteEntry() {
                         }}</QTooltip
                     >
                 </QIcon>
-                <QIcon
-                    v-if="!entity?.travelFk"
-                    name="vn:deletedTicket"
-                    size="xs"
-                    color="primary"
-                >
-                    <QTooltip>{{ t('This entry is deleted') }}</QTooltip>
-                </QIcon>
             </QCardActions>
         </template>
         <template #actions="{ entity }">
@@ -250,6 +143,21 @@ async function deleteEntry() {
                 >
                     <QTooltip>{{ t('Supplier card') }}</QTooltip>
                 </QBtn>
+                <QBtn
+                    :to="{
+                        name: 'TravelMain',
+                        query: {
+                            params: JSON.stringify({
+                                agencyModeFk: entity.travel?.agencyModeFk,
+                            }),
+                        },
+                    }"
+                    size="md"
+                    icon="local_airport"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('All travels with current agency') }}</QTooltip>
+                </QBtn>
                 <QBtn
                     :to="{
                         name: 'EntryMain',
@@ -269,24 +177,10 @@ async function deleteEntry() {
 </template>
 <i18n>
 es:
-    Travel: Envío
     Supplier card: Ficha del proveedor
     All travels with current agency: Todos los envíos con la agencia actual
     All entries with current supplier: Todas las entradas con el proveedor actual
     Show entry report: Ver informe del pedido
     Inventory entry: Es inventario
     Virtual entry: Es una redada
-    shipped: Enviado
-    landed: Recibido
-    This entry is deleted: Esta entrada está eliminada
-    Cannot recalculate prices because this is an inventory entry: No se pueden recalcular los precios porque es una entrada de inventario
-    Entry deleted: Entrada eliminada
-    Entry cloned: Entrada clonada
-    Entry prices recalculated: Precios de la entrada recalculados
-    Failed to recalculate rates: No se pudieron recalcular las tarifas
-    Failed to clone entry: No se pudo clonar la entrada
-    Failed to delete entry: No se pudo eliminar la entrada
-    Recalculate rates: Recalcular tarifas
-    Clone: Clonar
-    Delete: Eliminar
 </i18n>
diff --git a/src/pages/Entry/Card/EntryFilter.js b/src/pages/Entry/Card/EntryFilter.js
index d9fd1c2be9c..3ff62cf273c 100644
--- a/src/pages/Entry/Card/EntryFilter.js
+++ b/src/pages/Entry/Card/EntryFilter.js
@@ -9,7 +9,6 @@ export default {
                     'shipped',
                     'agencyModeFk',
                     'warehouseOutFk',
-                    'warehouseInFk',
                     'daysInForward',
                 ],
                 include: [
@@ -22,13 +21,13 @@ export default {
                     {
                         relation: 'warehouseOut',
                         scope: {
-                            fields: ['name', 'code'],
+                            fields: ['name'],
                         },
                     },
                     {
                         relation: 'warehouseIn',
                         scope: {
-                            fields: ['name', 'code'],
+                            fields: ['name'],
                         },
                     },
                 ],
@@ -40,17 +39,5 @@ export default {
                 fields: ['id', 'nickname'],
             },
         },
-        {
-            relation: 'currency',
-            scope: {
-                fields: ['id', 'code'],
-            },
-        },
-        {
-            relation: 'entryType',
-            scope: {
-                fields: ['code', 'description'],
-            },
-        },
     ],
 };
diff --git a/src/pages/Entry/Card/EntryNotes.vue b/src/pages/Entry/Card/EntryNotes.vue
index 459c3b069ac..55cac043792 100644
--- a/src/pages/Entry/Card/EntryNotes.vue
+++ b/src/pages/Entry/Card/EntryNotes.vue
@@ -17,7 +17,7 @@ const selected = ref([]);
 
 const sortEntryObservationOptions = (data) => {
     entryObservationsOptions.value = [...data].sort((a, b) =>
-        a.description.localeCompare(b.description),
+        a.description.localeCompare(b.description)
     );
 };
 
@@ -142,7 +142,7 @@ const columns = computed(() => [
             fab
             color="primary"
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
             @click="entryObservationsRef.insert()"
         />
     </QPageSticky>
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index c40e2ba46f6..8c46fb6e67e 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -2,17 +2,19 @@
 import { onMounted, ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { toDate } from 'src/filters';
-import { getUrl } from 'src/composables/getUrl';
-import axios from 'axios';
 
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
-import EntryBuys from './EntryBuys.vue';
-import VnTitle from 'src/components/common/VnTitle.vue';
-import VnCheckbox from 'src/components/common/VnCheckbox.vue';
+
+import { toDate, toCurrency, toCelsius } from 'src/filters';
+import { getUrl } from 'src/composables/getUrl';
+import axios from 'axios';
+import FetchedTags from 'src/components/ui/FetchedTags.vue';
 import VnToSummary from 'src/components/ui/VnToSummary.vue';
+import EntryDescriptorMenu from './EntryDescriptorMenu.vue';
+import VnRow from 'src/components/ui/VnRow.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -31,6 +33,117 @@ const entry = ref();
 const entryBuys = ref([]);
 const entryUrl = ref();
 
+onMounted(async () => {
+    entryUrl.value = (await getUrl('entry/')) + entityId.value;
+});
+
+const tableColumnComponents = {
+    quantity: {
+        component: () => 'span',
+        props: () => {},
+    },
+    stickers: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+    packagingFk: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+    weight: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+    packing: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+    grouping: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+    buyingValue: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+    amount: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+    pvp: {
+        component: () => 'span',
+        props: () => {},
+        event: () => {},
+    },
+};
+
+const entriesTableColumns = computed(() => {
+    return [
+        {
+            label: t('globals.quantity'),
+            field: 'quantity',
+            name: 'quantity',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.stickers'),
+            field: 'stickers',
+            name: 'stickers',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.package'),
+            field: 'packagingFk',
+            name: 'packagingFk',
+            align: 'left',
+        },
+        {
+            label: t('globals.weight'),
+            field: 'weight',
+            name: 'weight',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.packing'),
+            field: 'packing',
+            name: 'packing',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.grouping'),
+            field: 'grouping',
+            name: 'grouping',
+            align: 'left',
+        },
+        {
+            label: t('entry.summary.buyingValue'),
+            field: 'buyingValue',
+            name: 'buyingValue',
+            align: 'left',
+            format: (value) => toCurrency(value),
+        },
+        {
+            label: t('entry.summary.import'),
+            name: 'amount',
+            align: 'left',
+            format: (_, row) => toCurrency(row.buyingValue * row.quantity),
+        },
+        {
+            label: t('entry.summary.pvp'),
+            name: 'pvp',
+            align: 'left',
+            format: (_, row) => toCurrency(row.price2) + ' / ' + toCurrency(row.price3),
+        },
+    ];
+});
+
 async function setEntryData(data) {
     if (data) entry.value = data;
     await fetchEntryBuys();
@@ -40,18 +153,14 @@ const fetchEntryBuys = async () => {
     const { data } = await axios.get(`Entries/${entry.value.id}/getBuys`);
     if (data) entryBuys.value = data;
 };
-
-onMounted(async () => {
-    entryUrl.value = (await getUrl('entry/')) + entityId.value;
-});
 </script>
+
 <template>
     <CardSummary
         ref="summaryRef"
         :url="`Entries/${entityId}/getEntry`"
         @on-fetch="(data) => setEntryData(data)"
         data-key="EntrySummary"
-        data-cy="entry-summary"
     >
         <template #header-left>
             <VnToSummary
@@ -64,154 +173,159 @@ onMounted(async () => {
         <template #header>
             <span>{{ entry.id }} - {{ entry.supplier.nickname }}</span>
         </template>
+        <template #menu="{ entity }">
+            <EntryDescriptorMenu :id="entity.id" />
+        </template>
         <template #body>
             <QCard class="vn-one">
                 <VnTitle
                     :url="`#/entry/${entityId}/basic-data`"
                     :text="t('globals.summary.basicData')"
                 />
-                <div class="card-group">
-                    <div class="card-content">
-                        <VnLv
-                            :label="t('entry.summary.commission')"
-                            :value="entry?.commission"
-                        />
-                        <VnLv
-                            :label="t('entry.summary.currency')"
-                            :value="entry?.currency?.name"
-                        />
-                        <VnLv
-                            :label="t('globals.company')"
-                            :value="entry?.company?.code"
-                        />
-                        <VnLv :label="t('globals.reference')" :value="entry?.reference" />
-                        <VnLv
-                            :label="t('entry.summary.invoiceNumber')"
-                            :value="entry?.invoiceNumber"
-                        />
-                    </div>
-                    <div class="card-content">
-                        <VnCheckbox
-                            :label="t('entry.summary.ordered')"
-                            v-model="entry.isOrdered"
-                            :disable="true"
-                            size="xs"
-                        />
-                        <VnCheckbox
-                            :label="t('globals.confirmed')"
-                            v-model="entry.isConfirmed"
-                            :disable="true"
-                            size="xs"
-                        />
-                        <VnCheckbox
-                            :label="t('entry.summary.booked')"
-                            v-model="entry.isBooked"
-                            :disable="true"
-                            size="xs"
-                        />
-                        <VnCheckbox
-                            :label="t('entry.summary.excludedFromAvailable')"
-                            v-model="entry.isExcludedFromAvailable"
-                            :disable="true"
-                            size="xs"
-                        />
-                    </div>
-                </div>
-            </QCard>
-            <QCard class="vn-one" v-if="entry?.travelFk">
-                <VnTitle
-                    :url="`#/travel/${entry.travel.id}/summary`"
-                    :text="t('Travel')"
+                <VnLv :label="t('entry.summary.commission')" :value="entry.commission" />
+                <VnLv
+                    :label="t('entry.summary.currency')"
+                    :value="entry.currency?.name"
                 />
-                <div class="card-group">
-                    <div class="card-content">
-                        <VnLv :label="t('entry.summary.travelReference')">
-                            <template #value>
-                                <span class="link">
-                                    {{ entry.travel.ref }}
-                                    <TravelDescriptorProxy :id="entry.travel.id" />
-                                </span>
-                            </template>
-                        </VnLv>
-                        <VnLv
-                            :label="t('entry.summary.travelAgency')"
-                            :value="entry.travel.agency?.name"
-                        />
-                        <VnLv
-                            :label="t('entry.summary.travelShipped')"
-                            :value="toDate(entry.travel.shipped)"
-                        />
-                        <VnLv
-                            :label="t('globals.warehouseOut')"
-                            :value="entry.travel.warehouseOut?.name"
-                        />
-                        <VnLv
-                            :label="t('entry.summary.travelLanded')"
-                            :value="toDate(entry.travel.landed)"
-                        />
-                        <VnLv
-                            :label="t('globals.warehouseIn')"
-                            :value="entry.travel.warehouseIn?.name"
-                        />
-                    </div>
-                    <div class="card-content">
-                        <VnCheckbox
-                            :label="t('entry.summary.travelDelivered')"
-                            v-model="entry.travel.isDelivered"
-                            :disable="true"
-                            size="xs"
-                        />
-                        <VnCheckbox
-                            :label="t('entry.summary.travelReceived')"
-                            v-model="entry.travel.isReceived"
-                            :disable="true"
-                            size="xs"
-                        />
-                    </div>
-                </div>
+                <VnLv :label="t('globals.company')" :value="entry.company.code" />
+                <VnLv :label="t('globals.reference')" :value="entry.reference" />
+                <VnLv
+                    :label="t('entry.summary.invoiceNumber')"
+                    :value="entry.invoiceNumber"
+                />
+                <VnLv
+                    :label="t('entry.basicData.initialTemperature')"
+                    :value="toCelsius(entry.initialTemperature)"
+                />
+                <VnLv
+                    :label="t('entry.basicData.finalTemperature')"
+                    :value="toCelsius(entry.finalTemperature)"
+                />
+            </QCard>
+            <QCard class="vn-one">
+                <VnTitle
+                    :url="`#/entry/${entityId}/basic-data`"
+                    :text="t('globals.summary.basicData')"
+                />
+                <VnLv :label="t('entry.summary.travelReference')">
+                    <template #value>
+                        <span class="link">
+                            {{ entry.travel.ref }}
+                            <TravelDescriptorProxy :id="entry.travel.id" />
+                        </span>
+                    </template>
+                </VnLv>
+                <VnLv
+                    :label="t('entry.summary.travelAgency')"
+                    :value="entry.travel.agency?.name"
+                />
+                <VnLv
+                    :label="t('globals.shipped')"
+                    :value="toDate(entry.travel.shipped)"
+                />
+                <VnLv
+                    :label="t('globals.warehouseOut')"
+                    :value="entry.travel.warehouseOut?.name"
+                />
+                <VnLv
+                    :label="t('entry.summary.travelDelivered')"
+                    :value="entry.travel.isDelivered"
+                />
+                <VnLv :label="t('globals.landed')" :value="toDate(entry.travel.landed)" />
+                <VnLv
+                    :label="t('globals.warehouseIn')"
+                    :value="entry.travel.warehouseIn?.name"
+                />
+                <VnLv
+                    :label="t('entry.summary.travelReceived')"
+                    :value="entry.travel.isReceived"
+                />
+            </QCard>
+            <QCard class="vn-one">
+                <VnTitle :url="`#/travel/${entityId}/summary`" :text="t('Travel data')" />
+                <VnRow class="block">
+                    <VnLv :label="t('entry.summary.ordered')" :value="entry.isOrdered" />
+                    <VnLv :label="t('globals.confirmed')" :value="entry.isConfirmed" />
+                    <VnLv :label="t('entry.summary.booked')" :value="entry.isBooked" />
+                    <VnLv
+                        :label="t('entry.summary.excludedFromAvailable')"
+                        :value="entry.isExcludedFromAvailable"
+                    />
+                </VnRow>
             </QCard>
             <QCard class="vn-max">
                 <VnTitle
                     :url="`#/entry/${entityId}/buys`"
                     :text="t('entry.summary.buys')"
                 />
-                <EntryBuys
-                    v-if="entityId"
-                    :id="Number(entityId)"
-                    :editable-mode="false"
-                    table-height="49vh"
-                />
+                <QTable
+                    :rows="entryBuys"
+                    :columns="entriesTableColumns"
+                    row-key="index"
+                    class="full-width q-mt-md"
+                    :no-data-label="t('globals.noResults')"
+                >
+                    <template #body="{ cols, row, rowIndex }">
+                        <QTr no-hover>
+                            <QTd v-for="col in cols" :key="col?.name">
+                                <component
+                                    :is="tableColumnComponents[col?.name].component()"
+                                    v-bind="tableColumnComponents[col?.name].props()"
+                                    @click="tableColumnComponents[col?.name].event()"
+                                    class="col-content"
+                                >
+                                    <template
+                                        v-if="
+                                            col?.name !== 'observation' &&
+                                            col?.name !== 'isConfirmed'
+                                        "
+                                        >{{ col.value }}</template
+                                    >
+                                    <QTooltip v-if="col.toolTip">{{
+                                        col.toolTip
+                                    }}</QTooltip>
+                                </component>
+                            </QTd>
+                        </QTr>
+                        <QTr no-hover>
+                            <QTd>
+                                <span>{{ row.item.itemType.code }}</span>
+                            </QTd>
+                            <QTd>
+                                <span>{{ row.item.id }}</span>
+                            </QTd>
+                            <QTd>
+                                <span>{{ row.item.size }}</span>
+                            </QTd>
+                            <QTd>
+                                <span>{{ toCurrency(row.item.minPrice) }}</span>
+                            </QTd>
+                            <QTd colspan="6">
+                                <span>{{ row.item.concept }}</span>
+                                <span v-if="row.item.subName" class="subName">
+                                    {{ row.item.subName }}
+                                </span>
+                                <FetchedTags :item="row.item" />
+                            </QTd>
+                        </QTr>
+                        <!-- Esta última row es utilizada para agregar un espaciado y así marcar una diferencia visual entre los diferentes buys -->
+                        <QTr v-if="rowIndex !== entryBuys.length - 1">
+                            <QTd colspan="10" class="vn-table-separation-row" />
+                        </QTr>
+                    </template>
+                </QTable>
             </QCard>
         </template>
     </CardSummary>
 </template>
+
 <style lang="scss" scoped>
-.card-group {
-    display: flex;
-    flex-direction: column;
-}
-
-.card-content {
-    display: flex;
-    flex-direction: column;
-    text-overflow: ellipsis;
-    > div {
-        max-height: 24px;
-    }
-}
-
-@media (min-width: 1010px) {
-    .card-group {
-        flex-direction: row;
-    }
-    .card-content {
-        flex: 1;
-        margin-right: 16px;
-    }
+.separation-row {
+    background-color: var(--vn-section-color) !important;
 }
 </style>
+
 <i18n>
 es:
-    Travel: Envío
-    InvoiceIn data: Datos factura
+    Travel data: Datos envío
 </i18n>
diff --git a/src/pages/Entry/EntryFilter.vue b/src/pages/Entry/EntryFilter.vue
index 8c60918a836..0f632c0ef3b 100644
--- a/src/pages/Entry/EntryFilter.vue
+++ b/src/pages/Entry/EntryFilter.vue
@@ -19,7 +19,6 @@ const props = defineProps({
 
 const currenciesOptions = ref([]);
 const companiesOptions = ref([]);
-const entryFilterPanel = ref();
 </script>
 
 <template>
@@ -39,7 +38,7 @@ const entryFilterPanel = ref();
         @on-fetch="(data) => (currenciesOptions = data)"
         auto-load
     />
-    <VnFilterPanel ref="entryFilterPanel" :data-key="props.dataKey" :search-button="true">
+    <VnFilterPanel :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
                 <strong>{{ t(`entryFilter.params.${tag.label}`) }}: </strong>
@@ -49,65 +48,70 @@ const entryFilterPanel = ref();
         <template #body="{ params, searchFn }">
             <QItem>
                 <QItemSection>
-                    <QCheckbox
-                        :label="t('params.isExcludedFromAvailable')"
-                        v-model="params.isExcludedFromAvailable"
-                        toggle-indeterminate
-                    >
-                        <QTooltip>
-                            {{ t('params.isExcludedFromAvailable') }}
-                        </QTooltip>
-                    </QCheckbox>
-                </QItemSection>
-                <QItemSection>
-                    <QCheckbox
-                        :label="t('params.isOrdered')"
-                        v-model="params.isOrdered"
-                        toggle-indeterminate
-                    >
-                        <QTooltip>
-                            {{ t('entry.list.tableVisibleColumns.isOrdered') }}
-                        </QTooltip>
-                    </QCheckbox>
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <QCheckbox
-                        :label="t('params.isReceived')"
-                        v-model="params.isReceived"
-                        toggle-indeterminate
-                    >
-                        <QTooltip>
-                            {{ t('entry.list.tableVisibleColumns.isReceived') }}
-                        </QTooltip>
-                    </QCheckbox>
-                </QItemSection>
-                <QItemSection>
-                    <QCheckbox
-                        :label="t('entry.list.tableVisibleColumns.isConfirmed')"
-                        v-model="params.isConfirmed"
-                        toggle-indeterminate
-                    >
-                        <QTooltip>
-                            {{ t('entry.list.tableVisibleColumns.isConfirmed') }}
-                        </QTooltip>
-                    </QCheckbox>
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInputDate
-                        :label="t('params.landed')"
-                        v-model="params.landed"
-                        @update:model-value="searchFn()"
+                    <VnInput
+                        v-model="params.search"
+                        :label="t('entryFilter.params.search')"
                         is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInput v-model="params.id" label="Id" is-outlined />
+                    <VnInput
+                        v-model="params.reference"
+                        :label="t('entryFilter.params.reference')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.invoiceNumber"
+                        :label="t('entryFilter.params.invoiceNumber')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.travelFk"
+                        :label="t('entryFilter.params.travelFk')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('entryFilter.params.companyFk')"
+                        v-model="params.companyFk"
+                        @update:model-value="searchFn()"
+                        :options="companiesOptions"
+                        option-value="id"
+                        option-label="code"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('entryFilter.params.currencyFk')"
+                        v-model="params.currencyFk"
+                        @update:model-value="searchFn()"
+                        :options="currenciesOptions"
+                        option-value="id"
+                        option-label="name"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    />
                 </QItemSection>
             </QItem>
             <QItem>
@@ -121,165 +125,62 @@ const entryFilterPanel = ref();
                         rounded
                     />
                 </QItemSection>
-                <QItemSection>
-                    <VnInput
-                        v-model="params.invoiceNumber"
-                        :label="t('params.invoiceNumber')"
-                        is-outlined
-                    />
-                </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInput
-                        v-model="params.reference"
-                        :label="t('entry.list.tableVisibleColumns.reference')"
-                        is-outlined
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnSelect
-                        :label="t('params.agencyModeId')"
-                        v-model="params.agencyModeId"
+                    <VnInputDate
+                        :label="t('entryFilter.params.created')"
+                        v-model="params.created"
                         @update:model-value="searchFn()"
-                        url="AgencyModes"
-                        :fields="['id', 'name']"
-                        hide-selected
-                        dense
-                        outlined
-                        rounded
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInput
-                        v-model="params.evaNotes"
-                        :label="t('params.evaNotes')"
                         is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnSelect
-                        :label="t('params.warehouseOutFk')"
-                        v-model="params.warehouseOutFk"
+                    <VnInputDate
+                        :label="t('entryFilter.params.from')"
+                        v-model="params.from"
                         @update:model-value="searchFn()"
-                        url="Warehouses"
-                        :fields="['id', 'name']"
-                        hide-selected
-                        dense
-                        outlined
-                        rounded
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnSelect
-                        :label="t('params.warehouseInFk')"
-                        v-model="params.warehouseInFk"
-                        @update:model-value="searchFn()"
-                        url="Warehouses"
-                        :fields="['id', 'name']"
-                        hide-selected
-                        dense
-                        outlined
-                        rounded
-                    >
-                        <template #option="scope">
-                            <QItem v-bind="scope.itemProps">
-                                <QItemSection>
-                                    <QItemLabel>
-                                        {{ scope.opt?.name }}
-                                    </QItemLabel>
-                                    <QItemLabel caption>
-                                        {{ `#${scope.opt?.id} , ${scope.opt?.nickname}` }}
-                                    </QItemLabel>
-                                </QItemSection>
-                            </QItem>
-                        </template>
-                    </VnSelect>
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInput
-                        v-model="params.invoiceNumber"
-                        :label="t('params.invoiceNumber')"
                         is-outlined
                     />
                 </QItemSection>
             </QItem>
-
             <QItem>
                 <QItemSection>
-                    <VnSelect
-                        :label="t('params.entryTypeCode')"
-                        v-model="params.entryTypeCode"
+                    <VnInputDate
+                        :label="t('entryFilter.params.to')"
+                        v-model="params.to"
                         @update:model-value="searchFn()"
-                        url="EntryTypes"
-                        :fields="['code', 'description']"
-                        option-value="code"
-                        option-label="description"
-                        hide-selected
-                        dense
-                        outlined
-                        rounded
+                        is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInput
-                        v-model="params.evaNotes"
-                        :label="t('params.evaNotes')"
-                        is-outlined
+                    <QCheckbox
+                        :label="t('entryFilter.params.isBooked')"
+                        v-model="params.isBooked"
+                        toggle-indeterminate
+                    />
+                </QItemSection>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('entryFilter.params.isConfirmed')"
+                        v-model="params.isConfirmed"
+                        toggle-indeterminate
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('entryFilter.params.isOrdered')"
+                        v-model="params.isOrdered"
+                        toggle-indeterminate
                     />
                 </QItemSection>
             </QItem>
         </template>
     </VnFilterPanel>
 </template>
-
-<i18n>
-en:
-    params:
-        isExcludedFromAvailable: Inventory
-        isOrdered: Ordered
-        isReceived: Received
-        isConfirmed: Confirmed
-        isRaid: Raid
-        landed: Date
-        id: Id
-        supplierFk: Supplier
-        invoiceNumber: Invoice number
-        reference: Ref/Alb/Guide
-        agencyModeId: Agency mode
-        evaNotes: Notes
-        warehouseOutFk: Origin
-        warehouseInFk: Destiny
-        entryTypeCode: Entry type
-        hasToShowDeletedEntries: Show deleted entries
-es:
-    params:
-        isExcludedFromAvailable: Inventario
-        isOrdered: Pedida
-        isConfirmed: Confirmado
-        isReceived: Recibida
-        isRaid: Raid
-        landed: Fecha
-        id: Id
-        supplierFk: Proveedor
-        invoiceNumber: Núm. factura
-        reference: Ref/Alb/Guía
-        agencyModeId: Modo agencia
-        evaNotes: Notas
-        warehouseOutFk: Origen
-        warehouseInFk: Destino
-        entryTypeCode: Tipo de entrada
-        hasToShowDeletedEntries: Mostrar entradas eliminadas
-</i18n>
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index 3c96a230286..3172c6d0e9b 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -1,25 +1,21 @@
 <script setup>
-import axios from 'axios';
-import VnSection from 'src/components/common/VnSection.vue';
 import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useState } from 'src/composables/useState';
-import { onBeforeMount } from 'vue';
-
 import EntryFilter from './EntryFilter.vue';
 import VnTable from 'components/VnTable/VnTable.vue';
+import { toCelsius, toDate } from 'src/filters';
+import { useSummaryDialog } from 'src/composables/useSummaryDialog';
+import EntrySummary from './Card/EntrySummary.vue';
 import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
-import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
-import { toDate } from 'src/filters';
+import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
+import VnSection from 'src/components/common/VnSection.vue';
 
 const { t } = useI18n();
 const tableRef = ref();
-const defaultEntry = ref({});
-const state = useState();
-const user = state.getUser();
 const dataKey = 'EntryList';
 
-const entryQueryFilter = {
+const { viewSummary } = useSummaryDialog();
+const entryFilter = {
     include: [
         {
             relation: 'suppliers',
@@ -44,58 +40,44 @@ const entryQueryFilter = {
 
 const columns = computed(() => [
     {
-        labelAbbreviation: 'Ex',
-        label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
-        toolTip: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
-        name: 'isExcludedFromAvailable',
-        component: 'checkbox',
-        width: '35px',
+        name: 'status',
+        columnFilter: false,
     },
     {
-        labelAbbreviation: 'Pe',
-        label: t('entry.list.tableVisibleColumns.isOrdered'),
-        toolTip: t('entry.list.tableVisibleColumns.isOrdered'),
-        name: 'isOrdered',
-        component: 'checkbox',
-        width: '35px',
+        align: 'left',
+        label: t('globals.id'),
+        name: 'id',
+        isId: true,
+        chip: {
+            condition: () => true,
+        },
     },
     {
-        labelAbbreviation: 'LE',
-        label: t('entry.list.tableVisibleColumns.isConfirmed'),
-        toolTip: t('entry.list.tableVisibleColumns.isConfirmed'),
-        name: 'isConfirmed',
-        component: 'checkbox',
-        width: '35px',
+        align: 'left',
+        label: t('globals.reference'),
+        name: 'reference',
+        isTitle: true,
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+        create: true,
+        cardVisible: true,
     },
     {
-        labelAbbreviation: 'Re',
-        label: t('entry.list.tableVisibleColumns.isReceived'),
-        toolTip: t('entry.list.tableVisibleColumns.isReceived'),
-        name: 'isReceived',
-        component: 'checkbox',
-        width: '35px',
-    },
-    {
-        label: t('entry.list.tableVisibleColumns.landed'),
-        name: 'landed',
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.created'),
+        name: 'created',
+        create: true,
+        cardVisible: true,
         component: 'date',
         columnField: {
             component: null,
         },
-        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)),
-        width: '105px',
-    },
-    {
-        label: t('globals.id'),
-        name: 'id',
-        isId: true,
-        component: 'number',
-        chip: {
-            condition: () => true,
-        },
-        width: '50px',
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.created)),
     },
     {
+        align: 'left',
         label: t('entry.list.tableVisibleColumns.supplierFk'),
         name: 'supplierFk',
         create: true,
@@ -104,213 +86,165 @@ const columns = computed(() => [
         attrs: {
             url: 'suppliers',
             fields: ['id', 'name'],
-            where: { order: 'name DESC' },
+        },
+        columnField: {
+            component: null,
         },
         format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
-        width: '110px',
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.invoiceNumber'),
-        name: 'invoiceNumber',
-        component: 'input',
-    },
-    {
-        align: 'left',
-        label: t('entry.list.tableVisibleColumns.reference'),
-        name: 'reference',
-        isTitle: true,
-        component: 'input',
-        columnField: {
-            component: null,
-        },
+        label: t('entry.list.tableVisibleColumns.isBooked'),
+        name: 'isBooked',
         cardVisible: true,
+        create: true,
+        component: 'checkbox',
     },
     {
         align: 'left',
-        label: 'AWB',
-        name: 'awbCode',
-        component: 'input',
-        width: '100px',
-    },
-    {
-        align: 'left',
-        label: t('entry.list.tableVisibleColumns.agencyModeId'),
-        name: 'agencyModeId',
+        label: t('entry.list.tableVisibleColumns.isConfirmed'),
+        name: 'isConfirmed',
         cardVisible: true,
-        component: 'select',
-        attrs: {
-            url: 'agencyModes',
-            fields: ['id', 'name'],
-        },
-        columnField: {
-            component: null,
-        },
-        format: (row, dashIfEmpty) => dashIfEmpty(row.agencyModeName),
+        create: true,
+        component: 'checkbox',
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.evaNotes'),
-        name: 'evaNotes',
-        component: 'input',
-    },
-    {
-        align: 'left',
-        label: t('entry.list.tableVisibleColumns.warehouseOutFk'),
-        name: 'warehouseOutFk',
+        label: t('entry.list.tableVisibleColumns.isOrdered'),
+        name: 'isOrdered',
         cardVisible: true,
-        component: 'select',
-        attrs: {
-            url: 'warehouses',
-            fields: ['id', 'name'],
-        },
-        columnField: {
-            component: null,
-        },
-        format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseOutName),
-        width: '65px',
+        create: true,
+        component: 'checkbox',
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.warehouseInFk'),
-        name: 'warehouseInFk',
-        cardVisible: true,
-        component: 'select',
-        attrs: {
-            url: 'warehouses',
-            fields: ['id', 'name'],
-        },
-        columnField: {
-            component: null,
-        },
-        format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseInName),
-        width: '65px',
-    },
-    {
-        align: 'left',
-        labelAbbreviation: t('Type'),
-        label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
-        toolTip: t('entry.list.tableVisibleColumns.entryTypeDescription'),
-        name: 'entryTypeCode',
-        component: 'select',
-        attrs: {
-            url: 'entryTypes',
-            fields: ['code', 'description'],
-            optionValue: 'code',
-            optionLabel: 'description',
-        },
-        width: '65px',
-        format: (row, dashIfEmpty) => dashIfEmpty(row.entryTypeDescription),
-    },
-    {
-        name: 'companyFk',
         label: t('entry.list.tableVisibleColumns.companyFk'),
-        cardVisible: false,
-        visible: false,
-        create: true,
+        name: 'companyFk',
         component: 'select',
         attrs: {
-            optionValue: 'id',
+            url: 'companies',
+            fields: ['id', 'code'],
             optionLabel: 'code',
-            url: 'Companies',
+            optionValue: 'id',
+        },
+        columnField: {
+            component: null,
+        },
+        create: true,
+
+        format: (row, dashIfEmpty) => dashIfEmpty(row.companyCode),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.travelFk'),
+        name: 'travelFk',
+        component: 'select',
+        attrs: {
+            url: 'travels',
+            fields: ['id', 'ref'],
+            optionLabel: 'ref',
+            optionValue: 'id',
+        },
+        columnField: {
+            component: null,
+        },
+        create: true,
+        format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.invoiceAmount'),
+        name: 'invoiceAmount',
+        cardVisible: true,
+    },
+    {
+        align: 'left',
+        name: 'initialTemperature',
+        label: t('entry.basicData.initialTemperature'),
+        field: 'initialTemperature',
+        format: (row) => toCelsius(row.initialTemperature),
+    },
+    {
+        align: 'left',
+        name: 'finalTemperature',
+        label: t('entry.basicData.finalTemperature'),
+        field: 'finalTemperature',
+        format: (row) => toCelsius(row.finalTemperature),
+    },
+    {
+        label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
+        name: 'isExcludedFromAvailable',
+        columnFilter: {
+            inWhere: true,
         },
     },
     {
-        name: 'travelFk',
-        label: t('entry.list.tableVisibleColumns.travelFk'),
-        cardVisible: false,
-        visible: false,
-        create: true,
+        align: 'right',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('components.smartCard.viewSummary'),
+                icon: 'preview',
+                action: (row) => viewSummary(row.id, EntrySummary),
+                isPrimary: true,
+            },
+        ],
     },
 ]);
-function getBadgeAttrs(row) {
-    const date = row.landed;
-    let today = Date.vnNew();
-    today.setHours(0, 0, 0, 0);
-    let timeTicket = new Date(date);
-    timeTicket.setHours(0, 0, 0, 0);
-
-    let timeDiff = today - timeTicket;
-
-    if (timeDiff > 0) return { color: 'info', 'text-color': 'black' };
-    if (timeDiff < 0) return { color: 'warning', 'text-color': 'black' };
-    switch (row.entryTypeCode) {
-        case 'regularization':
-        case 'life':
-        case 'internal':
-        case 'inventory':
-            if (!row.isOrdered || !row.isConfirmed)
-                return { color: 'negative', 'text-color': 'black' };
-            break;
-        case 'product':
-        case 'packaging':
-        case 'devaluation':
-        case 'payment':
-        case 'transport':
-            if (
-                row.invoiceAmount === null ||
-                (row.invoiceNumber === null && row.reference === null) ||
-                !row.isOrdered ||
-                !row.isConfirmed
-            )
-                return { color: 'negative', 'text-color': 'black' };
-            break;
-        default:
-            break;
-    }
-    return { color: 'transparent' };
-}
-
-onBeforeMount(async () => {
-    defaultEntry.value = (await axios.get('EntryConfigs/findOne')).data;
-});
 </script>
 
 <template>
     <VnSection
         :data-key="dataKey"
+        :columns="columns"
         prefix="entry"
         url="Entries/filter"
         :array-data-props="{
             url: 'Entries/filter',
-            order: 'landed DESC',
-            userFilter: EntryFilter,
+            order: 'id DESC',
+            userFilter: entryFilter,
         }"
     >
         <template #advanced-menu>
-            <EntryFilter :data-key="dataKey" />
+            <EntryFilter data-key="EntryList" />
         </template>
         <template #body>
             <VnTable
-                v-if="defaultEntry.defaultSupplierFk"
                 ref="tableRef"
                 :data-key="dataKey"
-                url="Entries/filter"
-                :filter="entryQueryFilter"
-                order="landed DESC"
                 :create="{
                     urlCreate: 'Entries',
-                    title: t('Create entry'),
+                    title: t('entry.list.newEntry'),
                     onDataSaved: ({ id }) => tableRef.redirect(id),
-                    formInitialData: {
-                        supplierFk: defaultEntry.defaultSupplierFk,
-                        dated: Date.vnNew(),
-                        companyFk: user?.companyFk,
-                    },
+                    formInitialData: {},
                 }"
                 :columns="columns"
                 redirect="entry"
                 :right-search="false"
             >
-                <template #column-landed="{ row }">
-                    <QBadge
-                        v-if="row?.travelFk"
-                        v-bind="getBadgeAttrs(row)"
-                        class="q-pa-sm"
-                        style="font-size: 14px"
-                    >
-                        {{ toDate(row.landed) }}
-                    </QBadge>
+                <template #column-status="{ row }">
+                    <div class="row q-gutter-xs">
+                        <QIcon
+                            v-if="!!row.isExcludedFromAvailable"
+                            name="vn:inventory"
+                            color="primary"
+                        >
+                            <QTooltip>{{
+                                t(
+                                    'entry.list.tableVisibleColumns.isExcludedFromAvailable',
+                                )
+                            }}</QTooltip>
+                        </QIcon>
+                        <QIcon v-if="!!row.isRaid" name="vn:net" color="primary">
+                            <QTooltip>
+                                {{
+                                    t('globals.raid', {
+                                        daysInForward: row.daysInForward,
+                                    })
+                                }}</QTooltip
+                            >
+                        </QIcon>
+                    </div>
                 </template>
                 <template #column-supplierFk="{ row }">
                     <span class="link" @click.stop>
@@ -318,27 +252,13 @@ onBeforeMount(async () => {
                         <SupplierDescriptorProxy :id="row.supplierFk" />
                     </span>
                 </template>
-                <template #column-create-travelFk="{ data }">
-                    <VnSelectTravelExtended
-                        :data="data"
-                        v-model="data.travelFk"
-                        :onFilterTravelSelected="
-                            (data, result) => (data.travelFk = result)
-                        "
-                        data-cy="entry-travel-select"
-                    />
+                <template #column-travelFk="{ row }">
+                    <span class="link" @click.stop>
+                        {{ row.travelRef }}
+                        <TravelDescriptorProxy :id="row.travelFk" />
+                    </span>
                 </template>
             </VnTable>
         </template>
     </VnSection>
 </template>
-
-<i18n>
-es:
-    Inventory entry: Es inventario
-    Virtual entry: Es una redada
-    Search entries: Buscar entradas
-    You can search by entry reference: Puedes buscar por referencia de la entrada
-    Create entry: Crear entrada
-    Type: Tipo
-</i18n>
diff --git a/src/pages/Entry/EntryStockBought.vue b/src/pages/Entry/EntryStockBought.vue
index 4bd0fe6408d..fa0bdc12e2f 100644
--- a/src/pages/Entry/EntryStockBought.vue
+++ b/src/pages/Entry/EntryStockBought.vue
@@ -34,20 +34,18 @@ const columns = computed(() => [
         label: t('entryStockBought.buyer'),
         isTitle: true,
         component: 'select',
-        isEditable: false,
         cardVisible: true,
         create: true,
         attrs: {
             url: 'Workers/activeWithInheritedRole',
-            fields: ['id', 'name', 'nickname'],
+            fields: ['id', 'name'],
             where: { role: 'buyer' },
             optionFilter: 'firstName',
-            optionLabel: 'nickname',
+            optionLabel: 'name',
             optionValue: 'id',
             useLike: false,
         },
         columnFilter: false,
-        width: '70px',
     },
     {
         align: 'center',
@@ -57,7 +55,6 @@ const columns = computed(() => [
         create: true,
         component: 'number',
         summation: true,
-        width: '50px',
     },
     {
         align: 'center',
@@ -81,7 +78,6 @@ const columns = computed(() => [
         actions: [
             {
                 title: t('entryStockBought.viewMoreDetails'),
-                name: 'searchBtn',
                 icon: 'search',
                 isPrimary: true,
                 action: (row) => {
@@ -95,7 +91,6 @@ const columns = computed(() => [
                 },
             },
         ],
-        'data-cy': 'table-actions',
     },
 ]);
 
@@ -163,7 +158,7 @@ function round(value) {
                 @on-fetch="
                     (data) => {
                         travel = data.find(
-                            (data) => data.warehouseIn?.code.toLowerCase() === 'vnh',
+                            (data) => data.warehouseIn?.code.toLowerCase() === 'vnh'
                         );
                     }
                 "
@@ -184,7 +179,6 @@ function round(value) {
                         @click="openDialog()"
                         :title="t('entryStockBought.editTravel')"
                         color="primary"
-                        data-cy="edit-travel"
                     />
                 </div>
             </VnRow>
@@ -245,11 +239,10 @@ function round(value) {
                 table-height="80vh"
                 auto-load
                 :column-search="false"
-                :without-header="true"
             >
                 <template #column-workerFk="{ row }">
                     <span class="link" @click.stop>
-                        {{ row?.worker?.user?.nickname }}
+                        {{ row?.worker?.user?.name }}
                         <WorkerDescriptorProxy :id="row?.workerFk" />
                     </span>
                 </template>
@@ -286,11 +279,10 @@ function round(value) {
     justify-content: center;
 }
 .column {
-    min-width: 40%;
-    margin-top: 5%;
     display: flex;
     flex-direction: column;
     align-items: center;
+    min-width: 35%;
 }
 .text-negative {
     color: $negative !important;
diff --git a/src/pages/Entry/EntryStockBoughtDetail.vue b/src/pages/Entry/EntryStockBoughtDetail.vue
index 1a37994d908..81217182575 100644
--- a/src/pages/Entry/EntryStockBoughtDetail.vue
+++ b/src/pages/Entry/EntryStockBoughtDetail.vue
@@ -21,7 +21,7 @@ const $props = defineProps({
 const customUrl = `StockBoughts/getStockBoughtDetail?workerFk=${$props.workerFk}&dated=${$props.dated}`;
 const columns = [
     {
-        align: 'right',
+        align: 'left',
         label: t('Entry'),
         name: 'entryFk',
         isTitle: true,
@@ -29,7 +29,7 @@ const columns = [
         columnFilter: false,
     },
     {
-        align: 'right',
+        align: 'left',
         name: 'itemFk',
         label: t('Item'),
         columnFilter: false,
@@ -44,21 +44,21 @@ const columns = [
         cardVisible: true,
     },
     {
-        align: 'right',
+        align: 'left',
         name: 'volume',
         label: t('Volume'),
         columnFilter: false,
         cardVisible: true,
     },
     {
-        align: 'right',
+        align: 'left',
         label: t('Packaging'),
         name: 'packagingFk',
         columnFilter: false,
         cardVisible: true,
     },
     {
-        align: 'right',
+        align: 'left',
         label: 'Packing',
         name: 'packing',
         columnFilter: false,
@@ -73,14 +73,12 @@ const columns = [
                 ref="tableRef"
                 data-key="StockBoughtsDetail"
                 :url="customUrl"
-                order="volume DESC"
+                order="itemName DESC"
                 :columns="columns"
                 :right-search="false"
                 :disable-infinite-scroll="true"
                 :disable-option="{ card: true }"
                 :limit="0"
-                :without-header="true"
-                :with-filters="false"
                 auto-load
             >
                 <template #column-entryFk="{ row }">
@@ -101,14 +99,16 @@ const columns = [
 </template>
 <style lang="css" scoped>
 .container {
-    max-width: 100%;
-    width: 50%;
+    max-width: 50vw;
     overflow: auto;
     justify-content: center;
     align-items: center;
     margin: auto;
     background-color: var(--vn-section-color);
-    padding: 2%;
+    padding: 4px;
+}
+.container > div > div > .q-table__top.relative-position.row.items-center {
+    background-color: red !important;
 }
 </style>
 <i18n>
diff --git a/src/pages/Entry/locale/en.yml b/src/pages/Entry/locale/en.yml
index 88b16cb03ba..80f3491a837 100644
--- a/src/pages/Entry/locale/en.yml
+++ b/src/pages/Entry/locale/en.yml
@@ -1,36 +1,21 @@
 entry:
-    lock:
-        title: Lock entry
-        message: This entry has been locked by {userName} for {time} minutes. Do you want to unlock it?
-        success: The entry has been locked successfully
     list:
         newEntry: New entry
         tableVisibleColumns:
-            isExcludedFromAvailable: Exclude from inventory
-            isOrdered: Ordered
-            isConfirmed: Ready to label
-            isReceived: Received
-            isRaid: Raid
-            landed: Date
+            created: Creation
             supplierFk: Supplier
-            reference: Ref/Alb/Guide
-            invoiceNumber: Invoice
-            agencyModeId: Agency
             isBooked: Booked
+            isConfirmed: Confirmed
+            isOrdered: Ordered
             companyFk: Company
-            evaNotes: Notes
-            warehouseOutFk: Origin
-            warehouseInFk: Destiny
-            entryTypeDescription: Entry type
-            invoiceAmount: Import
             travelFk: Travel
-            dated: Dated
+            isExcludedFromAvailable: Inventory
+            invoiceAmount: Import
         inventoryEntry: Inventory entry
     summary:
         commission: Commission
         currency: Currency
         invoiceNumber: Invoice number
-        invoiceAmount: Invoice amount
         ordered: Ordered
         booked: Booked
         excludedFromAvailable: Inventory
@@ -48,7 +33,6 @@ entry:
         buyingValue: Buying value
         import: Import
         pvp: PVP
-        entryType: Entry type
     basicData:
         travel: Travel
         currency: Currency
@@ -85,55 +69,17 @@ entry:
             landing: Landing
             isExcludedFromAvailable: Es inventory
     params:
-        isExcludedFromAvailable: Exclude from inventory
-        isOrdered: Ordered
-        isConfirmed: Ready to label
-        isReceived: Received
-        isIgnored: Ignored
-        isRaid: Raid
-        landed: Date
-        supplierFk: Supplier
-        reference: Ref/Alb/Guide
-        invoiceNumber: Invoice
-        agencyModeId: Agency
-        isBooked: Booked
-        companyFk: Company
-        evaNotes: Notes
-        warehouseOutFk: Origin
-        warehouseInFk: Destiny
-        entryTypeDescription: Entry type
-        invoiceAmount: Import
-        travelFk: Travel
-        dated: Dated
-        itemFk: Item id
-        hex: Color
-        name: Item name
-        size: Size
-        stickers: Stickers
-        packagingFk: Packaging
-        weight: Kg
-        groupingMode: Grouping selector
-        grouping: Grouping
-        quantity: Quantity
-        buyingValue: Buying value
-        price2: Package
-        price3: Box
-        minPrice: Minumum price
-        hasMinPrice: Has minimum price
-        packingOut: Packing out
-        comment: Comment
-        subName: Supplier name
-        tags: Tags
-        company_name: Company name
-        itemTypeFk: Item type
-        workerFk: Worker id
+        toShipped: To
+        fromShipped: From
+        daysOnward: Days onward
+        daysAgo: Days ago
+        warehouseInFk: Warehouse in
     search: Search entries
     searchInfo: You can search by entry reference
     descriptorMenu:
         showEntryReport: Show entry report
 entryFilter:
     params:
-        isExcludedFromAvailable: Exclude from inventory
         invoiceNumber: Invoice number
         travelFk: Travel
         companyFk: Company
@@ -145,16 +91,8 @@ entryFilter:
         isBooked: Booked
         isConfirmed: Confirmed
         isOrdered: Ordered
-        isReceived: Received
         search: General search
         reference: Reference
-        landed: Landed
-        id: Id
-        agencyModeId: Agency
-        evaNotes: Notes
-        warehouseOutFk: Origin
-        warehouseInFk: Destiny
-        entryTypeCode: Entry type
 myEntries:
     id: ID
     landed: Landed
diff --git a/src/pages/Entry/locale/es.yml b/src/pages/Entry/locale/es.yml
index 3025d64cbc3..a5b968016f9 100644
--- a/src/pages/Entry/locale/es.yml
+++ b/src/pages/Entry/locale/es.yml
@@ -1,36 +1,21 @@
 entry:
-    lock:
-        title: Entrada bloqueada
-        message: Esta entrada ha sido bloqueada por {userName} hace {time} minutos. ¿Quieres desbloquearla?
-        success: La entrada ha sido bloqueada correctamente
     list:
         newEntry: Nueva entrada
         tableVisibleColumns:
-            isExcludedFromAvailable: Excluir del inventario
-            isOrdered: Pedida
-            isConfirmed: Lista para etiquetar
-            isReceived: Recibida
-            isRaid: Redada
-            landed: Fecha
+            created: Creación
             supplierFk: Proveedor
-            invoiceNumber: Nº Factura
-            reference: Ref/Alb/Guía
-            agencyModeId: Agencia
             isBooked: Asentado
+            isConfirmed: Confirmado
+            isOrdered: Pedida
             companyFk: Empresa
             travelFk: Envio
-            evaNotes: Notas
-            warehouseOutFk: Origen
-            warehouseInFk: Destino
-            entryTypeDescription: Tipo entrada
+            isExcludedFromAvailable: Inventario
             invoiceAmount: Importe
-            dated: Fecha
         inventoryEntry: Es inventario
     summary:
         commission: Comisión
         currency: Moneda
         invoiceNumber: Núm. factura
-        invoiceAmount: Importe
         ordered: Pedida
         booked: Contabilizada
         excludedFromAvailable: Inventario
@@ -49,13 +34,12 @@ entry:
         buyingValue: Coste
         import: Importe
         pvp: PVP
-        entryType: Tipo entrada
     basicData:
         travel: Envío
         currency: Moneda
         observation: Observación
         commission: Comisión
-        booked: Contabilizada
+        booked: Asentado
         excludedFromAvailable: Inventario
         initialTemperature: Ini °C
         finalTemperature: Fin °C
@@ -85,70 +69,31 @@ entry:
             packingOut: Embalaje envíos
             landing: Llegada
             isExcludedFromAvailable: Es inventario
-
+    params:
+        toShipped: Hasta
+        fromShipped: Desde
+        warehouseInFk: Alm. entrada
+        daysOnward: Días adelante
+        daysAgo: Días atras
+    descriptorMenu:
+        showEntryReport: Ver informe del pedido
     search: Buscar entradas
     searchInfo: Puedes buscar por referencia de entrada
-    params:
-        isExcludedFromAvailable: Excluir del inventario
-        isOrdered: Pedida
-        isConfirmed: Lista para etiquetar
-        isReceived: Recibida
-        isRaid: Redada
-        isIgnored: Ignorado
-        landed: Fecha
-        supplierFk: Proveedor
-        invoiceNumber: Nº Factura
-        reference: Ref/Alb/Guía
-        agencyModeId: Agencia
-        isBooked: Asentado
-        companyFk: Empresa
-        travelFk: Envio
-        evaNotes: Notas
-        warehouseOutFk: Origen
-        warehouseInFk: Destino
-        entryTypeDescription: Tipo entrada
-        invoiceAmount: Importe
-        dated: Fecha
-        itemFk: Id artículo
-        hex: Color
-        name: Nombre artículo
-        size: Medida
-        stickers: Etiquetas
-        packagingFk: Embalaje
-        weight: Kg
-        groupinMode: Selector de grouping
-        grouping: Grouping
-        quantity: Quantity
-        buyingValue: Precio de compra
-        price2: Paquete
-        price3: Caja
-        minPrice: Precio mínimo
-        hasMinPrice: Tiene precio mínimo
-        packingOut: Packing out
-        comment: Referencia
-        subName: Nombre proveedor
-        tags: Etiquetas
-        company_name: Nombre empresa
-        itemTypeFk: Familia
-        workerFk: Comprador
 entryFilter:
     params:
-        isExcludedFromAvailable: Inventario
-        isOrdered: Pedida
-        isConfirmed: Confirmado
-        isReceived: Recibida
-        isRaid: Raid
-        landed: Fecha
-        id: Id
-        supplierFk: Proveedor
         invoiceNumber: Núm. factura
-        reference: Ref/Alb/Guía
-        agencyModeId: Modo agencia
-        evaNotes: Notas
-        warehouseOutFk: Origen
-        warehouseInFk: Destino
-        entryTypeCode: Tipo de entrada
-        hasToShowDeletedEntries: Mostrar entradas eliminadas
+        travelFk: Envío
+        companyFk: Empresa
+        currencyFk: Moneda
+        supplierFk: Proveedor
+        from: Desde
+        to: Hasta
+        created: Fecha creación
+        isBooked: Asentado
+        isConfirmed: Confirmado
+        isOrdered: Pedida
+        search: Búsqueda general
+        reference: Referencia
 myEntries:
     id: ID
     landed: F. llegada
diff --git a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
index 905ddebb2b0..c01ec4ab4a2 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
@@ -125,7 +125,7 @@ function deleteFile(dmsFk) {
                 <VnInput
                     clearable
                     clear-icon="close"
-                    :label="t('invoiceIn.supplierRef')"
+                    :label="t('Supplier ref')"
                     v-model="data.supplierRef"
                 />
             </VnRow>
@@ -149,7 +149,6 @@ function deleteFile(dmsFk) {
                     option-value="id"
                     option-label="id"
                     :filter-options="['id', 'name']"
-                    data-cy="UnDeductibleVatSelect"
                 >
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
@@ -216,7 +215,7 @@ function deleteFile(dmsFk) {
                         v-else
                         icon="add_circle"
                         round
-                        v-shortcut="'+'"
+                        shortcut="+"
                         padding="xs"
                         @click="
                             () => {
@@ -311,6 +310,7 @@ function deleteFile(dmsFk) {
         supplierFk: Supplier
     es:
         supplierFk: Proveedor
+        Supplier ref: Ref. proveedor
         Expedition date: Fecha expedición
         Operation date: Fecha operación
         Undeductible VAT: Iva no deducible
diff --git a/src/pages/InvoiceIn/Card/InvoiceInCard.vue b/src/pages/InvoiceIn/Card/InvoiceInCard.vue
index 34cc26437a5..8aa35f4d86b 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInCard.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInCard.vue
@@ -1,18 +1,47 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import InvoiceInDescriptor from './InvoiceInDescriptor.vue';
-import { onBeforeRouteUpdate } from 'vue-router';
-import { setRectificative } from '../composables/setRectificative';
-import filter from './InvoiceInFilter.js';
 
-onBeforeRouteUpdate(async (to) => await setRectificative(to));
+const filter = {
+    include: [
+        {
+            relation: 'supplier',
+            scope: {
+                include: {
+                    relation: 'contacts',
+                    scope: { where: { email: { neq: null } } },
+                },
+            },
+        },
+        { relation: 'invoiceInDueDay' },
+        { relation: 'company' },
+        { relation: 'currency' },
+        {
+            relation: 'dms',
+            scope: {
+                fields: [
+                    'dmsTypeFk',
+                    'reference',
+                    'hardCopyNumber',
+                    'workerFk',
+                    'description',
+                    'hasFile',
+                    'file',
+                    'created',
+                    'companyFk',
+                    'warehouseFk',
+                ],
+            },
+        },
+    ],
+};
 </script>
 
 <template>
     <VnCardBeta
         data-key="InvoiceIn"
-        url="InvoiceIns"
+        base-url="InvoiceIns"
         :descriptor="InvoiceInDescriptor"
-        :filter="filter"
+        :user-filter="filter"
     />
 </template>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index 3843f5bf713..da7bd4426b5 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -7,7 +7,6 @@ import { toCurrency, toDate } from 'src/filters';
 import VnLv from 'src/components/ui/VnLv.vue';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
-import filter from './InvoiceInFilter.js';
 import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue';
 
 const $props = defineProps({ id: { type: Number, default: null } });
@@ -17,10 +16,33 @@ const { t } = useI18n();
 const cardDescriptorRef = ref();
 const entityId = computed(() => $props.id || +currentRoute.value.params.id);
 const totalAmount = ref();
-const config = ref();
-const cplusRectificationTypes = ref([]);
-const siiTypeInvoiceIns = ref([]);
-const invoiceCorrectionTypes = ref([]);
+
+const filter = {
+    include: [
+        {
+            relation: 'supplier',
+            scope: {
+                include: {
+                    relation: 'contacts',
+                    scope: {
+                        where: {
+                            email: { neq: null },
+                        },
+                    },
+                },
+            },
+        },
+        {
+            relation: 'invoiceInDueDay',
+        },
+        {
+            relation: 'company',
+        },
+        {
+            relation: 'currency',
+        },
+    ],
+};
 const invoiceInCorrection = reactive({ correcting: [], corrected: null });
 const routes = reactive({
     getSupplier: (id) => {
@@ -90,6 +112,7 @@ async function setInvoiceCorrection(id) {
 <template>
     <CardDescriptor
         ref="cardDescriptorRef"
+        module="InvoiceIn"
         data-key="InvoiceIn"
         :url="`InvoiceIns/${entityId}`"
         :filter="filter"
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
index 8b039ec2726..c3ab635c849 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
@@ -186,7 +186,7 @@ const createInvoiceInCorrection = async () => {
                 clickable
                 @click="book(entityId)"
             >
-                <QItemSection>{{ t('invoiceIn.descriptorMenu.book') }}</QItemSection>
+                <QItemSection>{{ t('invoiceIn.descriptorMenu.toBook') }}</QItemSection>
             </QItem>
         </template>
     </InvoiceInToBook>
@@ -197,7 +197,7 @@ const createInvoiceInCorrection = async () => {
         @click="triggerMenu('unbook')"
     >
         <QItemSection>
-            {{ t('invoiceIn.descriptorMenu.unbook') }}
+            {{ t('invoiceIn.descriptorMenu.toUnbook') }}
         </QItemSection>
     </QItem>
     <QItem
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
index 20cc1cc719b..23387ff7425 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, onBeforeMount } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import axios from 'axios';
@@ -11,7 +11,6 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import useNotify from 'src/composables/useNotify.js';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
-import { toCurrency } from 'filters/index';
 
 const route = useRoute();
 const { notify } = useNotify();
@@ -25,7 +24,7 @@ const invoiceInFormRef = ref();
 const invoiceId = +route.params.id;
 const filter = { where: { invoiceInFk: invoiceId } };
 const areRows = ref(false);
-const totals = ref();
+
 const columns = computed(() => [
     {
         name: 'duedate',
@@ -64,8 +63,6 @@ const columns = computed(() => [
     },
 ]);
 
-const totalAmount = computed(() => getTotal(invoiceInFormRef.value.formData, 'amount'));
-
 const isNotEuro = (code) => code != 'EUR';
 
 async function insert() {
@@ -73,10 +70,6 @@ async function insert() {
     await invoiceInFormRef.value.reload();
     notify(t('globals.dataSaved'), 'positive');
 }
-
-onBeforeMount(async () => {
-    totals.value = (await axios.get(`InvoiceIns/${invoiceId}/getTotals`)).data;
-});
 </script>
 <template>
     <CrudModel
@@ -151,7 +144,7 @@ onBeforeMount(async () => {
                         <QTd />
                         <QTd />
                         <QTd>
-                            {{ toCurrency(totalAmount) }}
+                            {{ getTotal(rows, 'amount', { currency: 'default' }) }}
                         </QTd>
                         <QTd>
                             <template v-if="isNotEuro(invoiceIn.currency.code)">
@@ -229,19 +222,10 @@ onBeforeMount(async () => {
         <QBtn
             color="primary"
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
             size="lg"
             round
-            @click="
-                () => {
-                    if (!areRows) insert();
-                    else
-                        invoiceInFormRef.insert({
-                            amount: (totals.totalTaxableBase - totalAmount).toFixed(2),
-                            invoiceInFk: invoiceId,
-                        });
-                }
-            "
+            @click="!areRows ? insert() : invoiceInFormRef.insert()"
         />
     </QPageSticky>
 </template>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInFilter.js b/src/pages/InvoiceIn/Card/InvoiceInFilter.js
deleted file mode 100644
index 6df8b583045..00000000000
--- a/src/pages/InvoiceIn/Card/InvoiceInFilter.js
+++ /dev/null
@@ -1,33 +0,0 @@
-export default {
-    include: [
-        {
-            relation: 'supplier',
-            scope: {
-                include: {
-                    relation: 'contacts',
-                    scope: { where: { email: { neq: null } } },
-                },
-            },
-        },
-        { relation: 'invoiceInDueDay' },
-        { relation: 'company' },
-        { relation: 'currency' },
-        {
-            relation: 'dms',
-            scope: {
-                fields: [
-                    'dmsTypeFk',
-                    'reference',
-                    'hardCopyNumber',
-                    'workerFk',
-                    'description',
-                    'hasFile',
-                    'file',
-                    'created',
-                    'companyFk',
-                    'warehouseFk',
-                ],
-            },
-        },
-    ],
-};
diff --git a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
index 6f8642313ae..e529ea6cd06 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
@@ -218,7 +218,7 @@ const columns = computed(() => [
         <QBtn
             color="primary"
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
             size="lg"
             round
             @click="invoiceInFormRef.insert()"
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index d358601d316..e546638f2de 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -193,7 +193,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
             <InvoiceIntoBook>
                 <template #content="{ book }">
                     <QBtn
-                        :label="t('Book')"
+                        :label="t('To book')"
                         color="orange-11"
                         text-color="black"
                         @click="book(entityId)"
@@ -224,7 +224,10 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                         </span>
                     </template>
                 </VnLv>
-                <VnLv :label="t('invoiceIn.supplierRef')" :value="entity.supplierRef" />
+                <VnLv
+                    :label="t('invoiceIn.list.supplierRef')"
+                    :value="entity.supplierRef"
+                />
                 <VnLv
                     :label="t('invoiceIn.summary.currency')"
                     :value="entity.currency?.code"
@@ -354,7 +357,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                                 entity.totals.totalTaxableBaseForeignValue &&
                                 toCurrency(
                                     entity.totals.totalTaxableBaseForeignValue,
-                                    currency,
+                                    currency
                                 )
                             }}</QTd>
                         </QTr>
@@ -389,7 +392,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                                     entity.totals.totalDueDayForeignValue &&
                                     toCurrency(
                                         entity.totals.totalDueDayForeignValue,
-                                        currency,
+                                        currency
                                     )
                                 }}
                             </QTd>
@@ -469,5 +472,5 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
         Search invoice: Buscar factura recibida
         You can search by invoice reference: Puedes buscar por referencia de la factura
         Totals: Totales
-        Book: Contabilizar
+        To book: Contabilizar
 </i18n>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
index e77453bc084..f99e060b8f1 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, nextTick } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { useArrayData } from 'src/composables/useArrayData';
@@ -25,6 +25,7 @@ const sageTaxTypes = ref([]);
 const sageTransactionTypes = ref([]);
 const rowsSelected = ref([]);
 const invoiceInFormRef = ref();
+const expenseRef = ref();
 
 defineProps({
     actionIcon: {
@@ -96,20 +97,6 @@ const columns = computed(() => [
     },
 ]);
 
-const taxableBaseTotal = computed(() => {
-    return getTotal(invoiceInFormRef.value.formData, 'taxableBase');
-});
-
-const taxRateTotal = computed(() => {
-    return getTotal(invoiceInFormRef.value.formData, null, {
-        cb: taxRate,
-    });
-});
-
-const combinedTotal = computed(() => {
-    return +taxableBaseTotal.value + +taxRateTotal.value;
-});
-
 const filter = {
     fields: [
         'id',
@@ -130,7 +117,7 @@ const isNotEuro = (code) => code != 'EUR';
 function taxRate(invoiceInTax) {
     const sageTaxTypeId = invoiceInTax.taxTypeSageFk;
     const taxRateSelection = sageTaxTypes.value.find(
-        (transaction) => transaction.id == sageTaxTypeId,
+        (transaction) => transaction.id == sageTaxTypeId
     );
     const taxTypeSage = taxRateSelection?.rate ?? 0;
     const taxableBase = invoiceInTax?.taxableBase ?? 0;
@@ -138,26 +125,35 @@ function taxRate(invoiceInTax) {
     return ((taxTypeSage / 100) * taxableBase).toFixed(2);
 }
 
-function autocompleteExpense(evt, row, col, ref) {
+function autocompleteExpense(evt, row, col) {
     const val = evt.target.value;
     if (!val) return;
 
     const param = isNaN(val) ? row[col.model] : val;
     const lookup = expenses.value.find(
-        ({ id }) => id == useAccountShortToStandard(param),
+        ({ id }) => id == useAccountShortToStandard(param)
     );
 
-    ref.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
+    expenseRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
 }
 
-function setCursor(ref) {
-    nextTick(() => {
-        const select = ref.vnSelectDialogRef
-            ? ref.vnSelectDialogRef.vnSelectRef
-            : ref.vnSelectRef;
-        select.$el.querySelector('input').setSelectionRange(0, 0);
+const taxableBaseTotal = computed(() => {   
+    return getTotal(invoiceInFormRef.value.formData, 'taxableBase', );
+});
+
+const taxRateTotal = computed(() => {
+    return getTotal(invoiceInFormRef.value.formData, null, {
+        cb: taxRate,
     });
-}
+});
+
+
+const combinedTotal = computed(() => {
+    return +taxableBaseTotal.value + +taxRateTotal.value;
+});
+
+
+
 </script>
 <template>
     <FetchData
@@ -195,24 +191,14 @@ function setCursor(ref) {
                 <template #body-cell-expense="{ row, col }">
                     <QTd>
                         <VnSelectDialog
-                            :ref="`expenseRef-${row.$index}`"
+                            ref="expenseRef"
                             v-model="row[col.model]"
                             :options="col.options"
                             :option-value="col.optionValue"
                             :option-label="col.optionLabel"
                             :filter-options="['id', 'name']"
                             :tooltip="t('Create a new expense')"
-                            @keydown.tab="
-                                autocompleteExpense(
-                                    $event,
-                                    row,
-                                    col,
-                                    $refs[`expenseRef-${row.$index}`],
-                                )
-                            "
-                            @update:model-value="
-                                setCursor($refs[`expenseRef-${row.$index}`])
-                            "
+                            @keydown.tab="autocompleteExpense($event, row, col)"
                         >
                             <template #option="scope">
                                 <QItem v-bind="scope.itemProps">
@@ -228,7 +214,7 @@ function setCursor(ref) {
                     </QTd>
                 </template>
                 <template #body-cell-taxablebase="{ row }">
-                    <QTd shrink>
+                    <QTd>
                         <VnInputNumber
                             clear-icon="close"
                             v-model="row.taxableBase"
@@ -239,16 +225,12 @@ function setCursor(ref) {
                 <template #body-cell-sageiva="{ row, col }">
                     <QTd>
                         <VnSelect
-                            :ref="`sageivaRef-${row.$index}`"
                             v-model="row[col.model]"
                             :options="col.options"
                             :option-value="col.optionValue"
                             :option-label="col.optionLabel"
                             :filter-options="['id', 'vat']"
                             data-cy="vat-sageiva"
-                            @update:model-value="
-                                setCursor($refs[`sageivaRef-${row.$index}`])
-                            "
                         >
                             <template #option="scope">
                                 <QItem v-bind="scope.itemProps">
@@ -266,15 +248,11 @@ function setCursor(ref) {
                 <template #body-cell-sagetransaction="{ row, col }">
                     <QTd>
                         <VnSelect
-                            :ref="`sagetransactionRef-${row.$index}`"
                             v-model="row[col.model]"
                             :options="col.options"
                             :option-value="col.optionValue"
                             :option-label="col.optionLabel"
                             :filter-options="['id', 'transaction']"
-                            @update:model-value="
-                                setCursor($refs[`sagetransactionRef-${row.$index}`])
-                            "
                         >
                             <template #option="scope">
                                 <QItem v-bind="scope.itemProps">
@@ -292,7 +270,7 @@ function setCursor(ref) {
                     </QTd>
                 </template>
                 <template #body-cell-foreignvalue="{ row }">
-                    <QTd shrink>
+                    <QTd>
                         <VnInputNumber
                             :class="{
                                 'no-pointer-events': !isNotEuro(currency),
@@ -305,7 +283,7 @@ function setCursor(ref) {
                                     row.taxableBase = await getExchange(
                                         val,
                                         row.currencyFk,
-                                        invoiceIn.issued,
+                                        invoiceIn.issued
                                     );
                                 }
                             "
@@ -448,7 +426,7 @@ function setCursor(ref) {
             color="primary"
             icon="add"
             size="lg"
-            v-shortcut="'+'"
+            shortcut="+"
             round
             @click="invoiceInFormRef.insert()"
         >
diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue
index 0960d0d6cef..e1723e3b17a 100644
--- a/src/pages/InvoiceIn/InvoiceInList.vue
+++ b/src/pages/InvoiceIn/InvoiceInList.vue
@@ -29,7 +29,6 @@ const cols = computed(() => [
         name: 'isBooked',
         label: t('invoiceIn.isBooked'),
         columnFilter: false,
-        component: 'checkbox',
     },
     {
         align: 'left',
@@ -57,7 +56,7 @@ const cols = computed(() => [
     {
         align: 'left',
         name: 'supplierRef',
-        label: t('invoiceIn.supplierRef'),
+        label: t('invoiceIn.list.supplierRef'),
     },
     {
         align: 'left',
@@ -178,7 +177,7 @@ const cols = computed(() => [
                         :required="true"
                     />
                     <VnInput
-                        :label="t('invoiceIn.supplierRef')"
+                        :label="t('invoiceIn.list.supplierRef')"
                         v-model="data.supplierRef"
                     />
                     <VnSelect
diff --git a/src/pages/InvoiceIn/InvoiceInToBook.vue b/src/pages/InvoiceIn/InvoiceInToBook.vue
index 5bdbe197b99..95ce8155a26 100644
--- a/src/pages/InvoiceIn/InvoiceInToBook.vue
+++ b/src/pages/InvoiceIn/InvoiceInToBook.vue
@@ -4,7 +4,6 @@ import { useQuasar } from 'quasar';
 import { useI18n } from 'vue-i18n';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import { useArrayData } from 'src/composables/useArrayData';
-import qs from 'qs';
 const { notify, dialog } = useQuasar();
 const { t } = useI18n();
 
@@ -13,51 +12,29 @@ defineExpose({ checkToBook });
 const { store } = useArrayData();
 
 async function checkToBook(id) {
-    let messages = [];
-
-    const hasProblemWithTax = (
-        await axios.get('InvoiceInTaxes/count', {
-            params: {
-                where: JSON.stringify({
-                    invoiceInFk: id,
-                    or: [{ taxTypeSageFk: null }, { transactionTypeSageFk: null }],
-                }),
-            },
-        })
-    ).data?.count;
-
-    if (hasProblemWithTax)
-        messages.push(t('The VAT and Transaction fields have not been informed'));
+    let directBooking = true;
 
     const { data: totals } = await axios.get(`InvoiceIns/${id}/getTotals`);
     const taxableBaseNotEqualDueDay = totals.totalDueDay != totals.totalTaxableBase;
     const vatNotEqualDueDay = totals.totalDueDay != totals.totalVat;
 
-    if (taxableBaseNotEqualDueDay && vatNotEqualDueDay)
-        messages.push(t('The sum of the taxable bases does not match the due dates'));
+    if (taxableBaseNotEqualDueDay && vatNotEqualDueDay) directBooking = false;
 
-    const dueDaysCount = (
-        await axios.get('InvoiceInDueDays/count', {
-            params: {
-                where: JSON.stringify({
-                    invoiceInFk: id,
-                    dueDated: { gte: Date.vnNew() },
-                }),
-            },
-        })
-    ).data?.count;
+    const { data: dueDaysCount } = await axios.get('InvoiceInDueDays/count', {
+        where: {
+            invoiceInFk: id,
+            dueDated: { gte: Date.vnNew() },
+        },
+    });
 
-    if (dueDaysCount) messages.push(t('Some due dates are less than or equal to today'));
+    if (dueDaysCount) directBooking = false;
 
-    if (!messages.length) toBook(id);
-    else
-        dialog({
-            component: VnConfirm,
-            componentProps: {
-                title: t('Are you sure you want to book this invoice?'),
-                message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''),
-            },
-        }).onOk(() => toBook(id));
+    if (directBooking) return toBook(id);
+
+    dialog({
+        component: VnConfirm,
+        componentProps: { title: t('Are you sure you want to book this invoice?') },
+    }).onOk(async () => await toBook(id));
 }
 
 async function toBook(id) {
@@ -82,7 +59,4 @@ async function toBook(id) {
 es:
     Are you sure you want to book this invoice?: ¿Estás seguro de querer asentar esta factura?
     It was not able to book the invoice: No se pudo contabilizar la factura
-    Some due dates are less than or equal to today: Algún vencimiento tiene una fecha menor o igual que hoy
-    The sum of the taxable bases does not match the due dates: La suma de las bases imponibles no coincide con la de los vencimientos
-    The VAT and Transaction fields have not been informed: No se han informado los campos de iva y/o transacción
 </i18n>
diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml
index 548e6c2010b..6b21b316bad 100644
--- a/src/pages/InvoiceIn/locale/en.yml
+++ b/src/pages/InvoiceIn/locale/en.yml
@@ -3,10 +3,10 @@ invoiceIn:
     searchInfo: Search incoming invoices by ID or supplier fiscal name
     serial: Serial
     isBooked: Is booked
-    supplierRef: Invoice nº
     list:
         ref: Reference
         supplier: Supplier
+        supplierRef: Supplier ref.
         file: File
         issued: Issued
         dueDated: Due dated
@@ -19,6 +19,8 @@ invoiceIn:
         unbook: Unbook
         delete: Delete
         clone: Clone
+        toBook: To book
+        toUnbook: To unbook
         deleteInvoice: Delete invoice
         invoiceDeleted: invoice deleted
         cloneInvoice: Clone invoice
@@ -68,3 +70,4 @@ invoiceIn:
         isBooked: Is booked
         account: Ledger account
         correctingFk: Rectificative
+        
\ No newline at end of file
diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml
index 142d95f929c..3f27c895c51 100644
--- a/src/pages/InvoiceIn/locale/es.yml
+++ b/src/pages/InvoiceIn/locale/es.yml
@@ -3,10 +3,10 @@ invoiceIn:
     searchInfo: Buscar facturas recibidas por ID o nombre fiscal del proveedor
     serial: Serie
     isBooked: Contabilizada
-    supplierRef: Nº factura
     list:
         ref: Referencia
         supplier: Proveedor
+        supplierRef: Ref. proveedor
         issued: F. emisión
         dueDated: F. vencimiento
         file: Fichero
@@ -15,10 +15,12 @@ invoiceIn:
     descriptor:
         ticketList: Listado de tickets
     descriptorMenu:
-        book: Contabilizar
-        unbook: Descontabilizar
+        book: Asentar
+        unbook: Desasentar
         delete: Eliminar
         clone: Clonar
+        toBook: Contabilizar
+        toUnbook: Descontabilizar
         deleteInvoice: Eliminar factura
         invoiceDeleted: Factura eliminada
         cloneInvoice: Clonar factura
@@ -66,3 +68,4 @@ invoiceIn:
         isBooked: Contabilizada
         account: Cuenta contable
         correctingFk: Rectificativa
+
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutCard.vue b/src/pages/InvoiceOut/Card/InvoiceOutCard.vue
index a50c9d24732..93e3fe0420a 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutCard.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutCard.vue
@@ -1,13 +1,11 @@
 <script setup>
 import InvoiceOutDescriptor from './InvoiceOutDescriptor.vue';
 import VnCardBeta from 'components/common/VnCardBeta.vue';
-import filter from './InvoiceOutFilter.js';
 </script>
 <template>
     <VnCardBeta
         data-key="InvoiceOut"
-        url="InvoiceOuts"
-        :filter="filter"
+        base-url="InvoiceOuts"
         :descriptor="InvoiceOutDescriptor"
     />
 </template>
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
index dfaf6c10988..209f1531e1b 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
@@ -8,8 +8,8 @@ import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy
 import VnLv from 'src/components/ui/VnLv.vue';
 import InvoiceOutDescriptorMenu from './InvoiceOutDescriptorMenu.vue';
 
+import useCardDescription from 'src/composables/useCardDescription';
 import { toCurrency, toDate } from 'src/filters';
-import filter from './InvoiceOutFilter.js';
 
 const $props = defineProps({
     id: {
@@ -26,20 +26,42 @@ const entityId = computed(() => {
     return $props.id || route.params.id;
 });
 
+const filter = {
+    include: [
+        {
+            relation: 'company',
+            scope: {
+                fields: ['id', 'code'],
+            },
+        },
+        {
+            relation: 'client',
+            scope: {
+                fields: ['id', 'name', 'email'],
+            },
+        },
+    ],
+};
+
 const descriptor = ref();
 
 function ticketFilter(invoice) {
     return JSON.stringify({ refFk: invoice.ref });
 }
+const data = ref(useCardDescription());
+const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.id));
 </script>
 
 <template>
     <CardDescriptor
         ref="descriptor"
+        module="InvoiceOut"
         :url="`InvoiceOuts/${entityId}`"
         :filter="filter"
-        title="ref"
-        data-key="InvoiceOut"
+        :title="data.title"
+        :subtitle="data.subtitle"
+        @on-fetch="setData"
+        data-key="invoiceOutData"
         width="lg-width"
     >
         <template #menu="{ entity, menuRef }">
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutFilter.js b/src/pages/InvoiceOut/Card/InvoiceOutFilter.js
deleted file mode 100644
index 48b20faf698..00000000000
--- a/src/pages/InvoiceOut/Card/InvoiceOutFilter.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export default {
-    include: [
-        {
-            relation: 'company',
-            scope: {
-                fields: ['id', 'code'],
-            },
-        },
-        {
-            relation: 'client',
-            scope: {
-                fields: ['id', 'name', 'email'],
-            },
-        },
-    ],
-};
diff --git a/src/pages/Item/components/CreateGenusForm.vue b/src/pages/Item/Card/CreateGenusForm.vue
similarity index 100%
rename from src/pages/Item/components/CreateGenusForm.vue
rename to src/pages/Item/Card/CreateGenusForm.vue
diff --git a/src/pages/Item/components/CreateSpecieForm.vue b/src/pages/Item/Card/CreateSpecieForm.vue
similarity index 100%
rename from src/pages/Item/components/CreateSpecieForm.vue
rename to src/pages/Item/Card/CreateSpecieForm.vue
diff --git a/src/pages/Item/Card/ItemBarcode.vue b/src/pages/Item/Card/ItemBarcode.vue
index 590b524cd84..6db5943c77b 100644
--- a/src/pages/Item/Card/ItemBarcode.vue
+++ b/src/pages/Item/Card/ItemBarcode.vue
@@ -92,7 +92,7 @@ const submit = async (rows) => {
                             class="cursor-pointer fill-icon-on-hover"
                             color="primary"
                             icon="add_circle"
-                            v-shortcut="'+'"
+                            shortcut="+"
                             flat
                         >
                             <QTooltip>
diff --git a/src/pages/Item/Card/ItemBasicData.vue b/src/pages/Item/Card/ItemBasicData.vue
index df7e71684c6..4c96401f3b9 100644
--- a/src/pages/Item/Card/ItemBasicData.vue
+++ b/src/pages/Item/Card/ItemBasicData.vue
@@ -11,7 +11,6 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
 import FilterItemForm from 'src/components/FilterItemForm.vue';
 import CreateIntrastatForm from './CreateIntrastatForm.vue';
-import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -55,8 +54,9 @@ const onIntrastatCreated = (response, formData) => {
         auto-load
     />
     <FormModel
+        :url="`Items/${route.params.id}`"
         :url-update="`Items/${route.params.id}`"
-        model="Item"
+        model="item"
         auto-load
         :clear-store-on-unmount="false"
     >
@@ -209,20 +209,30 @@ const onIntrastatCreated = (response, formData) => {
                 />
             </VnRow>
             <VnRow class="row q-gutter-md q-mb-md">
-                <VnCheckbox
-                    v-model="data.isFragile"
-                    :label="t('item.basicData.isFragile')"
-                    :info="t('item.basicData.isFragileTooltip')"
-                    class="q-mr-sm"
-                    size="xs"
-                />
-                <VnCheckbox
-                    v-model="data.isPhotoRequested"
-                    :label="t('item.basicData.isPhotoRequested')"
-                    :info="t('item.basicData.isPhotoRequestedTooltip')"
-                    class="q-mr-sm"
-                    size="xs"
-                />
+                <div>
+                    <QCheckbox
+                        v-model="data.isFragile"
+                        :label="t('item.basicData.isFragile')"
+                        class="q-mr-sm"
+                    />
+                    <QIcon name="info" class="cursor-pointer" size="xs">
+                        <QTooltip max-width="300px">
+                            {{ t('item.basicData.isFragileTooltip') }}
+                        </QTooltip>
+                    </QIcon>
+                </div>
+                <div>
+                    <QCheckbox
+                        v-model="data.isPhotoRequested"
+                        :label="t('item.basicData.isPhotoRequested')"
+                        class="q-mr-sm"
+                    />
+                    <QIcon name="info" class="cursor-pointer" size="xs">
+                        <QTooltip>
+                            {{ t('item.basicData.isPhotoRequestedTooltip') }}
+                        </QTooltip>
+                    </QIcon>
+                </div>
             </VnRow>
             <VnRow>
                 <VnInput
diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue
index a40d8158987..4894d94fcd3 100644
--- a/src/pages/Item/Card/ItemBotanical.vue
+++ b/src/pages/Item/Card/ItemBotanical.vue
@@ -7,8 +7,8 @@ import FetchData from 'components/FetchData.vue';
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
-import CreateGenusForm from '../components/CreateGenusForm.vue';
-import CreateSpecieForm from '../components/CreateSpecieForm.vue';
+import CreateGenusForm from './CreateGenusForm.vue';
+import CreateSpecieForm from './CreateSpecieForm.vue';
 
 const route = useRoute();
 const { t } = useI18n();
diff --git a/src/pages/Item/Card/ItemCard.vue b/src/pages/Item/Card/ItemCard.vue
index 610b77a02ae..2546982eb7b 100644
--- a/src/pages/Item/Card/ItemCard.vue
+++ b/src/pages/Item/Card/ItemCard.vue
@@ -5,7 +5,7 @@ import ItemDescriptor from './ItemDescriptor.vue';
 <template>
     <VnCardBeta
         data-key="Item"
-        :url="`Items/${$route.params.id}/getCard`"
+        base-url="Items"
         :descriptor="ItemDescriptor"
     />
 </template>
diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue
index a4c58ef4b2c..c6fee8540ef 100644
--- a/src/pages/Item/Card/ItemDescriptor.vue
+++ b/src/pages/Item/Card/ItemDescriptor.vue
@@ -7,6 +7,7 @@ import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue';
+import useCardDescription from 'src/composables/useCardDescription';
 import axios from 'axios';
 import { dashIfEmpty } from 'src/filters';
 import { useArrayData } from 'src/composables/useArrayData';
@@ -34,10 +35,6 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
-    proxyRender: {
-        type: Boolean,
-        default: false,
-    },
 });
 
 const route = useRoute();
@@ -58,8 +55,10 @@ onMounted(async () => {
     mounted.value = true;
 });
 
+const data = ref(useCardDescription());
 const setData = async (entity) => {
     if (!entity) return;
+    data.value = useCardDescription(entity.name, entity.id);
     await updateStock();
 };
 
@@ -91,7 +90,10 @@ const updateStock = async () => {
 
 <template>
     <CardDescriptor
-        data-key="Item"
+        data-key="ItemData"
+        module="Item"
+        :title="data.title"
+        :subtitle="data.subtitle"
         :summary="$props.summary"
         :url="`Items/${entityId}/getCard`"
         @on-fetch="setData"
@@ -115,7 +117,7 @@ const updateStock = async () => {
                 <template #value>
                     <span class="link">
                         {{ entity.itemType?.worker?.user?.name }}
-                        <WorkerDescriptorProxy :id="entity.itemType?.worker?.id ?? NaN" />
+                        <WorkerDescriptorProxy :id="entity.itemType?.worker?.id" />
                     </span>
                 </template>
             </VnLv>
@@ -150,7 +152,7 @@ const updateStock = async () => {
             </QCardActions>
         </template>
         <template #actions="{}">
-            <QCardActions class="row justify-center" v-if="proxyRender">
+            <QCardActions class="row justify-center">
                 <QBtn
                     :to="{
                         name: 'ItemDiary',
@@ -163,16 +165,6 @@ const updateStock = async () => {
                 >
                     <QTooltip>{{ t('item.descriptor.itemDiary') }}</QTooltip>
                 </QBtn>
-                <QBtn
-                    :to="{
-                        name: 'ItemLastEntries',
-                    }"
-                    size="md"
-                    icon="vn:regentry"
-                    color="primary"
-                >
-                    <QTooltip>{{ t('item.descriptor.itemLastEntries') }}</QTooltip>
-                </QBtn>
             </QCardActions>
         </template>
     </CardDescriptor>
diff --git a/src/pages/Item/Card/ItemDescriptorProxy.vue b/src/pages/Item/Card/ItemDescriptorProxy.vue
index f686e822115..2ffc9080f1a 100644
--- a/src/pages/Item/Card/ItemDescriptorProxy.vue
+++ b/src/pages/Item/Card/ItemDescriptorProxy.vue
@@ -4,7 +4,7 @@ import ItemSummary from './ItemSummary.vue';
 
 const $props = defineProps({
     id: {
-        type: [Number, String],
+        type: Number,
         required: true,
     },
     dated: {
@@ -21,8 +21,9 @@ const $props = defineProps({
     },
 });
 </script>
+
 <template>
-    <QPopupProxy style="max-width: 10px">
+    <QPopupProxy>
         <ItemDescriptor
             v-if="$props.id"
             :id="$props.id"
@@ -30,7 +31,6 @@ const $props = defineProps({
             :dated="dated"
             :sale-fk="saleFk"
             :warehouse-fk="warehouseFk"
-            :proxy-render="true"
         />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Item/Card/ItemShelving.vue b/src/pages/Item/Card/ItemShelving.vue
index b29e2a2a5a9..7ad60c9e0c6 100644
--- a/src/pages/Item/Card/ItemShelving.vue
+++ b/src/pages/Item/Card/ItemShelving.vue
@@ -110,16 +110,10 @@ const columns = computed(() => [
         attrs: { inWhere: true },
         align: 'left',
     },
-    {
-        label: t('globals.visible'),
-        name: 'stock',
-        attrs: { inWhere: true },
-        align: 'left',
-    },
 ]);
 
 const totalLabels = computed(() =>
-    rows.value.reduce((acc, row) => acc + row.stock / row.packing, 0).toFixed(2),
+    rows.value.reduce((acc, row) => acc + row.stock / row.packing, 0).toFixed(2)
 );
 
 const removeLines = async () => {
@@ -163,7 +157,7 @@ watchEffect(selectedRows);
                     openConfirmationModal(
                         t('shelvings.removeConfirmTitle'),
                         t('shelvings.removeConfirmSubtitle'),
-                        removeLines,
+                        removeLines
                     )
                 "
             >
diff --git a/src/pages/Item/Card/ItemTags.vue b/src/pages/Item/Card/ItemTags.vue
index ab26b9caea5..5a7d7f818de 100644
--- a/src/pages/Item/Card/ItemTags.vue
+++ b/src/pages/Item/Card/ItemTags.vue
@@ -178,7 +178,7 @@ const insertTag = (rows) => {
                             @click="insertTag(rows)"
                             color="primary"
                             icon="add"
-                            v-shortcut="'+'"
+                            shortcut="+"
                             fab
                             data-cy="createNewTag"
                         >
diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue
index fdfa1d3d1d7..1c4382fbd2a 100644
--- a/src/pages/Item/ItemFixedPrice.vue
+++ b/src/pages/Item/ItemFixedPrice.vue
@@ -65,19 +65,10 @@ const columns = computed(() => [
         name: 'name',
         ...defaultColumnAttrs,
         create: true,
-        columnFilter: {
-            component: 'select',
-            attrs: {
-                url: 'Items',
-                fields: ['id', 'name', 'subName'],
-                optionLabel: 'name',
-                optionValue: 'name',
-                uppercase: false,
-            },
-        },
     },
     {
         label: t('item.fixedPrice.groupingPrice'),
+        field: 'rate2',
         name: 'rate2',
         ...defaultColumnAttrs,
         component: 'input',
@@ -85,6 +76,7 @@ const columns = computed(() => [
     },
     {
         label: t('item.fixedPrice.packingPrice'),
+        field: 'rate3',
         name: 'rate3',
         ...defaultColumnAttrs,
         component: 'input',
@@ -93,6 +85,7 @@ const columns = computed(() => [
 
     {
         label: t('item.fixedPrice.minPrice'),
+        field: 'minPrice',
         name: 'minPrice',
         ...defaultColumnAttrs,
         component: 'input',
@@ -115,6 +108,7 @@ const columns = computed(() => [
     },
     {
         label: t('item.fixedPrice.ended'),
+        field: 'ended',
         name: 'ended',
         ...defaultColumnAttrs,
         columnField: {
@@ -130,6 +124,7 @@ const columns = computed(() => [
 
     {
         label: t('globals.warehouse'),
+        field: 'warehouseFk',
         name: 'warehouseFk',
         ...defaultColumnAttrs,
         columnClass: 'shrink',
@@ -420,6 +415,7 @@ function handleOnDataSave({ CrudModelRef }) {
             'row-key': 'id',
             selection: 'multiple',
         }"
+        :use-model="true"
         v-model:selected="rowsSelected"
         :create-as-dialog="false"
         :create="{
diff --git a/src/pages/Item/ItemType/Card/ItemTypeBasicData.vue b/src/pages/Item/ItemType/Card/ItemTypeBasicData.vue
index 475dffd8b9a..b4032ff8a5b 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeBasicData.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeBasicData.vue
@@ -40,7 +40,12 @@ const itemPackingTypesOptions = ref([]);
         }"
         auto-load
     />
-    <FormModel :url-update="`ItemTypes/${route.params.id}`" model="ItemType" auto-load>
+    <FormModel
+        :url="`ItemTypes/${route.params.id}`"
+        :url-update="`ItemTypes/${route.params.id}`"
+        model="itemTypeBasicData"
+        auto-load
+    >
         <template #form="{ data }">
             <VnRow>
                 <VnInput v-model="data.code" :label="t('itemType.shared.code')" />
diff --git a/src/pages/Item/ItemType/Card/ItemTypeCard.vue b/src/pages/Item/ItemType/Card/ItemTypeCard.vue
index 84e810de513..fa51e428e0a 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeCard.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeCard.vue
@@ -1,14 +1,12 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import ItemTypeDescriptor from 'src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue';
-import filter from './ItemTypeFilter.js';
 </script>
 
 <template>
     <VnCardBeta
-        data-key="ItemType"
-        url="ItemTypes"
-        :filter="filter"
+        data-key="ItemTypeSummary"
+        base-url="ItemTypes"
         :descriptor="ItemTypeDescriptor"
     />
 </template>
diff --git a/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue b/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue
index 725fb30aa60..09d3dbce575 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue
@@ -1,11 +1,12 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
-import filter from './ItemTypeFilter.js';
+import useCardDescription from 'src/composables/useCardDescription';
 
 const $props = defineProps({
     id: {
@@ -19,31 +20,46 @@ const $props = defineProps({
 });
 
 const route = useRoute();
+const { t } = useI18n();
 
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+
+const itemTypeFilter = {
+    include: [
+        { relation: 'worker' },
+        { relation: 'category' },
+        { relation: 'itemPackingType' },
+        { relation: 'temperature' },
+    ],
+};
+
+const data = ref(useCardDescription());
+const setData = (entity) => (data.value = useCardDescription(entity.code, entity.id));
 </script>
+
 <template>
     <CardDescriptor
+        module="ItemType"
         :url="`ItemTypes/${entityId}`"
-        :filter="filter"
-        title="code"
-        data-key="ItemType"
+        :filter="itemTypeFilter"
+        :title="data.title"
+        :subtitle="data.subtitle"
+        data-key="itemTypeDescriptor"
+        @on-fetch="setData"
     >
         <template #body="{ entity }">
-            <VnLv :label="$t('itemType.shared.code')" :value="entity.code" />
-            <VnLv :label="$t('itemType.shared.name')" :value="entity.name" />
-            <VnLv :label="$t('itemType.shared.worker')">
+            <VnLv :label="t('itemType.shared.code')" :value="entity.code" />
+            <VnLv :label="t('itemType.shared.name')" :value="entity.name" />
+            <VnLv :label="t('itemType.shared.worker')">
                 <template #value>
                     <span class="link">{{ entity.worker?.firstName }}</span>
                     <WorkerDescriptorProxy :id="entity.worker?.id" />
                 </template>
             </VnLv>
-            <VnLv
-                :label="$t('itemType.shared.category')"
-                :value="entity.category?.name"
-            />
+            <VnLv :label="t('itemType.shared.category')" :value="entity.category?.name" />
         </template>
     </CardDescriptor>
 </template>
+
diff --git a/src/pages/Item/ItemType/Card/ItemTypeFilter.js b/src/pages/Item/ItemType/Card/ItemTypeFilter.js
deleted file mode 100644
index 5651d368d83..00000000000
--- a/src/pages/Item/ItemType/Card/ItemTypeFilter.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
-    include: [
-        { relation: 'worker' },
-        { relation: 'category' },
-        { relation: 'itemPackingType' },
-        { relation: 'temperature' },
-    ],
-};
diff --git a/src/pages/Item/ItemType/Card/ItemTypeSummary.vue b/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
index 3b63c4b63ed..9ba774ca462 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeSummary.vue
@@ -3,7 +3,7 @@ import { ref, computed, onUpdated } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
-import filter from './ItemTypeFilter.js';
+
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import VnToSummary from 'src/components/ui/VnToSummary.vue';
@@ -21,6 +21,15 @@ const $props = defineProps({
     },
 });
 
+const itemTypeFilter = {
+    include: [
+        { relation: 'worker' },
+        { relation: 'category' },
+        { relation: 'itemPackingType' },
+        { relation: 'temperature' },
+    ],
+};
+
 const entityId = computed(() => $props.id || route.params.id);
 const summaryRef = ref();
 const itemType = ref();
@@ -34,8 +43,8 @@ async function setItemTypeData(data) {
     <CardSummary
         ref="summaryRef"
         :url="`ItemTypes/${entityId}`"
-        data-key="ItemType"
-        :filter="filter"
+        data-key="ItemTypeSummary"
+        :filter="itemTypeFilter"
         @on-fetch="(data) => setItemTypeData(data)"
         class="full-width"
     >
diff --git a/src/pages/Item/components/ItemProposal.vue b/src/pages/Item/components/ItemProposal.vue
deleted file mode 100644
index d2dbea7b320..00000000000
--- a/src/pages/Item/components/ItemProposal.vue
+++ /dev/null
@@ -1,332 +0,0 @@
-<script setup>
-import { ref, computed } from 'vue';
-import { useI18n } from 'vue-i18n';
-import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
-import { toCurrency } from 'filters/index';
-import VnStockValueDisplay from 'src/components/ui/VnStockValueDisplay.vue';
-import VnTable from 'src/components/VnTable/VnTable.vue';
-import axios from 'axios';
-import notifyResults from 'src/utils/notifyResults';
-import FetchData from 'components/FetchData.vue';
-
-const MATCH = 'match';
-
-const { t } = useI18n();
-const $props = defineProps({
-    itemLack: {
-        type: Object,
-        required: true,
-        default: () => {},
-    },
-    replaceAction: {
-        type: Boolean,
-        required: false,
-        default: false,
-    },
-    sales: {
-        type: Array,
-        required: false,
-        default: () => [],
-    },
-});
-const proposalSelected = ref([]);
-const ticketConfig = ref({});
-const proposalTableRef = ref(null);
-
-const sale = computed(() => $props.sales[0]);
-const saleFk = computed(() => sale.value.saleFk);
-const filter = computed(() => ({
-    itemFk: $props.itemLack.itemFk,
-    sales: saleFk.value,
-}));
-
-const defaultColumnAttrs = {
-    align: 'center',
-    sortable: false,
-};
-const emit = defineEmits(['onDialogClosed', 'itemReplaced']);
-
-const conditionalValuePrice = (price) =>
-    price > 1 + ticketConfig.value.lackAlertPrice / 100 ? 'match' : 'not-match';
-
-const columns = computed(() => [
-    {
-        ...defaultColumnAttrs,
-        label: t('proposal.available'),
-        name: 'available',
-        field: 'available',
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-            columnClass: 'shrink',
-        },
-        columnClass: 'shrink',
-    },
-    {
-        ...defaultColumnAttrs,
-        label: t('proposal.counter'),
-        name: 'counter',
-        field: 'counter',
-        columnClass: 'shrink',
-        style: 'max-width: 75px',
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-            columnClass: 'shrink',
-        },
-    },
-
-    {
-        align: 'left',
-        sortable: true,
-        label: t('proposal.longName'),
-        name: 'longName',
-        field: 'longName',
-        columnClass: 'expand',
-    },
-    {
-        align: 'left',
-        sortable: true,
-        label: t('item.list.color'),
-        name: 'tag5',
-        field: 'value5',
-        columnClass: 'expand',
-    },
-    {
-        align: 'left',
-        sortable: true,
-        label: t('item.list.stems'),
-        name: 'tag6',
-        field: 'value6',
-        columnClass: 'expand',
-    },
-    {
-        align: 'left',
-        sortable: true,
-        label: t('item.list.producer'),
-        name: 'tag7',
-        field: 'value7',
-        columnClass: 'expand',
-    },
-
-    {
-        ...defaultColumnAttrs,
-        label: t('proposal.price2'),
-        name: 'price2',
-        style: 'max-width: 75px',
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-            columnClass: 'shrink',
-        },
-    },
-    {
-        ...defaultColumnAttrs,
-        label: t('proposal.minQuantity'),
-        name: 'minQuantity',
-        field: 'minQuantity',
-        style: 'max-width: 75px',
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-            columnClass: 'shrink',
-        },
-    },
-    {
-        ...defaultColumnAttrs,
-        label: t('proposal.located'),
-        name: 'located',
-        field: 'located',
-    },
-    {
-        align: 'right',
-        label: '',
-        name: 'tableActions',
-        actions: [
-            {
-                title: t('Replace'),
-                icon: 'change_circle',
-                show: (row) => isSelectionAvailable(row),
-                action: change,
-                isPrimary: true,
-            },
-        ],
-    },
-]);
-
-function extractMatchValues(obj) {
-    return Object.keys(obj)
-        .filter((key) => key.startsWith(MATCH))
-        .map((key) => parseInt(key.replace(MATCH, ''), 10));
-}
-const gradientStyle = (value) => {
-    let color = 'white';
-    const perc = parseFloat(value);
-    switch (true) {
-        case perc >= 0 && perc < 33:
-            color = 'primary';
-            break;
-        case perc >= 33 && perc < 66:
-            color = 'warning';
-            break;
-
-        default:
-            color = 'secondary';
-            break;
-    }
-    return color;
-};
-const statusConditionalValue = (row) => {
-    const matches = extractMatchValues(row);
-    const value = matches.reduce((acc, i) => acc + row[`${MATCH}${i}`], 0);
-    return 100 * (value / matches.length);
-};
-
-const isSelectionAvailable = (itemProposal) => {
-    const { price2 } = itemProposal;
-    const salePrice = sale.value.price;
-    const byPrice = (100 * price2) / salePrice > ticketConfig.value.lackAlertPrice;
-    if (byPrice) {
-        return byPrice;
-    }
-    const byQuantity =
-        (100 * itemProposal.available) / Math.abs($props.itemLack.lack) <
-        ticketConfig.value.lackAlertPrice;
-    return byQuantity;
-};
-
-async function change({ itemFk: substitutionFk }) {
-    try {
-        const promises = $props.sales.map(({ saleFk, quantity }) => {
-            const params = {
-                saleFk,
-                substitutionFk,
-                quantity,
-            };
-            return axios.post('Sales/replaceItem', params);
-        });
-        const results = await Promise.allSettled(promises);
-
-        notifyResults(results, 'saleFk');
-        emit('itemReplaced', {
-            type: 'refresh',
-            quantity: quantity.value,
-            itemProposal: proposalSelected.value[0],
-        });
-        proposalSelected.value = [];
-    } catch (error) {
-        console.error(error);
-    }
-}
-
-async function handleTicketConfig(data) {
-    ticketConfig.value = data[0];
-}
-</script>
-<template>
-    <FetchData
-        url="TicketConfigs"
-        :filter="{ fields: ['lackAlertPrice'] }"
-        @on-fetch="handleTicketConfig"
-        auto-load
-    />
-
-    <VnTable
-        v-if="ticketConfig"
-        auto-load
-        data-cy="proposalTable"
-        ref="proposalTableRef"
-        data-key="ItemsGetSimilar"
-        url="Items/getSimilar"
-        :user-filter="filter"
-        :columns="columns"
-        class="full-width q-mt-md"
-        row-key="id"
-        :row-click="change"
-        :is-editable="false"
-        :right-search="false"
-        :without-header="true"
-        :disable-option="{ card: true, table: true }"
-    >
-        <template #column-longName="{ row }">
-            <QTd
-                class="flex"
-                style="max-width: 100%; flex-shrink: 50px; flex-wrap: nowrap"
-            >
-                <div
-                    class="middle full-width"
-                    :class="[`proposal-${gradientStyle(statusConditionalValue(row))}`]"
-                >
-                    <QTooltip> {{ statusConditionalValue(row) }}% </QTooltip>
-                </div>
-                <div style="flex: 2 0 100%; align-content: center">
-                    <div>
-                        <span class="link">{{ row.longName }}</span>
-                        <ItemDescriptorProxy :id="row.id" />
-                    </div>
-                </div>
-            </QTd>
-        </template>
-        <template #column-tag5="{ row }">
-            <span :class="{ match: !row.match5 }">{{ row.value5 }}</span>
-        </template>
-        <template #column-tag6="{ row }">
-            <span :class="{ match: !row.match6 }">{{ row.value6 }}</span>
-        </template>
-        <template #column-tag7="{ row }">
-            <span :class="{ match: !row.match7 }">{{ row.value7 }}</span>
-        </template>
-        <template #column-counter="{ row }">
-            <span
-                :class="{
-                    match: row.counter === 1,
-                    'not-match': row.counter !== 1,
-                }"
-                >{{ row.counter }}</span
-            >
-        </template>
-        <template #column-minQuantity="{ row }">
-            {{ row.minQuantity }}
-        </template>
-        <template #column-price2="{ row }">
-            <div class="flex column items-center content-center">
-                <VnStockValueDisplay :value="(sales[0].price - row.price2) / 100" />
-                <span :class="[conditionalValuePrice(row.price2)]">{{
-                    toCurrency(row.price2)
-                }}</span>
-            </div>
-        </template>
-    </VnTable>
-</template>
-<style lang="scss" scoped>
-@import 'src/css/quasar.variables.scss';
-.middle {
-    float: left;
-    margin-right: 2px;
-    flex: 2 0 5px;
-}
-.match {
-    color: $negative;
-}
-.not-match {
-    color: inherit;
-}
-.proposal-warning {
-    background-color: $warning;
-}
-.proposal-secondary {
-    background-color: $secondary;
-}
-.proposal-primary {
-    background-color: $primary;
-}
-.text {
-    margin: 0.05rem;
-    padding: 1px;
-    border: 1px solid var(--vn-label-color);
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    font-size: smaller;
-}
-</style>
diff --git a/src/pages/Item/components/ItemProposalProxy.vue b/src/pages/Item/components/ItemProposalProxy.vue
deleted file mode 100644
index 7da0ce398fd..00000000000
--- a/src/pages/Item/components/ItemProposalProxy.vue
+++ /dev/null
@@ -1,56 +0,0 @@
-<script setup>
-import ItemProposal from './ItemProposal.vue';
-import { useDialogPluginComponent } from 'quasar';
-
-const $props = defineProps({
-    itemLack: {
-        type: Object,
-        required: true,
-        default: () => {},
-    },
-    replaceAction: {
-        type: Boolean,
-        required: false,
-        default: false,
-    },
-    sales: {
-        type: Array,
-        required: false,
-        default: () => [],
-    },
-});
-const { dialogRef } = useDialogPluginComponent();
-const emit = defineEmits([
-    'onDialogClosed',
-    'itemReplaced',
-    ...useDialogPluginComponent.emits,
-]);
-defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() });
-</script>
-<template>
-    <QDialog ref="dialogRef" transition-show="scale" transition-hide="scale">
-        <QCard class="dialog-width">
-            <QCardSection class="row items-center q-pb-none">
-                <span class="text-h6 text-grey">{{ $t('Item proposal') }}</span>
-                <QSpace />
-                <QBtn icon="close" flat round dense v-close-popup />
-            </QCardSection>
-            <QCardSection>
-                <ItemProposal
-                    v-bind="$props"
-                    @item-replaced="
-                        (data) => {
-                            emit('itemReplaced', data);
-                            dialogRef.hide();
-                        }
-                    "
-                ></ItemProposal
-            ></QCardSection>
-        </QCard>
-    </QDialog>
-</template>
-<style lang="scss" scoped>
-.dialog-width {
-    max-width: $width-lg;
-}
-</style>
diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml
index 9d27fc96e2a..bc73abb1220 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -112,7 +112,6 @@ item:
         available: Available
         warehouseText: 'Calculated on the warehouse of { warehouseName }'
         itemDiary: Item diary
-        itemLastEntries: Last entries
         producer: Producer
         clone:
             title: All its properties will be copied
@@ -131,7 +130,6 @@ item:
         origin: Orig.
         userName: Buyer
         weight: Weight
-        color: Color
         weightByPiece: Weight/stem
         stemMultiplier: Multiplier
         producer: Producer
@@ -217,24 +215,4 @@ item:
         specie: Specie
     search: 'Search item'
     searchInfo: 'You can search by id'
-    regularizeStock: Regularize stock
-itemProposal: Items proposal
-proposal:
-    difference: Difference
-    title: Items proposal
-    itemFk: Item
-    longName: Name
-    subName: Producer
-    value5: value5
-    value6: value6
-    value7: value7
-    value8: value8
-    available: Available
-    minQuantity: minQuantity
-    price2: Price
-    located: Located
-    counter: Counter
-    groupingPrice: Grouping Price
-    itemOldPrice: itemOld Price
-    status: State
-    quantityToReplace: Quanity to replace
+    regularizeStock: Regularize stock
\ No newline at end of file
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index 935f5160bf1..dd5074f5fc4 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -118,7 +118,6 @@ item:
         available: Disponible
         warehouseText: 'Calculado sobre el almacén de { warehouseName }'
         itemDiary: Registro de compra-venta
-        itemLastEntries: Últimas entradas
         producer: Productor
         clone:
             title: Todas sus propiedades serán copiadas
@@ -136,7 +135,6 @@ item:
         size: Medida
         origin: Orig.
         weight: Peso
-        color: Color
         weightByPiece: Peso/tallo
         userName: Comprador
         stemMultiplier: Multiplicador
@@ -222,30 +220,5 @@ item:
         achieved: 'Conseguido'
         concept: 'Concepto'
         state: 'Estado'
-itemProposal: Artículos similares
-proposal:
-    substitutionAvailable: Sustitución disponible
-    notSubstitutionAvailableByPrice: Sustitución no disponible, 30% de diferencia por precio o cantidad
-    compatibility: Compatibilidad
-    title: Items de sustitución para los tickets seleccionados
-    itemFk: Item
-    longName: Nombre
-    subName: Productor
-    value5: value5
-    value6: value6
-    value7: value7
-    value8: value8
-    available: Disponible
-    minQuantity: Min. cantidad
-    price2: Precio
-    located: Ubicado
-    counter: Contador
-    difference: Diferencial
-    groupingPrice: Precio Grouping
-    itemOldPrice: Precio itemOld
-    status: Estado
-    quantityToReplace: Cantidad a reemplazar
-    replace: Sustituir
-    replaceAndConfirm: Sustituir y confirmar precio
-search: 'Buscar artículo'
-searchInfo: 'Puedes buscar por id'
+    search: 'Buscar artículo'
+    searchInfo: 'Puedes buscar por id'
diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue
index 873f8abb4ee..4efab56fbe5 100644
--- a/src/pages/Monitor/MonitorOrders.vue
+++ b/src/pages/Monitor/MonitorOrders.vue
@@ -157,7 +157,7 @@ const openTab = (id) =>
                         openConfirmationModal(
                             $t('globals.deleteConfirmTitle'),
                             $t('salesOrdersTable.deleteConfirmMessage'),
-                            removeOrders,
+                            removeOrders
                         )
                     "
                 >
diff --git a/src/pages/Monitor/locale/en.yml b/src/pages/Monitor/locale/en.yml
index 496c8761a16..21324087c42 100644
--- a/src/pages/Monitor/locale/en.yml
+++ b/src/pages/Monitor/locale/en.yml
@@ -38,7 +38,6 @@ salesTicketsTable:
     payMethod: Pay method
     department: Department
     packing: ITP
-    hasItemLost: Item lost
 searchBar:
     label: Search tickets
     info: Search tickets by id or alias
diff --git a/src/pages/Monitor/locale/es.yml b/src/pages/Monitor/locale/es.yml
index f6a29879f08..30afb1904ba 100644
--- a/src/pages/Monitor/locale/es.yml
+++ b/src/pages/Monitor/locale/es.yml
@@ -39,7 +39,6 @@ salesTicketsTable:
     payMethod: Método de pago
     department: Departamento
     packing: ITP
-    hasItemLost: Artículo perdido
 searchBar:
     label: Buscar tickets
     info: Buscar tickets por identificador o alias
diff --git a/src/pages/Order/Card/CatalogFilterValueDialog.vue b/src/pages/Order/Card/CatalogFilterValueDialog.vue
index d1bd48c9e90..b91e7d229bf 100644
--- a/src/pages/Order/Card/CatalogFilterValueDialog.vue
+++ b/src/pages/Order/Card/CatalogFilterValueDialog.vue
@@ -110,7 +110,7 @@ const getSelectedTagValues = async (tag) => {
             </div>
             <QBtn
                 icon="add_circle"
-                v-shortcut="'+'"
+                shortcut="+"
                 flat
                 class="filter-icon q-mb-md"
                 size="md"
diff --git a/src/pages/Order/Card/OrderBasicData.vue b/src/pages/Order/Card/OrderBasicData.vue
index 9c02d7494b5..8594a05f459 100644
--- a/src/pages/Order/Card/OrderBasicData.vue
+++ b/src/pages/Order/Card/OrderBasicData.vue
@@ -14,6 +14,7 @@ import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 const { t } = useI18n();
 const route = useRoute();
 const state = useState();
+const ORDER_MODEL = 'order';
 
 const isNew = Boolean(!route.params.id);
 const clientList = ref([]);
@@ -31,7 +32,7 @@ const fetchAddressList = async (addressId) => {
     });
     addressList.value = data;
     if (addressList.value?.length === 1) {
-        state.get('Order').addressFk = addressList.value[0].id;
+        state.get(ORDER_MODEL).addressFk = addressList.value[0].id;
     }
 };
 
@@ -90,8 +91,9 @@ const onClientChange = async (clientId) => {
     <VnSubToolbar v-if="isNew" />
     <div class="q-pa-md">
         <FormModel
+            :url="`Orders/${route.params.id}`"
             :url-update="`Orders/${route.params.id}/updateBasicData`"
-            model="Order"
+            :model="ORDER_MODEL"
             :filter="orderFilter"
             @on-fetch="fetchOrderDetails"
             auto-load
diff --git a/src/pages/Order/Card/OrderCard.vue b/src/pages/Order/Card/OrderCard.vue
index ad5c73a878c..823815f59b9 100644
--- a/src/pages/Order/Card/OrderCard.vue
+++ b/src/pages/Order/Card/OrderCard.vue
@@ -1,14 +1,12 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
-import filter from './OrderFilter.js';
 </script>
 
 <template>
     <VnCardBeta
         data-key="Order"
-        url="Orders"
-        :filter="filter"
+        base-url="Orders"
         :descriptor="OrderDescriptor"
     />
 </template>
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index 76e60898343..262f503fd11 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -184,7 +184,7 @@ function addOrder(value, field, params) {
                         {{
                             t(
                                 categoryList.find((c) => c.id == customTag.value)?.name ||
-                                    '',
+                                    ''
                             )
                         }}
                     </strong>
@@ -296,7 +296,7 @@ function addOrder(value, field, params) {
                     <template #append>
                         <QBtn
                             icon="add_circle"
-                            v-shortcut="'+'"
+                            shortcut="+"
                             flat
                             color="primary"
                             size="md"
diff --git a/src/pages/Order/Card/OrderCatalogItemDialog.vue b/src/pages/Order/Card/OrderCatalogItemDialog.vue
index 766945e4ddf..77f6a840548 100644
--- a/src/pages/Order/Card/OrderCatalogItemDialog.vue
+++ b/src/pages/Order/Card/OrderCatalogItemDialog.vue
@@ -20,7 +20,7 @@ const props = defineProps({
 });
 const state = useState();
 
-const orderData = computed(() => state.get('Order'));
+const orderData = computed(() => state.get('orderData'));
 
 const prices = ref((props.item.prices || []).map((item) => ({ ...item, quantity: 0 })));
 const isLoading = ref(false);
@@ -39,11 +39,11 @@ const addToOrder = async () => {
     });
 
     const { data: orderTotal } = await axios.get(
-        `Orders/${Number(route.params.id)}/getTotal`,
+        `Orders/${Number(route.params.id)}/getTotal`
     );
 
     state.set('orderTotal', orderTotal);
-    state.set('Order', {
+    state.set('orderData', {
         ...orderData.value,
         items,
     });
@@ -56,7 +56,7 @@ const canAddToOrder = () => {
     if (canAddToOrder) {
         const excedQuantity = prices.value.reduce(
             (acc, { quantity }) => acc + quantity,
-            0,
+            0
         );
         if (excedQuantity > props.item.available) {
             canAddToOrder = false;
diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue
index 0d18864dc86..0d5f0146f7b 100644
--- a/src/pages/Order/Card/OrderDescriptor.vue
+++ b/src/pages/Order/Card/OrderDescriptor.vue
@@ -4,7 +4,8 @@ import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { toCurrency, toDate } from 'src/filters';
 import { useState } from 'src/composables/useState';
-import filter from './OrderFilter.js';
+import useCardDescription from 'src/composables/useCardDescription';
+
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import FetchData from 'components/FetchData.vue';
@@ -23,15 +24,44 @@ const $props = defineProps({
 const route = useRoute();
 const state = useState();
 const { t } = useI18n();
+const data = ref(useCardDescription());
 const getTotalRef = ref();
 
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
 
+const filter = {
+    include: [
+        { relation: 'agencyMode', scope: { fields: ['name'] } },
+        {
+            relation: 'address',
+            scope: { fields: ['nickname'] },
+        },
+        { relation: 'rows', scope: { fields: ['id'] } },
+        {
+            relation: 'client',
+            scope: {
+                fields: [
+                    'salesPersonFk',
+                    'name',
+                    'isActive',
+                    'isFreezed',
+                    'isTaxDataChecked',
+                ],
+                include: {
+                    relation: 'salesPersonUser',
+                    scope: { fields: ['id', 'name'] },
+                },
+            },
+        },
+    ],
+};
+
 const setData = (entity) => {
     if (!entity) return;
     getTotalRef.value && getTotalRef.value.fetch();
+    data.value = useCardDescription(entity?.client?.name, entity?.id);
     state.set('orderTotal', total);
 };
 
@@ -57,9 +87,11 @@ const total = ref(0);
         ref="descriptor"
         :url="`Orders/${entityId}`"
         :filter="filter"
-        title="client.name"
+        module="Order"
+        :title="data.title"
+        :subtitle="data.subtitle"
         @on-fetch="setData"
-        data-key="Order"
+        data-key="orderData"
     >
         <template #body="{ entity }">
             <VnLv
diff --git a/src/pages/Order/Card/OrderFilter.js b/src/pages/Order/Card/OrderFilter.js
deleted file mode 100644
index 3e521b92c48..00000000000
--- a/src/pages/Order/Card/OrderFilter.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default {
-    include: [
-        { relation: 'agencyMode', scope: { fields: ['name'] } },
-        {
-            relation: 'address',
-            scope: { fields: ['nickname'] },
-        },
-        { relation: 'rows', scope: { fields: ['id'] } },
-        {
-            relation: 'client',
-            scope: {
-                fields: [
-                    'salesPersonFk',
-                    'name',
-                    'isActive',
-                    'isFreezed',
-                    'isTaxDataChecked',
-                ],
-                include: {
-                    relation: 'salesPersonUser',
-                    scope: { fields: ['id', 'name'] },
-                },
-            },
-        },
-    ],
-};
diff --git a/src/pages/Order/Card/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue
index 1b864de6f88..cf219a244f8 100644
--- a/src/pages/Order/Card/OrderLines.vue
+++ b/src/pages/Order/Card/OrderLines.vue
@@ -21,7 +21,7 @@ const router = useRouter();
 const route = useRoute();
 const { t } = useI18n();
 const quasar = useQuasar();
-const descriptorData = useArrayData('Order');
+const descriptorData = useArrayData('orderData');
 const componentKey = ref(0);
 const tableLinesRef = ref();
 const order = ref();
@@ -238,7 +238,7 @@ watch(
         lineFilter.value.where.orderFk = router.currentRoute.value.params.id;
 
         tableLinesRef.value.reload();
-    },
+    }
 );
 </script>
 
diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue
index a4bdb288102..a289688e47e 100644
--- a/src/pages/Order/Card/OrderSummary.vue
+++ b/src/pages/Order/Card/OrderSummary.vue
@@ -27,7 +27,7 @@ const $props = defineProps({
 const entityId = computed(() => $props.id || route.params.id);
 const summary = ref();
 const quasar = useQuasar();
-const descriptorData = useArrayData('Order');
+const descriptorData = useArrayData('orderData');
 const detailsColumns = ref([
     {
         name: 'item',
diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue
index 40990f32906..21cb5ed7e99 100644
--- a/src/pages/Order/OrderList.vue
+++ b/src/pages/Order/OrderList.vue
@@ -71,9 +71,8 @@ const columns = computed(() => [
         format: (row) => row?.name,
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'isConfirmed',
-        component: 'checkbox',
         label: t('module.isConfirmed'),
     },
     {
@@ -96,9 +95,7 @@ const columns = computed(() => [
         columnField: {
             component: null,
         },
-        style: () => {
-            return { color: 'positive' };
-        },
+        style: 'color="positive"',
     },
     {
         align: 'left',
diff --git a/src/pages/Shelving/Parking/Card/ParkingBasicData.vue b/src/pages/Parking/Card/ParkingBasicData.vue
similarity index 68%
rename from src/pages/Shelving/Parking/Card/ParkingBasicData.vue
rename to src/pages/Parking/Card/ParkingBasicData.vue
index 3de35800218..550a0684e81 100644
--- a/src/pages/Shelving/Parking/Card/ParkingBasicData.vue
+++ b/src/pages/Parking/Card/ParkingBasicData.vue
@@ -1,11 +1,16 @@
 <script setup>
-import { ref } from 'vue';
+import { ref, computed } from 'vue';
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 import VnRow from 'components/ui/VnRow.vue';
 import FetchData from 'src/components/FetchData.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import FormModel from 'components/FormModel.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 
+const { t } = useI18n();
+const route = useRoute();
+const parkingId = computed(() => route.params?.id || null);
 const sectors = ref([]);
 const sectorFilter = { fields: ['id', 'description'] };
 
@@ -22,21 +27,18 @@ const filter = {
         @on-fetch="(data) => (sectors = data)"
         auto-load
     />
-    <FormModel model="Parking" auto-load>
+    <FormModel :url="`Parkings/${parkingId}`" model="parking" :filter="filter" auto-load>
         <template #form="{ data }">
             <VnRow>
-                <VnInput v-model="data.code" :label="$t('globals.code')" />
-                <VnInput
-                    v-model="data.pickingOrder"
-                    :label="$t('parking.pickingOrder')"
-                />
+                <VnInput v-model="data.code" :label="t('globals.code')" />
+                <VnInput v-model="data.pickingOrder" :label="t('parking.pickingOrder')" />
             </VnRow>
             <VnRow>
                 <VnSelect
                     v-model="data.sectorFk"
                     option-value="id"
                     option-label="description"
-                    :label="$t('parking.sector')"
+                    :label="t('parking.sector')"
                     :options="sectors"
                     use-input
                     input-debounce="0"
diff --git a/src/pages/Shelving/Parking/Card/ParkingCard.vue b/src/pages/Parking/Card/ParkingCard.vue
similarity index 53%
rename from src/pages/Shelving/Parking/Card/ParkingCard.vue
rename to src/pages/Parking/Card/ParkingCard.vue
index b32c1b7d335..1cd2df7b743 100644
--- a/src/pages/Shelving/Parking/Card/ParkingCard.vue
+++ b/src/pages/Parking/Card/ParkingCard.vue
@@ -1,14 +1,12 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
-import ParkingDescriptor from 'pages/Shelving/Parking/Card/ParkingDescriptor.vue';
-import filter from './ParkingFilter.js';
+import ParkingDescriptor from 'pages/Parking/Card/ParkingDescriptor.vue';
 </script>
 
 <template>
     <VnCardBeta
         data-key="Parking"
-        url="Parkings"
-        :filter="filter"
+        base-url="Parkings"
         :descriptor="ParkingDescriptor"
     />
 </template>
diff --git a/src/pages/Shelving/Parking/Card/ParkingDescriptor.vue b/src/pages/Parking/Card/ParkingDescriptor.vue
similarity index 58%
rename from src/pages/Shelving/Parking/Card/ParkingDescriptor.vue
rename to src/pages/Parking/Card/ParkingDescriptor.vue
index 46c9f8ea0a8..d36ea16fc22 100644
--- a/src/pages/Shelving/Parking/Card/ParkingDescriptor.vue
+++ b/src/pages/Parking/Card/ParkingDescriptor.vue
@@ -1,9 +1,10 @@
 <script setup>
 import { computed } from 'vue';
+import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'components/ui/VnLv.vue';
-import filter from './ParkingFilter.js';
+
 const props = defineProps({
     id: {
         type: Number,
@@ -12,11 +13,18 @@ const props = defineProps({
     },
 });
 
+const { t } = useI18n();
 const route = useRoute();
 const entityId = computed(() => props.id || route.params.id);
+
+const filter = {
+    fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'],
+    include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }],
+};
 </script>
 <template>
     <CardDescriptor
+        module="Parking"
         data-key="Parking"
         :url="`Parkings/${entityId}`"
         title="code"
@@ -24,9 +32,9 @@ const entityId = computed(() => props.id || route.params.id);
         :to-module="{ name: 'ParkingList' }"
     >
         <template #body="{ entity }">
-            <VnLv :label="$t('globals.code')" :value="entity.code" />
-            <VnLv :label="$t('parking.pickingOrder')" :value="entity.pickingOrder" />
-            <VnLv :label="$t('parking.sector')" :value="entity.sector?.description" />
+            <VnLv :label="t('globals.code')" :value="entity.code" />
+            <VnLv :label="t('parking.pickingOrder')" :value="entity.pickingOrder" />
+            <VnLv :label="t('parking.sector')" :value="entity.sector?.description" />
         </template>
     </CardDescriptor>
 </template>
diff --git a/src/pages/Shelving/Parking/Card/ParkingLog.vue b/src/pages/Parking/Card/ParkingLog.vue
similarity index 100%
rename from src/pages/Shelving/Parking/Card/ParkingLog.vue
rename to src/pages/Parking/Card/ParkingLog.vue
diff --git a/src/pages/Shelving/Parking/Card/ParkingSummary.vue b/src/pages/Parking/Card/ParkingSummary.vue
similarity index 100%
rename from src/pages/Shelving/Parking/Card/ParkingSummary.vue
rename to src/pages/Parking/Card/ParkingSummary.vue
diff --git a/src/pages/Shelving/Parking/ParkingFilter.vue b/src/pages/Parking/ParkingFilter.vue
similarity index 100%
rename from src/pages/Shelving/Parking/ParkingFilter.vue
rename to src/pages/Parking/ParkingFilter.vue
diff --git a/src/pages/Shelving/Parking/ParkingList.vue b/src/pages/Parking/ParkingList.vue
similarity index 90%
rename from src/pages/Shelving/Parking/ParkingList.vue
rename to src/pages/Parking/ParkingList.vue
index fe6c93ba538..bce87126ead 100644
--- a/src/pages/Shelving/Parking/ParkingList.vue
+++ b/src/pages/Parking/ParkingList.vue
@@ -9,7 +9,6 @@ import CardList from 'components/ui/CardList.vue';
 import VnLv from 'components/ui/VnLv.vue';
 import ParkingFilter from './ParkingFilter.vue';
 import ParkingSummary from './Card/ParkingSummary.vue';
-import exprBuilder from './ParkingExprBuilder.js';
 import VnSection from 'src/components/common/VnSection.vue';
 
 const stateStore = useStateStore();
@@ -24,7 +23,19 @@ onUnmounted(() => (stateStore.rightDrawer = false));
 const filter = {
     fields: ['id', 'sectorFk', 'code', 'pickingOrder'],
 };
+
+function exprBuilder(param, value) {
+    switch (param) {
+        case 'code':
+            return { [param]: { like: `%${value}%` } };
+        case 'sectorFk':
+            return { [param]: value };
+        case 'search':
+            return { or: [{ code: { like: `%${value}%` } }, { id: value }] };
+    }
+}
 </script>
+
 <template>
     <VnSection
         :data-key="dataKey"
diff --git a/src/pages/Shelving/Parking/locale/en.yml b/src/pages/Parking/locale/en.yml
similarity index 100%
rename from src/pages/Shelving/Parking/locale/en.yml
rename to src/pages/Parking/locale/en.yml
diff --git a/src/pages/Shelving/Parking/locale/es.yml b/src/pages/Parking/locale/es.yml
similarity index 100%
rename from src/pages/Shelving/Parking/locale/es.yml
rename to src/pages/Parking/locale/es.yml
diff --git a/src/pages/Route/Agency/AgencyList.vue b/src/pages/Route/Agency/AgencyList.vue
index 5c2904bf3a4..4322b9bc808 100644
--- a/src/pages/Route/Agency/AgencyList.vue
+++ b/src/pages/Route/Agency/AgencyList.vue
@@ -51,6 +51,7 @@ const columns = computed(() => [
         name: 'isAnyVolumeAllowed',
         component: 'checkbox',
         cardVisible: true,
+        disable: true,
     },
     {
         align: 'right',
@@ -71,7 +72,7 @@ const columns = computed(() => [
         :data-key
         :columns="columns"
         prefix="agency"
-        :right-filter="true"
+        :right-filter="false"
         :array-data-props="{
             url: 'Agencies',
             order: 'name',
@@ -82,7 +83,6 @@ const columns = computed(() => [
             <VnTable
                 :data-key
                 :columns="columns"
-                is-editable="false"
                 :right-search="false"
                 :use-model="true"
                 redirect="route/agency"
diff --git a/src/pages/Route/Agency/Card/AgencyBasicData.vue b/src/pages/Route/Agency/Card/AgencyBasicData.vue
index 4270b136c44..599058b3e21 100644
--- a/src/pages/Route/Agency/Card/AgencyBasicData.vue
+++ b/src/pages/Route/Agency/Card/AgencyBasicData.vue
@@ -21,7 +21,7 @@ const warehouses = ref([]);
         @on-fetch="(data) => (warehouses = data)"
         auto-load
     />
-    <FormModel :update-url="`Agencies/${routeId}`" model="Agency" auto-load>
+    <FormModel :url="`Agencies/${routeId}`" model="agency" auto-load>
         <template #form="{ data }">
             <VnRow>
                 <VnInput v-model="data.name" :label="t('globals.name')" />
diff --git a/src/pages/Route/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue
index 7dc31f8ba35..35685790a60 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 VnCardBeta from 'src/components/common/VnCardBeta.vue';
 </script>
 <template>
-    <VnCardBeta data-key="Agency" url="Agencies" :descriptor="AgencyDescriptor" />
+    <VnCardBeta data-key="Agency" base-url="Agencies" :descriptor="AgencyDescriptor" />
 </template>
diff --git a/src/pages/Route/Agency/Card/AgencyDescriptor.vue b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
index a0472c6c3c8..b9772037c76 100644
--- a/src/pages/Route/Agency/Card/AgencyDescriptor.vue
+++ b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
@@ -22,6 +22,7 @@ const card = computed(() => store.data);
 </script>
 <template>
     <CardDescriptor
+        module="Agency"
         data-key="Agency"
         :url="`Agencies/${entityId}`"
         :title="card?.name"
diff --git a/src/pages/Route/Agency/Card/AgencyWorkcenter.vue b/src/pages/Route/Agency/Card/AgencyWorkcenter.vue
index 9a921386877..7cabf396d0e 100644
--- a/src/pages/Route/Agency/Card/AgencyWorkcenter.vue
+++ b/src/pages/Route/Agency/Card/AgencyWorkcenter.vue
@@ -88,7 +88,7 @@ async function deleteWorCenter(id) {
         </VnPaginate>
     </div>
     <QPageSticky :offset="[18, 18]">
-        <QBtn @click.stop="dialog.show()" color="primary" fab v-shortcut="'+'" icon="add">
+        <QBtn @click.stop="dialog.show()" color="primary" fab shortcut="+" icon="add">
             <QDialog ref="dialog">
                 <FormModelPopup
                     :title="t('Add work center')"
diff --git a/src/pages/Route/Card/RouteCard.vue b/src/pages/Route/Card/RouteCard.vue
index c178dc6bf34..81b6cfa169a 100644
--- a/src/pages/Route/Card/RouteCard.vue
+++ b/src/pages/Route/Card/RouteCard.vue
@@ -1,13 +1,12 @@
 <script setup>
 import RouteDescriptor from 'pages/Route/Card/RouteDescriptor.vue';
 import VnCardBeta from 'src/components/common/VnCardBeta.vue';
-import filter from './RouteFilter.js';
 </script>
 <template>
     <VnCardBeta
         data-key="Route"
-        url="Routes"
-        :filter="filter"
+        base-url="Routes"
+        custom-url="Routes/filter"
         :descriptor="RouteDescriptor"
     />
 </template>
diff --git a/src/pages/Route/Card/RouteDescriptor.vue b/src/pages/Route/Card/RouteDescriptor.vue
index 503cd1941f4..68c08b8210e 100644
--- a/src/pages/Route/Card/RouteDescriptor.vue
+++ b/src/pages/Route/Card/RouteDescriptor.vue
@@ -1,14 +1,13 @@
 <script setup>
 import { ref, computed, onMounted } from 'vue';
 import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'components/ui/VnLv.vue';
+import useCardDescription from 'composables/useCardDescription';
 import { dashIfEmpty, toDate } from 'src/filters';
 import RouteDescriptorMenu from 'pages/Route/Card/RouteDescriptorMenu.vue';
-import filter from './RouteFilter.js';
-import useCardDescription from 'src/composables/useCardDescription';
 import axios from 'axios';
-
 const $props = defineProps({
     id: {
         type: Number,
@@ -18,6 +17,7 @@ const $props = defineProps({
 });
 
 const route = useRoute();
+const { t } = useI18n();
 const zone = ref();
 const zoneId = ref();
 const entityId = computed(() => {
@@ -36,31 +36,81 @@ const getZone = async () => {
     const { data: zoneData } = await axios.get(`Zones/${zoneId.value}`);
     zone.value = zoneData.name;
 };
+
+const filter = {
+    fields: [
+        'id',
+        'workerFk',
+        'agencyModeFk',
+        'dated',
+        'm3',
+        'warehouseFk',
+        'description',
+        'vehicleFk',
+        'kmStart',
+        'kmEnd',
+        'started',
+        'finished',
+        'cost',
+        'isOk',
+    ],
+    include: [
+        { relation: 'agencyMode', scope: { fields: ['id', 'name'] } },
+        {
+            relation: 'vehicle',
+            scope: { fields: ['id', 'm3'] },
+        },
+        {
+            relation: 'ticket',
+            scope: {
+                fields: ['id', 'name', 'zoneFk'],
+                include: { relation: 'zone', scope: { fields: ['id', 'name'] } },
+            },
+        },
+        {
+            relation: 'worker',
+            scope: {
+                fields: ['id'],
+                include: {
+                    relation: 'user',
+                    scope: {
+                        fields: ['id'],
+                        include: { relation: 'emailUser', scope: { fields: ['email'] } },
+                    },
+                },
+            },
+        },
+    ],
+};
 const data = ref(useCardDescription());
 const setData = (entity) => (data.value = useCardDescription(entity.code, entity.id));
 onMounted(async () => {
     getZone();
 });
 </script>
+
 <template>
     <CardDescriptor
+        module="Route"
         :url="`Routes/${entityId}`"
         :filter="filter"
-        :title="null"
-        data-key="Route"
+        :title="data.title"
+        :subtitle="data.subtitle"
+        data-key="routeData"
+        @on-fetch="setData"
         width="lg-width"
     >
         <template #body="{ entity }">
-            <VnLv :label="$t('Date')" :value="toDate(entity?.dated)" />
-            <VnLv :label="$t('Agency')" :value="entity?.agencyMode?.name" />
-            <VnLv :label="$t('Zone')" :value="zone" />
+            <VnLv :label="t('Date')" :value="toDate(entity?.dated)" />
+            <VnLv :label="t('Agency')" :value="entity?.agencyMode?.name" />
+            <VnLv :label="t('Zone')" :value="zone" />
             <VnLv
-                :label="$t('Volume')"
+                :label="t('Volume')"
                 :value="`${dashIfEmpty(entity?.m3)} / ${dashIfEmpty(
                     entity?.vehicle?.m3,
                 )} m³`"
             />
-            <VnLv :label="$t('Description')" :value="entity?.description" />
+            <VnLv :label="t('Description')" :value="entity?.description" />
         </template>
         <template #menu="{ entity }">
             <RouteDescriptorMenu :route="entity" />
diff --git a/src/pages/Route/Card/RouteFilter.js b/src/pages/Route/Card/RouteFilter.js
deleted file mode 100644
index 90ee71bf77c..00000000000
--- a/src/pages/Route/Card/RouteFilter.js
+++ /dev/null
@@ -1,39 +0,0 @@
-export default {
-    fields: [
-        'code',
-        'id',
-        'workerFk',
-        'agencyModeFk',
-        'created',
-        'm3',
-        'warehouseFk',
-        'description',
-        'vehicleFk',
-        'kmStart',
-        'kmEnd',
-        'started',
-        'finished',
-        'cost',
-        'isOk',
-    ],
-    include: [
-        { relation: 'agencyMode', scope: { fields: ['id', 'name'] } },
-        {
-            relation: 'vehicle',
-            scope: { fields: ['id', 'm3'] },
-        },
-        {
-            relation: 'worker',
-            scope: {
-                fields: ['id'],
-                include: {
-                    relation: 'user',
-                    scope: {
-                        fields: ['id'],
-                        include: { relation: 'emailUser', scope: { fields: ['email'] } },
-                    },
-                },
-            },
-        },
-    ],
-};
diff --git a/src/pages/Route/Card/RouteFilter.vue b/src/pages/Route/Card/RouteFilter.vue
index 21858102be2..72bfed1da7e 100644
--- a/src/pages/Route/Card/RouteFilter.vue
+++ b/src/pages/Route/Card/RouteFilter.vue
@@ -100,7 +100,7 @@ const emit = defineEmits(['search']);
                     <VnSelect
                         :label="t('Vehicle')"
                         v-model="params.vehicleFk"
-                        url="Vehicles/active"
+                        url="Vehicles"
                         sort-by="numberPlate ASC"
                         option-value="id"
                         option-label="numberPlate"
diff --git a/src/pages/Route/Card/RouteForm.vue b/src/pages/Route/Card/RouteForm.vue
index 667204b15ac..633ff44bcb0 100644
--- a/src/pages/Route/Card/RouteForm.vue
+++ b/src/pages/Route/Card/RouteForm.vue
@@ -11,7 +11,6 @@ import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInput from 'components/common/VnInput.vue';
 import axios from 'axios';
 import VnInputTime from 'components/common/VnInputTime.vue';
-import filter from './RouteFilter.js';
 import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
@@ -28,6 +27,52 @@ const defaultInitialData = {
     isOk: false,
 };
 const maxDistance = ref();
+
+const routeFilter = {
+    fields: [
+        'id',
+        'workerFk',
+        'agencyModeFk',
+        'dated',
+        'm3',
+        'warehouseFk',
+        'description',
+        'vehicleFk',
+        'kmStart',
+        'kmEnd',
+        'started',
+        'finished',
+        'cost',
+        'isOk',
+    ],
+    include: [
+        { relation: 'agencyMode', scope: { fields: ['id', 'name'] } },
+        {
+            relation: 'vehicle',
+            scope: { fields: ['id', 'm3'] },
+        },
+        {
+            relation: 'ticket',
+            scope: {
+                fields: ['id', 'name', 'zoneFk'],
+                include: { relation: 'zone', scope: { fields: ['id', 'name'] } },
+            },
+        },
+        {
+            relation: 'worker',
+            scope: {
+                fields: ['id'],
+                include: {
+                    relation: 'user',
+                    scope: {
+                        fields: ['id'],
+                        include: { relation: 'emailUser', scope: { fields: ['email'] } },
+                    },
+                },
+            },
+        },
+    ],
+};
 const onSave = (data, response) => {
     if (isNew) {
         axios.post(`Routes/${response?.id}/updateWorkCenter`);
@@ -44,10 +89,11 @@ const onSave = (data, response) => {
         sort-by="id ASC"
     />
     <FormModel
+        :url="isNew ? null : `Routes/${route.params?.id}`"
         :url-create="isNew ? 'Routes' : null"
         :observe-form-changes="!isNew"
-        :filter="filter"
-        model="Route"
+        :filter="routeFilter"
+        model="route"
         :auto-load="!isNew"
         :form-initial-data="isNew ? defaultInitialData : null"
         @on-data-saved="onSave"
@@ -58,7 +104,7 @@ const onSave = (data, response) => {
                 <VnSelect
                     :label="t('Vehicle')"
                     v-model="data.vehicleFk"
-                    url="Vehicles/active"
+                    url="Vehicles"
                     sort-by="numberPlate ASC"
                     option-value="id"
                     option-label="numberPlate"
diff --git a/src/pages/Route/Roadmap/RoadmapBasicData.vue b/src/pages/Route/Roadmap/RoadmapBasicData.vue
index a9e6059c337..2fe80536294 100644
--- a/src/pages/Route/Roadmap/RoadmapBasicData.vue
+++ b/src/pages/Route/Roadmap/RoadmapBasicData.vue
@@ -11,16 +11,17 @@ import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
 const { t } = useI18n();
 const router = useRouter();
 
+const filter = { include: [{ relation: 'supplier' }] };
 const onSave = (data, response) => {
     router.push({ name: 'RoadmapSummary', params: { id: response?.id } });
 };
 </script>
 <template>
     <FormModel
-        :update-url="`Roadmaps/${$route.params?.id}`"
         :url="`Roadmaps/${$route.params?.id}`"
         observe-form-changes
-        model="Roadmap"
+        :filter="filter"
+        model="roadmap"
         auto-load
         @on-data-saved="onSave"
     >
diff --git a/src/pages/Route/Roadmap/RoadmapCard.vue b/src/pages/Route/Roadmap/RoadmapCard.vue
index 48ba516a114..0b81de6737d 100644
--- a/src/pages/Route/Roadmap/RoadmapCard.vue
+++ b/src/pages/Route/Roadmap/RoadmapCard.vue
@@ -3,5 +3,5 @@ import VnCardBeta from 'components/common/VnCardBeta.vue';
 import RoadmapDescriptor from 'pages/Route/Roadmap/RoadmapDescriptor.vue';
 </script>
 <template>
-    <VnCardBeta data-key="Roadmap" url="Roadmaps" :descriptor="RoadmapDescriptor" />
+    <VnCardBeta data-key="Roadmap" base-url="Roadmaps" :descriptor="RoadmapDescriptor" />
 </template>
diff --git a/src/pages/Route/Roadmap/RoadmapDescriptor.vue b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
index baa864a150f..788173688cb 100644
--- a/src/pages/Route/Roadmap/RoadmapDescriptor.vue
+++ b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
@@ -1,13 +1,13 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'components/ui/VnLv.vue';
+import useCardDescription from 'composables/useCardDescription';
 import { dashIfEmpty, toDateHourMin } from 'src/filters';
 import SupplierDescriptorProxy from 'pages/Supplier/Card/SupplierDescriptorProxy.vue';
 import RoadmapDescriptorMenu from 'pages/Route/Roadmap/RoadmapDescriptorMenu.vue';
-import filter from 'pages/Route/Roadmap/RoadmapFilter.js';
 
 const $props = defineProps({
     id: {
@@ -23,10 +23,22 @@ const { t } = useI18n();
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+
+const filter = { include: [{ relation: 'supplier' }] };
+const data = ref(useCardDescription());
+const setData = (entity) => (data.value = useCardDescription(entity.code, entity.id));
 </script>
 
 <template>
-    <CardDescriptor :url="`Roadmaps/${entityId}`" :filter="filter" data-key="Roadmap">
+    <CardDescriptor
+        module="Roadmap"
+        :url="`Roadmaps/${entityId}`"
+        :filter="filter"
+        :title="data.title"
+        :subtitle="data.subtitle"
+        data-key="Roadmap"
+        @on-fetch="setData"
+    >
         <template #body="{ entity }">
             <VnLv :label="t('Roadmap')" :value="entity?.name" />
             <VnLv :label="t('ETD')" :value="toDateHourMin(entity?.etd)" />
diff --git a/src/pages/Route/Roadmap/RoadmapFilter.js b/src/pages/Route/Roadmap/RoadmapFilter.js
deleted file mode 100644
index 0ae890363ae..00000000000
--- a/src/pages/Route/Roadmap/RoadmapFilter.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default {
-    include: [{ relation: 'supplier' }],
-};
diff --git a/src/pages/Route/Roadmap/RoadmapStops.vue b/src/pages/Route/Roadmap/RoadmapStops.vue
index e4085d57295..d8215ea4984 100644
--- a/src/pages/Route/Roadmap/RoadmapStops.vue
+++ b/src/pages/Route/Roadmap/RoadmapStops.vue
@@ -68,7 +68,7 @@ const updateDefaultStop = (data) => {
                         <QBtn
                             flat
                             icon="add"
-                            v-shortcut="'+'"
+                            shortcut="+"
                             class="cursor-pointer"
                             color="primary"
                             @click="roadmapStopsCrudRef.insert()"
diff --git a/src/pages/Route/Roadmap/RoadmapSummary.vue b/src/pages/Route/Roadmap/RoadmapSummary.vue
index 0c1c2b90398..1fbb1897d5b 100644
--- a/src/pages/Route/Roadmap/RoadmapSummary.vue
+++ b/src/pages/Route/Roadmap/RoadmapSummary.vue
@@ -67,6 +67,7 @@ const filter = {
             },
         },
     ],
+    where: { id: entityId },
 };
 </script>
 
@@ -75,7 +76,7 @@ const filter = {
         <CardSummary
             data-key="RoadmapSummary"
             ref="summary"
-            :url="`Roadmaps/${entityId}`"
+            :url="`Roadmaps`"
             :filter="filter"
         >
             <template #header-left>
diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue
index 46bc1a69080..221fc47545a 100644
--- a/src/pages/Route/RouteExtendedList.vue
+++ b/src/pages/Route/RouteExtendedList.vue
@@ -3,7 +3,7 @@ import { computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import { useQuasar } from 'quasar';
-import { dashIfEmpty, toDate, toHour } from 'src/filters';
+import { toDate } from 'src/filters';
 import { useRouter } from 'vue-router';
 import { usePrintService } from 'src/composables/usePrintService';
 
@@ -38,7 +38,7 @@ const routeFilter = {
 };
 const columns = computed(() => [
     {
-        align: 'center',
+        align: 'left',
         name: 'id',
         label: 'Id',
         chip: {
@@ -48,7 +48,7 @@ const columns = computed(() => [
         columnFilter: false,
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'workerFk',
         label: t('route.Worker'),
         create: true,
@@ -68,10 +68,10 @@ const columns = computed(() => [
         },
         useLike: false,
         cardVisible: true,
-        format: (row, dashIfEmpty) => dashIfEmpty(row.workerUserName),
+        format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'agencyModeFk',
         label: t('route.Agency'),
         isTitle: true,
@@ -87,17 +87,17 @@ const columns = computed(() => [
             },
         },
         columnClass: 'expand',
-        format: (row, dashIfEmpty) => dashIfEmpty(row.agencyName),
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'vehicleFk',
         label: t('route.Vehicle'),
         cardVisible: true,
         create: true,
         component: 'select',
         attrs: {
-            url: 'vehicles/active',
+            url: 'vehicles',
+            fields: ['id', 'numberPlate'],
             optionLabel: 'numberPlate',
             optionFilterValue: 'numberPlate',
             find: {
@@ -108,31 +108,29 @@ const columns = computed(() => [
         columnFilter: {
             inWhere: true,
         },
-        format: (row, dashIfEmpty) => dashIfEmpty(row.vehiclePlateNumber),
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'dated',
         label: t('route.Date'),
         columnFilter: false,
         cardVisible: true,
         create: true,
         component: 'date',
-        format: ({ dated }, dashIfEmpty) =>
-            dated === '0000-00-00' ? dashIfEmpty(null) : toDate(dated),
+        format: ({ date }) => toDate(date),
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'from',
         label: t('route.From'),
         visible: false,
         cardVisible: true,
         create: true,
         component: 'date',
-        format: ({ from }) => toDate(from),
+        format: ({ date }) => toDate(date),
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'to',
         label: t('route.To'),
         visible: false,
@@ -149,20 +147,18 @@ const columns = computed(() => [
         columnClass: 'shrink',
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'started',
         label: t('route.hourStarted'),
         component: 'time',
         columnFilter: false,
-        format: ({ started }) => toHour(started),
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'finished',
         label: t('route.hourFinished'),
         component: 'time',
         columnFilter: false,
-        format: ({ finished }) => toHour(finished),
     },
     {
         align: 'center',
@@ -181,7 +177,7 @@ const columns = computed(() => [
         visible: false,
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'description',
         label: t('route.Description'),
         isTitle: true,
@@ -190,7 +186,7 @@ const columns = computed(() => [
         field: 'description',
     },
     {
-        align: 'center',
+        align: 'left',
         name: 'isOk',
         label: t('route.Served'),
         component: 'checkbox',
@@ -304,62 +300,60 @@ const openTicketsDialog = (id) => {
             <RouteFilter data-key="RouteList" />
         </template>
     </RightMenu>
-    <QPage class="q-px-md">
-        <VnTable
-            class="route-list"
-            ref="tableRef"
-            data-key="RouteList"
-            url="Routes/filter"
-            :columns="columns"
-            :right-search="false"
-            :is-editable="true"
-            :filter="routeFilter"
-            redirect="route"
-            :row-click="false"
-            :create="{
-                urlCreate: 'Routes',
-                title: t('route.createRoute'),
-                onDataSaved: ({ id }) => tableRef.redirect(id),
-                formInitialData: {},
-            }"
-            save-url="Routes/crud"
-            :disable-option="{ card: true }"
-            table-height="85vh"
-            v-model:selected="selectedRows"
-            :table="{
-                'row-key': 'id',
-                selection: 'multiple',
-            }"
-        >
-            <template #moreBeforeActions>
-                <QBtn
-                    icon="vn:clone"
-                    color="primary"
-                    class="q-mr-sm"
-                    :disable="!selectedRows?.length"
-                    @click="confirmationDialog = true"
-                >
-                    <QTooltip>{{ t('route.Clone Selected Routes') }}</QTooltip>
-                </QBtn>
-                <QBtn
-                    icon="cloud_download"
-                    color="primary"
-                    class="q-mr-sm"
-                    :disable="!selectedRows?.length"
-                    @click="showRouteReport"
-                >
-                    <QTooltip>{{ t('route.Download selected routes as PDF') }}</QTooltip>
-                </QBtn>
-                <QBtn
-                    icon="check"
-                    color="primary"
-                    class="q-mr-sm"
-                    :disable="!selectedRows?.length"
-                    @click="markAsServed()"
-                >
-                    <QTooltip>{{ t('route.Mark as served') }}</QTooltip>
-                </QBtn>
-            </template>
-        </VnTable>
-    </QPage>
+    <VnTable
+        class="route-list"
+        ref="tableRef"
+        data-key="RouteList"
+        url="Routes/filter"
+        :columns="columns"
+        :right-search="false"
+        :is-editable="true"
+        :filter="routeFilter"
+        redirect="route"
+        :row-click="false"
+        :create="{
+            urlCreate: 'Routes',
+            title: t('route.createRoute'),
+            onDataSaved: ({ id }) => tableRef.redirect(id),
+            formInitialData: {},
+        }"
+        save-url="Routes/crud"
+        :disable-option="{ card: true }"
+        table-height="85vh"
+        v-model:selected="selectedRows"
+        :table="{
+            'row-key': 'id',
+            selection: 'multiple',
+        }"
+    >
+        <template #moreBeforeActions>
+            <QBtn
+                icon="vn:clone"
+                color="primary"
+                class="q-mr-sm"
+                :disable="!selectedRows?.length"
+                @click="confirmationDialog = true"
+            >
+                <QTooltip>{{ t('route.Clone Selected Routes') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                icon="cloud_download"
+                color="primary"
+                class="q-mr-sm"
+                :disable="!selectedRows?.length"
+                @click="showRouteReport"
+            >
+                <QTooltip>{{ t('route.Download selected routes as PDF') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                icon="check"
+                color="primary"
+                class="q-mr-sm"
+                :disable="!selectedRows?.length"
+                @click="markAsServed()"
+            >
+                <QTooltip>{{ t('route.Mark as served') }}</QTooltip>
+            </QBtn>
+        </template>
+    </VnTable>
 </template>
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index 9dad8ba22b5..bc3227f6c86 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -38,17 +38,6 @@ const columns = computed(() => [
         align: 'left',
         name: 'workerFk',
         label: t('route.Worker'),
-        component: 'select',
-        attrs: {
-            url: 'Workers/activeWithInheritedRole',
-            fields: ['id', 'name'],
-            useLike: false,
-            optionFilter: 'firstName',
-            find: {
-                value: 'workerFk',
-                label: 'workerUserName',
-            },
-        },
         create: true,
         cardVisible: true,
         format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
@@ -59,15 +48,6 @@ const columns = computed(() => [
         name: 'agencyName',
         label: t('route.Agency'),
         cardVisible: true,
-        component: 'select',
-        attrs: {
-            url: 'agencyModes',
-            fields: ['id', 'name'],
-            find: {
-                value: 'agencyModeFk',
-                label: 'agencyName',
-            },
-        },
         create: true,
         columnClass: 'expand',
         columnFilter: false,
@@ -77,17 +57,6 @@ const columns = computed(() => [
         name: 'vehiclePlateNumber',
         label: t('route.Vehicle'),
         cardVisible: true,
-        component: 'select',
-        attrs: {
-            url: 'vehicles',
-            fields: ['id', 'numberPlate'],
-            optionLabel: 'numberPlate',
-            optionFilterValue: 'numberPlate',
-            find: {
-                value: 'vehicleFk',
-                label: 'vehiclePlateNumber',
-            },
-        },
         create: true,
         columnFilter: false,
     },
diff --git a/src/pages/Route/RouteTickets.vue b/src/pages/Route/RouteTickets.vue
index adc7dfdaaad..1416f77ce1e 100644
--- a/src/pages/Route/RouteTickets.vue
+++ b/src/pages/Route/RouteTickets.vue
@@ -120,8 +120,8 @@ const deletePriorities = async () => {
     try {
         await Promise.all(
             selectedRows.value.map((ticket) =>
-                axios.patch(`Tickets/${ticket?.id}/`, { priority: null }),
-            ),
+                axios.patch(`Tickets/${ticket?.id}/`, { priority: null })
+            )
         );
     } finally {
         refreshKey.value++;
@@ -132,8 +132,8 @@ const setOrderedPriority = async () => {
     try {
         await Promise.all(
             ticketList.value.map((ticket, index) =>
-                axios.patch(`Tickets/${ticket?.id}/`, { priority: index + 1 }),
-            ),
+                axios.patch(`Tickets/${ticket?.id}/`, { priority: index + 1 })
+            )
         );
     } finally {
         refreshKey.value++;
@@ -162,7 +162,7 @@ const setHighestPriority = async (ticket, ticketList) => {
 const goToBuscaman = async (ticket = null) => {
     await openBuscaman(
         routeEntity.value?.vehicleFk,
-        ticket ? [ticket] : selectedRows.value,
+        ticket ? [ticket] : selectedRows.value
     );
 };
 
@@ -393,13 +393,7 @@ const openSmsDialog = async () => {
             </VnPaginate>
         </div>
         <QPageSticky :offset="[20, 20]">
-            <QBtn
-                fab
-                icon="add"
-                v-shortcut="'+'"
-                color="primary"
-                @click="openTicketsDialog"
-            >
+            <QBtn fab icon="add" shortcut="+" color="primary" @click="openTicketsDialog">
                 <QTooltip>
                     {{ t('Add ticket') }}
                 </QTooltip>
diff --git a/src/pages/Route/Vehicle/Card/VehicleBasicData.vue b/src/pages/Route/Vehicle/Card/VehicleBasicData.vue
deleted file mode 100644
index e78bc6edd2c..00000000000
--- a/src/pages/Route/Vehicle/Card/VehicleBasicData.vue
+++ /dev/null
@@ -1,162 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-import FormModel from 'components/FormModel.vue';
-import FetchData from 'src/components/FetchData.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import VnRow from 'components/ui/VnRow.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import VnInputNumber from 'src/components/common/VnInputNumber.vue';
-
-const warehouses = ref([]);
-const companies = ref([]);
-const countries = ref([]);
-const fuelTypes = ref([]);
-const bankPolicies = ref([]);
-const deliveryPoints = ref([]);
-</script>
-<template>
-    <FetchData
-        url="Warehouses"
-        :filter="{ fields: ['id', 'name'] }"
-        @on-fetch="(data) => (warehouses = data)"
-        auto-load
-    />
-    <FetchData
-        url="Companies"
-        :filter="{ fields: ['id', 'code'] }"
-        @on-fetch="(data) => (companies = data)"
-        auto-load
-    />
-    <FetchData
-        url="Countries"
-        :filter="{ fields: ['code'] }"
-        @on-fetch="(data) => (countries = data)"
-        auto-load
-    />
-    <FetchData
-        url="FuelTypes"
-        :filter="{ fields: ['id', 'name'] }"
-        @on-fetch="(data) => (fuelTypes = data)"
-        auto-load
-    />
-    <FetchData
-        url="DeliveryPoints"
-        :filter="{ fields: ['id', 'name'] }"
-        @on-fetch="(data) => (deliveryPoints = data)"
-        auto-load
-    />
-    <FormModel model="Vehicle" :url-update="`Vehicles/${$route.params.id}`">
-        <template #form="{ data }">
-            <VnRow>
-                <VnInput v-model="data.description" :label="$t('globals.description')" />
-                <VnInput v-model="data.numberPlate" :label="$t('vehicle.numberPlate')" />
-            </VnRow>
-            <VnRow>
-                <VnInput
-                    v-model="data.model"
-                    :label="$t('globals.model')"
-                    :required="true"
-                />
-                <VnSelect
-                    url="VehicleTypes"
-                    v-model="data.vehicleTypeFk"
-                    :label="$t('globals.type')"
-                />
-            </VnRow>
-            <VnRow>
-                <VnInput
-                    v-model="data.tradeMark"
-                    :label="$t('vehicle.tradeMark')"
-                    :required="true"
-                />
-                <VnInput v-model="data.chassis" :label="$t('vehicle.chassis')" />
-            </VnRow>
-            <VnRow>
-                <VnSelect
-                    v-model="data.fuelTypeFk"
-                    :label="$t('globals.fuel')"
-                    :options="fuelTypes"
-                />
-                <VnSelect
-                    v-model="data.deliveryPointFk"
-                    :label="$t('globals.deliveryPoint')"
-                    :options="deliveryPoints"
-                />
-            </VnRow>
-            <VnRow>
-                <VnSelect
-                    v-model="data.companyFk"
-                    :label="$t('globals.company')"
-                    :options="companies"
-                    option-label="code"
-                />
-                <VnSelect
-                    v-model="data.warehouseFk"
-                    :label="$t('globals.warehouse')"
-                    :options="warehouses"
-                />
-            </VnRow>
-            <VnRow>
-                <VnSelect
-                    url="Suppliers"
-                    :filter="{ fields: ['id', 'name'] }"
-                    v-model="data.supplierFk"
-                    :label="$t('globals.supplier')"
-                />
-                <VnSelect
-                    url="Suppliers"
-                    :filter="{ fields: ['id', 'name'] }"
-                    v-model="data.supplierCoolerFk"
-                    :label="$t('vehicle.supplierCooler')"
-                />
-            </VnRow>
-            <VnRow>
-                <VnSelect
-                    url="BankPolicies"
-                    :filter="{ fields: ['id', 'ref'] }"
-                    v-model="data.bankPolicyFk"
-                    :label="$t('vehicle.leasing')"
-                    :options="bankPolicies"
-                    option-label="ref"
-                    option-value="id"
-                />
-                <VnInput v-model="data.leasing" :label="$t('vehicle.nLeasing')" />
-            </VnRow>
-            <VnRow>
-                <VnInputNumber v-model="data.import" :label="$t('globals.amount')" />
-                <VnInputNumber
-                    v-model="data.importCooler"
-                    :label="$t('vehicle.amountCooler')"
-                />
-            </VnRow>
-            <VnRow>
-                <VnSelect
-                    url="Ppes"
-                    option-label="id"
-                    v-model="data.ppeFk"
-                    :label="$t('vehicle.ppe')"
-                />
-                <VnSelect
-                    v-model="data.countryCodeFk"
-                    :label="$t('globals.country')"
-                    :options="countries"
-                    option-label="code"
-                    option-value="code"
-                />
-            </VnRow>
-            <VnRow>
-                <VnInput v-model="data.vin" :label="$t('vehicle.vin')" />
-                <span :style="{ 'align-self': $q.screen.gt.xs ? 'end' : 'unset' }">
-                    <QCheckbox
-                        v-model="data.isActive"
-                        :label="$t('vehicle.isActive')"
-                        :false-value="0"
-                        :true-value="1"
-                        dense
-                        class="q-mt-sm"
-                    />
-                </span>
-            </VnRow>
-        </template>
-    </FormModel>
-</template>
diff --git a/src/pages/Route/Vehicle/Card/VehicleCard.vue b/src/pages/Route/Vehicle/Card/VehicleCard.vue
deleted file mode 100644
index f59420aa24b..00000000000
--- a/src/pages/Route/Vehicle/Card/VehicleCard.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-<script setup>
-import VnCardBeta from 'components/common/VnCardBeta.vue';
-import VehicleDescriptor from './VehicleDescriptor.vue';
-import VehicleFilter from '../VehicleFilter.js';
-</script>
-<template>
-    <VnCardBeta
-        data-key="Vehicle"
-        url="Vehicles"
-        :filter="VehicleFilter"
-        :descriptor="VehicleDescriptor"
-    />
-</template>
diff --git a/src/pages/Route/Vehicle/Card/VehicleDescriptor.vue b/src/pages/Route/Vehicle/Card/VehicleDescriptor.vue
deleted file mode 100644
index d9a2434ab3c..00000000000
--- a/src/pages/Route/Vehicle/Card/VehicleDescriptor.vue
+++ /dev/null
@@ -1,49 +0,0 @@
-<script setup>
-import VnLv from 'src/components/ui/VnLv.vue';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
-import axios from 'axios';
-import useNotify from 'src/composables/useNotify.js';
-
-const { notify } = useNotify();
-</script>
-<template>
-    <CardDescriptor
-        :url="`Vehicles/${$route.params.id}`"
-        data-key="Vehicle"
-        title="numberPlate"
-        :to-module="{ name: 'VehicleList' }"
-    >
-        <template #menu="{ entity }">
-            <QItem
-                data-cy="delete"
-                v-ripple
-                clickable
-                @click="
-                    async () => {
-                        try {
-                            await axios.delete(`Vehicles/${entity.id}`);
-                            notify('vehicle.remove', 'positive');
-                            $router.push({ name: 'VehicleList' });
-                        } catch (e) {
-                            throw e;
-                        }
-                    }
-                "
-            >
-                <QItemSection>
-                    {{ $t('vehicle.delete') }}
-                </QItemSection>
-            </QItem>
-        </template>
-        <template #body="{ entity }">
-            <VnLv :label="$t('vehicle.numberPlate')" :value="entity.numberPlate" />
-            <VnLv :label="$t('vehicle.tradeMark')" :value="entity.tradeMark" />
-            <VnLv :label="$t('globals.model')" :value="entity.model" />
-            <VnLv :label="$t('globals.country')" :value="entity.countryCodeFk" />
-        </template>
-    </CardDescriptor>
-</template>
-<i18n>
-es:
-    Vehicle removed: Vehículo eliminado
-</i18n>
diff --git a/src/pages/Route/Vehicle/Card/VehicleSummary.vue b/src/pages/Route/Vehicle/Card/VehicleSummary.vue
deleted file mode 100644
index 981870cb29b..00000000000
--- a/src/pages/Route/Vehicle/Card/VehicleSummary.vue
+++ /dev/null
@@ -1,127 +0,0 @@
-<script setup>
-import { computed } from 'vue';
-import { useRoute } from 'vue-router';
-import CardSummary from 'components/ui/CardSummary.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
-import VnTitle from 'src/components/common/VnTitle.vue';
-import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
-import VehicleFilter from '../VehicleFilter.js';
-import { downloadFile } from 'src/composables/downloadFile';
-import { dashIfEmpty } from 'src/filters';
-
-const props = defineProps({ id: { type: [Number, String], default: null } });
-
-const route = useRoute();
-const entityId = computed(() => props.id || +route.params.id);
-const links = {
-    'basic-data': `#/vehicle/${entityId.value}/basic-data`,
-    notes: `#/vehicle/${entityId.value}/notes`,
-    dms: `#/vehicle/${entityId.value}/dms`,
-    'invoice-in': `#/vehicle/${entityId.value}/invoice-in`,
-    events: `#/vehicle/${entityId.value}/events`,
-};
-</script>
-<template>
-    <CardSummary data-key="Vehicle" :url="`Vehicles/${entityId}`" :filter="VehicleFilter">
-        <template #header="{ entity }">
-            <div>{{ entity.id }} - {{ entity.numberPlate }}</div>
-        </template>
-        <template #body="{ entity }">
-            <QCard class="vn-one">
-                <QCardSection dense>
-                    <VnTitle
-                        :url="links['basic-data']"
-                        :text="$t('globals.pageTitles.basicData')"
-                    />
-                </QCardSection>
-                <QCardSection content>
-                    <QList dense>
-                        <VnLv
-                            :label="$t('globals.description')"
-                            :value="entity.description"
-                        />
-                        <VnLv
-                            :label="$t('vehicle.tradeMark')"
-                            :value="entity.tradeMark"
-                        />
-                        <VnLv :label="$t('globals.model')" :value="entity.model" />
-                        <VnLv :label="$t('globals.supplier')">
-                            <template #value>
-                                <span class="link">
-                                    {{ entity.supplier?.name }}
-                                    <SupplierDescriptorProxy :id="entity.supplierFk" />
-                                </span>
-                            </template>
-                        </VnLv>
-                        <VnLv :label="$t('vehicle.supplierCooler')">
-                            <template #value>
-                                <span class="link">
-                                    {{ entity.supplierCooler?.name }}
-                                    <SupplierDescriptorProxy
-                                        :id="entity.supplierCoolerFk"
-                                    />
-                                </span>
-                            </template>
-                        </VnLv>
-                        <VnLv :label="$t('vehicle.vin')" :value="entity.vin" />
-                    </QList>
-                    <QList dense>
-                        <VnLv :label="$t('vehicle.chassis')" :value="entity.chassis" />
-                        <VnLv
-                            :label="$t('globals.fuel')"
-                            :value="entity.fuelType?.name"
-                        />
-                        <VnLv :label="$t('vehicle.ppe')" :value="entity.ppeFk" />
-                        <VnLv :label="$t('vehicle.nLeasing')" :value="entity.leasing" />
-                        <VnLv
-                            :label="$t('vehicle.leasing')"
-                            :value="entity.bankPolicy?.ref"
-                        >
-                            <template #value>
-                                <span v-text="dashIfEmpty(entity.bankPolicy?.name)" />
-                                <QBtn
-                                    v-if="entity.bankPolicy?.dmsFk"
-                                    class="q-ml-xs"
-                                    color="primary"
-                                    flat
-                                    dense
-                                    icon="cloud_download"
-                                    @click="downloadFile(entity.bankPolicy?.dmsFk)"
-                                >
-                                    <QTooltip>{{ $t('globals.download') }}</QTooltip>
-                                </QBtn>
-                            </template>
-                        </VnLv>
-                        <VnLv :label="$t('globals.amount')" :value="entity.import" />
-                    </QList>
-                    <QList dense>
-                        <VnLv
-                            :label="$t('globals.warehouse')"
-                            :value="entity.warehouse?.name"
-                        />
-                        <VnLv
-                            :label="$t('globals.company')"
-                            :value="entity.company?.code"
-                        />
-                        <VnLv
-                            :label="$t('globals.deliveryPoint')"
-                            :value="entity.deliveryPoint?.name"
-                        />
-                        <VnLv
-                            :label="$t('globals.country')"
-                            :value="entity.countryCodeFk"
-                        />
-                        <VnLv
-                            :label="$t('vehicle.isKmTruckRate')"
-                            :value="!!entity.isKmTruckRate"
-                        />
-                        <VnLv
-                            :label="$t('vehicle.isActive')"
-                            :value="!!entity.isActive"
-                        />
-                    </QList>
-                </QCardSection>
-            </QCard>
-        </template>
-    </CardSummary>
-</template>
diff --git a/src/pages/Route/Vehicle/VehicleFilter.js b/src/pages/Route/Vehicle/VehicleFilter.js
deleted file mode 100644
index cbf5cc621c1..00000000000
--- a/src/pages/Route/Vehicle/VehicleFilter.js
+++ /dev/null
@@ -1,76 +0,0 @@
-export default {
-    fields: [
-        'id',
-        'description',
-        'isActive',
-        'isKmTruckRate',
-        'warehouseFk',
-        'companyFk',
-        'numberPlate',
-        'chassis',
-        'supplierFk',
-        'supplierCoolerFk',
-        'tradeMark',
-        'fuelTypeFk',
-        'import',
-        'importCooler',
-        'vin',
-        'model',
-        'ppeFk',
-        'countryCodeFk',
-        'leasing',
-        'bankPolicyFk',
-        'vehicleTypeFk',
-        'deliveryPointFk',
-    ],
-    include: [
-        {
-            relation: 'warehouse',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'company',
-            scope: {
-                fields: ['id', 'code'],
-            },
-        },
-        {
-            relation: 'supplier',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'supplierCooler',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'fuelType',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'bankPolicy',
-            scope: {
-                fields: ['id', 'ref', 'dmsFk'],
-            },
-        },
-        {
-            relation: 'ppe',
-            scope: {
-                fields: ['id'],
-            },
-        },
-        {
-            relation: 'deliveryPoint',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-    ],
-};
diff --git a/src/pages/Route/Vehicle/VehicleList.vue b/src/pages/Route/Vehicle/VehicleList.vue
deleted file mode 100644
index e5b94501005..00000000000
--- a/src/pages/Route/Vehicle/VehicleList.vue
+++ /dev/null
@@ -1,224 +0,0 @@
-<script setup>
-import { ref, computed } from 'vue';
-import { useI18n } from 'vue-i18n';
-import VnTable from 'components/VnTable/VnTable.vue';
-import FetchData from 'src/components/FetchData.vue';
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import VehicleSummary from 'src/pages/Route/Vehicle/Card/VehicleSummary.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import VnSection from 'src/components/common/VnSection.vue';
-
-const { t } = useI18n();
-const { viewSummary } = useSummaryDialog();
-const warehouses = ref([]);
-const companies = ref([]);
-const countries = ref([]);
-const vehicleStates = ref([]);
-const vehicleTypes = ref([]);
-
-const columns = computed(() => [
-    {
-        name: 'isActive',
-        columnFilter: false,
-        align: 'center',
-    },
-    {
-        name: 'id',
-        label: t('globals.id'),
-        isId: true,
-        chip: {
-            condition: () => true,
-        },
-    },
-    {
-        name: 'description',
-        label: t('globals.description'),
-    },
-    {
-        name: 'tradeMark',
-        label: t('vehicle.tradeMark'),
-        cardVisible: true,
-    },
-    {
-        name: 'numberPlate',
-        label: t('vehicle.numberPlate'),
-        isTitle: true,
-    },
-    {
-        name: 'vehicleTypeFk',
-        label: t('globals.type'),
-        format: (row) => row.type,
-        columnFilter: {
-            component: 'select',
-            name: 'vehicleTypeFk',
-            options: vehicleTypes.value,
-        },
-        cardVisible: true,
-    },
-    {
-        name: 'vehicleStateFk',
-        label: t('globals.state'),
-        columnFilter: {
-            component: 'select',
-            name: 'vehicleStateFk',
-            optionLabel: 'state',
-            options: vehicleStates.value,
-        },
-        format: (row, dashIfEmpty) => dashIfEmpty(row.state),
-    },
-    {
-        name: 'chassis',
-        label: t('vehicle.chassis'),
-    },
-    {
-        name: 'leasing',
-        label: t('vehicle.leasing'),
-    },
-    {
-        name: 'warehouseFk',
-        label: t('globals.warehouse'),
-        format: (row, dashIfEmpty) => dashIfEmpty(row.warehouse),
-        columnFilter: {
-            component: 'select',
-            name: 'warehouseFk',
-            options: warehouses.value,
-        },
-        cardVisible: true,
-    },
-    {
-        name: 'companyFk',
-        label: t('globals.company'),
-        format: (row, dashIfEmpty) => dashIfEmpty(row.company),
-        columnFilter: {
-            component: 'select',
-            name: 'companyFk',
-            optionLabel: 'code',
-            options: companies.value,
-        },
-    },
-    {
-        name: 'countryCodeFk',
-        label: t('globals.country'),
-        columnFilter: {
-            component: 'select',
-            name: 'countryCodeFk',
-            optionValue: 'code',
-            optionLabel: 'code',
-            options: countries.value,
-        },
-    },
-    {
-        align: 'right',
-        name: 'tableActions',
-        actions: [
-            {
-                title: t('components.smartCard.openSummary'),
-                icon: 'preview',
-                action: (row) => viewSummary(row.id, VehicleSummary),
-            },
-        ],
-    },
-]);
-</script>
-<template>
-    <FetchData
-        url="Warehouses"
-        :filter="{ fields: ['id', 'name'] }"
-        @on-fetch="(data) => (warehouses = data)"
-        auto-load
-    />
-    <FetchData
-        url="Companies"
-        :filter="{ fields: ['id', 'code'] }"
-        @on-fetch="(data) => (companies = data)"
-        auto-load
-    />
-    <FetchData
-        url="Countries"
-        :filter="{ fields: ['name', 'code'] }"
-        @on-fetch="(data) => (countries = data)"
-        auto-load
-    />
-    <FetchData
-        url="VehicleStates"
-        :filter="{ fields: ['id', 'state'] }"
-        @on-fetch="(data) => (vehicleStates = data)"
-        auto-load
-    />
-    <FetchData
-        url="VehicleTypes"
-        :filter="{ fields: ['id', 'name'] }"
-        @on-fetch="(data) => (vehicleTypes = data)"
-        auto-load
-    />
-    <VnSection
-        data-key="VehicleList"
-        :columns="columns"
-        prefix="vehicle"
-        :array-data-props="{
-            url: 'Vehicles/filter',
-        }"
-    >
-        <template #body>
-            <VnTable
-                ref="tableRef"
-                data-key="VehicleList"
-                :columns="columns"
-                redirect="route/vehicle"
-                :create="{
-                    urlCreate: 'Vehicles',
-                    title: t('vehicle.create'),
-                    onDataSaved: ({ id }) => $refs.tableRef.redirect(id),
-                    formInitialData: { isActive: true, isKmTruckRate: false },
-                }"
-                :use-model="true"
-                :right-search="false"
-            >
-                <template #column-isActive="{ row }">
-                    <span>
-                        <QIcon
-                            v-if="!row.isActive"
-                            name="vn:inactive-car"
-                            color="primary"
-                            size="xs"
-                        >
-                            <QTooltip>{{ $t('globals.inactive') }}</QTooltip>
-                        </QIcon>
-                    </span>
-                </template>
-                <template #more-create-dialog="{ data }">
-                    <VnInput
-                        v-model="data.numberPlate"
-                        :label="$t('vehicle.numberPlate')"
-                        :uppercase="true"
-                    />
-                    <VnInput v-model="data.tradeMark" :label="$t('vehicle.tradeMark')" />
-                    <VnInput v-model="data.model" :label="$t('globals.model')" />
-                    <VnSelect
-                        v-model="data.vehicleTypeFk"
-                        :label="$t('globals.type')"
-                        :options="vehicleTypes"
-                    />
-                    <VnSelect
-                        v-model="data.warehouseFk"
-                        :label="$t('globals.warehouse')"
-                        :options="warehouses"
-                    />
-                    <VnSelect
-                        v-model="data.countryCodeFk"
-                        :label="$t('globals.country')"
-                        option-value="code"
-                        option-label="name"
-                        :options="countries"
-                    />
-                    <VnInput
-                        v-model="data.description"
-                        :label="$t('globals.description')"
-                    />
-                    <QCheckbox to v-model="data.isActive" :label="$t('globals.active')" />
-                </template>
-            </VnTable>
-        </template>
-    </VnSection>
-</template>
diff --git a/src/pages/Route/Vehicle/locale/en.yml b/src/pages/Route/Vehicle/locale/en.yml
deleted file mode 100644
index c92022f9d29..00000000000
--- a/src/pages/Route/Vehicle/locale/en.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-vehicle:
-    tradeMark: Trade Mark
-    numberPlate: Nº Plate
-    chassis: Chassis
-    leasing: Leasing
-    isKmTruckRate: Trailer
-    delete: Delete Vehicle
-    supplierCooler: Supplier Cooler
-    vin: VIN
-    ppe: Ppe
-    isActive: Active
-    nLeasing: Nº Leasing
-    create: Create Vehicle
-    amountCooler: Amount cooler
-    remove: Vehicle removed
-    search: Search Vehicle
-    searchInfo: Search by id or number plate
-    params:
-        vehicleTypeFk: Type
-        vehicleStateFk: State
diff --git a/src/pages/Route/Vehicle/locale/es.yml b/src/pages/Route/Vehicle/locale/es.yml
deleted file mode 100644
index c878f97ac56..00000000000
--- a/src/pages/Route/Vehicle/locale/es.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-vehicle:
-    tradeMark: Marca
-    numberPlate: Matrícula
-    chassis: Nº de bastidor
-    leasing: Leasing
-    isKmTruckRate: Trailer
-    delete: Eliminar vehículo
-    supplierCooler: Proveedor Frío
-    vin: VIN
-    ppe: Nº Inmovilizado
-    create: Crear vehículo
-    amountCooler: Importe frío
-    isActive: Activo
-    nLeasing: Nº leasing
-    remove: Vehículo eliminado
-    search: Buscar Vehículo
-    searchInfo: Buscar por id o matrícula
-    params:
-        vehicleTypeFk: Tipo
-        vehicleStateFk: Estado
diff --git a/src/pages/Shelving/Card/ShelvingCard.vue b/src/pages/Shelving/Card/ShelvingCard.vue
index 9e0ac8ad2ce..41a0db33cb8 100644
--- a/src/pages/Shelving/Card/ShelvingCard.vue
+++ b/src/pages/Shelving/Card/ShelvingCard.vue
@@ -1,14 +1,12 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import ShelvingDescriptor from 'pages/Shelving/Card/ShelvingDescriptor.vue';
-import filter from './ShelvingFilter.js';
 </script>
 
 <template>
     <VnCardBeta
         data-key="Shelving"
-        url="Shelvings"
-        :filter="filter"
+        base-url="Shelvings"
         :descriptor="ShelvingDescriptor"
     />
 </template>
diff --git a/src/pages/Shelving/Card/ShelvingDescriptor.vue b/src/pages/Shelving/Card/ShelvingDescriptor.vue
index 5e618aa7f46..b1ff4a8aedf 100644
--- a/src/pages/Shelving/Card/ShelvingDescriptor.vue
+++ b/src/pages/Shelving/Card/ShelvingDescriptor.vue
@@ -1,12 +1,12 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'components/ui/VnLv.vue';
+import useCardDescription from 'composables/useCardDescription';
 import ShelvingDescriptorMenu from 'pages/Shelving/Card/ShelvingDescriptorMenu.vue';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
-import filter from './ShelvingFilter.js';
 
 const $props = defineProps({
     id: {
@@ -22,13 +22,35 @@ const { t } = useI18n();
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+
+const filter = {
+    include: [
+        {
+            relation: 'worker',
+            scope: {
+                fields: ['id'],
+                include: {
+                    relation: 'user',
+                    scope: { fields: ['nickname'] },
+                },
+            },
+        },
+        { relation: 'parking' },
+    ],
+};
+const data = ref(useCardDescription());
+const setData = (entity) => (data.value = useCardDescription(entity.code, entity.id));
 </script>
+
 <template>
     <CardDescriptor
+        module="Shelving"
         :url="`Shelvings/${entityId}`"
         :filter="filter"
-        title="code"
-        data-key="Shelving"
+        :title="data.title"
+        :subtitle="data.subtitle"
+        data-key="Shelvings"
+        @on-fetch="setData"
     >
         <template #body="{ entity }">
             <VnLv :label="t('globals.code')" :value="entity.code" />
diff --git a/src/pages/Shelving/Card/ShelvingFilter.js b/src/pages/Shelving/Card/ShelvingFilter.js
deleted file mode 100644
index e302e1b9cb4..00000000000
--- a/src/pages/Shelving/Card/ShelvingFilter.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export default {
-    include: [
-        {
-            relation: 'worker',
-            scope: {
-                fields: ['id'],
-                include: {
-                    relation: 'user',
-                    scope: { fields: ['nickname'] },
-                },
-            },
-        },
-        { relation: 'parking' },
-    ],
-};
diff --git a/src/pages/Shelving/Card/ShelvingForm.vue b/src/pages/Shelving/Card/ShelvingForm.vue
index 0780583427d..3bbd94a0a54 100644
--- a/src/pages/Shelving/Card/ShelvingForm.vue
+++ b/src/pages/Shelving/Card/ShelvingForm.vue
@@ -1,4 +1,5 @@
 <script setup>
+import { useI18n } from 'vue-i18n';
 import { computed } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import VnRow from 'components/ui/VnRow.vue';
@@ -6,8 +7,8 @@ import FormModel from 'components/FormModel.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
-import filter from './ShelvingFilter.js';
 
+const { t } = useI18n();
 const route = useRoute();
 const router = useRouter();
 const entityId = computed(() => route.params.id ?? null);
@@ -19,6 +20,22 @@ const defaultInitialData = {
     isRecyclable: false,
 };
 
+const shelvingFilter = {
+    include: [
+        {
+            relation: 'worker',
+            scope: {
+                fields: ['id'],
+                include: {
+                    relation: 'user',
+                    scope: { fields: ['nickname'] },
+                },
+            },
+        },
+        { relation: 'parking' },
+    ],
+};
+
 const onSave = (shelving, newShelving) => {
     if (isNew) {
         router.push({ name: 'ShelvingBasicData', params: { id: newShelving?.id } });
@@ -28,10 +45,11 @@ const onSave = (shelving, newShelving) => {
 <template>
     <VnSubToolbar v-if="isNew" />
     <FormModel
+        :url="isNew ? null : `Shelvings/${entityId}`"
         :url-create="isNew ? 'Shelvings' : null"
         :observe-form-changes="!isNew"
-        :filter="filter"
-        model="Shelving"
+        :filter="shelvingFilter"
+        model="shelving"
         :auto-load="!isNew"
         :form-initial-data="isNew ? defaultInitialData : null"
         @on-data-saved="onSave"
@@ -40,7 +58,7 @@ const onSave = (shelving, newShelving) => {
             <VnRow>
                 <VnInput
                     v-model="data.code"
-                    :label="$t('globals.code')"
+                    :label="t('globals.code')"
                     :rules="validate('Shelving.code')"
                 />
                 <VnSelect
@@ -50,7 +68,7 @@ const onSave = (shelving, newShelving) => {
                     option-label="code"
                     :filter-options="['id', 'code']"
                     :fields="['id', 'code']"
-                    :label="$t('shelving.list.parking')"
+                    :label="t('shelving.list.parking')"
                     :rules="validate('Shelving.parkingFk')"
                 />
             </VnRow>
@@ -58,12 +76,12 @@ const onSave = (shelving, newShelving) => {
                 <VnInput
                     v-model="data.priority"
                     type="number"
-                    :label="$t('shelving.list.priority')"
+                    :label="t('shelving.list.priority')"
                     :rules="validate('Shelving.priority')"
                 />
                 <QCheckbox
                     v-model="data.isRecyclable"
-                    :label="$t('shelving.summary.recyclable')"
+                    :label="t('shelving.summary.recyclable')"
                     :rules="validate('Shelving.isRecyclable')"
                 />
             </VnRow>
diff --git a/src/pages/Shelving/Card/ShelvingSearchbar.vue b/src/pages/Shelving/Card/ShelvingSearchbar.vue
index 741b1166305..bfc8ad4f50a 100644
--- a/src/pages/Shelving/Card/ShelvingSearchbar.vue
+++ b/src/pages/Shelving/Card/ShelvingSearchbar.vue
@@ -1,15 +1,15 @@
 <script setup>
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
-import exprBuilder from '../ShelvingExprBuilder.js';
+import {useI18n} from "vue-i18n";
+const { t } = useI18n();
 </script>
 
 <template>
     <VnSearchbar
         data-key="ShelvingList"
         url="Shelvings"
-        :label="$t('Search shelving')"
-        :info="$t('You can search by shelving reference')"
-        :expr-builder="exprBuilder"
+        :label="t('Search shelving')"
+        :info="t('You can search by shelving reference')"
     />
 </template>
 
diff --git a/src/pages/Shelving/Card/ShelvingSummary.vue b/src/pages/Shelving/Card/ShelvingSummary.vue
index f89ff4d788e..39fa4639f23 100644
--- a/src/pages/Shelving/Card/ShelvingSummary.vue
+++ b/src/pages/Shelving/Card/ShelvingSummary.vue
@@ -1,10 +1,10 @@
 <script setup>
 import { computed, ref } from 'vue';
 import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'components/ui/VnLv.vue';
 import VnUserLink from 'components/ui/VnUserLink.vue';
-import filter from './ShelvingFilter.js';
 import ShelvingDescriptorMenu from './ShelvingDescriptorMenu.vue';
 
 const $props = defineProps({
@@ -14,9 +14,25 @@ const $props = defineProps({
     },
 });
 const route = useRoute();
-
+const { t } = useI18n();
 const summary = ref({});
 const entityId = computed(() => $props.id || route.params.id);
+
+const filter = {
+    include: [
+        {
+            relation: 'worker',
+            scope: {
+                fields: ['id'],
+                include: {
+                    relation: 'user',
+                    scope: { fields: ['nickname'] },
+                },
+            },
+        },
+        { relation: 'parking' },
+    ],
+};
 </script>
 
 <template>
@@ -25,7 +41,7 @@ const entityId = computed(() => $props.id || route.params.id);
             ref="summary"
             :url="`Shelvings/${entityId}`"
             :filter="filter"
-            data-key="Shelving"
+            data-key="ShelvingSummary"
         >
             <template #header="{ entity }">
                 <div>{{ entity.code }}</div>
@@ -42,19 +58,16 @@ const entityId = computed(() => $props.id || route.params.id);
                         class="header header-link"
                         :to="{ name: 'ShelvingBasicData', params: { id: entityId } }"
                     >
-                        {{ $t('globals.pageTitles.basicData') }}
+                        {{ t('globals.pageTitles.basicData') }}
                         <QIcon name="open_in_new" />
                     </RouterLink>
-                    <VnLv :label="$t('globals.code')" :value="entity.code" />
+                    <VnLv :label="t('globals.code')" :value="entity.code" />
                     <VnLv
-                        :label="$t('shelving.list.parking')"
+                        :label="t('shelving.list.parking')"
                         :value="entity.parking?.code"
                     />
-                    <VnLv
-                        :label="$t('shelving.list.priority')"
-                        :value="entity.priority"
-                    />
-                    <VnLv v-if="entity.worker" :label="$t('globals.worker')">
+                    <VnLv :label="t('shelving.list.priority')" :value="entity.priority" />
+                    <VnLv v-if="entity.worker" :label="t('globals.worker')">
                         <template #value>
                             <VnUserLink
                                 :name="entity.worker?.user?.nickname"
@@ -63,7 +76,7 @@ const entityId = computed(() => $props.id || route.params.id);
                         </template>
                     </VnLv>
                     <VnLv
-                        :label="$t('shelving.summary.recyclable')"
+                        :label="t('shelving.summary.recyclable')"
                         :value="entity.isRecyclable"
                     />
                 </QCard>
diff --git a/src/pages/Shelving/Parking/Card/ParkingFilter.js b/src/pages/Shelving/Parking/Card/ParkingFilter.js
deleted file mode 100644
index fd1855c4535..00000000000
--- a/src/pages/Shelving/Parking/Card/ParkingFilter.js
+++ /dev/null
@@ -1,4 +0,0 @@
-export default {
-    fields: ['id', 'sectorFk', 'code', 'pickingOrder', 'row', 'column'],
-    include: [{ relation: 'sector', scope: { fields: ['id', 'description'] } }],
-};
diff --git a/src/pages/Shelving/Parking/ParkingExprBuilder.js b/src/pages/Shelving/Parking/ParkingExprBuilder.js
deleted file mode 100644
index 16d2262c8fd..00000000000
--- a/src/pages/Shelving/Parking/ParkingExprBuilder.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default (param, value) => {
-    switch (param) {
-        case 'code':
-            return { [param]: { like: `%${value}%` } };
-        case 'sectorFk':
-            return { [param]: value };
-        case 'search':
-            return { or: [{ code: { like: `%${value}%` } }, { id: value }] };
-    }
-};
diff --git a/src/pages/Shelving/ShelvingExprBuilder.js b/src/pages/Shelving/ShelvingExprBuilder.js
deleted file mode 100644
index b9aad8a711e..00000000000
--- a/src/pages/Shelving/ShelvingExprBuilder.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default (param, value) => {
-    switch (param) {
-        case 'search':
-            return { code: { like: `%${value}%` } };
-        case 'parkingFk':
-        case 'userFk':
-        case 'isRecyclable':
-            return { [param]: value };
-    }
-};
diff --git a/src/pages/Shelving/ShelvingList.vue b/src/pages/Shelving/ShelvingList.vue
index 4e0c21100e8..cf158e76b17 100644
--- a/src/pages/Shelving/ShelvingList.vue
+++ b/src/pages/Shelving/ShelvingList.vue
@@ -1,5 +1,6 @@
 <script setup>
 import VnPaginate from 'components/ui/VnPaginate.vue';
+import { useI18n } from 'vue-i18n';
 import CardList from 'components/ui/CardList.vue';
 import VnLv from 'components/ui/VnLv.vue';
 import { useRouter } from 'vue-router';
@@ -7,9 +8,9 @@ import ShelvingFilter from 'pages/Shelving/Card/ShelvingFilter.vue';
 import ShelvingSummary from 'pages/Shelving/Card/ShelvingSummary.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import VnSection from 'src/components/common/VnSection.vue';
-import exprBuilder from './ShelvingExprBuilder.js';
 
 const router = useRouter();
+const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
 const dataKey = 'ShelvingList';
 
@@ -20,6 +21,17 @@ const filter = {
 function navigate(id) {
     router.push({ path: `/shelving/${id}` });
 }
+
+function exprBuilder(param, value) {
+    switch (param) {
+        case 'search':
+            return { code: { like: `%${value}%` } };
+        case 'parkingFk':
+        case 'userFk':
+        case 'isRecyclable':
+            return { [param]: value };
+    }
+}
 </script>
 
 <template>
@@ -50,18 +62,18 @@ function navigate(id) {
                             >
                                 <template #list-items>
                                     <VnLv
-                                        :label="$t('shelving.list.parking')"
-                                        :title-label="$t('shelving.list.parking')"
+                                        :label="t('shelving.list.parking')"
+                                        :title-label="t('shelving.list.parking')"
                                         :value="row.parking?.code"
                                     />
                                     <VnLv
-                                        :label="$t('shelving.list.priority')"
+                                        :label="t('shelving.list.priority')"
                                         :value="row?.priority"
                                     />
                                 </template>
                                 <template #actions>
                                     <QBtn
-                                        :label="$t('components.smartCard.openSummary')"
+                                        :label="t('components.smartCard.openSummary')"
                                         @click.stop="viewSummary(row.id, ShelvingSummary)"
                                         color="primary"
                                     />
@@ -72,9 +84,9 @@ function navigate(id) {
                 </div>
                 <QPageSticky :offset="[20, 20]">
                     <RouterLink :to="{ name: 'ShelvingCreate' }">
-                        <QBtn fab icon="add" color="primary" v-shortcut="'+'" />
+                        <QBtn fab icon="add" color="primary" shortcut="+" />
                         <QTooltip>
-                            {{ $t('shelving.list.newShelving') }}
+                            {{ t('shelving.list.newShelving') }}
                         </QTooltip>
                     </RouterLink>
                 </QPageSticky>
diff --git a/src/pages/Supplier/Card/SupplierAccounts.vue b/src/pages/Supplier/Card/SupplierAccounts.vue
index 365eb67a141..4a6901d1d13 100644
--- a/src/pages/Supplier/Card/SupplierAccounts.vue
+++ b/src/pages/Supplier/Card/SupplierAccounts.vue
@@ -71,7 +71,7 @@ function bankEntityFilter(val, update) {
         filteredBankEntitiesOptions.value = bankEntitiesOptions.value.filter(
             (bank) =>
                 bank.bic.toLowerCase().startsWith(needle) ||
-                bank.name.toLowerCase().includes(needle),
+                bank.name.toLowerCase().includes(needle)
         );
     });
 }
@@ -170,7 +170,7 @@ function bankEntityFilter(val, update) {
                             <QIcon name="info" class="cursor-pointer">
                                 <QTooltip>{{
                                     t(
-                                        'Name of the bank account holder if different from the provider',
+                                        'Name of the bank account holder if different from the provider'
                                     )
                                 }}</QTooltip>
                             </QIcon>
@@ -194,7 +194,7 @@ function bankEntityFilter(val, update) {
                     <QBtn
                         flat
                         icon="add"
-                        v-shortcut
+                        shortcut="+"
                         class="cursor-pointer"
                         color="primary"
                         @click="supplierAccountRef.insert()"
diff --git a/src/pages/Supplier/Card/SupplierAddresses.vue b/src/pages/Supplier/Card/SupplierAddresses.vue
index c4c0ab7bef6..e568962ff28 100644
--- a/src/pages/Supplier/Card/SupplierAddresses.vue
+++ b/src/pages/Supplier/Card/SupplierAddresses.vue
@@ -89,7 +89,7 @@ const redirectToUpdateView = (addressData) => {
                 icon="add"
                 color="primary"
                 @click="redirectToCreateView()"
-                v-shortcut="'+'"
+                shortcut="+"
             />
             <QTooltip>
                 {{ t('New address') }}
diff --git a/src/pages/Supplier/Card/SupplierAgencyTerm.vue b/src/pages/Supplier/Card/SupplierAgencyTerm.vue
index ab21f1f76fb..99b672cc4c5 100644
--- a/src/pages/Supplier/Card/SupplierAgencyTerm.vue
+++ b/src/pages/Supplier/Card/SupplierAgencyTerm.vue
@@ -114,7 +114,7 @@ const redirectToCreateView = () => {
             icon="add"
             color="primary"
             @click="redirectToCreateView()"
-            v-shortcut="'+'"
+            shortcut="+"
         />
         <QTooltip>
             {{ t('supplier.agencyTerms.addRow') }}
diff --git a/src/pages/Supplier/Card/SupplierBasicData.vue b/src/pages/Supplier/Card/SupplierBasicData.vue
index 631700a4aab..f6c13b7afcd 100644
--- a/src/pages/Supplier/Card/SupplierBasicData.vue
+++ b/src/pages/Supplier/Card/SupplierBasicData.vue
@@ -19,8 +19,9 @@ const companySizes = [
 </script>
 <template>
     <FormModel
+        :url="`Suppliers/${route.params.id}`"
         :url-update="`Suppliers/${route.params.id}`"
-        model="Supplier"
+        model="supplier"
         auto-load
         :clear-store-on-unmount="false"
         @on-data-saved="arrayData.fetch({})"
diff --git a/src/pages/Supplier/Card/SupplierCard.vue b/src/pages/Supplier/Card/SupplierCard.vue
index e30f79f962b..594026d18e9 100644
--- a/src/pages/Supplier/Card/SupplierCard.vue
+++ b/src/pages/Supplier/Card/SupplierCard.vue
@@ -1,13 +1,19 @@
 <script setup>
+import VnCard from 'components/common/VnCard.vue';
 import SupplierDescriptor from './SupplierDescriptor.vue';
-import VnCardBeta from 'src/components/common/VnCardBeta.vue';
-import filter from './SupplierFilter.js';
+import SupplierListFilter from '../SupplierListFilter.vue';
 </script>
 <template>
-    <VnCardBeta
+    <VnCard
         data-key="Supplier"
-        url="Suppliers"
+        base-url="Suppliers"
         :descriptor="SupplierDescriptor"
-        :filter="filter"
+        :filter-panel="SupplierListFilter"
+        search-data-key="SupplierList"
+        :searchbar-props="{
+            url: 'Suppliers/filter',
+            searchUrl: 'table',
+            label: 'Search suppliers',
+        }"
     />
 </template>
diff --git a/src/pages/Supplier/Card/SupplierConsumption.vue b/src/pages/Supplier/Card/SupplierConsumption.vue
index 718de95ddf4..8a7021fb341 100644
--- a/src/pages/Supplier/Card/SupplierConsumption.vue
+++ b/src/pages/Supplier/Card/SupplierConsumption.vue
@@ -16,7 +16,6 @@ import axios from 'axios';
 import { useStateStore } from 'stores/useStateStore';
 import { useState } from 'src/composables/useState';
 import { useArrayData } from 'composables/useArrayData';
-import RightMenu from 'src/components/common/RightMenu.vue';
 
 const state = useState();
 const stateStore = useStateStore();
@@ -174,59 +173,59 @@ onMounted(async () => {
             </div>
         </div>
     </Teleport>
-    <RightMenu>
-        <template #right-panel>
+    <QPage class="column items-center q-pa-md">
+        <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
             <SupplierConsumptionFilter data-key="SupplierConsumption" />
-        </template>
-    </RightMenu>
-    <QTable
-        :rows="rows"
-        row-key="id"
-        hide-header
-        class="full-width q-mt-md"
-        :no-data-label="t('No results')"
-    >
-        <template #body="{ row }">
-            <QTr>
-                <QTd no-hover>
-                    <span class="label">{{ t('supplier.consumption.entry') }}: </span>
-                    <span>{{ row.id }}</span>
-                </QTd>
-                <QTd no-hover>
-                    <span class="label">{{ t('globals.date') }}: </span>
-                    <span>{{ toDate(row.shipped) }}</span></QTd
-                >
-                <QTd colspan="6" no-hover>
-                    <span class="label">{{ t('globals.reference') }}: </span>
-                    <span>{{ row.invoiceNumber }}</span>
-                </QTd>
-            </QTr>
-            <QTr v-for="(buy, index) in row.buys" :key="index">
-                <QTd no-hover>
-                    <QBtn flat color="blue" dense no-caps>{{ buy.itemName }}</QBtn>
-                    <ItemDescriptorProxy :id="buy.itemFk" />
-                </QTd>
+        </Teleport>
+        <QTable
+            :rows="rows"
+            row-key="id"
+            hide-header
+            class="full-width q-mt-md"
+            :no-data-label="t('No results')"
+        >
+            <template #body="{ row }">
+                <QTr>
+                    <QTd no-hover>
+                        <span class="label">{{ t('supplier.consumption.entry') }}: </span>
+                        <span>{{ row.id }}</span>
+                    </QTd>
+                    <QTd no-hover>
+                        <span class="label">{{ t('globals.date') }}: </span>
+                        <span>{{ toDate(row.shipped) }}</span></QTd
+                    >
+                    <QTd colspan="6" no-hover>
+                        <span class="label">{{ t('globals.reference') }}: </span>
+                        <span>{{ row.invoiceNumber }}</span>
+                    </QTd>
+                </QTr>
+                <QTr v-for="(buy, index) in row.buys" :key="index">
+                    <QTd no-hover>
+                        <QBtn flat color="blue" dense no-caps>{{ buy.itemName }}</QBtn>
+                        <ItemDescriptorProxy :id="buy.itemFk" />
+                    </QTd>
 
-                <QTd no-hover>
-                    <span>{{ buy.subName }}</span>
-                    <FetchedTags :item="buy" />
-                </QTd>
-                <QTd no-hover> {{ dashIfEmpty(buy.quantity) }}</QTd>
-                <QTd no-hover> {{ dashIfEmpty(buy.price) }}</QTd>
-                <QTd colspan="2" no-hover> {{ dashIfEmpty(buy.total) }}</QTd>
-            </QTr>
-            <QTr>
-                <QTd colspan="5" no-hover>
-                    <span class="label">{{ t('Total entry') }}: </span>
-                    <span>{{ row.total }} €</span>
-                </QTd>
-                <QTd no-hover>
-                    <span class="label">{{ t('Total stems') }}: </span>
-                    <span>{{ row.quantity }}</span>
-                </QTd>
-            </QTr>
-        </template>
-    </QTable>
+                    <QTd no-hover>
+                        <span>{{ buy.subName }}</span>
+                        <FetchedTags :item="buy" />
+                    </QTd>
+                    <QTd no-hover> {{ dashIfEmpty(buy.quantity) }}</QTd>
+                    <QTd no-hover> {{ dashIfEmpty(buy.price) }}</QTd>
+                    <QTd colspan="2" no-hover> {{ dashIfEmpty(buy.total) }}</QTd>
+                </QTr>
+                <QTr>
+                    <QTd colspan="5" no-hover>
+                        <span class="label">{{ t('Total entry') }}: </span>
+                        <span>{{ row.total }} €</span>
+                    </QTd>
+                    <QTd no-hover>
+                        <span class="label">{{ t('Total stems') }}: </span>
+                        <span>{{ row.quantity }}</span>
+                    </QTd>
+                </QTr>
+            </template>
+        </QTable>
+    </QPage>
 </template>
 
 <style scoped lang="scss">
diff --git a/src/pages/Supplier/Card/SupplierContacts.vue b/src/pages/Supplier/Card/SupplierContacts.vue
index f96d92ab1db..6781c8d34ae 100644
--- a/src/pages/Supplier/Card/SupplierContacts.vue
+++ b/src/pages/Supplier/Card/SupplierContacts.vue
@@ -78,7 +78,7 @@ const insertRow = () => {
                     <QBtn
                         flat
                         icon="add"
-                        v-shortcut="'+'"
+                        shortcut="+"
                         class="cursor-pointer"
                         color="primary"
                         @click="insertRow()"
diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue
index 462bdf853ae..37c9c1cff23 100644
--- a/src/pages/Supplier/Card/SupplierDescriptor.vue
+++ b/src/pages/Supplier/Card/SupplierDescriptor.vue
@@ -7,8 +7,8 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 
 import { toDateString } from 'src/filters';
+import useCardDescription from 'src/composables/useCardDescription';
 import { getUrl } from 'src/composables/getUrl';
-import filter from './SupplierFilter.js';
 import { useArrayData } from 'src/composables/useArrayData';
 
 const $props = defineProps({
@@ -28,6 +28,42 @@ const { t } = useI18n();
 const url = ref();
 const arrayData = useArrayData();
 
+const filter = {
+    fields: [
+        'id',
+        'name',
+        'nickname',
+        'nif',
+        'payMethodFk',
+        'payDemFk',
+        'payDay',
+        'isActive',
+        'isReal',
+        'isTrucker',
+        'account',
+    ],
+    include: [
+        {
+            relation: 'payMethod',
+            scope: {
+                fields: ['id', 'name'],
+            },
+        },
+        {
+            relation: 'payDem',
+            scope: {
+                fields: ['id', 'payDem'],
+            },
+        },
+        {
+            relation: 'client',
+            scope: {
+                fields: ['id', 'fi'],
+            },
+        },
+    ],
+};
+
 onMounted(async () => {
     url.value = await getUrl('');
 });
@@ -36,6 +72,11 @@ const entityId = computed(() => {
     return $props.id || route.params.id;
 });
 
+const data = ref(useCardDescription());
+const setData = (entity) => {
+    data.value = useCardDescription(entity.ref, entity.id);
+};
+
 const supplier = computed(() => arrayData.store.data);
 
 const getEntryQueryParams = (supplier) => {
@@ -62,9 +103,13 @@ const getEntryQueryParams = (supplier) => {
 
 <template>
     <CardDescriptor
+        module="Supplier"
         :url="`Suppliers/${entityId}`"
+        :title="data.title"
+        :subtitle="data.subtitle"
         :filter="filter"
-        data-key="Supplier"
+        @on-fetch="setData"
+        data-key="supplierDescriptor"
         :summary="$props.summary"
     >
         <template #body="{ entity }">
diff --git a/src/pages/Supplier/Card/SupplierFilter.js b/src/pages/Supplier/Card/SupplierFilter.js
deleted file mode 100644
index 3ce5c3de29e..00000000000
--- a/src/pages/Supplier/Card/SupplierFilter.js
+++ /dev/null
@@ -1,35 +0,0 @@
-export default {
-    fields: [
-        'id',
-        'name',
-        'nickname',
-        'nif',
-        'payMethodFk',
-        'payDemFk',
-        'payDay',
-        'isActive',
-        'isSerious',
-        'isTrucker',
-        'account',
-    ],
-    include: [
-        {
-            relation: 'payMethod',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'payDem',
-            scope: {
-                fields: ['id', 'payDem'],
-            },
-        },
-        {
-            relation: 'client',
-            scope: {
-                fields: ['id', 'fi'],
-            },
-        },
-    ],
-};
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index ecee5b76b09..e569eb23609 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -10,7 +10,6 @@ import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnLocation from 'src/components/common/VnLocation.vue';
 import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
-import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -183,11 +182,18 @@ function handleLocation(data, location) {
                         v-model="data.isTrucker"
                         :label="t('supplier.fiscalData.isTrucker')"
                     />
-                    <VnCheckbox
-                        v-model="data.isVies"
-                        :label="t('globals.isVies')" 
-                        :info="t('whenActivatingIt')" 
-                    />
+                    <div class="row items-center">
+                        <QCheckbox v-model="data.isVies" :label="t('globals.isVies')" />
+                        <QIcon name="info" size="xs" class="cursor-pointer q-ml-sm">
+                            <QTooltip>
+                                {{
+                                    t(
+                                        'When activating it, do not enter the country code in the ID field.'
+                                    )
+                                }}
+                            </QTooltip>
+                        </QIcon>
+                    </div>
                 </div>
             </VnRow>
         </template>
@@ -195,8 +201,6 @@ function handleLocation(data, location) {
 </template>
 
 <i18n>
-en:
-    whenActivatingIt: When activating it, do not enter the country code in the ID field.
 es:
-    whenActivatingIt: Al activarlo, no informar el código del país en el campo nif.
+    When activating it, do not enter the country code in the ID field.: Al activarlo, no informar el código del país en el campo nif
 </i18n>
diff --git a/src/pages/Supplier/SupplierList.vue b/src/pages/Supplier/SupplierList.vue
index 600790745eb..85cc11857c4 100644
--- a/src/pages/Supplier/SupplierList.vue
+++ b/src/pages/Supplier/SupplierList.vue
@@ -2,15 +2,14 @@
 import { computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import VnTable from 'components/VnTable/VnTable.vue';
-import VnSection from 'src/components/common/VnSection.vue';
+import VnSearchbar from 'components/ui/VnSearchbar.vue';
+import RightMenu from 'src/components/common/RightMenu.vue';
+import SupplierListFilter from './SupplierListFilter.vue';
 import VnInput from 'src/components/common/VnInput.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import FetchData from 'src/components/FetchData.vue';
 
 const { t } = useI18n();
 const tableRef = ref();
-const dataKey = 'SupplierList';
-const provincesOptions = ref([]);
+
 const columns = computed(() => [
     {
         align: 'left',
@@ -105,62 +104,38 @@ const columns = computed(() => [
     },
 ]);
 </script>
+
 <template>
-    <FetchData
-        url="Provinces"
-        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
-        @on-fetch="(data) => (provincesOptions = data)"
-        auto-load
-    />
-    <VnSection
-        :data-key="dataKey"
-        :columns="columns"
-        prefix="supplier"
-        :array-data-props="{
-            url: 'Suppliers/filter',
-            order: 'id ASC',
+    <VnSearchbar data-key="SuppliersList" :limit="20" :label="t('Search suppliers')" />
+    <RightMenu>
+        <template #right-panel>
+            <SupplierListFilter data-key="SuppliersList" />
+        </template>
+    </RightMenu>
+    <VnTable
+        ref="tableRef"
+        data-key="SuppliersList"
+        url="Suppliers/filter"
+        redirect="supplier"
+        :create="{
+            urlCreate: 'Suppliers/newSupplier',
+            title: t('Create Supplier'),
+            onDataSaved: ({ id }) => tableRef.redirect(id),
+            formInitialData: {},
+            mapper: (data) => {
+                data.name = data.socialName;
+
+                return data;
+            },
         }"
+        :right-search="false"
+        order="id ASC"
+        :columns="columns"
     >
-        <template #body>
-            <VnTable
-                ref="tableRef"
-                :data-key="dataKey"
-                :create="{
-                    urlCreate: 'Suppliers/newSupplier',
-                    title: t('Create Supplier'),
-                    onDataSaved: ({ id }) => tableRef.redirect(id),
-                    formInitialData: {},
-                    mapper: (data) => {
-                        data.name = data.socialName;
-                        delete data.socialName;
-                        return data;
-                    },
-                }"
-                :columns="columns"
-                redirect="supplier"
-                :right-search="false"
-            >
-                <template #more-create-dialog="{ data }">
-                    <VnInput
-                        :label="t('globals.name')"
-                        v-model="data.socialName"
-                        :uppercase="true"
-                    />
-                </template>
-            </VnTable>
-        </template>
-        <template #moreFilterPanel="{ params, searchFn }">
-            <VnSelect
-                :label="t('globals.params.provinceFk')"
-                v-model="params.provinceFk"
-                @update:model-value="searchFn()"
-                :options="provincesOptions"
-                filled
-                dense
-                class="q-px-sm q-pr-lg"
-            />
-        </template>
-    </VnSection>
+        <template #more-create-dialog="{ data }">
+            <VnInput :label="t('globals.name')" v-model="data.socialName" :uppercase="true" />
+            </template>
+    </VnTable>
 </template>
 
 <i18n>
diff --git a/src/pages/Supplier/SupplierListFilter.vue b/src/pages/Supplier/SupplierListFilter.vue
new file mode 100644
index 00000000000..b170a35cc8b
--- /dev/null
+++ b/src/pages/Supplier/SupplierListFilter.vue
@@ -0,0 +1,122 @@
+<script setup>
+import { ref } from 'vue';
+import { useI18n } from 'vue-i18n';
+
+import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import FetchData from 'components/FetchData.vue';
+
+const props = defineProps({
+    dataKey: {
+        type: String,
+        required: true,
+    },
+});
+
+const { t } = useI18n();
+
+const provincesOptions = ref([]);
+const countriesOptions = ref([]);
+</script>
+
+<template>
+    <FetchData
+        url="Provinces"
+        :filter="{ fields: ['id', 'name'], order: 'name ASC'}"
+        @on-fetch="(data) => (provincesOptions = data)"
+        auto-load
+    />
+    <FetchData
+        url="countries"
+        :filter="{ fields: ['id', 'name'], order: 'name ASC'}"
+        @on-fetch="(data) => (countriesOptions = data)"
+        auto-load
+    />
+    <VnFilterPanel
+        :data-key="props.dataKey"
+        :search-button="true"
+        :unremovable-params="['supplierFk']"
+    >
+        <template #tags="{ tag, formatFn }">
+            <div class="q-gutter-x-xs">
+                <strong>{{ t(`params.${tag.label}`) }}: </strong>
+                <span>{{ formatFn(tag.value) }}</span>
+            </div>
+        </template>
+        <template #body="{ params, searchFn }">
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.search"
+                        :label="t('params.search')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.nickname"
+                        :label="t('params.nickname')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput v-model="params.nif" :label="t('params.nif')" is-outlined />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.provinceFk')"
+                        v-model="params.provinceFk"
+                        @update:model-value="searchFn()"
+                        :options="provincesOptions"
+                        option-value="id"
+                        option-label="name"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.countryFk')"
+                        v-model="params.countryFk"
+                        @update:model-value="searchFn()"
+                        :options="countriesOptions"
+                        option-value="id"
+                        option-label="name"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    />
+                </QItemSection>
+            </QItem>
+        </template>
+    </VnFilterPanel>
+</template>
+
+<i18n>
+en:
+    params:
+        search: General search
+        nickname: Alias
+        nif: Tax number
+        provinceFk: Province
+        countryFk: Country
+es:
+    params:
+        search: Búsqueda general
+        nickname: Alias
+        nif: NIF/CIF
+        provinceFk: Provincia
+        countryFk: País
+</i18n>
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
index 055c9a0ffd4..c6a85c287d4 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
@@ -9,9 +9,8 @@ import FetchData from 'components/FetchData.vue';
 import { useStateStore } from 'stores/useStateStore';
 import { toCurrency } from 'filters/index';
 import { useRole } from 'src/composables/useRole';
-import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
-const haveNegatives = defineModel('have-negatives', { type: Boolean, required: true });
+const haveNegatives = defineModel('haveNegatives', { type: Boolean, required: true });
 const formData = defineModel({ type: Object, required: true });
 
 const stateStore = useStateStore();
@@ -183,19 +182,22 @@ onMounted(async () => {
         </QCard>
         <QCard
             v-if="haveNegatives"
-            class="q-pa-xs q-mb-md q-ma-md color-vn-text"
+            class="q-pa-md q-mb-md q-ma-md color-vn-text"
             bordered
             flat
             style="border-color: black"
         >
             <QCardSection horizontal class="flex row items-center">
-                <VnCheckbox
-                    v-model="formData.withoutNegatives"
+                <QCheckbox
                     :label="t('basicData.withoutNegatives')"
-                    :info="t('basicData.withoutNegativesInfo')"
+                    v-model="formData.withoutNegatives"
                     :toggle-indeterminate="false"
-                    size="xs"
                 />
+                <QIcon name="info" size="xs" class="q-ml-sm">
+                    <QTooltip max-width="350px">
+                        {{ t('basicData.withoutNegativesInfo') }}
+                    </QTooltip>
+                </QIcon>
             </QCardSection>
         </QCard>
     </QDrawer>
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
index 9d70fea38a8..cf44815374b 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
@@ -260,7 +260,7 @@ async function getZone(options) {
         auto-load
     />
     <QForm>
-        <VnRow class="row q-gutter-md q-mb-md no-wrap">
+        <VnRow>
             <VnSelect
                 :label="t('ticketList.client')"
                 v-model="clientId"
@@ -296,7 +296,7 @@ async function getZone(options) {
                 :rules="validate('ticketList.warehouse')"
             />
         </VnRow>
-        <VnRow class="row q-gutter-md q-mb-md no-wrap">
+        <VnRow>
             <VnSelect
                 :label="t('basicData.address')"
                 v-model="addressId"
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue
index ef2eb75d6e0..89249b899d0 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataView.vue
@@ -1,7 +1,7 @@
 <script setup>
-import { ref, computed } from 'vue';
+import { ref, onBeforeMount } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useRouter } from 'vue-router';
+import { useRoute, useRouter } from 'vue-router';
 
 import TicketBasicData from './TicketBasicData.vue';
 import TicketBasicDataForm from './TicketBasicDataForm.vue';
@@ -9,69 +9,104 @@ import { useVnConfirm } from 'composables/useVnConfirm';
 
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
-import { useArrayData } from 'src/composables/useArrayData';
 
 const { notify } = useNotify();
+const route = useRoute();
 const router = useRouter();
 const { t } = useI18n();
 const stepperRef = ref(null);
 const { openConfirmationModal } = useVnConfirm();
 
 const step = ref(1);
-const haveNegatives = ref(true);
+const formData = ref({});
+const initialDataLoaded = ref(false);
+const haveNegatives = ref(false);
 
-const ticket = computed(() => useArrayData('Ticket').store?.data);
+const ticketFilter = {
+    include: [
+        { relation: 'address' },
+        {
+            relation: 'client',
+            scope: {
+                fields: [
+                    'salesPersonFk',
+                    'name',
+                    'isActive',
+                    'isFreezed',
+                    'isTaxDataChecked',
+                    'credit',
+                    'email',
+                    'phone',
+                    'mobile',
+                    'hasElectronicInvoice',
+                ],
+                include: {
+                    relation: 'salesPersonUser',
+                    scope: { fields: ['id', 'name'] },
+                },
+            },
+        },
+        { relation: 'invoiceOut' },
+    ],
+};
+
+const getTicketData = async () => {
+    const params = { filter: JSON.stringify(ticketFilter) };
+    const { data } = await axios.get(`tickets/${route.params.id}`, { params });
+    formData.value = data;
+    initialDataLoaded.value = true;
+};
 
 const isFormInvalid = () => {
     return (
-        !ticket.value.clientFk ||
-        !ticket.value.addressFk ||
-        !ticket.value.agencyModeFk ||
-        !ticket.value.companyFk ||
-        !ticket.value.shipped ||
-        !ticket.value.landed ||
-        !ticket.value.zoneFk
+        !formData.value.clientFk ||
+        !formData.value.addressFk ||
+        !formData.value.agencyModeFk ||
+        !formData.value.companyFk ||
+        !formData.value.shipped ||
+        !formData.value.landed ||
+        !formData.value.zoneFk
     );
 };
 
 const getPriceDifference = async () => {
     const params = {
-        landed: ticket.value.landed,
-        addressId: ticket.value.addressFk,
-        agencyModeId: ticket.value.agencyModeFk,
-        zoneId: ticket.value.zoneFk,
-        warehouseId: ticket.value.warehouseFk,
-        shipped: ticket.value.shipped,
+        landed: formData.value.landed,
+        addressId: formData.value.addressFk,
+        agencyModeId: formData.value.agencyModeFk,
+        zoneId: formData.value.zoneFk,
+        warehouseId: formData.value.warehouseFk,
+        shipped: formData.value.shipped,
     };
     const { data } = await axios.post(
-        `tickets/${ticket.value.id}/priceDifference`,
+        `tickets/${formData.value.id}/priceDifference`,
         params
     );
-    ticket.value.sale = data;
+    formData.value.sale = data;
 };
 
 const submit = async () => {
-    if (!ticket.value.option) return notify(t('basicData.chooseAnOption'), 'negative');
+    if (!formData.value.option) return notify(t('basicData.chooseAnOption'), 'negative');
 
     const params = {
-        clientFk: ticket.value.clientFk,
-        nickname: ticket.value.nickname,
-        agencyModeFk: ticket.value.agencyModeFk,
-        addressFk: ticket.value.addressFk,
-        zoneFk: ticket.value.zoneFk,
-        warehouseFk: ticket.value.warehouseFk,
-        companyFk: ticket.value.companyFk,
-        shipped: ticket.value.shipped,
-        landed: ticket.value.landed,
-        isDeleted: ticket.value.isDeleted,
-        option: ticket.value.option,
-        isWithoutNegatives: ticket.value.withoutNegatives,
-        withWarningAccept: ticket.value.withWarningAccept,
+        clientFk: formData.value.clientFk,
+        nickname: formData.value.nickname,
+        agencyModeFk: formData.value.agencyModeFk,
+        addressFk: formData.value.addressFk,
+        zoneFk: formData.value.zoneFk,
+        warehouseFk: formData.value.warehouseFk,
+        companyFk: formData.value.companyFk,
+        shipped: formData.value.shipped,
+        landed: formData.value.landed,
+        isDeleted: formData.value.isDeleted,
+        option: formData.value.option,
+        isWithoutNegatives: formData.value.withoutNegatives,
+        withWarningAccept: formData.value.withWarningAccept,
         keepPrice: false,
     };
 
     const { data } = await axios.post(
-        `tickets/${ticket.value.id}/componentUpdate`,
+        `tickets/${formData.value.id}/componentUpdate`,
         params
     );
 
@@ -83,7 +118,7 @@ const submit = async () => {
 };
 
 const submitWithNegatives = async () => {
-    ticket.value.withWarningAccept = true;
+    formData.value.withWarningAccept = true;
     submit();
 };
 
@@ -95,7 +130,7 @@ const onNextStep = async () => {
         await getPriceDifference();
         stepperRef.value.next();
     } else if (step.value === 2) {
-        if (haveNegatives.value && !ticket.value.withoutNegatives)
+        if (haveNegatives.value && !formData.value.withoutNegatives)
             openConfirmationModal(
                 t('basicData.negativesConfirmTitle'),
                 t('basicData.negativesConfirmMessage'),
@@ -104,10 +139,11 @@ const onNextStep = async () => {
         else submit();
     }
 };
+
+onBeforeMount(async () => await getTicketData());
 </script>
 <template>
     <QStepper
-        v-if="ticket"
         v-model="step"
         ref="stepperRef"
         color="primary"
@@ -119,10 +155,10 @@ const onNextStep = async () => {
         }"
     >
         <QStep :name="1" :title="t('globals.pageTitles.basicData')" :done="step > 1">
-            <TicketBasicDataForm v-model="ticket" />
+            <TicketBasicDataForm v-if="initialDataLoaded" v-model="formData" />
         </QStep>
         <QStep :name="2" :title="t('basicData.priceDifference')">
-            <TicketBasicData v-model="ticket" v-model:have-negatives="haveNegatives" />
+            <TicketBasicData v-model="formData" v-model:have-negatives="haveNegatives" />
         </QStep>
         <template #navigation>
             <QStepperNavigation class="flex justify-between">
diff --git a/src/pages/Ticket/Card/TicketCard.vue b/src/pages/Ticket/Card/TicketCard.vue
index e22d5799ab1..6886a8e577a 100644
--- a/src/pages/Ticket/Card/TicketCard.vue
+++ b/src/pages/Ticket/Card/TicketCard.vue
@@ -1,13 +1,7 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
 import TicketDescriptor from './TicketDescriptor.vue';
-import filter from './TicketFilter.js';
 </script>
 <template>
-    <VnCardBeta
-        data-key="Ticket"
-        url="Tickets"
-        :descriptor="TicketDescriptor"
-        :filter="filter"
-    />
+    <VnCardBeta data-key="Ticket" base-url="Tickets" :descriptor="TicketDescriptor" />
 </template>
diff --git a/src/pages/Ticket/Card/TicketComponents.vue b/src/pages/Ticket/Card/TicketComponents.vue
index 5936ffc2851..842607e0c20 100644
--- a/src/pages/Ticket/Card/TicketComponents.vue
+++ b/src/pages/Ticket/Card/TicketComponents.vue
@@ -19,7 +19,7 @@ import RightMenu from 'src/components/common/RightMenu.vue';
 const route = useRoute();
 const { t } = useI18n();
 const salesRef = ref(null);
-const arrayData = useArrayData('Ticket');
+const arrayData = useArrayData('ticketData');
 const { store } = arrayData;
 
 const ticketData = computed(() => store.data);
diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue
index c5f3233b1de..c9849d631fb 100644
--- a/src/pages/Ticket/Card/TicketDescriptor.vue
+++ b/src/pages/Ticket/Card/TicketDescriptor.vue
@@ -6,11 +6,9 @@ import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
+import useCardDescription from 'src/composables/useCardDescription';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import { toDateTimeFormat } from 'src/filters/date';
-import filter from './TicketFilter.js';
-import FetchData from 'src/components/FetchData.vue';
-import TicketProblems from 'src/components/TicketProblems.vue';
 
 const $props = defineProps({
     id: {
@@ -30,24 +28,100 @@ const { t } = useI18n();
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
-const problems = ref({});
+
+const filter = {
+    include: [
+        {
+            relation: 'address',
+            scope: {
+                fields: ['id', 'name', 'mobile', 'phone', 'incotermsFk'],
+            },
+        },
+        {
+            relation: 'client',
+            scope: {
+                fields: [
+                    'id',
+                    'name',
+                    'salesPersonFk',
+                    'phone',
+                    'mobile',
+                    'email',
+                    'isActive',
+                    'isFreezed',
+                    'isTaxDataChecked',
+                    'hasElectronicInvoice',
+                ],
+                include: [
+                    {
+                        relation: 'user',
+                        scope: {
+                            fields: ['id', 'lang'],
+                        },
+                    },
+                    { relation: 'salesPersonUser' },
+                ],
+            },
+        },
+        {
+            relation: 'ticketState',
+            scope: {
+                include: { relation: 'state' },
+            },
+        },
+        {
+            relation: 'warehouse',
+            scope: {
+                fields: ['id', 'name'],
+            },
+        },
+        {
+            relation: 'agencyMode',
+            scope: {
+                fields: ['id', 'name'],
+            },
+        },
+        {
+            relation: 'zone',
+            scope: {
+                fields: [
+                    'agencyModeFk',
+                    'bonus',
+                    'hour',
+                    'id',
+                    'isVolumetric',
+                    'itemMaxSize',
+                    'm3Max',
+                    'name',
+                    'price',
+                    'travelingDays',
+                ],
+            },
+        },
+    ],
+};
+
+const data = ref(useCardDescription());
 
 function ticketFilter(ticket) {
     return JSON.stringify({ clientFk: ticket.clientFk });
 }
+
+const setData = (entity) => {
+    data.value = useCardDescription(entity.ref, entity.id);
+};
 </script>
 
 <template>
-    <FetchData
-        :url="`Tickets/${entityId}/getTicketProblems`"
-        auto-load
-        @on-fetch="(data) => ([problems] = data)"
-    />
     <CardDescriptor
+        module="Ticket"
         :url="`Tickets/${entityId}`"
         :filter="filter"
-        data-key="Ticket"
+        :title="data.title"
+        :subtitle="data.subtitle"
+        @on-fetch="setData"
         :summary="$props.summary"
+        data-key="ticketData"
         width="lg-width"
     >
         <template #menu="{ entity }">
@@ -93,9 +167,48 @@ function ticketFilter(ticket) {
             <VnLv :label="t('globals.warehouse')" :value="entity.warehouse?.name" />
             <VnLv :label="t('globals.alias')" :value="entity.nickname" />
         </template>
-        <template #icons>
-            <QCardActions class="q-gutter-x-xs">
-                <TicketProblems :row="problems" />
+        <template #icons="{ entity }">
+            <QCardActions class="q-gutter-x-md">
+                <QIcon
+                    v-if="entity.client.isActive == false"
+                    name="vn:disabled"
+                    size="xs"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('Client inactive') }}</QTooltip>
+                </QIcon>
+                <QIcon
+                    v-if="entity.client.isFreezed == true"
+                    name="vn:frozen"
+                    size="xs"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('Client Frozen') }}</QTooltip>
+                </QIcon>
+                <QIcon
+                    v-if="entity?.problem?.includes('hasRisk')"
+                    name="vn:risk"
+                    size="xs"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('Client has debt') }}</QTooltip>
+                </QIcon>
+                <QIcon
+                    v-if="entity.client.isTaxDataChecked == false"
+                    name="vn:no036"
+                    size="xs"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('Client not checked') }}</QTooltip>
+                </QIcon>
+                <QIcon
+                    v-if="entity.isDeleted == true"
+                    name="vn:deletedTicket"
+                    size="xs"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('This ticket is deleted') }}</QTooltip>
+                </QIcon>
             </QCardActions>
         </template>
         <template #actions="{ entity }">
diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue
index f8084ff2f62..166e86978ab 100644
--- a/src/pages/Ticket/Card/TicketExpedition.vue
+++ b/src/pages/Ticket/Card/TicketExpedition.vue
@@ -40,7 +40,7 @@ const expeditionsFilter = computed(() => ({
     order: ['created DESC'],
 }));
 
-const ticketArrayData = useArrayData('Ticket');
+const ticketArrayData = useArrayData('ticketData');
 const ticketStore = ticketArrayData.store;
 const ticketData = computed(() => ticketStore.data);
 
diff --git a/src/pages/Ticket/Card/TicketFilter.js b/src/pages/Ticket/Card/TicketFilter.js
deleted file mode 100644
index 7846f16584e..00000000000
--- a/src/pages/Ticket/Card/TicketFilter.js
+++ /dev/null
@@ -1,72 +0,0 @@
-export default {
-    include: [
-        {
-            relation: 'address',
-            scope: {
-                fields: ['id', 'name', 'mobile', 'phone', 'incotermsFk'],
-            },
-        },
-        {
-            relation: 'client',
-            scope: {
-                fields: [
-                    'id',
-                    'name',
-                    'salesPersonFk',
-                    'phone',
-                    'mobile',
-                    'email',
-                    'isActive',
-                    'isFreezed',
-                    'isTaxDataChecked',
-                    'hasElectronicInvoice',
-                    'credit',
-                ],
-                include: [
-                    {
-                        relation: 'user',
-                        scope: {
-                            fields: ['id', 'lang'],
-                        },
-                    },
-                    { relation: 'salesPersonUser' },
-                ],
-            },
-        },
-        {
-            relation: 'ticketState',
-            scope: {
-                include: { relation: 'state' },
-            },
-        },
-        {
-            relation: 'warehouse',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'agencyMode',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'zone',
-            scope: {
-                fields: [
-                    'agencyModeFk',
-                    'bonus',
-                    'hour',
-                    'id',
-                    'isVolumetric',
-                    'itemMaxSize',
-                    'm3Max',
-                    'name',
-                    'price',
-                    'travelingDays',
-                ],
-            },
-        },
-    ],
-};
diff --git a/src/pages/Ticket/Card/TicketNotes.vue b/src/pages/Ticket/Card/TicketNotes.vue
index feb88bf8438..f558b71cc2b 100644
--- a/src/pages/Ticket/Card/TicketNotes.vue
+++ b/src/pages/Ticket/Card/TicketNotes.vue
@@ -32,7 +32,7 @@ watch(
         crudModelFilter.where.ticketFk = route.params.id;
         store.filter = crudModelFilter;
         await ticketNotesCrudRef.value.reload();
-    },
+    }
 );
 function handleDelete(row) {
     ticketNotesCrudRef.value.remove([row]);
@@ -105,7 +105,7 @@ async function handleSave() {
                     <VnRow v-if="observationTypes.length > rows.length">
                         <QBtn
                             icon="add_circle"
-                            v-shortcut="'+'"
+                            shortcut="+"
                             flat
                             class="fill-icon-on-hover q-ml-md"
                             color="primary"
diff --git a/src/pages/Ticket/Card/TicketPackage.vue b/src/pages/Ticket/Card/TicketPackage.vue
index 5fbf4c80017..8ebdb44017a 100644
--- a/src/pages/Ticket/Card/TicketPackage.vue
+++ b/src/pages/Ticket/Card/TicketPackage.vue
@@ -41,7 +41,7 @@ watch(
         crudModelFilter.where.ticketFk = route.params.id;
         store.filter = crudModelFilter;
         await ticketPackagingsCrudRef.value.reload();
-    },
+    }
 );
 </script>
 
@@ -118,7 +118,7 @@ watch(
                     <VnRow>
                         <QBtn
                             icon="add_circle"
-                            v-shortcut="'+'"
+                            shortcut="+"
                             flat
                             class="fill-icon-on-hover q-ml-md"
                             color="primary"
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 6f02a2ce6aa..f5fb50ecff8 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -14,7 +14,7 @@ import VnImg from 'src/components/ui/VnImg.vue';
 
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
-import TicketTransferProxy from './TicketTransferProxy.vue';
+import TicketTransfer from './TicketTransfer.vue';
 
 import { toCurrency, toPercentage } from 'src/filters';
 import { useArrayData } from 'composables/useArrayData';
@@ -23,7 +23,6 @@ import useNotify from 'src/composables/useNotify.js';
 import axios from 'axios';
 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 route = useRoute();
@@ -35,7 +34,7 @@ const editPriceProxyRef = ref(null);
 const editManaProxyRef = ref(null);
 const stateBtnDropdownRef = ref(null);
 const quasar = useQuasar();
-const arrayData = useArrayData('Ticket');
+const arrayData = useArrayData('ticketData');
 const { store } = arrayData;
 const selectedRows = ref([]);
 const hasSelectedRows = computed(() => selectedRows.value.length > 0);
@@ -627,9 +626,8 @@ watch(
                     @click="setTransferParams()"
                     data-cy="ticketSaleTransferBtn"
                 >
-                    <QTooltip>{{ t('ticketSale.transferLines') }}</QTooltip>
-                    <TicketTransferProxy
-                        class="full-width"
+                    <QTooltip>{{ t('Transfer lines') }}</QTooltip>
+                    <TicketTransfer
                         :transfer="transfer"
                         :ticket="store.data"
                         @refresh-data="resetChanges()"
@@ -699,7 +697,53 @@ watch(
         :disabled-attr="isTicketEditable"
     >
         <template #column-statusIcons="{ row }">
-            <TicketProblems :row="row" />
+            <router-link
+                v-if="row.claim?.claimFk"
+                :to="{ name: 'ClaimBasicData', params: { id: row.claim?.claimFk } }"
+            >
+                <QIcon color="primary" name="vn:claims" size="xs">
+                    <QTooltip>
+                        {{ t('ticketSale.claim') }}:
+                        {{ row.claim?.claimFk }}
+                    </QTooltip>
+                </QIcon>
+            </router-link>
+            <QIcon v-if="row.visible < 0" color="primary" name="warning" size="xs">
+                <QTooltip>
+                    {{ t('ticketSale.visible') }}: {{ row.visible || 0 }}
+                </QTooltip>
+            </QIcon>
+            <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.itemShortage"
+                color="primary"
+                name="vn:unavailable"
+                size="xs"
+            >
+                <QTooltip>
+                    {{ t('ticketSale.noVisible') }}
+                </QTooltip>
+            </QIcon>
+            <QIcon
+                v-if="row.hasComponentLack"
+                color="primary"
+                name="vn:components"
+                size="xs"
+            >
+                <QTooltip>
+                    {{ t('ticketSale.hasComponentLack') }}
+                </QTooltip>
+            </QIcon>
         </template>
         <template #body-cell-picture="{ row }">
             <QTd>
@@ -837,7 +881,7 @@ watch(
             color="primary"
             fab
             icon="add"
-            v-shortcut="'+'"
+            shortcut="+"
             data-cy="ticketSaleAddToBasketBtn"
         />
         <QTooltip class="text-no-wrap">
diff --git a/src/pages/Ticket/Card/TicketService.vue b/src/pages/Ticket/Card/TicketService.vue
index 6ce69a6aa40..d045eadee87 100644
--- a/src/pages/Ticket/Card/TicketService.vue
+++ b/src/pages/Ticket/Card/TicketService.vue
@@ -40,7 +40,7 @@ watch(
     async () => {
         store.filter = crudModelFilter.value;
         await ticketServiceCrudRef.value.reload();
-    },
+    }
 );
 
 onMounted(async () => await getDefaultTaxClass());
@@ -59,7 +59,7 @@ const createRefund = async () => {
         t('service.createRefundSuccess', {
             ticketId: refundTicket.id,
         }),
-        'positive',
+        'positive'
     );
     router.push({ name: 'TicketSale', params: { id: refundTicket.id } });
 };
@@ -225,7 +225,7 @@ async function handleSave() {
             color="primary"
             icon="add"
             @click="ticketServiceCrudRef.insert()"
-            v-shortcut="'+'"
+            shortcut="+"
         />
     </QPageSticky>
 </template>
diff --git a/src/pages/Ticket/Card/TicketSplit.vue b/src/pages/Ticket/Card/TicketSplit.vue
deleted file mode 100644
index e7905726669..00000000000
--- a/src/pages/Ticket/Card/TicketSplit.vue
+++ /dev/null
@@ -1,37 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-
-import VnInputDate from 'src/components/common/VnInputDate.vue';
-import split from './components/split';
-const emit = defineEmits(['ticketTransfered']);
-
-const $props = defineProps({
-    ticket: {
-        type: [Array, Object],
-        default: () => {},
-    },
-});
-
-const splitDate = ref(Date.vnNew());
-
-const splitSelectedRows = async () => {
-    const tickets = Array.isArray($props.ticket) ? $props.ticket : [$props.ticket];
-    await split(tickets, splitDate.value);
-    emit('ticketTransfered', tickets);
-};
-</script>
-
-<template>
-    <VnInputDate class="q-mr-sm" :label="$t('New date')" v-model="splitDate" clearable />
-    <QBtn class="q-mr-sm" color="primary" label="Split" @click="splitSelectedRows"></QBtn>
-</template>
-<style lang="scss">
-.q-table__bottom.row.items-center.q-table__bottom--nodata {
-    border-top: none;
-}
-</style>
-<i18n>
-es:
-    Sales to transfer: Líneas a transferir
-    Destination ticket: Ticket destinatario
-</i18n>
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index 5838efa8803..8cb518823f3 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -20,7 +20,6 @@ import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnToSummary from 'src/components/ui/VnToSummary.vue';
 import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
-import TicketProblems from 'src/components/TicketProblems.vue';
 
 const route = useRoute();
 const { notify } = useNotify();
@@ -41,7 +40,7 @@ const editableStates = ref([]);
 const ticketUrl = ref();
 const grafanaUrl = 'https://grafana.verdnatura.es';
 const stateBtnDropdownRef = ref();
-const descriptorData = useArrayData('Ticket');
+const descriptorData = useArrayData('ticketData');
 
 onMounted(async () => {
     ticketUrl.value = (await getUrl('ticket/')) + entityId.value + '/';
@@ -321,7 +320,83 @@ onMounted(async () => {
                     <template #body="props">
                         <QTr :props="props">
                             <QTd class="q-gutter-x-xs">
-                                <TicketProblems :row="props.row" />
+                                <QBtn
+                                    flat
+                                    round
+                                    icon="vn:claims"
+                                    v-if="props.row.claim"
+                                    color="primary"
+                                    :to="{
+                                        name: 'ClaimCard',
+                                        params: {
+                                            id: props.row.claim.claimFk,
+                                        },
+                                    }"
+                                >
+                                    <QTooltip>
+                                        {{ t('ticket.summary.claim') }}:
+                                        {{ props.row.claim.claimFk }}
+                                    </QTooltip>
+                                </QBtn>
+                                <QBtn
+                                    flat
+                                    round
+                                    icon="vn:claims"
+                                    v-if="props.row.claimBeginning"
+                                    color="primary"
+                                    :to="{
+                                        name: 'ClaimCard',
+                                        params: {
+                                            id: props.row.claimBeginning.claimFk,
+                                        },
+                                    }"
+                                >
+                                    <QTooltip>
+                                        {{ t('ticket.summary.claim') }}:
+                                        {{ props.row.claimBeginning.claimFk }}
+                                    </QTooltip>
+                                </QBtn>
+                                <QIcon
+                                    name="warning"
+                                    v-show="props.row.visible < 0"
+                                    color="primary"
+                                    size="xs"
+                                >
+                                    <QTooltip>
+                                        {{ t('globals.visible') }}:
+                                        {{ props.row.visible }}
+                                    </QTooltip>
+                                </QIcon>
+                                <QIcon
+                                    name="vn:reserved"
+                                    v-show="props.row.reserved"
+                                    color="primary"
+                                    size="xs"
+                                >
+                                    <QTooltip>
+                                        {{ t('ticket.summary.reserved') }}
+                                    </QTooltip>
+                                </QIcon>
+                                <QIcon
+                                    name="vn:unavailable"
+                                    v-show="props.row.itemShortage"
+                                    color="primary"
+                                    size="xs"
+                                >
+                                    <QTooltip>
+                                        {{ t('ticket.summary.itemShortage') }}
+                                    </QTooltip>
+                                </QIcon>
+                                <QIcon
+                                    name="vn:components"
+                                    v-show="props.row.hasComponentLack"
+                                    color="primary"
+                                    size="xs"
+                                >
+                                    <QTooltip>
+                                        {{ t('ticket.summary.hasComponentLack') }}
+                                    </QTooltip>
+                                </QIcon>
                             </QTd>
                             <QTd>
                                 <QBtn class="link" flat>
diff --git a/src/pages/Ticket/Card/TicketTracking.vue b/src/pages/Ticket/Card/TicketTracking.vue
index acf464fb1e1..f4b8544d375 100644
--- a/src/pages/Ticket/Card/TicketTracking.vue
+++ b/src/pages/Ticket/Card/TicketTracking.vue
@@ -19,7 +19,7 @@ watch(
     async (val) => {
         paginateFilter.where.ticketFk = val;
         paginateRef.value.fetch();
-    },
+    }
 );
 
 const paginateFilter = reactive({
@@ -119,7 +119,7 @@ const openCreateModal = () => createTrackingDialogRef.value.show();
                 color="primary"
                 fab
                 icon="add"
-                v-shortcut="'+'"
+                shortcut="+"
             />
             <QTooltip class="text-no-wrap">
                 {{ t('tracking.addState') }}
diff --git a/src/pages/Ticket/Card/TicketTransfer.vue b/src/pages/Ticket/Card/TicketTransfer.vue
index ffa964c920e..005d74a0e4a 100644
--- a/src/pages/Ticket/Card/TicketTransfer.vue
+++ b/src/pages/Ticket/Card/TicketTransfer.vue
@@ -1,11 +1,11 @@
 <script setup>
 import { ref, computed, onMounted } from 'vue';
 import { useI18n } from 'vue-i18n';
+
 import VnInput from 'src/components/common/VnInput.vue';
 import TicketTransferForm from './TicketTransferForm.vue';
 
 import { toDateFormat } from 'src/filters/date.js';
-const emit = defineEmits(['ticketTransfered']);
 
 const $props = defineProps({
     mana: {
@@ -21,15 +21,16 @@ const $props = defineProps({
         default: () => {},
     },
     ticket: {
-        type: [Array, Object],
+        type: Object,
         default: () => {},
     },
 });
 
-onMounted(() => (_transfer.value = $props.transfer));
 const { t } = useI18n();
+const QPopupProxyRef = ref(null);
 const transferFormRef = ref(null);
 const _transfer = ref();
+
 const transferLinesColumns = computed(() => [
     {
         label: t('ticketList.id'),
@@ -85,74 +86,76 @@ const handleRowClick = (row) => {
         transferFormRef.value.transferSales(ticketId);
     }
 };
+
+onMounted(() => (_transfer.value = $props.transfer));
 </script>
 
 <template>
-    <QTable
-        :rows="transfer.sales"
-        :columns="transferLinesColumns"
-        :title="t('Sales to transfer')"
-        row-key="id"
-        :pagination="{ rowsPerPage: 0 }"
-        class="full-width q-mt-md"
-        :no-data-label="t('globals.noResults')"
-    >
-        <template #body-cell-quantity="{ row }">
-            <QTd @click.stop>
-                <VnInput
-                    v-model.number="row.quantity"
-                    :clearable="false"
-                    style="max-width: 60px"
-                />
-            </QTd>
-        </template>
-    </QTable>
-    <QSeparator vertical spaced />
-    <QTable
-        v-if="transfer.lastActiveTickets"
-        :rows="transfer.lastActiveTickets"
-        :columns="destinationTicketColumns"
-        :title="t('Destination ticket')"
-        row-key="id"
-        class="full-width q-mt-md"
-        @row-click="(_, row) => handleRowClick(row)"
-        :no-data-label="t('globals.noResults')"
-        :pagination="{ rowsPerPage: 0 }"
-    >
-        <template #body-cell-address="{ row }">
-            <QTd @click.stop>
-                <span>
-                    {{ row.nickname }}
-                    {{ row.name }}
-                    {{ row.street }}
-                    {{ row.postalCode }}
-                    {{ row.city }}
-                </span>
-                <QTooltip>
-                    {{ row.nickname }}
-                    {{ row.name }}
-                    {{ row.street }}
-                    {{ row.postalCode }}
-                    {{ row.city }}
-                </QTooltip>
-            </QTd>
-        </template>
+    <QPopupProxy ref="QPopupProxyRef" data-cy="ticketTransferPopup">
+        <QCard class="q-px-md" style="display: flex; width: 80vw">
+            <QTable
+                :rows="transfer.sales"
+                :columns="transferLinesColumns"
+                :title="t('Sales to transfer')"
+                row-key="id"
+                :pagination="{ rowsPerPage: 0 }"
+                class="full-width q-mt-md"
+                :no-data-label="t('globals.noResults')"
+            >
+                <template #body-cell-quantity="{ row }">
+                    <QTd @click.stop>
+                        <VnInput
+                            v-model.number="row.quantity"
+                            :clearable="false"
+                            style="max-width: 60px"
+                        />
+                    </QTd>
+                </template>
+            </QTable>
+            <QSeparator vertical spaced />
+            <QTable
+                v-if="transfer.lastActiveTickets"
+                :rows="transfer.lastActiveTickets"
+                :columns="destinationTicketColumns"
+                :title="t('Destination ticket')"
+                row-key="id"
+                class="full-width q-mt-md"
+                @row-click="(_, row) => handleRowClick(row)"
+            >
+                <template #body-cell-address="{ row }">
+                    <QTd @click.stop>
+                        <span>
+                            {{ row.nickname }}
+                            {{ row.name }}
+                            {{ row.street }}
+                            {{ row.postalCode }}
+                            {{ row.city }}
+                        </span>
+                        <QTooltip>
+                            {{ row.nickname }}
+                            {{ row.name }}
+                            {{ row.street }}
+                            {{ row.postalCode }}
+                            {{ row.city }}
+                        </QTooltip>
+                    </QTd>
+                </template>
 
-        <template #no-data>
-            <TicketTransferForm ref="transferFormRef" v-bind="$props" />
-        </template>
-        <template #bottom>
-            <TicketTransferForm ref="transferFormRef" v-bind="$props" />
-        </template>
-    </QTable>
+                <template #no-data>
+                    <TicketTransferForm ref="transferFormRef" v-bind="$props" />
+                </template>
+                <template #bottom>
+                    <TicketTransferForm ref="transferFormRef" v-bind="$props" />
+                </template>
+            </QTable>
+        </QCard>
+    </QPopupProxy>
 </template>
-<style lang="scss">
-.q-table__bottom.row.items-center.q-table__bottom--nodata {
-    border-top: none;
-}
-</style>
+
 <i18n>
 es:
     Sales to transfer: Líneas a transferir
     Destination ticket: Ticket destinatario
+    Transfer to ticket: Transferir a ticket
+    New ticket: Nuevo ticket
 </i18n>
diff --git a/src/pages/Ticket/Card/TicketTransferProxy.vue b/src/pages/Ticket/Card/TicketTransferProxy.vue
deleted file mode 100644
index 3f3f018df3f..00000000000
--- a/src/pages/Ticket/Card/TicketTransferProxy.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-import TicketTransfer from './TicketTransfer.vue';
-import Split from './TicketSplit.vue';
-const emit = defineEmits(['ticketTransfered']);
-
-const $props = defineProps({
-    mana: {
-        type: Number,
-        default: null,
-    },
-    newPrice: {
-        type: Number,
-        default: 0,
-    },
-    transfer: {
-        type: Object,
-        default: () => {},
-    },
-    ticket: {
-        type: [Array, Object],
-        default: () => {},
-    },
-    split: {
-        type: Boolean,
-        default: false,
-    },
-});
-
-const popupProxyRef = ref(null);
-const splitRef = ref(null);
-const transferRef = ref(null);
-</script>
-
-<template>
-    <QPopupProxy ref="popupProxyRef" data-cy="ticketTransferPopup">
-        <div class="flex row items-center q-ma-lg" v-if="$props.split">
-            <Split
-                ref="splitRef"
-                @splitSelectedRows="splitSelectedRows"
-                :ticket="$props.ticket"
-            />
-        </div>
-
-        <div v-else>
-            <TicketTransfer
-                ref="transferRef"
-                :ticket="$props.ticket"
-                :sales="$props.sales"
-                :transfer="$props.transfer"
-            />
-        </div>
-    </QPopupProxy>
-</template>
diff --git a/src/pages/Ticket/Card/components/split.js b/src/pages/Ticket/Card/components/split.js
deleted file mode 100644
index afa1d5cd6ef..00000000000
--- a/src/pages/Ticket/Card/components/split.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import axios from 'axios';
-import notifyResults from 'src/utils/notifyResults';
-
-export default async function (data, date) {
-    const reducedData = data.reduce((acc, item) => {
-        const existing = acc.find(({ ticketFk }) => ticketFk === item.id);
-        if (existing) {
-            existing.sales.push(item.saleFk);
-        } else {
-            acc.push({ ticketFk: item.id, sales: [item.saleFk], date });
-        }
-        return acc;
-    }, []);
-
-    const promises = reducedData.map((params) => axios.post(`Tickets/split`, params));
-
-    const results = await Promise.allSettled(promises);
-
-    notifyResults(results, 'ticketFk');
-
-    return results;
-}
diff --git a/src/pages/Ticket/Negative/TicketLackDetail.vue b/src/pages/Ticket/Negative/TicketLackDetail.vue
deleted file mode 100644
index dcf835d0305..00000000000
--- a/src/pages/Ticket/Negative/TicketLackDetail.vue
+++ /dev/null
@@ -1,198 +0,0 @@
-<script setup>
-import { computed, onMounted, onUnmounted, ref } from 'vue';
-import { useI18n } from 'vue-i18n';
-import ChangeQuantityDialog from './components/ChangeQuantityDialog.vue';
-import ChangeStateDialog from './components/ChangeStateDialog.vue';
-import ChangeItemDialog from './components/ChangeItemDialog.vue';
-import TicketTransferProxy from '../Card/TicketTransferProxy.vue';
-import FetchData from 'src/components/FetchData.vue';
-import { useStateStore } from 'stores/useStateStore';
-import { useState } from 'src/composables/useState';
-
-import { useRoute } from 'vue-router';
-import TicketLackTable from './TicketLackTable.vue';
-import VnPopupProxy from 'src/components/common/VnPopupProxy.vue';
-import ItemProposalProxy from 'src/pages/Item/components/ItemProposalProxy.vue';
-
-import { useQuasar } from 'quasar';
-const quasar = useQuasar();
-const { t } = useI18n();
-const editableStates = ref([]);
-const stateStore = useStateStore();
-const tableRef = ref();
-const changeItemDialogRef = ref(null);
-const changeStateDialogRef = ref(null);
-const changeQuantityDialogRef = ref(null);
-const showProposalDialog = ref(false);
-const showChangeQuantityDialog = ref(false);
-const selectedRows = ref([]);
-const route = useRoute();
-onMounted(() => {
-    stateStore.rightDrawer = false;
-});
-onUnmounted(() => {
-    stateStore.rightDrawer = true;
-});
-
-const entityId = computed(() => route.params.id);
-const item = ref({});
-
-const itemProposalSelected = ref(null);
-const reload = async () => {
-    tableRef.value.tableRef.reload();
-};
-defineExpose({ reload });
-const filter = computed(() => ({
-    scopeDays: route.query.days,
-    showType: true,
-    alertLevelCode: 'FREE',
-    date: Date.vnNew(),
-    warehouseFk: useState().getUser().value.warehouseFk,
-}));
-const itemProposalEvt = (data) => {
-    const { itemProposal } = data;
-    itemProposalSelected.value = itemProposal;
-    reload();
-};
-
-function onBuysFetched(data) {
-    Object.assign(item.value, data[0]);
-}
-const showItemProposal = () => {
-    quasar
-        .dialog({
-            component: ItemProposalProxy,
-            componentProps: {
-                itemLack: tableRef.value.itemLack,
-                replaceAction: true,
-                sales: selectedRows.value,
-            },
-        })
-        .onOk(itemProposalEvt);
-};
-</script>
-
-<template>
-    <FetchData
-        url="States/editableStates"
-        @on-fetch="(data) => (editableStates = data)"
-        auto-load
-    />
-    <FetchData
-        :url="`Items/${entityId}/getCard`"
-        :fields="['longName']"
-        @on-fetch="(data) => (item = data)"
-        auto-load
-    />
-    <FetchData
-        :url="`Buys/latestBuysFilter`"
-        :fields="['longName']"
-        :filter="{ where: { 'i.id': entityId } }"
-        @on-fetch="onBuysFetched"
-        auto-load
-    />
-
-    <TicketLackTable
-        ref="tableRef"
-        :filter="filter"
-        @update:selection="({ value }, _) => (selectedRows = value)"
-    >
-        <template #top-right>
-            <QBtnGroup push class="q-mr-lg" style="column-gap: 1px">
-                <QBtn
-                    data-cy="transferLines"
-                    color="primary"
-                    :disable="!(selectedRows.length === 1)"
-                >
-                    <template #default>
-                        <QIcon name="vn:splitline" />
-                        <QIcon name="vn:ticket" />
-
-                        <QTooltip>{{ t('ticketSale.transferLines') }} </QTooltip>
-                        <TicketTransferProxy
-                            ref="transferFormRef"
-                            split="true"
-                            :ticket="selectedRows"
-                            :transfer="{
-                                sales: selectedRows,
-                                lastActiveTickets: selectedRows.map((row) => row.id),
-                            }"
-                            @ticket-transfered="reload"
-                        ></TicketTransferProxy>
-                    </template>
-                </QBtn>
-                <QBtn
-                    color="primary"
-                    @click="showProposalDialog = true"
-                    :disable="selectedRows.length < 1"
-                    data-cy="itemProposal"
-                >
-                    <QIcon
-                        name="import_export"
-                        class="rotate-90"
-                        @click="showItemProposal"
-                    ></QIcon>
-                    <QTooltip bottom anchor="bottom right">
-                        {{ t('itemProposal') }}
-                    </QTooltip>
-                </QBtn>
-                <VnPopupProxy
-                    data-cy="changeItem"
-                    icon="sync"
-                    :disable="selectedRows.length < 1"
-                    :tooltip="t('negative.detail.modal.changeItem.title')"
-                >
-                    <template #extraIcon> <QIcon name="vn:item" /> </template>
-                    <template v-slot="{ popup }">
-                        <ChangeItemDialog
-                            ref="changeItemDialogRef"
-                            @update-item="popup.hide()"
-                            :selected-rows="selectedRows"
-                    /></template>
-                </VnPopupProxy>
-                <VnPopupProxy
-                    data-cy="changeState"
-                    icon="sync"
-                    :disable="selectedRows.length < 1"
-                    :tooltip="t('negative.detail.modal.changeState.title')"
-                >
-                    <template #extraIcon> <QIcon name="vn:eye" /> </template>
-                    <template v-slot="{ popup }">
-                        <ChangeStateDialog
-                            ref="changeStateDialogRef"
-                            @update-state="popup.hide()"
-                            :selected-rows="selectedRows"
-                    /></template>
-                </VnPopupProxy>
-                <VnPopupProxy
-                    data-cy="changeQuantity"
-                    icon="sync"
-                    :disable="selectedRows.length < 1"
-                    :tooltip="t('negative.detail.modal.changeQuantity.title')"
-                    @click="showChangeQuantityDialog = true"
-                >
-                    <template #extraIcon> <QIcon name="exposure" /> </template>
-                    <template v-slot="{ popup }">
-                        <ChangeQuantityDialog
-                            ref="changeQuantityDialogRef"
-                            @update-quantity="popup.hide()"
-                            :selected-rows="selectedRows"
-                    /></template>
-                </VnPopupProxy> </QBtnGroup
-        ></template>
-    </TicketLackTable>
-</template>
-<style lang="scss" scoped>
-.list-enter-active,
-.list-leave-active {
-    transition: all 1s ease;
-}
-.list-enter-from,
-.list-leave-to {
-    opacity: 0;
-    background-color: $primary;
-}
-.q-table.q-table__container > div:first-child {
-    border-radius: unset;
-}
-</style>
diff --git a/src/pages/Ticket/Negative/TicketLackFilter.vue b/src/pages/Ticket/Negative/TicketLackFilter.vue
deleted file mode 100644
index 3762f453d87..00000000000
--- a/src/pages/Ticket/Negative/TicketLackFilter.vue
+++ /dev/null
@@ -1,175 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-import { useI18n } from 'vue-i18n';
-
-import FetchData from 'components/FetchData.vue';
-import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-const { t } = useI18n();
-const props = defineProps({
-    dataKey: {
-        type: String,
-        required: true,
-    },
-});
-
-const to = Date.vnNew();
-to.setDate(to.getDate() + 1);
-
-const warehouses = ref();
-const categoriesOptions = ref([]);
-const itemTypesRef = ref(null);
-const itemTypesOptions = ref([]);
-
-const itemTypesFilter = {
-    fields: ['id', 'name', 'categoryFk'],
-    include: 'category',
-    order: 'name ASC',
-    where: {},
-};
-const onCategoryChange = async (categoryFk, search) => {
-    if (!categoryFk) {
-        itemTypesFilter.where.categoryFk = null;
-        delete itemTypesFilter.where.categoryFk;
-    } else {
-        itemTypesFilter.where.categoryFk = categoryFk;
-    }
-    search();
-    await itemTypesRef.value.fetch();
-};
-const emit = defineEmits(['set-user-params']);
-
-const setUserParams = (params) => {
-    emit('set-user-params', params);
-};
-</script>
-
-<template>
-    <FetchData url="Warehouses" @on-fetch="(data) => (warehouses = data)" auto-load />
-    <FetchData
-        url="ItemCategories"
-        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
-        @on-fetch="(data) => (categoriesOptions = data)"
-        auto-load
-    />
-
-    <FetchData
-        ref="itemTypesRef"
-        url="ItemTypes"
-        :filter="itemTypesFilter"
-        @on-fetch="(data) => (itemTypesOptions = data)"
-        auto-load
-    />
-
-    <VnFilterPanel
-        :data-key="props.dataKey"
-        :search-button="true"
-        @set-user-params="setUserParams"
-    >
-        <template #tags="{ tag, formatFn }">
-            <div class="q-gutter-x-xs">
-                <strong>{{ t(`negative.${tag.label}`) }}</strong>
-                <span>{{ formatFn(tag.value) }}</span>
-            </div>
-        </template>
-        <template #body="{ params, searchFn }">
-            <QList dense class="q-gutter-y-sm q-mt-sm">
-                <QItem>
-                    <QItemSection>
-                        <VnInput
-                            v-model="params.days"
-                            :label="t('negative.days')"
-                            dense
-                            is-outlined
-                            type="number"
-                            @update:model-value="
-                                (value) => {
-                                    setUserParams(params);
-                                }
-                            "
-                        />
-                    </QItemSection>
-                </QItem>
-                <QItem>
-                    <QItemSection>
-                        <VnInput
-                            v-model="params.id"
-                            :label="t('negative.id')"
-                            dense
-                            is-outlined
-                        />
-                    </QItemSection>
-                </QItem>
-                <QItem>
-                    <QItemSection>
-                        <VnInput
-                            v-model="params.producer"
-                            :label="t('negative.producer')"
-                            dense
-                            is-outlined
-                        />
-                    </QItemSection>
-                </QItem>
-                <QItem>
-                    <QItemSection>
-                        <VnInput
-                            v-model="params.origen"
-                            :label="t('negative.origen')"
-                            dense
-                            is-outlined
-                        />
-                    </QItemSection> </QItem
-                ><QItem>
-                    <QItemSection v-if="categoriesOptions">
-                        <VnSelect
-                            :label="t('negative.categoryFk')"
-                            v-model="params.categoryFk"
-                            @update:model-value="
-                                ($event) => onCategoryChange($event, searchFn)
-                            "
-                            :options="categoriesOptions"
-                            option-value="id"
-                            option-label="name"
-                            hide-selected
-                            dense
-                            outlined
-                            rounded
-                        /> </QItemSection
-                    ><QItemSection v-else>
-                        <QSkeleton class="full-width" type="QSelect" />
-                    </QItemSection>
-                </QItem>
-                <QItem>
-                    <QItemSection v-if="itemTypesOptions">
-                        <VnSelect
-                            :label="t('negative.type')"
-                            v-model="params.typeFk"
-                            @update:model-value="searchFn()"
-                            :options="itemTypesOptions"
-                            option-value="id"
-                            option-label="name"
-                            hide-selected
-                            dense
-                            outlined
-                            rounded
-                        >
-                            <template #option="scope">
-                                <QItem v-bind="scope.itemProps">
-                                    <QItemSection>
-                                        <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
-                                        <QItemLabel caption>{{
-                                            scope.opt?.category?.name
-                                        }}</QItemLabel>
-                                    </QItemSection>
-                                </QItem>
-                            </template>
-                        </VnSelect> </QItemSection
-                    ><QItemSection v-else>
-                        <QSkeleton class="full-width" type="QSelect" />
-                    </QItemSection>
-                </QItem>
-            </QList>
-        </template>
-    </VnFilterPanel>
-</template>
diff --git a/src/pages/Ticket/Negative/TicketLackList.vue b/src/pages/Ticket/Negative/TicketLackList.vue
deleted file mode 100644
index d1e8b823ab1..00000000000
--- a/src/pages/Ticket/Negative/TicketLackList.vue
+++ /dev/null
@@ -1,227 +0,0 @@
-<script setup>
-import { computed, ref, reactive } from 'vue';
-import { useI18n } from 'vue-i18n';
-import { useStateStore } from 'stores/useStateStore';
-import VnTable from 'components/VnTable/VnTable.vue';
-import { onBeforeMount } from 'vue';
-import { dashIfEmpty, toDate, toHour } from 'src/filters';
-import { useRouter } from 'vue-router';
-import { useState } from 'src/composables/useState';
-import { useRole } from 'src/composables/useRole';
-import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
-import RightMenu from 'src/components/common/RightMenu.vue';
-import TicketLackFilter from './TicketLackFilter.vue';
-onBeforeMount(() => {
-    stateStore.$state.rightDrawer = true;
-});
-const router = useRouter();
-const stateStore = useStateStore();
-const { t } = useI18n();
-const selectedRows = ref([]);
-const tableRef = ref();
-const filterParams = ref({});
-const negativeParams = reactive({
-    days: useRole().likeAny('buyer') ? 2 : 0,
-    warehouseFk: useState().getUser().value.warehouseFk,
-});
-const redirectToCreateView = ({ itemFk }) => {
-    router.push({
-        name: 'NegativeDetail',
-        params: { id: itemFk },
-        query: { days: filterParams.value.days ?? negativeParams.days },
-    });
-};
-const columns = computed(() => [
-    {
-        name: 'date',
-        align: 'center',
-        label: t('negative.date'),
-        format: ({ timed }) => toDate(timed),
-        sortable: true,
-        cardVisible: true,
-        isId: true,
-        columnFilter: {
-            component: 'date',
-        },
-    },
-    {
-        columnClass: 'shrink',
-        name: 'timed',
-        align: 'center',
-        label: t('negative.timed'),
-        format: ({ timed }) => toHour(timed),
-        sortable: true,
-        cardVisible: true,
-        columnFilter: {
-            component: 'time',
-        },
-    },
-    {
-        name: 'itemFk',
-        align: 'center',
-        label: t('negative.id'),
-        format: ({ itemFk }) => itemFk,
-        sortable: true,
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-            columnClass: 'shrink',
-        },
-    },
-    {
-        name: 'longName',
-        align: 'center',
-        label: t('negative.longName'),
-        field: ({ longName }) => longName,
-
-        sortable: true,
-        headerStyle: 'width: 350px',
-        cardVisible: true,
-        columnClass: 'expand',
-    },
-    {
-        name: 'producer',
-        align: 'center',
-        label: t('negative.supplier'),
-        field: ({ producer }) => dashIfEmpty(producer),
-        sortable: true,
-        columnClass: 'shrink',
-    },
-    {
-        name: 'inkFk',
-        align: 'center',
-        label: t('negative.colour'),
-        field: ({ inkFk }) => inkFk,
-        sortable: true,
-        cardVisible: true,
-    },
-    {
-        name: 'size',
-        align: 'center',
-        label: t('negative.size'),
-        field: ({ size }) => size,
-        sortable: true,
-        cardVisible: true,
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-            columnClass: 'shrink',
-        },
-    },
-    {
-        name: 'category',
-        align: 'center',
-        label: t('negative.origen'),
-        field: ({ category }) => dashIfEmpty(category),
-        sortable: true,
-        cardVisible: true,
-    },
-    {
-        name: 'lack',
-        align: 'center',
-        label: t('negative.lack'),
-        field: ({ lack }) => lack,
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-            columnClass: 'shrink',
-        },
-        sortable: true,
-        headerStyle: 'padding-center: 33px',
-        cardVisible: true,
-    },
-    {
-        name: 'tableActions',
-        align: 'center',
-        actions: [
-            {
-                title: t('Open details'),
-                icon: 'edit',
-                action: redirectToCreateView,
-                isPrimary: true,
-            },
-        ],
-    },
-]);
-
-const setUserParams = (params) => {
-    filterParams.value = params;
-};
-</script>
-
-<template>
-    <RightMenu>
-        <template #right-panel>
-            <TicketLackFilter data-key="NegativeList" @set-user-params="setUserParams" />
-        </template>
-    </RightMenu>
-    {{ filterRef }}
-    <VnTable
-        ref="tableRef"
-        data-key="NegativeList"
-        :url="`Tickets/itemLack`"
-        :order="['itemFk DESC, date DESC, timed DESC']"
-        :user-params="negativeParams"
-        auto-load
-        :columns="columns"
-        default-mode="table"
-        :right-search="false"
-        :is-editable="false"
-        :use-model="true"
-        :map-key="false"
-        :row-click="redirectToCreateView"
-        v-model:selected="selectedRows"
-        :create="false"
-        :crud-model="{
-            disableInfiniteScroll: true,
-        }"
-        :table="{
-            'row-key': 'itemFk',
-            selection: 'multiple',
-        }"
-    >
-        <template #column-itemFk="{ row }">
-            <div
-                style="display: flex; justify-content: space-around; align-items: center"
-            >
-                <span @click.stop>{{ row.itemFk }}</span>
-            </div>
-        </template>
-        <template #column-longName="{ row }">
-            <span class="link" @click.stop>
-                {{ row.longName }}
-                <ItemDescriptorProxy :id="row.itemFk" />
-            </span>
-        </template>
-    </VnTable>
-</template>
-
-<style lang="scss" scoped>
-.list {
-    max-height: 100%;
-    padding: 15px;
-    width: 100%;
-}
-
-.grid-style-transition {
-    transition:
-        transform 0.28s,
-        background-color 0.28s;
-}
-
-#true {
-    background-color: $positive;
-}
-
-#false {
-    background-color: $negative;
-}
-
-div.q-dialog__inner > div {
-    max-width: fit-content !important;
-}
-.q-btn-group > .q-btn-item:not(:first-child) {
-    border-top-left-radius: 0;
-    border-bottom-left-radius: 0;
-}
-</style>
diff --git a/src/pages/Ticket/Negative/TicketLackTable.vue b/src/pages/Ticket/Negative/TicketLackTable.vue
deleted file mode 100644
index 176e8f7adf9..00000000000
--- a/src/pages/Ticket/Negative/TicketLackTable.vue
+++ /dev/null
@@ -1,356 +0,0 @@
-<script setup>
-import FetchedTags from 'components/ui/FetchedTags.vue';
-import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
-import { computed, ref, watch } from 'vue';
-import { useI18n } from 'vue-i18n';
-import axios from 'axios';
-import FetchData from 'src/components/FetchData.vue';
-import { toDate, toHour } from 'src/filters';
-import useNotify from 'src/composables/useNotify.js';
-import ZoneDescriptorProxy from 'pages/Zone/Card/ZoneDescriptorProxy.vue';
-import { useRoute } from 'vue-router';
-import VnTable from 'src/components/VnTable/VnTable.vue';
-import TicketDescriptorProxy from '../Card/TicketDescriptorProxy.vue';
-import VnInputNumber from 'src/components/common/VnInputNumber.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
-
-const $props = defineProps({
-    filter: {
-        type: Object,
-        default: () => ({}),
-    },
-});
-
-watch(
-    () => $props.filter,
-    (v) => {
-        filterLack.value.where = v;
-        tableRef.value.reload(filterLack);
-    },
-);
-
-const filterLack = ref({
-    include: [
-        {
-            relation: 'workers',
-            scope: {
-                fields: ['id', 'firstName'],
-            },
-        },
-    ],
-    where: { ...$props.filter },
-    order: 'ts.alertLevelCode ASC',
-});
-
-const selectedRows = ref([]);
-const { t } = useI18n();
-const { notify } = useNotify();
-const entityId = computed(() => route.params.id);
-const item = ref({});
-const route = useRoute();
-const columns = computed(() => [
-    {
-        name: 'status',
-        align: 'center',
-        sortable: false,
-        columnClass: 'shrink',
-        columnFilter: false,
-    },
-    {
-        name: 'ticketFk',
-        label: t('negative.detail.ticketFk'),
-        align: 'center',
-        sortable: true,
-        columnFilter: {
-            component: 'input',
-            type: 'number',
-        },
-    },
-    {
-        name: 'shipped',
-        label: t('negative.detail.shipped'),
-        field: 'shipped',
-        align: 'center',
-        format: ({ shipped }) => toDate(shipped),
-        sortable: true,
-        columnFilter: {
-            component: 'date',
-            columnClass: 'shrink',
-        },
-    },
-    {
-        name: 'minTimed',
-        label: t('negative.detail.theoreticalhour'),
-        field: 'minTimed',
-        align: 'center',
-        sortable: true,
-        component: 'time',
-        columnFilter: {},
-    },
-    {
-        name: 'alertLevelCode',
-        label: t('negative.detail.state'),
-        columnFilter: {
-            name: 'alertLevelCode',
-            component: 'select',
-            attrs: {
-                url: 'AlertLevels',
-                fields: ['name', 'code'],
-                optionLabel: 'code',
-                optionValue: 'code',
-            },
-        },
-        align: 'center',
-        sortable: true,
-    },
-    {
-        name: 'zoneName',
-        label: t('negative.detail.zoneName'),
-        field: 'zoneName',
-        align: 'center',
-        sortable: true,
-    },
-    {
-        name: 'nickname',
-        label: t('negative.detail.nickname'),
-        field: 'nickname',
-        align: 'center',
-        sortable: true,
-    },
-    {
-        name: 'quantity',
-        label: t('negative.detail.quantity'),
-        field: 'quantity',
-        sortable: true,
-        component: 'input',
-        type: 'number',
-    },
-]);
-
-const emit = defineEmits(['update:selection']);
-const itemLack = ref(null);
-const fetchItemLack = ref(null);
-const tableRef = ref(null);
-defineExpose({ tableRef, itemLack });
-watch(selectedRows, () => emit('update:selection', selectedRows));
-const getInputEvents = ({ col, ...rows }) => ({
-    'update:modelValue': () => saveChange(col.name, rows),
-    'keyup.enter': () => saveChange(col.name, rows),
-});
-const saveChange = async (field, { row }) => {
-    try {
-        switch (field) {
-            case 'alertLevelCode':
-                await axios.post(`Tickets/state`, {
-                    ticketFk: row.ticketFk,
-                    code: row[field],
-                });
-                break;
-
-            case 'quantity':
-                await axios.post(`Sales/${row.saleFk}/updateQuantity`, {
-                    quantity: +row.quantity,
-                });
-                break;
-        }
-        notify('globals.dataSaved', 'positive');
-        fetchItemLack.value.fetch();
-    } catch (err) {
-        console.error('Error saving changes', err);
-        f;
-    }
-};
-
-function onBuysFetched(data) {
-    Object.assign(item.value, data[0]);
-}
-</script>
-
-<template>
-    <FetchData
-        ref="fetchItemLack"
-        :url="`Tickets/itemLack`"
-        :params="{ id: entityId }"
-        @on-fetch="(data) => (itemLack = data[0])"
-        auto-load
-    />
-    <FetchData
-        :url="`Items/${entityId}/getCard`"
-        :fields="['longName']"
-        @on-fetch="(data) => (item = data)"
-        auto-load
-    />
-    <FetchData
-        :url="`Buys/latestBuysFilter`"
-        :fields="['longName']"
-        :filter="{ where: { 'i.id': entityId } }"
-        @on-fetch="onBuysFetched"
-        auto-load
-    />
-    <VnTable
-        ref="tableRef"
-        data-key="NegativeItem"
-        :map-key="false"
-        :url="`Tickets/itemLack/${entityId}`"
-        :columns="columns"
-        auto-load
-        :create="false"
-        :create-as-dialog="false"
-        :use-model="true"
-        :filter="filterLack"
-        :order="['ts.alertLevelCode ASC']"
-        :table="{
-            'row-key': 'id',
-            selection: 'multiple',
-        }"
-        dense
-        :is-editable="true"
-        :row-click="false"
-        :right-search="false"
-        :right-search-icon="false"
-        v-model:selected="selectedRows"
-        :disable-option="{ card: true }"
-    >
-        <template #top-left>
-            <div style="display: flex; align-items: center" v-if="itemLack">
-                <!-- <VnImg :id="itemLack.itemFk" class="rounded image-wrapper"></VnImg> -->
-                <div class="flex column" style="align-items: center">
-                    <QBadge
-                        ref="badgeLackRef"
-                        class="q-ml-xs"
-                        text-color="white"
-                        :color="itemLack.lack === 0 ? 'positive' : 'negative'"
-                        :label="itemLack.lack"
-                    />
-                </div>
-                <div class="flex column left" style="align-items: flex-start">
-                    <QBtn flat class="link text-blue">
-                        {{ item?.longName ?? item.name }}
-                        <ItemDescriptorProxy :id="entityId" />
-                        <FetchedTags class="q-ml-md" :item="item" :columns="7" />
-                    </QBtn>
-                </div>
-            </div>
-        </template>
-        <template #top-right>
-            <slot name="top-right" />
-        </template>
-
-        <template #column-status="{ row }">
-            <QTd style="min-width: 150px">
-                <div class="icon-container">
-                    <QIcon
-                        v-if="row.isBasket"
-                        name="vn:basket"
-                        color="primary"
-                        class="cursor-pointer"
-                        size="xs"
-                    >
-                        <QTooltip>{{ t('negative.detail.isBasket') }}</QTooltip>
-                    </QIcon>
-                    <QIcon
-                        v-if="row.hasToIgnore"
-                        name="star"
-                        color="primary"
-                        class="cursor-pointer fill-icon"
-                        size="xs"
-                    >
-                        <QTooltip>{{ t('negative.detail.hasToIgnore') }}</QTooltip>
-                    </QIcon>
-                    <QIcon
-                        v-if="row.hasObservation"
-                        name="change_circle"
-                        color="primary"
-                        class="cursor-pointer"
-                        size="xs"
-                    >
-                        <QTooltip>{{
-                            t('negative.detail.hasObservation')
-                        }}</QTooltip> </QIcon
-                    ><QIcon
-                        v-if="row.isRookie"
-                        name="vn:Person"
-                        size="xs"
-                        color="primary"
-                        class="cursor-pointer"
-                    >
-                        <QTooltip>{{ t('negative.detail.isRookie') }}</QTooltip>
-                    </QIcon>
-                    <QIcon
-                        v-if="row.peticionCompra"
-                        name="vn:buyrequest"
-                        size="xs"
-                        color="primary"
-                        class="cursor-pointer"
-                    >
-                        <QTooltip>{{ t('negative.detail.peticionCompra') }}</QTooltip>
-                    </QIcon>
-                    <QIcon
-                        v-if="row.turno"
-                        name="vn:calendar"
-                        size="xs"
-                        color="primary"
-                        class="cursor-pointer"
-                    >
-                        <QTooltip>{{ t('negative.detail.turno') }}</QTooltip>
-                    </QIcon>
-                </div></QTd
-            >
-        </template>
-        <template #column-nickname="{ row }">
-            <span class="link" @click.stop>
-                {{ row.nickname }}
-                <CustomerDescriptorProxy :id="row.customerId" />
-            </span>
-        </template>
-        <template #column-ticketFk="{ row }">
-            <span class="q-pa-sm link">
-                {{ row.id }}
-                <TicketDescriptorProxy :id="row.id" />
-            </span>
-        </template>
-        <template #column-alertLevelCode="props">
-            <VnSelect
-                url="States/editableStates"
-                auto-load
-                hide-selected
-                option-value="id"
-                option-label="name"
-                v-model="props.row.alertLevelCode"
-                v-on="getInputEvents(props)"
-            />
-        </template>
-
-        <template #column-zoneName="{ row }">
-            <span class="link">{{ row.zoneName }}</span>
-            <ZoneDescriptorProxy :id="row.zoneFk" />
-        </template>
-        <template #column-quantity="props">
-            <VnInputNumber
-                v-model.number="props.row.quantity"
-                v-on="getInputEvents(props)"
-            ></VnInputNumber>
-        </template>
-    </VnTable>
-</template>
-<style lang="scss" scoped>
-.icon-container {
-    display: grid;
-    grid-template-columns: repeat(3, 0.2fr);
-    row-gap: 5px; /* Ajusta el espacio entre los iconos según sea necesario */
-}
-.icon-container > * {
-    width: 100%;
-    height: auto;
-}
-.list-enter-active,
-.list-leave-active {
-    transition: all 1s ease;
-}
-.list-enter-from,
-.list-leave-to {
-    opacity: 0;
-    background-color: $primary;
-}
-</style>
diff --git a/src/pages/Ticket/Negative/components/ChangeItemDialog.vue b/src/pages/Ticket/Negative/components/ChangeItemDialog.vue
deleted file mode 100644
index e419b85c080..00000000000
--- a/src/pages/Ticket/Negative/components/ChangeItemDialog.vue
+++ /dev/null
@@ -1,90 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-import axios from 'axios';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import notifyResults from 'src/utils/notifyResults';
-const emit = defineEmits(['update-item']);
-
-const showChangeItemDialog = ref(false);
-const newItem = ref(null);
-const $props = defineProps({
-    selectedRows: {
-        type: Array,
-        default: () => [],
-    },
-});
-
-const updateItem = async () => {
-    try {
-        showChangeItemDialog.value = true;
-        const rowsToUpdate = $props.selectedRows.map(({ saleFk, quantity }) =>
-            axios.post(`Sales/replaceItem`, {
-                saleFk,
-                substitutionFk: newItem.value,
-                quantity,
-            }),
-        );
-        const result = await Promise.allSettled(rowsToUpdate);
-        notifyResults(result, 'saleFk');
-        emit('update-item', newItem.value);
-    } catch (err) {
-        console.error('Error updating item:', err);
-        return err;
-    }
-};
-</script>
-
-<template>
-    <QCard class="q-pa-sm">
-        <QCardSection class="row items-center justify-center column items-stretch">
-            {{ showChangeItemDialog }}
-            <span>{{ $t('negative.detail.modal.changeItem.title') }}</span>
-            <VnSelect
-                url="Items/WithName"
-                :fields="['id', 'name']"
-                :sort-by="['id DESC']"
-                :options="items"
-                option-label="name"
-                option-value="id"
-                v-model="newItem"
-            >
-            </VnSelect>
-        </QCardSection>
-        <QCardActions align="right">
-            <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
-            <QBtn
-                :label="$t('globals.confirm')"
-                color="primary"
-                :disable="!newItem"
-                @click="updateItem"
-                unelevated
-                autofocus
-            /> </QCardActions
-    ></QCard>
-</template>
-
-<style lang="scss" scoped>
-.list {
-    max-height: 100%;
-    padding: 15px;
-    width: 100%;
-}
-
-.grid-style-transition {
-    transition:
-        transform 0.28s,
-        background-color 0.28s;
-}
-
-#true {
-    background-color: $positive;
-}
-
-#false {
-    background-color: $negative;
-}
-
-div.q-dialog__inner > div {
-    max-width: fit-content !important;
-}
-</style>
diff --git a/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue b/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue
deleted file mode 100644
index 2e9aac4f0ab..00000000000
--- a/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-import axios from 'axios';
-import VnInput from 'src/components/common/VnInput.vue';
-import notifyResults from 'src/utils/notifyResults';
-
-const showChangeQuantityDialog = ref(false);
-const newQuantity = ref(null);
-const $props = defineProps({
-    selectedRows: {
-        type: Array,
-        default: () => [],
-    },
-});
-const emit = defineEmits(['update-quantity']);
-const updateQuantity = async () => {
-    try {
-        showChangeQuantityDialog.value = true;
-        const rowsToUpdate = $props.selectedRows.map(({ saleFk }) =>
-            axios.post(`Sales/${saleFk}/updateQuantity`, {
-                saleFk,
-                quantity: +newQuantity.value,
-            }),
-        );
-
-        const result = await Promise.allSettled(rowsToUpdate);
-        notifyResults(result, 'saleFk');
-
-        emit('update-quantity', newQuantity.value);
-    } catch (err) {
-        return err;
-    }
-};
-</script>
-
-<template>
-    <QCard class="q-pa-sm">
-        <QCardSection class="row items-center justify-center column items-stretch">
-            <span>{{ $t('negative.detail.modal.changeQuantity.title') }}</span>
-            <VnInput
-                type="number"
-                :min="0"
-                :label="$t('negative.detail.modal.changeQuantity.placeholder')"
-                v-model="newQuantity"
-            />
-        </QCardSection>
-        <QCardActions align="right">
-            <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
-            <QBtn
-                :label="$t('globals.confirm')"
-                color="primary"
-                :disable="!newQuantity || newQuantity < 0"
-                @click="updateQuantity"
-                unelevated
-                autofocus
-            /> </QCardActions
-    ></QCard>
-</template>
-
-<style lang="scss" scoped>
-.list {
-    max-height: 100%;
-    padding: 15px;
-    width: 100%;
-}
-
-.grid-style-transition {
-    transition:
-        transform 0.28s,
-        background-color 0.28s;
-}
-
-#true {
-    background-color: $positive;
-}
-
-#false {
-    background-color: $negative;
-}
-
-div.q-dialog__inner > div {
-    max-width: fit-content !important;
-}
-</style>
diff --git a/src/pages/Ticket/Negative/components/ChangeStateDialog.vue b/src/pages/Ticket/Negative/components/ChangeStateDialog.vue
deleted file mode 100644
index 1acc7e0ef64..00000000000
--- a/src/pages/Ticket/Negative/components/ChangeStateDialog.vue
+++ /dev/null
@@ -1,91 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-import axios from 'axios';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import FetchData from 'components/FetchData.vue';
-import notifyResults from 'src/utils/notifyResults';
-
-const emit = defineEmits(['update-state']);
-const editableStates = ref([]);
-const showChangeStateDialog = ref(false);
-const newState = ref(null);
-const $props = defineProps({
-    selectedRows: {
-        type: Array,
-        default: () => [],
-    },
-});
-const updateState = async () => {
-    try {
-        showChangeStateDialog.value = true;
-        const rowsToUpdate = $props.selectedRows.map(({ id }) =>
-            axios.post(`Tickets/state`, {
-                ticketFk: id,
-                code: newState.value,
-            }),
-        );
-        const result = await Promise.allSettled(rowsToUpdate);
-        notifyResults(result, 'ticketFk');
-
-        emit('update-state', newState.value);
-    } catch (err) {
-        return err;
-    }
-};
-</script>
-
-<template>
-    <FetchData
-        url="States/editableStates"
-        @on-fetch="(data) => (editableStates = data)"
-        auto-load
-    />
-    <QCard class="q-pa-sm">
-        <QCardSection class="row items-center justify-center column items-stretch">
-            <span>{{ $t('negative.detail.modal.changeState.title') }}</span>
-            <VnSelect
-                :label="$t('negative.detail.modal.changeState.placeholder')"
-                v-model="newState"
-                :options="editableStates"
-                option-label="name"
-                option-value="code"
-            />
-        </QCardSection>
-        <QCardActions align="right">
-            <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
-            <QBtn
-                :label="$t('globals.confirm')"
-                color="primary"
-                :disable="!newState"
-                @click="updateState"
-                unelevated
-                autofocus
-            /> </QCardActions
-    ></QCard>
-</template>
-
-<style lang="scss" scoped>
-.list {
-    max-height: 100%;
-    padding: 15px;
-    width: 100%;
-}
-
-.grid-style-transition {
-    transition:
-        transform 0.28s,
-        background-color 0.28s;
-}
-
-#true {
-    background-color: $positive;
-}
-
-#false {
-    background-color: $negative;
-}
-
-div.q-dialog__inner > div {
-    max-width: fit-content !important;
-}
-</style>
diff --git a/src/pages/Ticket/TicketFuture.vue b/src/pages/Ticket/TicketFuture.vue
index 92911cd2549..0d216bed4fb 100644
--- a/src/pages/Ticket/TicketFuture.vue
+++ b/src/pages/Ticket/TicketFuture.vue
@@ -1,22 +1,24 @@
 <script setup>
-import { ref, computed, reactive, watch } from 'vue';
+import { onMounted, ref, computed, reactive } from 'vue';
 import { useI18n } from 'vue-i18n';
 
+import FetchData from 'components/FetchData.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
 import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
-import VnTable from 'src/components/VnTable/VnTable.vue';
 import TicketFutureFilter from './TicketFutureFilter.vue';
 
 import { dashIfEmpty, toCurrency } from 'src/filters';
 import { useVnConfirm } from 'composables/useVnConfirm';
+import { useArrayData } from 'composables/useArrayData';
 import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
 import useNotify from 'src/composables/useNotify.js';
 import { useState } from 'src/composables/useState';
 import { toDateTimeFormat } from 'src/filters/date.js';
 import axios from 'axios';
-import TicketProblems from 'src/components/TicketProblems.vue';
 
 const state = useState();
 const { t } = useI18n();
@@ -24,126 +26,214 @@ const { openConfirmationModal } = useVnConfirm();
 const { notify } = useNotify();
 const user = state.getUser();
 
+const itemPackingTypesOptions = ref([]);
 const selectedTickets = ref([]);
-const vnTableRef = ref({});
-const originElRef = ref(null);
-const destinationElRef = ref(null);
+
+const exprBuilder = (param, value) => {
+    switch (param) {
+        case 'id':
+            return { id: value };
+        case 'futureId':
+            return { futureId: value };
+        case 'liters':
+            return { liters: value };
+        case 'lines':
+            return { lines: value };
+        case 'iptColFilter':
+            return { ipt: { like: `%${value}%` } };
+        case 'futureIptColFilter':
+            return { futureIpt: { like: `%${value}%` } };
+        case 'totalWithVat':
+            return { totalWithVat: value };
+    }
+};
+
 const userParams = reactive({
     futureScopeDays: Date.vnNew().toISOString(),
     originScopeDays: Date.vnNew().toISOString(),
     warehouseFk: user.value.warehouseFk,
 });
 
+const arrayData = useArrayData('FutureTickets', {
+    url: 'Tickets/getTicketsFuture',
+    userParams: userParams,
+    exprBuilder: exprBuilder,
+});
+const { store } = arrayData;
+
+const params = reactive({
+    futureScopeDays: Date.vnNew(),
+    originScopeDays: Date.vnNew(),
+    warehouseFk: user.value.warehouseFk,
+});
+
+const applyColumnFilter = async (col) => {
+    const paramKey = col.columnFilter?.filterParamKey || col.field;
+    params[paramKey] = col.columnFilter.filterValue;
+    await arrayData.addFilter({ params });
+};
+
+const getInputEvents = (col) => {
+    return col.columnFilter.type === 'select'
+        ? { 'update:modelValue': () => applyColumnFilter(col) }
+        : {
+              'keyup.enter': () => applyColumnFilter(col),
+          };
+};
+
+const tickets = computed(() => store.data);
+
 const ticketColumns = computed(() => [
     {
-        label: '',
+        label: t('futureTickets.problems'),
         name: 'problems',
-        headerClass: 'horizontal-separator',
         align: 'left',
-        columnFilter: false,
+        columnFilter: null,
     },
     {
         label: t('advanceTickets.ticketId'),
-        name: 'id',
+        name: 'ticketId',
         align: 'center',
-        headerClass: 'horizontal-separator',
+        sortable: true,
+        columnFilter: {
+            component: VnInput,
+            type: 'text',
+            filterValue: null,
+            filterParamKey: 'id',
+            event: getInputEvents,
+            attrs: {
+                dense: true,
+            },
+        },
     },
     {
         label: t('futureTickets.shipped'),
         name: 'shipped',
         align: 'left',
-        columnFilter: false,
-        headerClass: 'horizontal-separator',
+        sortable: true,
+        columnFilter: null,
     },
     {
-        align: 'center',
-        class: 'shrink',
         label: t('advanceTickets.ipt'),
         name: 'ipt',
+        field: 'ipt',
+        align: 'left',
+        sortable: true,
         columnFilter: {
-            component: 'select',
+            component: VnSelect,
+            filterParamKey: 'iptColFilter',
+            type: 'select',
+            filterValue: null,
+            event: getInputEvents,
             attrs: {
-                url: 'itemPackingTypes',
-                fields: ['code', 'description'],
-                where: { isActive: true },
-                optionValue: 'code',
-                optionLabel: 'description',
-                inWhere: false,
+                options: itemPackingTypesOptions.value,
+                'option-value': 'code',
+                'option-label': 'description',
+                dense: true,
             },
         },
-        format: (row, dashIfEmpty) => dashIfEmpty(row.ipt),
-        headerClass: 'horizontal-separator',
+        format: (val) => dashIfEmpty(val),
     },
     {
         label: t('ticketList.state'),
         name: 'state',
         align: 'left',
-        columnFilter: false,
-        headerClass: 'horizontal-separator',
+        sortable: true,
+        columnFilter: null,
     },
     {
         label: t('advanceTickets.liters'),
         name: 'liters',
+        field: 'liters',
         align: 'left',
-        headerClass: 'horizontal-separator',
+        sortable: true,
+        columnFilter: {
+            component: VnInput,
+            type: 'text',
+            filterValue: null,
+            event: getInputEvents,
+            attrs: {
+                dense: true,
+            },
+        },
     },
     {
         label: t('advanceTickets.import'),
+        field: 'import',
         name: 'import',
         align: 'left',
-        headerClass: 'horizontal-separator',
-        columnFilter: false,
-        format: (row) => toCurrency(row.totalWithVat),
+        sortable: true,
     },
     {
         label: t('futureTickets.availableLines'),
         name: 'lines',
         field: 'lines',
         align: 'center',
-        headerClass: 'horizontal-separator',
-        format: (row, dashIfEmpty) => dashIfEmpty(row.lines),
+        sortable: true,
+        columnFilter: {
+            component: VnInput,
+            type: 'text',
+            filterValue: null,
+            event: getInputEvents,
+            attrs: {
+                dense: true,
+            },
+        },
+        format: (val) => dashIfEmpty(val),
     },
     {
         label: t('advanceTickets.futureId'),
         name: 'futureId',
-        align: 'center',
-        headerClass: 'horizontal-separator vertical-separator ',
-        columnClass: 'vertical-separator',
+        align: 'left',
+        sortable: true,
+        columnFilter: {
+            component: VnInput,
+            type: 'text',
+            filterValue: null,
+            filterParamKey: 'futureId',
+            event: getInputEvents,
+            attrs: {
+                dense: true,
+            },
+        },
     },
     {
         label: t('futureTickets.futureShipped'),
         name: 'futureShipped',
         align: 'left',
-        headerClass: 'horizontal-separator',
-        columnFilter: false,
-        format: (row) => toDateTimeFormat(row.futureShipped),
+        sortable: true,
+        columnFilter: null,
+        format: (val) => dashIfEmpty(val),
     },
+
     {
-        align: 'center',
         label: t('advanceTickets.futureIpt'),
-        class: 'shrink',
         name: 'futureIpt',
+        field: 'futureIpt',
+        align: 'left',
+        sortable: true,
         columnFilter: {
-            component: 'select',
+            component: VnSelect,
+            filterParamKey: 'futureIptColFilter',
+            type: 'select',
+            filterValue: null,
+            event: getInputEvents,
             attrs: {
-                url: 'itemPackingTypes',
-                fields: ['code', 'description'],
-                where: { isActive: true },
-                optionValue: 'code',
-                optionLabel: 'description',
+                options: itemPackingTypesOptions.value,
+                'option-value': 'code',
+                'option-label': 'description',
+                dense: true,
             },
         },
-        headerClass: 'horizontal-separator',
-        format: (row, dashIfEmpty) => dashIfEmpty(row.futureIpt),
+        format: (val) => dashIfEmpty(val),
     },
     {
         label: t('advanceTickets.futureState'),
         name: 'futureState',
         align: 'right',
-        headerClass: 'horizontal-separator',
-        class: 'expand',
-        columnFilter: false,
-        format: (row, dashIfEmpty) => dashIfEmpty(row.futureState),
+        sortable: true,
+        columnFilter: null,
+        format: (val) => dashIfEmpty(val),
     },
 ]);
 
@@ -168,51 +258,26 @@ const moveTicketsFuture = async () => {
     await axios.post('Tickets/merge', params);
     notify(t('advanceTickets.moveTicketSuccess'), 'positive');
     selectedTickets.value = [];
-    vnTableRef.value.reload();
+    arrayData.fetch({ append: false });
 };
-
-watch(
-    () => vnTableRef.value.tableRef?.$el,
-    ($el) => {
-        if (!$el) return;
-        const head = $el.querySelector('thead');
-        const firstRow = $el.querySelector('thead > tr');
-
-        const newRow = document.createElement('tr');
-        destinationElRef.value = document.createElement('th');
-        originElRef.value = document.createElement('th');
-
-        newRow.classList.add('bg-header');
-        destinationElRef.value.classList.add('text-uppercase', 'color-vn-label');
-        originElRef.value.classList.add('text-uppercase', 'color-vn-label');
-
-        destinationElRef.value.setAttribute('colspan', '7');
-        originElRef.value.setAttribute('colspan', '9');
-
-        originElRef.value.textContent = `${t('advanceTickets.origin')}`;
-        destinationElRef.value.textContent = `${t('advanceTickets.destination')}`;
-
-        newRow.append(destinationElRef.value, originElRef.value);
-        head.insertBefore(newRow, firstRow);
-    },
-    { once: true, inmmediate: true },
-);
-
-watch(
-    () => vnTableRef.value.params,
-    () => {
-        if (originElRef.value && destinationElRef.value) {
-            destinationElRef.value.textContent = `${t('advanceTickets.origin')}`;
-            originElRef.value.textContent = `${t('advanceTickets.destination')}`;
-        }
-    },
-    { deep: true },
-);
+onMounted(async () => {
+    await arrayData.fetch({ append: false });
+});
 </script>
 
 <template>
+    <FetchData
+        url="itemPackingTypes"
+        :filter="{
+            fields: ['code', 'description'],
+            order: 'description ASC',
+            where: { isActive: true },
+        }"
+        auto-load
+        @on-fetch="(data) => (itemPackingTypesOptions = data)"
+    />
     <VnSearchbar
-        data-key="futureTicket"
+        data-key="FutureTickets"
         :label="t('Search ticket')"
         :info="t('futureTickets.searchInfo')"
     />
@@ -228,7 +293,7 @@ watch(
                         t(`futureTickets.moveTicketDialogSubtitle`, {
                             selectedTickets: selectedTickets.length,
                         }),
-                        moveTicketsFuture,
+                        moveTicketsFuture
                     )
                 "
             >
@@ -240,135 +305,235 @@ watch(
     </VnSubToolbar>
     <RightMenu>
         <template #right-panel>
-            <TicketFutureFilter data-key="futureTickets" />
+            <TicketFutureFilter data-key="FutureTickets" />
         </template>
     </RightMenu>
     <QPage class="column items-center q-pa-md">
-        <VnTable
-            data-key="futureTickets"
-            ref="vnTableRef"
-            url="Tickets/getTicketsFuture"
-            search-url="futureTickets"
-            :user-params="userParams"
-            :limit="0"
+        <QTable
+            :rows="tickets"
             :columns="ticketColumns"
-            :table="{
-                'row-key': '$index',
-                selection: 'multiple',
-            }"
+            row-key="id"
+            selection="multiple"
             v-model:selected="selectedTickets"
-            :right-search="false"
-            auto-load
-            :disable-option="{ card: true }"
+            :pagination="{ rowsPerPage: 0 }"
+            :no-data-label="t('globals.noResults')"
+            style="max-width: 99%"
         >
-            <template #column-problems="{ row }">
-                <span class="q-gutter-x-xs">
-                    <QIcon
-                        v-if="row.futureAgencyFk !== row.agencyFk && row.agencyFk"
-                        color="primary"
-                        name="vn:agency-term"
-                        size="xs"
-                        class="q-mr-xs"
+            <template #header="props">
+                <QTr>
+                    <QTh class="horizontal-separator" />
+                    <QTh
+                        class="horizontal-separator text-uppercase color-vn-label"
+                        colspan="8"
+                        translate
                     >
-                        <QTooltip class="column">
-                            <span>
-                                {{
-                                    t('advanceTickets.originAgency', {
-                                        agency: row.futureAgency,
-                                    })
-                                }}
-                            </span>
-                            <span>
-                                {{
-                                    t('advanceTickets.destinationAgency', {
-                                        agency: row.agency,
-                                    })
-                                }}
-                            </span>
+                        {{ t('advanceTickets.origin') }}
+                    </QTh>
+                    <QTh
+                        class="horizontal-separator text-uppercase color-vn-label"
+                        colspan="4"
+                        translate
+                    >
+                        {{ t('advanceTickets.destination') }}
+                    </QTh>
+                </QTr>
+                <QTr>
+                    <QTh>
+                        <QCheckbox v-model="props.selected" />
+                    </QTh>
+                    <QTh
+                        v-for="(col, index) in ticketColumns"
+                        :key="index"
+                        :class="{ 'vertical-separator': col.name === 'futureId' }"
+                    >
+                        {{ col.label }}
+                    </QTh>
+                </QTr>
+            </template>
+            <template #top-row="{ cols }">
+                <QTr>
+                    <QTd />
+                    <QTd
+                        v-for="(col, index) in cols"
+                        :key="index"
+                        style="max-width: 100px"
+                    >
+                        <component
+                            :is="col.columnFilter.component"
+                            v-if="col.columnFilter"
+                            v-model="col.columnFilter.filterValue"
+                            v-bind="col.columnFilter.attrs"
+                            v-on="col.columnFilter.event(col)"
+                            dense
+                        />
+                    </QTd>
+                </QTr>
+            </template>
+            <template #header-cell-availableLines="{ col }">
+                <QTh class="vertical-separator">
+                    {{ col.label }}
+                </QTh>
+            </template>
+            <template #body-cell-problems="{ row }">
+                <QTd class="q-gutter-x-xs">
+                    <QIcon
+                        v-if="row.isTaxDataChecked === 0"
+                        color="primary"
+                        name="vn:no036"
+                        size="xs"
+                    >
+                        <QTooltip>
+                            {{ t('futureTickets.noVerified') }}
                         </QTooltip>
                     </QIcon>
-                    <TicketProblems :row />
-                </span>
+                    <QIcon
+                        v-if="row.hasTicketRequest"
+                        color="primary"
+                        name="vn:buyrequest"
+                        size="xs"
+                    >
+                        <QTooltip>
+                            {{ t('futureTickets.purchaseRequest') }}
+                        </QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.itemShortage"
+                        color="primary"
+                        name="vn:unavailable"
+                        size="xs"
+                    >
+                        <QTooltip>
+                            {{ t('ticketSale.noVisible') }}
+                        </QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.isFreezed"
+                        color="primary"
+                        name="vn:frozen"
+                        size="xs"
+                    >
+                        <QTooltip>
+                            {{ t('futureTickets.clientFrozen') }}
+                        </QTooltip>
+                    </QIcon>
+                    <QIcon v-if="row.risk" color="primary" name="vn:risk" size="xs">
+                        <QTooltip>
+                            {{ t('futureTickets.risk') }}: {{ row.risk }}
+                        </QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.hasComponentLack"
+                        color="primary"
+                        name="vn:components"
+                        size="xs"
+                    >
+                        <QTooltip>
+                            {{ t('futureTickets.componentLack') }}
+                        </QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.hasRounding"
+                        color="primary"
+                        name="sync_problem"
+                        size="xs"
+                    >
+                        <QTooltip>
+                            {{ t('futureTickets.rounding') }}
+                        </QTooltip>
+                    </QIcon>
+                </QTd>
             </template>
-            <template #column-id="{ row }">
-                <QBtn flat class="link" @click.stop dense>
-                    {{ row.id }}
-                    <TicketDescriptorProxy :id="row.id" />
-                </QBtn>
+            <template #body-cell-ticketId="{ row }">
+                <QTd>
+                    <QBtn flat class="link">
+                        {{ row.id }}
+                        <TicketDescriptorProxy :id="row.id" />
+                    </QBtn>
+                </QTd>
             </template>
-            <template #column-shipped="{ row }">
-                <QBadge
-                    text-color="black"
-                    :color="getDateQBadgeColor(row.shipped)"
-                    class="q-ma-none"
-                >
-                    {{ toDateTimeFormat(row.shipped) }}
-                </QBadge>
+            <template #body-cell-shipped="{ row }">
+                <QTd class="shipped">
+                    <QBadge
+                        text-color="black"
+                        :color="getDateQBadgeColor(row.shipped)"
+                        class="q-ma-none"
+                    >
+                        {{ toDateTimeFormat(row.shipped) }}
+                    </QBadge>
+                </QTd>
             </template>
-            <template #column-state="{ row }">
-                <QBadge
-                    v-if="row.state"
-                    text-color="black"
-                    :color="row.classColor"
-                    class="q-ma-none"
-                    dense
-                >
-                    {{ row.state }}
-                </QBadge>
-                <span v-else> {{ dashIfEmpty(row.state) }}</span>
+            <template #body-cell-state="{ row }">
+                <QTd>
+                    <QBadge
+                        text-color="black"
+                        :color="row.classColor"
+                        class="q-ma-none"
+                        dense
+                    >
+                        {{ row.state }}
+                    </QBadge>
+                </QTd>
             </template>
-            <template #column-import="{ row }">
-                <QBadge
-                    :text-color="
-                        totalPriceColor(row.totalWithVat) === 'warning'
-                            ? 'black'
-                            : 'white'
-                    "
-                    :color="totalPriceColor(row.totalWithVat)"
-                    class="q-ma-none"
-                    dense
-                >
-                    {{ toCurrency(row.totalWithVat || 0) }}
-                </QBadge>
+            <template #body-cell-import="{ row }">
+                <QTd>
+                    <QBadge
+                        :text-color="
+                            totalPriceColor(row.totalWithVat) === 'warning'
+                                ? 'black'
+                                : 'white'
+                        "
+                        :color="totalPriceColor(row.totalWithVat)"
+                        class="q-ma-none"
+                        dense
+                    >
+                        {{ toCurrency(row.totalWithVat || 0) }}
+                    </QBadge>
+                </QTd>
             </template>
-            <template #column-futureId="{ row }">
-                <QBtn flat class="link" @click.stop dense>
-                    {{ row.futureId }}
-                    <TicketDescriptorProxy :id="row.futureId" />
-                </QBtn>
+            <template #body-cell-futureId="{ row }">
+                <QTd class="vertical-separator">
+                    <QBtn flat class="link" dense>
+                        {{ row.futureId }}
+                        <TicketDescriptorProxy :id="row.futureId" />
+                    </QBtn>
+                </QTd>
             </template>
-            <template #column-futureShipped="{ row }">
-                <QBadge
-                    text-color="black"
-                    :color="getDateQBadgeColor(row.futureShipped)"
-                    class="q-ma-none"
-                >
-                    {{ toDateTimeFormat(row.futureShipped) }}
-                </QBadge>
+            <template #body-cell-futureShipped="{ row }">
+                <QTd class="shipped">
+                    <QBadge
+                        text-color="black"
+                        :color="getDateQBadgeColor(row.futureShipped)"
+                        class="q-ma-none"
+                    >
+                        {{ toDateTimeFormat(row.futureShipped) }}
+                    </QBadge>
+                </QTd>
             </template>
-            <template #column-futureState="{ row }">
-                <QBadge
-                    text-color="black"
-                    :color="row.futureClassColor"
-                    class="q-mr-xs"
-                    dense
-                >
-                    {{ row.futureState }}
-                </QBadge>
+            <template #body-cell-futureState="{ row }">
+                <QTd>
+                    <QBadge
+                        text-color="black"
+                        :color="row.futureClassColor"
+                        class="q-ma-none"
+                        dense
+                    >
+                        {{ row.futureState }}
+                    </QBadge>
+                </QTd>
             </template>
-        </VnTable>
+        </QTable>
     </QPage>
 </template>
 
 <style scoped lang="scss">
-:deep(.vertical-separator) {
+.shipped {
+    min-width: 132px;
+}
+.vertical-separator {
     border-left: 4px solid white !important;
 }
 
-:deep(.horizontal-separator) {
-    border-top: 4px solid white !important;
-}
-:deep(.horizontal-bottom-separator) {
+.horizontal-separator {
     border-bottom: 4px solid white !important;
 }
 </style>
diff --git a/src/pages/Ticket/TicketFutureFilter.vue b/src/pages/Ticket/TicketFutureFilter.vue
index 64e060a3921..d28b0af71e9 100644
--- a/src/pages/Ticket/TicketFutureFilter.vue
+++ b/src/pages/Ticket/TicketFutureFilter.vue
@@ -12,7 +12,7 @@ import axios from 'axios';
 import { onMounted } from 'vue';
 
 const { t } = useI18n();
-defineProps({
+const props = defineProps({
     dataKey: {
         type: String,
         required: true,
@@ -58,7 +58,7 @@ onMounted(async () => {
         auto-load
     />
     <VnFilterPanel
-        :data-key
+        :data-key="props.dataKey"
         :un-removable-params="['warehouseFk', 'originScopeDays ', 'futureScopeDays']"
     >
         <template #tags="{ tag, formatFn }">
diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml
index cdbb22d9be6..f11b32c3a5e 100644
--- a/src/pages/Ticket/locale/en.yml
+++ b/src/pages/Ticket/locale/en.yml
@@ -23,8 +23,6 @@ ticketSale:
     hasComponentLack: Component lack
     ok: Ok
     more: More
-    transferLines: Transfer lines(no basket)/ Split
-    transferBasket: Some row selected is basket
 advanceTickets:
     preparation: Preparation
     origin: Origin
@@ -190,6 +188,7 @@ ticketList:
     accountPayment: Account payment
     sendDocuware: Set delivered and send delivery note(s) to the tablet
     addPayment: Add payment
+    date: Date
     company: Company
     amount: Amount
     reference: Reference
@@ -203,89 +202,9 @@ ticketList:
     creditCard: Credit card
     transfers: Transfers
     province: Province
+    warehouse: Warehouse
+    hour: Hour
     closure: Closure
     toLines: Go to lines
     addressNickname: Address nickname
     ref: Reference
-    rounding: Rounding
-    noVerifiedData: No verified data
-    purchaseRequest: Purchase request
-    notVisible: Not visible
-    clientFrozen: Client frozen
-    componentLack: Component lack
-negative:
-    hour: Hour
-    id: Id Article
-    longName: Article
-    supplier: Supplier
-    colour: Colour
-    size: Size
-    origen: Origin
-    value: Negative
-    itemFk: Article
-    producer: Producer
-    warehouse: Warehouse
-    warehouseFk: Warehouse
-    category: Category
-    categoryFk: Family
-    type: Type
-    typeFk: Type
-    lack: Negative
-    inkFk: inkFk
-    timed: timed
-    date: Date
-    minTimed: minTimed
-    negativeAction: Negative
-    totalNegative: Total negatives
-    days: Days
-    buttonsUpdate:
-        item: Item
-        state: State
-        quantity: Quantity
-    modalOrigin:
-        title: Update negatives
-        question: Select a state to update
-    modalSplit:
-        title: Confirm split selected
-        question: Select a state to update
-    detail:
-        saleFk: Sale
-        itemFk: Article
-        ticketFk: Ticket
-        code: Code
-        nickname: Alias
-        name: Name
-        zoneName: Agency name
-        shipped: Date
-        theoreticalhour: Theoretical hour
-        agName: Agency
-        quantity: Quantity
-        alertLevelCode: Group state
-        state: State
-        peticionCompra: Ticket request
-        isRookie: Is rookie
-        turno: Turn line
-        isBasket: Basket
-        hasObservation: Has substitution
-        hasToIgnore: VIP
-        modal:
-            changeItem:
-                title: Update item reference
-                placeholder: New item
-            changeState:
-                title: Update tickets state
-                placeholder: New state
-            changeQuantity:
-                title: Update tickets quantity
-                placeholder: New quantity
-            split:
-                title: Are you sure you want to split selected tickets?
-                subTitle: Confirm split action
-            handleSplited:
-                title: Handle splited  tickets
-                subTitle: Confirm date and agency
-    split:
-        ticket: Old ticket
-        newTicket: New ticket
-        status: Result
-        message: Message
diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml
index 75d3c6a2b7b..945da8367f8 100644
--- a/src/pages/Ticket/locale/es.yml
+++ b/src/pages/Ticket/locale/es.yml
@@ -127,8 +127,6 @@ ticketSale:
     ok: Ok
     more: Más
     address: Consignatario
-    transferLines: Transferir líneas(no cesta)/ Separar
-    transferBasket: No disponible para una cesta
     size: Medida
 ticketComponents:
     serie: Serie
@@ -215,84 +213,3 @@ ticketList:
     toLines: Ir a lineas
     addressNickname: Alias consignatario
     ref: Referencia
-negative:
-    hour: Hora
-    id: Id Articulo
-    longName: Articulo
-    supplier: Productor
-    colour: Color
-    size: Medida
-    origen: Origen
-    value: Negativo
-    warehouseFk: Almacen
-    producer: Producer
-    category: Categoría
-    categoryFk: Familia
-    typeFk: Familia
-    warehouse: Almacen
-    lack: Negativo
-    inkFk: Color
-    timed: Hora
-    date: Fecha
-    minTimed: Hora
-    type: Tipo
-    negativeAction: Negativo
-    totalNegative: Total negativos
-    days: Rango de dias
-    buttonsUpdate:
-        item: artículo
-        state: Estado
-        quantity: Cantidad
-    modalOrigin:
-        title: Actualizar negativos
-        question: Seleccione un estado para guardar
-    modalSplit:
-        title: Confirmar acción de split
-        question: Selecciona un estado
-    detail:
-        saleFk: Línea
-        itemFk: Artículo
-        ticketFk: Ticket
-        code: code
-        nickname: Alias
-        name: Nombre
-        zoneName: Agencia
-        shipped: F. envío
-        theoreticalhour: Hora teórica
-        agName: Agencia
-        quantity: Cantidad
-        alertLevelCode: Estado agrupado
-        state: Estado
-        peticionCompra: Petición compra
-        isRookie: Cliente nuevo
-        turno: Linea turno
-        isBasket: Cesta
-        hasObservation: Tiene sustitución
-        hasToIgnore: VIP
-        modal:
-            changeItem:
-                title: Actualizar referencia artículo
-                placeholder: Nuevo articulo
-            changeState:
-                title: Actualizar estado
-                placeholder: Nuevo estado
-            changeQuantity:
-                title: Actualizar cantidad
-                placeholder: Nueva cantidad
-            split:
-                title: ¿Seguro de separar los tickets seleccionados?
-                subTitle: Confirma separar tickets seleccionados
-            handleSplited:
-                title: Gestionar tickets spliteados
-                subTitle: Confir fecha y agencia
-    split:
-        ticket: Ticket viejo
-        newTicket: Ticket nuevo
-        status: Estado
-        message: Mensaje
-    rounding: Redondeo
-    noVerifiedData: Sin datos comprobados
-    purchaseRequest: Petición de compra
-    notVisible: No visible
-    clientFrozen: Cliente congelado
-    componentLack: Faltan componentes
diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue
index b1adc812622..4b9aa28ed06 100644
--- a/src/pages/Travel/Card/TravelBasicData.vue
+++ b/src/pages/Travel/Card/TravelBasicData.vue
@@ -9,7 +9,6 @@ import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
-import VnInputTime from 'components/common/VnInputTime.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -54,16 +53,7 @@ const warehousesOptionsIn = ref([]);
                 <VnInputDate v-model="data.shipped" :label="t('globals.shipped')" />
                 <VnInputDate v-model="data.landed" :label="t('globals.landed')" />
             </VnRow>
-            <VnRow>
-                <VnInputDate
-                    v-model="data.availabled"
-                    :label="t('travel.summary.availabled')" 
-                    />
-                <VnInputTime
-                    v-model="data.availabled"
-                    :label="t('travel.summary.availabledHour')"
-                />
-            </VnRow>
+
             <VnRow>
                 <VnSelect
                     :label="t('globals.warehouseOut')"
@@ -111,3 +101,10 @@ const warehousesOptionsIn = ref([]);
         </template>
     </FormModel>
 </template>
+
+<i18n>
+es:
+    raidDays: El travel se desplaza automáticamente cada día para estar desde hoy al número de días indicado. Si se deja vacio no se moverá
+en:
+    raidDays: The travel adjusts itself daily to match the number of days set, starting from today. If left blank, it won’t move
+</i18n>
diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue
index cb09eafd680..445675b902f 100644
--- a/src/pages/Travel/Card/TravelCard.vue
+++ b/src/pages/Travel/Card/TravelCard.vue
@@ -1,13 +1,43 @@
 <script setup>
 import TravelDescriptor from './TravelDescriptor.vue';
 import VnCardBeta from 'src/components/common/VnCardBeta.vue';
-import filter from './TravelFilter.js';
+
+const userFilter = {
+    fields: [
+        'id',
+        'ref',
+        'shipped',
+        'landed',
+        'totalEntries',
+        'warehouseInFk',
+        'warehouseOutFk',
+        'cargoSupplierFk',
+        'agencyModeFk',
+        'isRaid',
+        'isDelivered',
+        'isReceived',
+    ],
+    include: [
+        {
+            relation: 'warehouseIn',
+            scope: {
+                fields: ['name'],
+            },
+        },
+        {
+            relation: 'warehouseOut',
+            scope: {
+                fields: ['name'],
+            },
+        },
+    ],
+};
 </script>
 <template>
     <VnCardBeta
         data-key="Travel"
-        url="Travels"
+        base-url="Travels"
         :descriptor="TravelDescriptor"
-        :filter="filter"
+        :user-filter="userFilter"
     />
 </template>
diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue
index 922f89f333f..72acf91b843 100644
--- a/src/pages/Travel/Card/TravelDescriptor.vue
+++ b/src/pages/Travel/Card/TravelDescriptor.vue
@@ -32,6 +32,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
 
 <template>
     <CardDescriptor
+        module="Travel"
         :url="`Travels/${entityId}`"
         :title="data.title"
         :subtitle="data.subtitle"
diff --git a/src/pages/Travel/Card/TravelFilter.js b/src/pages/Travel/Card/TravelFilter.js
index 05436834ffb..f5f4520fd49 100644
--- a/src/pages/Travel/Card/TravelFilter.js
+++ b/src/pages/Travel/Card/TravelFilter.js
@@ -11,7 +11,6 @@ export default {
         'agencyModeFk',
         'isRaid',
         'daysInForward',
-        'availabled',
     ],
     include: [
         {
diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index 9f955261181..16d42f10424 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -10,8 +10,6 @@ import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue'
 import FetchData from 'src/components/FetchData.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import { toDate, toCurrency, toCelsius } from 'src/filters';
-import { toDateTimeFormat } from 'src/filters/date.js';
-import { dashIfEmpty } from 'src/filters';
 import axios from 'axios';
 import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
 
@@ -335,12 +333,6 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
                 <VnLv :label="t('globals.reference')" :value="travel.ref" />
                 <VnLv label="m³" :value="travel.m3" />
                 <VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
-                <VnLv
-                    :label="t('travel.summary.availabled')"
-                    :value="
-                        dashIfEmpty(toDateTimeFormat(travel.availabled))
-                    "
-                />
             </QCard>
             <QCard class="full-width">
                 <VnTitle :text="t('travel.summary.entries')" />
diff --git a/src/pages/Travel/Card/TravelThermographs.vue b/src/pages/Travel/Card/TravelThermographs.vue
index 2376bd6d253..2946c8814bc 100644
--- a/src/pages/Travel/Card/TravelThermographs.vue
+++ b/src/pages/Travel/Card/TravelThermographs.vue
@@ -217,7 +217,7 @@ const removeThermograph = async (id) => {
             icon="add"
             color="primary"
             @click="redirectToThermographForm('create')"
-            v-shortcut="'+'"
+            shortcut="+"
         />
         <QTooltip class="text-no-wrap">
             {{ t('Add thermograph') }}
diff --git a/src/pages/Travel/ExtraCommunityFilter.vue b/src/pages/Travel/ExtraCommunityFilter.vue
index b22574632fc..b903aeabffb 100644
--- a/src/pages/Travel/ExtraCommunityFilter.vue
+++ b/src/pages/Travel/ExtraCommunityFilter.vue
@@ -113,7 +113,7 @@ warehouses();
                         <template #append>
                             <QBtn
                                 icon="add"
-                                v-shortcut="'+'"
+                                shortcut="+"
                                 flat
                                 dense
                                 size="12px"
diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue
index b227afcb213..e90c01be237 100644
--- a/src/pages/Travel/TravelList.vue
+++ b/src/pages/Travel/TravelList.vue
@@ -10,9 +10,6 @@ import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
 import TravelFilter from './TravelFilter.vue';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
 import VnSection from 'src/components/common/VnSection.vue';
-import VnInputTime from 'src/components/common/VnInputTime.vue';
-import VnInputDate from 'src/components/common/VnInputDate.vue';
-import { toDateTimeFormat } from 'src/filters/date';
 
 const { viewSummary } = useSummaryDialog();
 const router = useRouter();
@@ -170,17 +167,6 @@ const columns = computed(() => [
         cardVisible: true,
         create: true,
     },
-    {
-        align: 'left',
-        name: 'availabled',
-        label: t('travel.summary.availabled'),
-        component: 'input',
-        columnClass: 'expand',
-        columnField: {
-            component: null,
-        },
-        format: (row, dashIfEmpty) => dashIfEmpty(toDateTimeFormat(row.availabled)),
-    },
     {
         align: 'right',
         label: '',
@@ -283,16 +269,6 @@ const columns = computed(() => [
                         :class="{ 'is-active': row.isReceived }"
                     />
                 </template>
-                <template #more-create-dialog="{ data }">
-                    <VnInputDate
-                        v-model="data.availabled"
-                        :label="t('travel.summary.availabled')"
-                    />
-                    <VnInputTime
-                        v-model="data.availabled"
-                        :label="t('travel.summary.availabledHour')"
-                    />
-                </template>
                 <template #moreFilterPanel="{ params }">
                     <VnInputNumber
                         :label="t('params.scopeDays')"
diff --git a/src/pages/Wagon/Card/WagonCard.vue b/src/pages/Wagon/Card/WagonCard.vue
index 644a30ffa33..ed6c837781b 100644
--- a/src/pages/Wagon/Card/WagonCard.vue
+++ b/src/pages/Wagon/Card/WagonCard.vue
@@ -2,5 +2,5 @@
 import VnCard from 'components/common/VnCard.vue';
 </script>
 <template>
-    <VnCard data-key="Wagon" url="Wagons" />
+    <VnCard data-key="Wagon" base-url="Wagons" />
 </template>
diff --git a/src/pages/Wagon/Type/WagonTypeList.vue b/src/pages/Wagon/Type/WagonTypeList.vue
index 4c0b078a730..c0943c58e80 100644
--- a/src/pages/Wagon/Type/WagonTypeList.vue
+++ b/src/pages/Wagon/Type/WagonTypeList.vue
@@ -96,13 +96,7 @@ async function remove(row) {
         >
         </VnTable>
         <QPageSticky :offset="[18, 18]">
-            <QBtn
-                @click.stop="dialog.show()"
-                color="primary"
-                fab
-                icon="add"
-                v-shortcut="'+'"
-            >
+            <QBtn @click.stop="dialog.show()" color="primary" fab icon="add" shortcut="+">
                 <QDialog ref="dialog">
                     <FormModelPopup
                         :title="t('Create new Wagon type')"
diff --git a/src/pages/Worker/Card/WorkerBasicData.vue b/src/pages/Worker/Card/WorkerBasicData.vue
index fcf0f0369e2..6a13e3f398a 100644
--- a/src/pages/Worker/Card/WorkerBasicData.vue
+++ b/src/pages/Worker/Card/WorkerBasicData.vue
@@ -1,5 +1,6 @@
 <script setup>
-import { ref } from 'vue';
+import { ref, onBeforeMount } from 'vue';
+import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import FetchData from 'components/FetchData.vue';
@@ -10,13 +11,18 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
 
 const { t } = useI18n();
-const form = ref();
 const educationLevels = ref([]);
 const countries = ref([]);
 const maritalStatus = [
     { code: 'M', name: t('Married') },
     { code: 'S', name: t('Single') },
 ];
+const advancedSummary = ref({});
+
+onBeforeMount(async () => {
+    advancedSummary.value =
+        (await useAdvancedSummary('Workers', +useRoute().params.id)) ?? {};
+});
 </script>
 <template>
     <FetchData
@@ -32,15 +38,14 @@ const maritalStatus = [
         auto-load
     />
     <FormModel
-        ref="form"
+        :filter="{ where: { id: +$route.params.id } }"
+        url="Workers/summary"
         :url-update="`Workers/${$route.params.id}`"
         auto-load
         model="Worker"
         @on-fetch="
             async (data) => {
-                Object.assign(data, (await useAdvancedSummary('Workers', data.id)) ?? {});
-                await $nextTick();
-                if (form) form.hasChanges = false;
+                Object.assign(data, advancedSummary);
             }
         "
     >
diff --git a/src/pages/Worker/Card/WorkerCalendar.vue b/src/pages/Worker/Card/WorkerCalendar.vue
index df4616011f4..5ca95a1a40f 100644
--- a/src/pages/Worker/Card/WorkerCalendar.vue
+++ b/src/pages/Worker/Card/WorkerCalendar.vue
@@ -1,8 +1,7 @@
 <script setup>
-import { nextTick, ref, watch, computed } from 'vue';
+import { nextTick, ref, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
-import { useAcl } from 'src/composables/useAcl';
 
 import WorkerCalendarFilter from 'pages/Worker/Card/WorkerCalendarFilter.vue';
 import FetchData from 'components/FetchData.vue';
@@ -10,17 +9,10 @@ import WorkerCalendarItem from 'pages/Worker/Card/WorkerCalendarItem.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 
 import axios from 'axios';
-import VnNotes from 'src/components/ui/VnNotes.vue';
-import { useStateStore } from 'src/stores/useStateStore';
-const stateStore = useStateStore();
 
 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 workerIsFreelance = ref();
 const WorkerFreelanceRef = ref();
 const workerCalendarFilterRef = ref(null);
@@ -34,10 +26,6 @@ const contractHolidays = ref(null);
 const yearHolidays = ref(null);
 const eventsMap = ref({});
 const festiveEventsMap = ref({});
-const saveUrl = ref();
-const body = {
-    workerFk: route.params.id,
-};
 
 const onFetchActiveContract = (data) => {
     if (!data) return;
@@ -79,7 +67,7 @@ const onFetchAbsences = (data) => {
                     name: holidayName,
                     isFestive: true,
                 },
-                true,
+                true
             );
         });
     }
@@ -158,7 +146,7 @@ watch(
     async () => {
         await nextTick();
         await activeContractRef.value.fetch();
-    },
+    }
 );
 watch([year, businessFk], () => refreshData());
 </script>
@@ -193,20 +181,6 @@ watch([year, businessFk], () => refreshData());
             />
         </template>
     </RightMenu>
-    <Teleport to="#st-data" v-if="stateStore.isSubToolbarShown() && canSeeNotes">
-        <VnNotes
-            :just-input="true"
-            :url="`Workers/${route.params.id}/business`"
-            :filter="{ fields: ['id', 'notes', 'workerFk'] }"
-            :save-url="saveUrl"
-            @on-fetch="
-                (data) => {
-                    saveUrl = `Businesses/${data.id}`;
-                }
-            "
-            :body="body"
-        />
-    </Teleport>
     <QPage class="column items-center">
         <QCard v-if="workerIsFreelance">
             <QCardSection class="text-center">
diff --git a/src/pages/Worker/Card/WorkerCalendarFilter.vue b/src/pages/Worker/Card/WorkerCalendarFilter.vue
index 48fc4094b8f..67b7df907be 100644
--- a/src/pages/Worker/Card/WorkerCalendarFilter.vue
+++ b/src/pages/Worker/Card/WorkerCalendarFilter.vue
@@ -180,6 +180,8 @@ const yearList = ref(generateYears());
                     :is-clearable="false"
                 />
             </QItemSection>
+        </QItem>
+        <QItem>
             <QItemSection>
                 <VnSelect
                     :label="t('Contract')"
diff --git a/src/pages/Worker/Card/WorkerCard.vue b/src/pages/Worker/Card/WorkerCard.vue
index 3b7a62025ae..1ada15a3386 100644
--- a/src/pages/Worker/Card/WorkerCard.vue
+++ b/src/pages/Worker/Card/WorkerCard.vue
@@ -3,10 +3,5 @@ import WorkerDescriptor from './WorkerDescriptor.vue';
 import VnCardBeta from 'src/components/common/VnCardBeta.vue';
 </script>
 <template>
-    <VnCardBeta
-        data-key="Worker"
-        url="Workers/summary"
-        :id-in-where="true"
-        :descriptor="WorkerDescriptor"
-    />
+    <VnCardBeta data-key="Worker" custom-url="Workers/summary" :descriptor="WorkerDescriptor" />
 </template>
diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue
index de3f634e2c0..d87fd4a54ac 100644
--- a/src/pages/Worker/Card/WorkerDescriptor.vue
+++ b/src/pages/Worker/Card/WorkerDescriptor.vue
@@ -10,7 +10,7 @@ import axios from 'axios';
 import VnImg from 'src/components/ui/VnImg.vue';
 import EditPictureForm from 'components/EditPictureForm.vue';
 import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
-import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
 
 const $props = defineProps({
     id: {
@@ -21,7 +21,7 @@ const $props = defineProps({
     dataKey: {
         type: String,
         required: false,
-        default: 'Worker',
+        default: 'workerData',
     },
 });
 const image = ref(null);
@@ -50,8 +50,9 @@ const handlePhotoUpdated = (evt = false) => {
 <template>
     <CardDescriptor
         ref="cardDescriptorRef"
+        module="Worker"
         :data-key="dataKey"
-        url="Workers/summary"
+        url="Workers/descriptor"
         :filter="{ where: { id: entityId } }"
         title="user.nickname"
         @on-fetch="getIsExcluded"
@@ -151,7 +152,7 @@ const handlePhotoUpdated = (evt = false) => {
                 <QBtn
                     :to="{
                         name: 'AccountCard',
-                        params: { id: entity.user?.id },
+                        params: { id: entity.user.id },
                     }"
                     size="md"
                     icon="face"
diff --git a/src/pages/Worker/Card/WorkerDescriptorProxy.vue b/src/pages/Worker/Card/WorkerDescriptorProxy.vue
index a142570f9ca..43deb7821a0 100644
--- a/src/pages/Worker/Card/WorkerDescriptorProxy.vue
+++ b/src/pages/Worker/Card/WorkerDescriptorProxy.vue
@@ -12,6 +12,11 @@ const $props = defineProps({
 
 <template>
     <QPopupProxy>
-        <WorkerDescriptor v-if="$props.id" :id="$props.id" :summary="WorkerSummary" />
+        <WorkerDescriptor
+            v-if="$props.id"
+            :id="$props.id"
+            :summary="WorkerSummary"
+            data-key="workerDescriptorProxy"
+        />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Worker/Card/WorkerFormation.vue b/src/pages/Worker/Card/WorkerFormation.vue
index e8680f7dd84..6fd5a4eae01 100644
--- a/src/pages/Worker/Card/WorkerFormation.vue
+++ b/src/pages/Worker/Card/WorkerFormation.vue
@@ -94,7 +94,6 @@ const columns = computed(() => [
         align: 'left',
         name: 'hasDiploma',
         label: t('worker.formation.tableVisibleColumns.hasDiploma'),
-        component: 'checkbox',
         create: true,
     },
     {
@@ -119,7 +118,7 @@ const columns = computed(() => [
         :url="`Workers/${entityId}/trainingCourse`"
         :url-create="`Workers/${entityId}/trainingCourse`"
         save-url="TrainingCourses/crud"
-        :user-filter="courseFilter"
+        :filter="courseFilter"
         :create="{
             urlCreate: 'trainingCourses',
             title: t('Create training course'),
diff --git a/src/pages/Worker/Card/WorkerMedical.vue b/src/pages/Worker/Card/WorkerMedical.vue
index c04f6496b9f..c220df76a2c 100644
--- a/src/pages/Worker/Card/WorkerMedical.vue
+++ b/src/pages/Worker/Card/WorkerMedical.vue
@@ -3,23 +3,11 @@ import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 import VnTable from 'components/VnTable/VnTable.vue';
-import { dashIfEmpty } from 'src/filters';
 const tableRef = ref();
 const { t } = useI18n();
 const route = useRoute();
 const entityId = computed(() => route.params.id);
 
-const centerFilter = {
-    include: [
-        {
-            relation: 'center',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-    ],
-};
-
 const columns = [
     {
         align: 'left',
@@ -48,9 +36,6 @@ const columns = [
             url: 'medicalCenters',
             fields: ['id', 'name'],
         },
-        format: (row, dashIfEmpty) => {
-            return dashIfEmpty(row.center?.name);
-        },
     },
     {
         align: 'left',
@@ -99,7 +84,6 @@ const columns = [
         ref="tableRef"
         data-key="WorkerMedical"
         :url="`Workers/${entityId}/medicalReview`"
-        :user-filter="centerFilter"
         save-url="MedicalReviews/crud"
         :create="{
             urlCreate: 'medicalReviews',
diff --git a/src/pages/Worker/Card/WorkerOperator.vue b/src/pages/Worker/Card/WorkerOperator.vue
index 6faeefe6704..cdacc72c05b 100644
--- a/src/pages/Worker/Card/WorkerOperator.vue
+++ b/src/pages/Worker/Card/WorkerOperator.vue
@@ -1,7 +1,7 @@
 <script setup>
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
-import { ref, computed, watch } from 'vue';
+import { ref, computed } from 'vue';
 import FetchData from 'components/FetchData.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
@@ -19,7 +19,6 @@ const trainsData = ref([]);
 const machinesData = ref([]);
 const route = useRoute();
 const routeId = computed(() => route.params.id);
-const selected = ref([]);
 
 const initialData = computed(() => {
     return {
@@ -42,21 +41,6 @@ async function insert() {
     await axios.post('Operators', initialData.value);
     crudModelRef.value.reload();
 }
-
-watch(
-    () => crudModelRef.value?.formData,
-    (formData) => {
-        if (formData && formData.length) {
-            if (JSON.stringify(selected.value) !== JSON.stringify(formData)) {
-                selected.value = formData;
-            }
-        } else if (selected.value.length > 0) {
-            selected.value = [];
-        }
-    },
-    { immediate: true, deep: true }
-);
-
 </script>
 
 <template>
@@ -83,7 +67,6 @@ watch(
             :data-required="{ workerFk: route.params.id }"
             ref="crudModelRef"
             search-url="operator"
-            :selected="selected"
             auto-load
         >
             <template #body="{ rows }">
diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue
index 47e13cf6d53..f6cb92aacd6 100644
--- a/src/pages/Worker/Card/WorkerPda.vue
+++ b/src/pages/Worker/Card/WorkerPda.vue
@@ -101,7 +101,7 @@ function reloadData() {
                                 openConfirmationModal(
                                     t(`Remove PDA`),
                                     t('Do you want to remove this PDA?'),
-                                    () => deallocatePDA(row.deviceProductionFk),
+                                    () => deallocatePDA(row.deviceProductionFk)
                                 )
                             "
                         >
@@ -114,13 +114,7 @@ function reloadData() {
             </template>
         </VnPaginate>
         <QPageSticky :offset="[18, 18]">
-            <QBtn
-                @click.stop="dialog.show()"
-                color="primary"
-                fab
-                icon="add"
-                v-shortcut="'+'"
-            >
+            <QBtn @click.stop="dialog.show()" color="primary" fab icon="add" shortcut="+">
                 <QDialog ref="dialog">
                     <FormModelPopup
                         :title="t('Add new device')"
diff --git a/src/pages/Worker/Card/WorkerPit.vue b/src/pages/Worker/Card/WorkerPit.vue
index 40e814452ea..79cf1a04fb1 100644
--- a/src/pages/Worker/Card/WorkerPit.vue
+++ b/src/pages/Worker/Card/WorkerPit.vue
@@ -221,7 +221,7 @@ const deleteRelative = async (id) => {
                                 color="primary"
                                 flat
                                 icon="add"
-                                v-shortcut="'+'"
+                                shortcut="+"
                                 style="flex: 0"
                                 data-cy="addRelative"
                             />
diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue
index 78c5dfd82b3..992f6ec7182 100644
--- a/src/pages/Worker/Card/WorkerSummary.vue
+++ b/src/pages/Worker/Card/WorkerSummary.vue
@@ -9,7 +9,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import VnTitle from 'src/components/common/VnTitle.vue';
 import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue';
-import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
 import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
 import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
 
diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue
index 7def6e94cf5..c580e5202de 100644
--- a/src/pages/Worker/Card/WorkerTimeControl.vue
+++ b/src/pages/Worker/Card/WorkerTimeControl.vue
@@ -64,17 +64,17 @@ const selectedCalendarDates = ref([]);
 // Date formateada para bindear al componente QDate
 const selectedDateFormatted = ref(toDateString(defaultDate.value));
 
-const arrayData = useArrayData('Worker');
+const arrayData = useArrayData('workerData');
 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' }]),
+    acl.hasAny([{ model: 'WorkerTimeControl', props: 'sendMail', accessType: 'WRITE' }])
 );
 const canUpdate = computed(() =>
     acl.hasAny([
         { model: 'WorkerTimeControl', props: 'updateMailState', accessType: 'WRITE' },
-    ]),
+    ])
 );
 const isHimself = computed(() => user.value.id === Number(route.params.id));
 
@@ -100,7 +100,7 @@ const getHeaderFormattedDate = (date) => {
 };
 
 const formattedWeekTotalHours = computed(() =>
-    secondsToHoursMinutes(weekTotalHours.value),
+    secondsToHoursMinutes(weekTotalHours.value)
 );
 
 const onInputChange = async (date) => {
@@ -320,7 +320,7 @@ const getFinishTime = () => {
     today.setHours(0, 0, 0, 0);
 
     let todayInWeek = weekDays.value.find(
-        (day) => day.dated.getTime() === today.getTime(),
+        (day) => day.dated.getTime() === today.getTime()
     );
 
     if (todayInWeek && todayInWeek.hours && todayInWeek.hours.length) {
@@ -472,7 +472,7 @@ onMounted(async () => {
                         openConfirmationModal(
                             t('Send time control email'),
                             t('Are you sure you want to send it?'),
-                            resendEmail,
+                            resendEmail
                         )
                     "
                 >
@@ -561,7 +561,7 @@ onMounted(async () => {
                                 @show-worker-time-form="
                                     showWorkerTimeForm(
                                         { id: hour.id, entryCode: hour.direction },
-                                        'edit',
+                                        'edit'
                                     )
                                 "
                                 class="hour-chip"
@@ -577,7 +577,7 @@ onMounted(async () => {
                             </span>
                             <QBtn
                                 icon="add_circle"
-                                v-shortcut="'+'"
+                                shortcut="+"
                                 flat
                                 color="primary"
                                 class="fill-icon cursor-pointer"
diff --git a/src/pages/Worker/WorkerDepartmentTree.vue b/src/pages/Worker/WorkerDepartmentTree.vue
index 9baf5ee571a..9abf4e3127e 100644
--- a/src/pages/Worker/WorkerDepartmentTree.vue
+++ b/src/pages/Worker/WorkerDepartmentTree.vue
@@ -3,7 +3,7 @@ import { onMounted, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useState } from 'src/composables/useState';
 import { useQuasar } from 'quasar';
-import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
 import CreateDepartmentChild from './CreateDepartmentChild.vue';
 import axios from 'axios';
 import { useRouter } from 'vue-router';
@@ -173,7 +173,7 @@ function handleEvent(type, event, node) {
                             color="primary"
                             flat
                             icon="add"
-                            v-shortcut="'+'"
+                            shortcut="+"
                             class="cursor-pointer"
                             @click.stop="showCreateNodeForm(node.id)"
                         >
diff --git a/src/pages/Zone/Card/ZoneBasicData.vue b/src/pages/Zone/Card/ZoneBasicData.vue
index 03013f011b9..cbeeff2e9cb 100644
--- a/src/pages/Zone/Card/ZoneBasicData.vue
+++ b/src/pages/Zone/Card/ZoneBasicData.vue
@@ -1,7 +1,5 @@
 <script setup>
 import { useI18n } from 'vue-i18n';
-import { ref } from 'vue';
-import FetchData from 'components/FetchData.vue';
 import FormModel from 'src/components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
@@ -9,23 +7,10 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 
 const { t } = useI18n();
-const validAddresses = ref([]);
-const addresses = ref([]);
-
-const setFilteredAddresses = (data) => {
-    const validIds = new Set(validAddresses.value.map((item) => item.addressFk));
-    addresses.value = data.filter((address) => validIds.has(address.id));
-};
 </script>
 
 <template>
-    <FetchData
-        url="RoadmapAddresses"
-        auto-load
-        @on-fetch="(data) => (validAddresses = data)"
-    />
-    <FetchData url="Addresses" auto-load @on-fetch="setFilteredAddresses" />
-    <FormModel auto-load model="Zone">
+    <FormModel :url="`Zones/${$route.params.id}`" auto-load model="zone">
         <template #form="{ data, validate }">
             <VnRow>
                 <VnInput
@@ -33,15 +18,15 @@ const setFilteredAddresses = (data) => {
                     :label="t('Name')"
                     clearable
                     v-model="data.name"
-                    :required="true"
                 />
             </VnRow>
+
             <VnRow>
                 <VnSelect
                     v-model="data.agencyModeFk"
                     :rules="validate('zone.agencyModeFk')"
-                    url="AgencyModes/isActive"
-                    :fields="['id', 'name']"
+                     url="AgencyModes/isActive"
+                     :fields="['id', 'name']"
                     :label="t('Agency')"
                     emit-value
                     map-options
@@ -84,7 +69,7 @@ const setFilteredAddresses = (data) => {
                     type="number"
                     min="0"
                 />
-                <VnInputTime v-model="data.hour" :label="t('Closing')" :required="true" />
+                <VnInputTime v-model="data.hour" :label="t('Closing')" />
             </VnRow>
 
             <VnRow>
@@ -93,7 +78,7 @@ const setFilteredAddresses = (data) => {
                     :label="t('Price')"
                     type="number"
                     min="0"
-                    :required="true"
+                    required="true"
                     clearable
                 />
                 <VnInput
@@ -101,7 +86,7 @@ const setFilteredAddresses = (data) => {
                     :label="t('Price optimum')"
                     type="number"
                     min="0"
-                    :required="true"
+                    required="true"
                     clearable
                 />
             </VnRow>
@@ -118,14 +103,12 @@ const setFilteredAddresses = (data) => {
                     v-model="data.addressFk"
                     option-value="id"
                     option-label="nickname"
-                    :options="addresses"
+                    url="Addresses"
                     :fields="['id', 'nickname']"
                     sort-by="id"
                     hide-selected
                     map-options
                     :rules="validate('data.addressFk')"
-                    :filter-options="['id']"
-                    :where="filterWhere"
                 />
             </VnRow>
             <VnRow>
diff --git a/src/pages/Zone/Card/ZoneCard.vue b/src/pages/Zone/Card/ZoneCard.vue
index 41daff5c0b9..a470cd5bdb8 100644
--- a/src/pages/Zone/Card/ZoneCard.vue
+++ b/src/pages/Zone/Card/ZoneCard.vue
@@ -1,12 +1,13 @@
 <script setup>
+import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 import { computed } from 'vue';
 
 import VnCard from 'components/common/VnCard.vue';
 import ZoneDescriptor from './ZoneDescriptor.vue';
 import ZoneFilterPanel from '../ZoneFilterPanel.vue';
-import filter from './ZoneFilter.js';
 
+const { t } = useI18n();
 const route = useRoute();
 const routeName = computed(() => route.name);
 
@@ -18,16 +19,15 @@ function notIsLocations(ifIsFalse, ifIsTrue) {
 
 <template>
     <VnCard
-        data-key="Zone"
-        :url="notIsLocations('Zones', undefined)"
+        data-key="zone"
+        :base-url="notIsLocations('Zones', undefined)"
         :descriptor="ZoneDescriptor"
-        :filter="filter"
         :filter-panel="notIsLocations(ZoneFilterPanel, undefined)"
         :search-data-key="notIsLocations('ZoneList', undefined)"
         :searchbar-props="{
             url: notIsLocations('Zones', 'ZoneLocations'),
-            label: notIsLocations($t('list.searchZone'), $t('list.searchLocation')),
-            info: $t('list.searchInfo'),
+            label: notIsLocations(t('list.searchZone'), t('list.searchLocation')),
+            info: t('list.searchInfo'),
             whereFilter: notIsLocations((value) => {
                 return /^\d+$/.test(value)
                     ? { id: value }
diff --git a/src/pages/Zone/Card/ZoneDescriptor.vue b/src/pages/Zone/Card/ZoneDescriptor.vue
index 27676212e65..8355c219e55 100644
--- a/src/pages/Zone/Card/ZoneDescriptor.vue
+++ b/src/pages/Zone/Card/ZoneDescriptor.vue
@@ -1,14 +1,15 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
 
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import { toTimeFormat } from 'src/filters/date';
 import { toCurrency } from 'filters/index';
 
+import useCardDescription from 'src/composables/useCardDescription';
 import ZoneDescriptorMenuItems from './ZoneDescriptorMenuItems.vue';
-import filter from './ZoneFilter.js';
 
 const $props = defineProps({
     id: {
@@ -19,22 +20,49 @@ const $props = defineProps({
 });
 
 const route = useRoute();
+const { t } = useI18n();
+
+const filter = {
+    include: [
+        {
+            relation: 'agencyMode',
+            scope: {
+                fields: ['name', 'id'],
+            },
+        },
+    ],
+};
+
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+
+const data = ref(useCardDescription());
+const setData = (entity) => {
+    data.value = useCardDescription(entity.ref, entity.id);
+};
 </script>
 
 <template>
-    <CardDescriptor :url="`Zones/${entityId}`" :filter="filter" data-key="Zone">
+    <CardDescriptor
+        module="Zone"
+        :url="`Zones/${entityId}`"
+        :title="data.title"
+        :subtitle="data.subtitle"
+        :filter="filter"
+        @on-fetch="setData"
+        data-key="zoneData"
+    >
         <template #menu="{ entity }">
             <ZoneDescriptorMenuItems :zone="entity" />
         </template>
         <template #body="{ entity }">
-            <VnLv :label="$t('list.agency')" :value="entity.agencyMode?.name" />
-            <VnLv :label="$t('zone.closing')" :value="toTimeFormat(entity.hour)" />
-            <VnLv :label="$t('zone.travelingDays')" :value="entity.travelingDays" />
-            <VnLv :label="$t('list.price')" :value="toCurrency(entity.price)" />
-            <VnLv :label="$t('zone.bonus')" :value="toCurrency(entity.bonus)" />
+            <VnLv :label="t('list.agency')" :value="entity.agencyMode.name" />
+            <VnLv :label="t('zone.closing')" :value="toTimeFormat(entity.hour)" />
+            <VnLv :label="t('zone.travelingDays')" :value="entity.travelingDays" />
+            <VnLv :label="t('list.price')" :value="toCurrency(entity.price)" />
+            <VnLv :label="t('zone.bonus')" :value="toCurrency(entity.bonus)" />
         </template>
     </CardDescriptor>
 </template>
+
diff --git a/src/pages/Zone/Card/ZoneEvents.vue b/src/pages/Zone/Card/ZoneEvents.vue
index 1e6debd25df..a5806bab9ff 100644
--- a/src/pages/Zone/Card/ZoneEvents.vue
+++ b/src/pages/Zone/Card/ZoneEvents.vue
@@ -78,13 +78,13 @@ const onZoneEventFormClose = () => {
                         {
                             isNewMode: true,
                         },
-                        true,
+                        true
                     )
                 "
                 color="primary"
                 fab
                 icon="add"
-                v-shortcut="'+'"
+                shortcut="+"
             />
             <QTooltip class="text-no-wrap">
                 {{ t('eventsInclusionForm.addEvent') }}
diff --git a/src/pages/Zone/Card/ZoneFilter.js b/src/pages/Zone/Card/ZoneFilter.js
deleted file mode 100644
index 3298c7c8a8f..00000000000
--- a/src/pages/Zone/Card/ZoneFilter.js
+++ /dev/null
@@ -1,10 +0,0 @@
-export default {
-    include: [
-        {
-            relation: 'agencyMode',
-            scope: {
-                fields: ['name', 'id'],
-            },
-        },
-    ],
-};
diff --git a/src/pages/Zone/Card/ZoneSearchbar.vue b/src/pages/Zone/Card/ZoneSearchbar.vue
index d1188a1e8b6..f7a59e97fe0 100644
--- a/src/pages/Zone/Card/ZoneSearchbar.vue
+++ b/src/pages/Zone/Card/ZoneSearchbar.vue
@@ -22,50 +22,15 @@ const exprBuilder = (param, value) => {
             return /^\d+$/.test(value) ? { id: value } : { name: { like: `%${value}%` } };
     }
 };
-
-const tableFilter = {
-    include: [
-        {
-            relation: 'agencyMode',
-            scope: {
-                fields: ['id', 'name'],
-            },
-        },
-        {
-            relation: 'address',
-            scope: {
-                fields: ['id', 'nickname', 'provinceFk', 'postalCode'],
-                include: [
-                    {
-                        relation: 'province',
-                        scope: {
-                            fields: ['id', 'name'],
-                        },
-                    },
-                    {
-                        relation: 'postcode',
-                        scope: {
-                            fields: ['code', 'townFk'],
-                            include: {
-                                relation: 'town',
-                                scope: {
-                                    fields: ['id', 'name'],
-                                },
-                            },
-                        },
-                    },
-                ],
-            },
-        },
-    ],
-};
 </script>
 
 <template>
     <VnSearchbar
         data-key="ZonesList"
         url="Zones"
-        :filter="tableFilter"
+        :filter="{
+            include: { relation: 'agencyMode', scope: { fields: ['name'] } },
+        }"
         :expr-builder="exprBuilder"
         :label="t('list.searchZone')"
         :info="t('list.searchInfo')"
diff --git a/src/pages/Zone/Card/ZoneSummary.vue b/src/pages/Zone/Card/ZoneSummary.vue
index 5b29b495b06..12480263321 100644
--- a/src/pages/Zone/Card/ZoneSummary.vue
+++ b/src/pages/Zone/Card/ZoneSummary.vue
@@ -11,7 +11,6 @@ import { getUrl } from 'src/composables/getUrl';
 import { toCurrency } from 'filters/index';
 import { toTimeFormat } from 'src/filters/date';
 import axios from 'axios';
-import filter from './ZoneFilter.js';
 import ZoneDescriptorMenuItems from './ZoneDescriptorMenuItems.vue';
 
 const route = useRoute();
@@ -27,6 +26,19 @@ const $props = defineProps({
 const entityId = computed(() => $props.id || route.params.id);
 const zoneUrl = ref();
 
+const filter = computed(() => {
+    const filter = {
+        include: {
+            relation: 'agencyMode',
+            fields: ['name'],
+        },
+        where: {
+            id: entityId,
+        },
+    };
+    return filter;
+});
+
 const columns = computed(() => [
     {
         label: t('list.name'),
@@ -60,9 +72,9 @@ onMounted(async () => {
 
 <template>
     <CardSummary
-        data-key="Zone"
+        data-key="ZoneSummary"
         ref="summary"
-        :url="`Zones/${entityId}`"
+        url="Zones/findOne"
         :filter="filter"
     >
         <template #header="{ entity }">
diff --git a/src/pages/Zone/Card/ZoneWarehouses.vue b/src/pages/Zone/Card/ZoneWarehouses.vue
index 165e9c84042..c96735697b5 100644
--- a/src/pages/Zone/Card/ZoneWarehouses.vue
+++ b/src/pages/Zone/Card/ZoneWarehouses.vue
@@ -109,7 +109,7 @@ const openCreateWarehouseForm = () => createWarehouseDialogRef.value.show();
                 icon="add"
                 color="primary"
                 @click="openCreateWarehouseForm()"
-                v-shortcut="'+'"
+                shortcut="+"
             >
                 <QTooltip>{{ t('warehouses.add') }}</QTooltip>
             </QBtn>
diff --git a/src/pages/Zone/Delivery/ZoneDeliveryList.vue b/src/pages/Zone/Delivery/ZoneDeliveryList.vue
index e3ec8cb2d4e..975cbdb67b4 100644
--- a/src/pages/Zone/Delivery/ZoneDeliveryList.vue
+++ b/src/pages/Zone/Delivery/ZoneDeliveryList.vue
@@ -74,7 +74,7 @@ async function remove(row) {
             </VnPaginate>
         </div>
         <QPageSticky position="bottom-right" :offset="[18, 18]">
-            <QBtn @click="create" fab icon="add" v-shortcut="'+'" color="primary" />
+            <QBtn @click="create" fab icon="add" shortcut="+" color="primary" />
         </QPageSticky>
     </QPage>
 </template>
diff --git a/src/pages/Zone/Upcoming/ZoneUpcomingList.vue b/src/pages/Zone/Upcoming/ZoneUpcomingList.vue
index 7b5c2ddbc80..5a7f0bb4c42 100644
--- a/src/pages/Zone/Upcoming/ZoneUpcomingList.vue
+++ b/src/pages/Zone/Upcoming/ZoneUpcomingList.vue
@@ -74,7 +74,7 @@ async function remove(row) {
             </VnPaginate>
         </div>
         <QPageSticky position="bottom-right" :offset="[18, 18]">
-            <QBtn @click="create" fab icon="add" v-shortcut="'+'" color="primary" />
+            <QBtn @click="create" fab icon="add" shortcut="+" color="primary" />
         </QPageSticky>
     </QPage>
 </template>
diff --git a/src/pages/Zone/ZoneList.vue b/src/pages/Zone/ZoneList.vue
index 4df84e4bdd7..e4a1774fe38 100644
--- a/src/pages/Zone/ZoneList.vue
+++ b/src/pages/Zone/ZoneList.vue
@@ -4,7 +4,7 @@ import { useRouter } from 'vue-router';
 import { computed, ref } from 'vue';
 import axios from 'axios';
 
-import { dashIfEmpty, toCurrency } from 'src/filters';
+import { toCurrency } from 'src/filters';
 import { toTimeFormat } from 'src/filters/date';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import useNotify from 'src/composables/useNotify.js';
@@ -17,6 +17,7 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import ZoneFilterPanel from './ZoneFilterPanel.vue';
 import ZoneSearchbar from './Card/ZoneSearchbar.vue';
+import FetchData from 'src/components/FetchData.vue';
 
 const { t } = useI18n();
 const router = useRouter();
@@ -25,6 +26,7 @@ const { viewSummary } = useSummaryDialog();
 const { openConfirmationModal } = useVnConfirm();
 const tableRef = ref();
 const warehouseOptions = ref([]);
+const validAddresses = ref([]);
 
 const tableFilter = {
     include: [
@@ -129,7 +131,6 @@ const columns = computed(() => [
         label: t('list.addressFk'),
         cardVisible: true,
         columnFilter: false,
-        columnClass: 'expand',
     },
     {
         align: 'right',
@@ -160,18 +161,30 @@ const handleClone = (id) => {
     openConfirmationModal(
         t('list.confirmCloneTitle'),
         t('list.confirmCloneSubtitle'),
-        () => clone(id),
+        () => clone(id)
     );
 };
 
-function formatRow(row) {
-    if (!row?.address) return '-';
-    return dashIfEmpty(`${row?.address?.nickname},
-            ${row?.address?.postcode?.town?.name} (${row?.address?.province?.name})`);
+function showValidAddresses(row) {
+    if (row.addressFk) {
+        const isValid = validAddresses.value.some(
+            (address) => address.addressFk === row.addressFk
+        );
+        if (isValid)
+            return `${row.address?.nickname},
+            ${row.address?.postcode?.town?.name} (${row.address?.province?.name})`;
+        else return '-';
+    }
+    return '-';
 }
 </script>
 
 <template>
+    <FetchData
+        url="RoadmapAddresses"
+        auto-load
+        @on-fetch="(data) => (validAddresses = data)"
+    />
     <ZoneSearchbar />
     <RightMenu>
         <template #right-panel>
@@ -194,7 +207,7 @@ function formatRow(row) {
         :right-search="false"
     >
         <template #column-addressFk="{ row }">
-            {{ dashIfEmpty(formatRow(row)) }}
+            {{ showValidAddresses(row) }}
         </template>
         <template #more-create-dialog="{ data }">
             <VnSelect
diff --git a/src/router/modules/account/aliasCard.js b/src/router/modules/account/aliasCard.js
index a5b00f44b3a..cbbd31e5103 100644
--- a/src/router/modules/account/aliasCard.js
+++ b/src/router/modules/account/aliasCard.js
@@ -3,7 +3,7 @@ export default {
     path: ':id',
     component: () => import('src/pages/Account/Alias/Card/AliasCard.vue'),
     redirect: { name: 'AliasSummary' },
-    meta: { moduleName: 'Alias', menu: ['AliasBasicData', 'AliasUsers'] },
+    meta: { menu: ['AliasBasicData', 'AliasUsers'] },
     children: [
         {
             name: 'AliasSummary',
diff --git a/src/router/modules/account/roleCard.js b/src/router/modules/account/roleCard.js
index f8100071fbf..c36ce71b9da 100644
--- a/src/router/modules/account/roleCard.js
+++ b/src/router/modules/account/roleCard.js
@@ -4,7 +4,6 @@ export default {
     component: () => import('src/pages/Account/Role/Card/RoleCard.vue'),
     redirect: { name: 'RoleSummary' },
     meta: {
-        moduleName: 'Role',
         menu: ['RoleBasicData', 'SubRoles', 'InheritedRoles', 'RoleLog'],
     },
     children: [
diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js
index b5656dc5ffb..f362c76533c 100644
--- a/src/router/modules/entry.js
+++ b/src/router/modules/entry.js
@@ -6,7 +6,13 @@ const entryCard = {
     component: () => import('src/pages/Entry/Card/EntryCard.vue'),
     redirect: { name: 'EntrySummary' },
     meta: {
-        menu: ['EntryBasicData', 'EntryBuys', 'EntryNotes', 'EntryDms', 'EntryLog'],
+        menu: [
+            'EntryBasicData',
+            'EntryBuys',
+            'EntryNotes',
+            'EntryDms',
+            'EntryLog',
+        ],
     },
     children: [
         {
@@ -85,7 +91,7 @@ export default {
             'EntryLatestBuys',
             'EntryStockBought',
             'EntryWasteRecalc',
-        ],
+        ]
     },
     component: RouterView,
     redirect: { name: 'EntryMain' },
@@ -97,7 +103,7 @@ export default {
             redirect: { name: 'EntryIndexMain' },
             children: [
                 {
-                    path: '',
+                    path:'',
                     name: 'EntryIndexMain',
                     redirect: { name: 'EntryList' },
                     component: () => import('src/pages/Entry/EntryList.vue'),
@@ -109,7 +115,6 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
-                            component: () => import('src/pages/Entry/EntryList.vue'),
                         },
                         entryCard,
                     ],
@@ -122,7 +127,7 @@ export default {
                         icon: 'add',
                     },
                     component: () => import('src/pages/Entry/EntryCreate.vue'),
-                },
+                },                
                 {
                     path: 'my',
                     name: 'MyEntries',
@@ -162,4 +167,4 @@ export default {
             ],
         },
     ],
-};
+};
\ No newline at end of file
diff --git a/src/router/modules/route.js b/src/router/modules/route.js
index 835324d20b1..946ad3e15c0 100644
--- a/src/router/modules/route.js
+++ b/src/router/modules/route.js
@@ -160,36 +160,6 @@ const roadmapCard = {
     ],
 };
 
-const vehicleCard = {
-    path: ':id',
-    name: 'VehicleCard',
-    component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'),
-    redirect: { name: 'VehicleSummary' },
-    meta: {
-        menu: ['VehicleBasicData'],
-    },
-    children: [
-        {
-            name: 'VehicleSummary',
-            path: 'summary',
-            meta: {
-                title: 'summary',
-                icon: 'view_list',
-            },
-            component: () => import('src/pages/Route/Vehicle/Card/VehicleSummary.vue'),
-        },
-        {
-            name: 'VehicleBasicData',
-            path: 'basic-data',
-            meta: {
-                title: 'basicData',
-                icon: 'vn:settings',
-            },
-            component: () => import('src/pages/Route/Vehicle/Card/VehicleBasicData.vue'),
-        },
-    ],
-};
-
 export default {
     name: 'Route',
     path: '/route',
@@ -204,7 +174,6 @@ export default {
             'RouteRoadmap',
             'CmrList',
             'AgencyList',
-            'VehicleList',
         ],
     },
     component: RouterView,
@@ -311,27 +280,6 @@ export default {
                         agencyCard,
                     ],
                 },
-                {
-                    path: 'vehicle',
-                    name: 'RouteVehicle',
-                    redirect: { name: 'VehicleList' },
-                    meta: {
-                        title: 'vehicle',
-                        icon: 'directions_car',
-                    },
-                    component: () => import('src/pages/Route/Vehicle/VehicleList.vue'),
-                    children: [
-                        {
-                            path: 'list',
-                            name: 'VehicleList',
-                            meta: {
-                                title: 'vehicleList',
-                                icon: 'directions_car',
-                            },
-                        },
-                        vehicleCard,
-                    ],
-                },
             ],
         },
     ],
diff --git a/src/router/modules/shelving.js b/src/router/modules/shelving.js
index c085dd8dc71..55fb04278c6 100644
--- a/src/router/modules/shelving.js
+++ b/src/router/modules/shelving.js
@@ -3,7 +3,7 @@ import { RouterView } from 'vue-router';
 const parkingCard = {
     name: 'ParkingCard',
     path: ':id',
-    component: () => import('src/pages/Shelving/Parking/Card/ParkingCard.vue'),
+    component: () => import('src/pages/Parking/Card/ParkingCard.vue'),
     redirect: { name: 'ParkingSummary' },
     meta: {
         menu: ['ParkingBasicData', 'ParkingLog'],
@@ -16,7 +16,7 @@ const parkingCard = {
                 title: 'summary',
                 icon: 'launch',
             },
-            component: () => import('src/pages/Shelving/Parking/Card/ParkingSummary.vue'),
+            component: () => import('src/pages/Parking/Card/ParkingSummary.vue'),
         },
         {
             path: 'basic-data',
@@ -25,8 +25,7 @@ const parkingCard = {
                 title: 'basicData',
                 icon: 'vn:settings',
             },
-            component: () =>
-                import('src/pages/Shelving/Parking/Card/ParkingBasicData.vue'),
+            component: () => import('src/pages/Parking/Card/ParkingBasicData.vue'),
         },
         {
             path: 'log',
@@ -35,7 +34,7 @@ const parkingCard = {
                 title: 'log',
                 icon: 'history',
             },
-            component: () => import('src/pages/Shelving/Parking/Card/ParkingLog.vue'),
+            component: () => import('src/pages/Parking/Card/ParkingLog.vue'),
         },
     ],
 };
@@ -128,7 +127,7 @@ export default {
                         title: 'parkingList',
                         icon: 'view_list',
                     },
-                    component: () => import('src/pages/Shelving/Parking/ParkingList.vue'),
+                    component: () => import('src/pages/Parking/ParkingList.vue'),
                     children: [
                         {
                             path: 'list',
diff --git a/src/router/modules/supplier.js b/src/router/modules/supplier.js
index 19763cdf3b8..4ece4c78455 100644
--- a/src/router/modules/supplier.js
+++ b/src/router/modules/supplier.js
@@ -1,12 +1,19 @@
 import { RouterView } from 'vue-router';
 
-const supplierCard = {
-    name: 'SupplierCard',
-    path: ':id',
-    component: () => import('src/pages/Supplier/Card/SupplierCard.vue'),
-    redirect: { name: 'SupplierSummary' },
+export default {
+    path: '/supplier',
+    name: 'Supplier',
     meta: {
-        menu: [
+        title: 'suppliers',
+        icon: 'vn:supplier',
+        moduleName: 'Supplier',
+        keyBinding: 'p',
+    },
+    component: RouterView,
+    redirect: { name: 'SupplierMain' },
+    menus: {
+        main: ['SupplierList'],
+        card: [
             'SupplierBasicData',
             'SupplierFiscalData',
             'SupplierBillingData',
@@ -20,165 +27,21 @@ const supplierCard = {
             'SupplierDms',
         ],
     },
-    children: [
-        {
-            name: 'SupplierSummary',
-            path: 'summary',
-            meta: {
-                title: 'summary',
-                icon: 'launch',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierSummary.vue'),
-        },
-        {
-            path: 'basic-data',
-            name: 'SupplierBasicData',
-            meta: {
-                title: 'basicData',
-                icon: 'vn:settings',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierBasicData.vue'),
-        },
-        {
-            path: 'fiscal-data',
-            name: 'SupplierFiscalData',
-            meta: {
-                title: 'fiscalData',
-                icon: 'vn:dfiscales',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierFiscalData.vue'),
-        },
-        {
-            path: 'billing-data',
-            name: 'SupplierBillingData',
-            meta: {
-                title: 'billingData',
-                icon: 'vn:payment',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierBillingData.vue'),
-        },
-        {
-            path: 'log',
-            name: 'SupplierLog',
-            meta: {
-                title: 'log',
-                icon: 'vn:History',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierLog.vue'),
-        },
-        {
-            path: 'account',
-            name: 'SupplierAccounts',
-            meta: {
-                title: 'accounts',
-                icon: 'vn:credit',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierAccounts.vue'),
-        },
-        {
-            path: 'contact',
-            name: 'SupplierContacts',
-            meta: {
-                title: 'contacts',
-                icon: 'contact_phone',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierContacts.vue'),
-        },
-        {
-            path: 'address',
-            name: 'SupplierAddresses',
-            meta: {
-                title: 'addresses',
-                icon: 'vn:delivery',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierAddresses.vue'),
-        },
-        {
-            path: 'address/create',
-            name: 'SupplierAddressesCreate',
-            component: () =>
-                import('src/pages/Supplier/Card/SupplierAddressesCreate.vue'),
-        },
-        {
-            path: 'balance',
-            name: 'SupplierBalance',
-            meta: {
-                title: 'balance',
-                icon: 'balance',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierBalance.vue'),
-        },
-        {
-            path: 'consumption',
-            name: 'SupplierConsumption',
-            meta: {
-                title: 'consumption',
-                icon: 'show_chart',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierConsumption.vue'),
-        },
-        {
-            path: 'agency-term',
-            name: 'SupplierAgencyTerm',
-            meta: {
-                title: 'agencyTerm',
-                icon: 'vn:agency-term',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierAgencyTerm.vue'),
-        },
-        {
-            path: 'dms',
-            name: 'SupplierDms',
-            meta: {
-                title: 'dms',
-                icon: 'smb_share',
-            },
-            component: () => import('src/pages/Supplier/Card/SupplierDms.vue'),
-        },
-        {
-            path: 'agency-term/create',
-            name: 'SupplierAgencyTermCreate',
-            component: () =>
-                import('src/pages/Supplier/Card/SupplierAgencyTermCreate.vue'),
-        },
-    ],
-};
-
-export default {
-    name: 'Supplier',
-    path: '/supplier',
-    meta: {
-        title: 'suppliers',
-        icon: 'vn:supplier',
-        moduleName: 'Supplier',
-        keyBinding: 'p',
-        menu: ['SupplierList'],
-    },
-    component: RouterView,
-    redirect: { name: 'SupplierMain' },
     children: [
         {
             path: '',
             name: 'SupplierMain',
             component: () => import('src/components/common/VnModule.vue'),
-            redirect: { name: 'SupplierIndexMain' },
+            redirect: { name: 'SupplierList' },
             children: [
                 {
-                    path: '',
-                    name: 'SupplierIndexMain',
-                    redirect: { name: 'SupplierList' },
+                    path: 'list',
+                    name: 'SupplierList',
+                    meta: {
+                        title: 'list',
+                        icon: 'view_list',
+                    },
                     component: () => import('src/pages/Supplier/SupplierList.vue'),
-                    children: [
-                        {
-                            path: 'list',
-                            name: 'SupplierList',
-                            meta: {
-                                title: 'list',
-                                icon: 'view_list',
-                            },
-                        },
-                        supplierCard,
-                    ],
                 },
                 {
                     path: 'create',
@@ -191,5 +54,143 @@ export default {
                 },
             ],
         },
+        {
+            name: 'SupplierCard',
+            path: ':id',
+            component: () => import('src/pages/Supplier/Card/SupplierCard.vue'),
+            redirect: { name: 'SupplierSummary' },
+            children: [
+                {
+                    name: 'SupplierSummary',
+                    path: 'summary',
+                    meta: {
+                        title: 'summary',
+                        icon: 'launch',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierSummary.vue'),
+                },
+                {
+                    path: 'basic-data',
+                    name: 'SupplierBasicData',
+                    meta: {
+                        title: 'basicData',
+                        icon: 'vn:settings',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierBasicData.vue'),
+                },
+                {
+                    path: 'fiscal-data',
+                    name: 'SupplierFiscalData',
+                    meta: {
+                        title: 'fiscalData',
+                        icon: 'vn:dfiscales',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierFiscalData.vue'),
+                },
+                {
+                    path: 'billing-data',
+                    name: 'SupplierBillingData',
+                    meta: {
+                        title: 'billingData',
+                        icon: 'vn:payment',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierBillingData.vue'),
+                },
+                {
+                    path: 'log',
+                    name: 'SupplierLog',
+                    meta: {
+                        title: 'log',
+                        icon: 'vn:History',
+                    },
+                    component: () => import('src/pages/Supplier/Card/SupplierLog.vue'),
+                },
+                {
+                    path: 'account',
+                    name: 'SupplierAccounts',
+                    meta: {
+                        title: 'accounts',
+                        icon: 'vn:credit',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierAccounts.vue'),
+                },
+                {
+                    path: 'contact',
+                    name: 'SupplierContacts',
+                    meta: {
+                        title: 'contacts',
+                        icon: 'contact_phone',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierContacts.vue'),
+                },
+                {
+                    path: 'address',
+                    name: 'SupplierAddresses',
+                    meta: {
+                        title: 'addresses',
+                        icon: 'vn:delivery',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierAddresses.vue'),
+                },
+                {
+                    path: 'address/create',
+                    name: 'SupplierAddressesCreate',
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierAddressesCreate.vue'),
+                },
+                {
+                    path: 'balance',
+                    name: 'SupplierBalance',
+                    meta: {
+                        title: 'balance',
+                        icon: 'balance',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierBalance.vue'),
+                },
+                {
+                    path: 'consumption',
+                    name: 'SupplierConsumption',
+                    meta: {
+                        title: 'consumption',
+                        icon: 'show_chart',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierConsumption.vue'),
+                },
+                {
+                    path: 'agency-term',
+                    name: 'SupplierAgencyTerm',
+                    meta: {
+                        title: 'agencyTerm',
+                        icon: 'vn:agency-term',
+                    },
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierAgencyTerm.vue'),
+                },
+                {
+                    path: 'dms',
+                    name: 'SupplierDms',
+                    meta: {
+                        title: 'dms',
+                        icon: 'smb_share',
+                    },
+                    component: () => import('src/pages/Supplier/Card/SupplierDms.vue'),
+                },
+                {
+                    path: 'agency-term/create',
+                    name: 'SupplierAgencyTermCreate',
+                    component: () =>
+                        import('src/pages/Supplier/Card/SupplierAgencyTermCreate.vue'),
+                },
+            ],
+        },
     ],
 };
diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js
index bfcb78787e2..e5b423f64de 100644
--- a/src/router/modules/ticket.js
+++ b/src/router/modules/ticket.js
@@ -192,13 +192,7 @@ export default {
         icon: 'vn:ticket',
         moduleName: 'Ticket',
         keyBinding: 't',
-        menu: [
-            'TicketList',
-            'TicketAdvance',
-            'TicketWeekly',
-            'TicketFuture',
-            'TicketNegative',
-        ],
+        menu: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
     },
     component: RouterView,
     redirect: { name: 'TicketMain' },
@@ -235,32 +229,6 @@ export default {
                     },
                     component: () => import('src/pages/Ticket/TicketCreate.vue'),
                 },
-                {
-                    path: 'negative',
-                    redirect: { name: 'TicketNegative' },
-                    children: [
-                        {
-                            name: 'TicketNegative',
-                            meta: {
-                                title: 'negative',
-                                icon: 'exposure',
-                            },
-                            component: () =>
-                                import('src/pages/Ticket/Negative/TicketLackList.vue'),
-                            path: '',
-                        },
-                        {
-                            name: 'NegativeDetail',
-                            path: ':id',
-                            meta: {
-                                title: 'summary',
-                                icon: 'launch',
-                            },
-                            component: () =>
-                                import('src/pages/Ticket/Negative/TicketLackDetail.vue'),
-                        },
-                    ],
-                },
                 {
                     path: 'weekly',
                     name: 'TicketWeekly',
diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js
index 3eb95a96ee2..1d013c5964f 100644
--- a/src/router/modules/worker.js
+++ b/src/router/modules/worker.js
@@ -201,10 +201,9 @@ const workerCard = {
 const departmentCard = {
     name: 'DepartmentCard',
     path: ':id',
-    component: () => import('src/pages/Worker/Department/Card/DepartmentCard.vue'),
+    component: () => import('src/pages/Department/Card/DepartmentCard.vue'),
     redirect: { name: 'DepartmentSummary' },
     meta: {
-        moduleName: 'Department',
         menu: ['DepartmentBasicData'],
     },
     children: [
@@ -215,8 +214,7 @@ const departmentCard = {
                 title: 'summary',
                 icon: 'launch',
             },
-            component: () =>
-                import('src/pages/Worker/Department/Card/DepartmentSummary.vue'),
+            component: () => import('src/pages/Department/Card/DepartmentSummary.vue'),
         },
         {
             path: 'basic-data',
@@ -225,8 +223,7 @@ const departmentCard = {
                 title: 'basicData',
                 icon: 'vn:settings',
             },
-            component: () =>
-                import('src/pages/Worker/Department/Card/DepartmentBasicData.vue'),
+            component: () => import('src/pages/Department/Card/DepartmentBasicData.vue'),
         },
     ],
 };
diff --git a/src/stores/__tests__/useNavigationStore.spec.js b/src/stores/__tests__/useNavigationStore.spec.js
deleted file mode 100644
index c5df6157e5c..00000000000
--- a/src/stores/__tests__/useNavigationStore.spec.js
+++ /dev/null
@@ -1,153 +0,0 @@
-import { setActivePinia, createPinia } from 'pinia';
-import { describe, beforeEach, afterEach, it, expect, vi, beforeAll } from 'vitest';
-import { useNavigationStore } from '../useNavigationStore';
-import axios from 'axios';
-
-let store;
-
-vi.mock('src/router/modules', () => [
-    { name: 'Item', meta: {} },
-    { name: 'Shelving', meta: {} },
-    { name: 'Order', meta: {} },
-]);
-
-vi.mock('src/filters', () => ({
-    toLowerCamel: vi.fn((name) => name.toLowerCase()),
-}));
-
-const modulesMock = [
-    {
-        name: 'Item',
-        children: null,
-        title: 'globals.pageTitles.undefined',
-        icon: undefined,
-        module: 'item',
-        isPinned: true,
-    },
-    {
-        name: 'Shelving',
-        children: null,
-        title: 'globals.pageTitles.undefined',
-        icon: undefined,
-        module: 'shelving',
-        isPinned: false,
-    },
-    {
-        name: 'Order',
-        children: null,
-        title: 'globals.pageTitles.undefined',
-        icon: undefined,
-        module: 'order',
-        isPinned: false,
-    },
-];
-
-const pinnedModulesMock = [
-    {
-        name: 'Item',
-        children: null,
-        title: 'globals.pageTitles.undefined',
-        icon: undefined,
-        module: 'item',
-        isPinned: true,
-    },
-];
-
-describe('useNavigationStore', () => {
-    beforeEach(() => {
-        setActivePinia(createPinia());
-        vi.spyOn(axios, 'get').mockResolvedValue({ data: true });
-        store = useNavigationStore();
-        store.getModules = vi.fn().mockReturnValue({
-            value: modulesMock,
-        });
-        store.getPinnedModules = vi.fn().mockReturnValue({
-            value: pinnedModulesMock,
-        });
-    });
-    afterEach(() => {
-        vi.clearAllMocks();
-    });
-
-    it('should return modules with correct structure', () => {
-        const store = useNavigationStore();
-        const modules = store.getModules();
-
-        expect(modules.value).toEqual(modulesMock);
-    });
-
-    it('should return pinned modules', () => {
-        const store = useNavigationStore();
-        const pinnedModules = store.getPinnedModules();
-
-        expect(pinnedModules.value).toEqual(pinnedModulesMock);
-    });
-
-    it('should toggle pinned modules', () => {
-        const store = useNavigationStore();
-
-        store.togglePinned('item');
-        store.togglePinned('shelving');
-        expect(store.pinnedModules).toEqual(['item', 'shelving']);
-
-        store.togglePinned('item');
-        expect(store.pinnedModules).toEqual(['shelving']);
-    });
-
-    it('should fetch pinned modules', async () => {
-        vi.spyOn(axios, 'get').mockResolvedValue({
-            data: [{ id: 1, workerFk: 9, moduleFk: 'order', position: 1 }],
-        });
-        const store = useNavigationStore();
-        await store.fetchPinned();
-
-        expect(store.pinnedModules).toEqual(['order']);
-    });
-
-    it('should add menu item correctly', () => {
-        const store = useNavigationStore();
-        const module = 'customer';
-        const parent = [];
-        const route = {
-            name: 'customer',
-            title: 'Customer',
-            icon: 'customer',
-            meta: {
-                keyBinding: 'ctrl+shift+c',
-                name: 'customer',
-                title: 'Customer',
-                icon: 'customer',
-                menu: 'customer',
-                menuChildren: [{ name: 'customer', title: 'Customer', icon: 'customer' }],
-            },
-        };
-
-        const result = store.addMenuItem(module, route, parent);
-        const expectedItem = {
-            children: [
-                {
-                    icon: 'customer',
-                    name: 'customer',
-                    title: 'globals.pageTitles.Customer',
-                },
-            ],
-            icon: 'customer',
-            keyBinding: 'ctrl+shift+c',
-            name: 'customer',
-            title: 'globals.pageTitles.Customer',
-        };
-        expect(result).toEqual(expectedItem);
-        expect(parent.length).toBe(1);
-        expect(parent).toEqual([expectedItem]);
-    });
-
-    it('should not add menu item if condition is not met', () => {
-        const store = useNavigationStore();
-        const module = 'testModule';
-        const route = { meta: { hidden: true, menuchildren: {} } };
-        const parent = [];
-        const result = store.addMenuItem(module, route, parent);
-        expect(result).toBeUndefined();
-        expect(parent.length).toBe(0);
-    });
-});
diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js
index b3996d1e3e2..8d62fdb4a22 100644
--- a/src/stores/useArrayDataStore.js
+++ b/src/stores/useArrayDataStore.js
@@ -19,7 +19,6 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
         page: 1,
         mapKey: 'id',
         keepData: false,
-        oneRecord: false,
     };
 
     function get(key) {
diff --git a/src/utils/notifyResults.js b/src/utils/notifyResults.js
deleted file mode 100644
index e87ad6c6f7b..00000000000
--- a/src/utils/notifyResults.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Notify } from 'quasar';
-
-export default function (results, key) {
-    results.forEach((result, index) => {
-        if (result.status === 'fulfilled') {
-            const data = JSON.parse(result.value.config.data);
-            Notify.create({
-                type: 'positive',
-                message: `Operación (${index + 1}) ${data[key]} completada con éxito.`,
-            });
-        } else {
-            const data = JSON.parse(result.reason.config.data);
-            Notify.create({
-                type: 'negative',
-                message: `Operación (${index + 1}) ${data[key]} fallida: ${result.reason.message}`,
-            });
-        }
-    });
-}
diff --git a/test/cypress/integration/Order/orderCatalog.spec.js b/test/cypress/integration/Order/orderCatalog.spec.js
index 1770a6b56e9..cffc47f9150 100644
--- a/test/cypress/integration/Order/orderCatalog.spec.js
+++ b/test/cypress/integration/Order/orderCatalog.spec.js
@@ -45,6 +45,7 @@ describe('OrderCatalog', () => {
         ).type('{enter}');
         cy.get(':nth-child(1) > [data-cy="catalogFilterCategory"]').click();
         cy.dataCy('catalogFilterValueDialogBtn').last().click();
+        cy.get('[data-cy="catalogFilterValueDialogTagSelect"]').click();
         cy.selectOption("[data-cy='catalogFilterValueDialogTagSelect']", 'Tallos');
         cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus();
         cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2');
diff --git a/test/cypress/integration/entry/entryList.spec.js b/test/cypress/integration/entry/entryList.spec.js
deleted file mode 100644
index 4f99f0cb6f1..00000000000
--- a/test/cypress/integration/entry/entryList.spec.js
+++ /dev/null
@@ -1,224 +0,0 @@
-describe('Entry', () => {
-    beforeEach(() => {
-        cy.viewport(1920, 1080);
-        cy.login('buyer');
-        cy.visit(`/#/entry/list`);
-    });
-
-    it('Filter deleted entries and other fields', () => {
-        createEntry();
-        cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
-        cy.waitForElement('[data-cy="entry-buys"]');
-        deleteEntry();
-        cy.typeSearchbar('{enter}');
-        cy.get('span[title="Date"]').click().click();
-        cy.typeSearchbar('{enter}');
-        cy.url().should('include', 'order');
-        cy.get('td[data-row-index="0"][data-col-field="landed"]').should(
-            'have.text',
-            '-',
-        );
-    });
-
-    it('Create entry, modify travel and add buys', () => {
-        createEntryAndBuy();
-        cy.get('a[data-cy="EntryBasicData-menu-item"]').click();
-        selectTravel('two');
-        cy.saveCard();
-        cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
-        deleteEntry();
-    });
-
-    it('Clone entry and recalculate rates', () => {
-        createEntry();
-
-        cy.waitForElement('[data-cy="entry-buys"]');
-
-        cy.url().then((previousUrl) => {
-            cy.get('[data-cy="descriptor-more-opts"]').click();
-            cy.get('div[data-cy="clone-entry"]').should('be.visible').click();
-
-            cy.get('.q-notification__message').eq(1).should('have.text', 'Entry cloned');
-
-            cy.url()
-                .should('not.eq', previousUrl)
-                .then(() => {
-                    cy.waitForElement('[data-cy="entry-buys"]');
-
-                    cy.get('[data-cy="descriptor-more-opts"]').click();
-                    cy.get('div[data-cy="recalculate-rates"]').click();
-
-                    cy.get('.q-notification__message')
-                        .eq(2)
-                        .should('have.text', 'Entry prices recalculated');
-
-                    cy.get('[data-cy="descriptor-more-opts"]').click();
-                    deleteEntry();
-
-                    cy.log(previousUrl);
-
-                    cy.visit(previousUrl);
-
-                    cy.waitForElement('[data-cy="entry-buys"]');
-                    deleteEntry();
-                });
-        });
-    });
-
-    it('Should notify when entry is lock by another user', () => {
-        const checkLockMessage = () => {
-            cy.get('[data-cy="entry-lock-confirm"]').should('be.visible');
-            cy.get('[data-cy="VnConfirm_message"] > span').should(
-                'contain.text',
-                'This entry has been locked by buyerNick',
-            );
-        };
-
-        createEntry();
-        goToEntryBuys();
-        cy.get('.q-notification__message')
-            .eq(1)
-            .should('have.text', 'The entry has been locked successfully');
-
-        cy.login('logistic');
-        cy.reload();
-        checkLockMessage();
-        cy.get('[data-cy="VnConfirm_cancel"]').click();
-        cy.url().should('include', 'summary');
-
-        goToEntryBuys();
-        checkLockMessage();
-        cy.get('[data-cy="VnConfirm_confirm"]').click();
-        cy.url().should('include', 'buys');
-
-        deleteEntry();
-    });
-
-    it('Edit buys and use toolbar actions', () => {
-        const COLORS = {
-            negative: 'rgb(251, 82, 82)',
-            positive: 'rgb(200, 228, 132)',
-            enabled: 'rgb(255, 255, 255)',
-            disable: 'rgb(168, 168, 168)',
-        };
-
-        const selectCell = (field, row = 0) =>
-            cy.get(`td[data-col-field="${field}"][data-row-index="${row}"]`);
-        const selectSpan = (field, row = 0) => selectCell(field, row).find('div > span');
-        const selectButton = (cySelector) => cy.get(`button[data-cy="${cySelector}"]`);
-        const clickAndType = (field, value, row = 0) => {
-            selectCell(field, row).click().type(`${value}{esc}`);
-        };
-        const checkText = (field, expectedText, row = 0) =>
-            selectCell(field, row).should('have.text', expectedText);
-        const checkColor = (field, expectedColor, row = 0) =>
-            selectSpan(field, row).should('have.css', 'color', expectedColor);
-
-        createEntryAndBuy();
-
-        selectCell('isIgnored').click().click().type('{esc}');
-        checkText('isIgnored', 'close');
-
-        clickAndType('stickers', '1');
-        checkText('stickers', '0/01');
-        checkText('quantity', '1');
-        checkText('amount', '50.00');
-        clickAndType('packing', '2');
-        checkText('packing', '12');
-        checkText('weight', '12.0');
-        checkText('quantity', '12');
-        checkText('amount', '600.00');
-        checkColor('packing', COLORS.enabled);
-
-        selectCell('groupingMode').click().click().click();
-        checkColor('packing', COLORS.disable);
-        checkColor('grouping', COLORS.enabled);
-
-        selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
-        checkText('amount', '12.00');
-        checkColor('minPrice', COLORS.disable);
-
-        selectCell('hasMinPrice').click().click();
-        checkColor('minPrice', COLORS.enabled);
-        selectCell('hasMinPrice').click();
-
-        cy.saveCard();
-        cy.get('span[data-cy="footer-stickers"]').should('have.text', '1');
-        cy.get('.q-notification__message').contains('Data saved');
-
-        selectButton('change-quantity-sign').should('be.disabled');
-        selectButton('check-buy-amount').should('be.disabled');
-        cy.get('tr.cursor-pointer > .q-table--col-auto-width > .q-checkbox').click();
-        selectButton('change-quantity-sign').should('be.enabled');
-        selectButton('check-buy-amount').should('be.enabled');
-
-        selectButton('change-quantity-sign').click();
-        selectButton('set-negative-quantity').click();
-        checkText('quantity', '-12');
-        selectButton('set-positive-quantity').click();
-        checkText('quantity', '12');
-        checkColor('amount', COLORS.disable);
-
-        selectButton('check-buy-amount').click();
-        selectButton('uncheck-amount').click();
-        checkColor('amount', COLORS.disable);
-
-        selectButton('check-amount').click();
-        checkColor('amount', COLORS.positive);
-        cy.saveCard();
-
-        cy.get('span[data-cy="footer-amount"]').should(
-            'have.css',
-            'color',
-            COLORS.positive,
-        );
-
-        deleteEntry();
-    });
-
-    function goToEntryBuys() {
-        const entryBuySelector = 'a[data-cy="EntryBuys-menu-item"]';
-        cy.get(entryBuySelector).should('be.visible');
-        cy.waitForElement('[data-cy="entry-buys"]');
-        cy.get(entryBuySelector).click();
-    }
-
-    function deleteEntry() {
-        cy.get('[data-cy="descriptor-more-opts"]').click();
-        cy.waitForElement('div[data-cy="delete-entry"]');
-        cy.get('div[data-cy="delete-entry"]').should('be.visible').click();
-        cy.url().should('include', 'list');
-    }
-
-    function createEntryAndBuy() {
-        createEntry();
-        createBuy();
-    }
-
-    function createEntry() {
-        cy.get('button[data-cy="vnTableCreateBtn"]').click();
-        selectTravel('one');
-        cy.get('button[data-cy="FormModelPopup_save"]').click();
-        cy.url().should('include', 'summary');
-        cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
-    }
-
-    function selectTravel(warehouse) {
-        cy.get('i[data-cy="Travel_icon"]').click();
-        cy.get('input[data-cy="Warehouse Out_select"]').type(warehouse);
-        cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
-        cy.get('button[data-cy="save-filter-travel-form"]').click();
-        cy.get('tr').eq(1).click();
-    }
-
-    function createBuy() {
-        cy.get('a[data-cy="EntryBuys-menu-item"]').click();
-        cy.get('a[data-cy="EntryBuys-menu-item"]').click();
-        cy.get('button[data-cy="vnTableCreateBtn"]').click();
-
-        cy.get('input[data-cy="itemFk-create-popup"]').type('1');
-        cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
-        cy.get('input[data-cy="Grouping mode_select"]').should('have.value', 'packing');
-        cy.get('button[data-cy="FormModelPopup_save"]').click();
-    }
-});
diff --git a/test/cypress/integration/entry/stockBought.spec.js b/test/cypress/integration/entry/stockBought.spec.js
index bc36156b4e4..078ad19cc28 100644
--- a/test/cypress/integration/entry/stockBought.spec.js
+++ b/test/cypress/integration/entry/stockBought.spec.js
@@ -6,7 +6,6 @@ describe('EntryStockBought', () => {
     });
     it('Should edit the reserved space', () => {
         cy.get('.q-field__native.q-placeholder').should('have.value', '01/01/2001');
-        cy.get('[data-col-field="reserve"][data-row-index="0"]').click();
         cy.get('input[name="reserve"]').type('10{enter}');
         cy.get('button[title="Save"]').click();
         cy.get('.q-notification__message').should('have.text', 'Data saved');
@@ -16,35 +15,25 @@ describe('EntryStockBought', () => {
         cy.get('input[aria-label="Reserve"]').type('1');
         cy.get('input[aria-label="Date"]').eq(1).clear();
         cy.get('input[aria-label="Date"]').eq(1).type('01-01');
-        cy.get('input[aria-label="Buyer"]').type('buyerBossNick');
-        cy.get('div[role="listbox"] > div > div[role="option"]')
-            .eq(0)
-            .should('be.visible')
-            .click();
-
-        cy.get('[data-cy="FormModelPopup_save"]').click();
+        cy.get('input[aria-label="Buyer"]').type('buyerboss{downarrow}{enter}');
         cy.get('.q-notification__message').should('have.text', 'Data created');
-
-        cy.get('[data-col-field="reserve"][data-row-index="1"]').click().clear();
-        cy.get('[data-cy="searchBtn"]').eq(1).click();
-        cy.get('.q-table__bottom.row.items-center.q-table__bottom--nodata')
-            .should('have.text', 'warningNo data available')
-            .type('{esc}');
-        cy.get('[data-col-field="reserve"][data-row-index="1"]')
-            .click()
-            .type('{backspace}{enter}');
-        cy.get('[data-cy="crudModelDefaultSaveBtn"]').should('be.enabled').click();
-        cy.get('.q-notification__message').eq(1).should('have.text', 'Data saved');
     });
     it('Should check detail for the buyer', () => {
-        cy.get('[data-cy="searchBtn"]').eq(0).click();
+        cy.get(':nth-child(1) > .sticky > .q-btn > .q-btn__content > .q-icon').click();
         cy.get('tBody > tr').eq(1).its('length').should('eq', 1);
     });
-
+    it('Should check detail for the buyerBoss and had no content', () => {
+        cy.get(':nth-child(2) > .sticky > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get('.q-table__bottom.row.items-center.q-table__bottom--nodata').should(
+            'have.text',
+            'warningNo data available'
+        );
+    });
     it('Should edit travel m3 and refresh', () => {
-        cy.get('[data-cy="edit-travel"]').should('be.visible').click();
-        cy.get('input[aria-label="m3"]').clear().type('60');
-        cy.get('[data-cy="FormModelPopup_save"]').click();
+        cy.get('.vn-row > div > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get('input[aria-label="m3"]').clear();
+        cy.get('input[aria-label="m3"]').type('60');
+        cy.get('.q-mt-lg > .q-btn--standard > .q-btn__content > .block').click();
         cy.get('.vn-row > div > :nth-child(2)').should('have.text', '60');
     });
 });
diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
index 11ca1bb59be..2016fca6df0 100644
--- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
@@ -1,9 +1,9 @@
 /// <reference types="cypress" />
 describe('InvoiceInBasicData', () => {
+    const formInputs = '.q-form > .q-card input';
     const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select';
+    const documentBtns = '[data-cy="dms-buttons"] button';
     const dialogInputs = '.q-dialog input';
-    const resetBtn = '.q-btn-group--push > .q-btn--flat';
-    const getDocumentBtns = (opt) => `[data-cy="dms-buttons"]  > :nth-child(${opt})`;
 
     beforeEach(() => {
         cy.login('developer');
@@ -11,16 +11,13 @@ describe('InvoiceInBasicData', () => {
     });
 
     it('should edit the provideer and supplier ref', () => {
-        cy.dataCy('UnDeductibleVatSelect').type('4751000000');
-        cy.get('.q-menu .q-item').contains('4751000000').click();
-        cy.get(resetBtn).click();
-
-        cy.waitForElement('#formModel').within(() => {
-            cy.dataCy('vnSupplierSelect').type('Bros nick');
-        })
-        cy.get('.q-menu .q-item').contains('Bros nick').click();
+        cy.selectOption(firstFormSelect, 'Bros');
+        cy.get('[title="Reset"]').click();
+        cy.get(formInputs).eq(1).type('{selectall}4739');
         cy.saveCard();
-        cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Bros nick');
+
+        cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Plants nick');
+        cy.get(formInputs).eq(1).invoke('val').should('eq', '4739');
     });
 
     it('should edit, remove and create the dms data', () => {
@@ -28,18 +25,18 @@ describe('InvoiceInBasicData', () => {
         const secondInput = "I don't know what posting here!";
 
         //edit
-        cy.get(getDocumentBtns(2)).click();
+        cy.get(documentBtns).eq(1).click();
         cy.get(dialogInputs).eq(0).type(`{selectall}${firtsInput}`);
         cy.get('textarea').type(`{selectall}${secondInput}`);
         cy.get('[data-cy="FormModelPopup_save"]').click();
-        cy.get(getDocumentBtns(2)).click();
+        cy.get(documentBtns).eq(1).click();
         cy.get(dialogInputs).eq(0).invoke('val').should('eq', firtsInput);
         cy.get('textarea').invoke('val').should('eq', secondInput);
         cy.get('[data-cy="FormModelPopup_save"]').click();
         cy.checkNotification('Data saved');
 
         //remove
-        cy.get(getDocumentBtns(3)).click();
+        cy.get(documentBtns).eq(2).click();
         cy.get('[data-cy="VnConfirm_confirm"]').click();
         cy.checkNotification('Data saved');
 
@@ -49,7 +46,7 @@ describe('InvoiceInBasicData', () => {
             'test/cypress/fixtures/image.jpg',
             {
                 force: true,
-            },
+            }
         );
         cy.get('[data-cy="FormModelPopup_save"]').click();
         cy.checkNotification('Data saved');
diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
index 1e7ce1003b7..f8b403a458f 100644
--- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
@@ -36,7 +36,7 @@ describe('InvoiceInVat', () => {
         cy.get(dialogInputs).eq(0).type(randomInt);
         cy.get(dialogInputs).eq(1).type('This is a dummy expense');
 
-        cy.get('[data-cy="FormModelPopup_save"]').click();
+        cy.get('button[type="submit"]').click();
         cy.get('.q-notification__message').should('have.text', 'Data created');
     });
 });
diff --git a/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js b/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
index 02b7fbb43ce..5f629df0b2c 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
@@ -7,7 +7,9 @@ describe('InvoiceOut negative bases', () => {
     });
 
     it('should filter and download as CSV', () => {
-        cy.get('input[name="ticketFk"]').type('23{enter}');
+        cy.get(
+            ':nth-child(7) > .full-width > :nth-child(1) > .column > div.q-px-xs > .q-field > .q-field__inner > .q-field__control'
+        ).type('23{enter}');
         cy.get('#subToolbar > .q-btn').click();
         cy.checkNotification('CSV downloaded successfully');
     });
diff --git a/test/cypress/integration/item/ItemProposal.spec.js b/test/cypress/integration/item/ItemProposal.spec.js
deleted file mode 100644
index b3ba9f67645..00000000000
--- a/test/cypress/integration/item/ItemProposal.spec.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/// <reference types="cypress" />
-describe('ItemProposal', () => {
-    beforeEach(() => {
-        const ticketId = 1;
-
-        cy.login('developer');
-        cy.visit(`/#/ticket/${ticketId}/summary`);
-    });
-
-    describe('Handle item proposal selected', () => {});
-});
diff --git a/test/cypress/integration/item/itemTag.spec.js b/test/cypress/integration/item/itemTag.spec.js
index 425eaffe63b..17423bc5108 100644
--- a/test/cypress/integration/item/itemTag.spec.js
+++ b/test/cypress/integration/item/itemTag.spec.js
@@ -16,7 +16,10 @@ describe('Item tag', () => {
         cy.dataCy(newTag).should('be.visible').click().type('Genero{enter}');
         cy.dataCy('tagGeneroValue').eq(1).should('be.visible');
         cy.dataCy(saveBtn).click();
-        cy.checkNotification("The tag or priority can't be repeated for an item");
+        cy.get('.q-notification__message').should(
+            'have.text',
+            "The tag or priority can't be repeated for an item",
+        );
     });
 
     it('should add a new tag', () => {
diff --git a/test/cypress/integration/parking/parkingBasicData.spec.js b/test/cypress/integration/parking/parkingBasicData.spec.js
index f64f23ec83e..0d130d335ab 100644
--- a/test/cypress/integration/parking/parkingBasicData.spec.js
+++ b/test/cypress/integration/parking/parkingBasicData.spec.js
@@ -13,11 +13,11 @@ describe('ParkingBasicData', () => {
         cy.get(sectorOpt).click();
 
         cy.get(codeInput).eq(0).clear();
-        cy.get(codeInput).eq(0).type('900-001');
+        cy.get(codeInput).eq(0).type(123);
 
         cy.saveCard();
 
         cy.get(sectorSelect).should('have.value', 'Second sector');
-        cy.get(codeInput).should('have.value', '900-001');
+        cy.get(codeInput).should('have.value', 123);
     });
 });
diff --git a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
index 82ec6626da0..e28caea7c55 100644
--- a/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
+++ b/test/cypress/integration/route/agency/agencyWorkCenter.spec.js
@@ -15,7 +15,6 @@ describe('AgencyWorkCenter', () => {
 
         // expect error when duplicate
         cy.get(createButton).click();
-        cy.selectOption(workCenterCombobox, 'workCenterOne');
         cy.get('[data-cy="FormModelPopup_save"]').click();
         cy.checkNotification('This workCenter is already assigned to this agency');
         cy.get('[data-cy="FormModelPopup_cancel"]').click();
diff --git a/test/cypress/integration/route/routeList.spec.js b/test/cypress/integration/route/routeList.spec.js
index 976ce735204..4da43ce8e63 100644
--- a/test/cypress/integration/route/routeList.spec.js
+++ b/test/cypress/integration/route/routeList.spec.js
@@ -4,6 +4,9 @@ describe('Route', () => {
         cy.login('developer');
         cy.visit(`/#/route/extended-list`);
     });
+    const getVnSelect =
+        '> :nth-child(1) > .column > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
+    const getRowColumn = (row, column) => `:nth-child(${row}) > :nth-child(${column})`;
 
     it('Route list create route', () => {
         cy.addBtnClick();
@@ -14,23 +17,15 @@ describe('Route', () => {
 
     it('Route list search and edit', () => {
         cy.get('#searchbar input').type('{enter}');
-        cy.get('[data-col-field="description"][data-row-index="0"]')
-            .click()
-            .type('routeTestOne{enter}');
+        cy.get('input[name="description"]').type('routeTestOne{enter}');
         cy.get('.q-table tr')
             .its('length')
             .then((rowCount) => {
                 expect(rowCount).to.be.greaterThan(0);
             });
-        cy.get('[data-col-field="workerFk"][data-row-index="0"]')
-            .click()
-            .type('{downArrow}{enter}');
-        cy.get('[data-col-field="agencyModeFk"][data-row-index="0"]')
-            .click()
-            .type('{downArrow}{enter}');
-        cy.get('[data-col-field="vehicleFk"][data-row-index="0"]')
-            .click()
-            .type('{downArrow}{enter}');
+        cy.get(getRowColumn(1, 3) + getVnSelect).type('{downArrow}{enter}');
+        cy.get(getRowColumn(1, 4) + getVnSelect).type('{downArrow}{enter}');
+        cy.get(getRowColumn(1, 5) + getVnSelect).type('{downArrow}{enter}');
         cy.get('button[title="Save"]').click();
         cy.get('.q-notification__message').should('have.text', 'Data saved');
     });
diff --git a/test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js b/test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js
deleted file mode 100644
index 64b9ca0a000..00000000000
--- a/test/cypress/integration/route/vehicle/vehicleDescriptor.spec.js
+++ /dev/null
@@ -1,13 +0,0 @@
-describe('Vehicle', () => {
-    beforeEach(() => {
-        cy.viewport(1920, 1080);
-        cy.login('deliveryAssistant');
-        cy.visit(`/#/route/vehicle/7`);
-    });
-
-    it('should delete a vehicle', () => {
-        cy.openActionsDescriptor();
-        cy.get('[data-cy="delete"]').click();
-        cy.checkNotification('Vehicle removed');
-    });
-});
diff --git a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
deleted file mode 100644
index 9ea1cff6311..00000000000
--- a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/// <reference types="cypress" />
-describe('Ticket Lack detail', () => {
-    beforeEach(() => {
-        cy.login('developer');
-        cy.intercept('GET', /\/api\/Tickets\/itemLack\/5.*$/, {
-            statusCode: 200,
-            body: [
-                {
-                    saleFk: 33,
-                    code: 'OK',
-                    ticketFk: 142,
-                    nickname: 'Malibu Point',
-                    shipped: '2000-12-31T23:00:00.000Z',
-                    hour: 0,
-                    quantity: 50,
-                    agName: 'Super-Man delivery',
-                    alertLevel: 0,
-                    stateName: 'OK',
-                    stateId: 3,
-                    itemFk: 5,
-                    price: 1.79,
-                    alertLevelCode: 'FREE',
-                    zoneFk: 9,
-                    zoneName: 'Zone superMan',
-                    theoreticalhour: '2011-11-01T22:59:00.000Z',
-                    isRookie: 1,
-                    turno: 1,
-                    peticionCompra: 1,
-                    hasObservation: 1,
-                    hasToIgnore: 1,
-                    isBasket: 1,
-                    minTimed: 0,
-                    customerId: 1104,
-                    customerName: 'Tony Stark',
-                    observationTypeCode: 'administrative',
-                },
-            ],
-        }).as('getItemLack');
-
-        cy.visit('/#/ticket/negative/5');
-        cy.wait('@getItemLack');
-    });
-    describe('Table actions', () => {
-        it.skip('should display only one row in the lack list', () => {
-            cy.location('href').should('contain', '#/ticket/negative/5');
-
-            cy.get('[data-cy="changeItem"]').should('be.disabled');
-            cy.get('[data-cy="changeState"]').should('be.disabled');
-            cy.get('[data-cy="changeQuantity"]').should('be.disabled');
-            cy.get('[data-cy="itemProposal"]').should('be.disabled');
-            cy.get('[data-cy="transferLines"]').should('be.disabled');
-            cy.get('tr.cursor-pointer > :nth-child(1)').click();
-            cy.get('[data-cy="changeItem"]').should('be.enabled');
-            cy.get('[data-cy="changeState"]').should('be.enabled');
-            cy.get('[data-cy="changeQuantity"]').should('be.enabled');
-            cy.get('[data-cy="itemProposal"]').should('be.enabled');
-            cy.get('[data-cy="transferLines"]').should('be.enabled');
-        });
-    });
-    describe('Item proposal', () => {
-        beforeEach(() => {
-            cy.get('tr.cursor-pointer > :nth-child(1)').click();
-
-            cy.intercept('GET', /\/api\/Items\/getSimilar\?.*$/, {
-                statusCode: 200,
-                body: [
-                    {
-                        id: 1,
-                        longName: 'Ranged weapon longbow 50cm',
-                        subName: 'Stark Industries',
-                        tag5: 'Color',
-                        value5: 'Brown',
-                        match5: 0,
-                        match6: 0,
-                        match7: 0,
-                        match8: 1,
-                        tag6: 'Categoria',
-                        value6: '+1 precission',
-                        tag7: 'Tallos',
-                        value7: '1',
-                        tag8: null,
-                        value8: null,
-                        available: 20,
-                        calc_id: 6,
-                        counter: 0,
-                        minQuantity: 1,
-                        visible: null,
-                        price2: 1,
-                    },
-                    {
-                        id: 2,
-                        longName: 'Ranged weapon longbow 100cm',
-                        subName: 'Stark Industries',
-                        tag5: 'Color',
-                        value5: 'Brown',
-                        match5: 0,
-                        match6: 1,
-                        match7: 0,
-                        match8: 1,
-                        tag6: 'Categoria',
-                        value6: '+1 precission',
-                        tag7: 'Tallos',
-                        value7: '1',
-                        tag8: null,
-                        value8: null,
-                        available: 50,
-                        calc_id: 6,
-                        counter: 1,
-                        minQuantity: 5,
-                        visible: null,
-                        price2: 10,
-                    },
-                    {
-                        id: 3,
-                        longName: 'Ranged weapon longbow 200cm',
-                        subName: 'Stark Industries',
-                        tag5: 'Color',
-                        value5: 'Brown',
-                        match5: 1,
-                        match6: 1,
-                        match7: 1,
-                        match8: 1,
-                        tag6: 'Categoria',
-                        value6: '+1 precission',
-                        tag7: 'Tallos',
-                        value7: '1',
-                        tag8: null,
-                        value8: null,
-                        available: 185,
-                        calc_id: 6,
-                        counter: 10,
-                        minQuantity: 10,
-                        visible: null,
-                        price2: 100,
-                    },
-                ],
-            }).as('getItemGetSimilar');
-            cy.get('[data-cy="itemProposal"]').click();
-            cy.wait('@getItemGetSimilar');
-        });
-        describe('Replace item if', () => {
-            it.only('Quantity is less than available', () => {
-                cy.get(':nth-child(1) > .text-right  > .q-btn').click();
-            });
-        });
-    });
-});
diff --git a/test/cypress/integration/ticket/negative/TicketLackList.spec.js b/test/cypress/integration/ticket/negative/TicketLackList.spec.js
deleted file mode 100644
index 01ab4f621d0..00000000000
--- a/test/cypress/integration/ticket/negative/TicketLackList.spec.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/// <reference types="cypress" />
-describe('Ticket Lack list', () => {
-    beforeEach(() => {
-        cy.login('developer');
-        cy.intercept('GET', /Tickets\/itemLack\?.*$/, {
-            statusCode: 200,
-            body: [
-                {
-                    itemFk: 5,
-                    longName: 'Ranged weapon pistol 9mm',
-                    warehouseFk: 1,
-                    producer: null,
-                    size: 15,
-                    category: null,
-                    warehouse: 'Warehouse One',
-                    lack: -50,
-                    inkFk: 'SLV',
-                    timed: '2025-01-25T22:59:00.000Z',
-                    minTimed: '23:59',
-                    originFk: 'Holand',
-                },
-            ],
-        }).as('getLack');
-
-        cy.visit('/#/ticket/negative');
-    });
-
-    describe('Table actions', () => {
-        it('should display only one row in the lack list', () => {
-            cy.wait('@getLack', { timeout: 10000 });
-
-            cy.get('.q-virtual-scroll__content > :nth-child(1) > .sticky').click();
-            cy.location('href').should('contain', '#/ticket/negative/5');
-        });
-    });
-});
diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js
index 593021e6e1b..2984a4ee493 100644
--- a/test/cypress/integration/ticket/ticketList.spec.js
+++ b/test/cypress/integration/ticket/ticketList.spec.js
@@ -53,29 +53,4 @@ describe('TicketList', () => {
         cy.checkNotification('Data created');
         cy.url().should('match', /\/ticket\/\d+\/summary/);
     });
-
-    it('should show the corerct problems', () => {
-        cy.intercept('GET', '**/api/Tickets/filter*', (req) => {
-            req.headers['cache-control'] = 'no-cache';
-            req.headers['pragma'] = 'no-cache';
-            req.headers['expires'] = '0';
-
-            req.on('response', (res) => {
-                delete res.headers['if-none-match'];
-                delete res.headers['if-modified-since'];
-            });
-        }).as('ticket');
-
-        cy.get('[data-cy="Warehouse_select"]').type('Warehouse Five');
-        cy.get('.q-menu .q-item').contains('Warehouse Five').click();
-        cy.wait('@ticket').then((interception) => {
-            const data = interception.response.body[1];
-            expect(data.hasComponentLack).to.equal(1);
-            expect(data.isTooLittle).to.equal(1);
-            expect(data.hasItemShortage).to.equal(1);
-        });
-        cy.get('.icon-components').should('exist');
-        cy.get('.icon-unavailable').should('exist');
-        cy.get('.icon-isTooLittle').should('exist');
-    });
 });
diff --git a/test/cypress/integration/vnComponent/VnShortcut.spec.js b/test/cypress/integration/vnComponent/VnShortcut.spec.js
index e08c4463576..b49b4e964d5 100644
--- a/test/cypress/integration/vnComponent/VnShortcut.spec.js
+++ b/test/cypress/integration/vnComponent/VnShortcut.spec.js
@@ -28,17 +28,6 @@ describe('VnShortcuts', () => {
             });
 
             cy.url().should('include', module);
-            if (['monitor', 'claim'].includes(module)) {
-                return;
-            }
-            cy.waitForElement('.q-page').should('exist');
-            cy.dataCy('vnTableCreateBtn').should('exist');
-            cy.get('.q-page').trigger('keydown', {
-                ctrlKey: true,
-                altKey: true,
-                key: '+',
-            });
-            cy.get('#formModel').should('exist');
         });
     }
 });
diff --git a/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js b/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
index 2cd43984a5a..343c1c1271e 100644
--- a/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
+++ b/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
@@ -9,7 +9,7 @@ describe('WagonTypeCreate', () => {
     it('should create a new wagon type and then delete it', () => {
         cy.get('.q-page-sticky > div > .q-btn').click();
         cy.get('input').first().type('Example for testing');
-        cy.get('[data-cy="FormModelPopup_save"]').click();
+        cy.get('button[type="submit"]').click();
         cy.get('[title="Remove"] > .q-btn__content > .q-icon').first().click();
     });
 });
diff --git a/test/cypress/integration/zone/zoneBasicData.spec.js b/test/cypress/integration/zone/zoneBasicData.spec.js
index 70ded3f7969..95a075fb336 100644
--- a/test/cypress/integration/zone/zoneBasicData.spec.js
+++ b/test/cypress/integration/zone/zoneBasicData.spec.js
@@ -1,6 +1,5 @@
 describe('ZoneBasicData', () => {
     const priceBasicData = '[data-cy="Price_input"]';
-    const saveBtn = '.q-btn-group > .q-btn--standard';
 
     beforeEach(() => {
         cy.viewport(1280, 720);
@@ -9,27 +8,20 @@ describe('ZoneBasicData', () => {
     });
 
     it('should throw an error if the name is empty', () => {
-        cy.intercept('GET', /\/api\/Zones\/4./).as('zone');
-
-        cy.wait('@zone').then(() => {
-            cy.get('[data-cy="zone-basic-data-name"] input').type(
-                '{selectall}{backspace}',
-            );
-        });
-
-        cy.get(saveBtn).click();
+        cy.get('[data-cy="zone-basic-data-name"] input').type('{selectall}{backspace}');
+        cy.get('.q-btn-group > .q-btn--standard').click();
         cy.checkNotification("can't be blank");
     });
 
     it('should throw an error if the price is empty', () => {
         cy.get(priceBasicData).clear();
-        cy.get(saveBtn).click();
+        cy.get('.q-btn-group > .q-btn--standard').click();
         cy.checkNotification('cannot be blank');
     });
 
     it("should edit the basicData's zone", () => {
         cy.get('.q-card > :nth-child(1)').type(' modified');
-        cy.get(saveBtn).click();
+        cy.get('.q-btn-group > .q-btn--standard').click();
         cy.checkNotification('Data saved');
     });
 });
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index aa4a1219e8e..2c93fbf844b 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -87,55 +87,36 @@ Cypress.Commands.add('getValue', (selector) => {
 });
 
 // Fill Inputs
-Cypress.Commands.add('selectOption', (selector, option, timeout = 2500) => {
+Cypress.Commands.add('selectOption', (selector, option, timeout = 5000) => {
     cy.waitForElement(selector, timeout);
-
-    cy.get(selector, { timeout })
-        .should('exist')
-        .should('be.visible')
-        .click()
-        .then(($el) => {
-            cy.wrap($el.is('input') ? $el : $el.find('input'))
-                .invoke('attr', 'aria-controls')
-                .then((ariaControl) => selectItem(selector, option, ariaControl));
+    cy.get(selector).click();
+    cy.get(selector).invoke('data', 'url').as('dataUrl');
+    cy.get(selector)
+        .clear()
+        .type(option)
+        .then(() => {
+            cy.get('.q-menu', { timeout })
+                .should('be.visible') // Asegurarse de que el menú está visible
+                .and('exist') // Verificar que el menú existe
+                .then(() => {
+                    cy.get('@dataUrl').then((url) => {
+                        if (url) {
+                            // Esperar a que el menú no esté visible (desaparezca)
+                            cy.get('.q-menu').should('not.be.visible');
+                            // Ahora esperar a que el menú vuelva a aparecer
+                            cy.get('.q-menu').should('be.visible').and('exist');
+                        }
+                    });
+                });
         });
+
+    // Finalmente, seleccionar la opción deseada
+    cy.get('.q-menu:visible') // Asegurarse de que estamos dentro del menú visible
+        .find('.q-item') // Encontrar los elementos de las opciones
+        .contains(option) // Verificar que existe una opción que contenga el texto deseado
+        .click(); // Hacer clic en la opción
 });
 
-function selectItem(selector, option, ariaControl, hasWrite = true) {
-    if (!hasWrite) cy.wait(100);
-
-    getItems(ariaControl).then((items) => {
-        const matchingItem = items
-            .toArray()
-            .find((item) => item.innerText.includes(option));
-        if (matchingItem) return cy.wrap(matchingItem).click();
-
-        if (hasWrite) cy.get(selector).clear().type(option, { delay: 0 });
-        return selectItem(selector, option, ariaControl, false);
-    });
-}
-
-function getItems(ariaControl, startTime = Cypress._.now(), timeout = 2500) {
-    // Se intenta obtener la lista de opciones del desplegable de manera recursiva
-    return cy
-        .get('#' + ariaControl, { timeout })
-        .should('exist')
-        .find('.q-item')
-        .should('exist')
-        .then(($items) => {
-            if (!$items?.length || $items.first().text().trim() === '') {
-                if (Cypress._.now() - startTime > timeout) {
-                    throw new Error(
-                        `getItems: Tiempo de espera (${timeout}ms) excedido.`,
-                    );
-                }
-                return getItems(ariaControl, startTime, timeout);
-            }
-
-            return cy.wrap($items);
-        });
-}
-
 Cypress.Commands.add('countSelectOptions', (selector, option) => {
     cy.waitForElement(selector);
     cy.get(selector).click({ force: true });
diff --git a/test/cypress/support/waitUntil.js b/test/cypress/support/waitUntil.js
index 359f8643fd1..5fb47a2d82f 100644
--- a/test/cypress/support/waitUntil.js
+++ b/test/cypress/support/waitUntil.js
@@ -1,7 +1,7 @@
 const waitUntil = (subject, checkFunction, originalOptions = {}) => {
     if (!(checkFunction instanceof Function)) {
         throw new Error(
-            '`checkFunction` parameter should be a function. Found: ' + checkFunction,
+            '`checkFunction` parameter should be a function. Found: ' + checkFunction
         );
     }