diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86ffce3fd..8e1d4c433 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,141 @@
+# Version 24.36 - 2024-08-27
+
+### Added 🆕
+
+-   feat(FormModel): trim data by default by:alexm
+-   feat(orderBasicData): add notes by:alexm
+-   feat(orderList): correct create order by:alexm
+-   feat(orderList): use orderFilter and fixed this by:alexm
+-   feat: #7323 handle workerPhoto (origin/7323_workerPhoto, 7323_workerPhoto) by:Javier Segarra
+-   feat: add recover password and reset password by:alexm
+-   feat: refs #7346 add seriaType option by:jgallego
+-   feat: refs #7346 elimino === by:jgallego
+-   feat: refs #7346 formdata uses serialType by:jgallego
+-   feat: refs #7346 refactor by:jgallego
+-   feat: refs #7346 sonarLint warnings (origin/7346-invoiceOutMultilple, 7346-invoiceOutMultilple) by:jgallego
+-   feat: refs #7710 uses cloneAll by:jgallego
+-   fix: refs #7717 fix OrderList table filters' and summary table style by:Jon
+
+### Changed 📦
+
+-   feat: refs #7346 refactor by:jgallego
+-   perf: date fields (mindshore/feature/TicketFutureFilter, feature/TicketFutureFilter) by:Javier Segarra
+-   perf: refs #7717 right menu filter by:Jon
+-   perf: use ref at component start by:Javier Segarra
+-   refactor: refs #7717 delete useless function and import by:Jon
+-   refactor: refs #7717 deleted useless code by:Jon
+
+### Fixed 🛠️
+
+-   feat(orderList): use orderFilter and fixed this by:alexm
+-   fix(VnTable): orderBy v-model by:alexm
+-   fix(account_card): redirection by:carlossa
+-   fix(orderLines): reload when delete and redirect when confirm by:alexm
+-   fix: #6336 ClaimListStates by:Javier Segarra
+-   fix: account subsections cards by:carlossa
+-   fix: duplicate key by:Jon
+-   fix: order description to vnTable by:alexm
+-   fix: orderCatalogFilter order by:alexm
+-   fix: quasar build warnings (6336_claim_fix_states) by:Javier Segarra
+-   fix: refs #7717 fix OrderList table filters' and summary table style by:Jon
+-   fix: refs #7717 fix basic data form & minor errors by:Jon
+-   fix: refs #7717 fix catalog filter, searchbar redirect and search by:Jon
+-   fix: refs #7717 fix catalog searchbar and worker tests(refs #7323) by:Jon
+-   fix: refs #7717 fix order sections by:Jon
+-   fix: refs #7717 fix volume and lines redirect by:Jon
+-   fix: refs #7717 fixed searchbar filter with rightmenu filters' applied by:Jon
+-   fix: test by:alexm
+-   fix: ticketDescriptorMenu by:Javier Segarra
+-   refs #7355 account fixes by:carlossa
+
+# Version 24.34 - 2024-08-20
+
+### Added 🆕
+
+-   chore: #6900 order params by:jorgep
+-   chore: refs #6900 drop console log by:jorgep
+-   chore: refs #6900 drop vnCurrency by:jorgep
+-   chore: refs #6900 fix e2e tests by:jorgep
+-   chore: refs #6900 mv rectificative logic by:jorgep
+-   chore: refs #6900 responsive code by:jorgep
+-   chore: refs #7283 drop array types by:jorgep
+-   chore: refs #7283 drop import by:jorgep
+-   chore: refs #7283 fix e2e logout by:jorgep
+-   chore: refs #7283 update VnAvatar title handling by:jorgep
+-   chore: refs #7323 fix test by:jorgep
+-   chore: refs #7323 remove unused import by:jorgep
+-   chore: refs #7323drop commented code by:jorgep
+-   feat(VnCard): use props searchbar by:alexm
+-   feat(customer): improve basicData to balance by:alexm
+-   feat(customer_balance): refs #6943 add functionality from salix by:alexm
+-   feat(customer_balance): refs #6943 translations by:alexm
+-   feat: refs #6130 husky commitLint config by:pablone
+-   feat: refs #6130 husky hooks by:pablone
+-   feat: refs #6900 add InvoiceInSerial by:jorgep
+-   feat: refs #6900 add locale by:jorgep
+-   feat: refs #6900 use VnTable & sort filter fields by:jorgep
+-   feat: refs #7323 add flex-wrap by:jorgep
+-   feat: refs #7323 add my account" btn & fix models log selectable by:jorgep
+-   feat: refs #7323 improve test by:jorgep
+
+### Changed 📦
+
+-   refactor(customer_log: use VnLog by:alexm
+-   refactor(customer_recovery): to vnTable by:alexm
+-   refactor(customer_webAccess): FormModel by:alexm
+-   refactor: refs #7283 update avatar size and color by:jorgep
+
+### Fixed 🛠️
+
+-   chore: refs #6900 fix e2e tests by:jorgep
+-   chore: refs #7283 fix e2e logout by:jorgep
+-   chore: refs #7323 fix test by:jorgep
+-   feat: refs #7323 add my account" btn & fix models log selectable by:jorgep
+-   fix #7355 fix acls list by:carlossa
+-   fix(VnFilterPanel): emit userParams better by:alexm
+-   fix(claim_summary): url links (HEAD -> 7864_testToMaster_2434, origin/test, origin/7864_testToMaster_2434, test) by:alexm
+-   fix(customer_sms: fix reload by:alexm
+-   fix(twoFactor): unify code login and twoFactor by:alexm
+-   fix: VnCard VnSearchbar props by:alexm
+-   fix: accountMailAlias by:alexm
+-   fix: refs #6130 add commit lint modules by:pablone
+-   fix: refs #6130 pnpm-lock.yml by:pablone
+-   fix: refs #6900 improve loading by:jorgep
+-   fix: refs #6900 improve logic (origin/6900-addSerial) by:jorgep
+-   fix: refs #6900 improve logic by:jorgep
+-   fix: refs #6900 rectificative btn reactivity by:jorgep
+-   fix: refs #6900 use type number by:jorgep
+-   fix: refs #6900 vat & dueday by:jorgep
+-   fix: refs #6900 vat, dueday & intrastat by:jorgep
+-   fix: refs #6989 show entity name & default time from config table by:jorgep
+-   fix: refs #7283 basicData locale by:jorgep
+-   fix: refs #7283 itemLastEntries filter by:jorgep
+-   fix: refs #7283 itemTags & VnImg by:jorgep
+-   fix: refs #7283 locale by:jorgep
+-   fix: refs #7283 min-width vnImg by:jorgep
+-   fix: refs #7283 use vnAvatar & add optional zoom by:jorgep
+-   fix: refs #7283 userPanel pic by:jorgep
+-   fix: refs #7323 add department popup by:jorgep
+-   fix: refs #7323 add locale by:jorgep
+-   fix: refs #7323 css righ menu by:jorgep
+-   fix: refs #7323 data-key & add select by:jorgep
+-   fix: refs #7323 load all opts by:jorgep
+-   fix: refs #7323 righ menu bug by:jorgep
+-   fix: refs #7323 use global locale by:jorgep
+-   fix: refs #7323 use workerFilter (origin/7323-warmfix-fixErrors) by:jorgep
+-   fix: refs #7323 vnsubtoolbar css by:jorgep
+-   fix: refs #7323 wrong css by:jorgep
+-   refs #7355 fix Rol, alias by:carlossa
+-   refs #7355 fix accountAlias by:carlossa
+-   refs #7355 fix alias summary by:carlossa
+-   refs #7355 fix conflicts by:carlossa
+-   refs #7355 fix create Rol by:carlossa
+-   refs #7355 fix list by:carlossa
+-   refs #7355 fix lists redirects summary by:carlossa
+-   refs #7355 fix roles by:carlossa
+-   refs #7355 fix search exprBuilder by:carlossa
+-   refs #7355 fix vnTable by:carlossa
+
 # Version 24.32 - 2024-08-06
 
 ### Added 🆕
diff --git a/package.json b/package.json
index 72bada823..eaffd8d85 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "salix-front",
-    "version": "24.34.0",
+    "version": "24.40.0",
     "description": "Salix frontend",
     "productName": "Salix",
     "author": "Verdnatura",
@@ -62,4 +62,4 @@
         "vite": "^5.1.4",
         "vitest": "^0.31.1"
     }
-}
+}
\ No newline at end of file
diff --git a/src/boot/keyShortcut.js b/src/boot/keyShortcut.js
new file mode 100644
index 000000000..5afb5b74a
--- /dev/null
+++ b/src/boot/keyShortcut.js
@@ -0,0 +1,34 @@
+export default {
+    mounted: function (el, binding) {
+        const shortcut = binding.value ?? '+';
+
+        const { key, ctrl, alt, callback } =
+            typeof shortcut === 'string'
+                ? {
+                      key: shortcut,
+                      ctrl: true,
+                      alt: true,
+                      callback: () =>
+                          document
+                              .querySelector(`button[shortcut="${shortcut}"]`)
+                              ?.click(),
+                  }
+                : binding.value;
+
+        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: function (el) {
+        if (el._handleKeydown) {
+            window.removeEventListener('keydown', el._handleKeydown);
+        }
+    },
+};
diff --git a/src/boot/mainShortcutMixin.js b/src/boot/mainShortcutMixin.js
new file mode 100644
index 000000000..8e5f147db
--- /dev/null
+++ b/src/boot/mainShortcutMixin.js
@@ -0,0 +1,38 @@
+import routes from 'src/router/modules';
+import { useRouter } from 'vue-router';
+
+let isNotified = false;
+
+export default {
+    created: function () {
+        const router = useRouter();
+        const keyBindingMap = routes
+            .filter((route) => route.meta.keyBinding)
+            .reduce((map, route) => {
+                map['Key' + route.meta.keyBinding.toUpperCase()] = route.path;
+                return map;
+            }, {});
+
+        const handleKeyDown = (event) => {
+            const { ctrlKey, altKey, code } = event;
+
+            if (ctrlKey && altKey && keyBindingMap[code] && !isNotified) {
+                event.preventDefault();
+                router.push(keyBindingMap[code]);
+                isNotified = true;
+            }
+        };
+
+        const handleKeyUp = (event) => {
+            const { ctrlKey, altKey } = event;
+
+            // Resetea la bandera cuando se sueltan las teclas ctrl o alt
+            if (!ctrlKey || !altKey) {
+                isNotified = false;
+            }
+        };
+
+        window.addEventListener('keydown', handleKeyDown);
+        window.addEventListener('keyup', handleKeyUp);
+    },
+};
diff --git a/src/boot/quasar.js b/src/boot/quasar.js
index a8d9b7ad9..e2035c880 100644
--- a/src/boot/quasar.js
+++ b/src/boot/quasar.js
@@ -1,6 +1,10 @@
 import { boot } from 'quasar/wrappers';
 import qFormMixin from './qformMixin';
+import mainShortcutMixin from './mainShortcutMixin';
+import keyShortcut from './keyShortcut';
 
 export default boot(({ app }) => {
     app.mixin(qFormMixin);
+    app.mixin(mainShortcutMixin);
+    app.directive('shortcut', keyShortcut);
 });
diff --git a/src/components/CreateBankEntityForm.vue b/src/components/CreateBankEntityForm.vue
index c46ac7752..1117225c7 100644
--- a/src/components/CreateBankEntityForm.vue
+++ b/src/components/CreateBankEntityForm.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { reactive, ref, onMounted, nextTick } from 'vue';
+import { reactive, ref, onMounted, nextTick, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import VnInput from 'src/components/common/VnInput.vue';
 
@@ -7,16 +7,21 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import FetchData from 'components/FetchData.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import FormModelPopup from './FormModelPopup.vue';
+import { useState } from 'src/composables/useState';
 
 defineProps({ showEntityField: { type: Boolean, default: true } });
 
 const emit = defineEmits(['onDataSaved']);
 const { t } = useI18n();
 const bicInputRef = ref(null);
+const state = useState();
+
+const customer = computed(() => state.get('customer'));
+
 const bankEntityFormData = reactive({
     name: null,
     bic: null,
-    countryFk: null,
+    countryFk: customer.value.countryFk,
     id: null,
 });
 
diff --git a/src/components/CreateNewExpenseForm.vue b/src/components/CreateNewExpenseForm.vue
new file mode 100644
index 000000000..7088cec03
--- /dev/null
+++ b/src/components/CreateNewExpenseForm.vue
@@ -0,0 +1,50 @@
+<script setup>
+import { useI18n } from 'vue-i18n';
+import VnRow from 'components/ui/VnRow.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import FormModelPopup from './FormModelPopup.vue';
+
+const emit = defineEmits(['onDataSaved']);
+const { t } = useI18n();
+</script>
+<template>
+    <FormModelPopup
+        url-create="Expenses"
+        model="Expense"
+        :title="t('New expense')"
+        :form-initial-data="{ id: null, isWithheld: false, name: null }"
+        @on-data-saved="emit('onDataSaved', $event)"
+    >
+        <template #form-inputs="{ data, validate }">
+            <VnRow>
+                <VnInput
+                    :label="`${t('globals.code')}`"
+                    v-model="data.id"
+                    :required="true"
+                    :rules="validate('expense.code')"
+                />
+                <QCheckbox
+                    dense
+                    size="sm"
+                    :label="`${t('It\'s a withholding')}`"
+                    v-model="data.isWithheld"
+                    :rules="validate('expense.isWithheld')"
+                />
+            </VnRow>
+            <VnRow>
+                <VnInput
+                    :label="`${t('globals.description')}`"
+                    v-model="data.name"
+                    :required="true"
+                    :rules="validate('expense.description')"
+                />
+            </VnRow>
+        </template>
+    </FormModelPopup>
+</template>
+
+<i18n>
+es:
+    New expense: Nuevo gasto
+    It's a withholding: Es una retención
+</i18n>
diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue
index a426ac2b4..4c44d29e2 100644
--- a/src/components/CreateNewPostcodeForm.vue
+++ b/src/components/CreateNewPostcodeForm.vue
@@ -105,7 +105,7 @@ async function setProvince(id, data) {
                     option-label="name"
                     option-value="id"
                     :rules="validate('postcode.city')"
-                    :roles-allowed-to-create="['deliveryAssistant']"
+                    :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
                     :emit-value="false"
                     clearable
                 >
diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index 33c831e3f..0386e037b 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -189,11 +189,11 @@ async function saveChanges(data) {
     });
 }
 
-async function insert() {
+async function insert(pushData = $props.dataRequired) {
     const $index = formData.value.length
         ? formData.value[formData.value.length - 1].$index + 1
         : 0;
-    formData.value.push(Object.assign({ $index }, $props.dataRequired));
+    formData.value.push(Object.assign({ $index }, pushData));
     hasChanges.value = true;
 }
 
diff --git a/src/components/FetchData.vue b/src/components/FetchData.vue
index 2a0864d3e..3038aa88e 100644
--- a/src/components/FetchData.vue
+++ b/src/components/FetchData.vue
@@ -44,7 +44,7 @@ onMounted(async () => {
 
 async function fetch(fetchFilter = {}) {
     try {
-        const filter = Object.assign(fetchFilter, $props.filter); // eslint-disable-line vue/no-dupe-keys
+        const filter = { ...fetchFilter, ...$props.filter }; // eslint-disable-line vue/no-dupe-keys
         if ($props.where && !fetchFilter.where) filter.where = $props.where;
         if ($props.sortBy) filter.order = $props.sortBy;
         if ($props.limit) filter.limit = $props.limit;
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index a0f6bf479..05f947cf3 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -22,7 +22,7 @@ const { t } = useI18n();
 const { validate } = useValidator();
 const { notify } = useNotify();
 const route = useRoute();
-
+const myForm = ref(null);
 const $props = defineProps({
     url: {
         type: String,
@@ -87,6 +87,10 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
+    defaultTrim: {
+        type: Boolean,
+        default: true,
+    },
 });
 const emit = defineEmits(['onFetch', 'onDataSaved']);
 const modelValue = computed(
@@ -105,11 +109,14 @@ const defaultButtons = computed(() => ({
         color: 'primary',
         icon: 'save',
         label: 'globals.save',
+        click: () => myForm.value.submit(),
+        type: 'submit',
     },
     reset: {
         color: 'primary',
         icon: 'restart_alt',
         label: 'globals.reset',
+        click: () => reset(),
     },
     ...$props.defaultButtons,
 }));
@@ -195,6 +202,7 @@ async function save() {
 
     isLoading.value = true;
     try {
+        formData.value = trimData(formData.value);
         const body = $props.mapper ? $props.mapper(formData.value) : formData.value;
         const method = $props.urlCreate ? 'post' : 'patch';
         const url =
@@ -253,6 +261,14 @@ function updateAndEmit(evt, val, res) {
     emit(evt, state.get(modelValue), res);
 }
 
+function trimData(data) {
+    if (!$props.defaultTrim) return data;
+    for (const key in data) {
+        if (typeof data[key] == 'string') data[key] = data[key].trim();
+    }
+    return data;
+}
+
 defineExpose({
     save,
     isLoading,
@@ -263,7 +279,14 @@ defineExpose({
 </script>
 <template>
     <div class="column items-center full-width">
-        <QForm @submit="save" @reset="reset" class="q-pa-md" id="formModel">
+        <QForm
+            ref="myForm"
+            v-if="formData"
+            @submit="save"
+            @reset="reset"
+            class="q-pa-md"
+            id="formModel"
+        >
             <QCard>
                 <slot
                     v-if="formData"
@@ -291,7 +314,7 @@ defineExpose({
                 :color="defaultButtons.reset.color"
                 :icon="defaultButtons.reset.icon"
                 flat
-                @click="reset"
+                @click="defaultButtons.reset.click"
                 :disable="!hasChanges"
                 :title="t(defaultButtons.reset.label)"
             />
@@ -331,7 +354,7 @@ defineExpose({
                 :label="tMobile('globals.save')"
                 color="primary"
                 icon="save"
-                @click="save"
+                @click="defaultButtons.save.click"
                 :disable="!hasChanges"
                 :title="t(defaultButtons.save.label)"
             />
diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue
index 743c2c9d1..8449f9354 100644
--- a/src/components/ItemsFilterPanel.vue
+++ b/src/components/ItemsFilterPanel.vue
@@ -159,8 +159,8 @@ const removeTag = (index, params, search) => {
     />
     <VnFilterPanel
         :data-key="props.dataKey"
-        :expr-builder="exprBuilder"
-        :custom-tags="customTags"
+        :expr-builder="props.exprBuilder"
+        :custom-tags="props.customTags"
     >
         <template #tags="{ tag, formatFn }">
             <strong v-if="tag.label === 'categoryFk'">
diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue
index 213c08d7e..03fe11a85 100644
--- a/src/components/LeftMenu.vue
+++ b/src/components/LeftMenu.vue
@@ -1,6 +1,6 @@
 <script setup>
 import axios from 'axios';
-import { onMounted, ref, reactive } from 'vue';
+import { onMounted, watch, ref, reactive } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { QSeparator, useQuasar } from 'quasar';
 import { useRoute } from 'vue-router';
@@ -29,6 +29,15 @@ onMounted(async () => {
     getRoutes();
 });
 
+watch(
+    () => route.matched,
+    () => {
+        items.value = [];
+        getRoutes();
+    },
+    { deep: true }
+);
+
 function findMatches(search, item) {
     const matches = [];
     function findRoute(search, item) {
diff --git a/src/components/LeftMenuItem.vue b/src/components/LeftMenuItem.vue
index f3f2315a3..ab74c1de5 100644
--- a/src/components/LeftMenuItem.vue
+++ b/src/components/LeftMenuItem.vue
@@ -33,7 +33,12 @@ const itemComputed = computed(() => {
         <QItemSection avatar v-if="!itemComputed.icon">
             <QIcon name="disabled_by_default" />
         </QItemSection>
-        <QItemSection>{{ t(itemComputed.title) }}</QItemSection>
+        <QItemSection>
+            {{ t(itemComputed.title) }}
+            <QTooltip v-if="item.keyBinding">
+                {{ 'Ctrl + Alt + ' + item?.keyBinding?.toUpperCase() }}
+            </QTooltip>
+        </QItemSection>
         <QItemSection side>
             <slot name="side" :item="itemComputed" />
         </QItemSection>
diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue
index e80a293c6..00faaebc2 100644
--- a/src/components/NavBar.vue
+++ b/src/components/NavBar.vue
@@ -24,7 +24,13 @@ const pinnedModulesRef = ref();
 <template>
     <QHeader color="white" elevated>
         <QToolbar class="q-py-sm q-px-md">
-            <QBtn @click="stateStore.toggleLeftDrawer()" icon="menu" round dense flat>
+            <QBtn
+                @click="stateStore.toggleLeftDrawer()"
+                icon="dock_to_right"
+                round
+                dense
+                flat
+            >
                 <QTooltip bottom anchor="bottom right">
                     {{ t('globals.collapseMenu') }}
                 </QTooltip>
diff --git a/src/components/RefundInvoiceForm.vue b/src/components/RefundInvoiceForm.vue
new file mode 100644
index 000000000..c21c892dd
--- /dev/null
+++ b/src/components/RefundInvoiceForm.vue
@@ -0,0 +1,174 @@
+<script setup>
+import { ref, reactive } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useRouter } from 'vue-router';
+import { useDialogPluginComponent } from 'quasar';
+import VnRow from 'components/ui/VnRow.vue';
+import FetchData from 'components/FetchData.vue';
+import VnSelect from 'components/common/VnSelect.vue';
+import FormPopup from './FormPopup.vue';
+import axios from 'axios';
+import useNotify from 'src/composables/useNotify.js';
+
+const $props = defineProps({
+    invoiceOutData: {
+        type: Object,
+        default: () => {},
+    },
+});
+
+const { dialogRef } = useDialogPluginComponent();
+const { t } = useI18n();
+const router = useRouter();
+const { notify } = useNotify();
+
+const rectificativeTypeOptions = ref([]);
+const siiTypeInvoiceOutsOptions = ref([]);
+const inheritWarehouse = ref(true);
+const invoiceParams = reactive({
+    id: $props.invoiceOutData?.id,
+});
+const invoiceCorrectionTypesOptions = ref([]);
+
+const refund = async () => {
+    const params = {
+        id: invoiceParams.id,
+        withWarehouse: invoiceParams.inheritWarehouse,
+        cplusRectificationTypeFk: invoiceParams.cplusRectificationTypeFk,
+        siiTypeInvoiceOutFk: invoiceParams.siiTypeInvoiceOutFk,
+        invoiceCorrectionTypeFk: invoiceParams.invoiceCorrectionTypeFk,
+    };
+
+    try {
+        const { data } = await axios.post('InvoiceOuts/refundAndInvoice', params);
+        notify(t('Refunded invoice'), 'positive');
+        const [id] = data?.refundId || [];
+        if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
+    } catch (err) {
+        console.error('Error refunding invoice', err);
+    }
+};
+</script>
+
+<template>
+    <FetchData
+        url="CplusRectificationTypes"
+        :filter="{ order: 'description' }"
+        @on-fetch="
+            (data) => (
+                (rectificativeTypeOptions = data),
+                (invoiceParams.cplusRectificationTypeFk = data.filter(
+                    (type) => type.description == 'I – Por diferencias'
+                )[0].id)
+            )
+        "
+        auto-load
+    />
+    <FetchData
+        url="SiiTypeInvoiceOuts"
+        :filter="{ where: { code: { like: 'R%' } } }"
+        @on-fetch="
+            (data) => (
+                (siiTypeInvoiceOutsOptions = data),
+                (invoiceParams.siiTypeInvoiceOutFk = data.filter(
+                    (type) => type.code == 'R4'
+                )[0].id)
+            )
+        "
+        auto-load
+    />
+    <FetchData
+        url="InvoiceCorrectionTypes"
+        @on-fetch="(data) => (invoiceCorrectionTypesOptions = data)"
+        auto-load
+    />
+
+    <QDialog ref="dialogRef">
+        <FormPopup
+            @on-submit="refund()"
+            :custom-submit-button-label="t('Accept')"
+            :default-cancel-button="false"
+        >
+            <template #form-inputs>
+                <VnRow>
+                    <VnSelect
+                        :label="t('Rectificative type')"
+                        :options="rectificativeTypeOptions"
+                        hide-selected
+                        option-label="description"
+                        option-value="id"
+                        v-model="invoiceParams.cplusRectificationTypeFk"
+                        :required="true"
+                    />
+                </VnRow>
+                <VnRow>
+                    <VnSelect
+                        :label="t('Class')"
+                        :options="siiTypeInvoiceOutsOptions"
+                        hide-selected
+                        option-label="description"
+                        option-value="id"
+                        v-model="invoiceParams.siiTypeInvoiceOutFk"
+                        :required="true"
+                    >
+                        <template #option="scope">
+                            <QItem v-bind="scope.itemProps">
+                                <QItemSection>
+                                    <QItemLabel>
+                                        {{ scope.opt?.code }} -
+                                        {{ scope.opt?.description }}
+                                    </QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
+                </VnRow>
+
+                <VnRow>
+                    <VnSelect
+                        :label="t('Type')"
+                        :options="invoiceCorrectionTypesOptions"
+                        hide-selected
+                        option-label="description"
+                        option-value="id"
+                        v-model="invoiceParams.invoiceCorrectionTypeFk"
+                        :required="true"
+                    /> </VnRow
+                ><VnRow>
+                    <div>
+                        <QCheckbox
+                            :label="t('Inherit warehouse')"
+                            v-model="inheritWarehouse"
+                        />
+                        <QIcon name="info" class="cursor-info q-ml-sm" size="sm">
+                            <QTooltip>{{ t('Inherit warehouse tooltip') }}</QTooltip>
+                        </QIcon>
+                    </div>
+                </VnRow>
+            </template>
+        </FormPopup>
+    </QDialog>
+</template>
+
+<i18n>
+en:
+    Refund invoice: Refund invoice
+    Rectificative type: Rectificative type
+    Class: Class
+    Type: Type
+    Refunded invoice: Refunded invoice
+    Inherit warehouse: Inherit the warehouse
+    Inherit warehouse tooltip: Select this option to inherit the warehouse when refunding the invoice
+    Accept: Accept
+    Error refunding invoice: Error refunding invoice
+es:
+    Refund invoice: Abonar factura
+    Rectificative type: Tipo rectificativa
+    Class: Clase
+    Type: Tipo
+    Refunded invoice: Factura abonada
+    Inherit warehouse: Heredar el almacén
+    Inherit warehouse tooltip: Seleccione esta opción para heredar el almacén al abonar la factura.
+    Accept: Aceptar
+    Error refunding invoice: Error abonando factura
+</i18n>
diff --git a/src/components/TransferInvoiceForm.vue b/src/components/TransferInvoiceForm.vue
index 17c11d87e..f7050cdba 100644
--- a/src/components/TransferInvoiceForm.vue
+++ b/src/components/TransferInvoiceForm.vue
@@ -2,13 +2,12 @@
 import { ref, reactive } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
-import { useQuasar } from 'quasar';
+import { useQuasar, useDialogPluginComponent } from 'quasar';
 import VnConfirm from 'components/ui/VnConfirm.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import FetchData from 'components/FetchData.vue';
 import VnSelect from 'components/common/VnSelect.vue';
 import FormPopup from './FormPopup.vue';
-import { useDialogPluginComponent } from 'quasar';
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
 
@@ -18,19 +17,19 @@ const $props = defineProps({
         default: () => {},
     },
 });
+
 const { dialogRef } = useDialogPluginComponent();
 const quasar = useQuasar();
 const { t } = useI18n();
 const router = useRouter();
 const { notify } = useNotify();
-const checked = ref(true);
-const transferInvoiceParams = reactive({
-    id: $props.invoiceOutData?.id,
-    refFk: $props.invoiceOutData?.ref,
-});
 
 const rectificativeTypeOptions = ref([]);
 const siiTypeInvoiceOutsOptions = ref([]);
+const checked = ref(true);
+const transferInvoiceParams = reactive({
+    id: $props.invoiceOutData?.id,
+});
 const invoiceCorrectionTypesOptions = ref([]);
 
 const selectedClient = (client) => {
@@ -44,10 +43,9 @@ const makeInvoice = async () => {
     const params = {
         id: transferInvoiceParams.id,
         cplusRectificationTypeFk: transferInvoiceParams.cplusRectificationTypeFk,
+        siiTypeInvoiceOutFk: transferInvoiceParams.siiTypeInvoiceOutFk,
         invoiceCorrectionTypeFk: transferInvoiceParams.invoiceCorrectionTypeFk,
         newClientFk: transferInvoiceParams.newClientFk,
-        refFk: transferInvoiceParams.refFk,
-        siiTypeInvoiceOutFk: transferInvoiceParams.siiTypeInvoiceOutFk,
         makeInvoice: checked.value,
     };
 
@@ -74,7 +72,7 @@ const makeInvoice = async () => {
             }
         }
 
-        const { data } = await axios.post('InvoiceOuts/transferInvoice', params);
+        const { data } = await axios.post('InvoiceOuts/transfer', params);
         notify(t('Transferred invoice'), 'positive');
         const id = data?.[0];
         if (id) router.push({ name: 'InvoiceOutSummary', params: { id } });
diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue
index 2f191691a..98334460a 100644
--- a/src/components/UserPanel.vue
+++ b/src/components/UserPanel.vue
@@ -164,7 +164,7 @@ const isEmployee = computed(() => useRole().isEmployee());
                     class="q-mt-sm q-px-md"
                     :to="`/worker/${user.id}`"
                     color="primary"
-                    :label="t('My account')"
+                    :label="t('globals.myAccount')"
                     dense
                 />
                 <div class="text-subtitle1 q-mt-md">
@@ -270,7 +270,3 @@ const isEmployee = computed(() => useRole().isEmployee());
     }
 }
 </style>
-<i18n>
-es:
-    My account: Mi cuenta
-</i18n>
diff --git a/src/components/VnSelectProvince.vue b/src/components/VnSelectProvince.vue
index ea10ace19..2f08db611 100644
--- a/src/components/VnSelectProvince.vue
+++ b/src/components/VnSelectProvince.vue
@@ -38,7 +38,7 @@ async function onProvinceCreated(_, data) {
         hide-selected
         v-model="provinceFk"
         :rules="validate && validate('postcode.provinceFk')"
-        :roles-allowed-to-create="['deliveryAssistant']"
+        :acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
     >
         <template #option="{ itemProps, opt }">
             <QItem v-bind="itemProps">
diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue
index c6d4d8ef2..fd3c29fa3 100644
--- a/src/components/VnTable/VnFilter.vue
+++ b/src/components/VnTable/VnFilter.vue
@@ -34,7 +34,7 @@ const model = defineModel(undefined, { required: true });
 const arrayData = useArrayData($props.dataKey, { searchUrl: $props.searchUrl });
 const columnFilter = computed(() => $props.column?.columnFilter);
 
-const updateEvent = { 'update:modelValue': addFilter, remove: () => addFilter(null) };
+const updateEvent = { 'update:modelValue': addFilter };
 const enterEvent = {
     'keyup.enter': () => addFilter(model.value),
     remove: () => addFilter(null),
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index d6b35d4da..d6008de0b 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -49,6 +49,10 @@ const $props = defineProps({
         type: Object,
         default: null,
     },
+    createAsDialog: {
+        type: Boolean,
+        default: true,
+    },
     cardClass: {
         type: String,
         default: 'flex-one',
@@ -65,9 +69,13 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
+    disableInfiniteScroll: {
+        type: Boolean,
+        default: false,
+    },
     hasSubToolbar: {
         type: Boolean,
-        default: true,
+        default: null,
     },
     disableOption: {
         type: Object,
@@ -85,6 +93,10 @@ const $props = defineProps({
         type: Object,
         default: () => ({}),
     },
+    crudModel: {
+        type: Object,
+        default: () => ({}),
+    },
     tableHeight: {
         type: String,
         default: '90vh',
@@ -107,7 +119,7 @@ const orders = ref(parseOrder(routeQuery.filter?.order));
 const CrudModelRef = ref({});
 const showForm = ref(false);
 const splittedColumns = ref({ columns: [] });
-const columnsVisibilitySkiped = ref();
+const columnsVisibilitySkipped = ref();
 const createForm = ref();
 
 const tableModes = [
@@ -135,7 +147,7 @@ onMounted(() => {
             ? CARD_MODE
             : $props.defaultMode;
     stateStore.rightDrawer = true;
-    columnsVisibilitySkiped.value = [
+    columnsVisibilitySkipped.value = [
         ...splittedColumns.value.columns
             .filter((c) => c.visible == false)
             .map((c) => c.name),
@@ -178,10 +190,20 @@ function setUserParams(watchedParams, watchedOrder) {
     watchedParams = { ...watchedParams, ...where };
     delete watchedParams.filter;
     delete params.value?.filter;
-    params.value = { ...params.value, ...watchedParams };
+    params.value = { ...params.value, ...sanitizer(watchedParams) };
     orders.value = parseOrder(order);
 }
 
+function sanitizer(params) {
+    for (const [key, value] of Object.entries(params)) {
+        if (typeof value == 'object') {
+            const param = Object.values(value)[0];
+            if (typeof param == 'string') params[key] = param.replaceAll('%', '');
+        }
+    }
+    return params;
+}
+
 function splitColumns(columns) {
     splittedColumns.value = {
         columns: [],
@@ -274,10 +296,17 @@ function parseOrder(urlOrders) {
 
 const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
 defineExpose({
+    create: createForm,
     reload,
     redirect: redirectFn,
     selected,
+    CrudModelRef,
 });
+
+function handleOnDataSaved(_) {
+    if (_.onDataSaved) _.onDataSaved(this);
+    else $props.create.onDataSaved(_);
+}
 </script>
 <template>
     <QDrawer
@@ -315,7 +344,7 @@ defineExpose({
                                 col?.columnFilter !== false &&
                                 col?.name !== 'tableActions'
                             "
-                            v-model="orders[col.name]"
+                            v-model="orders[col.orderBy ?? col.name]"
                             :name="col.orderBy ?? col.name"
                             :data-key="$attrs['data-key']"
                             :search-url="searchUrl"
@@ -332,300 +361,293 @@ defineExpose({
         </QScrollArea>
     </QDrawer>
     <!-- class in div to fix warn-->
-    <div class="q-px-md">
-        <CrudModel
-            v-bind="$attrs"
-            :limit="20"
-            ref="CrudModelRef"
-            @on-fetch="(...args) => emit('onFetch', ...args)"
-            :search-url="searchUrl"
-            :disable-infinite-scroll="isTableMode"
-            @save-changes="reload"
-            :has-sub-toolbar="$attrs['hasSubToolbar'] ?? isEditable"
-            :auto-load="hasParams || $attrs['auto-load']"
-        >
-            <template
-                v-for="(_, slotName) in $slots"
-                #[slotName]="slotData"
-                :key="slotName"
+    <CrudModel
+        v-bind="$attrs"
+        :class="$attrs['class'] ?? 'q-px-md'"
+        :limit="$attrs['limit'] ?? 20"
+        ref="CrudModelRef"
+        @on-fetch="(...args) => emit('onFetch', ...args)"
+        :search-url="searchUrl"
+        :disable-infinite-scroll="
+            $attrs['disableInfiniteScroll'] ? isTableMode : !disableInfiniteScroll
+        "
+        @save-changes="reload"
+        :has-sub-toolbar="$props.hasSubToolbar ?? isEditable"
+        :auto-load="hasParams || $attrs['auto-load']"
+    >
+        <template v-for="(_, slotName) in $slots" #[slotName]="slotData" :key="slotName">
+            <slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
+        </template>
+        <template #body="{ rows }">
+            <QTable
+                v-bind="table"
+                class="vnTable"
+                :columns="splittedColumns.columns"
+                :rows="rows"
+                v-model:selected="selected"
+                :grid="!isTableMode"
+                table-header-class="bg-header"
+                card-container-class="grid-three"
+                flat
+                :style="isTableMode && `max-height: ${tableHeight}`"
+                virtual-scroll
+                @virtual-scroll="
+                    (event) =>
+                        event.index > rows.length - 2 &&
+                        ($props.crudModel?.paginate ?? true) &&
+                        CrudModelRef.vnPaginateRef.paginate()
+                "
+                @row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
+                @update:selected="emit('update:selected', $event)"
             >
-                <slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
-            </template>
-            <template #body="{ rows }">
-                <QTable
-                    v-bind="table"
-                    class="vnTable"
-                    :columns="splittedColumns.columns"
-                    :rows="rows"
-                    v-model:selected="selected"
-                    :grid="!isTableMode"
-                    table-header-class="bg-header"
-                    card-container-class="grid-three"
-                    flat
-                    :style="isTableMode && `max-height: ${tableHeight}`"
-                    virtual-scroll
-                    @virtual-scroll="
-                        (event) =>
-                            event.index > rows.length - 2 &&
-                            CrudModelRef.vnPaginateRef.paginate()
-                    "
-                    @row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
-                    @update:selected="emit('update:selected', $event)"
-                >
-                    <template #top-left v-if="!$props.withoutHeader">
-                        <slot name="top-left"></slot>
-                    </template>
-                    <template #top-right v-if="!$props.withoutHeader">
-                        <VnVisibleColumn
-                            v-if="isTableMode"
-                            v-model="splittedColumns.columns"
-                            :table-code="tableCode ?? route.name"
-                            :skip="columnsVisibilitySkiped"
-                        />
-                        <QBtnToggle
-                            v-model="mode"
-                            toggle-color="primary"
-                            class="bg-vn-section-color"
-                            dense
-                            :options="tableModes"
-                        />
-                        <QBtn
-                            v-if="$props.rightSearch"
-                            icon="filter_alt"
-                            class="bg-vn-section-color q-ml-md"
-                            dense
-                            @click="stateStore.toggleRightDrawer()"
-                        />
-                    </template>
-                    <template #header-cell="{ col }">
-                        <QTh v-if="col.visible ?? true">
-                            <div
-                                class="column self-start q-ml-xs ellipsis"
-                                :class="`text-${col?.align ?? 'left'}`"
-                                :style="$props.columnSearch ? 'height: 75px' : ''"
-                            >
-                                <div
-                                    class="row items-center no-wrap"
-                                    style="height: 30px"
-                                >
-                                    <VnTableOrder
-                                        v-model="orders[col.name]"
-                                        :name="col.orderBy ?? col.name"
-                                        :label="col?.label"
-                                        :data-key="$attrs['data-key']"
-                                        :search-url="searchUrl"
-                                    />
-                                </div>
-                                <VnTableFilter
-                                    v-if="$props.columnSearch"
-                                    :column="col"
-                                    :show-title="true"
+                <template #top-left v-if="!$props.withoutHeader">
+                    <slot name="top-left"></slot>
+                </template>
+                <template #top-right v-if="!$props.withoutHeader">
+                    <VnVisibleColumn
+                        v-if="isTableMode"
+                        v-model="splittedColumns.columns"
+                        :table-code="tableCode ?? route.name"
+                        :skip="columnsVisibilitySkipped"
+                    />
+                    <QBtnToggle
+                        v-model="mode"
+                        toggle-color="primary"
+                        class="bg-vn-section-color"
+                        dense
+                        :options="tableModes.filter((mode) => !mode.disable)"
+                    />
+                    <QBtn
+                        v-if="$props.rightSearch"
+                        icon="filter_alt"
+                        class="bg-vn-section-color q-ml-md"
+                        dense
+                        @click="stateStore.toggleRightDrawer()"
+                    />
+                </template>
+                <template #header-cell="{ col }">
+                    <QTh v-if="col.visible ?? true">
+                        <div
+                            class="column self-start q-ml-xs ellipsis"
+                            :class="`text-${col?.align ?? 'left'}`"
+                            :style="$props.columnSearch ? 'height: 75px' : ''"
+                        >
+                            <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?.label"
                                     :data-key="$attrs['data-key']"
-                                    v-model="params[columnName(col)]"
                                     :search-url="searchUrl"
-                                    class="full-width"
                                 />
                             </div>
-                        </QTh>
-                    </template>
-                    <template #header-cell-tableActions>
-                        <QTh auto-width class="sticky" />
-                    </template>
-                    <template #body-cell-tableStatus="{ col, row }">
-                        <QTd auto-width :class="getColAlign(col)">
-                            <VnTableChip
-                                :columns="splittedColumns.columnChips"
+                            <VnTableFilter
+                                v-if="$props.columnSearch"
+                                :column="col"
+                                :show-title="true"
+                                :data-key="$attrs['data-key']"
+                                v-model="params[columnName(col)]"
+                                :search-url="searchUrl"
+                                class="full-width"
+                            />
+                        </div>
+                    </QTh>
+                </template>
+                <template #header-cell-tableActions>
+                    <QTh auto-width class="sticky" />
+                </template>
+                <template #body-cell-tableStatus="{ col, row }">
+                    <QTd auto-width :class="getColAlign(col)">
+                        <VnTableChip :columns="splittedColumns.columnChips" :row="row">
+                            <template #afterChip>
+                                <slot name="afterChip" :row="row"></slot>
+                            </template>
+                        </VnTableChip>
+                    </QTd>
+                </template>
+                <template #body-cell="{ col, row, rowIndex }">
+                    <!-- Columns -->
+                    <QTd
+                        auto-width
+                        class="no-margin q-px-xs"
+                        :class="[getColAlign(col), col.columnClass]"
+                        v-if="col.visible ?? true"
+                        @click.ctrl="
+                            ($event) =>
+                                rowCtrlClickFunction && rowCtrlClickFunction($event, row)
+                        "
+                    >
+                        <slot
+                            :name="`column-${col.name}`"
+                            :col="col"
+                            :row="row"
+                            :row-index="rowIndex"
+                        >
+                            <VnTableColumn
+                                :column="col"
                                 :row="row"
-                            >
-                                <template #afterChip>
-                                    <slot name="afterChip" :row="row"></slot>
-                                </template>
-                            </VnTableChip>
-                        </QTd>
-                    </template>
-                    <template #body-cell="{ col, row, rowIndex }">
-                        <!-- Columns -->
-                        <QTd
-                            auto-width
-                            class="no-margin q-px-xs"
-                            :class="[getColAlign(col), col.columnClass]"
-                            v-if="col.visible ?? true"
-                            @click.ctrl="
-                                ($event) =>
-                                    rowCtrlClickFunction &&
-                                    rowCtrlClickFunction($event, row)
+                                :is-editable="col.isEditable ?? isEditable"
+                                v-model="row[col.name]"
+                                component-prop="columnField"
+                            />
+                        </slot>
+                    </QTd>
+                </template>
+                <template #body-cell-tableActions="{ col, row }">
+                    <QTd
+                        auto-width
+                        :class="getColAlign(col)"
+                        class="sticky no-padding"
+                        @click="stopEventPropagation($event)"
+                    >
+                        <QBtn
+                            v-for="(btn, index) of col.actions"
+                            v-show="btn.show ? btn.show(row) : true"
+                            :key="index"
+                            :title="btn.title"
+                            :icon="btn.icon"
+                            class="q-px-sm text-primary-light"
+                            flat
+                            :style="`visibility: ${
+                                (btn.show && btn.show(row)) ?? true ? 'visible' : 'hidden'
+                            }`"
+                            @click="btn.action(row)"
+                        />
+                    </QTd>
+                </template>
+                <template #item="{ row, colsMap }">
+                    <component
+                        :is="$props.redirect ? 'router-link' : 'span'"
+                        :to="`/${$props.redirect}/` + row.id"
+                    >
+                        <QCard
+                            bordered
+                            flat
+                            class="row no-wrap justify-between cursor-pointer"
+                            @click="
+                                (_, row) => {
+                                    $props.rowClick && $props.rowClick(row);
+                                }
                             "
                         >
-                            <slot
-                                :name="`column-${col.name}`"
-                                :col="col"
-                                :row="row"
-                                :row-index="rowIndex"
-                            >
-                                <VnTableColumn
-                                    :column="col"
-                                    :row="row"
-                                    :is-editable="col.isEditable ?? isEditable"
-                                    v-model="row[col.name]"
-                                    component-prop="columnField"
-                                />
-                            </slot>
-                        </QTd>
-                    </template>
-                    <template #body-cell-tableActions="{ col, row }">
-                        <QTd
-                            auto-width
-                            :class="getColAlign(col)"
-                            class="sticky no-padding"
-                            @click="stopEventPropagation($event)"
-                        >
-                            <QBtn
-                                v-for="(btn, index) of col.actions"
-                                :key="index"
-                                :title="btn.title"
-                                :icon="btn.icon"
-                                class="q-px-sm"
-                                flat
-                                :class="
-                                    btn.isPrimary
-                                        ? 'text-primary-light'
-                                        : 'color-vn-text '
-                                "
-                                :style="`visibility: ${
-                                    (btn.show && btn.show(row)) ?? true
-                                        ? 'visible'
-                                        : 'hidden'
-                                }`"
-                                @click="btn.action(row)"
-                            />
-                        </QTd>
-                    </template>
-                    <template #item="{ row, colsMap }">
-                        <component
-                            :is="$props.redirect ? 'router-link' : 'span'"
-                            :to="`/${$props.redirect}/` + row.id"
-                        >
-                            <QCard
-                                bordered
-                                flat
-                                class="row no-wrap justify-between cursor-pointer"
-                                @click="
-                                    (_, row) => {
-                                        $props.rowClick && $props.rowClick(row);
-                                    }
-                                "
+                            <QCardSection
+                                vertical
+                                class="no-margin no-padding"
+                                :class="colsMap.tableActions ? 'w-80' : 'fit'"
                             >
+                                <!-- Chips -->
                                 <QCardSection
-                                    vertical
-                                    class="no-margin no-padding"
-                                    :class="colsMap.tableActions ? 'w-80' : 'fit'"
+                                    v-if="splittedColumns.chips.length"
+                                    class="no-margin q-px-xs q-py-none"
                                 >
-                                    <!-- Chips -->
-                                    <QCardSection
-                                        v-if="splittedColumns.chips.length"
-                                        class="no-margin q-px-xs q-py-none"
+                                    <VnTableChip
+                                        :columns="splittedColumns.chips"
+                                        :row="row"
                                     >
-                                        <VnTableChip
-                                            :columns="splittedColumns.chips"
-                                            :row="row"
-                                        >
-                                            <template #afterChip>
-                                                <slot name="afterChip" :row="row"></slot>
-                                            </template>
-                                        </VnTableChip>
-                                    </QCardSection>
-                                    <!-- Title -->
-                                    <QCardSection
-                                        v-if="splittedColumns.title"
-                                        class="q-pl-sm q-py-none text-primary-light text-bold text-h6 cardEllipsis"
+                                        <template #afterChip>
+                                            <slot name="afterChip" :row="row"></slot>
+                                        </template>
+                                    </VnTableChip>
+                                </QCardSection>
+                                <!-- Title -->
+                                <QCardSection
+                                    v-if="splittedColumns.title"
+                                    class="q-pl-sm q-py-none text-primary-light text-bold text-h6 cardEllipsis"
+                                >
+                                    <span
+                                        :title="row[splittedColumns.title.name]"
+                                        @click="stopEventPropagation($event)"
+                                        class="cursor-text"
                                     >
-                                        <span
-                                            :title="row[splittedColumns.title.name]"
-                                            @click="stopEventPropagation($event)"
-                                            class="cursor-text"
-                                        >
-                                            {{ row[splittedColumns.title.name] }}
-                                        </span>
-                                    </QCardSection>
-                                    <!-- Fields -->
-                                    <QCardSection
-                                        class="q-pl-sm q-pr-lg q-py-xs"
-                                        :class="$props.cardClass"
+                                        {{ row[splittedColumns.title.name] }}
+                                    </span>
+                                </QCardSection>
+                                <!-- Fields -->
+                                <QCardSection
+                                    class="q-pl-sm q-pr-lg q-py-xs"
+                                    :class="$props.cardClass"
+                                >
+                                    <div
+                                        v-for="(
+                                            col, index
+                                        ) of splittedColumns.cardVisible"
+                                        :key="col.name"
+                                        class="fields"
                                     >
-                                        <div
-                                            v-for="(
-                                                col, index
-                                            ) of splittedColumns.cardVisible"
-                                            :key="col.name"
-                                            class="fields"
+                                        <VnLv
+                                            :label="
+                                                !col.component && col.label
+                                                    ? `${col.label}:`
+                                                    : ''
+                                            "
                                         >
-                                            <VnLv
-                                                :label="
-                                                    !col.component && col.label
-                                                        ? `${col.label}:`
-                                                        : ''
-                                                "
-                                            >
-                                                <template #value>
-                                                    <span
-                                                        @click="
-                                                            stopEventPropagation($event)
-                                                        "
+                                            <template #value>
+                                                <span
+                                                    @click="stopEventPropagation($event)"
+                                                >
+                                                    <slot
+                                                        :name="`column-${col.name}`"
+                                                        :col="col"
+                                                        :row="row"
+                                                        :row-index="index"
                                                     >
-                                                        <slot
-                                                            :name="`column-${col.name}`"
-                                                            :col="col"
+                                                        <VnTableColumn
+                                                            :column="col"
                                                             :row="row"
-                                                            :row-index="index"
-                                                        >
-                                                            <VnTableColumn
-                                                                :column="col"
-                                                                :row="row"
-                                                                :is-editable="false"
-                                                                v-model="row[col.name]"
-                                                                component-prop="columnField"
-                                                                :show-label="true"
-                                                            />
-                                                        </slot>
-                                                    </span>
-                                                </template>
-                                            </VnLv>
-                                        </div>
-                                    </QCardSection>
+                                                            :is-editable="false"
+                                                            v-model="row[col.name]"
+                                                            component-prop="columnField"
+                                                            :show-label="true"
+                                                        />
+                                                    </slot>
+                                                </span>
+                                            </template>
+                                        </VnLv>
+                                    </div>
                                 </QCardSection>
-                                <!-- Actions -->
-                                <QCardSection
-                                    v-if="colsMap.tableActions"
-                                    class="column flex-center w-10 no-margin q-pa-xs q-gutter-y-xs"
-                                    @click="stopEventPropagation($event)"
-                                >
-                                    <QBtn
-                                        v-for="(btn, index) of splittedColumns.actions
-                                            .actions"
-                                        :key="index"
-                                        :title="btn.title"
-                                        :icon="btn.icon"
-                                        class="q-pa-xs"
-                                        flat
-                                        :class="
-                                            btn.isPrimary
-                                                ? 'text-primary-light'
-                                                : 'color-vn-text '
-                                        "
-                                        @click="btn.action(row)"
-                                    />
-                                </QCardSection>
-                            </QCard>
-                        </component>
-                    </template>
-                </QTable>
-            </template>
-        </CrudModel>
-    </div>
-    <QPageSticky v-if="create" :offset="[20, 20]" style="z-index: 2">
-        <QBtn @click="showForm = !showForm" color="primary" fab icon="add" />
+                            </QCardSection>
+                            <!-- Actions -->
+                            <QCardSection
+                                v-if="colsMap.tableActions"
+                                class="column flex-center w-10 no-margin q-pa-xs q-gutter-y-xs"
+                                @click="stopEventPropagation($event)"
+                            >
+                                <QBtn
+                                    v-for="(btn, index) of splittedColumns.actions
+                                        .actions"
+                                    :key="index"
+                                    :title="btn.title"
+                                    :icon="btn.icon"
+                                    class="q-pa-xs"
+                                    flat
+                                    :class="
+                                        btn.isPrimary
+                                            ? 'text-primary-light'
+                                            : 'color-vn-text '
+                                    "
+                                    @click="btn.action(row)"
+                                />
+                            </QCardSection>
+                        </QCard>
+                    </component>
+                </template>
+            </QTable>
+        </template>
+    </CrudModel>
+    <QPageSticky v-if="$props.create" :offset="[20, 20]" style="z-index: 2">
+        <QBtn
+            @click="
+                () =>
+                    createAsDialog ? (showForm = !showForm) : handleOnDataSaved(create)
+            "
+            color="primary"
+            fab
+            icon="add"
+            shortcut="+"
+        />
         <QTooltip>
-            {{ createForm.title }}
+            {{ createForm?.title }}
         </QTooltip>
     </QPageSticky>
     <QDialog v-model="showForm" transition-show="scale" transition-hide="scale">
@@ -739,6 +761,7 @@ es:
     }
     .q-table__top {
         top: 0;
+        padding: 12px 0;
     }
     tbody {
         .q-checkbox {
diff --git a/src/components/common/RightMenu.vue b/src/components/common/RightMenu.vue
index 732e5367d..3aa1891f9 100644
--- a/src/components/common/RightMenu.vue
+++ b/src/components/common/RightMenu.vue
@@ -37,7 +37,7 @@ const stateStore = useStateStore();
                 @click="stateStore.toggleRightDrawer()"
                 round
                 dense
-                icon="menu"
+                icon="dock_to_left"
             >
                 <QTooltip bottom anchor="bottom right">
                     {{ t('globals.collapseMenu') }}
diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 94adbf6cf..7d29da232 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -1,6 +1,6 @@
 <script setup>
 import { onBeforeMount, computed } from 'vue';
-import { useRoute, onBeforeRouteUpdate } from 'vue-router';
+import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
 import { useArrayData } from 'src/composables/useArrayData';
 import { useStateStore } from 'stores/useStateStore';
 import useCardSize from 'src/composables/useCardSize';
@@ -8,7 +8,6 @@ import VnSubToolbar from '../ui/VnSubToolbar.vue';
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
 import LeftMenu from 'components/LeftMenu.vue';
 import RightMenu from 'components/common/RightMenu.vue';
-
 const props = defineProps({
     dataKey: { type: String, required: true },
     baseUrl: { type: String, default: undefined },
@@ -18,23 +17,32 @@ const props = defineProps({
     filterPanel: { type: Object, default: undefined },
     searchDataKey: { type: String, default: undefined },
     searchbarProps: { type: Object, default: undefined },
+    redirectOnError: { type: Boolean, default: false },
 });
 
 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: url.value,
     filter: props.filter,
 });
 
 onBeforeMount(async () => {
-    if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
-    await arrayData.fetch({ append: false, updateRouter: false });
+    try {
+        if (!props.baseUrl) arrayData.store.filter.where = { id: route.params.id };
+        await arrayData.fetch({ append: false, updateRouter: false });
+    } catch (e) {
+        router.push({ name: 'WorkerList' });
+    }
 });
 
 if (props.baseUrl) {
@@ -62,17 +70,16 @@ if (props.baseUrl) {
     <slot name="searchbar" v-if="props.searchDataKey">
         <VnSearchbar :data-key="props.searchDataKey" v-bind="props.searchbarProps" />
     </slot>
-    <slot v-else name="searchbar" />
     <RightMenu>
         <template #right-panel v-if="props.filterPanel">
-            <component :is="props.filterPanel" :data-key="props.searchDataKey" />
+            <component :is="props.filterPanel" :data-key="searchRightDataKey" />
         </template>
     </RightMenu>
     <QPageContainer>
         <QPage>
             <VnSubToolbar />
             <div :class="[useCardSize(), $attrs.class]">
-                <RouterView />
+                <RouterView :key="route.path" />
             </div>
         </QPage>
     </QPageContainer>
diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue
index c42de6690..16e3c641f 100644
--- a/src/components/common/VnDmsList.vue
+++ b/src/components/common/VnDmsList.vue
@@ -5,12 +5,14 @@ import { useRoute } from 'vue-router';
 import { useQuasar, QCheckbox, QBtn, QInput } from 'quasar';
 import axios from 'axios';
 
+import VnUserLink from '../ui/VnUserLink.vue';
+import { downloadFile } from 'src/composables/downloadFile';
+import VnImg from 'components/ui/VnImg.vue';
 import VnPaginate from 'components/ui/VnPaginate.vue';
 import VnDms from 'src/components/common/VnDms.vue';
 import VnConfirm from 'components/ui/VnConfirm.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
-import VnUserLink from '../ui/VnUserLink.vue';
-import { downloadFile } from 'src/composables/downloadFile';
+import { useSession } from 'src/composables/useSession';
 
 const route = useRoute();
 const quasar = useQuasar();
@@ -18,6 +20,7 @@ const { t } = useI18n();
 const rows = ref();
 const dmsRef = ref();
 const formDialog = ref({});
+const token = useSession().getTokenMultimedia();
 
 const $props = defineProps({
     model: {
@@ -89,6 +92,23 @@ const dmsFilter = {
 };
 
 const columns = computed(() => [
+    {
+        label: '',
+        name: 'file',
+        align: 'left',
+        component: VnImg,
+        props: (prop) => {
+            return {
+                storage: 'dms',
+                collection: null,
+                resolution: null,
+                id: prop.row.file.split('.')[0],
+                token: token,
+                class: 'rounded',
+                ratio: 1,
+            };
+        },
+    },
     {
         align: 'left',
         field: 'id',
@@ -135,19 +155,13 @@ const columns = computed(() => [
         field: 'hasFile',
         label: t('globals.original'),
         name: 'hasFile',
+        toolTip: t('The documentation is available in paper form'),
         component: QCheckbox,
         props: (prop) => ({
             disable: true,
             'model-value': Boolean(prop.value),
         }),
     },
-    {
-        align: 'left',
-        field: 'file',
-        label: t('globals.file'),
-        name: 'file',
-        component: 'span',
-    },
     {
         align: 'left',
         field: 'worker',
@@ -297,6 +311,14 @@ defineExpose({
                 row-key="clientFk"
                 :grid="$q.screen.lt.sm"
             >
+                <template #header="props">
+                    <QTr :props="props" class="bg">
+                        <QTh v-for="col in props.cols" :key="col.name" :props="props">
+                            <QTooltip v-if="col.toolTip">{{ col.toolTip }}</QTooltip
+                            >{{ col.label }}
+                        </QTh>
+                    </QTr>
+                </template>
                 <template #body-cell="props">
                     <QTd :props="props">
                         <QTr :props="props">
@@ -386,10 +408,6 @@ defineExpose({
     </QPageSticky>
 </template>
 <style scoped>
-.q-gutter-y-ms {
-    display: grid;
-    row-gap: 20px;
-}
 .labelColor {
     color: var(--vn-label-color);
 }
@@ -397,8 +415,10 @@ defineExpose({
 <i18n>
 en:
     contentTypesInfo: Allowed file types {allowedContentTypes}
+    The documentation is available in paper form: The documentation is available in paper form
 es:
     contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes}
     Generate identifier for original file: Generar identificador para archivo original
     Upload file: Subir fichero
+    the documentation is available in paper form: Se tiene la documentación en papel
 </i18n>
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 33b97e29d..570d0cbfe 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -1,6 +1,7 @@
 <script setup>
 import { computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
+import { useValidator } from 'src/composables/useValidator';
 
 const emit = defineEmits([
     'update:modelValue',
@@ -27,9 +28,11 @@ const $props = defineProps({
         default: true,
     },
 });
+const { validations } = useValidator();
 
 const { t } = useI18n();
-const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
+const requiredFieldRule = (val) => validations().required($attrs.required, val);
+
 const vnInputRef = ref(null);
 const value = computed({
     get() {
@@ -57,21 +60,22 @@ const focus = () => {
 defineExpose({
     focus,
 });
+import { useAttrs } from 'vue';
+const $attrs = useAttrs();
 
-const inputRules = [
+const mixinRules = [
+    requiredFieldRule,
+    ...($attrs.rules ?? []),
     (val) => {
         const { min } = vnInputRef.value.$attrs;
+        if (!min) return null;
         if (min >= 0) if (Math.floor(val) < min) return t('inputMin', { value: min });
     },
 ];
 </script>
 
 <template>
-    <div
-        @mouseover="hover = true"
-        @mouseleave="hover = false"
-        :rules="$attrs.required ? [requiredFieldRule] : null"
-    >
+    <div @mouseover="hover = true" @mouseleave="hover = false">
         <QInput
             ref="vnInputRef"
             v-model="value"
@@ -80,7 +84,7 @@ const inputRules = [
             :class="{ required: $attrs.required }"
             @keyup.enter="emit('keyup.enter')"
             :clearable="false"
-            :rules="inputRules"
+            :rules="mixinRules"
             :lazy-rules="true"
             hide-bottom-space
         >
@@ -88,7 +92,6 @@ const inputRules = [
                 <slot name="prepend" />
             </template>
             <template #append>
-                <slot name="append" v-if="$slots.append && !$attrs.disabled" />
                 <QIcon
                     name="close"
                     size="xs"
@@ -100,6 +103,7 @@ const inputRules = [
                         }
                     "
                 ></QIcon>
+                <slot name="append" v-if="$slots.append && !$attrs.disabled" />
                 <QIcon v-if="info" name="info">
                     <QTooltip max-width="350px">
                         {{ info }}
@@ -115,3 +119,8 @@ const inputRules = [
     es:
         inputMin: Debe ser mayor a {value}
 </i18n>
+<style lang="scss">
+.q-field__append {
+    padding-inline: 0;
+}
+</style>
diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue
index 6e57a8a53..96e47d6d7 100644
--- a/src/components/common/VnInputDate.vue
+++ b/src/components/common/VnInputDate.vue
@@ -3,12 +3,16 @@ import { onMounted, watch, computed, ref } from 'vue';
 import { date } from 'quasar';
 import { useI18n } from 'vue-i18n';
 
-const model = defineModel({ type: String });
+const model = defineModel({ type: [String, Date] });
 const $props = defineProps({
     isOutlined: {
         type: Boolean,
         default: false,
     },
+    showEvent: {
+        type: Boolean,
+        default: true,
+    },
 });
 
 const { t } = useI18n();
@@ -94,6 +98,7 @@ watch(
             :class="{ required: $attrs.required }"
             :rules="$attrs.required ? [requiredFieldRule] : null"
             :clearable="false"
+            @click="isPopupOpen = true"
         >
             <template #append>
                 <QIcon
@@ -111,6 +116,7 @@ watch(
                     "
                 />
                 <QIcon
+                    v-if="showEvent"
                     name="event"
                     class="cursor-pointer"
                     @click="isPopupOpen = !isPopupOpen"
@@ -130,6 +136,7 @@ watch(
                     v-model="popupDate"
                     :landscape="true"
                     :today-btn="true"
+                    :options="$attrs.options"
                     @update:model-value="
                         (date) => {
                             formattedDate = date;
diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue
index 7ee93de19..b3478bb23 100644
--- a/src/components/common/VnInputTime.vue
+++ b/src/components/common/VnInputTime.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { watch, computed, ref, nextTick } from 'vue';
+import { computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { date } from 'quasar';
 
@@ -14,13 +14,13 @@ const props = defineProps({
         default: false,
     },
 });
+const initialDate = ref(model.value ?? Date.vnNew());
 const { t } = useI18n();
 const requiredFieldRule = (val) => !!val || t('globals.fieldRequired');
 
 const dateFormat = 'HH:mm';
 const isPopupOpen = ref();
 const hover = ref();
-const inputRef = ref();
 
 const styleAttrs = computed(() => {
     return props.isOutlined
@@ -50,7 +50,8 @@ const formattedTime = computed({
             }
             if (!props.timeOnly) {
                 const [hh, mm] = time.split(':');
-                const date = new Date(model.value ? model.value : null);
+
+                const date = new Date(model.value ? model.value : initialDate.value);
                 date.setHours(hh, mm, 0);
                 time = date?.toISOString();
             }
@@ -62,37 +63,10 @@ const formattedTime = computed({
 function dateToTime(newDate) {
     return date.formatDate(new Date(newDate), dateFormat);
 }
-
-watch(
-    () => model.value,
-    (val) => (formattedTime.value = val),
-    { immediate: true }
-);
-
-watch(
-    () => formattedTime.value,
-    async (val) => {
-        let position = 3;
-        const input = inputRef.value?.getNativeElement();
-        if (!val || !input) return;
-
-        let [hh, mm] = val.split(':');
-        hh = parseInt(hh);
-        if (hh >= 10 || mm != '00') return;
-
-        await nextTick();
-        await nextTick();
-        if (!hh) position = 0;
-        input.setSelectionRange(position, position);
-    },
-    { immediate: true }
-);
 </script>
-
 <template>
     <div @mouseover="hover = true" @mouseleave="hover = false">
         <QInput
-            ref="inputRef"
             class="vn-input-time"
             mask="##:##"
             placeholder="--:--"
@@ -102,7 +76,7 @@ watch(
             style="min-width: 100px"
             :rules="$attrs.required ? [requiredFieldRule] : null"
             @click="isPopupOpen = false"
-            @focus="inputRef.getNativeElement().setSelectionRange(0, 0)"
+            type="time"
         >
             <template #append>
                 <QIcon
@@ -149,6 +123,11 @@ watch(
     border-style: solid;
 }
 </style>
+<style lang="scss" scoped>
+:deep(input[type='time']::-webkit-calendar-picker-indicator) {
+    display: none;
+}
+</style>
 <i18n>
     es:
         Open time: Abrir tiempo
diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue
index 2163d54d4..ab522cfde 100644
--- a/src/components/common/VnLog.vue
+++ b/src/components/common/VnLog.vue
@@ -14,6 +14,7 @@ import VnJsonValue from '../common/VnJsonValue.vue';
 import FetchData from '../FetchData.vue';
 import VnSelect from './VnSelect.vue';
 import VnUserLink from '../ui/VnUserLink.vue';
+import VnPaginate from '../ui/VnPaginate.vue';
 
 const stateStore = useStateStore();
 const validationsStore = useValidator();
@@ -66,9 +67,10 @@ const filter = {
             },
         },
     ],
+    where: { and: [{ originFk: route.params.id }] },
 };
 
-const workers = ref();
+const paginate = ref();
 const actions = ref();
 const changeInput = ref();
 const searchInput = ref();
@@ -235,9 +237,7 @@ async function openPointRecord(id, modelLog) {
     const locale = validations[modelLog.model]?.locale || {};
     pointRecord.value = parseProps(propNames, locale, data);
 }
-async function setLogTree() {
-    filter.where = { and: [{ originFk: route.params.id }] };
-    const { data } = await getLogs(filter);
+async function setLogTree(data) {
     logTree.value = getLogTree(data);
 }
 
@@ -266,15 +266,7 @@ async function applyFilter() {
         filter.where.and.push(selectedFilters.value);
     }
 
-    const { data } = await getLogs(filter);
-
-    logTree.value = getLogTree(data);
-}
-
-async function getLogs(filter) {
-    return axios.get(props.url ?? `${props.model}Logs`, {
-        params: { filter: JSON.stringify(filter) },
-    });
+    paginate.value.fetch(filter);
 }
 
 function setDate(type) {
@@ -377,8 +369,6 @@ async function clearFilter() {
     await applyFilter();
 }
 
-setLogTree();
-
 onUnmounted(() => {
     stateStore.rightDrawer = false;
 });
@@ -391,16 +381,6 @@ watch(
 );
 </script>
 <template>
-    <FetchData
-        :url="`${props.model}Logs/${route.params.id}/editors`"
-        :filter="{
-            fields: ['id', 'nickname', 'name', 'image'],
-            order: 'nickname',
-            limit: 30,
-        }"
-        @on-fetch="(data) => (workers = data)"
-        auto-load
-    />
     <FetchData
         :url="`${props.model}Logs/${route.params.id}/models`"
         :filter="{ order: ['changedModel'] }"
@@ -418,231 +398,283 @@ watch(
         "
         auto-load
     />
-    <div
-        class="column items-center logs origin-log q-mt-md"
-        v-for="(originLog, originLogIndex) in logTree"
-        :key="originLogIndex"
+    <VnPaginate
+        ref="paginate"
+        :data-key="`${model}Log`"
+        :url="`${model}Logs`"
+        :filter="filter"
+        :skeleton="false"
+        auto-load
+        @on-fetch="setLogTree"
     >
-        <QItem class="origin-info items-center q-my-md" v-if="logTree.length > 1">
-            <h6 class="origin-id text-grey">
-                {{ useCapitalize(validations[props.model].locale.name) }}
-                #{{ originLog.originFk }}
-            </h6>
-            <div class="line bg-grey"></div>
-        </QItem>
-        <div
-            class="user-log q-mb-sm"
-            v-for="(userLog, userIndex) in originLog.logs"
-            :key="userIndex"
-        >
-            <div class="timeline">
-                <div class="user-avatar">
-                    <VnUserLink :worker-id="userLog?.user?.id">
-                        <template #link>
-                            <VnAvatar
-                                :class="{ 'cursor-pointer': userLog?.user?.id }"
-                                :worker-id="userLog?.user?.id"
-                                :title="userLog?.user?.nickname"
-                                :show-letter="!userLog?.user"
-                                size="lg"
-                            />
-                        </template>
-                    </VnUserLink>
-                </div>
-                <div class="arrow bg-panel" v-if="byRecord"></div>
-                <div class="line"></div>
-            </div>
-            <QList class="user-changes" v-if="userLog">
-                <QItem
-                    class="model-log column q-px-none q-py-xs"
-                    v-for="(modelLog, modelLogIndex) in userLog.logs"
-                    :key="modelLogIndex"
+        <template #body>
+            <div
+                class="column items-center logs origin-log q-mt-md"
+                v-for="(originLog, originLogIndex) in logTree"
+                :key="originLogIndex"
+            >
+                <QItem class="origin-info items-center q-my-md" v-if="logTree.length > 1">
+                    <h6 class="origin-id text-grey">
+                        {{ useCapitalize(validations[props.model].locale.name) }}
+                        #{{ originLog.originFk }}
+                    </h6>
+                    <div class="line bg-grey"></div>
+                </QItem>
+                <div
+                    class="user-log q-mb-sm"
+                    v-for="(userLog, userIndex) in originLog.logs"
+                    :key="userIndex"
                 >
-                    <QItemSection>
-                        <QItemLabel class="model-info q-mb-xs" v-if="!byRecord">
-                            <QChip
-                                dense
-                                size="md"
-                                class="model-name q-mr-xs text-white"
-                                v-if="
-                                    !(modelLog.changedModel && modelLog.changedModelId) &&
-                                    modelLog.model
-                                "
-                                :style="{
-                                    backgroundColor: useColor(modelLog.model),
-                                }"
-                                :title="`${modelLog.model} #${modelLog.id}`"
-                            >
-                                {{ t(modelLog.modelI18n) }}
-                            </QChip>
-
-                            <span
-                                class="model-id q-mr-xs"
-                                v-if="modelLog.summaryId"
-                                v-text="`#${modelLog.summaryId}`"
-                            />
-                            <span
-                                class="model-value"
-                                :title="modelLog.showValue"
-                                v-text="modelLog.showValue"
-                            />
-                            <QBtn
-                                flat
-                                round
-                                color="grey"
-                                class="q-mr-xs q-ml-auto"
-                                size="sm"
-                                icon="filter_alt"
-                                :title="t('recordChanges')"
-                                @click.stop="filterByRecord(modelLog)"
-                            />
-                        </QItemLabel>
-                    </QItemSection>
-                    <QItemSection>
-                        <QCard
-                            class="changes-log q-py-none q-mb-xs"
-                            v-for="(log, logIndex) in modelLog.logs"
-                            :key="logIndex"
+                    <div class="timeline">
+                        <div class="user-avatar">
+                            <VnUserLink :worker-id="userLog?.user?.id">
+                                <template #link>
+                                    <VnAvatar
+                                        :class="{ 'cursor-pointer': userLog?.user?.id }"
+                                        :worker-id="userLog?.user?.id"
+                                        :title="userLog?.user?.nickname"
+                                        :show-letter="!userLog?.user"
+                                        size="lg"
+                                    />
+                                </template>
+                            </VnUserLink>
+                        </div>
+                        <div class="arrow bg-panel" v-if="byRecord"></div>
+                        <div class="line"></div>
+                    </div>
+                    <QList class="user-changes" v-if="userLog">
+                        <QItem
+                            class="model-log column q-px-none q-py-xs"
+                            v-for="(modelLog, modelLogIndex) in userLog.logs"
+                            :key="modelLogIndex"
                         >
-                            <QCardSection class="change-info q-pa-none">
-                                <QItem
-                                    class="q-px-sm q-py-xs justify-between items-center"
-                                >
-                                    <div
-                                        class="date text-grey text-caption q-mr-sm"
-                                        :title="
-                                            date.formatDate(
-                                                log.creationDate,
-                                                'DD/MM/YYYY hh:mm:ss'
-                                            ) ?? `date:'dd/MM/yyyy HH:mm:ss'`
+                            <QItemSection>
+                                <QItemLabel class="model-info q-mb-xs" v-if="!byRecord">
+                                    <QChip
+                                        dense
+                                        size="md"
+                                        class="model-name q-mr-xs text-white"
+                                        v-if="
+                                            !(
+                                                modelLog.changedModel &&
+                                                modelLog.changedModelId
+                                            ) && modelLog.model
                                         "
+                                        :style="{
+                                            backgroundColor: useColor(modelLog.model),
+                                        }"
+                                        :title="`${modelLog.model} #${modelLog.id}`"
                                     >
-                                        {{ toRelativeDate(log.creationDate) }}
-                                    </div>
-                                    <div>
-                                        <QBtn
-                                            color="grey"
-                                            class="pit"
-                                            icon="preview"
-                                            flat
-                                            round
-                                            :title="t('pointRecord')"
-                                            padding="none"
-                                            v-if="log.action != 'insert'"
-                                            @click.stop="
-                                                openPointRecord(log.id, modelLog)
-                                            "
-                                        >
-                                            <QPopupProxy>
-                                                <QCard v-if="pointRecord">
-                                                    <div
-                                                        class="header q-px-sm q-py-xs q-ma-none text-white text-bold bg-primary"
-                                                    >
-                                                        {{ modelLog.modelI18n }}
-                                                        <span v-if="modelLog.id"
-                                                            >#{{ modelLog.id }}</span
-                                                        >
-                                                    </div>
-                                                    <QCardSection
-                                                        class="change-detail q-pa-sm"
-                                                    >
-                                                        <QItem
-                                                            v-for="(
-                                                                value, index
-                                                            ) in pointRecord"
-                                                            :key="index"
-                                                            class="q-pa-none"
-                                                        >
-                                                            <span
-                                                                class="json-field q-mr-xs text-grey"
-                                                                :title="value.name"
-                                                            >
-                                                                {{ value.nameI18n }}:
-                                                            </span>
-                                                            <VnJsonValue
-                                                                :value="value.val.val"
-                                                            />
-                                                        </QItem>
-                                                    </QCardSection>
-                                                </QCard>
-                                            </QPopupProxy>
-                                        </QBtn>
-                                        <QIcon
-                                            class="action q-ml-xs"
-                                            :class="actionsClass[log.action]"
-                                            :name="actionsIcon[log.action]"
-                                            :title="
-                                                t(`actions.${actionsText[log.action]}`)
-                                            "
-                                        />
-                                    </div>
-                                </QItem>
-                            </QCardSection>
-                            <QCardSection
-                                class="change-detail q-px-sm q-py-xs"
-                                :class="{ expanded: log.expand }"
-                                v-if="log.props.length || log.description"
-                            >
-                                <QIcon
-                                    class="cursor-pointer q-mr-md"
-                                    color="grey"
-                                    name="expand_more"
-                                    :title="t('globals.details')"
-                                    size="sm"
-                                    @click="log.expand = !log.expand"
-                                />
-                                <span v-if="log.props.length" class="attributes">
-                                    <span v-if="!log.expand" class="q-pa-none text-grey">
-                                        <span
-                                            v-for="(prop, propIndex) in log.props"
-                                            :key="propIndex"
-                                            class="basic-json"
-                                        >
-                                            <span class="json-field" :title="prop.name">
-                                                {{ prop.nameI18n }}:
-                                            </span>
-                                            <VnJsonValue :value="prop.val.val" />
-                                            <span v-if="propIndex < log.props.length - 1"
-                                                >,&nbsp;
-                                            </span>
-                                        </span>
-                                    </span>
+                                        {{ t(modelLog.modelI18n) }}
+                                    </QChip>
+
                                     <span
-                                        v-if="log.expand"
-                                        class="expanded-json column q-pa-none"
-                                    >
-                                        <div
-                                            v-for="(prop, prop2Index) in log.props"
-                                            :key="prop2Index"
-                                            class="q-pa-none text-grey"
+                                        class="model-id q-mr-xs"
+                                        v-if="modelLog.summaryId"
+                                        v-text="`#${modelLog.summaryId}`"
+                                    />
+                                    <span
+                                        class="model-value"
+                                        :title="modelLog.showValue"
+                                        v-text="modelLog.showValue"
+                                    />
+                                    <QBtn
+                                        flat
+                                        round
+                                        color="grey"
+                                        class="q-mr-xs q-ml-auto"
+                                        size="sm"
+                                        icon="filter_alt"
+                                        :title="t('recordChanges')"
+                                        @click.stop="filterByRecord(modelLog)"
+                                    />
+                                </QItemLabel>
+                            </QItemSection>
+                            <QItemSection>
+                                <QCard
+                                    class="changes-log q-py-none q-mb-xs"
+                                    v-for="(log, logIndex) in modelLog.logs"
+                                    :key="logIndex"
+                                >
+                                    <QCardSection class="change-info q-pa-none">
+                                        <QItem
+                                            class="q-px-sm q-py-xs justify-between items-center"
                                         >
-                                            <span class="json-field" :title="prop.name">
-                                                {{ prop.nameI18n }}:
-                                            </span>
-                                            <VnJsonValue :value="prop.val.val" />
-                                            <span v-if="prop.val.id" class="id-value">
-                                                #{{ prop.val.id }}
-                                            </span>
-                                            <span v-if="log.action == 'update'">
-                                                ←
-                                                <VnJsonValue :value="prop.old.val" />
-                                                <span v-if="prop.old.id" class="id-value">
-                                                    #{{ prop.old.id }}
+                                            <div
+                                                class="date text-grey text-caption q-mr-sm"
+                                                :title="
+                                                    date.formatDate(
+                                                        log.creationDate,
+                                                        'DD/MM/YYYY hh:mm:ss'
+                                                    ) ?? `date:'dd/MM/yyyy HH:mm:ss'`
+                                                "
+                                            >
+                                                {{ toRelativeDate(log.creationDate) }}
+                                            </div>
+                                            <div>
+                                                <QBtn
+                                                    color="grey"
+                                                    class="pit"
+                                                    icon="preview"
+                                                    flat
+                                                    round
+                                                    :title="t('pointRecord')"
+                                                    padding="none"
+                                                    v-if="log.action != 'insert'"
+                                                    @click.stop="
+                                                        openPointRecord(log.id, modelLog)
+                                                    "
+                                                >
+                                                    <QPopupProxy>
+                                                        <QCard v-if="pointRecord">
+                                                            <div
+                                                                class="header q-px-sm q-py-xs q-ma-none text-white text-bold bg-primary"
+                                                            >
+                                                                {{ modelLog.modelI18n }}
+                                                                <span v-if="modelLog.id"
+                                                                    >#{{
+                                                                        modelLog.id
+                                                                    }}</span
+                                                                >
+                                                            </div>
+                                                            <QCardSection
+                                                                class="change-detail q-pa-sm"
+                                                            >
+                                                                <QItem
+                                                                    v-for="(
+                                                                        value, index
+                                                                    ) in pointRecord"
+                                                                    :key="index"
+                                                                    class="q-pa-none"
+                                                                >
+                                                                    <span
+                                                                        class="json-field q-mr-xs text-grey"
+                                                                        :title="
+                                                                            value.name
+                                                                        "
+                                                                    >
+                                                                        {{
+                                                                            value.nameI18n
+                                                                        }}:
+                                                                    </span>
+                                                                    <VnJsonValue
+                                                                        :value="
+                                                                            value.val.val
+                                                                        "
+                                                                    />
+                                                                </QItem>
+                                                            </QCardSection>
+                                                        </QCard>
+                                                    </QPopupProxy>
+                                                </QBtn>
+                                                <QIcon
+                                                    class="action q-ml-xs"
+                                                    :class="actionsClass[log.action]"
+                                                    :name="actionsIcon[log.action]"
+                                                    :title="
+                                                        t(
+                                                            `actions.${
+                                                                actionsText[log.action]
+                                                            }`
+                                                        )
+                                                    "
+                                                />
+                                            </div>
+                                        </QItem>
+                                    </QCardSection>
+                                    <QCardSection
+                                        class="change-detail q-px-sm q-py-xs"
+                                        :class="{ expanded: log.expand }"
+                                        v-if="log.props.length || log.description"
+                                    >
+                                        <QIcon
+                                            class="cursor-pointer q-mr-md"
+                                            color="grey"
+                                            name="expand_more"
+                                            :title="t('globals.details')"
+                                            size="sm"
+                                            @click="log.expand = !log.expand"
+                                        />
+                                        <span v-if="log.props.length" class="attributes">
+                                            <span
+                                                v-if="!log.expand"
+                                                class="q-pa-none text-grey"
+                                            >
+                                                <span
+                                                    v-for="(prop, propIndex) in log.props"
+                                                    :key="propIndex"
+                                                    class="basic-json"
+                                                >
+                                                    <span
+                                                        class="json-field"
+                                                        :title="prop.name"
+                                                    >
+                                                        {{ prop.nameI18n }}:
+                                                    </span>
+                                                    <VnJsonValue :value="prop.val.val" />
+                                                    <span
+                                                        v-if="
+                                                            propIndex <
+                                                            log.props.length - 1
+                                                        "
+                                                        >,&nbsp;
+                                                    </span>
                                                 </span>
                                             </span>
-                                        </div>
-                                    </span>
-                                </span>
-                                <span v-if="!log.props.length" class="description">
-                                    {{ log.description }}
-                                </span>
-                            </QCardSection>
-                        </QCard>
-                    </QItemSection>
-                </QItem>
-            </QList>
-        </div>
-    </div>
+                                            <span
+                                                v-if="log.expand"
+                                                class="expanded-json column q-pa-none"
+                                            >
+                                                <div
+                                                    v-for="(
+                                                        prop, prop2Index
+                                                    ) in log.props"
+                                                    :key="prop2Index"
+                                                    class="q-pa-none text-grey"
+                                                >
+                                                    <span
+                                                        class="json-field"
+                                                        :title="prop.name"
+                                                    >
+                                                        {{ prop.nameI18n }}:
+                                                    </span>
+                                                    <VnJsonValue :value="prop.val.val" />
+                                                    <span
+                                                        v-if="prop.val.id"
+                                                        class="id-value"
+                                                    >
+                                                        #{{ prop.val.id }}
+                                                    </span>
+                                                    <span v-if="log.action == 'update'">
+                                                        ←
+                                                        <VnJsonValue
+                                                            :value="prop.old.val"
+                                                        />
+                                                        <span
+                                                            v-if="prop.old.id"
+                                                            class="id-value"
+                                                        >
+                                                            #{{ prop.old.id }}
+                                                        </span>
+                                                    </span>
+                                                </div>
+                                            </span>
+                                        </span>
+                                        <span
+                                            v-if="!log.props.length"
+                                            class="description"
+                                        >
+                                            {{ log.description }}
+                                        </span>
+                                    </QCardSection>
+                                </QCard>
+                            </QItemSection>
+                        </QItem>
+                    </QList>
+                </div>
+            </div>
+        </template>
+    </VnPaginate>
     <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
         <QList dense>
             <QSeparator />
@@ -691,17 +723,16 @@ watch(
                 </QOptionGroup>
             </QItem>
             <QItem class="q-mt-sm">
-                <QItemSection v-if="!workers">
-                    <QSkeleton type="QInput" class="full-width" />
-                </QItemSection>
-                <QItemSection v-if="workers && userRadio !== null">
+                <QItemSection v-if="userRadio !== null">
                     <VnSelect
                         class="full-width"
                         :label="t('globals.user')"
                         v-model="userSelect"
                         option-label="name"
                         option-value="id"
-                        :options="workers"
+                        :url="`${model}Logs/${$route.params.id}/editors`"
+                        :fields="['id', 'nickname', 'name', 'image']"
+                        sort-by="nickname"
                         @update:model-value="selectFilter('userSelect')"
                         hide-selected
                     >
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index 63a3f088f..1e3a32f48 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -73,6 +73,14 @@ const $props = defineProps({
         type: Boolean,
         default: true,
     },
+    params: {
+        type: Object,
+        default: null,
+    },
+    noOne: {
+        type: Boolean,
+        default: false,
+    },
 });
 
 const { t } = useI18n();
@@ -85,6 +93,11 @@ const myOptionsOriginal = ref([]);
 const vnSelectRef = ref();
 const dataRef = ref();
 const lastVal = ref();
+const noOneText = t('globals.noOne');
+const noOneOpt = ref({
+    [optionValue.value]: false,
+    [optionLabel.value]: noOneText,
+});
 
 const value = computed({
     get() {
@@ -100,9 +113,11 @@ watch(options, (newValue) => {
     setOptions(newValue);
 });
 
-watch(modelValue, (newValue) => {
+watch(modelValue, async (newValue) => {
     if (!myOptions.value.some((option) => option[optionValue.value] == newValue))
-        fetchFilter(newValue);
+        await fetchFilter(newValue);
+
+    if ($props.noOne) myOptions.value.unshift(noOneOpt.value);
 });
 
 onMounted(() => {
@@ -153,13 +168,19 @@ async function fetchFilter(val) {
             ? optionValue.value
             : optionFilter.value ?? optionLabel.value);
 
-    const defaultWhere = $props.useLike
-        ? { [key]: { like: `%${val}%` } }
-        : { [key]: val };
+    let defaultWhere = {};
+    if ($props.filterOptions.length) {
+        defaultWhere = $props.filterOptions.reduce((obj, prop) => {
+            if (!obj.or) obj.or = [];
+            obj.or.push({ [prop]: getVal(val) });
+            return obj;
+        }, {});
+    } else defaultWhere = { [key]: getVal(val) };
     const where = { ...(val ? defaultWhere : {}), ...$props.where };
     const fetchOptions = { where, include, limit };
     if (fields) fetchOptions.fields = fields;
     if (sortBy) fetchOptions.order = sortBy;
+
     return dataRef.value.fetch(fetchOptions);
 }
 
@@ -180,6 +201,9 @@ async function filterHandler(val, update) {
     } else newOptions = filter(val, myOptionsOriginal.value);
     update(
         () => {
+            if ($props.noOne && noOneText.toLowerCase().includes(val.toLowerCase()))
+                newOptions.unshift(noOneOpt.value);
+
             myOptions.value = newOptions;
         },
         (ref) => {
@@ -194,6 +218,8 @@ async function filterHandler(val, update) {
 function nullishToTrue(value) {
     return value ?? true;
 }
+
+const getVal = (val) => ($props.useLike ? { like: `%${val}%` } : val);
 </script>
 
 <template>
@@ -205,6 +231,7 @@ function nullishToTrue(value) {
         :limit="limit"
         :sort-by="sortBy"
         :fields="fields"
+        :params="params"
     />
     <QSelect
         v-model="value"
diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue
index 7f7c29f5d..17f893255 100644
--- a/src/components/common/VnSelectDialog.vue
+++ b/src/components/common/VnSelectDialog.vue
@@ -1,6 +1,7 @@
 <script setup>
 import { ref, computed } from 'vue';
 import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 
 import VnSelect from 'src/components/common/VnSelect.vue';
 const emit = defineEmits(['update:modelValue']);
@@ -11,6 +12,10 @@ const $props = defineProps({
         type: Array,
         default: () => ['developer'],
     },
+    acls: {
+        type: Array,
+        default: () => [],
+    },
     actionIcon: {
         type: String,
         default: 'add',
@@ -22,15 +27,12 @@ const $props = defineProps({
 });
 
 const role = useRole();
-const showForm = ref(false);
+const acl = useAcl();
 
 const isAllowedToCreate = computed(() => {
+    if ($props.acls.length) return acl.hasAny($props.acls);
     return role.hasAny($props.rolesAllowedToCreate);
 });
-
-const toggleForm = () => {
-    showForm.value = !showForm.value;
-};
 </script>
 
 <template>
@@ -41,7 +43,7 @@ const toggleForm = () => {
     >
         <template v-if="isAllowedToCreate" #append>
             <QIcon
-                @click.stop.prevent="toggleForm()"
+                @click.stop.prevent="$refs.dialog.show()"
                 :name="actionIcon"
                 :size="actionIcon === 'add' ? 'xs' : 'sm'"
                 :class="['default-icon', { '--add-icon': actionIcon === 'add' }]"
@@ -51,7 +53,7 @@ const toggleForm = () => {
             >
                 <QTooltip v-if="tooltip">{{ tooltip }}</QTooltip>
             </QIcon>
-            <QDialog v-model="showForm" transition-show="scale" transition-hide="scale">
+            <QDialog ref="dialog" transition-show="scale" transition-hide="scale">
                 <slot name="form" />
             </QDialog>
         </template>
diff --git a/src/components/ui/CatalogItem.vue b/src/components/ui/CatalogItem.vue
index ef722483b..545bfbbb4 100644
--- a/src/components/ui/CatalogItem.vue
+++ b/src/components/ui/CatalogItem.vue
@@ -127,11 +127,6 @@ const dialog = ref(null);
     flex-direction: column;
     gap: 4px;
 
-    .subName {
-        color: var(--vn-label-color);
-        text-transform: uppercase;
-    }
-
     p {
         margin-bottom: 0;
     }
diff --git a/src/components/ui/FetchedTags.vue b/src/components/ui/FetchedTags.vue
index beaa85bfe..a0edf85f8 100644
--- a/src/components/ui/FetchedTags.vue
+++ b/src/components/ui/FetchedTags.vue
@@ -2,10 +2,6 @@
 import { computed } from 'vue';
 
 const $props = defineProps({
-    maxLength: {
-        type: Number,
-        required: true,
-    },
     item: {
         type: Object,
         required: true,
diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue
index 0480650db..4fa374b62 100644
--- a/src/components/ui/VnConfirm.vue
+++ b/src/components/ui/VnConfirm.vue
@@ -15,7 +15,7 @@ const props = defineProps({
         default: null,
     },
     message: {
-        type: String,
+        type: [String, Boolean],
         default: null,
     },
     data: {
@@ -31,11 +31,15 @@ const props = defineProps({
 });
 
 defineEmits(['confirm', ...useDialogPluginComponent.emits]);
+defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() });
 
 const { dialogRef, onDialogOK } = useDialogPluginComponent();
 
 const title = props.title || t('Confirm');
-const message = props.message || t('Are you sure you want to continue?');
+const message =
+    props.message ||
+    (props.message !== false ? t('Are you sure you want to continue?') : false);
+
 const isLoading = ref(false);
 
 async function confirm() {
@@ -61,12 +65,14 @@ async function confirm() {
                     size="xl"
                     v-if="icon"
                 />
-                <span class="text-h6 text-grey">{{ title }}</span>
+                <span class="text-h6">{{ title }}</span>
                 <QSpace />
                 <QBtn icon="close" :disable="isLoading" flat round dense v-close-popup />
             </QCardSection>
-            <QCardSection class="row items-center">
-                <span v-html="message"></span>
+            <QCardSection class="q-pb-none">
+                <span v-if="message !== false" v-html="message" />
+            </QCardSection>
+            <QCardSection class="row items-center q-pt-none">
                 <slot name="customHTML"></slot>
             </QCardSection>
             <QCardActions align="right">
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
index e3019663c..637180c22 100644
--- a/src/components/ui/VnFilterPanel.vue
+++ b/src/components/ui/VnFilterPanel.vue
@@ -3,6 +3,7 @@ import { onMounted, ref, computed, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useArrayData } from 'composables/useArrayData';
 import { useRoute } from 'vue-router';
+import { date } from 'quasar';
 import toDate from 'filters/toDate';
 import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
 
@@ -24,7 +25,7 @@ const $props = defineProps({
         type: Boolean,
         default: true,
     },
-    unRemovableParams: {
+    unremovableParams: {
         type: Array,
         required: false,
         default: () => [],
@@ -92,16 +93,18 @@ function setUserParams(watchedParams) {
     const order = watchedParams.filter?.order;
 
     delete watchedParams.filter;
-    userParams.value = { ...userParams.value, ...sanitizer(watchedParams) };
+    userParams.value = sanitizer(watchedParams);
     emit('setUserParams', userParams.value, order);
 }
 
 watch(
-    () => [route.query[$props.searchUrl], arrayData.store.userParams],
-    ([newSearchUrl, newUserParams], [oldSearchUrl, oldUserParams]) => {
-        if (newSearchUrl || oldSearchUrl) setUserParams(newSearchUrl);
-        if (newUserParams || oldUserParams) setUserParams(newUserParams);
-    }
+    () => route.query[$props.searchUrl],
+    (val, oldValue) => (val || oldValue) && setUserParams(val)
+);
+
+watch(
+    () => arrayData.store.userParams,
+    (val, oldValue) => (val || oldValue) && setUserParams(val)
 );
 
 watch(
@@ -111,58 +114,51 @@ watch(
 
 const isLoading = ref(false);
 async function search(evt) {
-    if (evt && $props.disableSubmitEvent) return;
+    try {
+        if (evt && $props.disableSubmitEvent) return;
 
-    store.filter.where = {};
-    isLoading.value = true;
-    const filter = { ...userParams.value, ...$props.modelValue };
-    store.userParamsChanged = true;
-    const { params: newParams } = await arrayData.addFilter({
-        params: filter,
-    });
-    userParams.value = newParams;
+        store.filter.where = {};
+        isLoading.value = true;
+        const filter = { ...userParams.value, ...$props.modelValue };
+        store.userParamsChanged = true;
+        const { params: newParams } = await arrayData.addFilter({
+            params: filter,
+        });
+        userParams.value = newParams;
 
-    if (!$props.showAll && !Object.values(filter).length) store.data = [];
-
-    isLoading.value = false;
-    emit('search');
-}
-
-async function reload() {
-    isLoading.value = true;
-    const params = Object.values(userParams.value).filter((param) => param);
-    store.skip = 0;
-    store.page = 1;
-    await arrayData.fetch({ append: false });
-    if (!$props.showAll && !params.length) store.data = [];
-    isLoading.value = false;
-    emit('refresh');
+        if (!$props.showAll && !Object.values(filter).length) store.data = [];
+        emit('search');
+    } finally {
+        isLoading.value = false;
+    }
 }
 
 async function clearFilters() {
-    isLoading.value = true;
-    store.userParamsChanged = true;
-    arrayData.reset(['skip', 'filter.skip', 'page']);
-    // Filtrar los params no removibles
-    const removableFilters = Object.keys(userParams.value).filter((param) =>
-        $props.unRemovableParams.includes(param)
-    );
-    const newParams = {};
-    // Conservar solo los params que no son removibles
-    for (const key of removableFilters) {
-        newParams[key] = userParams.value[key];
-    }
-    userParams.value = {};
-    userParams.value = { ...newParams }; // Actualizar los params con los removibles
-    await arrayData.applyFilter({ params: userParams.value });
+    try {
+        isLoading.value = true;
+        store.userParamsChanged = true;
+        arrayData.reset(['skip', 'filter.skip', 'page']);
+        // Filtrar los params no removibles
+        const removableFilters = Object.keys(userParams.value).filter((param) =>
+            $props.unremovableParams.includes(param)
+        );
+        const newParams = {};
+        // Conservar solo los params que no son removibles
+        for (const key of removableFilters) {
+            newParams[key] = userParams.value[key];
+        }
+        userParams.value = {};
+        userParams.value = { ...newParams }; // Actualizar los params con los removibles
+        await arrayData.applyFilter({ params: userParams.value });
 
-    if (!$props.showAll) {
-        store.data = [];
+        if (!$props.showAll) {
+            store.data = [];
+        }
+        emit('clear');
+        emit('update:modelValue', userParams.value);
+    } finally {
+        isLoading.value = false;
     }
-
-    isLoading.value = false;
-    emit('clear');
-    emit('update:modelValue', userParams.value);
 }
 
 const tagsList = computed(() => {
@@ -176,10 +172,10 @@ const tagsList = computed(() => {
 });
 
 const tags = computed(() => {
-    return tagsList.value.filter((tag) => !($props.customTags || []).includes(tag.key));
+    return tagsList.value.filter((tag) => !($props.customTags || []).includes(tag.label));
 });
 const customTags = computed(() =>
-    tagsList.value.filter((tag) => ($props.customTags || []).includes(tag.key))
+    tagsList.value.filter((tag) => ($props.customTags || []).includes(tag.label))
 );
 
 async function remove(key) {
@@ -190,6 +186,7 @@ async function remove(key) {
 }
 
 function formatValue(value) {
+    if (value instanceof Date) return date.formatDate(value, 'DD/MM/YYYY');
     if (typeof value === 'boolean') return value ? t('Yes') : t('No');
     if (isNaN(value) && !isNaN(Date.parse(value))) return toDate(value);
 
@@ -198,7 +195,7 @@ function formatValue(value) {
 
 function sanitizer(params) {
     for (const [key, value] of Object.entries(params)) {
-        if (typeof value == 'object') {
+        if (value && typeof value === 'object') {
             const param = Object.values(value)[0];
             if (typeof param == 'string') params[key] = param.replaceAll('%', '');
         }
@@ -225,32 +222,18 @@ function sanitizer(params) {
                     </QItemLabel>
                 </QItemSection>
                 <QItemSection top side>
-                    <div class="q-gutter-xs">
-                        <QBtn
-                            @click="clearFilters"
-                            color="primary"
-                            dense
-                            flat
-                            icon="filter_list_off"
-                            padding="none"
-                            round
-                            size="sm"
-                        >
-                            <QTooltip>{{ t('Remove filters') }}</QTooltip>
-                        </QBtn>
-                        <QBtn
-                            @click="reload"
-                            color="primary"
-                            dense
-                            flat
-                            icon="refresh"
-                            padding="none"
-                            round
-                            size="sm"
-                        >
-                            <QTooltip>{{ t('Refresh') }}</QTooltip>
-                        </QBtn>
-                    </div>
+                    <QBtn
+                        @click="clearFilters"
+                        color="primary"
+                        dense
+                        flat
+                        icon="filter_list_off"
+                        padding="none"
+                        round
+                        size="sm"
+                    >
+                        <QTooltip>{{ t('Remove filters') }}</QTooltip>
+                    </QBtn>
                 </QItemSection>
             </QItem>
             <QItem class="q-mb-sm">
@@ -264,7 +247,7 @@ function sanitizer(params) {
                     <VnFilterPanelChip
                         v-for="chip of tags"
                         :key="chip.label"
-                        :removable="!unRemovableParams.includes(chip.label)"
+                        :removable="!unremovableParams?.includes(chip.label)"
                         @remove="remove(chip.label)"
                     >
                         <slot name="tags" :tag="chip" :format-fn="formatValue">
diff --git a/src/components/ui/VnImg.vue b/src/components/ui/VnImg.vue
index 9585b81d8..ceb4e8468 100644
--- a/src/components/ui/VnImg.vue
+++ b/src/components/ui/VnImg.vue
@@ -39,6 +39,8 @@ const getUrl = (zoom = false) => {
     const curResolution = zoom
         ? $props.zoomResolution || $props.resolution
         : $props.resolution;
+    if ($props.storage === 'dms')
+        return `/api/${$props.storage}/${$props.id}/downloadFile?access_token=${token}`;
     return isEmployee
         ? `/api/${$props.storage}/${$props.collection}/${curResolution}/${$props.id}/download?access_token=${token}&${timeStamp.value}`
         : noImage;
@@ -52,6 +54,7 @@ defineExpose({
 </script>
 <template>
     <QImg
+        :draggable="true"
         :class="{ zoomIn: zoom }"
         :src="getUrl()"
         v-bind="$attrs"
@@ -60,10 +63,12 @@ defineExpose({
     />
     <QDialog v-if="$props.zoom" v-model="show">
         <QImg
+            :draggable="true"
             :src="getUrl(true)"
             v-bind="$attrs"
             spinner-color="primary"
             class="img_zoom"
+            :ratio="0"
         />
     </QDialog>
 </template>
diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue
index 0df719c66..79a79c383 100644
--- a/src/components/ui/VnPaginate.vue
+++ b/src/components/ui/VnPaginate.vue
@@ -10,6 +10,10 @@ const props = defineProps({
         type: String,
         required: true,
     },
+    class: {
+        type: String,
+        default: '',
+    },
     autoLoad: {
         type: Boolean,
         default: false,
@@ -115,8 +119,8 @@ watch(
 );
 
 watch(
-    () => [props.url, props.filter],
-    ([url, filter]) => mounted.value && fetch({ url, filter })
+    () => [props.url, props.filter, props.userParams],
+    ([url, filter, userParams]) => mounted.value && fetch({ url, filter, userParams })
 );
 
 const addFilter = async (filter, params) => {
@@ -215,18 +219,25 @@ defineExpose({ fetch, addFilter, paginate });
         v-if="store.data"
         @load="onLoad"
         :offset="offset"
-        class="full-width"
+        :class="['full-width', props.class]"
         :disable="disableInfiniteScroll || !store.hasMoreData"
         v-bind="$attrs"
     >
         <slot name="body" :rows="store.data"></slot>
-        <div v-if="isLoading" class="info-row q-pa-md text-center">
+        <div v-if="isLoading" class="spinner info-row q-pa-md text-center">
             <QSpinner color="primary" size="md" />
         </div>
     </QInfiniteScroll>
 </template>
 
 <style lang="scss" scoped>
+.spinner {
+    z-index: 1;
+    align-content: end;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+}
 .info-row {
     width: 100%;
 
diff --git a/src/components/ui/VnRow.vue b/src/components/ui/VnRow.vue
index 5c01d7216..16bcfab7d 100644
--- a/src/components/ui/VnRow.vue
+++ b/src/components/ui/VnRow.vue
@@ -1,3 +1,6 @@
+<script setup>
+defineProps({ wrap: { type: Boolean, default: false } });
+</script>
 <template>
     <div class="vn-row q-gutter-md q-mb-md">
         <slot />
@@ -9,10 +12,15 @@
     > :deep(*) {
         flex: 1;
     }
+    &[wrap] {
+        flex-wrap: wrap;
+    }
 }
 @media screen and (max-width: 800px) {
     .vn-row {
-        flex-direction: column;
+        &:not(.wrap) {
+            flex-direction: column;
+        }
     }
 }
 </style>
diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue
index 2053efd62..a78403b5c 100644
--- a/src/components/ui/VnSearchbar.vue
+++ b/src/components/ui/VnSearchbar.vue
@@ -63,17 +63,13 @@ const props = defineProps({
         type: String,
         default: '',
     },
-    makeFetch: {
-        type: Boolean,
-        default: true,
-    },
-    searchUrl: {
-        type: String,
-        default: 'params',
+    whereFilter: {
+        type: Function,
+        default: undefined,
     },
 });
 
-const searchText = ref('');
+const searchText = ref();
 let arrayDataProps = { ...props };
 if (props.redirect)
     arrayDataProps = {
@@ -104,18 +100,23 @@ onMounted(() => {
 });
 
 async function search() {
-    const staticParams = Object.entries(store.userParams).filter(
-        ([key, value]) => value && (props.staticParams || []).includes(key)
-    );
+    const staticParams = Object.entries(store.userParams);
     arrayData.reset(['skip', 'page']);
 
-    if (props.makeFetch)
-        await arrayData.applyFilter({
-            params: {
-                ...Object.fromEntries(staticParams),
-                search: searchText.value,
-            },
-        });
+    const filter = {
+        params: {
+            ...Object.fromEntries(staticParams),
+            search: searchText.value,
+        },
+    };
+
+    if (props.whereFilter) {
+        filter.filter = {
+            where: props.whereFilter(searchText.value),
+        };
+        delete filter.params.search;
+    }
+    await arrayData.applyFilter(filter);
 }
 </script>
 <template>
@@ -123,7 +124,7 @@ async function search() {
         <QForm @submit="search" id="searchbarForm">
             <VnInput
                 id="searchbar"
-                v-model="searchText"
+                v-model.trim="searchText"
                 :placeholder="t(props.label)"
                 dense
                 standout
diff --git a/src/components/ui/VnSms.vue b/src/components/ui/VnSms.vue
index 81058a6cb..bf6e0695e 100644
--- a/src/components/ui/VnSms.vue
+++ b/src/components/ui/VnSms.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { watch, computed } from 'vue';
+import { computed } from 'vue';
 import { date } from 'quasar';
 import VnPaginate from 'src/components/ui/VnPaginate.vue';
 import VnAvatar from '../ui/VnAvatar.vue';
diff --git a/src/components/ui/VnSubToolbar.vue b/src/components/ui/VnSubToolbar.vue
index 5e2412437..5ded4be00 100644
--- a/src/components/ui/VnSubToolbar.vue
+++ b/src/components/ui/VnSubToolbar.vue
@@ -43,20 +43,9 @@ onBeforeUnmount(() => stateStore.toggleSubToolbar());
         </slot>
     </QToolbar>
 </template>
-<style lang="scss">
-.q-toolbar {
-    background: var(--vn-section-color);
-}
-</style>
 <style lang="scss" scoped>
 .sticky {
     position: sticky;
-    top: 61px;
     z-index: 1;
 }
-@media (max-width: $breakpoint-sm) {
-    .sticky {
-        top: 90px;
-    }
-}
 </style>
diff --git a/src/components/ui/VnUserLink.vue b/src/components/ui/VnUserLink.vue
index b04ea7476..00c50ee34 100644
--- a/src/components/ui/VnUserLink.vue
+++ b/src/components/ui/VnUserLink.vue
@@ -1,20 +1,18 @@
 <script setup>
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
-import { useI18n } from 'vue-i18n';
 
-const $props = defineProps({
+defineProps({
     name: { type: String, default: null },
+    tag: { type: String, default: null },
     workerId: { type: Number, default: null },
     defaultName: { type: Boolean, default: false },
 });
-
-const { t } = useI18n();
 </script>
 <template>
     <slot name="link">
-        <span :class="{ link: $props.workerId }">
-            {{ $props.defaultName ? $props.name ?? t('globals.system') : $props.name }}
+        <span :class="{ link: workerId }">
+            {{ defaultName ? name ?? $t('globals.system') : name }}
         </span>
     </slot>
-    <WorkerDescriptorProxy v-if="$props.workerId" :id="$props.workerId" />
+    <WorkerDescriptorProxy v-if="workerId" :id="workerId" />
 </template>
diff --git a/src/composables/getDateQBadgeColor.js b/src/composables/getDateQBadgeColor.js
index be9ef41b5..a91213a0a 100644
--- a/src/composables/getDateQBadgeColor.js
+++ b/src/composables/getDateQBadgeColor.js
@@ -7,5 +7,5 @@ export function getDateQBadgeColor(date) {
     let comparation = today - timeTicket;
 
     if (comparation == 0) return 'warning';
-    if (comparation < 0) return 'negative';
+    if (comparation < 0) return 'success';
 }
diff --git a/src/composables/getTotal.js b/src/composables/getTotal.js
new file mode 100644
index 000000000..41c4330c4
--- /dev/null
+++ b/src/composables/getTotal.js
@@ -0,0 +1,10 @@
+import { toCurrency } from 'src/filters';
+
+export function getTotal(rows, key, opts = {}) {
+    const { currency, cb } = opts;
+    const total = rows.reduce((acc, row) => acc + +(cb ? cb(row) : row[key] || 0), 0);
+
+    return currency
+        ? toCurrency(total, currency == 'default' ? undefined : currency)
+        : total;
+}
diff --git a/src/composables/useAcl.js b/src/composables/useAcl.js
index 46aaa3c25..ede359186 100644
--- a/src/composables/useAcl.js
+++ b/src/composables/useAcl.js
@@ -16,13 +16,18 @@ export function useAcl() {
         state.setAcls(acls);
     }
 
-    function hasAny(model, prop, accessType) {
-        const acls = state.getAcls().value[model];
-        if (acls) 
-            return ['*', prop].some((key) => {
-                const acl = acls[key];
-                return acl && (acl['*'] || acl[accessType]);
-            });
+    function hasAny(acls) {
+        for (const acl of acls) {
+            let { model, props, accessType } = acl;
+            const modelAcls = state.getAcls().value[model];
+            Array.isArray(props) || (props = [props]);
+            if (modelAcls)
+                return ['*', ...props].some((key) => {
+                    const acl = modelAcls[key];
+                    return acl && (acl['*'] || acl[accessType]);
+                });
+        }
+        return false;
     }
 
     return {
diff --git a/src/composables/usePrintService.js b/src/composables/usePrintService.js
index edf9598b2..68a009d7b 100644
--- a/src/composables/usePrintService.js
+++ b/src/composables/usePrintService.js
@@ -16,7 +16,8 @@ export function usePrintService() {
         );
     }
 
-    function openReport(path, params) {
+    function openReport(path, params, isNewTab = '_self') {
+        if (typeof params === 'string') params = JSON.parse(params);
         params = Object.assign(
             {
                 access_token: getTokenMultimedia(),
@@ -25,8 +26,7 @@ export function usePrintService() {
         );
 
         const query = new URLSearchParams(params).toString();
-
-        window.open(`api/${path}?${query}`);
+        window.open(`api/${path}?${query}`, isNewTab);
     }
 
     return {
diff --git a/src/composables/useValidator.js b/src/composables/useValidator.js
index 5ad96ea1b..7a7032608 100644
--- a/src/composables/useValidator.js
+++ b/src/composables/useValidator.js
@@ -28,7 +28,7 @@ export function useValidator() {
     }
 
     const { t } = useI18n();
-    const validations = function (validation) {
+    const validations = function (validation = {}) {
         return {
             format: (value) => {
                 const { allowNull, with: format, allowBlank } = validation;
@@ -40,12 +40,15 @@ export function useValidator() {
                 if (!isValid) return message;
             },
             presence: (value) => {
-                let message = `Value can't be empty`;
+                let message = t(`globals.valueCantBeEmpty`);
                 if (validation.message)
                     message = t(validation.message) || validation.message;
 
                 return !validator.isEmpty(value ? String(value) : '') || message;
             },
+            required: (required, value) => {
+                return required ? !!value || t('globals.fieldRequired') : null;
+            },
             length: (value) => {
                 const options = {
                     min: validation.min || validation.is,
@@ -71,12 +74,17 @@ export function useValidator() {
                     return validator.isInt(value) || 'Value should be integer';
                 return validator.isNumeric(value) || 'Value should be a number';
             },
+            min: (value, min) => {
+                if (min >= 0)
+                    if (Math.floor(value) < min) return t('inputMin', { value: min });
+            },
             custom: (value) => validation.bindedFunction(value) || 'Invalid value',
         };
     };
 
     return {
         validate,
+        validations,
         models,
     };
 }
diff --git a/src/css/app.scss b/src/css/app.scss
index 3efe92db4..3c51dc8af 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -37,6 +37,10 @@ a {
 .link {
     color: $color-link;
     cursor: pointer;
+
+    &--white {
+        color: white;
+    }
 }
 
 .tx-color-link {
@@ -103,10 +107,6 @@ select:-webkit-autofill {
     border-radius: 8px;
 }
 
-.card-width {
-    width: 770px;
-}
-
 .vn-card-list {
     width: 100%;
     max-width: 60em;
@@ -190,6 +190,10 @@ select:-webkit-autofill {
     font-size: medium;
 }
 
+.q-toolbar {
+    background: var(--vn-section-color);
+}
+
 .q-card__actions {
     justify-content: center;
 }
@@ -264,3 +268,15 @@ input::-webkit-inner-spin-button {
         max-width: 400px;
     }
 }
+.edit-photo-btn {
+    position: absolute;
+    right: 12px;
+    bottom: 12px;
+    z-index: 1;
+    cursor: pointer;
+}
+
+.subName {
+    color: var(--vn-label-color);
+    text-transform: uppercase;
+}
diff --git a/src/filters/date.js b/src/filters/date.js
index f9fd1e0b2..058c90060 100644
--- a/src/filters/date.js
+++ b/src/filters/date.js
@@ -20,21 +20,21 @@ export function isValidDate(date) {
  * Converts a given date to a specific format.
  *
  * @param {number|string|Date} date - The date to be formatted.
+ * @param {Object} opts - Optional parameters to customize the output format.
  * @returns {string} The formatted date as a string in 'dd/mm/yyyy' format. If the provided date is not valid, an empty string is returned.
  *
  * @example
  * // returns "02/12/2022"
  * toDateFormat(new Date(2022, 11, 2));
  */
-export function toDateFormat(date, locale = 'es-ES') {
-    if (!isValidDate(date)) {
-        return '';
-    }
-    return new Date(date).toLocaleDateString(locale, {
-        year: 'numeric',
-        month: '2-digit',
-        day: '2-digit',
-    });
+export function toDateFormat(date, locale = 'es-ES', opts = {}) {
+    if (!isValidDate(date)) return '';
+
+    const format = Object.assign(
+        { year: 'numeric', month: '2-digit', day: '2-digit' },
+        opts
+    );
+    return new Date(date).toLocaleDateString(locale, format);
 }
 
 /**
diff --git a/src/filters/dateRange.js b/src/filters/dateRange.js
index 7aa2869e5..4c0cfe654 100644
--- a/src/filters/dateRange.js
+++ b/src/filters/dateRange.js
@@ -1,7 +1,7 @@
 export default function dateRange(value) {
     const minHour = new Date(value);
     minHour.setHours(0, 0, 0, 0);
-    const maxHour = new Date();
+    const maxHour = new Date(value);
     maxHour.setHours(23, 59, 59, 59);
 
     return [minHour, maxHour];
diff --git a/src/filters/getParamWhere.js b/src/filters/getParamWhere.js
new file mode 100644
index 000000000..48cd9c479
--- /dev/null
+++ b/src/filters/getParamWhere.js
@@ -0,0 +1,21 @@
+// parsing JSON safely
+function parseJSON(str, fallback) {
+    try {
+        return JSON.parse(str ?? '{}');
+    } catch (e) {
+        console.error('Error parsing JSON:', e);
+        return fallback;
+    }
+}
+export default function (route, param) {
+    // catch route query params
+    const params = parseJSON(route?.query?.params, {});
+
+    // extract and parse filter from params
+    const { filter: filterStr = '{}' } = params;
+    const where = parseJSON(filterStr, {})?.where;
+    if (where && where[param] !== undefined) {
+        return where[param];
+    }
+    return null;
+}
diff --git a/src/filters/index.js b/src/filters/index.js
index 940788ed1..5f08f19c7 100644
--- a/src/filters/index.js
+++ b/src/filters/index.js
@@ -11,6 +11,7 @@ import dashIfEmpty from './dashIfEmpty';
 import dateRange from './dateRange';
 import toHour from './toHour';
 import dashOrCurrency from './dashOrCurrency';
+import getParamWhere from './getParamWhere';
 
 export {
     toLowerCase,
@@ -26,4 +27,5 @@ export {
     toPercentage,
     dashIfEmpty,
     dateRange,
+    getParamWhere,
 };
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index f61dda8a4..c792c8315 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -2,6 +2,7 @@ globals:
     lang:
         es: Spanish
         en: English
+    quantity: Quantity
     language: Language
     entity: Entity
     user: User
@@ -40,6 +41,8 @@ globals:
     noChanges: No changes to save
     changesToSave: You have changes pending to save
     confirmRemove: You are about to delete this row. Are you sure?
+    rowWillBeRemoved: This row will be removed
+    sureToContinue: Are you sure you want to continue?
     rowAdded: Row added
     rowRemoved: Row removed
     pleaseWait: Please wait...
@@ -67,6 +70,7 @@ globals:
     allRows: 'All { numberRows } row(s)'
     markAll: Mark all
     requiredField: Required field
+    valueCantBeEmpty: Value cannot be empty
     class: clase
     type: Type
     reason: reason
@@ -83,7 +87,7 @@ globals:
     description: Description
     id: Id
     order: Order
-    original: Original
+    original: Phys. Doc
     file: File
     selectFile: Select a file
     copyClipboard: Copy on clipboard
@@ -93,6 +97,12 @@ globals:
     since: Since
     from: From
     to: To
+    notes: Notes
+    refresh: Refresh
+    item: Item
+    ticket: Ticket
+    campaign: Campaign
+    weight: Weight
     pageTitles:
         logIn: Login
         addressEdit: Update address
@@ -120,9 +130,11 @@ globals:
         notifications: Notifications
         defaulter: Defaulter
         customerCreate: New customer
+        createOrder: New order
         fiscalData: Fiscal data
         billingData: Billing data
         consignees: Consignees
+        'address-create': New address
         notes: Notes
         credits: Credits
         greuges: Greuges
@@ -255,6 +267,11 @@ globals:
         twoFactor: Two factor
         recoverPassword: Recover password
         resetPassword: Reset password
+        ticketsMonitor: Tickets monitor
+        clientsActionsMonitor: Clients and actions
+        serial: Serial
+        medical: Mutual
+    supplier: Supplier
     created: Created
     worker: Worker
     now: Now
@@ -267,6 +284,8 @@ globals:
         title: Unsaved changes will be lost
         subtitle: Are you sure exit without saving?
     createInvoiceIn: Create invoice in
+    myAccount: My account
+    noOne: No one
 errors:
     statusUnauthorized: Access denied
     statusInternalServerError: An internal server error has ocurred
@@ -303,135 +322,6 @@ resetPassword:
     repeatPassword: Repeat password
     passwordNotMatch: Passwords don't match
     passwordChanged: Password changed
-customer:
-    list:
-        phone: Phone
-        email: Email
-        customerOrders: Display customer orders
-        moreOptions: More options
-    card:
-        customerList: Customer list
-        customerId: Claim ID
-        salesPerson: Sales person
-        credit: Credit
-        risk: Risk
-        securedCredit: Secured credit
-        payMethod: Pay method
-        debt: Debt
-        isFrozen: Customer frozen
-        hasDebt: Customer has debt
-        isDisabled: Customer inactive
-        notChecked: Customer no checked
-        webAccountInactive: Web account inactive
-        noWebAccess: Web access is disabled
-        businessType: Business type
-        passwordRequirements: 'The password must have at least { length } length characters, {nAlpha} alphabetic characters, {nUpper} capital letters, {nDigits} digits and {nPunct} symbols (Ex: $%&.)\n'
-        businessTypeFk: Business type
-    summary:
-        basicData: Basic data
-        fiscalAddress: Fiscal address
-        fiscalData: Fiscal data
-        billingData: Billing data
-        consignee: Default consignee
-        businessData: Business data
-        financialData: Financial data
-        customerId: Customer ID
-        name: Name
-        contact: Contact
-        phone: Phone
-        mobile: Mobile
-        email: Email
-        salesPerson: Sales person
-        contactChannel: Contact channel
-        socialName: Social name
-        fiscalId: Fiscal ID
-        postcode: Postcode
-        province: Province
-        country: Country
-        street: Address
-        isEqualizated: Is equalizated
-        isActive: Is active
-        invoiceByAddress: Invoice by address
-        verifiedData: Verified data
-        hasToInvoice: Has to invoice
-        notifyByEmail: Notify by email
-        vies: VIES
-        payMethod: Pay method
-        bankAccount: Bank account
-        dueDay: Due day
-        hasLcr: Has LCR
-        hasCoreVnl: Has core VNL
-        hasB2BVnl: Has B2B VNL
-        addressName: Address name
-        addressCity: City
-        addressStreet: Street
-        username: Username
-        webAccess: Web access
-        totalGreuge: Total greuge
-        mana: Mana
-        priceIncreasingRate: Price increasing rate
-        averageInvoiced: Average invoiced
-        claimRate: Claming rate
-        risk: Risk
-        riskInfo: Invoices minus payments plus orders not yet invoiced
-        credit: Credit
-        creditInfo: Company's maximum risk
-        securedCredit: Secured credit
-        securedCreditInfo: Solunion's maximum risk
-        balance: Balance
-        balanceInfo: Invoices minus payments
-        balanceDue: Balance due
-        balanceDueInfo: Deviated invoices minus payments
-        recoverySince: Recovery since
-        businessType: Business Type
-        city: City
-        descriptorInfo: Invoices minus payments plus orders not yet
-        rating: Rating
-        recommendCredit: Recommended credit
-    basicData:
-        socialName: Fiscal name
-        businessType: Business type
-        contact: Contact
-        youCanSaveMultipleEmails: You can save multiple emails
-        email: Email
-        phone: Phone
-        mobile: Mobile
-        salesPerson: Sales person
-        contactChannel: Contact channel
-        previousClient: Previous client
-    extendedList:
-        tableVisibleColumns:
-            id: Identifier
-            name: Name
-            socialName: Social name
-            fi: Tax number
-            salesPersonFk: Salesperson
-            credit: Credit
-            creditInsurance: Credit insurance
-            phone: Phone
-            mobile: Mobile
-            street: Street
-            countryFk: Country
-            provinceFk: Province
-            city: City
-            postcode: Postcode
-            email: Email
-            created: Created
-            businessTypeFk: Business type
-            payMethodFk: Billing data
-            sageTaxTypeFk: Sage tax type
-            sageTransactionTypeFk: Sage tr. type
-            isActive: Active
-            isVies: Vies
-            isTaxDataChecked: Verified data
-            isEqualizated: Is equalizated
-            isFreezed: Freezed
-            hasToInvoice: Invoice
-            hasToInvoiceByAddress: Invoice by address
-            isToBeMailed: Mailing
-            hasLcr: Received LCR
-            hasCoreVnl: VNL core received
-            hasSepaVnl: VNL B2B received
 entry:
     list:
         newEntry: New entry
@@ -453,6 +343,7 @@ entry:
             travelFk: Travel
             isExcludedFromAvailable: Inventory
             isRaid: Raid
+            invoiceAmount: Import
     summary:
         commission: Commission
         currency: Currency
@@ -689,6 +580,7 @@ invoiceOut:
             chooseValidClient: Choose a valid client
             chooseValidCompany: Choose a valid company
             chooseValidPrinter: Choose a valid printer
+            chooseValidSerialType: Choose a serial type
             fillDates: Invoice date and the max date should be filled
             invoiceDateLessThanMaxDate: Invoice date can not be less than max date
             invoiceWithFutureDate: Exists an invoice with a future date
@@ -743,56 +635,6 @@ parking:
     searchBar:
         info: You can search by parking code
         label: Search parking...
-invoiceIn:
-    list:
-        ref: Reference
-        supplier: Supplier
-        supplierRef: Supplier ref.
-        serialNumber: Serial number
-        serial: Serial
-        file: File
-        issued: Issued
-        isBooked: Is booked
-        awb: AWB
-        amount: Amount
-    card:
-        issued: Issued
-        amount: Amount
-        client: Client
-        company: Company
-        customerCard: Customer card
-        ticketList: Ticket List
-        vat: Vat
-        dueDay: Due day
-        intrastat: Intrastat
-    summary:
-        supplier: Supplier
-        supplierRef: Supplier ref.
-        currency: Currency
-        docNumber: Doc number
-        issued: Expedition date
-        operated: Operation date
-        bookEntried: Entry date
-        bookedDate: Booked date
-        sage: Sage withholding
-        vat: Undeductible VAT
-        company: Company
-        booked: Booked
-        expense: Expense
-        taxableBase: Taxable base
-        rate: Rate
-        sageVat: Sage vat
-        sageTransaction: Sage transaction
-        dueDay: Date
-        bank: Bank
-        amount: Amount
-        foreignValue: Foreign value
-        dueTotal: Due day
-        noMatch: Do not match
-        code: Code
-        net: Net
-        stems: Stems
-        country: Country
 order:
     field:
         salesPersonFk: Sales Person
@@ -869,6 +711,7 @@ worker:
         timeControl: Time control
         locker: Locker
         balance: Balance
+        medical: Medical
     list:
         name: Name
         email: Email
@@ -880,6 +723,7 @@ worker:
         newWorker: New worker
     card:
         workerId: Worker ID
+        user: User
         name: Name
         email: Email
         phone: Phone
@@ -948,6 +792,15 @@ worker:
             amount: Importe
             remark: Bonficado
             hasDiploma: Diploma
+    medical:
+        tableVisibleColumns:
+            date: Date
+            time: Hour
+            center: Formation Center
+            invoice: Invoice
+            amount: Amount
+            isFit: Fit
+            remark: Observations
     imageNotFound: Image not found
     balance:
         tableVisibleColumns:
@@ -957,6 +810,16 @@ worker:
             credit: Have
             concept: Concept
 wagon:
+    pageTitles:
+        wagons: Wagons
+        wagonsList: Wagons List
+        wagonCreate: Create wagon
+        wagonEdit: Edit wagon
+        typesList: Types List
+        typeCreate: Create type
+        typeEdit: Edit type
+        wagonCounter: Trolley counter
+        wagonTray: Tray List
     type:
         name: Name
         submit: Submit
@@ -1120,9 +983,12 @@ travel:
             agency: Agency
             shipped: Shipped
             landed: Landed
+            shipHour: Shipment Hour
+            landHour: Landing Hour
             warehouseIn: Warehouse in
             warehouseOut: Warehouse out
             totalEntries: Total entries
+            totalEntriesTooltip: Total entries
     summary:
         confirmed: Confirmed
         entryId: Entry Id
@@ -1275,6 +1141,7 @@ components:
         active: Is active
         visible: Is visible
         floramondo: Is floramondo
+        showBadDates: Show future items
     userPanel:
         copyToken: Token copied to clipboard
         settings: Settings
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index 4e71a69fb..91ece1b2c 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -3,6 +3,7 @@ globals:
         es: Español
         en: Inglés
     language: Idioma
+    quantity: Cantidad
     entity: Entidad
     user: Usuario
     details: Detalles
@@ -39,6 +40,8 @@ globals:
     noChanges: Sin cambios que guardar
     changesToSave: Tienes cambios pendientes de guardar
     confirmRemove: Vas a eliminar este registro. ¿Continuar?
+    rowWillBeRemoved: Esta linea se eliminará
+    sureToContinue: ¿Seguro que quieres continuar?
     rowAdded: Fila añadida
     rowRemoved: Fila eliminada
     pleaseWait: Por favor espera...
@@ -76,6 +79,9 @@ globals:
     warehouse: Almacén
     company: Empresa
     fieldRequired: Campo requerido
+    valueCantBeEmpty: El valor no puede estar vacío
+    Value can't be blank: El valor no puede estar en blanco
+    Value can't be null: El valor no puede ser nulo
     allowedFilesText: 'Tipos de archivo permitidos: { allowedContentTypes }'
     smsSent: SMS enviado
     confirmDeletion: Confirmar eliminación
@@ -83,7 +89,7 @@ globals:
     description: Descripción
     id: Id
     order: Orden
-    original: Original
+    original: Doc. física
     file: Fichero
     selectFile: Seleccione un fichero
     copyClipboard: Copiar en portapapeles
@@ -93,6 +99,12 @@ globals:
     since: Desde
     from: Desde
     to: Hasta
+    notes: Notas
+    refresh: Actualizar
+    item: Artículo
+    ticket: Ticket
+    campaign: Campaña
+    weight: Peso
     pageTitles:
         logIn: Inicio de sesión
         addressEdit: Modificar consignatario
@@ -115,6 +127,7 @@ globals:
         inheritedRoles: Roles heredados
         customers: Clientes
         customerCreate: Nuevo cliente
+        createOrder: Nuevo pedido
         list: Listado
         webPayments: Pagos Web
         extendedList: Listado extendido
@@ -124,6 +137,7 @@ globals:
         fiscalData: Datos fiscales
         billingData: Forma de pago
         consignees: Consignatarios
+        'address-create': Nuevo consignatario
         notes: Notas
         credits: Créditos
         greuges: Greuges
@@ -236,7 +250,7 @@ globals:
         purchaseRequest: Petición de compra
         weeklyTickets: Tickets programados
         formation: Formación
-        locations: Ubicaciones
+        locations: Localizaciones
         warehouses: Almacenes
         roles: Roles
         connections: Conexiones
@@ -257,6 +271,11 @@ globals:
         twoFactor: Doble factor
         recoverPassword: Recuperar contraseña
         resetPassword: Restablecer contraseña
+        ticketsMonitor: Monitor de tickets
+        clientsActionsMonitor: Clientes y acciones
+        serial: Facturas por serie
+        medical: Mutua
+    supplier: Proveedor
     created: Fecha creación
     worker: Trabajador
     now: Ahora
@@ -269,7 +288,8 @@ globals:
         title: Los cambios que no haya guardado se perderán
         subtitle: ¿Seguro que quiere salir sin guardar?
     createInvoiceIn: Crear factura recibida
-
+    myAccount: Mi cuenta
+    noOne: Nadie
 errors:
     statusUnauthorized: Acceso denegado
     statusInternalServerError: Ha ocurrido un error interno del servidor
@@ -304,134 +324,6 @@ resetPassword:
     repeatPassword: Repetir contraseña
     passwordNotMatch: Las contraseñas no coinciden
     passwordChanged: Contraseña cambiada
-customer:
-    list:
-        phone: Teléfono
-        email: Email
-        customerOrders: Mostrar órdenes del cliente
-        moreOptions: Más opciones
-    card:
-        customerId: ID cliente
-        salesPerson: Comercial
-        credit: Crédito
-        risk: Riesgo
-        securedCredit: Crédito asegurado
-        payMethod: Método de pago
-        debt: Riesgo
-        isFrozen: Cliente congelado
-        hasDebt: Cliente con riesgo
-        isDisabled: Cliente inactivo
-        notChecked: Cliente no comprobado
-        webAccountInactive: Sin acceso web
-        noWebAccess: El acceso web está desactivado
-        businessType: Tipo de negocio
-        passwordRequirements: 'La contraseña debe tener al menos { length } caracteres de longitud, {nAlpha} caracteres alfabéticos, {nUpper} letras mayúsculas, {nDigits} dígitos y {nPunct} símbolos (Ej: $%&.)'
-        businessTypeFk: Tipo de negocio
-    summary:
-        basicData: Datos básicos
-        fiscalAddress: Dirección fiscal
-        fiscalData: Datos fiscales
-        billingData: Datos de facturación
-        consignee: Consignatario pred.
-        businessData: Datos comerciales
-        financialData: Datos financieros
-        customerId: ID cliente
-        name: Nombre
-        contact: Contacto
-        phone: Teléfono
-        mobile: Móvil
-        email: Email
-        salesPerson: Comercial
-        contactChannel: Canal de contacto
-        socialName: Razón social
-        fiscalId: NIF/CIF
-        postcode: Código postal
-        province: Provincia
-        country: País
-        street: Calle
-        isEqualizated: Recargo de equivalencia
-        isActive: Activo
-        invoiceByAddress: Facturar por consignatario
-        verifiedData: Datos verificados
-        hasToInvoice: Facturar
-        notifyByEmail: Notificar por email
-        vies: VIES
-        payMethod: Método de pago
-        bankAccount: Cuenta bancaria
-        dueDay: Día de pago
-        hasLcr: Recibido LCR
-        hasCoreVnl: Recibido core VNL
-        hasB2BVnl: Recibido B2B VNL
-        addressName: Nombre de la dirección
-        addressCity: Ciudad
-        addressStreet: Calle
-        username: Usuario
-        webAccess: Acceso web
-        totalGreuge: Greuge total
-        mana: Maná
-        priceIncreasingRate: Ratio de incremento de precio
-        averageInvoiced: Facturación media
-        claimRate: Ratio de reclamaciones
-        risk: Riesgo
-        riskInfo: Facturas menos recibos mas pedidos sin facturar
-        credit: Crédito
-        creditInfo: Riesgo máximo asumido por la empresa
-        securedCredit: Crédito asegurado
-        securedCreditInfo: Riesgo máximo asumido por Solunion
-        balance: Balance
-        balanceInfo: Facturas menos recibos
-        balanceDue: Saldo vencido
-        balanceDueInfo: Facturas fuera de plazo menos recibos
-        recoverySince: Recobro desde
-        businessType: Tipo de negocio
-        city: Población
-        descriptorInfo: Facturas menos recibos mas pedidos sin facturar
-        rating: Clasificación
-        recommendCredit: Crédito recomendado
-    basicData:
-        socialName: Nombre fiscal
-        businessType: Tipo de negocio
-        contact: Contacto
-        youCanSaveMultipleEmails: Puede guardar varios correos electrónicos encadenándolos mediante comas sin espacios{','} ejemplo{':'} user{'@'}dominio{'.'}com, user2{'@'}dominio{'.'}com siendo el primer correo electrónico el principal
-        email: Email
-        phone: Teléfono
-        mobile: Móvil
-        salesPerson: Comercial
-        contactChannel: Canal de contacto
-        previousClient: Cliente anterior
-    extendedList:
-        tableVisibleColumns:
-            id: Identificador
-            name: Nombre
-            socialName: Razón social
-            fi: NIF / CIF
-            salesPersonFk: Comercial
-            credit: Crédito
-            creditInsurance: Crédito asegurado
-            phone: Teléfono
-            mobile: Móvil
-            street: Dirección fiscal
-            countryFk: País
-            provinceFk: Provincia
-            city: Población
-            postcode: Código postal
-            email: Email
-            created: Fecha creación
-            businessTypeFk: Tipo de negocio
-            payMethodFk: Forma de pago
-            sageTaxTypeFk: Tipo de impuesto Sage
-            sageTransactionTypeFk: Tipo tr. sage
-            isActive: Activo
-            isVies: Vies
-            isTaxDataChecked: Datos comprobados
-            isEqualizated: Recargo de equivalencias
-            isFreezed: Congelado
-            hasToInvoice: Factura
-            hasToInvoiceByAddress: Factura por consigna
-            isToBeMailed: Env. emails
-            hasLcr: Recibido LCR
-            hasCoreVnl: Recibido core VNL
-            hasSepaVnl: Recibido B2B VNL
 entry:
     list:
         newEntry: Nueva entrada
@@ -453,6 +345,7 @@ entry:
             travelFk: Envio
             isExcludedFromAvailable: Inventario
             isRaid: Redada
+            invoiceAmount: Importe
     summary:
         commission: Comisión
         currency: Moneda
@@ -696,6 +589,7 @@ invoiceOut:
             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
@@ -788,54 +682,6 @@ parking:
     searchBar:
         info: Puedes buscar por código de parking
         label: Buscar parking...
-invoiceIn:
-    list:
-        ref: Referencia
-        supplier: Proveedor
-        supplierRef: Ref. proveedor
-        serialNumber: Num. serie
-        shortIssued: F. emisión
-        serial: Serie
-        file: Fichero
-        issued: Fecha emisión
-        isBooked: Conciliada
-        awb: AWB
-        amount: Importe
-    card:
-        issued: Fecha emisión
-        amount: Importe
-        client: Cliente
-        company: Empresa
-        customerCard: Ficha del cliente
-        ticketList: Listado de tickets
-        vat: Iva
-        dueDay: Fecha de vencimiento
-    summary:
-        supplier: Proveedor
-        supplierRef: Ref. proveedor
-        currency: Divisa
-        docNumber: Número documento
-        issued: Fecha de expedición
-        operated: Fecha operación
-        bookEntried: Fecha asiento
-        bookedDate: Fecha contable
-        sage: Retención sage
-        vat: Iva no deducible
-        company: Empresa
-        booked: Contabilizada
-        expense: Gasto
-        taxableBase: Base imp.
-        rate: Tasa
-        sageTransaction: Sage transación
-        dueDay: Fecha
-        bank: Caja
-        amount: Importe
-        foreignValue: Divisa
-        dueTotal: Vencimiento
-        code: Código
-        net: Neto
-        stems: Tallos
-        country: País
 department:
     pageTitles:
         basicData: Basic data
@@ -871,6 +717,8 @@ worker:
         timeControl: Control de horario
         locker: Taquilla
         balance: Balance
+        formation: Formación
+        medical: Mutua
     list:
         name: Nombre
         email: Email
@@ -882,6 +730,7 @@ worker:
         newWorker: Nuevo trabajador
     card:
         workerId: ID Trabajador
+        user: Usuario
         name: Nombre
         email: Correo personal
         phone: Teléfono
@@ -941,6 +790,15 @@ worker:
             amount: Importe
             remark: Bonficado
             hasDiploma: Diploma
+    medical:
+        tableVisibleColumns:
+            date: Fecha
+            time: Hora
+            center: Centro de Formación
+            invoice: Factura
+            amount: Importe
+            isFit: Apto
+            remark: Observaciones
     imageNotFound: No se ha encontrado la imagen
     balance:
         tableVisibleColumns:
@@ -950,6 +808,16 @@ worker:
             credit: Haber
             concept: Concepto
 wagon:
+    pageTitles:
+        wagons: Vagones
+        wagonsList: Listado vagones
+        wagonCreate: Crear tipo
+        wagonEdit: Editar tipo
+        typesList: Listado tipos
+        typeCreate: Crear tipo
+        typeEdit: Editar tipo
+        wagonCounter: Contador de carros
+        wagonTray: Listado bandejas
     type:
         name: Nombre
         submit: Guardar
@@ -1098,11 +966,14 @@ travel:
             id: Id
             ref: Referencia
             agency: Agencia
-            shipped: Enviado
-            landed: Llegada
-            warehouseIn: Almacén de salida
-            warehouseOut: Almacén de entrada
-            totalEntries: Total de entradas
+            shipped: F.envío
+            shipHour: Hora de envío
+            landHour: Hora de llegada
+            landed: F.entrega
+            warehouseIn: Alm.salida
+            warehouseOut: Alm.entrada
+            totalEntries: ∑
+            totalEntriesTooltip: Entradas totales
     summary:
         confirmed: Confirmado
         entryId: Id entrada
@@ -1253,6 +1124,7 @@ components:
         active: Activo
         visible: Visible
         floramondo: Floramondo
+        showBadDates: Ver items a futuro
     userPanel:
         copyToken: Token copiado al portapapeles
         settings: Configuración
@@ -1267,6 +1139,7 @@ components:
         clone: Clonar
         openCard: Ficha
         openSummary: Detalles
+        viewSummary: Vista previa
     cardDescriptor:
         mainList: Listado principal
         summary: Resumen
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index 88c5ee293..51cd20071 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -5,7 +5,7 @@ const quasar = useQuasar();
 </script>
 
 <template>
-    <QLayout view="hHh LpR fFf">
+    <QLayout view="hHh LpR fFf" v-shortcut>
         <Navbar />
         <RouterView></RouterView>
         <QFooter v-if="quasar.platform.is.mobile"></QFooter>
diff --git a/src/pages/Account/AccountAcls.vue b/src/pages/Account/AccountAcls.vue
index fdb0ecee1..dd93a0cb5 100644
--- a/src/pages/Account/AccountAcls.vue
+++ b/src/pages/Account/AccountAcls.vue
@@ -6,7 +6,6 @@ import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
 import { useQuasar } from 'quasar';
 
-import FetchData from 'components/FetchData.vue';
 import VnTable from 'components/VnTable/VnTable.vue';
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
 import VnConfirm from 'components/ui/VnConfirm.vue';
@@ -24,7 +23,6 @@ const stateStore = useStateStore();
 const quasar = useQuasar();
 
 const tableRef = ref();
-const rolesOptions = ref([]);
 
 const exprBuilder = (param, value) => {
     switch (param) {
@@ -143,6 +141,7 @@ const deleteAcl = async ({ id }) => {
             formInitialData: {},
         }"
         order="id DESC"
+        :disable-option="{ card: true }"
         :columns="columns"
         default-mode="table"
         :right-search="true"
diff --git a/src/pages/Account/AccountAliasList.vue b/src/pages/Account/AccountAliasList.vue
index b6f7b219c..c67283297 100644
--- a/src/pages/Account/AccountAliasList.vue
+++ b/src/pages/Account/AccountAliasList.vue
@@ -21,24 +21,21 @@ const columns = computed(() => [
     {
         align: 'left',
         name: 'id',
-        label: t('id'),
+        label: t('Id'),
         isId: true,
-        field: 'id',
         cardVisible: true,
     },
     {
         align: 'left',
         name: 'alias',
-        label: t('alias'),
-        field: 'alias',
+        label: t('Alias'),
         cardVisible: true,
         create: true,
     },
     {
         align: 'left',
         name: 'description',
-        label: t('description'),
-        field: 'description',
+        label: t('Description'),
         cardVisible: true,
         create: true,
     },
@@ -69,9 +66,17 @@ const columns = computed(() => [
         }"
         order="id DESC"
         :columns="columns"
+        :disable-option="{ card: true }"
         default-mode="table"
         redirect="account/alias"
         :is-editable="true"
         :use-model="true"
     />
 </template>
+
+<i18n>
+    es:
+        Id: Id
+        Alias: Alias
+        Description: Descripción
+</i18n>
diff --git a/src/pages/Account/AccountConnections.vue b/src/pages/Account/AccountConnections.vue
index 4d3450665..057745831 100644
--- a/src/pages/Account/AccountConnections.vue
+++ b/src/pages/Account/AccountConnections.vue
@@ -27,15 +27,15 @@ const filter = {
     order: 'created DESC',
 };
 
-const urlPath = 'AccessTokens';
+const urlPath = 'VnTokens';
 
 const refresh = () => paginateRef.value.fetch();
 
 const navigate = (id) => router.push({ name: 'AccountSummary', params: { id } });
 
-const killSession = async (id) => {
+const killSession = async ({ userId, created }) => {
     try {
-        await axios.delete(`${urlPath}/${id}`);
+        await axios.post(`${urlPath}/killSession`, { userId, created });
         paginateRef.value.fetch();
         notify(t('Session killed'), 'positive');
     } catch (error) {
@@ -84,7 +84,7 @@ const killSession = async (id) => {
                                     openConfirmationModal(
                                         t('Session will be killed'),
                                         t('Are you sure you want to continue?'),
-                                        () => killSession(row.id)
+                                        () => killSession(row)
                                     )
                                 "
                                 outline
diff --git a/src/pages/Account/AccountList.vue b/src/pages/Account/AccountList.vue
index cdd88551b..d698596b9 100644
--- a/src/pages/Account/AccountList.vue
+++ b/src/pages/Account/AccountList.vue
@@ -14,15 +14,23 @@ const columns = computed(() => [
     {
         align: 'left',
         name: 'id',
-        label: t('id'),
+        label: t('Id'),
         isId: true,
         field: 'id',
         cardVisible: true,
+        columnFilter: {
+            component: 'select',
+            name: 'search',
+            attrs: {
+                url: 'VnUsers/preview',
+                fields: ['id', 'name'],
+            },
+        },
     },
     {
         align: 'left',
         name: 'username',
-        label: t('nickname'),
+        label: t('Nickname'),
         isTitle: true,
         component: 'input',
         columnField: {
@@ -37,7 +45,7 @@ const columns = computed(() => [
     {
         align: 'left',
         name: 'name',
-        label: t('name'),
+        label: t('Name'),
         component: 'input',
         columnField: {
             component: null,
@@ -65,6 +73,7 @@ const columns = computed(() => [
                 title: t('View Summary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row.id, AccountSummary),
+                isPrimary: true,
             },
         ],
     },
@@ -108,3 +117,10 @@ const exprBuilder = (param, value) => {
         :use-model="true"
     />
 </template>
+
+<i18n>
+    es:
+        Id: Id
+        Nickname: Nickname
+        Name: Nombre
+</i18n>
diff --git a/src/pages/Account/Card/AccountCard.vue b/src/pages/Account/Card/AccountCard.vue
index a9857b283..67fa15898 100644
--- a/src/pages/Account/Card/AccountCard.vue
+++ b/src/pages/Account/Card/AccountCard.vue
@@ -15,7 +15,6 @@ const { t } = useI18n();
             url: 'VnUsers/preview',
             label: t('account.search'),
             info: t('account.searchInfo'),
-            searchUrl: 'table',
         }"
     />
 </template>
diff --git a/src/pages/Account/Card/AccountDescriptor.vue b/src/pages/Account/Card/AccountDescriptor.vue
index bc0c8c713..4571ee8ab 100644
--- a/src/pages/Account/Card/AccountDescriptor.vue
+++ b/src/pages/Account/Card/AccountDescriptor.vue
@@ -72,7 +72,7 @@ const hasAccount = ref(false);
             </VnImg>
         </template>
         <template #body="{ entity }">
-            <VnLv :label="t('account.card.nickname')" :value="entity.nickname" />
+            <VnLv :label="t('account.card.nickname')" :value="entity.name" />
             <VnLv :label="t('account.card.role')" :value="entity.role.name" />
         </template>
         <template #actions="{ entity }">
diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue
index f67cc0c6b..0e35d25f3 100644
--- a/src/pages/Account/Card/AccountDescriptorMenu.vue
+++ b/src/pages/Account/Card/AccountDescriptorMenu.vue
@@ -1,15 +1,12 @@
 <script setup>
 import axios from 'axios';
 import { computed, ref, toRefs } from 'vue';
-import { useQuasar } from 'quasar';
 import { useI18n } from 'vue-i18n';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import { useRoute } from 'vue-router';
 import { useArrayData } from 'src/composables/useArrayData';
-import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import useNotify from 'src/composables/useNotify.js';
-const quasar = useQuasar();
 const $props = defineProps({
     hasAccount: {
         type: Boolean,
@@ -35,7 +32,7 @@ async function updateStatusAccount(active) {
 
     account.value.hasAccount = active;
     const status = active ? 'enable' : 'disable';
-    quasar.notify({
+    notify({
         message: t(`account.card.${status}Account.success`),
         type: 'positive',
     });
@@ -44,19 +41,11 @@ async function updateStatusUser(active) {
     await axios.patch(`VnUsers/${entityId.value}`, { active });
     account.value.active = active;
     const status = active ? 'activate' : 'deactivate';
-    quasar.notify({
+    notify({
         message: t(`account.card.actions.${status}User.success`),
         type: 'positive',
     });
 }
-function setPassword() {
-    quasar.dialog({
-        component: CustomerChangePassword,
-        componentProps: {
-            id: entityId.value,
-        },
-    });
-}
 const showSyncDialog = ref(false);
 const syncPassword = ref(null);
 const shouldSyncPassword = ref(false);
@@ -66,20 +55,11 @@ async function sync() {
     await axios.patch(`Accounts/${account.value.name}/sync`, {
         params,
     });
-    quasar.notify({
+    notify({
         message: t('account.card.actions.sync.success'),
         type: 'positive',
     });
 }
-
-const removeAccount = async () => {
-    try {
-        await axios.delete(`VnUsers/${account.value.id}`);
-        notify(t('Account removed'), 'positive');
-    } catch (error) {
-        console.error('Error deleting user', error);
-    }
-};
 </script>
 <template>
     <VnConfirm
@@ -112,24 +92,6 @@ const removeAccount = async () => {
             />
         </template>
     </VnConfirm>
-    <!-- <QItem v-ripple clickable @click="setPassword">
-        <QItemSection>{{ t('account.card.actions.setPassword') }}</QItemSection>
-    </QItem>
-    <QItem
-        v-if="!account.hasAccount"
-        v-ripple
-        clickable
-        @click="
-            openConfirmationModal(
-                t('account.card.actions.enableAccount.title'),
-                t('account.card.actions.enableAccount.subtitle'),
-                () => updateStatusAccount(true)
-            )
-        "
-    >
-        <QItemSection>{{ t('account.card.actions.enableAccount.name') }}</QItemSection>
-    </QItem> -->
-
     <QItem
         v-if="account.hasAccount"
         v-ripple
@@ -178,10 +140,4 @@ const removeAccount = async () => {
     </QItem>
 
     <QSeparator />
-    <!-- <QItem @click="removeAccount(id)" v-ripple clickable>
-        <QItemSection avatar>
-            <QIcon name="delete" />
-        </QItemSection>
-        <QItemSection>{{ t('account.card.actions.delete.name') }}</QItemSection>
-    </QItem> -->
 </template>
diff --git a/src/pages/Account/Card/AccountMailAlias.vue b/src/pages/Account/Card/AccountMailAlias.vue
index 594353219..15d03c665 100644
--- a/src/pages/Account/Card/AccountMailAlias.vue
+++ b/src/pages/Account/Card/AccountMailAlias.vue
@@ -169,7 +169,13 @@ onMounted(async () => await getAccountData(false));
             <AccountMailAliasCreateForm @on-submit-create-alias="createMailAlias" />
         </QDialog>
         <QPageSticky position="bottom-right" :offset="[18, 18]">
-            <QBtn fab icon="add" color="primary" @click="openCreateMailAliasForm()">
+            <QBtn
+                fab
+                icon="add"
+                color="primary"
+                @click="openCreateMailAliasForm()"
+                shortcut="+"
+            >
                 <QTooltip>{{ t('warehouses.add') }}</QTooltip>
             </QBtn>
         </QPageSticky>
diff --git a/src/pages/Account/Card/AccountPrivileges.vue b/src/pages/Account/Card/AccountPrivileges.vue
index 1300f5018..fea57105b 100644
--- a/src/pages/Account/Card/AccountPrivileges.vue
+++ b/src/pages/Account/Card/AccountPrivileges.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref } from 'vue';
+import { ref, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
@@ -12,16 +12,21 @@ const route = useRoute();
 
 const rolesOptions = ref([]);
 const formModelRef = ref();
+watch(
+    () => route.params.id,
+    () => formModelRef.value.reset()
+);
 </script>
 <template>
     <FetchData url="VnRoles" auto-load @on-fetch="(data) => (rolesOptions = data)" />
     <FormModel
         ref="formModelRef"
         model="AccountPrivileges"
-        :url="`VnUsers/${route.params.id}/privileges`"
+        url="VnUsers/preview"
+        :filter="{ where: { id: route.params.id } }"
         :url-create="`VnUsers/${route.params.id}/privileges`"
+        :id="route.params.id"
         auto-load
-        @on-data-saved="formModelRef.fetch()"
     >
         <template #form="{ data }">
             <div class="q-gutter-y-sm">
diff --git a/src/pages/Account/Card/AccountSummary.vue b/src/pages/Account/Card/AccountSummary.vue
index 1901f9cde..5a21e18a5 100644
--- a/src/pages/Account/Card/AccountSummary.vue
+++ b/src/pages/Account/Card/AccountSummary.vue
@@ -48,7 +48,7 @@ const filter = {
                         <QIcon name="open_in_new" />
                     </router-link>
                 </QCardSection>
-                <VnLv :label="t('account.card.nickname')" :value="account.nickname" />
+                <VnLv :label="t('account.card.nickname')" :value="account.name" />
                 <VnLv :label="t('account.card.role')" :value="account.role.name" />
             </QCard>
         </template>
diff --git a/src/pages/Account/Role/AccountRoles.vue b/src/pages/Account/Role/AccountRoles.vue
index 2f80606b4..ea175d913 100644
--- a/src/pages/Account/Role/AccountRoles.vue
+++ b/src/pages/Account/Role/AccountRoles.vue
@@ -4,11 +4,9 @@ import { computed, ref } from 'vue';
 import VnTable from 'components/VnTable/VnTable.vue';
 import { useRoute } from 'vue-router';
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
-import { useStateStore } from 'stores/useStateStore';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import RoleSummary from './Card/RoleSummary.vue';
 const route = useRoute();
-const stateStore = useStateStore();
 const { t } = useI18n();
 const $props = defineProps({
     id: {
@@ -23,24 +21,30 @@ const columns = computed(() => [
     {
         align: 'left',
         name: 'id',
-        label: t('id'),
+        label: t('Id'),
         isId: true,
         columnFilter: {
             inWhere: true,
+            component: 'select',
+            name: 'search',
+            attrs: {
+                url: 'VnRoles',
+                fields: ['id', 'name'],
+            },
         },
         cardVisible: true,
     },
     {
         align: 'left',
         name: 'name',
-        label: t('name'),
+        label: t('Name'),
         cardVisible: true,
         create: true,
     },
     {
         align: 'left',
         name: 'description',
-        label: t('description'),
+        label: t('Description'),
         cardVisible: true,
         create: true,
     },
@@ -53,6 +57,7 @@ const columns = computed(() => [
                 title: t('View Summary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row.id, RoleSummary),
+                isPrimary: true,
             },
         ],
     },
@@ -95,8 +100,16 @@ const exprBuilder = (param, value) => {
             },
         }"
         order="id ASC"
+        :disable-option="{ card: true }"
         :columns="columns"
         default-mode="table"
         redirect="account/role"
     />
 </template>
+
+<i18n>
+    es:
+        Id: Id
+        Description: Descripción
+        Name: Nombre
+</i18n>
diff --git a/src/pages/Claim/Card/ClaimDevelopment.vue b/src/pages/Claim/Card/ClaimDevelopment.vue
index f7e8131c6..61d9f5858 100644
--- a/src/pages/Claim/Card/ClaimDevelopment.vue
+++ b/src/pages/Claim/Card/ClaimDevelopment.vue
@@ -16,7 +16,6 @@ const claimReasons = ref([]);
 const claimResults = ref([]);
 const claimResponsibles = ref([]);
 const claimRedeliveries = ref([]);
-const workers = ref([]);
 const selected = ref([]);
 const saveButtonRef = ref();
 
@@ -82,7 +81,9 @@ const columns = computed(() => [
         label: t('Worker'),
         field: (row) => row.workerFk,
         sortable: true,
-        options: workers.value,
+        url: 'Workers/search',
+        where: { active: 1 },
+        sortBy: 'name ASC',
         model: 'workerFk',
         optionValue: 'id',
         optionLabel: 'nickname',
@@ -129,13 +130,6 @@ const columns = computed(() => [
         @on-fetch="(data) => (claimRedeliveries = data)"
         auto-load
     />
-    <FetchData
-        url="Workers/search"
-        :where="{ active: 1 }"
-        order="name ASC"
-        @on-fetch="(data) => (workers = data)"
-        auto-load
-    />
     <CrudModel
         data-key="ClaimDevelopments"
         url="ClaimDevelopments"
@@ -165,6 +159,9 @@ const columns = computed(() => [
                     >
                         <VnSelect
                             v-model="row[col.model]"
+                            :url="col.url"
+                            :where="col.where"
+                            :sort-by="col.sortBy"
                             :options="col.options"
                             :option-value="col.optionValue"
                             :option-label="col.optionLabel"
diff --git a/src/pages/Claim/Card/ClaimLines.vue b/src/pages/Claim/Card/ClaimLines.vue
index 52fbfca98..77c7dacf1 100644
--- a/src/pages/Claim/Card/ClaimLines.vue
+++ b/src/pages/Claim/Card/ClaimLines.vue
@@ -45,7 +45,7 @@ async function onFetchClaim(data) {
 
 const amount = ref();
 const amountClaimed = ref();
-async function onFetch(rows, newRows) {
+function onFetch(rows, newRows) {
     if (newRows) rows = newRows;
     amount.value = 0;
     amountClaimed.value = 0;
@@ -155,7 +155,7 @@ function showImportDialog() {
 async function saveWhenHasChanges() {
     if (claimLinesForm.value.getChanges().updates) {
         await claimLinesForm.value.onSubmit();
-        await claimLinesForm.value.reload();
+        onFetch(claimLinesForm.value.formData);
     }
 }
 </script>
@@ -211,7 +211,7 @@ async function saveWhenHasChanges() {
                     <template #body-cell-claimed="{ row }">
                         <QTd auto-width align="right" class="text-primary">
                             <QInput
-                                v-model="row.quantity"
+                                v-model.number="row.quantity"
                                 type="number"
                                 dense
                                 @keyup.enter="saveWhenHasChanges()"
@@ -266,7 +266,9 @@ async function saveWhenHasChanges() {
                                             <template v-if="column.name === 'claimed'">
                                                 <QItemLabel class="text-primary">
                                                     <QInput
-                                                        v-model="props.row.quantity"
+                                                        v-model.number="
+                                                            props.row.quantity
+                                                        "
                                                         type="number"
                                                         dense
                                                         autofocus
diff --git a/src/pages/Claim/Card/ClaimSummary.vue b/src/pages/Claim/Card/ClaimSummary.vue
index 4d817c3c2..d77f718c6 100644
--- a/src/pages/Claim/Card/ClaimSummary.vue
+++ b/src/pages/Claim/Card/ClaimSummary.vue
@@ -1,11 +1,10 @@
 <script setup>
 import axios from 'axios';
-import { onMounted, ref, computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { toDate, toCurrency } from 'src/filters';
 import dashIfEmpty from 'src/filters/dashIfEmpty';
-import { getUrl } from 'src/composables/getUrl';
 import { useSession } from 'src/composables/useSession';
 
 import VnLv from 'src/components/ui/VnLv.vue';
@@ -36,8 +35,6 @@ const $props = defineProps({
 
 const entityId = computed(() => $props.id || route.params.id);
 const ClaimStates = ref([]);
-const claimUrl = ref();
-const salixUrl = ref();
 const claimDmsRef = ref();
 const claimDms = ref([]);
 const multimediaDialog = ref();
@@ -97,8 +94,8 @@ const detailsColumns = ref([
     {
         name: 'total',
         label: 'claim.total',
-        field: ({ sale }) =>
-            toCurrency(sale.quantity * sale.price * ((100 - sale.discount) / 100)),
+        field: (row) =>
+            toCurrency(row.quantity * row.sale.price * ((100 - row.sale.discount) / 100)),
         sortable: true,
     },
 ]);
@@ -152,11 +149,6 @@ const developmentColumns = ref([
     },
 ]);
 
-onMounted(async () => {
-    salixUrl.value = await getUrl('');
-    claimUrl.value = salixUrl.value + `claim/${entityId.value}/`;
-});
-
 async function getClaimDms() {
     claimDmsFilter.value.where = { claimFk: entityId.value };
     await claimDmsRef.value.fetch();
@@ -177,10 +169,15 @@ function openDialog(dmsId) {
     multimediaSlide.value = dmsId;
     multimediaDialog.value = true;
 }
+
 async function changeState(value) {
     await axios.patch(`Claims/updateClaim/${entityId.value}`, { claimStateFk: value });
     router.go(route.fullPath);
 }
+
+function claimUrl(section) {
+    return '#/claim/' + entityId.value + '/' + section;
+}
 </script>
 
 <template>
@@ -234,7 +231,7 @@ async function changeState(value) {
         <template #body="{ entity: { claim, salesClaimed, developments } }">
             <QCard class="vn-one" v-if="$route.name != 'ClaimSummary'">
                 <VnTitle
-                    :url="`#/claim/${entityId}/basic-data`"
+                    :url="claimUrl('basic-data')"
                     :text="t('globals.pageTitles.basicData')"
                 />
                 <VnLv :label="t('claim.created')" :value="toDate(claim.created)" />
@@ -275,7 +272,7 @@ async function changeState(value) {
                 />
             </QCard>
             <QCard class="vn-two">
-                <VnTitle :url="`#/claim/${entityId}/notes`" :text="t('claim.notes')" />
+                <VnTitle :url="claimUrl('notes')" :text="t('claim.notes')" />
                 <ClaimNotes
                     :id="entityId"
                     :add-note="false"
@@ -284,7 +281,7 @@ async function changeState(value) {
                 />
             </QCard>
             <QCard class="vn-two" v-if="claimDms?.length">
-                <VnTitle :url="`#/claim/${entityId}/photos`" :text="t('claim.photos')" />
+                <VnTitle :url="claimUrl('photos')" :text="t('claim.photos')" />
                 <div class="container max-container-height" style="overflow: auto">
                     <div
                         class="multimedia-container"
@@ -326,7 +323,7 @@ async function changeState(value) {
                 </div>
             </QCard>
             <QCard class="vn-max" v-if="salesClaimed.length > 0">
-                <VnTitle :url="`#/claim/${entityId}/lines`" :text="t('claim.details')" />
+                <VnTitle :url="claimUrl('lines')" :text="t('claim.details')" />
                 <QTable
                     :columns="detailsColumns"
                     :rows="salesClaimed"
@@ -365,7 +362,7 @@ async function changeState(value) {
                 </QTable>
             </QCard>
             <QCard class="vn-max" v-if="developments.length > 0">
-                <VnTitle :url="claimUrl + 'development'" :text="t('claim.development')" />
+                <VnTitle :url="claimUrl('development')" :text="t('claim.development')" />
                 <QTable
                     :columns="developmentColumns"
                     :rows="developments"
@@ -390,7 +387,7 @@ async function changeState(value) {
                 </QTable>
             </QCard>
             <QCard class="vn-max">
-                <VnTitle :url="claimUrl + 'action'" :text="t('claim.actions')" />
+                <VnTitle :url="claimUrl('action')" :text="t('claim.actions')" />
                 <div id="slider-container" class="q-px-xl q-py-md">
                     <QSlider
                         v-model="claim.responsibility"
diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue
index 6fd607da0..6d85817dc 100644
--- a/src/pages/Claim/ClaimList.vue
+++ b/src/pages/Claim/ClaimList.vue
@@ -50,8 +50,9 @@ const columns = computed(() => [
         align: 'left',
         label: t('claim.attendedBy'),
         name: 'attendedBy',
-        cardVisible: true,
+        orderBy: 'workerFk',
         columnFilter: {
+            name: 'attenderFk',
             component: 'select',
             attrs: {
                 url: 'Workers/activeWithInheritedRole',
@@ -63,6 +64,7 @@ const columns = computed(() => [
                 optionFilter: 'firstName',
             },
         },
+        cardVisible: true,
     },
     {
         align: 'left',
@@ -77,6 +79,9 @@ const columns = computed(() => [
     {
         align: 'left',
         label: t('claim.state'),
+        format: ({ stateCode }) =>
+            claimFilterRef.value?.states.find(({ code }) => code === stateCode)
+                ?.description,
         name: 'stateCode',
         chip: {
             condition: () => true,
@@ -96,7 +101,7 @@ const columns = computed(() => [
         name: 'tableActions',
         actions: [
             {
-                title: t('Client ticket list'),
+                title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row.id, ClaimSummary),
             },
diff --git a/src/pages/Claim/locale/es.yml b/src/pages/Claim/locale/es.yml
index 90bef8e66..052416aa7 100644
--- a/src/pages/Claim/locale/es.yml
+++ b/src/pages/Claim/locale/es.yml
@@ -42,7 +42,7 @@ claim:
     pickup: Recoger
     null: No
     agency: Agencia
-    delivery: Entrega
+    delivery: Reparto
     fileDescription: 'ID de reclamación {claimId} del cliente {clientName} con ID {clientId}'
     noData: 'No hay imágenes/videos, haz clic aquí o arrastra y suelta el archivo'
     dragDrop: Arrastra y suelta aquí
diff --git a/src/pages/Customer/Card/CustomerAddress.vue b/src/pages/Customer/Card/CustomerAddress.vue
index a97b45a50..166c33e1a 100644
--- a/src/pages/Customer/Card/CustomerAddress.vue
+++ b/src/pages/Customer/Card/CustomerAddress.vue
@@ -169,6 +169,13 @@ const toCustomerAddressEdit = (addressId) => {
                             {{ item.postalCode }} - {{ item.city }},
                             {{ item.province.name }}
                         </div>
+                        <div>
+                            {{ item.phone }}
+                            <span v-if="item.mobile"
+                                >,
+                                {{ item.mobile }}
+                            </span>
+                        </div>
                         <div class="flex">
                             <QCheckbox
                                 :label="t('Is equalizated')"
@@ -208,7 +215,13 @@ const toCustomerAddressEdit = (addressId) => {
     </div>
 
     <QPageSticky :offset="[18, 18]">
-        <QBtn @click.stop="toCustomerAddressCreate()" color="primary" fab icon="add" />
+        <QBtn
+            @click.stop="toCustomerAddressCreate()"
+            color="primary"
+            fab
+            icon="add"
+            shortcut="+"
+        />
         <QTooltip>
             {{ t('New consignee') }}
         </QTooltip>
diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue
index 346e76681..2a1991bbd 100644
--- a/src/pages/Customer/Card/CustomerBalance.vue
+++ b/src/pages/Customer/Card/CustomerBalance.vue
@@ -2,15 +2,15 @@
 import { computed, onBeforeMount, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
-import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 import axios from 'axios';
 import { useQuasar } from 'quasar';
+import FetchData from 'components/FetchData.vue';
 
 import { toCurrency, toDate, toDateHourMin } from 'src/filters';
 import { useState } from 'composables/useState';
 import { useStateStore } from 'stores/useStateStore';
 import { usePrintService } from 'composables/usePrintService';
-import { useSession } from 'composables/useSession';
 import { useVnConfirm } from 'composables/useVnConfirm';
 
 import VnTable from 'components/VnTable/VnTable.vue';
@@ -22,12 +22,10 @@ import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment
 import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
 
 const { openConfirmationModal } = useVnConfirm();
-const { sendEmail } = usePrintService();
+const { sendEmail, openReport } = usePrintService();
 const { t } = useI18n();
-const { hasAny } = useRole();
-
-const session = useSession();
-const tokenMultimedia = session.getTokenMultimedia();
+const { hasAny } = useAcl();
+const currentBalance = ref({});
 const quasar = useQuasar();
 const route = useRoute();
 const state = useState();
@@ -36,7 +34,7 @@ const user = state.getUser();
 
 const clientRisk = ref([]);
 const tableRef = ref();
-const companyId = ref();
+const companyId = ref(user.value.companyFk);
 const companyLastId = ref(user.value.companyFk);
 const balances = ref([]);
 const vnFilterRef = ref({});
@@ -76,14 +74,14 @@ const companyFilterColumn = {
 
 const columns = computed(() => [
     {
-        align: 'left',
+        align: 'right',
         name: 'payed',
         label: t('Date'),
         format: ({ payed }) => toDate(payed),
         cardVisible: true,
     },
     {
-        align: 'left',
+        align: 'right',
         name: 'created',
         label: t('Creation date'),
         format: ({ created }) => toDateHourMin(created),
@@ -91,16 +89,10 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'workerFk',
         label: t('Employee'),
         columnField: {
             component: 'userLink',
-            attrs: ({ row }) => {
-                return {
-                    workerId: row.workerFk,
-                    name: row.userName,
-                };
-            },
+            attrs: ({ row }) => ({ workerId: row.workerFk, name: row.userName }),
         },
         cardVisible: true,
     },
@@ -125,14 +117,14 @@ const columns = computed(() => [
         isId: true,
     },
     {
-        align: 'right',
+        align: 'left',
         name: 'credit',
         label: t('Havings'),
         format: ({ credit }) => credit && toCurrency(credit),
         cardVisible: true,
     },
     {
-        align: 'right',
+        align: 'left',
         name: 'balance',
         label: t('Balance'),
         format: ({ balance }) => toCurrency(balance),
@@ -171,41 +163,15 @@ const columns = computed(() => [
 
 onBeforeMount(() => {
     stateStore.rightDrawer = true;
-    companyId.value = user.value.companyFk;
 });
 
-async function getClientRisk() {
-    const { data } = await axios.get(`clientRisks`, {
-        params: {
-            filter: JSON.stringify({
-                include: { relation: 'company', scope: { fields: ['code'] } },
-                where: { clientFk: route.params.id, companyFk: user.value.companyFk },
-            }),
-        },
-    });
-    clientRisk.value = data;
-    return clientRisk.value;
-}
-
-async function getCurrentBalance() {
-    const currentBalance = (await getClientRisk()).find((balance) => {
-        return balance.companyFk === companyId.value;
-    });
-    return currentBalance && currentBalance.amount;
-}
-
-async function onFetch(data) {
-    balances.value = [];
-    for (const [index, balance] of data.entries()) {
-        if (index === 0) {
-            balance.balance = await getCurrentBalance();
-            continue;
-        }
-        const previousBalance = data[index - 1];
-        balance.balance =
-            previousBalance?.balance - (previousBalance?.debit - previousBalance?.credit);
+async function getCurrentBalance(data) {
+    for (const balance of data) {
+        currentBalance.value[balance.companyFk] = {
+            code: balance.company.code,
+            amount: balance.amount,
+        };
     }
-    balances.value = data;
 }
 
 const showNewPaymentDialog = () => {
@@ -220,19 +186,27 @@ const showNewPaymentDialog = () => {
 };
 
 const showBalancePdf = ({ id }) => {
-    const url = `api/InvoiceOuts/${id}/download?access_token=${tokenMultimedia}`;
-    window.open(url, '_blank');
+    openReport(`InvoiceOuts/${id}/download`, {}, '_blank');
 };
 </script>
 
 <template>
+    <FetchData
+        url="clientRisks"
+        :filter="{
+            include: { relation: 'company', scope: { fields: ['code'] } },
+            where: { clientFk: route.params.id, companyFk: companyId },
+        }"
+        auto-load
+        @on-fetch="getCurrentBalance"
+    ></FetchData>
     <VnSubToolbar class="q-mb-md">
         <template #st-data>
             <div class="column justify-center q-px-md q-py-sm">
                 <span class="text-bold">{{ t('Total by company') }}</span>
-                <div class="row justify-center" v-if="clientRisk?.length">
-                    {{ clientRisk[0].company.code }}:
-                    {{ toCurrency(clientRisk[0].amount) }}
+                <div class="row justify-center">
+                    {{ currentBalance[companyId]?.code }}:
+                    {{ toCurrency(currentBalance[companyId]?.amount) }}
                 </div>
             </div>
         </template>
@@ -258,7 +232,7 @@ const showBalancePdf = ({ id }) => {
         :right-search="false"
         :is-editable="false"
         :column-search="false"
-        @on-fetch="onFetch"
+        :disable-option="{ card: true }"
         auto-load
     >
         <template #column-balance="{ rowIndex }">
@@ -266,7 +240,7 @@ const showBalancePdf = ({ id }) => {
         </template>
         <template #column-description="{ row }">
             <div class="link" v-if="row.isInvoice">
-                {{ row.description }}
+                {{ t('bill', { ref: row.description }) }}
                 <InvoiceOutDescriptorProxy :id="row.description" />
             </div>
             <span v-else class="q-pa-xs dotted rounded-borders" :title="row.description">
@@ -284,7 +258,9 @@ const showBalancePdf = ({ id }) => {
             >
                 <VnInput
                     v-model="scope.value"
-                    :disable="!hasAny(['administrative'])"
+                    :disable="
+                        !hasAny([{ model: 'Receipt', props: '*', accessType: 'WRITE' }])
+                    "
                     @keypress.enter="scope.set"
                     autofocus
                 />
@@ -292,7 +268,13 @@ const showBalancePdf = ({ id }) => {
         </template>
     </VnTable>
     <QPageSticky :offset="[18, 18]" style="z-index: 2">
-        <QBtn @click.stop="showNewPaymentDialog()" color="primary" fab icon="add" />
+        <QBtn
+            @click.stop="showNewPaymentDialog()"
+            color="primary"
+            fab
+            icon="add"
+            shortcut="+"
+        />
         <QTooltip>
             {{ t('New payment') }}
         </QTooltip>
diff --git a/src/pages/Customer/Card/CustomerBasicData.vue b/src/pages/Customer/Card/CustomerBasicData.vue
index 87a3b08f7..91d9edc05 100644
--- a/src/pages/Customer/Card/CustomerBasicData.vue
+++ b/src/pages/Customer/Card/CustomerBasicData.vue
@@ -25,6 +25,7 @@ const title = ref();
     />
     <FetchData
         url="BusinessTypes"
+        :filter="{ fields: ['code', 'description'], order: 'description ASC ' }"
         @on-fetch="(data) => (businessTypes = data)"
         auto-load
     />
@@ -38,7 +39,7 @@ const title = ref();
                     clearable
                     v-model="data.name"
                 />
-                <QSelect
+                <VnSelect
                     :input-debounce="0"
                     :label="t('customer.basicData.businessType')"
                     :options="businessTypes"
@@ -89,15 +90,18 @@ const title = ref();
             </VnRow>
             <VnRow>
                 <VnSelect
-                    url="Workers/activeWithInheritedRole"
-                    :filter="{ where: { role: 'salesPerson' } }"
-                    option-filter="firstName"
+                    url="Workers/search"
                     v-model="data.salesPersonFk"
                     :label="t('customer.basicData.salesPerson')"
+                    :params="{
+                        departmentCodes: ['VT', 'shopping'],
+                    }"
+                    :fields="['id', 'nickname']"
+                    sort-by="nickname ASC"
                     :rules="validate('client.salesPersonFk')"
                     :use-like="false"
-                    :emit-value="false"
-                    @update:model-value="(val) => (title = val?.nickname)"
+                    emit-value
+                    auto-load
                 >
                     <template #prepend>
                         <VnAvatar
@@ -106,8 +110,19 @@ const title = ref();
                             :title="title"
                         />
                     </template>
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
+                                <QItemLabel caption
+                                    >{{ scope.opt?.nickname }},
+                                    {{ scope.opt?.code }}</QItemLabel
+                                >
+                            </QItemSection>
+                        </QItem>
+                    </template>
                 </VnSelect>
-                <QSelect
+                <VnSelect
                     v-model="data.contactChannelFk"
                     :options="contactChannels"
                     option-value="id"
@@ -120,7 +135,8 @@ const title = ref();
                 />
             </VnRow>
             <VnRow>
-                <QSelect
+                <VnSelect
+                    url="Clients"
                     :input-debounce="0"
                     :label="t('customer.basicData.previousClient')"
                     :options="clients"
@@ -129,7 +145,9 @@ const title = ref();
                     map-options
                     option-label="name"
                     option-value="id"
+                    sort-by="name ASC"
                     v-model="data.transferorFk"
+                    :fields="['id', 'name']"
                 >
                     <template #append>
                         <QIcon name="info" class="cursor-pointer">
@@ -140,7 +158,7 @@ const title = ref();
                             }}</QTooltip>
                         </QIcon>
                     </template>
-                </QSelect>
+                </VnSelect>
             </VnRow>
         </template>
     </FormModel>
diff --git a/src/pages/Customer/Card/CustomerBillingData.vue b/src/pages/Customer/Card/CustomerBillingData.vue
index b01dc4523..a968d0ec8 100644
--- a/src/pages/Customer/Card/CustomerBillingData.vue
+++ b/src/pages/Customer/Card/CustomerBillingData.vue
@@ -3,7 +3,6 @@ import { ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
-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';
@@ -14,8 +13,6 @@ import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue';
 const { t } = useI18n();
 const route = useRoute();
 
-const payMethods = ref([]);
-const bankEntitiesOptions = ref([]);
 const bankEntitiesRef = ref(null);
 
 const filter = {
@@ -31,15 +28,6 @@ const getBankEntities = (data, formData) => {
 </script>
 
 <template>
-    <fetch-data @on-fetch="(data) => (payMethods = data)" auto-load url="PayMethods" />
-    <fetch-data
-        ref="bankEntitiesRef"
-        @on-fetch="(data) => (bankEntitiesOptions = data)"
-        :filter="filter"
-        auto-load
-        url="BankEntities"
-    />
-
     <FormModel
         :url-update="`Clients/${route.params.id}`"
         :url="`Clients/${route.params.id}/getCard`"
@@ -49,8 +37,9 @@ const getBankEntities = (data, formData) => {
         <template #form="{ data, validate }">
             <VnRow>
                 <VnSelect
+                    auto-load
+                    url="PayMethods"
                     :label="t('Billing data')"
-                    :options="payMethods"
                     hide-selected
                     option-label="name"
                     option-value="id"
@@ -69,8 +58,11 @@ const getBankEntities = (data, formData) => {
                 </VnInput>
                 <VnSelectDialog
                     :label="t('Swift / BIC')"
-                    :options="bankEntitiesOptions"
-                    :roles-allowed-to-create="['salesAssistant', 'hr']"
+                    ref="bankEntitiesRef"
+                    :filter="filter"
+                    auto-load
+                    url="BankEntities"
+                    :acls="[{ model: 'BankEntity', props: '*', accessType: 'WRITE' }]"
                     :rules="validate('Worker.bankEntity')"
                     hide-selected
                     option-label="name"
@@ -85,9 +77,8 @@ const getBankEntities = (data, formData) => {
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
                             <QItemSection v-if="scope.opt">
-                                <QItemLabel
-                                    >{{ scope.opt.bic }} {{ scope.opt.name }}</QItemLabel
-                                >
+                                <QItemLabel>{{ scope.opt.bic }} </QItemLabel>
+                                <QItemLabel caption> {{ scope.opt.name }}</QItemLabel>
                             </QItemSection>
                         </QItem>
                     </template>
diff --git a/src/pages/Customer/Card/CustomerCard.vue b/src/pages/Customer/Card/CustomerCard.vue
index 229946ea2..139917d05 100644
--- a/src/pages/Customer/Card/CustomerCard.vue
+++ b/src/pages/Customer/Card/CustomerCard.vue
@@ -1,17 +1,23 @@
 <script setup>
+import { computed } from 'vue';
+import { useRoute } from 'vue-router';
+
 import VnCard from 'components/common/VnCard.vue';
 import CustomerDescriptor from './CustomerDescriptor.vue';
 import CustomerFilter from '../CustomerFilter.vue';
+const route = useRoute();
+
+const routeName = computed(() => route.name);
 </script>
 <template>
     <VnCard
         data-key="Client"
         base-url="Clients"
         :descriptor="CustomerDescriptor"
-        :filter-panel="CustomerFilter"
+        :filter-panel="routeName != 'CustomerConsumption' && CustomerFilter"
         search-data-key="CustomerList"
         :searchbar-props="{
-            url: 'Clients/extendedListFilter',
+            url: 'Clients/filter',
             label: 'Search customer',
             info: 'You can search by customer id or name',
         }"
diff --git a/src/pages/Customer/Card/CustomerConsumption.vue b/src/pages/Customer/Card/CustomerConsumption.vue
index 98a3115da..35f366e47 100644
--- a/src/pages/Customer/Card/CustomerConsumption.vue
+++ b/src/pages/Customer/Card/CustomerConsumption.vue
@@ -1,17 +1,241 @@
 <script setup>
+import { ref, computed, onBeforeMount } from 'vue';
+import axios from 'axios';
 import { useI18n } from 'vue-i18n';
-import CustomerConsumptionFilter from './CustomerConsumptionFilter.vue';
-import { useStateStore } from 'src/stores/useStateStore';
+import { toDate } from 'src/filters/index';
+import { useRoute } from 'vue-router';
+
+import VnTable from 'components/VnTable/VnTable.vue';
+import FetchedTags from 'components/ui/FetchedTags.vue';
+import { useArrayData } from 'src/composables/useArrayData';
+import { usePrintService } from 'src/composables/usePrintService';
+import { useVnConfirm } from 'src/composables/useVnConfirm';
+
+const { openConfirmationModal } = useVnConfirm();
+const { openReport, sendEmail } = usePrintService();
+import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
+import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
+import VnSelect from 'components/common/VnSelect.vue';
+import VnInputDate from 'components/common/VnInputDate.vue';
+
+const arrayData = useArrayData('Client');
 const { t } = useI18n();
+const route = useRoute();
+const campaignList = ref();
+const showActionBtns = computed(() => handleQueryParams());
+function handleQueryParams() {
+    const query = getQueryParams();
+    return query.from && query.to;
+}
+const columns = computed(() => [
+    {
+        name: 'search',
+        align: 'left',
+        label: t('globals.search'),
+        visible: false,
+    },
+    {
+        name: 'itemFk',
+        align: 'left',
+        label: t('globals.item'),
+        columnClass: 'shrink',
+        cardVisible: true,
+        columnFilter: {
+            name: 'itemId',
+        },
+    },
+    {
+        name: 'ticketFk',
+        align: 'left',
+        label: t('globals.ticket'),
+        cardVisible: true,
+        columnFilter: {
+            inWhere: true,
+        },
+    },
+    {
+        name: 'shipped',
+        align: 'left',
+        label: t('globals.shipped'),
+        format: ({ shipped }) => toDate(shipped),
+        columnFilter: false,
+        cardVisible: true,
+    },
+    {
+        name: 'description',
+        align: 'left',
+        label: t('globals.description'),
+        columnClass: 'expand',
+        columnFilter: {
+            inWhere: true,
+        },
+    },
+    {
+        name: 'quantity',
+        label: t('globals.quantity'),
+        cardVisible: true,
+        columnFilter: {
+            inWhere: true,
+        },
+    },
+    {
+        name: 'grouped',
+        label: t('Group by items'),
+        component: 'checkbox',
+        visible: false,
+        orderBy: false,
+    },
+]);
+
+onBeforeMount(async () => {
+    campaignList.value = (await axios('Campaigns/latest')).data;
+});
+
+function getQueryParams() {
+    return JSON.parse(route.query.consumption ?? '{}');
+}
+function getParams() {
+    const query = getQueryParams();
+    return {
+        from: query.from,
+        to: query.to,
+        recipient: arrayData.store.data.email,
+        recipientId: arrayData.store.data.id,
+    };
+}
+const userParams = computed(() => {
+    const minDate = Date.vnNew();
+    minDate.setHours(0, 0, 0, 0);
+    minDate.setMonth(minDate.getMonth() - 2);
+
+    const maxDate = Date.vnNew();
+    maxDate.setHours(23, 59, 59, 59);
+
+    return {
+        campaign: campaignList.value[0]?.id,
+        from: minDate,
+        to: maxDate,
+    };
+});
+const openReportPdf = () => {
+    openReport(`Clients/${route.params.id}/campaign-metrics-pdf`, getParams());
+};
+
+const openSendEmailDialog = async () => {
+    openConfirmationModal(
+        t('The consumption report will be sent'),
+        t('Please, confirm'),
+        () => sendCampaignMetricsEmail({ address: arrayData.store.data.email })
+    );
+};
+const sendCampaignMetricsEmail = ({ address }) => {
+    sendEmail(`Clients/${route.params.id}/campaign-metrics-email`, {
+        recipient: address,
+        ...getParams(),
+    });
+};
 </script>
 
 <template>
-    <Teleport to="#right-panel" v-if="useStateStore().isHeaderMounted()">
-        <CustomerConsumptionFilter data-key="CustomerConsumption" />
-    </Teleport>
+    <VnTable
+        v-if="campaignList"
+        data-key="CustomerConsumption"
+        url="Clients/consumption"
+        :order="['itemTypeFk', 'itemName', 'itemSize', 'description']"
+        :columns="columns"
+        search-url="consumption"
+        :filter="filter"
+        :user-params="userParams"
+        :default-remove="false"
+        :default-reset="false"
+        :default-save="false"
+        :has-sub-toolbar="true"
+        auto-load
+    >
+        <template #moreBeforeActions>
+            <QBtn
+                color="primary"
+                flat
+                icon-right="picture_as_pdf"
+                @click="openReportPdf()"
+                :disabled="!showActionBtns"
+            >
+                <QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                color="primary"
+                flat
+                icon-right="email"
+                @click="openSendEmailDialog()"
+                :disabled="!showActionBtns"
+            >
+                <QTooltip>{{ t('Send to email') }}</QTooltip>
+            </QBtn>
+        </template>
+        <template #column-itemFk="{ row }">
+            <span class="link">
+                {{ row.itemFk }}
+                <ItemDescriptorProxy :id="row.itemFk" />
+            </span>
+        </template>
+        <template #column-ticketFk="{ row }">
+            <span class="link">
+                {{ row.ticketFk }}
+                <TicketDescriptorProxy :id="row.ticketFk" />
+            </span>
+        </template>
+        <template #column-description="{ row }">
+            <div>{{ row.concept }}</div>
+            <div v-if="row.subName" class="subName">
+                {{ row.subName }}
+            </div>
+            <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
+                    v-model="params.campaign"
+                    :options="campaignList"
+                    :label="t('globals.campaign')"
+                    :filled="true"
+                    class="q-px-sm q-pt-none fit"
+                    dense
+                    option-label="code"
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel>
+                                    {{ scope.opt?.code }}
+                                    {{
+                                        new Date(scope.opt?.dated).getFullYear()
+                                    }}</QItemLabel
+                                >
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
+                <VnInputDate
+                    v-model="params.from"
+                    :label="t('globals.from')"
+                    :filled="true"
+                    class="q-px-xs q-pt-none fit"
+                    dense
+                />
+                <VnInputDate
+                    v-model="params.to"
+                    :label="t('globals.to')"
+                    :filled="true"
+                    class="q-px-xs q-pt-none fit"
+                    dense
+                />
+            </div>
+        </template>
+    </VnTable>
 </template>
 
 <i18n>
 es:
     Enter a new search: Introduce una nueva búsqueda
+    Group by items: Agrupar por artículos
 </i18n>
diff --git a/src/pages/Customer/Card/CustomerConsumptionFilter.vue b/src/pages/Customer/Card/CustomerConsumptionFilter.vue
deleted file mode 100644
index 4d2c5ff3c..000000000
--- a/src/pages/Customer/Card/CustomerConsumptionFilter.vue
+++ /dev/null
@@ -1,91 +0,0 @@
-<script setup>
-import { useI18n } from 'vue-i18n';
-import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import { QItem } from 'quasar';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import { QItemSection } from 'quasar';
-
-const { t } = useI18n();
-defineProps({ dataKey: { type: String, required: true } });
-</script>
-<template>
-    <VnFilterPanel :data-key="dataKey" :search-button="true">
-        <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 }">
-            <QItem>
-                <QItemSection>
-                    <VnInput
-                        :label="t('params.item')"
-                        v-model="params.itemId"
-                        is-outlined
-                        lazy-rules
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnSelect
-                        v-model="params.buyerId"
-                        url="TicketRequests/getItemTypeWorker"
-                        :label="t('params.buyer')"
-                        option-value="id"
-                        option-label="nickname"
-                        dense
-                        outlined
-                        rounded
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <!--It's required to include the relation category !! There's 413 records in production-->
-                <QItemSection>
-                    <VnSelect
-                        v-model="params.typeId"
-                        url="ItemTypes"
-                        :label="t('params.type')"
-                        option-label="name"
-                        option-value="id"
-                        dense
-                        outlined
-                        rounded
-                    >
-                    </VnSelect>
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnSelect
-                        url="ItemCategories"
-                        :label="t('params.category')"
-                        option-label="name"
-                        option-value="id"
-                        v-model="params.categoryId"
-                        dense
-                        outlined
-                        rounded
-                    />
-                </QItemSection>
-            </QItem>
-        </template>
-    </VnFilterPanel>
-</template>
-<i18n>
-en:
-    params:
-        item: Item id
-        buyer: Buyer
-        type: Type
-        category: Category
-es:
-    params:
-        item: Id artículo
-        buyer: Comprador
-        type: Tipo
-        category: Categoría
-</i18n>
diff --git a/src/pages/Customer/Card/CustomerCreditContracts.vue b/src/pages/Customer/Card/CustomerCreditContracts.vue
index 568adcf0b..0ff074793 100644
--- a/src/pages/Customer/Card/CustomerCreditContracts.vue
+++ b/src/pages/Customer/Card/CustomerCreditContracts.vue
@@ -53,6 +53,8 @@ const openDialog = (item) => {
             promise: updateData,
         },
     });
+    updateData();
+    showQPageSticky.value = true;
 };
 
 const openViewCredit = (credit) => {
@@ -193,6 +195,7 @@ const updateData = () => {
             color="primary"
             fab
             icon="add"
+            shortcut="+"
         />
         <QTooltip>
             {{ t('New contract') }}
diff --git a/src/pages/Customer/Card/CustomerCreditOpinion.vue b/src/pages/Customer/Card/CustomerCreditOpinion.vue
index 9c060b1a5..92fef1d76 100644
--- a/src/pages/Customer/Card/CustomerCreditOpinion.vue
+++ b/src/pages/Customer/Card/CustomerCreditOpinion.vue
@@ -1,23 +1,17 @@
 <script setup>
-import { computed, ref, watch } from 'vue';
+import { computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
-import { QBtn } from 'quasar';
-
 import { toCurrency, toDateHourMin } from 'src/filters';
+import VnTable from 'src/components/VnTable/VnTable.vue';
 
-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 WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 
 const { t } = useI18n();
 const route = useRoute();
 
-const clientInformasRef = ref(null);
-const rows = ref([]);
+const tableRef = ref();
 
 const filter = {
     include: [
@@ -37,10 +31,9 @@ const filter = {
 const columns = computed(() => [
     {
         align: 'left',
-        field: 'created',
-        format: (value) => toDateHourMin(value),
+        format: ({ created }) => toDateHourMin(created),
         label: t('Since'),
-        name: 'since',
+        name: 'created',
     },
     {
         align: 'left',
@@ -51,66 +44,56 @@ const columns = computed(() => [
     {
         align: 'right',
         field: 'rating',
-        label: t('Rating'),
+        label: t('customer.summary.rating'),
         name: 'rating',
+        create: true,
+        columnCreate: {
+            component: 'number',
+            autofocus: true,
+        },
     },
     {
         align: 'right',
         field: 'recommendedCredit',
-        format: (value) => toCurrency(value),
-        label: t('Recommended credit'),
+        format: ({ recommendedCredit }) => toCurrency(recommendedCredit),
+        label: t('customer.summary.recommendCredit'),
         name: 'recommendedCredit',
+        create: true,
+        columnCreate: {
+            component: 'number',
+            autofocus: true,
+        },
     },
 ]);
-
-watch(
-    () => route.params.id,
-    (newValue) => {
-        if (!newValue) return;
-        filter.where.clientFk = newValue;
-        clientInformasRef.value?.fetch();
-    }
-);
 </script>
 
 <template>
-    <FetchData
-        :filter="filter"
-        @on-fetch="(data) => (rows = data)"
-        auto-load
-        ref="clientInformasRef"
+    <VnTable
+        ref="tableRef"
+        data-key="ClientInformas"
         url="ClientInformas"
-    />
-
-    <FormModel
-        :form-initial-data="{}"
-        :observe-form-changes="false"
-        :url-create="`Clients/${route.params.id}/setRating`"
+        :filter="filter"
+        :order="['created DESC']"
+        :columns="columns"
+        :right-search="false"
+        :is-editable="false"
+        :use-model="true"
+        :column-search="false"
+        :disable-option="{ card: true }"
+        auto-load
+        :create="{
+            urlCreate: `Clients/${route.params.id}/setRating`,
+            title: 'Create rating',
+            onDataSaved: () => tableRef.reload(),
+            formInitialData: {},
+        }"
     >
-        <template #form="{ data }">
-            <VnRow>
-                <div class="col">
-                    <VnInput
-                        :label="t('Rating')"
-                        clearable
-                        type="number"
-                        v-model.number="data.rating"
-                    />
-                </div>
-                <div class="col">
-                    <VnInput
-                        :label="t('Recommended credit')"
-                        clearable
-                        type="number"
-                        v-model.number="data.recommendedCredit"
-                    />
-                </div>
-            </VnRow>
+        <template #column-employee="{ row }">
+            <span class="link">{{ row.worker.user.nickname }}</span>
+            <WorkerDescriptorProxy :id="row.worker.id" />
         </template>
-    </FormModel>
-
-    <div class="full-width flex justify-center" v-if="rows.length">
-        <QTable
+    </VnTable>
+    <!-- <QTable
             :columns="columns"
             :pagination="{ rowsPerPage: 0 }"
             :rows="rows"
@@ -120,22 +103,16 @@ watch(
             class="card-width q-px-lg"
         >
             <template #body-cell-employee="{ row }">
-                <QTd auto-width @click.stop>
-                    <QBtn color="blue" flat no-caps>{{ row.worker.user.nickname }}</QBtn>
+                <QTd @click.stop>
+                    <span class="link">{{ row.worker.user.nickname }}</span>
                     <WorkerDescriptorProxy :id="row.clientFk" />
                 </QTd>
             </template>
-        </QTable>
-    </div>
-
-    <h5 class="flex justify-center color-vn-label" v-else>
-        {{ t('globals.noResults') }}
-    </h5>
+        </QTable> -->
 </template>
 
 <i18n>
 es:
-    Rating: Clasificación
     Recommended credit: Crédito recomendado
     Since: Desde
     Employee: Empleado
diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue
index 0e76bcfed..b18f90d20 100644
--- a/src/pages/Customer/Card/CustomerDescriptor.vue
+++ b/src/pages/Customer/Card/CustomerDescriptor.vue
@@ -3,7 +3,7 @@ import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
-import { toCurrency, toDate } from 'src/filters';
+import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
 
 import useCardDescription from 'src/composables/useCardDescription';
 
@@ -11,6 +11,10 @@ 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 = computed(() => state.get('customer'));
 
 const $props = defineProps({
     id: {
@@ -43,7 +47,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
         :subtitle="data.subtitle"
         @on-fetch="setData"
         :summary="$props.summary"
-        data-key="customerData"
+        data-key="customer"
     >
         <template #menu="{ entity }">
             <CustomerDescriptorMenu :customer="entity" />
@@ -57,35 +61,46 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
                 :value="toCurrency(entity.creditInsurance)"
             />
 
-            <VnLv :label="t('customer.card.debt')" :value="toCurrency(entity.debt)" />
-            <VnLv v-if="entity.salesPersonUser" :label="t('customer.card.salesPerson')">
+            <VnLv
+                :label="t('customer.card.debt')"
+                :value="toCurrency(entity.debt)"
+                :info="t('customer.summary.riskInfo')"
+            />
+            <VnLv :label="t('customer.card.salesPerson')">
                 <template #value>
                     <VnUserLink
-                        :name="entity.salesPersonUser?.name"
+                        v-if="entity.salesPersonUser"
+                        :name="entity.salesPersonUser.name"
                         :worker-id="entity.salesPersonFk"
                     />
+                    <span v-else>{{ dashIfEmpty(entity.salesPersonUser) }}</span>
                 </template>
             </VnLv>
             <VnLv
                 :label="t('customer.card.businessTypeFk')"
-                :value="entity.businessTypeFk"
+                :value="entity.businessType.description"
             />
         </template>
-        <template #icons="{ entity }">
-            <QCardActions class="q-gutter-x-md">
+        <template #icons>
+            <QCardActions v-if="customer" class="q-gutter-x-md">
                 <QIcon
-                    v-if="!entity.isActive"
+                    v-if="!customer.isActive"
                     name="vn:disabled"
                     size="xs"
                     color="primary"
                 >
                     <QTooltip>{{ t('customer.card.isDisabled') }}</QTooltip>
                 </QIcon>
-                <QIcon v-if="entity.isFreezed" name="vn:frozen" size="xs" color="primary">
+                <QIcon
+                    v-if="customer.isFreezed"
+                    name="vn:frozen"
+                    size="xs"
+                    color="primary"
+                >
                     <QTooltip>{{ t('customer.card.isFrozen') }}</QTooltip>
                 </QIcon>
                 <QIcon
-                    v-if="!entity.account.active"
+                    v-if="!customer.account?.active"
                     color="primary"
                     name="vn:noweb"
                     size="xs"
@@ -93,7 +108,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
                     <QTooltip>{{ t('customer.card.webAccountInactive') }}</QTooltip>
                 </QIcon>
                 <QIcon
-                    v-if="entity.debt > entity.credit"
+                    v-if="customer.debt > customer.credit"
                     name="vn:risk"
                     size="xs"
                     color="primary"
@@ -101,7 +116,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
                     <QTooltip>{{ t('customer.card.hasDebt') }}</QTooltip>
                 </QIcon>
                 <QIcon
-                    v-if="!entity.isTaxDataChecked"
+                    v-if="!customer.isTaxDataChecked"
                     name="vn:no036"
                     size="xs"
                     color="primary"
@@ -109,7 +124,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
                     <QTooltip>{{ t('customer.card.notChecked') }}</QTooltip>
                 </QIcon>
                 <QBtn
-                    v-if="entity.unpaid"
+                    v-if="customer.unpaid"
                     flat
                     size="sm"
                     icon="vn:Client_unpaid"
@@ -121,13 +136,13 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
                         <br />
                         {{
                             t('unpaidDated', {
-                                dated: toDate(entity.unpaid.dated),
+                                dated: toDate(customer.unpaid.dated),
                             })
                         }}
                         <br />
                         {{
                             t('unpaidAmount', {
-                                amount: toCurrency(entity.unpaid.amount),
+                                amount: toCurrency(customer.unpaid.amount),
                             })
                         }}
                     </QTooltip>
@@ -139,7 +154,13 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
                 <QBtn
                     :to="{
                         name: 'TicketList',
-                        query: { table: JSON.stringify({ clientFk: entity.id }) },
+                        query: {
+                            from: undefined,
+                            to: undefined,
+                            table: JSON.stringify({
+                                clientFk: entity.id,
+                            }),
+                        },
                     }"
                     size="md"
                     icon="vn:ticket"
@@ -160,23 +181,8 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit
                 </QBtn>
                 <QBtn
                     :to="{
-                        name: 'OrderCreate',
-                        query: { clientId: entity.id },
-                    }"
-                    size="md"
-                    icon="vn:basketadd"
-                    color="primary"
-                >
-                    <QTooltip>{{ t('New order') }}</QTooltip>
-                </QBtn>
-                <QBtn
-                    :to="{
-                        name: 'AccountList',
-                        query: {
-                            table: JSON.stringify({
-                                filter: { where: { id: entity.id } },
-                            }),
-                        },
+                        name: 'AccountSummary',
+                        params: { id: entity.id },
                     }"
                     size="md"
                     icon="face"
@@ -197,7 +203,6 @@ es:
     Go to module index: Ir al índice del módulo
     Customer ticket list: Listado de tickets del cliente
     Customer invoice out list: Listado de facturas del cliente
-    New order: Nuevo pedido
     Go to user: Ir al usuario
     Customer unpaid: Cliente impago
     Unpaid: Impagado
diff --git a/src/pages/Customer/Card/CustomerDescriptorMenu.vue b/src/pages/Customer/Card/CustomerDescriptorMenu.vue
index 560ee51c8..89b10a4fe 100644
--- a/src/pages/Customer/Card/CustomerDescriptorMenu.vue
+++ b/src/pages/Customer/Card/CustomerDescriptorMenu.vue
@@ -8,6 +8,9 @@ import { useQuasar } from 'quasar';
 import useNotify from 'src/composables/useNotify';
 
 import VnSmsDialog from 'src/components/common/VnSmsDialog.vue';
+import TicketCreateDialog from 'src/pages/Ticket/TicketCreateDialog.vue';
+import OrderCreateDialog from 'src/pages/Order/Card/OrderCreateDialog.vue';
+import { ref } from 'vue';
 
 const $props = defineProps({
     customer: {
@@ -40,20 +43,32 @@ const sendSms = async (payload) => {
         notify(error.message, 'positive');
     }
 };
+
+const ticketCreateFormDialog = ref(null);
+const openTicketCreateForm = () => {
+    ticketCreateFormDialog.value.show();
+};
+const orderCreateFormDialog = ref(null);
+const openOrderCreateForm = () => {
+    orderCreateFormDialog.value.show();
+};
 </script>
 
 <template>
-    <QItem v-ripple clickable>
+    <QItem v-ripple clickable @click="openTicketCreateForm()">
         <QItemSection>
-            <RouterLink
-                :to="{
-                    name: 'TicketCreate',
-                    query: { clientFk: customer.id },
-                }"
-                class="color-vn-text"
-            >
-                {{ t('Simple ticket') }}
-            </RouterLink>
+            {{ t('globals.pageTitles.createTicket') }}
+            <QDialog ref="ticketCreateFormDialog">
+                <TicketCreateDialog />
+            </QDialog>
+        </QItemSection>
+    </QItem>
+    <QItem v-ripple clickable @click="openOrderCreateForm()">
+        <QItemSection>
+            {{ t('globals.pageTitles.createOrder') }}
+            <QDialog ref="orderCreateFormDialog">
+                <OrderCreateDialog :client-fk="customer.id" />
+            </QDialog>
         </QItemSection>
     </QItem>
     <QItem v-ripple clickable>
diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue
index 54b8adb70..d8c07a46f 100644
--- a/src/pages/Customer/Card/CustomerFiscalData.vue
+++ b/src/pages/Customer/Card/CustomerFiscalData.vue
@@ -93,7 +93,7 @@ function handleLocation(data, location) {
             <VnRow>
                 <VnLocation
                     :rules="validate('Worker.postcode')"
-                    :roles-allowed-to-create="['deliveryAssistant']"
+                    :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
                     :location="data"
                     @update:model-value="(location) => handleLocation(data, location)"
                 />
diff --git a/src/pages/Customer/Card/CustomerGreuges.vue b/src/pages/Customer/Card/CustomerGreuges.vue
index 12173727f..1d8b8585f 100644
--- a/src/pages/Customer/Card/CustomerGreuges.vue
+++ b/src/pages/Customer/Card/CustomerGreuges.vue
@@ -5,10 +5,10 @@ import { useRoute } from 'vue-router';
 import { toCurrency } from 'src/filters';
 import { toDateTimeFormat } from 'src/filters/date';
 import VnTable from 'components/VnTable/VnTable.vue';
-
+import FetchData from 'components/FetchData.vue';
+const entityId = computed(() => route.params.id);
 const { t } = useI18n();
 const route = useRoute();
-const rows = ref([]);
 const totalAmount = ref();
 const tableRef = ref();
 const filter = computed(() => {
@@ -28,7 +28,7 @@ const filter = computed(() => {
             },
         ],
         where: {
-            clientFk: route.params.id,
+            clientFk: entityId,
         },
     };
 });
@@ -47,7 +47,6 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'userFk',
         label: t('Created by'),
         component: 'userLink',
         attrs: ({ row }) => {
@@ -73,6 +72,7 @@ const columns = computed(() => [
         columnCreate: {
             component: 'select',
             url: 'greugeTypes',
+            sortBy: 'name ASC ',
             limit: 0,
         },
     },
@@ -84,14 +84,14 @@ const columns = computed(() => [
         create: true,
     },
 ]);
-
-const setRows = (data) => {
-    rows.value = data;
-    totalAmount.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0);
-};
 </script>
 
 <template>
+    <FetchData
+        :url="`Greuges/${entityId}/sumAmount`"
+        auto-load
+        @on-fetch="({ sumAmount }) => (totalAmount = sumAmount)"
+    ></FetchData>
     <VnTable
         ref="tableRef"
         data-key="Greuges"
@@ -104,10 +104,10 @@ const setRows = (data) => {
         :is-editable="false"
         :use-model="true"
         :column-search="false"
-        @on-fetch="(data) => setRows(data)"
+        :disable-option="{ card: true }"
         :create="{
             urlCreate: `Greuges`,
-            title: t('New credit'),
+            title: t('New greuge'),
             onDataSaved: () => tableRef.reload(),
             formInitialData: { shipped: new Date(), clientFk: route.params.id },
         }"
diff --git a/src/pages/Customer/Card/CustomerMandates.vue b/src/pages/Customer/Card/CustomerMandates.vue
index 7af3e5828..248515b4a 100644
--- a/src/pages/Customer/Card/CustomerMandates.vue
+++ b/src/pages/Customer/Card/CustomerMandates.vue
@@ -1,20 +1,19 @@
 <script setup>
-import { computed, ref } from 'vue';
+import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
 import { toDateTimeFormat } from 'src/filters/date';
 
-import FetchData from 'components/FetchData.vue';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import { dashIfEmpty } from 'src/filters';
 
 const { t } = useI18n();
 const route = useRoute();
 
-const rows = ref([]);
-
 const filter = {
     include: [
-        { relation: 'mandateType', scope: { fields: ['id', 'name'] } },
+        { relation: 'mandateType', scope: { fields: ['id', 'code'] } },
         { relation: 'company', scope: { fields: ['id', 'code'] } },
     ],
     where: { clientFk: route.params.id },
@@ -22,114 +21,61 @@ const filter = {
     limit: 20,
 };
 
-const tableColumnComponents = {
-    id: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    company: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    type: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    registerDate: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    endDate: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-};
-
 const columns = computed(() => [
     {
         align: 'left',
-        field: 'id',
-        label: t('Id'),
         name: 'id',
+        label: t('globals.id'),
+        field: 'id',
+        isId: true,
     },
     {
         align: 'left',
-        field: (row) => row.company.code,
-        label: t('Company'),
+        cardVisible: true,
+        format: ({ company }) => company.code,
+        label: t('globals.company'),
         name: 'company',
     },
     {
         align: 'left',
-        field: (row) => row.mandateType.name,
-        label: t('Type'),
+        cardVisible: true,
+        format: ({ mandateType }) => mandateType.code,
+        label: t('globals.type'),
         name: 'type',
     },
     {
         align: 'left',
-        field: 'created',
+        cardVisible: true,
         label: t('Register date'),
-        name: 'registerDate',
-        format: (value) => toDateTimeFormat(value),
+        name: 'created',
+        format: ({ created }) => toDateTimeFormat(created),
     },
     {
-        align: 'left',
-        field: 'finished',
+        align: 'right',
+        cardVisible: true,
+        name: 'finished',
         label: t('End date'),
-        name: 'endDate',
-        format: (value) => (value ? toDateTimeFormat(value) : '-'),
+        format: ({ finished }) => dashIfEmpty(toDateTimeFormat(finished)),
     },
 ]);
 </script>
 
 <template>
-    <FetchData
-        :filter="filter"
-        @on-fetch="(data) => (rows = data)"
-        auto-load
-        url="Mandates"
-    />
-
     <QPage class="column items-center q-pa-md">
-        <QTable
+        <VnTable
+            :filter="filter"
+            auto-load
+            url="Mandates"
             :columns="columns"
-            :pagination="{ rowsPerPage: 12 }"
-            :rows="rows"
             class="full-width q-mt-md"
-            row-key="id"
-            v-if="rows?.length"
-        >
-            <template #body-cell="props">
-                <QTd :props="props">
-                    <QTr :props="props" class="cursor-pointer">
-                        <component
-                            :is="tableColumnComponents[props.col.name].component"
-                            @click="tableColumnComponents[props.col.name].event(props)"
-                            class="rounded-borders q-pa-sm"
-                            v-bind="tableColumnComponents[props.col.name].props(props)"
-                        >
-                            {{ props.value }}
-                        </component>
-                    </QTr>
-                </QTd>
-            </template>
-        </QTable>
-
-        <h5 class="flex justify-center color-vn-label" v-else>
-            {{ t('globals.noResults') }}
-        </h5>
+            :right-search="false"
+            :row-click="false"
+        />
     </QPage>
 </template>
 
 <i18n>
 es:
-    Id: Id
-    Company: Empresa
-    Type: Tipo
     Register date: Fecha alta
     End date: Fecha baja
 </i18n>
diff --git a/src/pages/Customer/Card/CustomerRecoveries.vue b/src/pages/Customer/Card/CustomerRecoveries.vue
index 8d3d05702..48576ca20 100644
--- a/src/pages/Customer/Card/CustomerRecoveries.vue
+++ b/src/pages/Customer/Card/CustomerRecoveries.vue
@@ -89,9 +89,10 @@ function setFinished(id) {
         :columns="columns"
         :use-model="true"
         :right-search="false"
+        :disable-option="{ card: true }"
         :create="{
             urlCreate: 'Recoveries',
-            title: 'New recovery',
+            title: t('New recovery'),
             onDataSaved: () => tableRef.reload(),
             formInitialData: { clientFk: route.params.id, started: Date.vnNew() },
         }"
diff --git a/src/pages/Customer/Card/CustomerSamples.vue b/src/pages/Customer/Card/CustomerSamples.vue
index de998d8d3..8e2ab92a0 100644
--- a/src/pages/Customer/Card/CustomerSamples.vue
+++ b/src/pages/Customer/Card/CustomerSamples.vue
@@ -1,19 +1,18 @@
 <script setup>
 import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useRoute, useRouter } from 'vue-router';
+import { useRoute } from 'vue-router';
 
-import { QBtn } from 'quasar';
+import { QBtn, useQuasar } from 'quasar';
 
-import FetchData from 'components/FetchData.vue';
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 import { toDateTimeFormat } from 'src/filters/date';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import { dashIfEmpty } from 'src/filters';
+import CustomerSamplesCreate from '../components/CustomerSamplesCreate.vue';
 
 const { t } = useI18n();
 const route = useRoute();
-const router = useRouter();
-
-const rows = ref([]);
 
 const filter = {
     include: [
@@ -26,105 +25,78 @@ const filter = {
     limit: 20,
 };
 
-const tableColumnComponents = {
-    sent: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    description: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    worker: {
-        component: QBtn,
-        props: () => ({ flat: true, color: 'blue', noCaps: true }),
-        event: () => {},
-    },
-    company: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-};
-
 const columns = computed(() => [
     {
         align: 'left',
-        field: 'created',
+        name: 'created',
         label: t('Sent'),
-        name: 'sent',
-        format: (value) => toDateTimeFormat(value),
+        format: ({ created }) => toDateTimeFormat(created),
     },
     {
         align: 'left',
-        field: (value) => value.type.description,
+        format: (row) => row.type.description,
         label: t('Description'),
         name: 'description',
     },
     {
         align: 'left',
-        field: (value) => value.user.name,
         label: t('Worker'),
-        name: 'worker',
+        columnField: {
+            component: 'userLink',
+            attrs: ({ row }) => {
+                return {
+                    defaultName: true,
+                    workerId: row?.user?.id,
+                    name: row?.user?.name,
+                };
+            },
+        },
     },
     {
         align: 'left',
-        field: (value) => value.company?.code,
+        format: ({ company }) => company?.code ?? dashIfEmpty(company),
         label: t('Company'),
         name: 'company',
     },
 ]);
+const quasar = useQuasar();
 
 const toCustomerSamplesCreate = () => {
-    router.push({ name: 'CustomerSamplesCreate' });
+    quasar
+        .dialog({
+            component: CustomerSamplesCreate,
+        })
+        .onOk(() => tableRef.value.reload());
 };
+const tableRef = ref();
 </script>
 
 <template>
-    <FetchData
-        :filter="filter"
-        @on-fetch="(data) => (rows = data)"
+    <VnTable
+        ref="tableRef"
+        data-key="ClientSamples"
         auto-load
+        :filter="filter"
         url="ClientSamples"
-    />
-
-    <div class="full-width flex justify-center">
-        <QPage class="card-width q-pa-lg">
-            <QTable
-                :columns="columns"
-                :pagination="{ rowsPerPage: 12 }"
-                :rows="rows"
-                class="full-width q-mt-md"
-                row-key="id"
-                :no-data-label="t('globals.noResults')"
-            >
-                <template #body-cell="props">
-                    <QTd :props="props">
-                        <QTr :props="props" class="cursor-pointer">
-                            <component
-                                :is="tableColumnComponents[props.col.name].component"
-                                class="col-content"
-                                v-bind="
-                                    tableColumnComponents[props.col.name].props(props)
-                                "
-                                @click="
-                                    tableColumnComponents[props.col.name].event(props)
-                                "
-                            >
-                                {{ props.value }}
-                                <WorkerDescriptorProxy
-                                    :id="props.row.userFk"
-                                    v-if="props.col.name === 'worker'"
-                                />
-                            </component>
-                        </QTr>
-                    </QTd>
-                </template>
-            </QTable>
-        </QPage>
-    </div>
+        :columns="columns"
+        :pagination="{ rowsPerPage: 12 }"
+        :disable-option="{ card: true }"
+        :right-search="false"
+        :rows="rows"
+        :order="['created DESC']"
+        class="full-width q-mt-md"
+        row-key="id"
+        :create="false"
+        :no-data-label="t('globals.noResults')"
+    >
+        <template #column-worker="{ row }">
+            <div v-if="row.user">
+                <span class="link">{{ row.user?.name }}</span
+                ><WorkerDescriptorProxy :id="row.userFk" />
+            </div>
+            <span v-else>{{ dashIfEmpty(row.user) }}</span>
+        </template>
+    </VnTable>
 
     <QPageSticky :offset="[18, 18]">
         <QBtn @click.stop="toCustomerSamplesCreate()" color="primary" fab icon="add" />
diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue
index 15bf19b48..f049426e2 100644
--- a/src/pages/Customer/Card/CustomerSummary.vue
+++ b/src/pages/Customer/Card/CustomerSummary.vue
@@ -1,10 +1,11 @@
 <script setup>
-import { computed, ref, onMounted } from 'vue';
+import { computed, ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
+import VnUserLink from 'src/components/ui/VnUserLink.vue';
+
 import { toCurrency, toPercentage, toDate } from 'src/filters';
 import CardSummary from 'components/ui/CardSummary.vue';
-import { getUrl } from 'src/composables/getUrl';
 import VnLv from 'src/components/ui/VnLv.vue';
 import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
 import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue';
@@ -23,11 +24,6 @@ const $props = defineProps({
 const entityId = computed(() => $props.id || route.params.id);
 const customer = computed(() => summary.value.entity);
 const summary = ref();
-const clientUrl = ref();
-
-onMounted(async () => {
-    clientUrl.value = (await getUrl('client/')) + entityId.value + '/';
-});
 
 const balanceDue = computed(() => {
     return (
@@ -40,11 +36,11 @@ const balanceDue = computed(() => {
 const balanceDueWarning = computed(() => (balanceDue.value ? 'negative' : ''));
 
 const claimRate = computed(() => {
-    return customer.value.claimsRatio.claimingRate;
+    return customer.value.claimsRatio?.claimingRate ?? 0;
 });
 
 const priceIncreasingRate = computed(() => {
-    return customer.value.claimsRatio.priceIncreasing / 100;
+    return customer.value.claimsRatio?.priceIncreasing ?? 0 / 100;
 });
 
 const debtWarning = computed(() => {
@@ -58,6 +54,11 @@ const creditWarning = computed(() => {
 
     return tooMuchInsurance || noCreditInsurance ? 'negative' : '';
 });
+const sumRisk = ({ clientRisks }) => {
+    let total = clientRisks.reduce((acc, { amount }) => acc + amount, 0);
+
+    return total;
+};
 </script>
 
 <template>
@@ -91,7 +92,13 @@ const creditWarning = computed(() => {
                 <VnLv
                     :label="t('customer.summary.salesPerson')"
                     :value="entity?.salesPersonUser?.name"
-                />
+                >
+                    <template #value>
+                        <VnUserLink
+                            :name="entity.salesPersonUser?.name"
+                            :worker-id="entity.salesPersonFk"
+                        /> </template
+                ></VnLv>
                 <VnLv
                     :label="t('customer.summary.contactChannel')"
                     :value="entity?.contactChannel?.name"
@@ -131,7 +138,7 @@ const creditWarning = computed(() => {
                     :url="`#/customer/${entityId}/fiscal-data`"
                     :text="t('customer.summary.fiscalData')"
                 />
-                <VnRow>
+                <VnRow class="block">
                     <VnLv
                         :label="t('customer.summary.isEqualizated')"
                         :value="entity.isEqualizated"
@@ -140,8 +147,6 @@ const creditWarning = computed(() => {
                         :label="t('customer.summary.isActive')"
                         :value="entity.isActive"
                     />
-                </VnRow>
-                <VnRow>
                     <VnLv
                         :label="t('customer.summary.verifiedData')"
                         :value="entity.isTaxDataChecked"
@@ -150,8 +155,6 @@ const creditWarning = computed(() => {
                         :label="t('customer.summary.hasToInvoice')"
                         :value="entity.hasToInvoice"
                     />
-                </VnRow>
-                <VnRow>
                     <VnLv
                         :label="t('customer.summary.notifyByEmail')"
                         :value="entity.isToBeMailed"
@@ -162,7 +165,7 @@ const creditWarning = computed(() => {
             <QCard class="vn-one">
                 <VnTitle
                     :url="`#/customer/${entityId}/billing-data`"
-                    :text="t('customer.summary.billingData')"
+                    :text="t('customer.summary.payMethodFk')"
                 />
                 <VnLv
                     :label="t('customer.summary.payMethod')"
@@ -170,7 +173,7 @@ const creditWarning = computed(() => {
                 />
                 <VnLv :label="t('customer.summary.bankAccount')" :value="entity.iban" />
                 <VnLv :label="t('customer.summary.dueDay')" :value="entity.dueDay" />
-                <VnRow class="q-mt-sm" wrap>
+                <VnRow class="q-mt-sm block">
                     <VnLv :label="t('customer.summary.hasLcr')" :value="entity.hasLcr" />
                     <VnLv
                         :label="t('customer.summary.hasCoreVnl')"
@@ -185,7 +188,7 @@ const creditWarning = computed(() => {
             </QCard>
             <QCard class="vn-one" v-if="entity.defaultAddress">
                 <VnTitle
-                    :url="`#/customer/${entityId}/consignees`"
+                    :url="`#/customer/${entityId}/address`"
                     :text="t('customer.summary.consignee')"
                 />
                 <VnLv
@@ -217,7 +220,11 @@ const creditWarning = computed(() => {
                 />
             </QCard>
             <QCard class="vn-one" v-if="entity.account">
-                <VnTitle :text="t('customer.summary.businessData')" />
+                <VnTitle
+                    :url="`${grafanaUrl}/d/adjlxzv5yjt34d/analisis-de-clientes-7c-crm?orgId=1&var-clientFk=${entityId}`"
+                    :text="t('customer.summary.businessData')"
+                    icon="vn:grafana"
+                />
                 <VnLv
                     :label="t('customer.summary.totalGreuge')"
                     :value="toCurrency(entity.totalGreuge)"
@@ -227,7 +234,6 @@ const creditWarning = computed(() => {
                     :value="toCurrency(entity?.mana?.mana)"
                 />
                 <VnLv
-                    v-if="entity.claimsRatio"
                     :label="t('customer.summary.priceIncreasingRate')"
                     :value="toPercentage(priceIncreasingRate)"
                 />
@@ -236,15 +242,14 @@ const creditWarning = computed(() => {
                     :value="toCurrency(entity?.averageInvoiced?.invoiced)"
                 />
                 <VnLv
-                    v-if="entity.claimsRatio"
                     :label="t('customer.summary.claimRate')"
                     :value="toPercentage(claimRate)"
                 />
             </QCard>
             <QCard class="vn-one" v-if="entity.account">
                 <VnTitle
-                    :url="`https://grafana.verdnatura.es/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`"
-                    :text="t('customer.summary.financialData')"
+                    :url="`${grafanaUrl}/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`"
+                    :text="t('customer.summary.payMethodFk')"
                     icon="vn:grafana"
                 />
                 <VnLv
@@ -262,15 +267,13 @@ const creditWarning = computed(() => {
                 />
 
                 <VnLv
-                    v-if="entity.creditInsurance"
                     :label="t('customer.summary.securedCredit')"
                     :value="toCurrency(entity.creditInsurance)"
                     :info="t('customer.summary.securedCreditInfo')"
                 />
-
                 <VnLv
                     :label="t('customer.summary.balance')"
-                    :value="toCurrency(entity.sumRisk) || toCurrency(0)"
+                    :value="toCurrency(sumRisk(entity)) || toCurrency(0)"
                     :info="t('customer.summary.balanceInfo')"
                 />
 
@@ -297,7 +300,7 @@ const creditWarning = computed(() => {
                     :value="entity.recommendedCredit"
                 />
             </QCard>
-            <QCard class="vn-one">
+            <QCard>
                 <VnTitle :text="t('Latest tickets')" />
                 <CustomerSummaryTable />
             </QCard>
diff --git a/src/pages/Customer/Card/CustomerUnpaid.vue b/src/pages/Customer/Card/CustomerUnpaid.vue
index 5b9a6cde2..ad00cbf59 100644
--- a/src/pages/Customer/Card/CustomerUnpaid.vue
+++ b/src/pages/Customer/Card/CustomerUnpaid.vue
@@ -151,7 +151,10 @@ watch(
                             clearable
                             type="number"
                             v-model="amount"
-                        />
+                            autofocus
+                        >
+                            <template #append>€</template></VnInput
+                        >
                     </div>
                 </VnRow>
             </QForm>
diff --git a/src/pages/Customer/Card/CustomerWebPayment.vue b/src/pages/Customer/Card/CustomerWebPayment.vue
index 13ec6b128..482582078 100644
--- a/src/pages/Customer/Card/CustomerWebPayment.vue
+++ b/src/pages/Customer/Card/CustomerWebPayment.vue
@@ -5,7 +5,7 @@ import { useRoute } from 'vue-router';
 
 import axios from 'axios';
 
-import { toCurrency, toDateHourMinSec } from 'src/filters';
+import { toCurrency, toDateHourMin } from 'src/filters';
 
 import CustomerCloseIconTooltip from '../components/CustomerCloseIconTooltip.vue';
 import CustomerCheckIconTooltip from '../components/CustomerCheckIconTooltip.vue';
@@ -74,7 +74,7 @@ const columns = computed(() => [
         field: 'created',
         label: t('Date'),
         name: 'date',
-        format: (value) => toDateHourMinSec(value),
+        format: (value) => toDateHourMin(value),
     },
     {
         align: 'left',
diff --git a/src/pages/Customer/CustomerCreate.vue b/src/pages/Customer/CustomerCreate.vue
index 193ed59c9..79da63283 100644
--- a/src/pages/Customer/CustomerCreate.vue
+++ b/src/pages/Customer/CustomerCreate.vue
@@ -86,7 +86,8 @@ function handleLocation(data, location) {
                 <VnRow>
                     <VnLocation
                         :rules="validate('Worker.postcode')"
-                        :roles-allowed-to-create="['deliveryAssistant']"
+                        :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
+                        v-model="data.location"
                         @update:model-value="(location) => handleLocation(data, location)"
                     >
                     </VnLocation>
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index 1dc0dab43..f6758bf4e 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -2,6 +2,7 @@
 import { ref, computed, markRaw } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
+import VnSelect from 'src/components/common/VnSelect.vue';
 import VnTable from 'components/VnTable/VnTable.vue';
 import VnLocation from 'src/components/common/VnLocation.vue';
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
@@ -69,7 +70,7 @@ const columns = computed(() => [
             optionFilter: 'firstName',
             useLike: false,
         },
-        create: true,
+        create: false,
         columnField: {
             component: null,
         },
@@ -195,6 +196,8 @@ const columns = computed(() => [
         component: 'select',
         attrs: {
             url: 'BusinessTypes',
+            fields: ['code', 'description'],
+            sortBy: 'description ASC ',
             optionLabel: 'description',
             optionValue: 'code',
         },
@@ -353,12 +356,13 @@ const columns = computed(() => [
             {
                 title: t('Client ticket list'),
                 icon: 'vn:ticket',
-                action: redirectToCreateView,
+                action: redirectToTicketsList,
                 isPrimary: true,
             },
             {
-                title: t('Client ticket list'),
+                title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
+                isPrimary: true,
                 action: (row) => viewSummary(row.id, CustomerSummary),
             },
         ],
@@ -366,11 +370,12 @@ const columns = computed(() => [
 ]);
 
 const { viewSummary } = useSummaryDialog();
-const redirectToCreateView = (row) => {
+const redirectToTicketsList = (row) => {
     router.push({
         name: 'TicketList',
+
         query: {
-            params: JSON.stringify({
+            table: JSON.stringify({
                 clientFk: row.id,
             }),
         },
@@ -395,10 +400,10 @@ function handleLocation(data, location) {
     <VnTable
         ref="tableRef"
         data-key="Customer"
-        url="Clients/extendedListFilter"
+        url="Clients/filter"
         :create="{
             urlCreate: 'Clients/createWithUser',
-            title: 'Create client',
+            title: t('globals.pageTitles.customerCreate'),
             onDataSaved: ({ id }) => tableRef.redirect(id),
             formInitialData: {
                 active: true,
@@ -411,8 +416,42 @@ function handleLocation(data, location) {
         auto-load
     >
         <template #more-create-dialog="{ data }">
+            <VnSelect
+                url="Workers/search"
+                v-model="data.salesPersonFk"
+                :label="t('customer.basicData.salesPerson')"
+                :params="{
+                    departmentCodes: ['VT', 'shopping'],
+                }"
+                :fields="['id', 'nickname']"
+                sort-by="nickname ASC"
+                :use-like="false"
+                emit-value
+                auto-load
+            >
+                <template #prepend>
+                    <VnAvatar
+                        :worker-id="data.salesPersonFk"
+                        color="primary"
+                        :title="title"
+                    />
+                </template>
+                <template #option="scope">
+                    <QItem v-bind="scope.itemProps">
+                        <QItemSection>
+                            <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
+                            <QItemLabel caption
+                                >{{ scope.opt?.nickname }},
+                                {{ scope.opt?.code }}</QItemLabel
+                            >
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
+
             <VnLocation
-                :roles-allowed-to-create="['deliveryAssistant']"
+                :acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
+                v-model="data.location"
                 @update:model-value="(location) => handleLocation(data, location)"
             />
             <QInput v-model="data.userName" :label="t('Web user')" />
diff --git a/src/pages/Customer/components/CustomerAddressCreate.vue b/src/pages/Customer/components/CustomerAddressCreate.vue
index e37306a94..7826c3579 100644
--- a/src/pages/Customer/components/CustomerAddressCreate.vue
+++ b/src/pages/Customer/components/CustomerAddressCreate.vue
@@ -57,12 +57,12 @@ function handleLocation(data, location) {
 </script>
 
 <template>
-    <fetch-data
+    <FetchData
         @on-fetch="(data) => (agencyModes = data)"
         auto-load
         url="AgencyModes/isActive"
     />
-    <fetch-data @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
+    <FetchData @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
 
     <FormModel
         :form-initial-data="formInitialData"
@@ -92,7 +92,8 @@ function handleLocation(data, location) {
 
             <VnLocation
                 :rules="validate('Worker.postcode')"
-                :roles-allowed-to-create="['deliveryAssistant']"
+                :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
+                v-model="data.location"
                 @update:model-value="(location) => handleLocation(data, location)"
             />
 
diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index 133d2fabc..2252a96dc 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -113,18 +113,18 @@ function handleLocation(data, location) {
 </script>
 
 <template>
-    <fetch-data
+    <FetchData
         @on-fetch="(data) => (agencyModes = data)"
         auto-load
         url="AgencyModes/isActive"
     />
-    <fetch-data @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
-    <fetch-data
+    <FetchData @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
+    <FetchData
         @on-fetch="(data) => (customsAgents = data)"
         auto-load
         url="CustomsAgents"
     />
-    <fetch-data @on-fetch="getData" auto-load url="ObservationTypes" />
+    <FetchData @on-fetch="getData" auto-load url="ObservationTypes" />
 
     <FormModel
         :observe-form-changes="false"
@@ -176,7 +176,7 @@ function handleLocation(data, location) {
                 <div class="col">
                     <VnLocation
                         :rules="validate('Worker.postcode')"
-                        :roles-allowed-to-create="['deliveryAssistant']"
+                        :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
                         :location="{
                             postcode: data.postalCode,
                             city: data.city,
diff --git a/src/pages/Customer/components/CustomerCreditContractsCreate.vue b/src/pages/Customer/components/CustomerCreditContractsCreate.vue
index c4434e870..c25e59e1a 100644
--- a/src/pages/Customer/components/CustomerCreditContractsCreate.vue
+++ b/src/pages/Customer/components/CustomerCreditContractsCreate.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { reactive } from 'vue';
+import { reactive, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
 
@@ -10,10 +10,12 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
 
 const { t } = useI18n();
 const route = useRoute();
+const routeId = computed(() => route.params.id);
 const router = useRouter();
 
 const initialData = reactive({
-    clientFK: Number(route.params.id),
+    started: Date.vnNew(),
+    clientFk: routeId.value,
 });
 
 const toCustomerCreditContracts = () => {
diff --git a/src/pages/Customer/components/CustomerCreditContractsInsurance.vue b/src/pages/Customer/components/CustomerCreditContractsInsurance.vue
index ce880d4b5..70f7cf046 100644
--- a/src/pages/Customer/components/CustomerCreditContractsInsurance.vue
+++ b/src/pages/Customer/components/CustomerCreditContractsInsurance.vue
@@ -1,47 +1,26 @@
 <script setup>
-import { computed, ref } from 'vue';
+import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
-import { toCurrency, toDateHourMinSec } from 'src/filters';
+import { toCurrency, toDate } from 'src/filters';
 
-import FetchData from 'components/FetchData.vue';
+import VnTable from 'src/components/VnTable/VnTable.vue';
 
 const { t } = useI18n();
 const route = useRoute();
 
-const rows = ref([]);
-
 const filter = {
     where: {
         creditClassificationFk: `${route.params.creditId}`,
     },
     limit: 20,
 };
-
-const tableColumnComponents = {
-    created: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    grade: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    credit: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-};
-
 const columns = computed(() => [
     {
         align: 'left',
         field: 'created',
-        format: (value) => toDateHourMinSec(value),
+        format: ({ created }) => toDate(created),
         label: t('Created'),
         name: 'created',
     },
@@ -53,8 +32,7 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        field: 'credit',
-        format: (value) => toCurrency(value),
+        format: ({ credit }) => toCurrency(credit),
         label: t('Credit'),
         name: 'credit',
     },
@@ -62,41 +40,19 @@ const columns = computed(() => [
 </script>
 
 <template>
-    <FetchData
-        :filter="filter"
-        @on-fetch="(data) => (rows = data)"
-        auto-load
+    <VnTable
         url="CreditInsurances"
-    />
-
-    <QPage class="column items-center q-pa-md" v-if="rows.length">
-        <QTable
-            :columns="columns"
-            :pagination="{ rowsPerPage: 12 }"
-            :rows="rows"
-            class="full-width q-mt-md"
-            row-key="id"
-        >
-            <template #body-cell="props">
-                <QTd :props="props">
-                    <QTr :props="props" class="cursor-pointer">
-                        <component
-                            :is="tableColumnComponents[props.col.name].component"
-                            class="col-content"
-                            v-bind="tableColumnComponents[props.col.name].props(props)"
-                            @click="tableColumnComponents[props.col.name].event(props)"
-                        >
-                            {{ props.value }}
-                        </component>
-                    </QTr>
-                </QTd>
-            </template>
-        </QTable>
-    </QPage>
-
-    <h5 class="flex justify-center color-vn-label" v-else>
-        {{ t('globals.noResults') }}
-    </h5>
+        ref="tableRef"
+        data-key="creditInsurances"
+        :filter="filter"
+        :columns="columns"
+        :right-search="false"
+        :is-editable="false"
+        :use-model="true"
+        :column-search="false"
+        :disable-option="{ card: true }"
+        auto-load
+    ></VnTable>
 </template>
 
 <i18n>
diff --git a/src/pages/Customer/components/CustomerFileManagementCreate.vue b/src/pages/Customer/components/CustomerFileManagementCreate.vue
index 7c15e0b71..f33a47bcc 100644
--- a/src/pages/Customer/components/CustomerFileManagementCreate.vue
+++ b/src/pages/Customer/components/CustomerFileManagementCreate.vue
@@ -83,35 +83,35 @@ const toCustomerFileManagement = () => {
 </script>
 
 <template>
-    <fetch-data
+    <FetchData
         @on-fetch="(data) => (client = data)"
         auto-load
         :url="`Clients/${route.params.id}/getCard`"
     />
-    <fetch-data
+    <FetchData
         :filter="filterFindOne"
         @on-fetch="(data) => (findOne = data)"
         auto-load
         url="DmsTypes/findOne"
     />
-    <fetch-data
+    <FetchData
         @on-fetch="(data) => (allowedContentTypes = data)"
         auto-load
         url="DmsContainers/allowedContentTypes"
     />
-    <fetch-data
+    <FetchData
         :filter="filterCompanies"
         @on-fetch="(data) => (optionsCompanies = data)"
         auto-load
         url="Companies"
     />
-    <fetch-data
+    <FetchData
         :filter="filterWarehouses"
         @on-fetch="(data) => (optionsWarehouses = data)"
         auto-load
         url="Warehouses"
     />
-    <fetch-data
+    <FetchData
         :filter="filterWarehouses"
         @on-fetch="(data) => (optionsDmsTypes = data)"
         auto-load
diff --git a/src/pages/Customer/components/CustomerFileManagementEdit.vue b/src/pages/Customer/components/CustomerFileManagementEdit.vue
index 80eaa44f9..107f41330 100644
--- a/src/pages/Customer/components/CustomerFileManagementEdit.vue
+++ b/src/pages/Customer/components/CustomerFileManagementEdit.vue
@@ -69,25 +69,25 @@ const toCustomerFileManagement = () => {
 </script>
 
 <template>
-    <fetch-data :url="`Dms/${route.params.dmsId}`" @on-fetch="setCurrentDms" auto-load />
-    <fetch-data
+    <FetchData :url="`Dms/${route.params.dmsId}`" @on-fetch="setCurrentDms" auto-load />
+    <FetchData
         @on-fetch="(data) => (allowedContentTypes = data)"
         auto-load
         url="DmsContainers/allowedContentTypes"
     />
-    <fetch-data
+    <FetchData
         :filter="filterCompanies"
         @on-fetch="(data) => (optionsCompanies = data)"
         auto-load
         url="Companies"
     />
-    <fetch-data
+    <FetchData
         :filter="filterWarehouses"
         @on-fetch="(data) => (optionsWarehouses = data)"
         auto-load
         url="Warehouses"
     />
-    <fetch-data
+    <FetchData
         :filter="filterWarehouses"
         @on-fetch="(data) => (optionsDmsTypes = data)"
         auto-load
diff --git a/src/pages/Customer/components/CustomerSamplesCreate.vue b/src/pages/Customer/components/CustomerSamplesCreate.vue
index 0470dc176..3c9eb856b 100644
--- a/src/pages/Customer/components/CustomerSamplesCreate.vue
+++ b/src/pages/Customer/components/CustomerSamplesCreate.vue
@@ -1,10 +1,11 @@
 <script setup>
-import { onBeforeMount, reactive, ref } from 'vue';
+import { computed, onBeforeMount, reactive, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
 
 import axios from 'axios';
-import { useQuasar } from 'quasar';
+import { usePrintService } from 'composables/usePrintService';
+import { useDialogPluginComponent, useQuasar } from 'quasar';
 
 import { useState } from 'src/composables/useState';
 import { useValidator } from 'src/composables/useValidator';
@@ -16,7 +17,9 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 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 { useStateStore } from 'stores/useStateStore';
+import FormPopup from 'src/components/FormPopup.vue';
+
+const { dialogRef, onDialogOK } = useDialogPluginComponent();
 
 const { notify } = useNotify();
 const { t } = useI18n();
@@ -26,17 +29,17 @@ const route = useRoute();
 const router = useRouter();
 const state = useState();
 const user = state.getUser();
-const stateStore = useStateStore();
-
-const client = ref({});
+const { sendEmail } = usePrintService();
 const hasChanged = ref(false);
 const isLoading = ref(false);
-const optionsClientsAddressess = ref([]);
-const optionsCompanies = ref([]);
+const addressess = ref([]);
+const companies = ref([]);
 const optionsEmailUsers = ref([]);
 const optionsSamplesVisible = ref([]);
 const sampleType = ref({ hasPreview: false });
-
+const initialData = reactive({});
+const entityId = computed(() => route.params.id);
+const customer = computed(() => state.get('customer'));
 const filterEmailUsers = { where: { userFk: user.value.id } };
 const filterClientsAddresses = {
     include: [
@@ -58,14 +61,13 @@ const filterSamplesVisible = {
     ],
     order: ['description'],
 };
-const initialData = reactive({});
+
+defineEmits(['confirm', ...useDialogPluginComponent.emits]);
 
 onBeforeMount(async () => {
-    const { data } = await axios.get(`Clients/1/getCard`);
-    client.value = data;
-    initialData.clientFk = route.params?.id;
-    initialData.recipient = data.email;
-    initialData.recipientId = data.id;
+    initialData.clientFk = customer.value.id;
+    initialData.recipient = customer.value.email;
+    initialData.recipientId = customer.value.id;
 });
 
 const setEmailUser = (data) => {
@@ -75,7 +77,7 @@ const setEmailUser = (data) => {
 
 const setClientsAddresses = (data) => {
     initialData.addressId = data[0].id;
-    optionsClientsAddressess.value = data;
+    addressess.value = data;
 };
 
 const setSampleType = (sampleId) => {
@@ -88,20 +90,6 @@ const setSampleType = (sampleId) => {
     initialData.companyId = companyFk;
 };
 
-const setInitialData = () => {
-    hasChanged.value = false;
-
-    initialData.addressId = optionsClientsAddressess.value[0].id;
-    initialData.companyFk = null;
-    initialData.from = null;
-    initialData.recipient = client.value.email;
-    initialData.recipientId = client.value.id;
-    initialData.replyTo = optionsEmailUsers.value[0]?.email;
-    initialData.typeFk = '';
-
-    sampleType.value = {};
-};
-
 const validateMessage = () => {
     if (!initialData.recipient) return 'Email cannot be blank';
     if (!sampleType.value) return 'Choose a sample';
@@ -120,14 +108,14 @@ const setParams = (params) => {
 const getPreview = async () => {
     try {
         const params = {
-            recipientId: route.params.id,
+            recipientId: entityId,
         };
         const validationMessage = validateMessage();
         if (validationMessage) return notify(t(validationMessage), 'negative');
 
         setParams(params);
 
-        const path = `${sampleType.value.model}/${route.params.id}/${sampleType.value.code}-html`;
+        const path = `${sampleType.value.model}/${entityId.value}/${sampleType.value.code}-html`;
         const { data } = await axios.get(path, { params });
 
         if (!data) return;
@@ -156,22 +144,33 @@ const onSubmit = async () => {
     }
 };
 
-const onDataSaved = async ({
-    addressId,
-    companyFk,
-    companyId,
-    from,
-    recipient,
-    replyTo,
-}) => {
-    await axios.post(`Clients/${route.params.id}/incoterms-authorization-email`, {
-        addressId,
-        companyFk,
-        companyId,
-        from,
-        recipient,
-        replyTo,
-    });
+const getSamples = async () => {
+    try {
+        const filter = { where: { id: initialData.typeFk } };
+        let { data } = await axios.get('Samples', {
+            params: { filter: JSON.stringify(filter) },
+        });
+        return data[0];
+    } catch (error) {
+        notify('errors.create', 'negative');
+    }
+};
+
+const onDataSaved = async () => {
+    try {
+        const params = {
+            recipientId: initialData.recipientId,
+            recipient: initialData.recipient,
+            replyTo: initialData.replyTo,
+        };
+        setParams(params);
+        const samplesData = await getSamples();
+        const path = `${samplesData.model}/${entityId.value}/${samplesData.code}-email`;
+        await sendEmail(path, params);
+        onDialogOK(params);
+    } catch (error) {
+        notify('errors.create', 'negative');
+    }
     toCustomerSamples();
 };
 
@@ -185,73 +184,54 @@ const toCustomerSamples = () => {
 </script>
 
 <template>
-    <fetch-data
+    <FetchData
         :filter="filterEmailUsers"
         @on-fetch="setEmailUser"
         auto-load
         url="EmailUsers"
     />
-    <fetch-data
+    <FetchData
         :filter="filterClientsAddresses"
-        :url="`Clients/${route.params.id}/addresses`"
+        :url="`Clients/${entityId}/addresses`"
         @on-fetch="setClientsAddresses"
         auto-load
     />
-    <fetch-data
+    <FetchData
         :filter="filterCompanies"
-        @on-fetch="(data) => (optionsCompanies = data)"
+        @on-fetch="(data) => (companies = data)"
         auto-load
         url="Companies"
     />
-    <fetch-data
+    <FetchData
         :filter="filterSamplesVisible"
         @on-fetch="(data) => (optionsSamplesVisible = data)"
         auto-load
         url="Samples/visible"
     />
 
-    <Teleport v-if="stateStore?.isSubToolbarShown()" to="#st-actions">
-        <QBtnGroup push class="q-gutter-x-sm">
-            <QBtn
-                :label="t('globals.cancel')"
-                @click="toCustomerSamples"
-                color="primary"
-                flat
-                icon="close"
-            />
-            <QBtn
-                :disabled="isLoading || !sampleType?.hasPreview"
-                :label="t('Preview')"
-                :loading="isLoading"
-                @click.stop="getPreview()"
-                color="primary"
-                flat
-                icon="preview"
-            />
-            <QBtn
-                :disabled="!hasChanged"
-                :label="t('globals.reset')"
-                :loading="isLoading"
-                @click="setInitialData"
-                color="primary"
-                flat
-                icon="restart_alt"
-                type="reset"
-            />
-            <QBtn
-                :disabled="!hasChanged"
-                :label="t('globals.save')"
-                :loading="isLoading"
-                @click="onSubmit"
-                color="primary"
-                icon="save"
-            />
-        </QBtnGroup>
-    </Teleport>
-
-    <div class="full-width flex justify-center">
-        <QCard class="card-width q-pa-lg">
-            <QForm>
+    <QDialog ref="dialogRef">
+        <FormPopup
+            :default-cancel-button="false"
+            :default-submit-button="false"
+            @on-submit="onSubmit()"
+        >
+            <template #custom-buttons>
+                <QBtn
+                    :disabled="isLoading || !sampleType?.hasPreview"
+                    :label="t('Preview')"
+                    :loading="isLoading"
+                    @click.stop="getPreview()"
+                    color="primary"
+                    flat
+                    icon="preview" /><QBtn
+                    :disabled="!hasChanged"
+                    :label="t('globals.save')"
+                    :loading="isLoading"
+                    @click="onSubmit"
+                    color="primary"
+                    icon="save"
+            /></template>
+            <template #form-inputs>
                 <div class="col">
                     <VnSelect
                         :label="t('Sample')"
@@ -308,7 +288,7 @@ const toCustomerSamples = () => {
                     <div class="col">
                         <VnSelect
                             :label="t('Company')"
-                            :options="optionsCompanies"
+                            :options="companies"
                             :rules="validate('entry.companyFk')"
                             hide-selected
                             option-label="code"
@@ -321,7 +301,7 @@ const toCustomerSamples = () => {
                     <div class="col">
                         <VnSelect
                             :label="t('Address')"
-                            :options="optionsClientsAddressess"
+                            :options="addressess"
                             hide-selected
                             option-label="nickname"
                             option-value="id"
@@ -359,15 +339,15 @@ const toCustomerSamples = () => {
                             required="true"
                             v-model="initialData.from"
                         />
-                    </div>
-                </VnRow>
-            </QForm>
-        </QCard>
-    </div>
+                    </div> </VnRow
+            ></template>
+        </FormPopup>
+    </QDialog>
 </template>
 
 <i18n>
 es:
+    New sample: Crear plantilla
     Sample: Plantilla
     Recipient: Destinatario
     Reply to: Responder a
diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue
index dc9969b61..374769a57 100644
--- a/src/pages/Customer/components/CustomerSummaryTable.vue
+++ b/src/pages/Customer/components/CustomerSummaryTable.vue
@@ -1,22 +1,25 @@
 <script setup>
-import { computed, ref } from 'vue';
+import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
 
-import { QBtn, date } from 'quasar';
+import { date } from 'quasar';
+import { toDateFormat } from 'src/filters/date.js';
 
 import { toCurrency } from 'src/filters';
 
-import FetchData from 'components/FetchData.vue';
-import CustomerSummaryTableActions from './CustomerSummaryTableActions.vue';
-import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
+import { useSummaryDialog } from 'src/composables/useSummaryDialog';
+import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue';
+
+import InvoiceOutDescriptorProxy from 'pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
 import RouteDescriptorProxy from 'src/pages/Route/Card/RouteDescriptorProxy.vue';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue';
 
 const { t } = useI18n();
 const route = useRoute();
 const router = useRouter();
-
-const rows = ref([]);
+const { viewSummary } = useSummaryDialog();
 
 const filter = {
     include: [
@@ -32,57 +35,6 @@ const filter = {
     ],
     where: { clientFk: route.params.id },
     order: ['shipped DESC', 'id'],
-    limit: 10,
-};
-
-const tableColumnComponents = {
-    id: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    nickname: {
-        component: QBtn,
-        props: () => ({ flat: true, color: 'blue', noCaps: true }),
-        event: () => {},
-    },
-    agency: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    route: {
-        component: QBtn,
-        props: () => ({ flat: true, color: 'blue' }),
-        event: () => {},
-    },
-    packages: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    date: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    state: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    total: {
-        component: 'span',
-        props: () => {},
-        event: () => {},
-    },
-    actions: {
-        component: CustomerSummaryTableActions,
-        props: (prop) => ({
-            id: prop.row.id,
-        }),
-        event: () => {},
-    },
 };
 
 const columns = computed(() => [
@@ -94,37 +46,37 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        field: 'nickname',
         label: t('Nickname'),
         name: 'nickname',
+        columnClass: 'expand',
     },
     {
         align: 'left',
-        field: (row) => row?.agencyMode?.name,
+        format: (row) => row.agencyMode.name,
+        columnClass: 'expand',
         label: t('Agency'),
-        name: 'agency',
     },
     {
         align: 'left',
-        field: 'routeFk',
+        name: 'routeFk',
+        columnClass: 'shrink',
         label: t('Route'),
-        name: 'route',
     },
     {
         align: 'left',
         field: 'packages',
         label: t('Packages'),
         name: 'packages',
+        columnClass: 'shrink',
     },
     {
         align: 'left',
-        field: (row) => date.formatDate(row?.shipped, 'DD/MM/YYYY'),
+        format: ({ shipped }) => date.formatDate(shipped, 'DD/MM/YYYY'),
         label: t('Date'),
-        name: 'date',
+        name: 'shipped',
     },
     {
         align: 'left',
-        field: (row) => row?.ticketState?.state?.name,
         label: t('State'),
         name: 'state',
     },
@@ -134,11 +86,25 @@ const columns = computed(() => [
         label: t('Total'),
         name: 'total',
     },
+
     {
-        align: 'left',
-        field: 'totalWithVat',
+        align: 'right',
         label: '',
-        name: 'actions',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('customer.summary.goToLines'),
+                icon: 'vn:lines',
+                action: ({ id }) => router.push({ params: { id }, name: 'TicketSale' }),
+                isPrimary: true,
+            },
+            {
+                title: t('components.smartCard.viewSummary'),
+                icon: 'preview',
+                isPrimary: true,
+                action: (row) => viewSummary(row.id, TicketSummary),
+            },
+        ],
     },
 ]);
 
@@ -156,84 +122,90 @@ const setTotalPriceColor = (ticket) => {
     if (total > 0 && total < 50) return 'warning';
 };
 
-const navigateToticketSummary = (id) => {
-    router.push({
-        name: 'TicketSummary',
-        params: { id },
-    });
+const setShippedColor = (date) => {
+    const today = Date.vnNew();
+    today.setHours(0, 0, 0, 0);
+
+    const ticketShipped = new Date(date);
+    ticketShipped.setHours(0, 0, 0, 0);
+
+    const difference = today - ticketShipped;
+
+    if (difference == 0) return 'warning';
+    if (difference < 0) return 'success';
 };
-const commonColumns = (col) => ['date', 'state', 'total'].includes(col);
 </script>
 
 <template>
-    <FetchData
+    <VnTable
+        data-key="CustomerTickets"
         :filter="filter"
-        @on-fetch="(data) => (rows = data)"
-        auto-load
+        :right-search="false"
+        :column-search="false"
         url="Tickets"
-    />
-    <QCard class="vn-one q-py-sm flex justify-between">
-        <QTable
-            :columns="columns"
-            :pagination="{ rowsPerPage: 12 }"
-            :rows="rows"
-            class="full-width"
-            row-key="id"
-        >
-            <template #body-cell="props">
-                <QTd :props="props" @click="navigateToticketSummary(props.row.id)">
-                    <QTr :props="props" class="cursor-pointer">
-                        <component
-                            :is="tableColumnComponents[props.col.name].component"
-                            @click="tableColumnComponents[props.col.name].event(props)"
-                            class="rounded-borders"
-                            v-bind="tableColumnComponents[props.col.name].props(props)"
-                        >
-                            <template v-if="!commonColumns(props.col.name)">
-                                <span
-                                    :class="{
-                                        link:
-                                            props.col.name === 'route' ||
-                                            props.col.name === 'nickname',
-                                    }"
-                                >
-                                    {{ props.value }}
-                                </span>
-                            </template>
-                            <template v-if="props.col.name === 'date'">
-                                <QBadge class="q-pa-sm" color="warning">
-                                    {{ props.value }}
-                                </QBadge>
-                            </template>
-                            <template v-if="props.col.name === 'state'">
-                                <QBadge :color="setStateColor(props.row)" class="q-pa-sm">
-                                    {{ props.value }}
-                                </QBadge>
-                            </template>
-                            <template v-if="props.col.name === 'total'">
-                                <QBadge
-                                    :color="setTotalPriceColor(props.row)"
-                                    class="q-pa-sm"
-                                    v-if="setTotalPriceColor(props.row)"
-                                >
-                                    {{ toCurrency(props.value) }}
-                                </QBadge>
-                                <div v-else>{{ toCurrency(props.value) }}</div>
-                            </template>
-                            <CustomerDescriptorProxy
-                                :id="props.row.clientFk"
-                                v-if="props.col.name === 'nickname'"
-                            />
-                            <RouteDescriptorProxy
-                                :id="props.row.routeFk"
-                                v-if="props.col.name === 'route'"
-                            />
-                        </component>
-                    </QTr>
-                </QTd>
-            </template>
-        </QTable>
-    </QCard>
+        :columns="columns"
+        search-url="tickets"
+        :without-header="true"
+        auto-load
+        order="shipped DESC, id"
+        :disable-option="{ card: true, table: true }"
+        limit="5"
+        class="full-width"
+        :disable-infinite-scroll="true"
+    >
+        <template #column-nickname="{ row }">
+            <span class="link">
+                {{ row.nickname }}
+                <CustomerDescriptorProxy :id="row.clientFk" />
+            </span>
+        </template>
+
+        <template #column-routeFk="{ row }">
+            <span class="link">
+                {{ row.routeFk }}
+                <RouteDescriptorProxy :id="row.routeFk" />
+            </span>
+        </template>
+        <template #column-total="{ row }">
+            <QBadge
+                class="q-pa-sm"
+                v-if="setTotalPriceColor(row)"
+                :color="setTotalPriceColor(row)"
+                text-color="black"
+            >
+                {{ toCurrency(row.totalWithVat) }}
+            </QBadge>
+            <span v-else> {{ toCurrency(row.totalWithVat) }}</span>
+        </template>
+        <template #column-state="{ row }">
+            <span v-if="row.invoiceOut">
+                <span :class="{ link: row.invoiceOut.ref }">
+                    {{ row.invoiceOut.ref }}
+                    <InvoiceOutDescriptorProxy :id="row.invoiceOut.id" />
+                </span>
+            </span>
+            <QBadge
+                class="q-pa-sm"
+                :color="setStateColor(row)"
+                text-color="black"
+                v-else-if="setStateColor(row)"
+            >
+                {{ row?.ticketState?.state.name }}
+            </QBadge>
+            <span v-else> {{ row?.ticketState?.state.name }}</span>
+        </template>
+        <template #column-shipped="{ row }">
+            <QBadge
+                class="q-pa-sm"
+                :color="setShippedColor(row.shipped)"
+                text-color="black"
+                v-if="setShippedColor(row.shipped)"
+            >
+                {{ toDateFormat(row.shipped) }}
+            </QBadge>
+            <span v-else> {{ toDateFormat(row.shipped) }}</span>
+        </template>
+    </VnTable>
 </template>
 
 <i18n>
diff --git a/src/pages/Customer/components/CustomerSummaryTableActions.vue b/src/pages/Customer/components/CustomerSummaryTableActions.vue
deleted file mode 100644
index 6e9038374..000000000
--- a/src/pages/Customer/components/CustomerSummaryTableActions.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-<script setup>
-import { useI18n } from 'vue-i18n';
-
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue';
-
-const { t } = useI18n();
-
-defineProps({
-    id: {
-        type: Number,
-        required: true,
-    },
-});
-
-const { viewSummary } = useSummaryDialog();
-</script>
-
-<template>
-    <div>
-        <QIcon color="primary" name="vn:lines" size="sm">
-            <QTooltip>
-                {{ t('Go to lines') }}
-            </QTooltip>
-        </QIcon>
-        <QIcon
-            @click.stop="viewSummary(id, TicketSummary)"
-            class="q-ml-md"
-            color="primary"
-            name="preview"
-            size="sm"
-        >
-            <QTooltip>
-                {{ t('Preview') }}
-            </QTooltip>
-        </QIcon>
-    </div>
-</template>
-
-<i18n>
-es:
-    Go to lines: Ir a lineas
-    Preview: Vista previa
-</i18n>
diff --git a/src/pages/Customer/locale/en.yml b/src/pages/Customer/locale/en.yml
index 6eb7cfa85..545c3f274 100644
--- a/src/pages/Customer/locale/en.yml
+++ b/src/pages/Customer/locale/en.yml
@@ -2,3 +2,135 @@ customerFilter:
     filter:
         name: Name
         socialName: Social name
+customer:
+    list:
+        phone: Phone
+        email: Email
+        customerOrders: Display customer orders
+        moreOptions: More options
+    card:
+        customerList: Customer list
+        customerId: Claim ID
+        salesPerson: Sales person
+        credit: Credit
+        risk: Risk
+        securedCredit: Secured credit
+        payMethod: Pay method
+        debt: Debt
+        isFrozen: Customer frozen
+        hasDebt: Customer has debt
+        isDisabled: Customer inactive
+        notChecked: Customer no checked
+        webAccountInactive: Web account inactive
+        noWebAccess: Web access is disabled
+        businessType: Business type
+        passwordRequirements: 'The password must have at least { length } length characters, {nAlpha} alphabetic characters, {nUpper} capital letters, {nDigits} digits and {nPunct} symbols (Ex: $%&.)\n'
+        businessTypeFk: Business type
+    summary:
+        basicData: Basic data
+        fiscalAddress: Fiscal address
+        fiscalData: Fiscal data
+        billingData: Billing data
+        consignee: Default consignee
+        businessData: Business data
+        financialData: Financial data
+        customerId: Customer ID
+        name: Name
+        contact: Contact
+        phone: Phone
+        mobile: Mobile
+        email: Email
+        salesPerson: Sales person
+        contactChannel: Contact channel
+        socialName: Social name
+        fiscalId: Fiscal ID
+        postcode: Postcode
+        province: Province
+        country: Country
+        street: Address
+        isEqualizated: Is equalizated
+        isActive: Is active
+        invoiceByAddress: Invoice by address
+        verifiedData: Verified data
+        hasToInvoice: Has to invoice
+        notifyByEmail: Notify by email
+        vies: VIES
+        payMethod: Pay method
+        bankAccount: Bank account
+        dueDay: Due day
+        hasLcr: Has LCR
+        hasCoreVnl: Has core VNL
+        hasB2BVnl: Has B2B VNL
+        addressName: Address name
+        addressCity: City
+        addressStreet: Street
+        username: Username
+        webAccess: Web access
+        totalGreuge: Total greuge
+        mana: Mana
+        priceIncreasingRate: Price increasing rate
+        averageInvoiced: Average invoiced
+        claimRate: Claming rate
+        payMethodFk: Billing data
+        risk: Risk
+        maximumRisk: Solunion's maximum risk
+        riskInfo: Invoices minus payments plus orders not yet invoiced
+        credit: Credit
+        creditInfo: Company's maximum risk
+        securedCredit: Secured credit
+        securedCreditInfo: Solunion's maximum risk
+        balance: Balance
+        balanceInfo: Invoices minus payments
+        balanceDue: Balance due
+        balanceDueInfo: Deviated invoices minus payments
+        recoverySince: Recovery since
+        businessType: Business Type
+        city: City
+        descriptorInfo: Invoices minus payments plus orders not yet
+        rating: Rating
+        recommendCredit: Recommended credit
+        goToLines: Go to lines
+    basicData:
+        socialName: Fiscal name
+        businessType: Business type
+        contact: Contact
+        youCanSaveMultipleEmails: You can save multiple emails
+        email: Email
+        phone: Phone
+        mobile: Mobile
+        salesPerson: Sales person
+        contactChannel: Contact channel
+        previousClient: Previous client
+    extendedList:
+        tableVisibleColumns:
+            id: Identifier
+            name: Name
+            socialName: Social name
+            fi: Tax number
+            salesPersonFk: Salesperson
+            credit: Credit
+            creditInsurance: Credit insurance
+            phone: Phone
+            mobile: Mobile
+            street: Street
+            countryFk: Country
+            provinceFk: Province
+            city: City
+            postcode: Postcode
+            email: Email
+            created: Created
+            businessTypeFk: Business type
+            payMethodFk: Billing data
+            sageTaxTypeFk: Sage tax type
+            sageTransactionTypeFk: Sage tr. type
+            isActive: Active
+            isVies: Vies
+            isTaxDataChecked: Verified data
+            isEqualizated: Is equalizated
+            isFreezed: Freezed
+            hasToInvoice: Invoice
+            hasToInvoiceByAddress: Invoice by address
+            isToBeMailed: Mailing
+            hasLcr: Received LCR
+            hasCoreVnl: VNL core received
+            hasSepaVnl: VNL B2B received
diff --git a/src/pages/Customer/locale/es.yml b/src/pages/Customer/locale/es.yml
index 111696f21..4fcbe3fa2 100644
--- a/src/pages/Customer/locale/es.yml
+++ b/src/pages/Customer/locale/es.yml
@@ -4,3 +4,134 @@ customerFilter:
     filter:
         name: Nombre
         socialName: Razón Social
+customer:
+    list:
+        phone: Teléfono
+        email: Email
+        customerOrders: Mostrar órdenes del cliente
+        moreOptions: Más opciones
+    card:
+        customerId: ID cliente
+        salesPerson: Comercial
+        credit: Crédito
+        risk: Riesgo
+        securedCredit: Crédito asegurado
+        payMethod: Método de pago
+        debt: Riesgo
+        isFrozen: Cliente congelado
+        hasDebt: Cliente con riesgo
+        isDisabled: Cliente inactivo
+        notChecked: Cliente no comprobado
+        webAccountInactive: Sin acceso web
+        noWebAccess: El acceso web está desactivado
+        businessType: Tipo de negocio
+        passwordRequirements: 'La contraseña debe tener al menos { length } caracteres de longitud, {nAlpha} caracteres alfabéticos, {nUpper} letras mayúsculas, {nDigits} dígitos y {nPunct} símbolos (Ej: $%&.)'
+        businessTypeFk: Tipo de negocio
+    summary:
+        basicData: Datos básicos
+        fiscalAddress: Dirección fiscal
+        fiscalData: Datos fiscales
+        billingData: Datos de facturación
+        consignee: Consignatario pred.
+        businessData: Datos comerciales
+        financialData: Datos financieros
+        customerId: ID cliente
+        name: Nombre
+        contact: Contacto
+        phone: Teléfono
+        mobile: Móvil
+        email: Email
+        salesPerson: Comercial
+        contactChannel: Canal de contacto
+        socialName: Razón social
+        fiscalId: NIF/CIF
+        postcode: Código postal
+        province: Provincia
+        country: País
+        street: Calle
+        isEqualizated: Recargo de equivalencia
+        isActive: Activo
+        invoiceByAddress: Facturar por consignatario
+        verifiedData: Datos verificados
+        hasToInvoice: Facturar
+        notifyByEmail: Notificar por email
+        vies: VIES
+        payMethod: Método de pago
+        bankAccount: Cuenta bancaria
+        dueDay: Día de pago
+        hasLcr: Recibido LCR
+        hasCoreVnl: Recibido core VNL
+        hasB2BVnl: Recibido B2B VNL
+        addressName: Nombre de la dirección
+        addressCity: Ciudad
+        addressStreet: Calle
+        username: Usuario
+        webAccess: Acceso web
+        totalGreuge: Greuge total
+        mana: Maná
+        priceIncreasingRate: Ratio de incremento de precio
+        averageInvoiced: Facturación media
+        claimRate: Ratio de reclamaciones
+        maximumRisk: Riesgo máximo asumido por Solunion
+        payMethodFk: Forma de pago
+        risk: Riesgo
+        riskInfo: Facturas menos recibos mas pedidos sin facturar
+        credit: Crédito
+        creditInfo: Riesgo máximo asumido por la empresa
+        securedCredit: Crédito asegurado
+        securedCreditInfo: Riesgo máximo asumido por Solunion
+        balance: Balance
+        balanceInfo: Facturas menos recibos
+        balanceDue: Saldo vencido
+        balanceDueInfo: Facturas fuera de plazo menos recibos
+        recoverySince: Recobro desde
+        businessType: Tipo de negocio
+        city: Población
+        descriptorInfo: Facturas menos recibos mas pedidos sin facturar
+        rating: Clasificación
+        recommendCredit: Crédito recomendado
+        goToLines: Ir a líneas
+    basicData:
+        socialName: Nombre fiscal
+        businessType: Tipo de negocio
+        contact: Contacto
+        youCanSaveMultipleEmails: Puede guardar varios correos electrónicos encadenándolos mediante comas sin espacios{','} ejemplo{':'} user{'@'}dominio{'.'}com, user2{'@'}dominio{'.'}com siendo el primer correo electrónico el principal
+        email: Email
+        phone: Teléfono
+        mobile: Móvil
+        salesPerson: Comercial
+        contactChannel: Canal de contacto
+        previousClient: Cliente anterior
+    extendedList:
+        tableVisibleColumns:
+            id: Identificador
+            name: Nombre
+            socialName: Razón social
+            fi: NIF / CIF
+            salesPersonFk: Comercial
+            credit: Crédito
+            creditInsurance: Crédito asegurado
+            phone: Teléfono
+            mobile: Móvil
+            street: Dirección fiscal
+            countryFk: País
+            provinceFk: Provincia
+            city: Población
+            postcode: Código postal
+            email: Email
+            created: Fecha creación
+            businessTypeFk: Tipo de negocio
+            payMethodFk: Forma de pago
+            sageTaxTypeFk: Tipo de impuesto Sage
+            sageTransactionTypeFk: Tipo tr. sage
+            isActive: Activo
+            isVies: Vies
+            isTaxDataChecked: Datos comprobados
+            isEqualizated: Recargo de equivalencias
+            isFreezed: Congelado
+            hasToInvoice: Factura
+            hasToInvoiceByAddress: Factura por consigna
+            isToBeMailed: Env. emails
+            hasLcr: Recibido LCR
+            hasCoreVnl: Recibido core VNL
+            hasSepaVnl: Recibido B2B VNL
diff --git a/src/pages/Dashboard/DashboardMain.vue b/src/pages/Dashboard/DashboardMain.vue
index 6da39ce25..56054156a 100644
--- a/src/pages/Dashboard/DashboardMain.vue
+++ b/src/pages/Dashboard/DashboardMain.vue
@@ -55,6 +55,15 @@ const pinnedModules = computed(() => navigation.getPinnedModules());
                                 >
                                     <div class="text-center text-primary button-text">
                                         {{ t(item.title) }}
+                                        <div v-if="item.keyBinding">
+                                            {{ '(' + item.keyBinding + ')' }}
+                                            <QTooltip>
+                                                {{
+                                                    'Ctrl + Alt + ' +
+                                                    item?.keyBinding?.toUpperCase()
+                                                }}
+                                            </QTooltip>
+                                        </div>
                                     </div>
                                 </QBtn>
                             </div>
diff --git a/src/pages/Department/Card/DepartmentBasicData.vue b/src/pages/Department/Card/DepartmentBasicData.vue
index 4573f7b66..98abfd6b9 100644
--- a/src/pages/Department/Card/DepartmentBasicData.vue
+++ b/src/pages/Department/Card/DepartmentBasicData.vue
@@ -16,12 +16,12 @@ const workersOptions = ref([]);
 const clientsOptions = ref([]);
 </script>
 <template>
-    <fetch-data
+    <FetchData
         url="Workers/search"
         @on-fetch="(data) => (workersOptions = data)"
         auto-load
     />
-    <fetch-data url="Clients" @on-fetch="(data) => (clientsOptions = data)" auto-load />
+    <FetchData url="Clients" @on-fetch="(data) => (clientsOptions = data)" auto-load />
     <FormModel
         :url="`Departments/${route.params.id}`"
         model="department"
diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue
index e5d6f50d9..b81b1db22 100644
--- a/src/pages/Entry/Card/EntryBasicData.vue
+++ b/src/pages/Entry/Card/EntryBasicData.vue
@@ -19,8 +19,6 @@ const { t } = useI18n();
 const { hasAny } = useRole();
 const isAdministrative = () => hasAny(['administrative']);
 
-const suppliersOptions = ref([]);
-const travelsOptions = ref([]);
 const companiesOptions = ref([]);
 const currenciesOptions = ref([]);
 
@@ -29,20 +27,6 @@ const onFilterTravelSelected = (formData, id) => {
 };
 </script>
 <template>
-    <FetchData
-        url="Suppliers"
-        :filter="{ fields: ['id', 'nickname'] }"
-        order="nickname"
-        @on-fetch="(data) => (suppliersOptions = data)"
-        auto-load
-    />
-    <FetchData
-        url="Travels/filter"
-        :filter="{ fields: ['id', 'warehouseInName'] }"
-        order="id"
-        @on-fetch="(data) => (travelsOptions = data)"
-        auto-load
-    />
     <FetchData
         ref="companiesRef"
         url="Companies"
@@ -71,9 +55,10 @@ const onFilterTravelSelected = (formData, id) => {
                 <VnSelect
                     :label="t('entry.basicData.supplier')"
                     v-model="data.supplierFk"
-                    :options="suppliersOptions"
+                    url="Suppliers"
                     option-value="id"
                     option-label="nickname"
+                    :fields="['id', 'nickname']"
                     hide-selected
                     :required="true"
                     map-options
@@ -92,7 +77,8 @@ const onFilterTravelSelected = (formData, id) => {
                 <VnSelectDialog
                     :label="t('entry.basicData.travel')"
                     v-model="data.travelFk"
-                    :options="travelsOptions"
+                    url="Travels/filter"
+                    :fields="['id', 'warehouseInName']"
                     option-value="id"
                     option-label="warehouseInName"
                     map-options
diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue
index 6e66f4ce7..ff89faada 100644
--- a/src/pages/Entry/Card/EntryBuys.vue
+++ b/src/pages/Entry/Card/EntryBuys.vue
@@ -26,7 +26,6 @@ const { notify } = useNotify();
 
 const rowsSelected = ref([]);
 const entryBuysPaginateRef = ref(null);
-const packagingsOptions = ref(null);
 const originalRowDataCopy = ref(null);
 
 const getInputEvents = (colField, props) => {
@@ -66,7 +65,10 @@ const tableColumnComponents = computed(() => ({
             'map-options': true,
             'use-input': true,
             'hide-selected': true,
-            options: packagingsOptions.value,
+            url: 'Packagings',
+            fields: ['id'],
+            where: { freightItemFk: true },
+            'sort-by': 'id ASC',
             dense: true,
         },
         event: getInputEvents,
@@ -304,13 +306,6 @@ const lockIconType = (groupingMode, mode) => {
 </script>
 
 <template>
-    <FetchData
-        ref="expensesRef"
-        url="Packagings"
-        :filter="{ fields: ['id'], where: { freightItemFk: true }, order: 'id ASC' }"
-        auto-load
-        @on-fetch="(data) => (packagingsOptions = data)"
-    />
     <VnSubToolbar>
         <template #st-actions>
             <QBtnGroup push style="column-gap: 10px">
@@ -423,7 +418,7 @@ const lockIconType = (groupingMode, mode) => {
                             <span v-if="props.row.item.subName" class="subName">
                                 {{ props.row.item.subName }}
                             </span>
-                            <FetchedTags :item="props.row.item" :max-length="5" />
+                            <FetchedTags :item="props.row.item" />
                         </QTd>
                     </QTr>
                 </template>
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index b32dc70a9..379be1d2f 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -319,7 +319,7 @@ const fetchEntryBuys = async () => {
                                 <span v-if="row.item.subName" class="subName">
                                     {{ row.item.subName }}
                                 </span>
-                                <FetchedTags :item="row.item" :max-length="5" />
+                                <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 -->
diff --git a/src/pages/Entry/EntryFilter.vue b/src/pages/Entry/EntryFilter.vue
index 194ce0a28..3b88072fa 100644
--- a/src/pages/Entry/EntryFilter.vue
+++ b/src/pages/Entry/EntryFilter.vue
@@ -20,7 +20,6 @@ const props = defineProps({
 
 const currenciesOptions = ref([]);
 const companiesOptions = ref([]);
-const suppliersOptions = ref([]);
 
 const stateStore = useStateStore();
 onMounted(async () => {
@@ -45,14 +44,6 @@ onMounted(async () => {
         @on-fetch="(data) => (currenciesOptions = data)"
         auto-load
     />
-    <FetchData
-        url="Suppliers"
-        :filter="{ fields: ['id', 'nickname', 'name'] }"
-        order="nickname"
-        @on-fetch="(data) => (suppliersOptions = data)"
-        auto-load
-    />
-
     <VnFilterPanel :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
@@ -135,9 +126,11 @@ onMounted(async () => {
                         :label="t('params.supplierFk')"
                         v-model="params.supplierFk"
                         @update:model-value="searchFn()"
-                        :options="suppliersOptions"
+                        url="Suppliers"
                         option-value="id"
                         option-label="name"
+                        :fields="['id', 'name', 'nickname']"
+                        sort-by="nickname"
                         hide-selected
                         dense
                         outlined
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index bd5ace677..6f7ff1935 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -7,11 +7,16 @@ import { useStateStore } from 'stores/useStateStore';
 import VnTable from 'components/VnTable/VnTable.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import { 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 TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
 
 const stateStore = useStateStore();
 const { t } = useI18n();
 const tableRef = ref();
 
+const { viewSummary } = useSummaryDialog();
 const entryFilter = {
     include: [
         {
@@ -142,6 +147,12 @@ const columns = computed(() => [
         create: true,
         format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
     },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.invoiceAmount'),
+        name: 'invoiceAmount',
+        cardVisible: true,
+    },
     {
         align: 'left',
         label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
@@ -168,6 +179,18 @@ const columns = computed(() => [
             inWhere: true,
         },
     },
+    {
+        align: 'right',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('components.smartCard.viewSummary'),
+                icon: 'preview',
+                action: (row) => viewSummary(row.id, EntrySummary),
+                isPrimary: true,
+            },
+        ],
+    },
 ]);
 onMounted(async () => {
     stateStore.rightDrawer = true;
@@ -201,7 +224,20 @@ onMounted(async () => {
         redirect="entry"
         auto-load
         :right-search="false"
-    />
+    >
+        <template #column-supplierFk="{ row }">
+            <span class="link" @click.stop>
+                {{ row.supplierName }}
+                <SupplierDescriptorProxy :id="row.supplierFk" />
+            </span>
+        </template>
+        <template #column-travelFk="{ row }">
+            <span class="link" @click.stop>
+                {{ row.travelRef }}
+                <TravelDescriptorProxy :id="row.travelFk" />
+            </span>
+        </template>
+    </VnTable>
 </template>
 
 <i18n>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
index ede9af825..045517a3f 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
@@ -223,6 +223,10 @@ async function onSubmit() {
                     autofocus
                 />
             </VnRow>
+            <VnRow>
+                <VnInputDate :label="t('Entry date')" v-model="data.bookEntried" />
+                <VnInputDate :label="t('Accounted date')" v-model="data.booked" />
+            </VnRow>
             <VnRow>
                 <VnSelect
                     :label="t('Undeductible VAT')"
@@ -285,10 +289,6 @@ async function onSubmit() {
                     </template>
                 </VnInput>
             </VnRow>
-            <VnRow>
-                <VnInputDate :label="t('Entry date')" v-model="data.bookEntried" />
-                <VnInputDate :label="t('Accounted date')" v-model="data.booked" />
-            </VnRow>
             <VnRow>
                 <VnSelect
                     :label="t('Currency')"
diff --git a/src/pages/InvoiceIn/Card/InvoiceInCard.vue b/src/pages/InvoiceIn/Card/InvoiceInCard.vue
index a95f289b0..0fe2a2368 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInCard.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInCard.vue
@@ -3,6 +3,8 @@ import VnCard from 'components/common/VnCard.vue';
 import InvoiceInDescriptor from './InvoiceInDescriptor.vue';
 import InvoiceInFilter from '../InvoiceInFilter.vue';
 import InvoiceInSearchbar from '../InvoiceInSearchbar.vue';
+import { onBeforeRouteUpdate } from 'vue-router';
+import { setRectificative } from '../composables/setRectificative';
 
 const filter = {
     include: [
@@ -20,6 +22,8 @@ const filter = {
         { relation: 'currency' },
     ],
 };
+
+onBeforeRouteUpdate(async (to) => await setRectificative(to));
 </script>
 <template>
     <VnCard
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index cba2a31d2..9bc4856a8 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n';
 import { useQuasar } from 'quasar';
 import axios from 'axios';
 import { toCurrency, toDate } from 'src/filters';
-import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 import { downloadFile } from 'src/composables/downloadFile';
 import { useArrayData } from 'src/composables/useArrayData';
 import { usePrintService } from 'composables/usePrintService';
@@ -24,7 +24,7 @@ const $props = defineProps({ id: { type: Number, default: null } });
 const { push, currentRoute } = useRouter();
 
 const quasar = useQuasar();
-const { hasAny } = useRole();
+const { hasAny } = useAcl();
 const { t } = useI18n();
 const { openReport, sendEmail } = usePrintService();
 const arrayData = useArrayData();
@@ -195,7 +195,8 @@ async function cloneInvoice() {
     push({ path: `/invoice-in/${data.id}/summary` });
 }
 
-const isAdministrative = () => hasAny(['administrative']);
+const canEditProp = (props) =>
+    hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]);
 
 const isAgricultural = () => {
     if (!config.value) return false;
@@ -283,7 +284,7 @@ const createInvoiceInCorrection = async () => {
             <InvoiceInToBook>
                 <template #content="{ book }">
                     <QItem
-                        v-if="!entity?.isBooked && isAdministrative()"
+                        v-if="!entity?.isBooked && canEditProp('toBook')"
                         v-ripple
                         clickable
                         @click="book(entityId)"
@@ -293,7 +294,7 @@ const createInvoiceInCorrection = async () => {
                 </template>
             </InvoiceInToBook>
             <QItem
-                v-if="entity?.isBooked && isAdministrative()"
+                v-if="entity?.isBooked && canEditProp('toUnbook')"
                 v-ripple
                 clickable
                 @click="triggerMenu('unbook')"
@@ -303,7 +304,7 @@ const createInvoiceInCorrection = async () => {
                 </QItemSection>
             </QItem>
             <QItem
-                v-if="isAdministrative()"
+                v-if="canEditProp('deleteById')"
                 v-ripple
                 clickable
                 @click="triggerMenu('delete')"
@@ -311,7 +312,7 @@ const createInvoiceInCorrection = async () => {
                 <QItemSection>{{ t('Delete invoice') }}</QItemSection>
             </QItem>
             <QItem
-                v-if="isAdministrative()"
+                v-if="canEditProp('clone')"
                 v-ripple
                 clickable
                 @click="triggerMenu('clone')"
@@ -356,10 +357,7 @@ const createInvoiceInCorrection = async () => {
         <template #body="{ entity }">
             <VnLv :label="t('invoiceIn.card.issued')" :value="toDate(entity.issued)" />
             <VnLv :label="t('invoiceIn.summary.booked')" :value="toDate(entity.booked)" />
-            <VnLv
-                :label="t('invoiceIn.card.amount')"
-                :value="toCurrency(totalAmount, entity.currency?.code)"
-            />
+            <VnLv :label="t('invoiceIn.card.amount')" :value="toCurrency(totalAmount)" />
             <VnLv :label="t('invoiceIn.summary.supplier')">
                 <template #value>
                     <span class="link">
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
index 7dbd0fe9e..1593ea1be 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
@@ -5,10 +5,10 @@ import { useI18n } from 'vue-i18n';
 import axios from 'axios';
 import { toDate } from 'src/filters';
 import { useArrayData } from 'src/composables/useArrayData';
+import { getTotal } from 'src/composables/getTotal';
 import CrudModel from 'src/components/CrudModel.vue';
 import FetchData from 'src/components/FetchData.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
-import { toCurrency } from 'src/filters';
 import useNotify from 'src/composables/useNotify.js';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
@@ -18,6 +18,7 @@ const { notify } = useNotify();
 const { t } = useI18n();
 const arrayData = useArrayData();
 const invoiceIn = computed(() => arrayData.store.data);
+const currency = computed(() => invoiceIn.value?.currency?.code);
 
 const rowsSelected = ref([]);
 const banks = ref([]);
@@ -71,7 +72,6 @@ async function insert() {
     await invoiceInFormRef.value.reload();
     notify(t('globals.dataSaved'), 'positive');
 }
-const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, 0);
 </script>
 <template>
     <FetchData
@@ -139,9 +139,9 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
                     <QTd>
                         <VnInputNumber
                             :class="{
-                                'no-pointer-events': !isNotEuro(invoiceIn.currency.code),
+                                'no-pointer-events': !isNotEuro(currency),
                             }"
-                            :disable="!isNotEuro(invoiceIn.currency.code)"
+                            :disable="!isNotEuro(currency)"
                             v-model="row.foreignValue"
                             clearable
                             clear-icon="close"
@@ -154,11 +154,17 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
                         <QTd />
                         <QTd />
                         <QTd>
-                            {{
-                                toCurrency(getTotalAmount(rows), invoiceIn.currency.code)
-                            }}
+                            {{ getTotal(rows, 'amount', { currency: 'default' }) }}
+                        </QTd>
+                        <QTd>
+                            <template v-if="isNotEuro(invoiceIn.currency.code)">
+                                {{
+                                    getTotal(rows, 'foreignValue', {
+                                        currency: invoiceIn.currency.code,
+                                    })
+                                }}
+                            </template>
                         </QTd>
-                        <QTd />
                     </QTr>
                 </template>
                 <template #item="props">
@@ -208,11 +214,9 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
                                         :label="t('Foreign value')"
                                         class="full-width"
                                         :class="{
-                                            'no-pointer-events': !isNotEuro(
-                                                invoiceIn.currency.code
-                                            ),
+                                            'no-pointer-events': !isNotEuro(currency),
                                         }"
-                                        :disable="!isNotEuro(invoiceIn.currency.code)"
+                                        :disable="!isNotEuro(currency)"
                                         v-model="props.row.foreignValue"
                                         clearable
                                         clear-icon="close"
diff --git a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
index 481698832..717f30b7f 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
@@ -2,18 +2,15 @@
 import { computed, ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { toCurrency } from 'src/filters';
+import { getTotal } from 'src/composables/getTotal';
 import CrudModel from 'src/components/CrudModel.vue';
 import FetchData from 'src/components/FetchData.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
-import { useArrayData } from 'src/composables/useArrayData';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
 
 const { t } = useI18n();
 
 const route = useRoute();
-const arrayData = useArrayData();
-const currency = computed(() => arrayData.store.data?.currency?.code);
 const invoceInIntrastat = ref([]);
 const rowsSelected = ref([]);
 const countries = ref([]);
@@ -72,9 +69,6 @@ const columns = computed(() => [
     },
 ]);
 
-const getTotal = (data, key) =>
-    data.reduce((acc, cur) => acc + +String(cur[key] || 0).replace(',', '.'), 0);
-
 const formatOpt = (row, { model, options }, prop) => {
     const obj = row[model];
     const option = options.find(({ id }) => id == obj);
@@ -154,7 +148,7 @@ const formatOpt = (row, { model, options }, prop) => {
                             <QTd />
                             <QTd />
                             <QTd>
-                                {{ toCurrency(getTotal(rows, 'amount'), currency) }}
+                                {{ getTotal(rows, 'amount', { currency: 'default' }) }}
                             </QTd>
                             <QTd>
                                 {{ getTotal(rows, 'net') }}
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index 644b472e2..bf2e7db48 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -35,7 +35,7 @@ const vatColumns = ref([
         name: 'landed',
         label: 'invoiceIn.summary.taxableBase',
         field: (row) => row.taxableBase,
-        format: (value) => toCurrency(value, currency.value),
+        format: (value) => toCurrency(value),
         sortable: true,
         align: 'left',
     },
@@ -64,7 +64,7 @@ const vatColumns = ref([
         name: 'rate',
         label: 'invoiceIn.summary.rate',
         field: (row) => taxRate(row.taxableBase, row.taxTypeSage?.rate),
-        format: (value) => toCurrency(value, currency.value),
+        format: (value) => toCurrency(value),
         sortable: true,
         align: 'left',
     },
@@ -72,7 +72,7 @@ const vatColumns = ref([
         name: 'currency',
         label: 'invoiceIn.summary.currency',
         field: (row) => row.foreignValue,
-        format: (value) => value,
+        format: (val) => val && toCurrency(val, currency.value),
         sortable: true,
         align: 'left',
     },
@@ -97,7 +97,7 @@ const dueDayColumns = ref([
         name: 'amount',
         label: 'invoiceIn.summary.amount',
         field: (row) => row.amount,
-        format: (value) => toCurrency(value, currency.value),
+        format: (value) => toCurrency(value),
         sortable: true,
         align: 'left',
     },
@@ -105,7 +105,7 @@ const dueDayColumns = ref([
         name: 'landed',
         label: 'invoiceIn.summary.foreignValue',
         field: (row) => row.foreignValue,
-        format: (value) => value,
+        format: (val) => val && toCurrency(val, currency.value),
         sortable: true,
         align: 'left',
     },
@@ -124,7 +124,7 @@ const intrastatColumns = ref([
     {
         name: 'amount',
         label: 'invoiceIn.summary.amount',
-        field: (row) => toCurrency(row.amount, currency.value),
+        field: (row) => toCurrency(row.amount),
         sortable: true,
         align: 'left',
     },
@@ -179,7 +179,6 @@ const getTotalTax = (tax) =>
 
 const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
 </script>
-
 <template>
     <CardSummary
         data-key="InvoiceInSummary"
@@ -229,10 +228,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                     :label="t('invoiceIn.summary.currency')"
                     :value="entity.currency?.code"
                 />
-                <VnLv
-                    :label="t('invoiceIn.summary.docNumber')"
-                    :value="`${entity.serial}/${entity.serialNumber}`"
-                />
+                <VnLv :label="t('invoiceIn.serial')" :value="`${entity.serial}`" />
             </QCard>
             <QCard class="vn-one">
                 <QCardSection class="q-pa-none">
@@ -293,12 +289,9 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                 <QCardSection class="q-pa-none">
                     <VnLv
                         :label="t('invoiceIn.summary.taxableBase')"
-                        :value="toCurrency(entity.totals.totalTaxableBase, currency)"
-                    />
-                    <VnLv
-                        label="Total"
-                        :value="toCurrency(entity.totals.totalVat, currency)"
+                        :value="toCurrency(entity.totals.totalTaxableBase)"
                     />
+                    <VnLv label="Total" :value="toCurrency(entity.totals.totalVat)" />
                     <VnLv :label="t('invoiceIn.summary.dueTotal')">
                         <template #value>
                             <QChip
@@ -311,7 +304,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                                         : t('invoiceIn.summary.dueTotal')
                                 "
                             >
-                                {{ toCurrency(entity.totals.totalDueDay, currency) }}
+                                {{ toCurrency(entity.totals.totalDueDay) }}
                             </QChip>
                         </template>
                     </VnLv>
@@ -350,15 +343,17 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                     <template #bottom-row>
                         <QTr class="bg">
                             <QTd></QTd>
+                            <QTd>{{ toCurrency(entity.totals.totalTaxableBase) }}</QTd>
+                            <QTd></QTd>
+                            <QTd></QTd>
+                            <QTd>{{ toCurrency(getTotalTax(entity.invoiceInTax)) }}</QTd>
                             <QTd>{{
-                                toCurrency(entity.totals.totalTaxableBase, currency)
+                                entity.totals.totalTaxableBaseForeignValue &&
+                                toCurrency(
+                                    entity.totals.totalTaxableBaseForeignValue,
+                                    currency
+                                )
                             }}</QTd>
-                            <QTd></QTd>
-                            <QTd></QTd>
-                            <QTd>{{
-                                toCurrency(getTotalTax(entity.invoiceInTax, currency))
-                            }}</QTd>
-                            <QTd></QTd>
                         </QTr>
                     </template>
                 </QTable>
@@ -384,9 +379,17 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                             <QTd></QTd>
                             <QTd></QTd>
                             <QTd>
-                                {{ toCurrency(entity.totals.totalDueDay, currency) }}
+                                {{ toCurrency(entity.totals.totalDueDay) }}
+                            </QTd>
+                            <QTd>
+                                {{
+                                    entity.totals.totalDueDayForeignValue &&
+                                    toCurrency(
+                                        entity.totals.totalDueDayForeignValue,
+                                        currency
+                                    )
+                                }}
                             </QTd>
-                            <QTd></QTd>
                         </QTr>
                     </template>
                 </QTable>
@@ -421,7 +424,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                     <template #bottom-row>
                         <QTr class="bg">
                             <QTd></QTd>
-                            <QTd>{{ toCurrency(intrastatTotals.amount, currency) }}</QTd>
+                            <QTd>{{ toCurrency(intrastatTotals.amount) }}</QTd>
                             <QTd>{{ intrastatTotals.net }}</QTd>
                             <QTd>{{ intrastatTotals.stems }}</QTd>
                             <QTd></QTd>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
index 4dac5058e..d44880937 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
@@ -2,18 +2,17 @@
 import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { useQuasar } from 'quasar';
-import axios from 'axios';
 import { useArrayData } from 'src/composables/useArrayData';
+import { getTotal } from 'src/composables/getTotal';
 import { toCurrency } from 'src/filters';
 import FetchData from 'src/components/FetchData.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import CrudModel from 'src/components/CrudModel.vue';
-import VnInput from 'src/components/common/VnInput.vue';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
+import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
+import CreateNewExpenseForm from 'src/components/CreateNewExpenseForm.vue';
 
 const { t } = useI18n();
-const quasar = useQuasar();
 
 const arrayData = useArrayData();
 const invoiceIn = computed(() => arrayData.store.data);
@@ -23,15 +22,7 @@ const expenses = ref([]);
 const sageTaxTypes = ref([]);
 const sageTransactionTypes = ref([]);
 const rowsSelected = ref([]);
-const newExpense = ref({
-    code: undefined,
-    isWithheld: false,
-    description: undefined,
-});
-
 const invoiceInFormRef = ref();
-const expensesRef = ref();
-const newExpenseRef = ref();
 
 defineProps({
     actionIcon: {
@@ -56,7 +47,7 @@ const columns = computed(() => [
     {
         name: 'taxablebase',
         label: t('Taxable base'),
-        field: (row) => toCurrency(row.taxableBase, currency.value),
+        field: (row) => row.taxableBase,
         model: 'taxableBase',
         sortable: true,
         tabIndex: 2,
@@ -91,7 +82,7 @@ const columns = computed(() => [
         label: t('Rate'),
         sortable: true,
         tabIndex: 5,
-        field: (row) => toCurrency(taxRate(row, row.taxTypeSageFk), currency.value),
+        field: (row) => taxRate(row, row.taxTypeSageFk),
         align: 'left',
     },
     {
@@ -132,40 +123,6 @@ function taxRate(invoiceInTax) {
     return (taxTypeSage / 100) * taxableBase;
 }
 
-async function addExpense() {
-    try {
-        if (!newExpense.value.code) throw new Error(t(`The code can't be empty`));
-        if (isNaN(newExpense.value.code))
-            throw new Error(t(`The code have to be a number`));
-        if (!newExpense.value.description)
-            throw new Error(t(`The description can't be empty`));
-
-        const data = [
-            {
-                id: newExpense.value.code,
-                isWithheld: newExpense.value.isWithheld,
-                name: newExpense.value.description,
-            },
-        ];
-
-        await axios.post(`Expenses`, data);
-        await expensesRef.value.fetch();
-        quasar.notify({
-            type: 'positive',
-            message: t('globals.dataSaved'),
-        });
-        newExpenseRef.value.hide();
-    } catch (error) {
-        quasar.notify({
-            type: 'negative',
-            message: t(`${error.message}`),
-        });
-    }
-}
-const getTotalTaxableBase = (rows) =>
-    rows.reduce((acc, { taxableBase }) => acc + +(taxableBase || 0), 0);
-const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0);
-
 const formatOpt = (row, { model, options }, prop) => {
     const obj = row[model];
     const option = options.find(({ id }) => id == obj);
@@ -207,46 +164,35 @@ const formatOpt = (row, { model, options }, prop) => {
             >
                 <template #body-cell-expense="{ row, col }">
                     <QTd>
-                        <VnSelect
+                        <VnSelectDialog
                             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')"
                         >
                             <template #option="scope">
                                 <QItem v-bind="scope.itemProps">
                                     {{ `${scope.opt.id}: ${scope.opt.name}` }}
                                 </QItem>
                             </template>
-                            <template #append>
-                                <QIcon
-                                    name="close"
-                                    @click.stop="value = null"
-                                    class="cursor-pointer"
-                                    size="xs"
+                            <template #form>
+                                <CreateNewExpenseForm
+                                    @on-data-saved="$refs.expensesRef.fetch()"
                                 />
-                                <QIcon
-                                    @click.stop.prevent="newExpenseRef.show()"
-                                    :name="actionIcon"
-                                    size="xs"
-                                    class="default-icon"
-                                >
-                                    <QTooltip>
-                                        {{ t('Create expense') }}
-                                    </QTooltip>
-                                </QIcon>
                             </template>
-                        </VnSelect>
+                        </VnSelectDialog>
                     </QTd>
                 </template>
                 <template #body-cell-taxablebase="{ row }">
                     <QTd>
+                        {{ currency }}
                         <VnInputNumber
                             :class="{
-                                'no-pointer-events': isNotEuro(invoiceIn.currency.code),
+                                'no-pointer-events': isNotEuro(currency),
                             }"
-                            :disable="isNotEuro(invoiceIn.currency.code)"
+                            :disable="isNotEuro(currency)"
                             label=""
                             clear-icon="close"
                             v-model="row.taxableBase"
@@ -312,9 +258,9 @@ const formatOpt = (row, { model, options }, prop) => {
                     <QTd>
                         <VnInputNumber
                             :class="{
-                                'no-pointer-events': !isNotEuro(invoiceIn.currency.code),
+                                'no-pointer-events': !isNotEuro(currency),
                             }"
-                            :disable="!isNotEuro(invoiceIn.currency.code)"
+                            :disable="!isNotEuro(currency)"
                             v-model="row.foreignValue"
                         />
                     </QTd>
@@ -324,12 +270,24 @@ const formatOpt = (row, { model, options }, prop) => {
                         <QTd />
                         <QTd />
                         <QTd>
-                            {{ toCurrency(getTotalTaxableBase(rows), currency) }}
+                            {{ getTotal(rows, 'taxableBase', { currency: 'default' }) }}
                         </QTd>
                         <QTd />
                         <QTd />
-                        <QTd> {{ toCurrency(getTotalRate(rows), currency) }}</QTd>
-                        <QTd />
+                        <QTd>
+                            {{
+                                getTotal(rows, null, { cb: taxRate, currency: 'default' })
+                            }}</QTd
+                        >
+                        <QTd>
+                            <template v-if="isNotEuro(invoiceIn.currency.code)">
+                                {{
+                                    getTotal(rows, 'foreignValue', {
+                                        currency: invoiceIn.currency.code,
+                                    })
+                                }}
+                            </template>
+                        </QTd>
                     </QTr>
                 </template>
                 <template #item="props">
@@ -341,7 +299,7 @@ const formatOpt = (row, { model, options }, prop) => {
                             <QSeparator />
                             <QList>
                                 <QItem>
-                                    <VnSelect
+                                    <VnSelectDialog
                                         :label="t('Expense')"
                                         class="full-width"
                                         v-model="props.row['expenseFk']"
@@ -349,24 +307,26 @@ const formatOpt = (row, { model, options }, prop) => {
                                         option-value="id"
                                         option-label="name"
                                         :filter-options="['id', 'name']"
+                                        :tooltip="t('Create a new expense')"
                                     >
                                         <template #option="scope">
                                             <QItem v-bind="scope.itemProps">
                                                 {{ `${scope.opt.id}: ${scope.opt.name}` }}
                                             </QItem>
                                         </template>
-                                    </VnSelect>
+                                        <template #form>
+                                            <CreateNewExpenseForm />
+                                        </template>
+                                    </VnSelectDialog>
                                 </QItem>
                                 <QItem>
                                     <VnInputNumber
                                         :label="t('Taxable base')"
                                         :class="{
-                                            'no-pointer-events': isNotEuro(
-                                                invoiceIn.currency.code
-                                            ),
+                                            'no-pointer-events': isNotEuro(currency),
                                         }"
                                         class="full-width"
-                                        :disable="isNotEuro(invoiceIn.currency.code)"
+                                        :disable="isNotEuro(currency)"
                                         clear-icon="close"
                                         v-model="props.row.taxableBase"
                                         clearable
@@ -427,11 +387,9 @@ const formatOpt = (row, { model, options }, prop) => {
                                         :label="t('Foreign value')"
                                         class="full-width"
                                         :class="{
-                                            'no-pointer-events': !isNotEuro(
-                                                invoiceIn.currency.code
-                                            ),
+                                            'no-pointer-events': !isNotEuro(currency),
                                         }"
-                                        :disable="!isNotEuro(invoiceIn.currency.code)"
+                                        :disable="!isNotEuro(currency)"
                                         v-model="props.row.foreignValue"
                                     />
                                 </QItem>
@@ -442,44 +400,6 @@ const formatOpt = (row, { model, options }, prop) => {
             </QTable>
         </template>
     </CrudModel>
-    <QDialog ref="newExpenseRef">
-        <QCard>
-            <QCardSection class="q-pb-none">
-                <QItem class="q-pa-none">
-                    <span class="text-primary text-h6 full-width">
-                        <QIcon name="edit" class="q-mr-xs" />
-                        {{ t('New expense') }}
-                    </span>
-                    <QBtn icon="close" flat round dense v-close-popup />
-                </QItem>
-            </QCardSection>
-            <QCardSection class="q-pt-none">
-                <QItem>
-                    <VnInput
-                        :label="`${t('Code')}*`"
-                        v-model="newExpense.code"
-                        :required="true"
-                    />
-                    <QCheckbox
-                        dense
-                        size="sm"
-                        :label="`${t('It\'s a withholding')}`"
-                        v-model="newExpense.isWithheld"
-                    />
-                </QItem>
-                <QItem>
-                    <VnInput
-                        :label="`${t('Descripction')}*`"
-                        v-model="newExpense.description"
-                    />
-                </QItem>
-            </QCardSection>
-            <QCardActions class="justify-end">
-                <QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
-                <QBtn :label="t('globals.save')" color="primary" @click="addExpense" />
-            </QCardActions>
-        </QCard>
-    </QDialog>
     <QPageSticky position="bottom-right" :offset="[25, 25]">
         <QBtn
             color="primary"
@@ -487,7 +407,9 @@ const formatOpt = (row, { model, options }, prop) => {
             size="lg"
             round
             @click="invoiceInFormRef.insert()"
-        />
+        >
+            <QTooltip>{{ t('Add tax') }}</QTooltip>
+        </QBtn>
     </QPageSticky>
 </template>
 
@@ -527,18 +449,11 @@ const formatOpt = (row, { model, options }, prop) => {
 <i18n>
 es:
     Expense: Gasto
-    Create expense: Crear gasto
+    Create a new expense: Crear nuevo gasto
     Add tax: Crear gasto
     Taxable base: Base imp.
     Sage tax: Sage iva
     Sage transaction: Sage transacción
     Rate: Tasa
     Foreign value: Divisa
-    New expense: Nuevo gasto
-    Code: Código
-    It's a withholding: Es una retención
-    Descripction: Descripción
-    The code can't be empty: El código no puede estar vacío
-    The description can't be empty: La descripción no puede estar vacía
-    The code have to be a number: El código debe ser un número.
 </i18n>
diff --git a/src/pages/InvoiceIn/InvoiceInFilter.vue b/src/pages/InvoiceIn/InvoiceInFilter.vue
index 2f87c2b2e..bf4e023a9 100644
--- a/src/pages/InvoiceIn/InvoiceInFilter.vue
+++ b/src/pages/InvoiceIn/InvoiceInFilter.vue
@@ -28,6 +28,16 @@ const activities = ref([]);
             </div>
         </template>
         <template #body="{ params, searchFn }">
+            <QItem>
+                <QItemSection>
+                    <VnInputDate :label="t('From')" v-model="params.from" is-outlined />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInputDate :label="t('To')" v-model="params.to" is-outlined />
+                </QItemSection>
+            </QItem>
             <QItem>
                 <QItemSection>
                     <VnSelect
@@ -64,16 +74,6 @@ const activities = ref([]);
                     />
                 </QItemSection>
             </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInput
-                        :label="t('params.serialNumber')"
-                        v-model="params.serialNumber"
-                        is-outlined
-                        lazy-rules
-                    />
-                </QItemSection>
-            </QItem>
             <QItem>
                 <QItemSection>
                     <VnInput
@@ -84,15 +84,6 @@ const activities = ref([]);
                     />
                 </QItemSection>
             </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInputDate
-                        :label="t('Issued')"
-                        v-model="params.issued"
-                        is-outlined
-                    />
-                </QItemSection>
-            </QItem>
             <QItem>
                 <QItemSection>
                     <VnInput
@@ -140,22 +131,6 @@ const activities = ref([]);
                     />
                 </QItemSection>
             </QItem>
-            <QExpansionItem :label="t('More options')" expand-separator>
-                <QItem>
-                    <QItemSection>
-                        <VnInputDate
-                            :label="t('From')"
-                            v-model="params.from"
-                            is-outlined
-                        />
-                    </QItemSection>
-                </QItem>
-                <QItem>
-                    <QItemSection>
-                        <VnInputDate :label="t('To')" v-model="params.to" is-outlined />
-                    </QItemSection>
-                </QItem>
-            </QExpansionItem>
         </template>
     </VnFilterPanel>
 </template>
@@ -179,6 +154,7 @@ en:
         correctedFk: Rectified
         issued: Issued
         to: To
+        from: From
         awbCode: AWB
         correctingFk: Rectificative
         supplierActivityFk: Supplier activity
@@ -201,6 +177,8 @@ es:
         correctedFk: Rectificada
         correctingFk: Rectificativa
         supplierActivityFk: Actividad proveedor
+        from: Desde
+        to: Hasta
     From: Desde
     To: Hasta
     Amount: Importe
diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue
index 234cfb50f..0cad09378 100644
--- a/src/pages/InvoiceIn/InvoiceInList.vue
+++ b/src/pages/InvoiceIn/InvoiceInList.vue
@@ -47,12 +47,6 @@ const cols = computed(() => [
         name: 'supplierRef',
         label: t('invoiceIn.list.supplierRef'),
     },
-
-    {
-        align: 'left',
-        name: 'serialNumber',
-        label: t('invoiceIn.list.serialNumber'),
-    },
     {
         align: 'left',
         name: 'serial',
@@ -141,7 +135,7 @@ const cols = computed(() => [
                 v-model="data.supplierFk"
                 url="Suppliers"
                 :fields="['id', 'nickname']"
-                :label="t('Supplier')"
+                :label="t('globals.supplier')"
                 option-value="id"
                 option-label="nickname"
                 :filter-options="['id', 'name']"
@@ -162,7 +156,7 @@ const cols = computed(() => [
             />
             <VnSelect
                 url="Companies"
-                :label="t('Company')"
+                :label="t('globals.company')"
                 :fields="['id', 'code']"
                 v-model="data.companyFk"
                 option-value="id"
diff --git a/src/pages/InvoiceIn/Serial/InvoiceInSerial.vue b/src/pages/InvoiceIn/Serial/InvoiceInSerial.vue
new file mode 100644
index 000000000..4eb9fa69d
--- /dev/null
+++ b/src/pages/InvoiceIn/Serial/InvoiceInSerial.vue
@@ -0,0 +1,68 @@
+<script setup>
+import { ref, computed, onBeforeMount } from 'vue';
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import axios from 'axios';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import RightMenu from 'src/components/common/RightMenu.vue';
+import InvoiceInSerialFilter from './InvoiceInSerialFilter.vue';
+
+const { t } = useI18n();
+
+const cols = computed(() => [
+    {
+        align: 'left',
+        name: 'serial',
+        label: t('Serial'),
+        columnFilter: false,
+    },
+    {
+        align: 'left',
+        name: 'pending',
+        label: t('Pending'),
+        columnFilter: false,
+    },
+    {
+        align: 'left',
+        name: 'total',
+        label: 'Total',
+        columnFilter: false,
+    },
+]);
+
+const daysAgo = ref();
+
+onBeforeMount(async () => {
+    const tableParam = useRoute().query.table;
+
+    if (tableParam) daysAgo.value = JSON.parse(tableParam).daysAgo;
+    else
+        daysAgo.value = (
+            await axios.get('InvoiceInConfigs/findOne', {
+                params: { filter: { fields: ['daysAgo'] } },
+            })
+        ).data?.daysAgo;
+});
+</script>
+<template>
+    <RightMenu>
+        <template #right-panel>
+            <InvoiceInSerialFilter data-key="InvoiceInSerial" />
+        </template>
+    </RightMenu>
+    <VnTable
+        v-if="!isNaN(daysAgo)"
+        data-key="InvoiceInSerial"
+        url="InvoiceIns/getSerial"
+        :columns="cols"
+        :right-search="false"
+        :user-params="{ daysAgo }"
+        :disable-option="{ card: true }"
+        auto-load
+    />
+</template>
+<i18n>
+es:
+    Serial: Serie
+    Pending: Pendiente
+</i18n>
diff --git a/src/pages/InvoiceIn/Serial/InvoiceInSerialFilter.vue b/src/pages/InvoiceIn/Serial/InvoiceInSerialFilter.vue
new file mode 100644
index 000000000..4f8c9d70b
--- /dev/null
+++ b/src/pages/InvoiceIn/Serial/InvoiceInSerialFilter.vue
@@ -0,0 +1,53 @@
+<script setup>
+import { useI18n } from 'vue-i18n';
+import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
+defineProps({ dataKey: { type: String, required: true } });
+
+const { t } = useI18n();
+</script>
+<template>
+    <VnFilterPanel :data-key="dataKey" :search-button="true">
+        <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 }">
+            <QItem>
+                <QItemSection>
+                    <VnInputNumber
+                        v-model="params.daysAgo"
+                        :label="t('params.daysAgo')"
+                        outlined
+                        rounded
+                        dense
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.serial"
+                        :label="t('params.serial')"
+                        outlined
+                        rounded
+                        dense
+                    />
+                </QItemSection>
+            </QItem>
+        </template>
+    </VnFilterPanel>
+</template>
+<i18n>
+en:
+    params:
+        daysAgo: Last days
+        serial: serial
+es:
+    params:
+        daysAgo: Últimos días
+        serial: serie
+</i18n>
diff --git a/src/pages/InvoiceIn/composables/setRectificative.js b/src/pages/InvoiceIn/composables/setRectificative.js
new file mode 100644
index 000000000..a1afb8fb0
--- /dev/null
+++ b/src/pages/InvoiceIn/composables/setRectificative.js
@@ -0,0 +1,14 @@
+import axios from 'axios';
+
+export async function setRectificative(route) {
+    const card = route.matched.find((route) => route.name === 'InvoiceInCard');
+    const corrective = card.children.find(
+        (route) => route.name === 'InvoiceInCorrective'
+    );
+
+    corrective.meta.hidden = !(
+        await axios.get('InvoiceInCorrections', {
+            params: { filter: { where: { correctingFk: route.params.id } } },
+        })
+    ).data.length;
+}
diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml
new file mode 100644
index 000000000..824fd6e12
--- /dev/null
+++ b/src/pages/InvoiceIn/locale/en.yml
@@ -0,0 +1,49 @@
+invoiceIn:
+    serial: Serial
+    list:
+        ref: Reference
+        supplier: Supplier
+        supplierRef: Supplier ref.
+        serial: Serial
+        file: File
+        issued: Issued
+        isBooked: Is booked
+        awb: AWB
+        amount: Amount
+    card:
+        issued: Issued
+        amount: Amount
+        client: Client
+        company: Company
+        customerCard: Customer card
+        ticketList: Ticket List
+        vat: Vat
+        dueDay: Due day
+        intrastat: Intrastat
+    summary:
+        supplier: Supplier
+        supplierRef: Supplier ref.
+        currency: Currency
+        issued: Expedition date
+        operated: Operation date
+        bookEntried: Entry date
+        bookedDate: Booked date
+        sage: Sage withholding
+        vat: Undeductible VAT
+        company: Company
+        booked: Booked
+        expense: Expense
+        taxableBase: Taxable base
+        rate: Rate
+        sageVat: Sage vat
+        sageTransaction: Sage transaction
+        dueDay: Date
+        bank: Bank
+        amount: Amount
+        foreignValue: Foreign value
+        dueTotal: Due day
+        noMatch: Do not match
+        code: Code
+        net: Net
+        stems: Stems
+        country: Country
diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml
new file mode 100644
index 000000000..944708364
--- /dev/null
+++ b/src/pages/InvoiceIn/locale/es.yml
@@ -0,0 +1,47 @@
+invoiceIn:
+    serial: Serie
+    list:
+        ref: Referencia
+        supplier: Proveedor
+        supplierRef: Ref. proveedor
+        shortIssued: F. emisión
+        file: Fichero
+        issued: Fecha emisión
+        isBooked: Conciliada
+        awb: AWB
+        amount: Importe
+    card:
+        issued: Fecha emisión
+        amount: Importe
+        client: Cliente
+        company: Empresa
+        customerCard: Ficha del cliente
+        ticketList: Listado de tickets
+        vat: Iva
+        dueDay: Fecha de vencimiento
+    summary:
+        supplier: Proveedor
+        supplierRef: Ref. proveedor
+        currency: Divisa
+        docNumber: Número documento
+        issued: Fecha de expedición
+        operated: Fecha operación
+        bookEntried: Fecha asiento
+        bookedDate: Fecha contable
+        sage: Retención sage
+        vat: Iva no deducible
+        company: Empresa
+        booked: Contabilizada
+        expense: Gasto
+        taxableBase: Base imp.
+        rate: Tasa
+        sageTransaction: Sage transación
+        dueDay: Fecha
+        bank: Caja
+        amount: Importe
+        foreignValue: Divisa
+        dueTotal: Vencimiento
+        code: Código
+        net: Neto
+        stems: Tallos
+        country: País
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue b/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue
index e524faa24..08b21fb4a 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue
@@ -5,6 +5,7 @@ import { useRouter } from 'vue-router';
 import { useQuasar } from 'quasar';
 
 import TransferInvoiceForm from 'src/components/TransferInvoiceForm.vue';
+import RefundInvoiceForm from 'src/components/RefundInvoiceForm.vue';
 import SendEmailDialog from 'components/common/SendEmailDialog.vue';
 
 import useNotify from 'src/composables/useNotify';
@@ -40,8 +41,7 @@ const invoiceFormType = ref('pdf');
 const defaultEmailAddress = ref($props.invoiceOutData.client?.email);
 
 const showInvoicePdf = () => {
-    const url = `api/InvoiceOuts/${$props.invoiceOutData.id}/download?access_token=${token}`;
-    window.open(url, '_blank');
+    openReport(`InvoiceOuts/${$props.invoiceOutData.id}/download`, {}, '_blank');
 };
 
 const showInvoiceCsv = () => {
@@ -141,6 +141,15 @@ const showTransferInvoiceForm = async () => {
         },
     });
 };
+
+const showRefundInvoiceForm = () => {
+    quasar.dialog({
+        component: RefundInvoiceForm,
+        componentProps: {
+            invoiceOutData: $props.invoiceOutData,
+        },
+    });
+};
 </script>
 
 <template>
@@ -222,17 +231,20 @@ const showTransferInvoiceForm = async () => {
         <QItemSection>{{ t('Generate PDF invoice') }}</QItemSection>
     </QItem>
     <QItem v-ripple clickable>
-        <QItemSection>{{ t('Refund...') }}</QItemSection>
+        <QItemSection>{{ t('Refund') }}</QItemSection>
         <QItemSection side>
             <QIcon name="keyboard_arrow_right" />
         </QItemSection>
         <QMenu anchor="top end" self="top start">
             <QList>
                 <QItem v-ripple clickable @click="refundInvoice(true)">
-                    <QItemSection>{{ t('With warehouse') }}</QItemSection>
+                    <QItemSection>{{ t('With warehouse, no invoice') }}</QItemSection>
                 </QItem>
                 <QItem v-ripple clickable @click="refundInvoice(false)">
-                    <QItemSection>{{ t('Without warehouse') }}</QItemSection>
+                    <QItemSection>{{ t('Without warehouse, no invoice') }}</QItemSection>
+                </QItem>
+                <QItem v-ripple clickable @click="showRefundInvoiceForm()">
+                    <QItemSection>{{ t('Invoiced') }}</QItemSection>
                 </QItem>
             </QList>
         </QMenu>
@@ -250,13 +262,14 @@ es:
     Delete invoice: Eliminar factura
     Book invoice: Asentar factura
     Generate PDF invoice: Generar PDF factura
-    Refund...: Abono
+    Refund: Abono
     As PDF: como PDF
     As CSV: como CSV
     Send PDF: Enviar PDF
     Send CSV: Enviar CSV
-    With warehouse: Con almacén
-    Without warehouse: Sin almacén
+    With warehouse, no invoice: Con almacén, sin factura
+    Without warehouse, no invoice: Sin almacén, sin factura
+    Invoiced: Facturado
     InvoiceOut deleted: Factura eliminada
     Confirm deletion: Confirmar eliminación
     Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura?
diff --git a/src/pages/InvoiceOut/InvoiceOutGlobal.vue b/src/pages/InvoiceOut/InvoiceOutGlobal.vue
index eecc61bc2..5f2eb3c02 100644
--- a/src/pages/InvoiceOut/InvoiceOutGlobal.vue
+++ b/src/pages/InvoiceOut/InvoiceOutGlobal.vue
@@ -94,11 +94,13 @@ const selectCustomerId = (id) => {
 };
 
 const statusText = computed(() => {
-    return status.value === 'invoicing'
-        ? `${t(`status.${status.value}`)} ${
-              addresses.value[getAddressNumber.value]?.clientId
-          }`
-        : t(`status.${status.value}`);
+    const baseStatus = t(`status.${status.value}`);
+    const clientId =
+        status.value === 'invoicing'
+            ? addresses.value[getAddressNumber.value]?.clientId || ''
+            : '';
+
+    return clientId ? `${baseStatus} ${clientId}`.trim() : baseStatus;
 });
 
 onMounted(() => (stateStore.rightDrawer = true));
diff --git a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
index 23c63ee6a..5bcb21001 100644
--- a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
+++ b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
@@ -20,21 +20,25 @@ const { initialDataLoading, formInitialData, invoicing, status } =
 const { makeInvoice, setStatusValue } = invoiceOutGlobalStore;
 
 const clientsToInvoice = ref('all');
-
 const companiesOptions = ref([]);
-
 const printersOptions = ref([]);
+const serialTypesOptions = ref([]);
 
-const clientsOptions = ref([]);
+const handleInvoiceOutSerialsFetch = (data) => {
+    serialTypesOptions.value = Array.from(
+        new Set(data.map((item) => item.type).filter((type) => type))
+    );
+};
 
 const formData = ref({});
 
 const optionsInitialData = computed(() => {
-    return (
-        companiesOptions.value.length > 0 &&
-        printersOptions.value.length > 0 &&
-        clientsOptions.value.length > 0
-    );
+    const optionsArrays = [
+        companiesOptions.value,
+        printersOptions.value,
+        serialTypesOptions.value,
+    ];
+    return optionsArrays.every((arr) => arr.length > 0);
 });
 
 const getStatus = computed({
@@ -48,7 +52,7 @@ const getStatus = computed({
 
 onMounted(async () => {
     await invoiceOutGlobalStore.init();
-    formData.value = formInitialData.value.invoiceDate;
+    formData.value = { invoiceDate: formInitialData.value.invoiceDate };
 });
 </script>
 
@@ -59,8 +63,11 @@ onMounted(async () => {
         auto-load
     />
     <FetchData url="Printers" @on-fetch="(data) => (printersOptions = data)" auto-load />
-    <FetchData url="Clients" @on-fetch="(data) => (clientsOptions = data)" auto-load />
-
+    <FetchData
+        url="invoiceOutSerials"
+        @on-fetch="handleInvoiceOutSerialsFetch"
+        auto-load
+    />
     <QForm
         v-if="!initialDataLoading && optionsInitialData"
         @submit="makeInvoice(formData, clientsToInvoice)"
@@ -87,13 +94,34 @@ onMounted(async () => {
                 v-if="clientsToInvoice === 'one'"
                 :label="t('client')"
                 v-model="formData.clientId"
-                :options="clientsOptions"
+                url="Clients"
                 option-value="id"
                 option-label="name"
                 hide-selected
                 dense
                 outlined
                 rounded
+            >
+                <template #option="scope">
+                    <QItem v-bind="scope.itemProps">
+                        <QItemSection>
+                            <QItemLabel>
+                                #{{ scope.opt?.id }} {{ scope.opt?.name }}
+                            </QItemLabel>
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
+            <VnSelect
+                :label="t('invoiceOutSerialType')"
+                v-model="formData.serialType"
+                :options="serialTypesOptions"
+                option-value="type"
+                option-label="type"
+                hide-selected
+                dense
+                outlined
+                rounded
             />
             <VnInputDate
                 v-model="formData.invoiceDate"
@@ -109,9 +137,7 @@ onMounted(async () => {
                 :label="t('company')"
                 v-model="formData.companyFk"
                 :options="companiesOptions"
-                option-value="id"
                 option-label="code"
-                hide-selected
                 dense
                 outlined
                 rounded
@@ -120,9 +146,6 @@ onMounted(async () => {
                 :label="t('printer')"
                 v-model="formData.printer"
                 :options="printersOptions"
-                option-value="id"
-                option-label="name"
-                hide-selected
                 dense
                 outlined
                 rounded
@@ -168,6 +191,7 @@ en:
     printer: Printer
     invoiceOut: Invoice out
     client: Client
+    invoiceOutSerialType: Serial Type
     stop: Stop
 
 es:
@@ -179,5 +203,6 @@ es:
     printer: Impresora
     invoiceOut: Facturar
     client: Cliente
+    invoiceOutSerialType: Tipo de Serie
     stop: Parar
 </i18n>
diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue
index 528cdf234..915b58b15 100644
--- a/src/pages/InvoiceOut/InvoiceOutList.vue
+++ b/src/pages/InvoiceOut/InvoiceOutList.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, onUnmounted, ref, computed } from 'vue';
+import { onMounted, onUnmounted, ref, computed, watchEffect } from 'vue';
 import { useI18n } from 'vue-i18n';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
@@ -12,7 +12,6 @@ import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
 import { toCurrency, toDate } from 'src/filters/index';
 import { useStateStore } from 'stores/useStateStore';
 import { QBtn } from 'quasar';
-import { watchEffect } from 'vue';
 import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
 
 const { t } = useI18n();
@@ -20,7 +19,6 @@ const stateStore = useStateStore();
 const { viewSummary } = useSummaryDialog();
 const tableRef = ref();
 const invoiceOutSerialsOptions = ref([]);
-const ticketsOptions = ref([]);
 const customerOptions = ref([]);
 const selectedRows = ref([]);
 const hasSelectedCards = computed(() => selectedRows.value.length > 0);
@@ -123,7 +121,7 @@ const columns = computed(() => [
         name: 'tableActions',
         actions: [
             {
-                title: t('InvoiceOutSummary'),
+                title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row.id, InvoiceOutSummary),
             },
@@ -199,7 +197,7 @@ watchEffect(selectedRows);
         :url="`${MODEL}/filter`"
         :create="{
             urlCreate: 'InvoiceOuts/createManualInvoice',
-            title: t('Create Manual Invoice'),
+            title: t('Create manual invoice'),
             onDataSaved: ({ id }) => tableRef.redirect(id),
             formInitialData: {
                 active: true,
@@ -222,14 +220,25 @@ watchEffect(selectedRows);
             </span>
         </template>
         <template #more-create-dialog="{ data }">
-            <VnSelect
-                url="Tickets"
-                v-model="data.ticketFk"
-                :label="t('invoiceOutList.tableVisibleColumns.ticket')"
-                :options="ticketsOptions"
-                option-label="nickname"
-                option-value="id"
-            />
+            <div class="flex no-wrap flex-center">
+                <VnSelect
+                    url="Tickets"
+                    v-model="data.ticketFk"
+                    :label="t('invoiceOutList.tableVisibleColumns.ticket')"
+                    option-label="id"
+                    option-value="id"
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
+                                <QItemLabel caption>{{ scope.opt?.nickname }}</QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
+                <span class="q-ml-md">O</span>
+            </div>
             <VnSelect
                 url="Clients"
                 v-model="data.clientFk"
@@ -238,21 +247,21 @@ watchEffect(selectedRows);
                 option-label="name"
                 option-value="id"
             />
-            <VnInputDate
-                :label="t('invoiceOutList.tableVisibleColumns.dueDate')"
-                v-model="data.maxShipped"
-            />
             <VnSelect
                 url="InvoiceOutSerials"
-                v-model="data.invoiceOutSerial"
+                v-model="data.serial"
                 :label="t('invoiceOutList.tableVisibleColumns.invoiceOutSerial')"
                 :options="invoiceOutSerialsOptions"
                 option-label="description"
                 option-value="code"
             />
+            <VnInputDate
+                :label="t('invoiceOutList.tableVisibleColumns.dueDate')"
+                v-model="data.maxShipped"
+            />
             <VnSelect
                 url="TaxAreas"
-                v-model="data.area"
+                v-model="data.taxArea"
                 :label="t('invoiceOutList.tableVisibleColumns.taxArea')"
                 :options="taxAreasOptions"
                 option-label="code"
@@ -273,10 +282,12 @@ en:
     fileAllowed: Successful download of CSV file
     youCanSearchByInvoiceReference: You can search by invoice reference
     createInvoice: Make invoice
+    Create manual invoice: Create manual invoice
 es:
     searchInvoice: Buscar factura emitida
     fileDenied: El navegador denegó la descarga de archivos...
     fileAllowed: Descarga exitosa de archivo CSV
     youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
     createInvoice: Crear factura
+    Create manual invoice: Crear factura manual
 </i18n>
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
index 93b326c59..774b42478 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
@@ -74,6 +74,9 @@ const columns = computed(() => [
         align: 'left',
         name: 'amount',
         label: t('invoiceOutModule.amount'),
+        columnFilter: {
+            type: 'number',
+        },
         format: (row) => toCurrency(row.amount),
         cardVisible: true,
     },
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
index 2d192ebb3..94eab2aab 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue
@@ -19,7 +19,7 @@ const props = defineProps({
     <VnFilterPanel
         :data-key="props.dataKey"
         :search-button="true"
-        :unremovable-params="['from', 'to']"
+        :un-removable-params="['from', 'to']"
         :hidden-tags="['from', 'to']"
     >
         <template #tags="{ tag, formatFn }">
diff --git a/src/pages/Item/Card/ItemBasicData.vue b/src/pages/Item/Card/ItemBasicData.vue
index 89c883295..ae9e45983 100644
--- a/src/pages/Item/Card/ItemBasicData.vue
+++ b/src/pages/Item/Card/ItemBasicData.vue
@@ -16,7 +16,6 @@ const route = useRoute();
 const { t } = useI18n();
 
 const itemTypesOptions = ref([]);
-const itemsWithNameOptions = ref([]);
 const intrastatsOptions = ref([]);
 const expensesOptions = ref([]);
 
diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue
index 416c7f78b..0687b8db3 100644
--- a/src/pages/Item/Card/ItemBotanical.vue
+++ b/src/pages/Item/Card/ItemBotanical.vue
@@ -14,20 +14,9 @@ const route = useRoute();
 const { t } = useI18n();
 
 const itemBotanicalsRef = ref(null);
-const itemGenusOptions = ref([]);
-const itemSpeciesOptions = ref([]);
 const itemBotanicals = ref([]);
 let itemBotanicalsForm = reactive({ itemFk: null });
 
-const onGenusCreated = (response, formData) => {
-    itemGenusOptions.value = [...itemGenusOptions.value, response];
-    formData.genusFk = response.id;
-};
-
-const onSpecieCreated = (response, formData) => {
-    itemSpeciesOptions.value = [...itemSpeciesOptions.value, response];
-    formData.specieFk = response.id;
-};
 const entityId = computed(() => {
     return route.params.id;
 });
@@ -47,18 +36,6 @@ onMounted(async () => {
         }"
         @on-fetch="(data) => (itemBotanicals = data)"
     />
-    <FetchData
-        url="Genera"
-        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
-        @on-fetch="(data) => (itemGenusOptions = data)"
-        auto-load
-    />
-    <FetchData
-        url="Species"
-        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
-        @on-fetch="(data) => (itemSpeciesOptions = data)"
-        auto-load
-    />
     <FormModel
         url-update="ItemBotanicals"
         model="entry"
@@ -69,36 +46,35 @@ onMounted(async () => {
         <template #form="{ data }">
             <VnRow>
                 <VnSelectDialog
+                    ref="genusRef"
                     :label="t('Genus')"
                     v-model="data.genusFk"
-                    :options="itemGenusOptions"
+                    url="Genera"
                     option-label="name"
                     option-value="id"
+                    :fields="['id', 'name']"
+                    sort-by="name ASC"
                     hide-selected
                 >
                     <template #form>
                         <CreateGenusForm
-                            @on-data-saved="
-                                (_, requestResponse) =>
-                                    onGenusCreated(requestResponse, data)
-                            "
+                            @on-data-saved="(_, res) => (data.genusFk = res.id)"
                         />
                     </template>
                 </VnSelectDialog>
                 <VnSelectDialog
                     :label="t('Species')"
                     v-model="data.specieFk"
-                    :options="itemSpeciesOptions"
+                    url="Species"
                     option-label="name"
                     option-value="id"
+                    :fields="['id', 'name']"
+                    sort-by="name ASC"
                     hide-selected
                 >
                     <template #form>
                         <CreateSpecieForm
-                            @on-data-saved="
-                                (_, requestResponse) =>
-                                    onSpecieCreated(requestResponse, data)
-                            "
+                            @on-data-saved="(_, res) => (data.specieFk = res.id)"
                         />
                     </template>
                 </VnSelectDialog>
diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue
index 8381f0624..baac0c608 100644
--- a/src/pages/Item/Card/ItemDescriptor.vue
+++ b/src/pages/Item/Card/ItemDescriptor.vue
@@ -10,8 +10,6 @@ import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.v
 import VnConfirm from 'components/ui/VnConfirm.vue';
 import RegularizeStockForm from 'components/RegularizeStockForm.vue';
 import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue';
-
-import { useState } from 'src/composables/useState';
 import useCardDescription from 'src/composables/useCardDescription';
 import { getUrl } from 'src/composables/getUrl';
 import axios from 'axios';
@@ -35,58 +33,69 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
+    warehouseFk: {
+        type: Number,
+        default: null,
+    },
 });
 
 const quasar = useQuasar();
 const route = useRoute();
 const router = useRouter();
 const { t } = useI18n();
-const state = useState();
-const user = state.getUser();
-
+const warehouseConfig = ref(null);
 const entityId = computed(() => {
     return $props.id || route.params.id;
 });
+
 const regularizeStockFormDialog = ref(null);
 const available = ref(null);
 const visible = ref(null);
-const _warehouseFk = ref(null);
 const salixUrl = ref();
-const warehouseFk = computed({
-    get() {
-        return _warehouseFk.value;
-    },
-    set(val) {
-        _warehouseFk.value = val;
-        if (val) updateStock();
-    },
-});
 
 onMounted(async () => {
-    warehouseFk.value = user.value.warehouseFk;
     salixUrl.value = await getUrl('');
+    await getItemConfigs();
+    await updateStock();
 });
 
 const data = ref(useCardDescription());
-const setData = (entity) => {
-    if (!entity) return;
-    data.value = useCardDescription(entity.name, entity.id);
+const setData = async (entity) => {
+    try {
+        if (!entity) return;
+        data.value = useCardDescription(entity.name, entity.id);
+        await updateStock();
+    } catch (err) {
+        console.error('Error item');
+    }
 };
 
+const getItemConfigs = async () => {
+    try {
+        const { data } = await axios.get('ItemConfigs/findOne');
+        if (!data) return;
+        return (warehouseConfig.value = data.warehouseFk);
+    } catch (err) {
+        console.error('Error item');
+    }
+};
 const updateStock = async () => {
     try {
         available.value = null;
         visible.value = null;
 
         const params = {
-            warehouseFk: warehouseFk.value,
+            warehouseFk: $props.warehouseFk,
             dated: $props.dated,
         };
 
+        await getItemConfigs();
+        if (!params.warehouseFk) {
+            params.warehouseFk = warehouseConfig.value;
+        }
         const { data } = await axios.get(`Items/${entityId.value}/getVisibleAvailable`, {
             params,
         });
-
         available.value = data.available;
         visible.value = data.visible;
     } catch (err) {
diff --git a/src/pages/Item/Card/ItemDescriptorImage.vue b/src/pages/Item/Card/ItemDescriptorImage.vue
index d923dd28f..a4ef22ce3 100644
--- a/src/pages/Item/Card/ItemDescriptorImage.vue
+++ b/src/pages/Item/Card/ItemDescriptorImage.vue
@@ -47,8 +47,11 @@ const getWarehouseName = async (warehouseFk) => {
     const filter = {
         where: { id: warehouseFk },
     };
-
-    const { data } = await axios.get('Warehouses/findOne', { filter });
+    const { data } = await axios.get('Warehouses/findOne', {
+        params: {
+            filter: JSON.stringify(filter),
+        },
+    });
     if (!data) return;
     warehouseName.value = data.name;
 };
@@ -138,14 +141,6 @@ en:
 </i18n>
 
 <style lang="scss" scoped>
-.edit-photo-btn {
-    position: absolute;
-    right: 12px;
-    bottom: 12px;
-    z-index: 1;
-    cursor: pointer;
-}
-
 .separation-borders {
     border-left: 1px solid $white;
     border-right: 1px solid $white;
diff --git a/src/pages/Item/Card/ItemDescriptorProxy.vue b/src/pages/Item/Card/ItemDescriptorProxy.vue
index 2b7b39a65..2ffc9080f 100644
--- a/src/pages/Item/Card/ItemDescriptorProxy.vue
+++ b/src/pages/Item/Card/ItemDescriptorProxy.vue
@@ -15,6 +15,10 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
+    warehouseFk: {
+        type: Number,
+        default: null,
+    },
 });
 </script>
 
@@ -26,6 +30,7 @@ const $props = defineProps({
             :summary="ItemSummary"
             :dated="dated"
             :sale-fk="saleFk"
+            :warehouse-fk="warehouseFk"
         />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Item/Card/ItemShelving.vue b/src/pages/Item/Card/ItemShelving.vue
index 7e7faab36..41cb34c03 100644
--- a/src/pages/Item/Card/ItemShelving.vue
+++ b/src/pages/Item/Card/ItemShelving.vue
@@ -3,7 +3,6 @@ import { onMounted, ref, computed, reactive } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
-import FetchData from 'components/FetchData.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
@@ -24,8 +23,6 @@ const { notify } = useNotify();
 const { openConfirmationModal } = useVnConfirm();
 
 const rowsSelected = ref([]);
-const parkingsOptions = ref([]);
-const shelvingsOptions = ref([]);
 
 const exprBuilder = (param, value) => {
     switch (param) {
@@ -104,7 +101,9 @@ const columns = computed(() => [
             filterValue: null,
             event: getInputEvents,
             attrs: {
-                options: parkingsOptions.value,
+                url: 'parkings',
+                fields: ['code'],
+                'sort-by': 'code ASC',
                 'option-value': 'code',
                 'option-label': 'code',
                 dense: true,
@@ -124,7 +123,9 @@ const columns = computed(() => [
             filterValue: null,
             event: getInputEvents,
             attrs: {
-                options: shelvingsOptions.value,
+                url: 'shelvings',
+                fields: ['code'],
+                'sort-by': 'code ASC',
                 'option-value': 'code',
                 'option-label': 'code',
                 dense: true,
@@ -188,18 +189,6 @@ onMounted(async () => {
 </script>
 
 <template>
-    <FetchData
-        url="parkings"
-        :filter="{ fields: ['code'], order: 'code ASC' }"
-        auto-load
-        @on-fetch="(data) => (parkingsOptions = data)"
-    />
-    <FetchData
-        url="shelvings"
-        :filter="{ fields: ['code'], order: 'code ASC' }"
-        auto-load
-        @on-fetch="(data) => (shelvingsOptions = data)"
-    />
     <template v-if="stateStore.isHeaderMounted()">
         <Teleport to="#st-data">
             <div class="q-pa-md q-mr-lg q-ma-xs" style="border: 2px solid #222">
@@ -237,7 +226,6 @@ onMounted(async () => {
             </QBtn>
         </Teleport>
     </template>
-
     <QPage class="column items-center q-pa-md">
         <QTable
             :rows="rows"
diff --git a/src/pages/Item/Card/ItemSummary.vue b/src/pages/Item/Card/ItemSummary.vue
index 7af3e0fa0..7b6015c30 100644
--- a/src/pages/Item/Card/ItemSummary.vue
+++ b/src/pages/Item/Card/ItemSummary.vue
@@ -7,8 +7,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import ItemDescriptorImage from 'src/pages/Item/Card/ItemDescriptorImage.vue';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
-
-import { useRole } from 'src/composables/useRole';
+import VnTitle from 'src/components/common/VnTitle.vue';
 
 const $props = defineProps({
     id: {
@@ -19,23 +18,10 @@ const $props = defineProps({
 
 const route = useRoute();
 const { t } = useI18n();
-const roleState = useRole();
 
 const entityId = computed(() => $props.id || route.params.id);
-
-const isBuyer = computed(() => {
-    return roleState.hasAny(['buyer']);
-});
-
-const isReplenisher = computed(() => {
-    return roleState.hasAny(['replenisher']);
-});
-
-const isAdministrative = computed(() => {
-    return roleState.hasAny(['administrative']);
-});
+const getUrl = (id, param) => `#/Item/${id}/${param}`;
 </script>
-
 <template>
     <CardSummary
         ref="summary"
@@ -44,13 +30,15 @@ const isAdministrative = computed(() => {
         data-key="ItemSummary"
     >
         <template #header-left>
-            <router-link
-                v-if="route.name !== 'ItemSummary'"
+            <QBtn
+                v-if="$route.name !== 'ItemSummary'"
                 :to="{ name: 'ItemSummary', params: { id: entityId } }"
-                class="header link"
-            >
-                <QIcon name="open_in_new" color="white" size="sm" />
-            </router-link>
+                class="header link--white"
+                icon="open_in_new"
+                flat
+                dense
+                round
+            />
         </template>
         <template #header="{ entity: { item } }">
             {{ item.id }} - {{ item.name }}
@@ -65,15 +53,10 @@ const isAdministrative = computed(() => {
                 />
             </QCard>
             <QCard class="vn-one">
-                <component
-                    :is="isBuyer ? 'router-link' : 'span'"
-                    :to="{ name: 'ItemBasicData', params: { id: entityId } }"
-                    class="header"
-                    :class="{ 'header-link': isBuyer }"
-                >
-                    {{ t('item.summary.basicData') }}
-                    <QIcon v-if="isBuyer" name="open_in_new" />
-                </component>
+                <VnTitle
+                    :url="getUrl(entityId, 'basic-data')"
+                    :text="t('item.summary.basicData')"
+                />
                 <VnLv :label="t('item.summary.name')" :value="item.name" />
                 <VnLv :label="t('item.summary.completeName')" :value="item.longName" />
                 <VnLv :label="t('item.summary.family')" :value="item.itemType.name" />
@@ -104,15 +87,10 @@ const isAdministrative = computed(() => {
                 </VnLv>
             </QCard>
             <QCard class="vn-one">
-                <component
-                    :is="isBuyer ? 'router-link' : 'span'"
-                    :to="{ name: 'ItemBasicData', params: { id: entityId } }"
-                    class="header"
-                    :class="{ 'header-link': isBuyer }"
-                >
-                    {{ t('item.summary.otherData') }}
-                    <QIcon v-if="isBuyer" name="open_in_new" />
-                </component>
+                <VnTitle
+                    :url="getUrl(entityId, 'basic-data')"
+                    :text="t('item.summary.otherData')"
+                />
                 <VnLv
                     :label="t('item.summary.intrastatCode')"
                     :value="item.intrastat.id"
@@ -137,15 +115,7 @@ const isAdministrative = computed(() => {
                 />
             </QCard>
             <QCard class="vn-one">
-                <component
-                    :is="isBuyer || isReplenisher ? 'router-link' : 'span'"
-                    :to="{ name: 'ItemTags', params: { id: entityId } }"
-                    class="header"
-                    :class="{ 'header-link': isBuyer || isReplenisher }"
-                >
-                    {{ t('item.summary.tags') }}
-                    <QIcon v-if="isBuyer || isReplenisher" name="open_in_new" />
-                </component>
+                <VnTitle :url="getUrl(entityId, 'tags')" :text="t('item.summary.tags')" />
                 <VnLv
                     v-for="(tag, index) in tags"
                     :key="index"
@@ -154,29 +124,14 @@ const isAdministrative = computed(() => {
                 />
             </QCard>
             <QCard class="vn-one" v-if="item.description">
-                <component
-                    :is="isBuyer ? 'router-link' : 'span'"
-                    :to="{ name: 'ItemBasicData', params: { id: entityId } }"
-                    class="header"
-                    :class="{ 'header-link': isBuyer }"
-                >
-                    {{ t('item.summary.description') }}
-                    <QIcon v-if="isBuyer" name="open_in_new" />
-                </component>
-                <p>
-                    {{ item.description }}
-                </p>
+                <VnTitle
+                    :url="getUrl(entityId, 'basic-data')"
+                    :text="t('item.summary.description')"
+                />
+                <p v-text="item.description" />
             </QCard>
             <QCard class="vn-one">
-                <component
-                    :is="isBuyer || isAdministrative ? 'router-link' : 'span'"
-                    :to="{ name: 'ItemTax', params: { id: entityId } }"
-                    class="header"
-                    :class="{ 'header-link': isBuyer || isAdministrative }"
-                >
-                    {{ t('item.summary.tax') }}
-                    <QIcon v-if="isBuyer || isAdministrative" name="open_in_new" />
-                </component>
+                <VnTitle :url="getUrl(entityId, 'tax')" :text="t('item.summary.tax')" />
                 <VnLv
                     v-for="(tax, index) in item.taxes"
                     :key="index"
@@ -185,15 +140,10 @@ const isAdministrative = computed(() => {
                 />
             </QCard>
             <QCard class="vn-one">
-                <component
-                    :is="isBuyer ? 'router-link' : 'span'"
-                    :to="{ name: 'ItemBotanical', params: { id: entityId } }"
-                    class="header"
-                    :class="{ 'header-link': isBuyer }"
-                >
-                    {{ t('item.summary.botanical') }}
-                    <QIcon v-if="isBuyer" name="open_in_new" />
-                </component>
+                <VnTitle
+                    :url="getUrl(entityId, 'botanical')"
+                    :text="t('item.summary.botanical')"
+                />
                 <VnLv :label="t('item.summary.genus')" :value="botanical?.genus?.name" />
                 <VnLv
                     :label="t('item.summary.specie')"
@@ -201,23 +151,19 @@ const isAdministrative = computed(() => {
                 />
             </QCard>
             <QCard class="vn-one">
-                <component
-                    :is="isBuyer || isReplenisher ? 'router-link' : 'span'"
-                    :to="{ name: 'ItemBarcode', params: { id: entityId } }"
-                    class="header"
-                    :class="{ 'header-link': isBuyer || isReplenisher }"
-                >
-                    {{ t('item.summary.barcode') }}
-                    <QIcon v-if="isBuyer || isReplenisher" name="open_in_new" />
-                </component>
-                <p v-for="(barcode, index) in item.itemBarcode" :key="index">
-                    {{ barcode.code }}
-                </p>
+                <VnTitle
+                    :url="getUrl(entityId, 'barcode')"
+                    :text="t('item.summary.barcode')"
+                />
+                <p
+                    v-for="(barcode, index) in item.itemBarcode"
+                    :key="index"
+                    v-text="barcode.code"
+                />
             </QCard>
         </template>
     </CardSummary>
 </template>
-
 <i18n>
 en:
     Este artículo necesita una foto: Este artículo necesita una foto
diff --git a/src/pages/Item/Card/ItemTags.vue b/src/pages/Item/Card/ItemTags.vue
index 40c9941e9..39723ae65 100644
--- a/src/pages/Item/Card/ItemTags.vue
+++ b/src/pages/Item/Card/ItemTags.vue
@@ -24,6 +24,7 @@ const getSelectedTagValues = async (tag) => {
         const filter = {
             fields: ['value'],
             order: 'value ASC',
+            limit: 30,
         };
 
         const params = { filter: JSON.stringify(filter) };
@@ -126,7 +127,7 @@ const insertTag = (rows) => {
                                 :key="row.tagFk"
                                 :label="t('Value')"
                                 v-model="row.value"
-                                :options="valueOptionsMap.get(row.tagFk)"
+                                :url="`Tags/${row.tagFk}/filterValue`"
                                 option-label="value"
                                 option-value="value"
                                 emit-value
@@ -135,6 +136,7 @@ const insertTag = (rows) => {
                                 :is-clearable="false"
                                 :required="false"
                                 :rules="validate('itemTag.tagFk')"
+                                :use-like="false"
                             />
                             <VnInput
                                 v-else-if="
diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue
index 2ecd1f21b..d91b5189e 100644
--- a/src/pages/Item/ItemFixedPrice.vue
+++ b/src/pages/Item/ItemFixedPrice.vue
@@ -1,196 +1,190 @@
 <script setup>
-import { onMounted, ref, reactive, computed, onUnmounted, watch } from 'vue';
+import { onMounted, ref, reactive, onUnmounted, nextTick, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-
-import FetchData from 'components/FetchData.vue';
+import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import FetchedTags from 'components/ui/FetchedTags.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue';
 import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue';
+import { useQuasar } from 'quasar';
 import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
-
+import { tMobile } from 'src/composables/tMobile';
+import VnConfirm from 'components/ui/VnConfirm.vue';
+import FetchData from 'src/components/FetchData.vue';
 import { useStateStore } from 'stores/useStateStore';
-import { dashIfEmpty } from 'src/filters';
+import { toDate } from 'src/filters';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import { useState } from 'src/composables/useState';
-import { toCurrency } from 'filters/index';
 import useNotify from 'src/composables/useNotify.js';
 import axios from 'axios';
-import { useArrayData } from 'composables/useArrayData';
 import { isLower, isBigger } from 'src/filters/date.js';
 import RightMenu from 'src/components/common/RightMenu.vue';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import { QCheckbox } from 'quasar';
 
+const quasar = useQuasar();
 const stateStore = useStateStore();
 const { t } = useI18n();
 const { openConfirmationModal } = useVnConfirm();
 const state = useState();
 const { notify } = useNotify();
-
+const tableRef = ref();
 const editTableCellDialogRef = ref(null);
 const user = state.getUser();
 const fixedPrices = ref([]);
-const fixedPricesOriginalData = ref([]);
 const warehousesOptions = ref([]);
 const rowsSelected = ref([]);
 
-const exprBuilder = (param, value) => {
-    switch (param) {
-        case 'name':
-            return { 'i.name': { like: `%${value}%` } };
-        case 'itemFk':
-        case 'warehouseFk':
-        case 'rate2':
-        case 'rate3':
-            param = `fp.${param}`;
-            return { [param]: value };
-        case 'minPrice':
-            param = `i.${param}`;
-            return { [param]: value };
-    }
-};
+const itemFixedPriceFilterRef = ref();
 
 const params = reactive({});
-const arrayData = useArrayData('ItemFixedPrices', {
-    url: 'FixedPrices/filter',
-    userParams: params,
-    order: ['name ASC', 'itemFk'],
-    exprBuilder: exprBuilder,
-});
-const store = arrayData.store;
-
-const fetchFixedPrices = async () => {
-    await arrayData.fetch({ append: false });
-};
-
-const onFixedPricesFetched = (data) => {
-    fixedPrices.value = data;
-    // el objetivo de guardar una copia de las rows es evitar guardar cambios si la data no cambió al disparar los eventos
-    fixedPricesOriginalData.value = JSON.parse(JSON.stringify(data));
-};
-
-watch(
-    () => store.data,
-    (data) => onFixedPricesFetched(data)
-);
-
-const applyColumnFilter = async (col) => {
-    try {
-        const paramKey = col.columnFilter?.filterParamKey || col.field;
-        params[paramKey] = col.columnFilter.filterValue;
-        await arrayData.addFilter({ params });
-    } catch (err) {
-        console.error('Error applying column filter', err);
-    }
-};
-
-const getColumnInputEvents = (col) => {
-    return col.columnFilter.type === 'select'
-        ? { 'update:modelValue': () => applyColumnFilter(col) }
-        : {
-              'keyup.enter': () => applyColumnFilter(col),
-          };
-};
-
-const defaultColumnFilter = {
-    component: VnInput,
-    type: 'text',
-    filterValue: null,
-    event: getColumnInputEvents,
-    attrs: {
-        dense: true,
-    },
-};
-
 const defaultColumnAttrs = {
     align: 'left',
     sortable: true,
 };
-
+onMounted(async () => {
+    stateStore.rightDrawer = true;
+    params.warehouseFk = user.value.warehouseFk;
+});
+onUnmounted(() => (stateStore.rightDrawer = false));
 const columns = computed(() => [
     {
         label: t('item.fixedPrice.itemId'),
         name: 'itemId',
-        field: 'itemFk',
         ...defaultColumnAttrs,
-        columnFilter: {
-            ...defaultColumnFilter,
+        isId: true,
+        cardVisible: true,
+        columnField: {
+            component: 'input',
+            type: 'number',
         },
+        columnClass: 'shrink',
     },
     {
-        label: t('globals.description'),
+        label: t('globals.name'),
         field: 'name',
         name: 'description',
         ...defaultColumnAttrs,
-        columnFilter: {
-            ...defaultColumnFilter,
-        },
+        create: true,
+        cardVisible: true,
     },
     {
         label: t('item.fixedPrice.groupingPrice'),
         field: 'rate2',
-        name: 'groupingPrice',
+        name: 'rate2',
         ...defaultColumnAttrs,
-        columnFilter: {
-            ...defaultColumnFilter,
+        cardVisible: true,
+        columnField: {
+            class: 'expand',
+            component: 'input',
+            type: 'number',
+        },
+        columnFilter: {
+            class: 'expand',
+            component: 'input',
+            type: 'number',
         },
-        format: (val) => toCurrency(val),
     },
     {
         label: t('item.fixedPrice.packingPrice'),
         field: 'rate3',
-        name: 'packingPrice',
+        name: 'rate3',
         ...defaultColumnAttrs,
-        columnFilter: {
-            ...defaultColumnFilter,
+        cardVisible: true,
+        columnField: {
+            class: 'expand',
+            component: 'input',
+            type: 'number',
+        },
+        columnFilter: {
+            class: 'expand',
+            component: 'input',
+            type: 'number',
         },
-        format: (val) => dashIfEmpty(val),
     },
 
     {
         label: t('item.fixedPrice.minPrice'),
         field: 'minPrice',
+        columnClass: 'shrink',
         name: 'minPrice',
         ...defaultColumnAttrs,
+        cardVisible: true,
+        columnField: {
+            class: 'expand',
+            component: 'input',
+            type: 'number',
+        },
         columnFilter: {
-            ...defaultColumnFilter,
+            class: 'expand',
+            component: 'input',
+            type: 'number',
         },
     },
     {
         label: t('item.fixedPrice.started'),
         field: 'started',
         name: 'started',
+        format: ({ started }) => toDate(started),
+        cardVisible: true,
         ...defaultColumnAttrs,
-        columnFilter: null,
+        columnField: {
+            component: 'date',
+            class: 'shrink',
+        },
+        columnFilter: {
+            component: 'date',
+        },
+        columnClass: 'expand',
     },
     {
         label: t('item.fixedPrice.ended'),
         field: 'ended',
         name: 'ended',
         ...defaultColumnAttrs,
-        columnFilter: null,
+        cardVisible: true,
+        columnField: {
+            component: 'date',
+            class: 'shrink',
+        },
+        columnFilter: {
+            component: 'date',
+        },
+        columnClass: 'expand',
+        format: (row) => toDate(row.ended),
     },
 
     {
         label: t('item.fixedPrice.warehouse'),
         field: 'warehouseFk',
-        name: 'warehouse',
+        name: 'warehouseFk',
         ...defaultColumnAttrs,
+        columnClass: 'shrink',
         columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getColumnInputEvents,
-            attrs: {
-                options: warehousesOptions.value,
-                'option-value': 'id',
-                'option-label': 'name',
-                dense: true,
-            },
+            component: 'select',
+        },
+        columnField: {
+            component: 'select',
+            class: 'expand',
+        },
+        attrs: {
+            options: warehousesOptions,
         },
     },
-    { name: 'deleteAction', align: 'center' },
+    {
+        align: 'right',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('delete'),
+                icon: 'delete',
+                action: (row) => confirmRemove(row),
+                isPrimary: true,
+            },
+        ],
+    },
 ]);
 
 const editTableFieldsOptions = [
@@ -218,15 +212,6 @@ const editTableFieldsOptions = [
             type: 'number',
         },
     },
-    {
-        field: 'hasMinPrice',
-        label: t('item.fixedPrice.hasMinPrice'),
-        component: 'checkbox',
-        attrs: {
-            'false-value': 0,
-            'true-value': 1,
-        },
-    },
     {
         field: 'started',
         label: t('item.fixedPrice.started'),
@@ -248,7 +233,6 @@ const editTableFieldsOptions = [
         },
     },
 ];
-
 const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => {
     return inputType === 'text'
         ? {
@@ -258,91 +242,6 @@ const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => {
         : { 'update:modelValue': () => upsertPrice(props, resetMinPrice) };
 };
 
-const validations = (row, rowIndex, col) => {
-    const isNew = !row.id;
-    // Si la row no tiene id significa que fue agregada con addRow y no se ha guardado en la base de datos
-    // Si isNew es falso no se checkea si el valor es igual a la original
-    if (!isNew)
-        if (fixedPricesOriginalData.value[rowIndex][col.field] == row[col.field])
-            return false;
-
-    const requiredFields = ['itemFk', 'started', 'ended', 'rate2', 'rate3'];
-    return requiredFields.every(
-        (field) => row[field] !== null && row[field] !== undefined
-    );
-};
-
-const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => {
-    if (!validations(row, rowIndex, col)) return;
-
-    try {
-        if (resetMinPrice) row.hasMinPrice = 0;
-
-        const { data } = await axios.patch('FixedPrices/upsertFixedPrice', row);
-        row = data;
-        fixedPricesOriginalData.value[rowIndex][col.field] = row[col.field];
-    } catch (err) {
-        console.error('Error editing price', err);
-    }
-};
-
-const addRow = () => {
-    if (!fixedPrices.value || fixedPrices.value.length === 0) {
-        fixedPrices.value = [];
-
-        const today = Date.vnNew();
-        const millisecsInDay = 86400000;
-        const daysInWeek = 7;
-        const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay);
-
-        const newPrice = {
-            started: today,
-            ended: nextWeek,
-            hasMinPrice: 0,
-        };
-
-        fixedPricesOriginalData.value.push({ ...newPrice });
-        fixedPrices.value.push({ ...newPrice });
-        return;
-    }
-
-    const lastItemCopy = JSON.parse(
-        JSON.stringify(fixedPrices.value[fixedPrices.value.length - 1])
-    );
-    delete lastItemCopy.id;
-    fixedPricesOriginalData.value.push(lastItemCopy);
-    fixedPrices.value.push(lastItemCopy);
-};
-
-const openEditTableCellDialog = () => {
-    editTableCellDialogRef.value.show();
-};
-
-const onEditCellDataSaved = async () => {
-    rowsSelected.value = [];
-    await fetchFixedPrices();
-};
-
-const onWarehousesFetched = (data) => {
-    warehousesOptions.value = data;
-    // Actualiza las 'options' del elemento con field 'warehouseFk' en 'editTableFieldsOptions'.
-    const warehouseField = editTableFieldsOptions.find(
-        (field) => field.field === 'warehouseFk'
-    );
-    warehouseField.attrs.options = data;
-};
-
-const removePrice = async (id, rowIndex) => {
-    try {
-        await axios.delete(`FixedPrices/${id}`);
-        fixedPrices.value.splice(rowIndex, 1);
-        fixedPricesOriginalData.value.splice(rowIndex, 1);
-        notify(t('globals.dataSaved'), 'positive');
-    } catch (err) {
-        console.error('Error removing price', err);
-    }
-};
-
 const updateMinPrice = async (value, props) => {
     // El checkbox hasMinPrice se encuentra en la misma columna que el input hasMinPrice
     // Por lo tanto le mandamos otro objeto con las mismas propiedades pero con el campo 'field' cambiado
@@ -354,213 +253,361 @@ const updateMinPrice = async (value, props) => {
     });
 };
 
-onMounted(async () => {
-    stateStore.rightDrawer = true;
-    params.warehouseFk = user.value.warehouseFk;
-    await fetchFixedPrices();
-});
+const upsertPrice = async (props, resetMinPrice = false) => {
+    try {
+        const { row } = props;
+        if (tableRef.value.CrudModelRef.getChanges().updates.length > 0) {
+            if (resetMinPrice) row.hasMinPrice = 0;
+            await upsertFixedPrice(row);
+        }
+    } catch (err) {
+        console.error('Error editing price', err);
+    }
+};
 
-onUnmounted(() => (stateStore.rightDrawer = false));
+async function upsertFixedPrice(row) {
+    try {
+        const { data } = await axios.patch('FixedPrices/upsertFixedPrice', row);
+        return data;
+    } catch (err) {
+        console.error('Error editing price', err);
+    }
+}
+
+async function saveOnRowChange(row) {
+    if (rowsSelected.value.length > 1) return;
+    if (rowsSelected.value[0]?.id === row.id) return;
+    else if (rowsSelected.value.length === 1) await upsertPrice(rowsSelected.value[0]);
+    rowsSelected.value = [row];
+}
+
+function checkLastVisibleRow() {
+    let lastVisibleRow = null;
+
+    getTableRows().forEach((row, index) => {
+        const rect = row.getBoundingClientRect();
+        if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
+            lastVisibleRow = index;
+        }
+    });
+
+    return lastVisibleRow;
+}
+
+const addRow = (original = null) => {
+    let copy = null;
+    if (!original) {
+        const today = Date.vnNew();
+        const millisecsInDay = 86400000;
+        const daysInWeek = 7;
+        const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay);
+
+        copy = {
+            id: 0,
+            started: today,
+            ended: nextWeek,
+            hasMinPrice: 0,
+            $index: 0,
+        };
+    } else
+        copy = {
+            $index: original.$index - 1,
+            itemFk: original.itemFk,
+            name: original.name,
+            subName: original.subName,
+            value5: original.value5,
+            value6: original.value6,
+            value7: original.value7,
+            value8: original.value8,
+            value9: original.value9,
+            value10: original.value10,
+            warehouseFk: original.warehouseFk,
+            rate2: original.rate2,
+            rate3: original.rate3,
+            hasMinPrice: original.hasMinPrice,
+            minPrice: original.minPrice,
+            started: Date.vnNew(),
+            ended: Date.vnNew(),
+        };
+    return { original, copy };
+};
+
+const getTableRows = () =>
+    document.getElementsByClassName('q-table')[0].querySelectorAll('tr.cursor-pointer');
+
+function highlightNewRow({ $index: index }) {
+    const row = getTableRows()[index];
+    if (row) {
+        row.classList.add('highlight');
+        setTimeout(() => {
+            row.classList.remove('highlight');
+        }, 3000); // Duración de la animación en milisegundos
+    }
+}
+const openEditTableCellDialog = () => {
+    editTableCellDialogRef.value.show();
+};
+
+const onEditCellDataSaved = async () => {
+    rowsSelected.value = [];
+    tableRef.value.reload();
+};
+
+const removeFuturePrice = async () => {
+    try {
+        rowsSelected.value.forEach(({ id }) => {
+            const rowIndex = fixedPrices.value.findIndex(({ id }) => id === id);
+            removePrice(id, rowIndex);
+        });
+    } catch (err) {
+        console.error('Error removing price', err);
+    }
+};
+
+function confirmRemove(item, isFuture) {
+    const promise = async () =>
+        isFuture ? removeFuturePrice(item.id) : removePrice(item.id);
+    quasar.dialog({
+        component: VnConfirm,
+        componentProps: {
+            title: t('globals.rowWillBeRemoved'),
+            message: t('globals.confirmDeletion'),
+            promise,
+        },
+    });
+}
+
+const removePrice = async (id) => {
+    try {
+        await axios.delete(`FixedPrices/${id}`);
+        notify(t('globals.dataSaved'), 'positive');
+        tableRef.value.reload({});
+    } catch (err) {
+        console.error('Error removing price', err);
+    }
+};
+const dateStyle = (date) =>
+    date
+        ? {
+              'bg-color': 'warning',
+              'is-outlined': true,
+          }
+        : {};
+
+function handleOnDataSave({ CrudModelRef }) {
+    const { original, copy } = addRow(CrudModelRef.formData[checkLastVisibleRow()]);
+    if (original) {
+        CrudModelRef.formData.splice(original?.$index ?? 0, 0, copy);
+    } else {
+        CrudModelRef.insert(copy);
+    }
+    nextTick(() => {
+        highlightNewRow(original ?? { $index: 0 });
+    });
+}
 </script>
 
 <template>
     <FetchData
-        url="Warehouses"
-        :filter="{ order: ['name'] }"
+        @on-fetch="(data) => (warehousesOptions = data)"
         auto-load
-        @on-fetch="(data) => onWarehousesFetched(data)"
+        url="Warehouses"
+        :filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
     />
     <RightMenu>
         <template #right-panel>
             <ItemFixedPriceFilter
                 data-key="ItemFixedPrices"
-                :warehouses-options="warehousesOptions"
+                ref="itemFixedPriceFilterRef"
             />
         </template>
     </RightMenu>
-    <QPage class="column items-center q-pa-md">
-        <QTable
-            :rows="fixedPrices"
+    <VnSubToolbar>
+        <template #st-data>
+            <QBtn
+                v-if="rowsSelected.length"
+                @click="openEditTableCellDialog()"
+                color="primary"
+                icon="edit"
+            >
+                <QTooltip>
+                    {{ t('Edit fixed price(s)') }}
+                </QTooltip>
+            </QBtn>
+            <QBtn
+                :label="tMobile('globals.remove')"
+                color="primary"
+                icon="delete"
+                flat
+                @click="(row) => confirmRemove(row, true)"
+                :title="t('globals.remove')"
+                v-if="rowsSelected.length"
+            />
+        </template>
+    </VnSubToolbar>
+    <QPage>
+        <VnTable
+            @on-fetch="
+                (data) =>
+                    data.forEach((item) => {
+                        item.hasMinPrice = `${item.hasMinPrice !== 0}`;
+                    })
+            "
+            :default-remove="false"
+            :default-reset="false"
+            :default-save="false"
+            data-key="ItemFixedPrices"
+            url="FixedPrices/filter"
+            :order="['itemFk ASC']"
+            save-url="FixedPrices/crud"
+            :user-params="{ warehouseFk: user.warehouseFk }"
+            ref="tableRef"
+            dense
             :columns="columns"
-            row-key="id"
-            selection="multiple"
+            default-mode="table"
+            auto-load
+            :is-editable="true"
+            :right-search="false"
+            :table="{
+                'row-key': 'id',
+                selection: 'multiple',
+            }"
+            :crud-model="{
+                paginate: false,
+            }"
             v-model:selected="rowsSelected"
-            :pagination="{ rowsPerPage: 0 }"
-            class="full-width q-mt-md"
-            :no-data-label="t('globals.noResults')"
+            :row-click="saveOnRowChange"
+            :create-as-dialog="false"
+            :create="{
+                onDataSaved: handleOnDataSave,
+            }"
+            :use-model="true"
+            :disable-option="{ card: true }"
         >
-            <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 #header-selection="scope">
+                <QCheckbox v-model="scope.selected" />
+            </template>
+            <template #body-selection="scope">
+                {{ scope }}
+                <QCheckbox flat v-model="scope.selected" />
             </template>
 
-            <template #body-cell-itemId="props">
-                <QTd>
-                    <VnSelect
-                        url="Items/withName"
-                        hide-selected
-                        option-label="id"
-                        option-value="id"
-                        v-model="props.row.itemFk"
-                        v-on="getRowUpdateInputEvents(props, true, 'select')"
-                    >
-                        <template #option="scope">
-                            <QItem v-bind="scope.itemProps">
-                                <QItemSection>
-                                    <QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
-                                    <QItemLabel caption>{{ scope.opt?.name }}</QItemLabel>
-                                </QItemSection>
-                            </QItem>
-                        </template>
-                    </VnSelect>
-                </QTd>
+            <template #column-itemId="props">
+                <VnSelect
+                    style="max-width: 100px"
+                    url="Items/withName"
+                    hide-selected
+                    option-label="id"
+                    option-value="id"
+                    v-model="props.row.itemFk"
+                    v-on="getRowUpdateInputEvents(props, true, 'select')"
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
+                                <QItemLabel caption>{{ scope.opt?.name }}</QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
             </template>
-            <template #body-cell-description="{ row }">
-                <QTd class="col">
-                    <span class="link">
-                        {{ row.name }}
-                    </span>
-                    <ItemDescriptorProxy :id="row.itemFk" />
-                    <FetchedTags :item="row" :max-length="6" />
-                </QTd>
+            <template #column-description="{ row }">
+                <span class="link">
+                    {{ row.name }}
+                </span>
+                <span class="subName">{{ row.subName }}</span>
+                <ItemDescriptorProxy :id="row.itemFk" />
+                <FetchedTags style="width: max-content; max-width: 220px" :item="row" />
             </template>
-            <template #body-cell-groupingPrice="props">
-                <QTd class="col">
-                    <VnInput
-                        v-model.number="props.row.rate2"
-                        v-on="getRowUpdateInputEvents(props)"
-                    >
-                        <template #append>€</template>
-                    </VnInput>
-                </QTd>
+            <template #column-rate2="props">
+                <VnInput
+                    mask="###.##"
+                    v-model.number="props.row.rate2"
+                    v-on="getRowUpdateInputEvents(props)"
+                >
+                    <template #append>€</template>
+                </VnInput>
             </template>
-            <template #body-cell-packingPrice="props">
-                <QTd class="col">
-                    <VnInput
-                        v-model.number="props.row.rate3"
-                        v-on="getRowUpdateInputEvents(props)"
-                    >
-                        <template #append>€</template>
-                    </VnInput>
-                </QTd>
+            <template #column-rate3="props">
+                <VnInput
+                    mask="###.##"
+                    v-model.number="props.row.rate3"
+                    v-on="getRowUpdateInputEvents(props)"
+                >
+                    <template #append>€</template>
+                </VnInput>
             </template>
-            <template #body-cell-minPrice="props">
+            <template #column-minPrice="props">
                 <QTd class="col">
-                    <div class="row">
+                    <div class="row" style="width: 115px">
                         <QCheckbox
-                            class="col"
                             :model-value="props.row.hasMinPrice"
                             @update:model-value="updateMinPrice($event, props)"
-                            :false-value="0"
-                            :true-value="1"
-                            :toggle-indeterminate="false"
+                            :false-value="'false'"
+                            :true-value="'true'"
                         />
                         <VnInput
                             class="col"
-                            :disable="!props.row.hasMinPrice"
+                            :disable="props.row.hasMinPrice === 1"
                             v-model.number="props.row.minPrice"
                             v-on="getRowUpdateInputEvents(props)"
-                            type="number"
-                        />
+                        >
+                            <template #append>€</template>
+                        </VnInput>
                     </div>
                 </QTd>
             </template>
-            <template #body-cell-started="props">
-                <QTd class="col" style="min-width: 160px">
-                    <VnInputDate
-                        v-model="props.row.started"
-                        v-on="getRowUpdateInputEvents(props, false, 'date')"
-                        v-bind="
-                            isBigger(props.row.started)
-                                ? { 'bg-color': 'warning', 'is-outlined': true }
-                                : {}
-                        "
-                    />
-                </QTd>
+            <template #column-started="props">
+                <VnInputDate
+                    class="vnInputDate"
+                    :show-event="true"
+                    v-model="props.row.started"
+                    v-on="getRowUpdateInputEvents(props, false, 'date')"
+                    v-bind="dateStyle(isBigger(props.row.started))"
+                />
             </template>
-            <template #body-cell-ended="props">
-                <QTd class="col" style="min-width: 150px">
-                    <VnInputDate
-                        v-model="props.row.ended"
-                        v-on="getRowUpdateInputEvents(props, false, 'date')"
-                        v-bind="
-                            isLower(props.row.ended)
-                                ? { 'bg-color': 'warning', 'is-outlined': true }
-                                : {}
-                        "
-                    />
-                </QTd>
+            <template #column-ended="props">
+                <VnInputDate
+                    class="vnInputDate"
+                    :show-event="true"
+                    v-model="props.row.ended"
+                    v-on="getRowUpdateInputEvents(props, false, 'date')"
+                    v-bind="dateStyle(isLower(props.row.ended))"
+                />
             </template>
-            <template #body-cell-warehouse="props">
-                <QTd class="col">
-                    <VnSelect
-                        :options="warehousesOptions"
-                        hide-selected
-                        option-label="name"
-                        option-value="id"
-                        v-model="props.row.warehouseFk"
-                        v-on="getRowUpdateInputEvents(props, false, 'select')"
-                    />
-                </QTd>
+            <template #column-warehouseFk="props">
+                <VnSelect
+                    style="max-width: 150px"
+                    :options="warehousesOptions"
+                    hide-selected
+                    option-label="name"
+                    option-value="id"
+                    v-model="props.row.warehouseFk"
+                    v-on="getRowUpdateInputEvents(props, false, 'select')"
+                />
             </template>
-            <template #body-cell-deleteAction="{ row, rowIndex }">
-                <QTd class="col">
-                    <QIcon
-                        name="delete"
-                        size="sm"
-                        class="cursor-pointer fill-icon-on-hover"
-                        color="primary"
-                        @click.stop="
-                            openConfirmationModal(
-                                t('This row will be removed'),
-                                t('Do you want to clone this item?'),
-                                () => removePrice(row.id, rowIndex)
-                            )
-                        "
-                    >
-                        <QTooltip class="text-no-wrap">
-                            {{ t('Delete') }}
-                        </QTooltip>
-                    </QIcon>
-                </QTd>
+            <template #column-deleteAction="{ row, rowIndex }">
+                <QIcon
+                    name="delete"
+                    size="sm"
+                    class="cursor-pointer fill-icon-on-hover"
+                    color="primary"
+                    @click.stop="
+                        openConfirmationModal(
+                            t('globals.rowWillBeRemoved'),
+                            t('Do you want to clone this item?'),
+                            () => removePrice(row.id, rowIndex)
+                        )
+                    "
+                >
+                    <QTooltip class="text-no-wrap">
+                        {{ t('globals.delete') }}
+                    </QTooltip>
+                </QIcon>
             </template>
-            <template #bottom-row>
-                <QTd align="center">
-                    <QIcon
-                        @click.stop="addRow()"
-                        class="fill-icon-on-hover"
-                        color="primary"
-                        name="add_circle"
-                        size="sm"
-                    >
-                        <QTooltip>
-                            {{ t('Add fixed price') }}
-                        </QTooltip>
-                    </QIcon>
-                </QTd>
-            </template>
-        </QTable>
-        <QPageSticky v-if="rowsSelected.length" :offset="[20, 20]">
-            <QBtn @click="openEditTableCellDialog()" color="primary" fab icon="edit" />
-            <QTooltip>
-                {{ t('Edit fixed price(s)') }}
-            </QTooltip>
-        </QPageSticky>
+        </VnTable>
+
         <QDialog ref="editTableCellDialogRef">
             <EditTableCellValueForm
                 edit-url="FixedPrices/editFixedPrice"
@@ -571,12 +618,56 @@ onUnmounted(() => (stateStore.rightDrawer = false));
         </QDialog>
     </QPage>
 </template>
+<style lang="scss">
+.q-table th,
+.q-table td {
+    padding-inline: 5px !important;
+    // text-align: -webkit-right;
+}
+.q-table tbody td {
+    max-width: none;
 
+    .q-td.col {
+        & .vnInputDate {
+            min-width: 90px;
+        }
+        & div.row {
+            & .q-checkbox {
+                & .q-checkbox__inner {
+                    position: relative !important;
+                    &.q-checkbox__inner--truthy {
+                        color: var(--q-primary);
+                    }
+                }
+            }
+        }
+    }
+}
+.q-field__after,
+.q-field__append {
+    padding: 0;
+}
+
+tbody tr.highlight .q-td {
+    animation: highlight-animation 4s ease-in-out;
+}
+@keyframes highlight-animation {
+    0% {
+        background-color: $primary-light;
+    }
+    100% {
+        background-color: transparent;
+    }
+}
+.subName {
+    margin-left: 5%;
+    font-size: 0.75rem;
+    text-transform: uppercase;
+    color: var(--vn-label-color);
+}
+</style>
 <i18n>
 es:
     Add fixed price: Añadir precio fijado
     Edit fixed price(s): Editar precio(s) fijado(s)
-    This row will be removed: Esta linea se eliminará
-    Are you sure you want to continue?: ¿Seguro que quieres continuar?
-    Delete: Eliminar
 </i18n>
diff --git a/src/pages/Item/ItemFixedPriceFilter.vue b/src/pages/Item/ItemFixedPriceFilter.vue
index 6c847ece8..84eefaed3 100644
--- a/src/pages/Item/ItemFixedPriceFilter.vue
+++ b/src/pages/Item/ItemFixedPriceFilter.vue
@@ -9,18 +9,29 @@ import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue';
 
 const { t } = useI18n();
 
-defineProps({
+const props = defineProps({
     dataKey: {
         type: String,
         required: true,
     },
-    warehousesOptions: {
-        type: Array,
-        default: () => [],
-    },
 });
 
 const itemTypeWorkersOptions = ref([]);
+const exprBuilder = (param, value) => {
+    switch (param) {
+        case 'name':
+            return { 'i.name': { like: `%${value}%` } };
+        case 'itemFk':
+        case 'warehouseFk':
+        case 'rate2':
+        case 'rate3':
+            param = `fp.${param}`;
+            return { [param]: value };
+        case 'minPrice':
+            param = `i.${param}`;
+            return { [param]: value };
+    }
+};
 </script>
 
 <template>
@@ -31,7 +42,7 @@ const itemTypeWorkersOptions = ref([]);
         :filter="{ fields: ['id', 'nickname'], order: 'nickname ASC', limit: 30 }"
         @on-fetch="(data) => (itemTypeWorkersOptions = data)"
     />
-    <ItemsFilterPanel :data-key="dataKey" :custom-tags="['tags']">
+    <ItemsFilterPanel :data-key="props.dataKey" :custom-tags="['tags']">
         <template #body="{ params, searchFn }">
             <QItem class="q-my-md">
                 <QItemSection>
@@ -52,9 +63,11 @@ const itemTypeWorkersOptions = ref([]);
             <QItem class="q-my-md">
                 <QItemSection>
                     <VnSelect
+                        url="Warehouses"
+                        auto-load
+                        :filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }"
                         :label="t('components.itemsFilterPanel.warehouseFk')"
                         v-model="params.warehouseFk"
-                        :options="warehousesOptions"
                         option-label="name"
                         option-value="id"
                         dense
@@ -93,8 +106,15 @@ const itemTypeWorkersOptions = ref([]);
                         toggle-indeterminate
                         @update:model-value="searchFn()"
                     />
-                </QItemSection>
-                <QItemSection>
+
+                    <QCheckbox
+                        v-model="params.showBadDates"
+                        :label="t(`components.itemsFilterPanel.showBadDates`)"
+                        toggle-indeterminate
+                        @update:model-value="searchFn()"
+                    >
+                    </QCheckbox>
+
                     <QCheckbox
                         :label="t('components.itemsFilterPanel.hasMinPrice')"
                         v-model="params.hasMinPrice"
diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue
index f1e3629cd..e3fcceb3a 100644
--- a/src/pages/Item/ItemList.vue
+++ b/src/pages/Item/ItemList.vue
@@ -517,7 +517,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                     <template #body-cell-description="{ row }">
                         <QTd class="col">
                             <span>{{ row.name }} {{ row.subName }}</span>
-                            <FetchedTags :item="row" :max-length="6" />
+                            <FetchedTags :item="row" />
                         </QTd>
                     </template>
                     <template #body-cell-isActive="{ row }">
@@ -562,7 +562,13 @@ onUnmounted(() => (stateStore.rightDrawer = false));
         </VnPaginate>
 
         <QPageSticky :offset="[20, 20]">
-            <QBtn @click="redirectToItemCreate()" color="primary" fab icon="add" />
+            <QBtn
+                @click="redirectToItemCreate()"
+                color="primary"
+                fab
+                icon="add"
+                shortcut="+"
+            />
             <QTooltip class="text-no-wrap">
                 {{ t('New item') }}
             </QTooltip>
diff --git a/src/pages/Item/ItemListFilter.vue b/src/pages/Item/ItemListFilter.vue
index 62c0c56dc..22dce9c64 100644
--- a/src/pages/Item/ItemListFilter.vue
+++ b/src/pages/Item/ItemListFilter.vue
@@ -30,7 +30,7 @@ const itemTypesRef = ref(null);
 const categoriesOptions = ref([]);
 const itemTypesOptions = ref([]);
 const buyersOptions = ref([]);
-const suppliersOptions = ref([]);
+const tagOptions = ref([]);
 const tagValues = ref([]);
 const fieldFiltersValues = ref([]);
 const moreFields = ref([]);
@@ -161,12 +161,6 @@ onMounted(async () => {
         @on-fetch="(data) => (buyersOptions = data)"
         auto-load
     />
-    <FetchData
-        url="Suppliers"
-        :filter="{ fields: ['id', 'name', 'nickname'], order: 'name ASC' }"
-        @on-fetch="(data) => (suppliersOptions = data)"
-        auto-load
-    />
     <FetchData
         url="Tags"
         :filter="{ fields: ['id', 'name', 'isFree'] }"
@@ -261,9 +255,11 @@ onMounted(async () => {
                         :label="t('params.supplierFk')"
                         v-model="params.supplierFk"
                         @update:model-value="searchFn()"
-                        :options="suppliersOptions"
+                        url="Suppliers"
                         option-value="id"
                         option-label="name"
+                        :fields="['id', 'name', 'nickname']"
+                        sort-by="name ASC"
                         hide-selected
                         dense
                         outlined
diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue
index ae6638953..8a41bbe04 100644
--- a/src/pages/Item/ItemRequest.vue
+++ b/src/pages/Item/ItemRequest.vue
@@ -1,7 +1,6 @@
 <script setup>
 import { ref, computed, onMounted, onBeforeMount, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
-import FetchData from 'components/FetchData.vue';
 import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
@@ -22,7 +21,6 @@ import RightMenu from 'src/components/common/RightMenu.vue';
 const { t } = useI18n();
 const { notify } = useNotify();
 const stateStore = useStateStore();
-const workersOptions = ref([]);
 let filterParams = ref({});
 const denyFormRef = ref(null);
 const denyRequestId = ref(null);
@@ -208,13 +206,6 @@ onBeforeMount(() => {
 </script>
 
 <template>
-    <FetchData
-        url="Workers"
-        :filter="{ where: { role: 'buyer' } }"
-        order="id"
-        @on-fetch="(data) => (workersOptions = data)"
-        auto-load
-    />
     <VnSearchbar
         data-key="ItemRequests"
         url="TicketRequests/filter"
@@ -268,7 +259,9 @@ onBeforeMount(() => {
                 <QTd>
                     <VnSelect
                         v-model="row.attenderFk"
-                        :options="workersOptions"
+                        :where="{ role: 'buyer' }"
+                        sort-by="id"
+                        url="Workers"
                         hide-selected
                         option-label="firstName"
                         option-value="id"
diff --git a/src/pages/Item/ItemRequestFilter.vue b/src/pages/Item/ItemRequestFilter.vue
index c9340dc1f..aa07b8d50 100644
--- a/src/pages/Item/ItemRequestFilter.vue
+++ b/src/pages/Item/ItemRequestFilter.vue
@@ -24,7 +24,6 @@ const stateOptions = [
 
 const itemTypesOptions = ref([]);
 const warehousesOptions = ref([]);
-const workersOptions = ref([]);
 
 const exprBuilder = (param, value) => {
     switch (param) {
@@ -72,18 +71,6 @@ const decrement = (paramsObj, key) => {
         @on-fetch="(data) => (warehousesOptions = data)"
         auto-load
     />
-    <FetchData
-        url="Workers/search"
-        :filter="{
-            fields: ['id', 'name'],
-            order: 'name ASC',
-        }"
-        :params="{
-            departmentCodes: ['VT'],
-        }"
-        @on-fetch="(data) => (workersOptions = data)"
-        auto-load
-    />
     <VnFilterPanel
         :data-key="props.dataKey"
         :search-button="true"
@@ -162,7 +149,10 @@ const decrement = (paramsObj, key) => {
                         :label="t('params.requesterFk')"
                         v-model="params.requesterFk"
                         @update:model-value="searchFn()"
-                        :options="workersOptions"
+                        url="Workers/search"
+                        :fields="['id', 'name']"
+                        order="name ASC"
+                        :params="{ departmentCodes: ['VT'] }"
                         option-value="id"
                         option-label="name"
                         hide-selected
diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue
index 125672d60..d874a5dcb 100644
--- a/src/pages/Item/ItemTypeList.vue
+++ b/src/pages/Item/ItemTypeList.vue
@@ -99,7 +99,13 @@ const exprBuilder = (param, value) => {
         </div>
     </QPage>
     <QPageSticky :offset="[20, 20]">
-        <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" />
+        <QBtn
+            fab
+            icon="add"
+            color="primary"
+            @click="redirectToCreateView()"
+            shortcut="+"
+        />
         <QTooltip>
             {{ t('New item type') }}
         </QTooltip>
diff --git a/src/pages/Login/LoginMain.vue b/src/pages/Login/LoginMain.vue
index c17201969..44b868ebd 100644
--- a/src/pages/Login/LoginMain.vue
+++ b/src/pages/Login/LoginMain.vue
@@ -1,6 +1,6 @@
 <script setup>
 import { ref } from 'vue';
-import { Notify, useQuasar } from 'quasar';
+import { Notify } from 'quasar';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
 
@@ -11,7 +11,6 @@ import VnLogo from 'components/ui/VnLogo.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import axios from 'axios';
 
-const quasar = useQuasar();
 const session = useSession();
 const loginCache = useLogin();
 const router = useRouter();
diff --git a/src/pages/Login/ResetPassword.vue b/src/pages/Login/ResetPassword.vue
index eff718e97..2751f1ceb 100644
--- a/src/pages/Login/ResetPassword.vue
+++ b/src/pages/Login/ResetPassword.vue
@@ -33,7 +33,6 @@ async function onSubmit() {
     };
 
     try {
-        console.log('newPassword: ', newPassword);
         await axios.post(
             'VnUsers/reset-password',
             { newPassword: newPassword.value },
diff --git a/src/pages/Monitor/MonitorClients.vue b/src/pages/Monitor/MonitorClients.vue
new file mode 100644
index 000000000..ff51e4464
--- /dev/null
+++ b/src/pages/Monitor/MonitorClients.vue
@@ -0,0 +1,145 @@
+<script setup>
+import { ref, computed } from 'vue';
+import { useI18n } from 'vue-i18n';
+import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
+import { toDateFormat } from 'src/filters/date.js';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import VnInputDate from 'src/components/common/VnInputDate.vue';
+import VnRow from 'src/components/ui/VnRow.vue';
+import { dateRange } from 'src/filters';
+const { t } = useI18n();
+
+const dates = dateRange(Date.vnNew());
+const from = ref(dates[0]);
+const to = ref(dates[1]);
+
+const filter = computed(() => {
+    const obj = {};
+    const formatFrom = setHours(from.value, 'from');
+    const formatTo = setHours(to.value, 'to');
+    let stamp;
+
+    if (!formatFrom && formatTo) stamp = { lte: formatTo };
+    else if (formatFrom && !formatTo) stamp = { gte: formatFrom };
+    else if (formatFrom && formatTo) stamp = { between: [formatFrom, formatTo] };
+
+    return Object.assign(obj, { where: { 'v.stamp': stamp } });
+});
+
+function exprBuilder(param, value) {
+    switch (param) {
+        case 'clientFk':
+            return { [`c.id`]: value };
+        case 'salesPersonFk':
+            return { [`c.${param}`]: value };
+    }
+}
+
+function setHours(date, type) {
+    if (!date) return null;
+
+    const d = new Date(date);
+    if (type == 'from') d.setHours(0, 0, 0, 0);
+    else d.setHours(23, 59, 59, 59);
+    return d;
+}
+
+const columns = computed(() => [
+    {
+        label: t('salesClientsTable.date'),
+        name: 'dated',
+        field: 'dated',
+        align: 'left',
+        columnFilter: false,
+        format: (row) => toDateFormat(row.dated, 'es-ES', { year: '2-digit' }),
+    },
+    {
+        label: t('salesClientsTable.hour'),
+        name: 'hour',
+        field: 'hour',
+        align: 'left',
+        columnFilter: false,
+    },
+    {
+        label: t('salesClientsTable.salesPerson'),
+        name: 'salesPersonFk',
+        field: 'salesPerson',
+        align: 'left',
+        columnField: {
+            component: null,
+        },
+        optionFilter: 'firstName',
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'Workers/activeWithInheritedRole',
+                fields: ['id', 'name'],
+                sortBy: 'nickname ASC',
+                where: { role: 'salesPerson' },
+                useLike: false,
+            },
+        },
+        columnClass: 'no-padding',
+    },
+    {
+        label: t('salesClientsTable.client'),
+        field: 'clientName',
+        name: 'clientFk',
+        align: 'left',
+        columnField: {
+            component: null,
+        },
+        orderBy: 'c.name',
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'Clients',
+                fields: ['id', 'name'],
+                sortBy: 'name ASC',
+            },
+        },
+        columnClass: 'no-padding',
+    },
+]);
+</script>
+
+<template>
+    <VnTable
+        ref="table"
+        data-key="SalesMonitorClients"
+        url="SalesMonitors/clientsFilter"
+        search-url="SalesMonitorClients"
+        :order="['dated DESC', 'hour DESC']"
+        :expr-builder="exprBuilder"
+        :filter="filter"
+        :offset="50"
+        auto-load
+        :columns="columns"
+        :right-search="false"
+        default-mode="table"
+        :disable-option="{ card: true }"
+        dense
+        class="q-px-none"
+    >
+        <template #top-left>
+            <VnRow>
+                <VnInputDate v-model="from" :label="$t('globals.from')" dense />
+                <VnInputDate v-model="to" :label="$t('globals.to')" dense />
+            </VnRow>
+        </template>
+        <template #column-salesPersonFk="{ row }">
+            <span class="link" :title="row.salesPerson" v-text="row.salesPerson" />
+            <WorkerDescriptorProxy :id="row.salesPersonFk" dense />
+        </template>
+        <template #column-clientFk="{ row }">
+            <span class="link" :title="row.clientName" v-text="row.clientName" />
+            <CustomerDescriptorProxy :id="row.clientFk" />
+        </template>
+    </VnTable>
+</template>
+<style lang="scss" scoped>
+.full-width .vn-row > * {
+    flex: 0.4;
+}
+</style>
diff --git a/src/pages/Monitor/MonitorClientsActions.vue b/src/pages/Monitor/MonitorClientsActions.vue
new file mode 100644
index 000000000..821773bbf
--- /dev/null
+++ b/src/pages/Monitor/MonitorClientsActions.vue
@@ -0,0 +1,26 @@
+<script setup>
+import SalesClientTable from './MonitorClients.vue';
+import SalesOrdersTable from './MonitorOrders.vue';
+import VnRow from 'src/components/ui/VnRow.vue';
+</script>
+<template>
+    <VnRow
+        class="q-pa-md"
+        :style="{ 'flex-direction': $q.screen.lt.lg ? 'column' : 'row', gap: '0px' }"
+    >
+        <div style="flex: 0.3">
+            <span
+                class="q-ml-md text-body1"
+                v-text="$t('salesMonitor.clientsOnWebsite')"
+            />
+            <SalesClientTable />
+        </div>
+        <div style="flex: 0.7">
+            <span
+                class="q-ml-md text-body1"
+                v-text="$t('salesMonitor.recentOrderActions')"
+            />
+            <SalesOrdersTable />
+        </div>
+    </VnRow>
+</template>
diff --git a/src/pages/Monitor/MonitorList.vue b/src/pages/Monitor/MonitorList.vue
deleted file mode 100644
index 4906247e8..000000000
--- a/src/pages/Monitor/MonitorList.vue
+++ /dev/null
@@ -1,90 +0,0 @@
-<script setup>
-import { onMounted, onUnmounted, ref } from 'vue';
-import { useI18n } from 'vue-i18n';
-
-import { useStateStore } from 'stores/useStateStore';
-import SalesClientTable from './SalesClientsTable.vue';
-import SalesOrdersTable from './SalesOrdersTable.vue';
-import SalesTicketsTable from './SalesTicketsTable.vue';
-import VnSearchbar from 'components/ui/VnSearchbar.vue';
-
-const { t } = useI18n();
-const stateStore = useStateStore();
-
-const expanded = ref(true);
-
-onMounted(async () => {
-    stateStore.leftDrawer = false;
-});
-
-onUnmounted(() => (stateStore.leftDrawer = true));
-</script>
-
-<template>
-    <template v-if="stateStore.isHeaderMounted()">
-        <Teleport to="#searchbar">
-            <VnSearchbar
-                data-key="SalesMonitorTickets"
-                url="SalesMonitors/salesFilter"
-                :redirect="false"
-                :label="t('searchBar.label')"
-                :info="t('searchBar.info')"
-            />
-        </Teleport>
-    </template>
-    <QPage class="column items-center q-pa-md">
-        <QCard class="full-width q-mb-lg">
-            <QExpansionItem v-model="expanded" dense :duration="150">
-                <template v-if="!expanded" #header>
-                    <div class="row full-width">
-                        <span class="flex col text-body1">
-                            {{ t('salesMonitor.clientsOnWebsite') }}
-                        </span>
-                        <span class="flex col q-ml-xl text-body1">
-                            {{ t('salesMonitor.recentOrderActions') }}
-                        </span>
-                    </div>
-                </template>
-                <template #default>
-                    <div class="expansion-tables-container">
-                        <QCardSection class="col">
-                            <span class="flex col q-mb-sm text-body1">
-                                {{ t('salesMonitor.clientsOnWebsite') }}
-                            </span>
-                            <SalesClientTable />
-                        </QCardSection>
-                        <QCardSection class="col">
-                            <span class="flex col q-mb-sm text-body1">
-                                {{ t('salesMonitor.recentOrderActions') }}
-                            </span>
-                            <SalesOrdersTable />
-                        </QCardSection>
-                    </div>
-                </template>
-            </QExpansionItem>
-        </QCard>
-        <QCard class="full-width">
-            <QItem class="justify-between">
-                <QItemLabel class="col slider-container">
-                    <span class="text-body1"
-                        >{{ t('salesMonitor.ticketsMonitor') }}
-                    </span>
-                    <QCardSection class="col" style="padding-inline: 0"
-                        ><SalesTicketsTable />
-                    </QCardSection>
-                </QItemLabel>
-            </QItem>
-        </QCard>
-    </QPage>
-</template>
-
-<style lang="scss" scoped>
-.expansion-tables-container {
-    display: flex;
-    border-top: 1px solid $color-spacer;
-
-    @media (max-width: $breakpoint-md-max) {
-        flex-direction: column;
-    }
-}
-</style>
diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue
new file mode 100644
index 000000000..eb455a239
--- /dev/null
+++ b/src/pages/Monitor/MonitorOrders.vue
@@ -0,0 +1,203 @@
+<script setup>
+import { ref, computed } from 'vue';
+import { useI18n } from 'vue-i18n';
+import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
+import VnTable from 'components/VnTable/VnTable.vue';
+
+import { toDateFormat, toDateTimeFormat } from 'src/filters/date.js';
+import { toCurrency } from 'src/filters';
+import { useVnConfirm } from 'composables/useVnConfirm';
+import axios from 'axios';
+
+const { t } = useI18n();
+const { openConfirmationModal } = useVnConfirm();
+
+const table = ref();
+const selectedRows = ref([]);
+
+function exprBuilder(param, value) {
+    switch (param) {
+        case 'clientFk':
+            return { [`c.id`]: value };
+        case 'salesPersonFk':
+            return { [`c.salesPersonFk`]: value };
+    }
+}
+
+const columns = computed(() => [
+    {
+        label: t('salesOrdersTable.dateSend'),
+        name: 'dateSend',
+        field: 'dateSend',
+        align: 'left',
+        orderBy: 'date_send',
+        columnFilter: false,
+    },
+    {
+        label: t('salesOrdersTable.dateMake'),
+        name: 'dateMake',
+        field: 'dateMake',
+        align: 'left',
+        orderBy: 'date_make',
+        columnFilter: false,
+        format: (row) => toDateTimeFormat(row.date_make),
+    },
+    {
+        label: t('salesOrdersTable.client'),
+        name: 'clientFk',
+        align: 'left',
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'Clients',
+                fields: ['id', 'name'],
+                sortBy: 'name ASC',
+            },
+        },
+    },
+    {
+        label: t('salesOrdersTable.agency'),
+        name: 'agencyName',
+        align: 'left',
+        columnFilter: false,
+    },
+    {
+        label: t('salesOrdersTable.salesPerson'),
+        name: 'salesPersonFk',
+        align: 'left',
+        optionFilter: 'firstName',
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'Workers/activeWithInheritedRole',
+                fields: ['id', 'name'],
+                sortBy: 'nickname ASC',
+                where: { role: 'salesPerson' },
+                useLike: false,
+            },
+        },
+    },
+    {
+        label: t('salesOrdersTable.import'),
+        name: 'import',
+        field: 'import',
+        align: 'left',
+        columnFilter: false,
+        format: (row) => toCurrency(row.import),
+    },
+]);
+
+const getBadgeColor = (date) => {
+    const today = Date.vnNew();
+    today.setHours(0, 0, 0, 0);
+
+    const orderLanded = new Date(date);
+    orderLanded.setHours(0, 0, 0, 0);
+
+    const difference = today - orderLanded;
+
+    if (difference == 0) return 'warning';
+    if (difference < 0) return 'success';
+    if (difference > 0) return 'alert';
+};
+
+const removeOrders = async () => {
+    try {
+        const selectedIds = selectedRows.value.map((row) => row.id);
+        const params = { deletes: selectedIds };
+        await axios.post('SalesMonitors/deleteOrders', params);
+        selectedRows.value = [];
+        await table.value.reload();
+    } catch (err) {
+        console.error('Error deleting orders', err);
+    }
+};
+
+const openTab = (id) =>
+    window.open(`#/order/${id}/summary`, '_blank', 'noopener, noreferrer');
+</script>
+<template>
+    <VnTable
+        ref="table"
+        class="q-px-none"
+        data-key="SalesMonitorOrders"
+        url="SalesMonitors/ordersFilter"
+        search-url="SalesMonitorOrders"
+        order="date_send DESC"
+        :right-search="false"
+        :expr-builder="exprBuilder"
+        auto-load
+        :columns="columns"
+        :table="{
+            'row-key': 'id',
+            selection: 'multiple',
+            'hide-bottom': true,
+        }"
+        default-mode="table"
+        :row-click="({ id }) => openTab(id)"
+        v-model:selected="selectedRows"
+        :disable-option="{ card: true }"
+    >
+        <template #top-left>
+            <QBtn
+                icon="refresh"
+                size="md"
+                color="primary"
+                dense
+                flat
+                @click="$refs.table.reload()"
+            >
+                <QTooltip>{{ $t('globals.refresh') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                v-if="selectedRows.length"
+                icon="delete"
+                size="md"
+                dense
+                flat
+                color="primary"
+                @click="
+                    openConfirmationModal(
+                        $t('salesOrdersTable.deleteConfirmTitle'),
+                        $t('salesOrdersTable.deleteConfirmMessage'),
+                        removeOrders
+                    )
+                "
+            >
+                <QTooltip>{{ t('salesOrdersTable.delete') }}</QTooltip>
+            </QBtn>
+        </template>
+        <template #column-dateSend="{ row }">
+            <QTd>
+                <QBadge
+                    :color="getBadgeColor(row.date_send)"
+                    text-color="black"
+                    class="q-pa-sm"
+                    style="font-size: 14px"
+                >
+                    {{ toDateFormat(row.date_send) }}
+                </QBadge>
+            </QTd>
+        </template>
+
+        <template #column-clientFk="{ row }">
+            <QTd @click.stop>
+                <span class="link" v-text="row.clientName" :title="row.clientName" />
+                <CustomerDescriptorProxy :id="row.clientFk" />
+            </QTd>
+        </template>
+
+        <template #column-salesPersonFk="{ row }">
+            <QTd @click.stop>
+                <span class="link" v-text="row.salesPerson" />
+                <WorkerDescriptorProxy :id="row.salesPersonFk" dense />
+            </QTd>
+        </template>
+    </VnTable>
+</template>
+<style lang="scss" scoped>
+.q-td {
+    max-width: 140px;
+}
+</style>
diff --git a/src/pages/Monitor/SalesClientsTable.vue b/src/pages/Monitor/SalesClientsTable.vue
deleted file mode 100644
index 2fb9e8e2f..000000000
--- a/src/pages/Monitor/SalesClientsTable.vue
+++ /dev/null
@@ -1,147 +0,0 @@
-<script setup>
-import { ref, computed, reactive, watch } from 'vue';
-import { useI18n } from 'vue-i18n';
-
-import FetchData from 'components/FetchData.vue';
-import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
-import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
-
-import { toDateFormat } from 'src/filters/date.js';
-import VnTable from 'src/components/VnTable/VnTable.vue';
-
-const { t } = useI18n();
-
-const paginateRef = ref(null);
-const workersActiveOptions = ref([]);
-const clientsOptions = ref([]);
-
-const from = ref(Date.vnNew());
-const to = ref(Date.vnNew());
-
-const dateRange = computed(() => {
-    const minHour = new Date(from.value);
-    minHour.setHours(0, 0, 0, 0);
-    const maxHour = new Date(to.value);
-    maxHour.setHours(23, 59, 59, 59);
-    return [minHour, maxHour];
-});
-
-const filter = reactive({
-    where: {
-        'v.stamp': {
-            between: dateRange.value,
-        },
-    },
-});
-
-const refetch = async () => await paginateRef.value.fetch();
-
-watch(dateRange, (val) => {
-    filter.where['v.stamp'].between = val;
-    refetch();
-});
-
-function exprBuilder(param, value) {
-    switch (param) {
-        case 'clientFk':
-            return { [`c.id`]: value };
-        case 'salesPersonFk':
-            return { [`c.${param}`]: value };
-    }
-}
-
-const params = reactive({});
-
-const columns = computed(() => [
-    {
-        label: t('salesClientsTable.date'),
-        name: 'dated',
-        field: 'dated',
-        align: 'left',
-        columnFilter: null,
-        sortable: true,
-        format: (row) => toDateFormat(row.dated),
-    },
-    {
-        label: t('salesClientsTable.hour'),
-        name: 'hour',
-        field: 'hour',
-        align: 'left',
-        sortable: true,
-    },
-    {
-        label: t('salesClientsTable.salesPerson'),
-        name: 'salesPerson',
-        field: 'salesPerson',
-        align: 'left',
-        sortable: true,
-        columnField: {
-            component: null,
-        },
-    },
-    {
-        label: t('salesClientsTable.client'),
-        field: 'clientName',
-        name: 'client',
-        align: 'left',
-        sortable: true,
-        columnField: {
-            component: null,
-        },
-    },
-]);
-</script>
-
-<template>
-    <FetchData
-        url="Workers/activeWithInheritedRole"
-        :filter="{
-            fields: ['id', 'nickname'],
-            order: 'nickname ASC',
-            where: { role: 'salesPerson' },
-        }"
-        auto-load
-        @on-fetch="(data) => (workersActiveOptions = data)"
-    />
-    <FetchData
-        url="Clients"
-        :filter="{
-            fields: ['id', 'name'],
-            order: 'name ASC',
-        }"
-        auto-load
-        @on-fetch="(data) => (clientsOptions = data)"
-    />
-    <QCard style="max-height: 380px; overflow-y: scroll">
-        <VnTable
-            ref="paginateRef"
-            data-key="SalesMonitorClients"
-            url="SalesMonitors/clientsFilter"
-            :order="['dated DESC', 'hour DESC']"
-            :limit="6"
-            :expr-builder="exprBuilder"
-            :user-params="params"
-            :filter="filter"
-            :offset="50"
-            auto-load
-            :columns="columns"
-            :right-search="false"
-            default-mode="table"
-            dense
-            :without-header="true"
-        >
-            <template #column-salesPerson="{ row }">
-                <QTd>
-                    <span class="link">{{ row.salesPerson }}</span>
-                    <WorkerDescriptorProxy :id="row.salesPersonFk" dense />
-                </QTd>
-            </template>
-            <template #column-client="{ row }">
-                <QTd>
-                    <span class="link">{{ row.clientName }}</span>
-                    <CustomerDescriptorProxy :id="row.clientFk" />
-                </QTd>
-            </template>
-        </VnTable>
-    </QCard>
-</template>
diff --git a/src/pages/Monitor/SalesOrdersTable.vue b/src/pages/Monitor/SalesOrdersTable.vue
deleted file mode 100644
index f0c389aa6..000000000
--- a/src/pages/Monitor/SalesOrdersTable.vue
+++ /dev/null
@@ -1,204 +0,0 @@
-<script setup>
-import { ref, computed } from 'vue';
-import { useI18n } from 'vue-i18n';
-
-import FetchData from 'components/FetchData.vue';
-import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
-import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
-import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
-import VnTable from 'components/VnTable/VnTable.vue';
-
-import { toDateFormat, toDateTimeFormat } from 'src/filters/date.js';
-import { toCurrency } from 'src/filters';
-import { useVnConfirm } from 'composables/useVnConfirm';
-import axios from 'axios';
-
-const { t } = useI18n();
-const { openConfirmationModal } = useVnConfirm();
-
-const paginateRef = ref(null);
-const workersActiveOptions = ref([]);
-const clientsOptions = ref([]);
-const selectedRows = ref([]);
-
-const dateRange = (value) => {
-    const minHour = new Date(value);
-    minHour.setHours(0, 0, 0, 0);
-    const maxHour = new Date(value);
-    maxHour.setHours(23, 59, 59, 59);
-
-    return [minHour, maxHour];
-};
-
-function exprBuilder(param, value) {
-    switch (param) {
-        case 'date_send':
-            return {
-                [`o.date_send`]: {
-                    between: dateRange(value),
-                },
-            };
-        case 'clientFk':
-            return { [`c.id`]: value };
-        case 'salesPersonFk':
-            return { [`c.${param}`]: value };
-    }
-}
-
-const columns = computed(() => [
-    {
-        label: t('salesOrdersTable.date'),
-        name: 'date',
-        field: 'dated',
-        align: 'left',
-        sortable: true,
-        cardVisible: true,
-    },
-    {
-        label: t('salesOrdersTable.client'),
-        name: 'client',
-        align: 'left',
-        sortable: true,
-        cardVisible: true,
-    },
-    {
-        label: t('salesOrdersTable.salesPerson'),
-        name: 'salesPerson',
-        align: 'left',
-        sortable: true,
-        cardVisible: true,
-    },
-]);
-
-const getBadgeColor = (date) => {
-    const today = Date.vnNew();
-    today.setHours(0, 0, 0, 0);
-
-    const orderLanded = new Date(date);
-    orderLanded.setHours(0, 0, 0, 0);
-
-    const difference = today - orderLanded;
-
-    if (difference == 0) return 'warning';
-    if (difference < 0) return 'success';
-    if (difference > 0) return 'alert';
-};
-
-const removeOrders = async () => {
-    try {
-        const selectedIds = selectedRows.value.map((row) => row.id);
-        const params = { deletes: selectedIds };
-        await axios.post('SalesMonitors/deleteOrders', params);
-        selectedRows.value = [];
-        await paginateRef.value.fetch();
-    } catch (err) {
-        console.error('Error deleting orders', err);
-    }
-};
-
-const redirectToOrderSummary = (orderId) => {
-    const url = `#/order/${orderId}/summary`;
-    window.open(url, '_blank');
-};
-</script>
-
-<template>
-    <FetchData
-        url="Workers/activeWithInheritedRole"
-        :filter="{
-            fields: ['id', 'nickname'],
-            order: 'nickname ASC',
-            where: { role: 'salesPerson' },
-        }"
-        auto-load
-        @on-fetch="(data) => (workersActiveOptions = data)"
-    />
-    <FetchData
-        url="Clients"
-        :filter="{
-            fields: ['id', 'name'],
-            order: 'name ASC',
-        }"
-        auto-load
-        @on-fetch="(data) => (clientsOptions = data)"
-    />
-
-    <VnSubToolbar />
-    <QCard style="max-height: 380px; overflow-y: scroll">
-        <VnTable
-            ref="paginateRef"
-            data-key="SalesMonitorOrders"
-            url="SalesMonitors/ordersFilter"
-            order="date_make DESC"
-            :limit="6"
-            :right-search="false"
-            :expr-builder="exprBuilder"
-            auto-load
-            :columns="columns"
-            :table="{
-                'row-key': 'id',
-                selection: 'multiple',
-                'hide-bottom': true,
-            }"
-            default-mode="table"
-            :without-header="false"
-            @row-click="(_, row) => redirectToOrderSummary(row.id)"
-            v-model:selected="selectedRows"
-        >
-            <template #top-left>
-                <QBtn
-                    v-if="selectedRows.length > 0"
-                    icon="delete"
-                    size="md"
-                    color="primary"
-                    @click="
-                        openConfirmationModal(
-                            t('salesOrdersTable.deleteConfirmTitle'),
-                            t('salesOrdersTable.deleteConfirmMessage'),
-                            removeOrders
-                        )
-                    "
-                >
-                    <QTooltip>{{ t('salesOrdersTable.delete') }}</QTooltip>
-                </QBtn>
-            </template>
-            <template #column-date="{ row }">
-                <QTd>
-                    <QBadge
-                        :color="getBadgeColor(row.date_send)"
-                        text-color="black"
-                        class="q-pa-sm q-mb-md"
-                        style="font-size: 14px"
-                    >
-                        {{ toDateFormat(row.date_send) }}
-                    </QBadge>
-                    <div>{{ toDateTimeFormat(row.date_make) }}</div>
-                </QTd>
-            </template>
-            <template #column-client="{ row }">
-                <QTd>
-                    <div class="q-mb-md">
-                        <span class="link">{{ row.clientName }}</span>
-                        <CustomerDescriptorProxy :id="row.clientFk" />
-                    </div>
-                    <span> {{ row.agencyName }}</span>
-                </QTd>
-            </template>
-
-            <template #column-salesPerson="{ row }">
-                <QTd>
-                    <div class="q-mb-md">
-                        <span class="link">{{ row.salesPerson }}</span>
-                        <WorkerDescriptorProxy :id="row.salesPersonFk" dense />
-                    </div>
-                    <span>{{ toCurrency(row.import) }}</span>
-                </QTd>
-            </template>
-        </VnTable>
-    </QCard>
-</template>
-<style lang="scss" scoped>
-.q-td {
-    color: gray;
-}
-</style>
diff --git a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
new file mode 100644
index 000000000..167a10465
--- /dev/null
+++ b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
@@ -0,0 +1,286 @@
+<script setup>
+import { ref } from 'vue';
+import { useI18n } from 'vue-i18n';
+
+import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
+import VnFilterPanelChip from 'src/components/ui/VnFilterPanelChip.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
+import FetchData from 'src/components/FetchData.vue';
+import { dateRange } from 'src/filters';
+
+defineProps({ dataKey: { type: String, required: true } });
+const { t } = useI18n();
+const warehouses = ref();
+const groupedStates = ref();
+
+const handleScopeDays = (params, days, callback) => {
+    const [from, to] = dateRange(Date.vnNew());
+    if (!days) {
+        Object.assign(params, { from, to, scopeDays: 1 });
+    } else {
+        params.from = from;
+        to.setDate(to.getDate() + days);
+        params.to = to;
+    }
+    if (callback) callback();
+};
+</script>
+<template>
+    <FetchData url="Warehouses" auto-load @on-fetch="(data) => (warehouses = data)" />
+    <FetchData
+        url="AlertLevels"
+        auto-load
+        @on-fetch="
+            (data) =>
+                (groupedStates = data.map((x) => Object.assign(x, { code: t(x.code) })))
+        "
+    />
+    <VnFilterPanel
+        :data-key="dataKey"
+        :search-button="true"
+        :hidden-tags="['from', 'to']"
+        :custom-tags="['scopeDays']"
+        :unremovable-params="['from', 'to', 'scopeDays']"
+    >
+        <template #tags="{ tag, formatFn }">
+            <div class="q-gutter-x-xs">
+                <strong v-text="`${t(`params.${tag.label}`)}:`" />
+                <span v-text="formatFn(tag.value)" />
+            </div>
+        </template>
+        <template #customTags="{ params, searchFn, formatFn }">
+            <VnFilterPanelChip
+                v-if="params.scopeDays"
+                removable
+                @remove="handleScopeDays(params, null, searchFn)"
+            >
+                <strong v-text="`${t(`params.scopeDays`)}:`" />
+                <span v-text="formatFn(params.scopeDays)" />
+            </VnFilterPanelChip>
+        </template>
+        <template #body="{ params }">
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        :label="t('params.clientFk')"
+                        v-model="params.clientFk"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        :label="t('params.orderFk')"
+                        v-model="params.orderFk"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInputNumber
+                        :label="t('params.scopeDays')"
+                        v-model="params.scopeDays"
+                        is-outlined
+                        @update:model-value="(val) => handleScopeDays(params, val)"
+                        @remove="(val) => handleScopeDays(params, val)"
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        :label="t('params.nickname')"
+                        v-model="params.nickname"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        outlined
+                        dense
+                        rounded
+                        :label="t('params.salesPersonFk')"
+                        v-model="params.salesPersonFk"
+                        url="Workers/search"
+                        :params="{ departmentCodes: ['VT'] }"
+                        is-outlined
+                        option-value="code"
+                        option-label="name"
+                        :no-one="true"
+                    >
+                        <template #option="{ opt, itemProps }">
+                            <QItem v-bind="itemProps">
+                                <QItemSection>
+                                    <QItemLabel>{{ opt.name }}</QItemLabel>
+                                    <QItemLabel
+                                        v-if="opt.code"
+                                        class="text-grey text-caption"
+                                    >
+                                        {{ `${opt.nickname}, ${opt.code}` }}
+                                    </QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        :label="t('params.refFk')"
+                        v-model="params.refFk"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        outlined
+                        dense
+                        rounded
+                        :label="t('params.agencyModeFk')"
+                        v-model="params.agencyModeFk"
+                        url="AgencyModes/isActive"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        outlined
+                        dense
+                        rounded
+                        :label="t('params.stateFk')"
+                        v-model="params.stateFk"
+                        url="States"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        outlined
+                        dense
+                        rounded
+                        :label="t('params.groupedStates')"
+                        v-model="params.alertLevel"
+                        :options="groupedStates"
+                        option-label="code"
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        outlined
+                        dense
+                        rounded
+                        :label="t('params.warehouseFk')"
+                        v-model="params.warehouseFk"
+                        :options="warehouses"
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        outlined
+                        dense
+                        rounded
+                        :label="t('params.provinceFk')"
+                        v-model="params.provinceFk"
+                        url="Provinces"
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('params.myTeam')"
+                        v-model="params.myTeam"
+                        toggle-indeterminate
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('params.problems')"
+                        v-model="params.problems"
+                        toggle-indeterminate
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('params.pending')"
+                        v-model="params.pending"
+                        toggle-indeterminate
+                    />
+                </QItemSection>
+            </QItem>
+        </template>
+    </VnFilterPanel>
+</template>
+<i18n>
+en:
+    params:
+        clientFk: Client id
+        orderFk: Order id
+        scopeDays: Days onward
+        nickname: Nickname
+        salesPersonFk: Sales person
+        refFk: Invoice
+        agencyModeFk: Agency
+        stateFk: State
+        groupedStates: Grouped State
+        warehouseFk: Warehouse
+        provinceFk: Province
+        myTeam: My team
+        problems: With problems
+        pending: Pending
+        from: From
+        to: To
+        alertLevel: Grouped State
+    FREE: Free
+    DELIVERED: Delivered
+    ON_PREPARATION: On preparation
+    ON_PREVIOUS: On previous
+    PACKED: Packed
+    No one: No one
+    
+es:
+    params:
+        clientFk: Id cliente
+        orderFk: Id cesta
+        scopeDays: Días en adelante
+        nickname: Nombre mostrado
+        salesPersonFk: Comercial
+        refFk: Factura
+        agencyModeFk: Agencia
+        stateFk: Estado
+        groupedStates: Estado agrupado
+        warehouseFk: Almacén
+        provinceFk: Provincia
+        myTeam: Mi equipo
+        problems: Con problemas
+        pending: Pendiente
+        from: Desde
+        To: Hasta
+        alertLevel: Estado agrupado
+    FREE: Libre
+    DELIVERED: Servido
+    ON_PREPARATION: En preparación
+    ON_PREVIOUS: En previa
+    PACKED: Encajado
+</i18n>
diff --git a/src/pages/Monitor/Ticket/MonitorTicketSearchbar.vue b/src/pages/Monitor/Ticket/MonitorTicketSearchbar.vue
new file mode 100644
index 000000000..4950ab381
--- /dev/null
+++ b/src/pages/Monitor/Ticket/MonitorTicketSearchbar.vue
@@ -0,0 +1,12 @@
+<script setup>
+import VnSearchbar from 'components/ui/VnSearchbar.vue';
+</script>
+<template>
+    <VnSearchbar
+        data-key="SalesMonitorTickets"
+        url="SalesMonitors/salesFilter"
+        :redirect="false"
+        :label="$t('searchBar.label')"
+        :info="$t('searchBar.info')"
+    />
+</template>
diff --git a/src/pages/Monitor/SalesTicketsTable.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue
similarity index 62%
rename from src/pages/Monitor/SalesTicketsTable.vue
rename to src/pages/Monitor/Ticket/MonitorTickets.vue
index 1ca68240b..258b5022f 100644
--- a/src/pages/Monitor/SalesTicketsTable.vue
+++ b/src/pages/Monitor/Ticket/MonitorTickets.vue
@@ -1,43 +1,38 @@
 <script setup>
-import { ref, computed, onMounted, reactive } from 'vue';
+import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useRouter } from 'vue-router';
-
 import FetchData from 'components/FetchData.vue';
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
-import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
 import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
 import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
 import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
 import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnTable from 'components/VnTable/VnTable.vue';
-
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import { toDateFormat, toTimeFormat } from 'src/filters/date.js';
-import { toCurrency, dateRange } from 'src/filters';
-const DEFAULT_AUTO_REFRESH = 1000;
+import { toDateFormat } from 'src/filters/date.js';
+import { toCurrency, dateRange, dashIfEmpty } from 'src/filters';
+import RightMenu from 'src/components/common/RightMenu.vue';
+import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue';
+import MonitorTicketFilter from './MonitorTicketFilter.vue';
+
+const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; // 2min in ms
 const { t } = useI18n();
 const autoRefresh = ref(false);
-const router = useRouter();
-const paginateRef = ref(null);
-const workersActiveOptions = ref([]);
-const provincesOptions = ref([]);
-const statesOptions = ref([]);
-const zonesOptions = ref([]);
+const tableRef = ref(null);
+const provinceOpts = ref([]);
+const stateOpts = ref([]);
+const zoneOpts = ref([]);
 const visibleColumns = ref([]);
-const allColumnNames = ref([]);
 const { viewSummary } = useSummaryDialog();
+const [from, to] = dateRange(Date.vnNew());
 
 function exprBuilder(param, value) {
     switch (param) {
         case 'stateFk':
             return { 'ts.stateFk': value };
         case 'salesPersonFk':
-            return { 'c.salesPersonFk': value };
+            return { 'c.salesPersonFk': !value ? null : value };
         case 'provinceFk':
             return { 'a.provinceFk': value };
         case 'theoreticalHour':
@@ -54,55 +49,12 @@ function exprBuilder(param, value) {
     }
 }
 
-const filter = { order: ['totalProblems DESC'] };
-let params = reactive({});
-
-const applyColumnFilter = async (col) => {
-    try {
-        const paramKey = col.columnFilter?.filterParamKey || col.field;
-        params[paramKey] = col.columnFilter.filterValue;
-        await paginateRef.value.addFilter(null, params);
-    } catch (err) {
-        console.error('Error applying column filter', err);
-    }
-};
-
-const getInputEvents = (col) => {
-    return col.columnFilter.type === 'select' || col.columnFilter.type === 'date'
-        ? { 'update:modelValue': () => applyColumnFilter(col) }
-        : {
-              'keyup.enter': () => applyColumnFilter(col),
-          };
-};
-
-const fetchParams = ($params = {}) => {
-    const excludedParams = ['search', 'clientFk', 'orderFk', 'refFk', 'scopeDays'];
-
-    const hasExcludedParams = excludedParams.some((param) => {
-        return $params && $params[param] != undefined;
-    });
-    const hasParams = Object.entries($params).length;
-    if (!hasParams || !hasExcludedParams) $params.scopeDays = 1;
-
-    if (typeof $params.scopeDays === 'number') {
-        const from = Date.vnNew();
-        from.setHours(0, 0, 0, 0);
-
-        const to = new Date(from.getTime());
-        to.setDate(to.getDate() + $params.scopeDays);
-        to.setHours(23, 59, 59, 999);
-
-        Object.assign($params, { from, to });
-    }
-    return { tableOrder: 'totalProblems DESC', ...$params };
-};
-
 const columns = computed(() => [
     {
         label: t('salesTicketsTable.problems'),
-        name: 'problems',
+        name: 'totalProblems',
         align: 'left',
-        sortable: true,
+
         columnFilter: false,
         attrs: {
             dense: true,
@@ -110,13 +62,12 @@ const columns = computed(() => [
     },
     {
         label: t('salesTicketsTable.identifier'),
-        name: 'identifier',
+        name: 'id',
         field: 'id',
         align: 'left',
-        sortable: true,
 
         columnFilter: {
-            component: 'input',
+            component: 'number',
             name: 'id',
             attrs: {
                 dense: true,
@@ -125,41 +76,41 @@ const columns = computed(() => [
     },
     {
         label: t('salesTicketsTable.client'),
-        name: 'client',
+        name: 'clientFk',
         align: 'left',
         field: 'nickname',
-        sortable: true,
         columnFilter: {
-            component: 'input',
-            name: 'nickname',
+            component: 'select',
             attrs: {
-                dense: true,
+                url: 'Clients',
+                fields: ['id', 'name', 'nickname'],
+                sortBy: 'name ASC',
             },
         },
     },
     {
         label: t('salesTicketsTable.salesPerson'),
-        name: 'salesPerson',
+        name: 'salesPersonFk',
         field: 'userName',
         align: 'left',
-        sortable: true,
+        optionFilter: 'firstName',
         columnFilter: {
             component: 'select',
-            name: 'salesPersonFk',
             attrs: {
-                options: workersActiveOptions.value,
-                'option-value': 'id',
-                'option-label': 'name',
-                dense: true,
+                url: 'Workers/activeWithInheritedRole',
+                fields: ['id', 'name'],
+                sortBy: 'nickname ASC',
+                where: { role: 'salesPerson' },
+                useLike: false,
             },
         },
     },
     {
         label: t('salesTicketsTable.date'),
-        name: 'date',
+        name: 'shippedDate',
         style: { 'max-width': '100px' },
         align: 'left',
-        sortable: true,
+
         columnFilter: {
             component: 'date',
             name: 'shippedDate',
@@ -170,61 +121,39 @@ const columns = computed(() => [
     },
     {
         label: t('salesTicketsTable.theoretical'),
-        name: 'theoretical',
+        name: 'theoreticalhour',
         field: 'zoneLanding',
         align: 'left',
-        sortable: true,
-        format: (val) => toTimeFormat(val),
-        columnFilter: {
-            component: 'input',
-            name: 'theoreticalHour',
-            attrs: {
-                dense: true,
-            },
-        },
+        format: (row) => row.theoreticalhour,
+        columnFilter: false,
     },
     {
         label: t('salesTicketsTable.practical'),
-        name: 'practical',
+        name: 'practicalHour',
         field: 'practicalHour',
         align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: 'input',
-            name: 'practicalHour',
-            attrs: {
-                dense: true,
-            },
-        },
+        format: (row) => row.practicalHour,
+        columnFilter: false,
     },
     {
         label: t('salesTicketsTable.preparation'),
-        name: 'preparation',
+        name: 'preparationHour',
         field: 'shipped',
         align: 'left',
-        sortable: true,
-        format: (val) => toTimeFormat(val),
-        columnFilter: {
-            component: 'input',
-            name: 'shippedDate',
-            attrs: {
-                dense: true,
-            },
-        },
+        format: (row) => row.preparationHour,
+        columnFilter: false,
     },
-
     {
         label: t('salesTicketsTable.province'),
-        name: 'province',
+        name: 'provinceFk',
         field: 'province',
         align: 'left',
-        style: { 'max-width': '100px' },
-        sortable: true,
+        format: (row) => row.province,
         columnFilter: {
             component: 'select',
             name: 'provinceFk',
             attrs: {
-                options: provincesOptions.value,
+                options: provinceOpts.value,
                 'option-value': 'id',
                 'option-label': 'name',
                 dense: true,
@@ -236,12 +165,11 @@ const columns = computed(() => [
         name: 'state',
         align: 'left',
         style: { 'max-width': '100px' },
-        sortable: true,
         columnFilter: {
             component: 'select',
             name: 'stateFk',
             attrs: {
-                options: statesOptions.value,
+                options: stateOpts.value,
                 'option-value': 'id',
                 'option-label': 'name',
                 dense: true,
@@ -253,10 +181,7 @@ const columns = computed(() => [
         name: 'isFragile',
         field: 'isFragile',
         align: 'left',
-        sortable: true,
-        columnFilter: {
-            inWhere: true,
-        },
+        columnFilter: false,
         attrs: {
             'checked-icon': 'local_bar',
             'unchecked-icon': 'local_bar',
@@ -266,14 +191,14 @@ const columns = computed(() => [
     },
     {
         label: t('salesTicketsTable.zone'),
-        name: 'zone',
+        name: 'zoneFk',
         align: 'left',
-        sortable: true,
+
         columnFilter: {
             component: 'select',
             name: 'zoneFk',
             attrs: {
-                options: zonesOptions.value,
+                options: zoneOpts.value,
                 'option-value': 'id',
                 'option-label': 'name',
                 dense: true,
@@ -282,13 +207,13 @@ const columns = computed(() => [
     },
     {
         label: t('salesTicketsTable.total'),
-        name: 'total',
+        name: 'totalWithVat',
         field: 'totalWithVat',
         align: 'left',
         style: { 'max-width': '75px' },
-        sortable: true,
+
         columnFilter: {
-            component: 'input',
+            component: 'number',
             name: 'totalWithVat',
             attrs: {
                 dense: true,
@@ -304,7 +229,7 @@ const columns = computed(() => [
                 title: t('salesTicketsTable.goToLines'),
                 icon: 'vn:lines',
                 color: 'priamry',
-                action: (row) => redirectToSales(row.id),
+                action: (row) => openTab(row.id),
                 isPrimary: true,
                 attrs: {
                     flat: true,
@@ -343,18 +268,13 @@ let refreshTimer = null;
 
 const autoRefreshHandler = (value) => {
     if (value)
-        refreshTimer = setInterval(() => paginateRef.value.fetch(), DEFAULT_AUTO_REFRESH);
+        refreshTimer = setInterval(() => tableRef.value.reload(), DEFAULT_AUTO_REFRESH);
     else {
         clearInterval(refreshTimer);
         refreshTimer = null;
     }
 };
 
-const redirectToTicketSummary = (id) => {
-    const url = `#/ticket/${id}/summary`;
-    window.open(url, '_blank');
-};
-
 const stateColors = {
     notice: 'info',
     success: 'positive',
@@ -375,30 +295,10 @@ const formatShippedDate = (date) => {
     return toDateFormat(_date);
 };
 
-const redirectToSales = (id) => {
-    const url = `#/ticket/${id}/sale`;
-    window.open(url, '_blank');
-};
-
-// onMounted(async () => {
-//     const filteredColumns = columns.value.filter((col) => col.name !== 'rowActions');
-//     allColumnNames.value = filteredColumns.map((col) => col.name);
-//     params = fetchParams();
-//     await paginateRef.value.addFilter(null, params);
-// });
+const openTab = (id) =>
+    window.open(`#/ticket/${id}/sale`, '_blank', 'noopener, noreferrer');
 </script>
-
 <template>
-    <FetchData
-        url="Workers/activeWithInheritedRole"
-        :filter="{
-            fields: ['id', 'nickname'],
-            order: 'nickname ASC',
-            where: { role: 'salesPerson' },
-        }"
-        auto-load
-        @on-fetch="(data) => (workersActiveOptions = data)"
-    />
     <FetchData
         url="Provinces"
         :filter="{
@@ -406,7 +306,7 @@ const redirectToSales = (id) => {
             order: 'name ASC',
         }"
         auto-load
-        @on-fetch="(data) => (provincesOptions = data)"
+        @on-fetch="(data) => (provinceOpts = data)"
     />
     <FetchData
         url="States"
@@ -415,7 +315,7 @@ const redirectToSales = (id) => {
             order: 'name ASC',
         }"
         auto-load
-        @on-fetch="(data) => (statesOptions = data)"
+        @on-fetch="(data) => (stateOpts = data)"
     />
     <FetchData
         url="Zones"
@@ -424,46 +324,60 @@ const redirectToSales = (id) => {
             order: 'name ASC',
         }"
         auto-load
-        @on-fetch="(data) => (zonesOptions = data)"
+        @on-fetch="(data) => (zoneOpts = data)"
     />
+    <MonitorTicketSearchbar />
+    <RightMenu>
+        <template #right-panel>
+            <MonitorTicketFilter data-key="saleMonitorTickets" />
+        </template>
+    </RightMenu>
     <VnTable
-        ref="paginateRef"
-        data-key="SalesMonitorTickets"
+        ref="tableRef"
+        data-key="saleMonitorTickets"
         url="SalesMonitors/salesFilter"
-        :filter="filter"
-        :limit="20"
+        search-url="saleMonitorTickets"
         :expr-builder="exprBuilder"
-        :user-params="params"
         :offset="50"
         :columns="columns"
         :visible-columns="visibleColumns"
         :right-search="false"
         default-mode="table"
         auto-load
-        @row-click="(_, row) => redirectToTicketSummary(row.id)"
+        :row-click="({ id }) => openTab(id)"
+        :disable-option="{ card: true }"
+        :user-params="{ from, to, scopeDays: 1 }"
     >
         <template #top-left>
-            <TableVisibleColumns
-                :all-columns="allColumnNames"
-                table-code="ticketsMonitor"
-                labels-traductions-path="salesTicketsTable"
-                @on-config-saved="visibleColumns = [...$event, 'rowActions']"
-            />
+            <QBtn
+                icon="refresh"
+                size="md"
+                color="primary"
+                class="q-mr-sm"
+                dense
+                flat
+                @click="$refs.tableRef.reload()"
+            >
+                <QTooltip>{{ $t('globals.refresh') }}</QTooltip>
+            </QBtn>
             <QCheckbox
                 v-model="autoRefresh"
-                :label="t('salesTicketsTable.autoRefresh')"
+                :label="$t('salesTicketsTable.autoRefresh')"
                 @update:model-value="autoRefreshHandler"
-            />
+                dense
+            >
+                <QTooltip>{{ $t('refreshInfo') }}</QTooltip>
+            </QCheckbox>
         </template>
-        <template #column-problems="{ row }">
-            <QTd class="no-padding" style="max-width: 50px">
+        <template #column-totalProblems="{ row }">
+            <QTd class="no-padding" style="max-width: 60px">
                 <QIcon
                     v-if="row.isTaxDataChecked === 0"
                     name="vn:no036"
                     color="primary"
                     size="xs"
                 >
-                    <QTooltip>{{ t('salesTicketsTable.noVerifiedData') }}</QTooltip>
+                    <QTooltip>{{ $t('salesTicketsTable.noVerifiedData') }}</QTooltip>
                 </QIcon>
                 <QIcon
                     v-if="row.hasTicketRequest"
@@ -471,7 +385,7 @@ const redirectToSales = (id) => {
                     color="primary"
                     size="xs"
                 >
-                    <QTooltip>{{ t('salesTicketsTable.purchaseRequest') }}</QTooltip>
+                    <QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
                 </QIcon>
                 <QIcon
                     v-if="row.itemShortage"
@@ -479,10 +393,10 @@ const redirectToSales = (id) => {
                     color="primary"
                     size="xs"
                 >
-                    <QTooltip>{{ t('salesTicketsTable.notVisible') }}</QTooltip>
+                    <QTooltip>{{ $t('salesTicketsTable.notVisible') }}</QTooltip>
                 </QIcon>
                 <QIcon v-if="row.isFreezed" name="vn:frozen" color="primary" size="xs">
-                    <QTooltip>{{ t('salesTicketsTable.clientFrozen') }}</QTooltip>
+                    <QTooltip>{{ $t('salesTicketsTable.clientFrozen') }}</QTooltip>
                 </QIcon>
                 <QIcon
                     v-if="row.risk"
@@ -490,7 +404,9 @@ const redirectToSales = (id) => {
                     :color="row.hasHighRisk ? 'negative' : 'primary'"
                     size="xs"
                 >
-                    <QTooltip>{{ t('salesTicketsTable.risk') }}: {{ row.risk }}</QTooltip>
+                    <QTooltip
+                        >{{ $t('salesTicketsTable.risk') }}: {{ row.risk }}</QTooltip
+                    >
                 </QIcon>
                 <QIcon
                     v-if="row.hasComponentLack"
@@ -498,7 +414,7 @@ const redirectToSales = (id) => {
                     color="primary"
                     size="xs"
                 >
-                    <QTooltip>{{ t('salesTicketsTable.componentLack') }}</QTooltip>
+                    <QTooltip>{{ $t('salesTicketsTable.componentLack') }}</QTooltip>
                 </QIcon>
                 <QIcon
                     v-if="row.isTooLittle"
@@ -506,11 +422,11 @@ const redirectToSales = (id) => {
                     color="primary"
                     size="xs"
                 >
-                    <QTooltip>{{ t('salesTicketsTable.tooLittle') }}</QTooltip>
+                    <QTooltip>{{ $t('salesTicketsTable.tooLittle') }}</QTooltip>
                 </QIcon>
             </QTd>
         </template>
-        <template #column-identifier="{ row }">
+        <template #column-id="{ row }">
             <QTd class="no-padding">
                 <span class="link" @click.stop.prevent>
                     {{ row.id }}
@@ -518,19 +434,19 @@ const redirectToSales = (id) => {
                 </span>
             </QTd>
         </template>
-        <template #column-client="{ row }">
-            <QTd class="no-padding" @click.stop.prevent>
+        <template #column-clientFk="{ row }">
+            <QTd class="no-padding" @click.stop :title="row.nickname">
                 <span class="link">{{ row.nickname }}</span>
                 <CustomerDescriptorProxy :id="row.clientFk" />
             </QTd>
         </template>
-        <template #column-salesPerson="{ row }">
-            <QTd class="no-padding" @click.stop.prevent>
-                <span class="link">{{ row.userName }}</span>
+        <template #column-salesPersonFk="{ row }">
+            <QTd class="no-padding" @click.stop :title="row.userName">
+                <span class="link" v-text="dashIfEmpty(row.userName)" />
                 <WorkerDescriptorProxy :id="row.salesPersonFk" />
             </QTd>
         </template>
-        <template #column-date="{ row }">
+        <template #column-shippedDate="{ row }">
             <QTd class="no-padding">
                 <QBadge
                     v-bind="getBadgeAttrs(row.shippedDate)"
@@ -541,6 +457,11 @@ const redirectToSales = (id) => {
                 </QBadge>
             </QTd>
         </template>
+        <template #column-provinceFk="{ row }">
+            <QTd class="no-padding">
+                <span :title="row.province" v-text="row.province" />
+            </QTd>
+        </template>
         <template #column-state="{ row }">
             <QTd class="no-padding" @click.stop.prevent>
                 <div v-if="row.refFk">
@@ -561,17 +482,17 @@ const redirectToSales = (id) => {
         <template #column-isFragile="{ row }">
             <QTd class="no-padding">
                 <QIcon v-if="row.isFragile" name="local_bar" color="primary" size="sm">
-                    <QTooltip>{{ t('salesTicketsTable.isFragile') }}</QTooltip>
+                    <QTooltip>{{ $t('salesTicketsTable.isFragile') }}</QTooltip>
                 </QIcon>
             </QTd>
         </template>
-        <template #column-zone="{ row }">
-            <QTd class="no-padding" @click.stop.prevent>
+        <template #column-zoneFk="{ row }">
+            <QTd class="no-padding" @click.stop.prevent :title="row.zoneName">
                 <span class="link">{{ row.zoneName }}</span>
                 <ZoneDescriptorProxy :id="row.zoneFk" />
             </QTd>
         </template>
-        <template #column-total="{ row }">
+        <template #column-totalWithVat="{ row }">
             <QTd class="no-padding">
                 <QBadge
                     :color="totalPriceColor(row) || 'transparent'"
diff --git a/src/pages/Monitor/locale/en.yml b/src/pages/Monitor/locale/en.yml
index f58db7854..4cdd245aa 100644
--- a/src/pages/Monitor/locale/en.yml
+++ b/src/pages/Monitor/locale/en.yml
@@ -11,11 +11,14 @@ salesClientsTable:
     client: Client
 salesOrdersTable:
     delete: Delete
-    date: Date
+    dateSend: Send date
+    dateMake: Make date
     client: Client
     salesPerson: Salesperson
     deleteConfirmTitle: Delete selected elements
     deleteConfirmMessage: All the selected elements will be deleted. Are you sure you want to continue?
+    agency: Agency
+    import: Import
 salesTicketsTable:
     autoRefresh: Auto-refresh
     problems: Problems
@@ -43,3 +46,4 @@ salesTicketsTable:
 searchBar:
     label: Search tickets
     info: Search tickets by id or alias
+refreshInfo: Toggle auto-refresh every 2 minutes
diff --git a/src/pages/Monitor/locale/es.yml b/src/pages/Monitor/locale/es.yml
index 918b51813..8087bb444 100644
--- a/src/pages/Monitor/locale/es.yml
+++ b/src/pages/Monitor/locale/es.yml
@@ -11,11 +11,14 @@ salesClientsTable:
     client: Cliente
 salesOrdersTable:
     delete: Eliminar
-    date: Fecha
+    dateSend: Fecha de envío
+    dateMake: Fecha de realización
     client: Cliente
     salesPerson: Comercial
     deleteConfirmTitle: Eliminar los elementos seleccionados
     deleteConfirmMessage: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
+    agency: Agencia
+    import: Importe
 salesTicketsTable:
     autoRefresh: Auto-refresco
     problems: Problemas
@@ -43,3 +46,4 @@ salesTicketsTable:
 searchBar:
     label: Buscar tickets
     info: Buscar tickets por identificador o alias
+refreshInfo: Conmuta el refresco automático cada 2 minutos
diff --git a/src/pages/Order/Card/OrderForm.vue b/src/pages/Order/Card/OrderBasicData.vue
similarity index 85%
rename from src/pages/Order/Card/OrderForm.vue
rename to src/pages/Order/Card/OrderBasicData.vue
index f447950d2..4bc9e2e43 100644
--- a/src/pages/Order/Card/OrderForm.vue
+++ b/src/pages/Order/Card/OrderBasicData.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { useRoute, useRouter } from 'vue-router';
+import { useRoute } from 'vue-router';
 import { ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import axios from 'axios';
@@ -7,6 +7,7 @@ import { useState } from 'composables/useState';
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnSelect from 'components/common/VnSelect.vue';
+import VnInput from 'components/common/VnInput.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 
@@ -15,7 +16,6 @@ const route = useRoute();
 const state = useState();
 const ORDER_MODEL = 'order';
 
-const router = useRouter();
 const isNew = Boolean(!route.params.id);
 const clientList = ref([]);
 const agencyList = ref([]);
@@ -64,13 +64,6 @@ const fetchOrderDetails = (order) => {
     fetchAgencyList(order?.landed, order?.addressFk);
 };
 
-const orderMapper = (order) => {
-    return {
-        addressId: order.addressFk,
-        agencyModeId: order.agencyModeFk,
-        landed: new Date(order.landed).toISOString(),
-    };
-};
 const orderFilter = {
     include: [
         { relation: 'agencyMode', scope: { fields: ['name'] } },
@@ -106,10 +99,6 @@ const onClientChange = async (clientId) => {
         console.error('Error al cambiar el cliente:', error);
     }
 };
-
-async function onDataSaved({ id }) {
-    await router.push({ path: `/order/${id}/catalog` });
-}
 </script>
 
 <template>
@@ -117,9 +106,8 @@ async function onDataSaved({ id }) {
     <div class="q-pa-md">
         <FormModel
             :url="`Orders/${route.params.id}`"
-            @on-data-saved="onDataSaved"
+            :url-update="`Orders/${route.params.id}/updateBasicData`"
             :model="ORDER_MODEL"
-            :mapper="orderMapper"
             :filter="orderFilter"
             @on-fetch="fetchOrderDetails"
             auto-load
@@ -180,8 +168,6 @@ async function onDataSaved({ id }) {
                             () => fetchAgencyList(data.landed, data.addressFk)
                         "
                     />
-                </VnRow>
-                <VnRow>
                     <VnSelect
                         :label="t('order.form.agencyModeFk')"
                         v-model="data.agencyModeFk"
@@ -189,9 +175,29 @@ async function onDataSaved({ id }) {
                         option-value="agencyModeFk"
                         option-label="agencyMode"
                         hide-selected
-                        :disable="!agencyList?.length"
-                    >
-                    </VnSelect>
+                        :disable="!agencyList?.length && data.isConfirmed === 1"
+                        clearable
+                        emit-value
+                        map-options
+                        :model-value="
+                            !data.isConfirmed &&
+                            agencyList?.length &&
+                            agencyList.some(
+                                (agency) => agency.agencyModeFk === data.agency_id
+                            )
+                                ? data.agencyModeFk
+                                : null
+                        "
+                    />
+                </VnRow>
+                <VnRow>
+                    <VnInput
+                        :label="t('globals.notes')"
+                        type="textarea"
+                        v-model="data.note"
+                        fill-input
+                        autogrow
+                    />
                 </VnRow>
             </template>
         </FormModel>
diff --git a/src/pages/Order/Card/OrderCard.vue b/src/pages/Order/Card/OrderCard.vue
index 5b6896656..67c0f1de5 100644
--- a/src/pages/Order/Card/OrderCard.vue
+++ b/src/pages/Order/Card/OrderCard.vue
@@ -1,16 +1,35 @@
 <script setup>
+import { computed } from 'vue';
+import { useRoute } from 'vue-router';
 import VnCard from 'components/common/VnCard.vue';
 import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
 import OrderFilter from './OrderFilter.vue';
 import OrderSearchbar from './OrderSearchbar.vue';
+import OrderCatalogFilter from './OrderCatalogFilter.vue';
+const config = {
+    OrderCatalog: OrderCatalogFilter,
+};
+const route = useRoute();
+
+const routeName = computed(() => route.name);
+const customRouteRedirectName = computed(() => {
+    const route = config[routeName.value];
+    if (route) return null;
+    return 'OrderList';
+});
+const customFilterPanel = computed(() => {
+    const filterPanel = config[routeName.value] ?? OrderFilter;
+    return filterPanel;
+});
 </script>
+
 <template>
     <VnCard
         data-key="Order"
         base-url="Orders"
         :descriptor="OrderDescriptor"
-        :filter-panel="OrderFilter"
-        search-data-key="OrderList"
+        :filter-panel="customFilterPanel"
+        :search-data-key="customRouteRedirectName"
     >
         <template #searchbar>
             <OrderSearchbar />
diff --git a/src/pages/Order/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue
similarity index 77%
rename from src/pages/Order/OrderCatalog.vue
rename to src/pages/Order/Card/OrderCatalog.vue
index 2cf6e1c29..68bf9511f 100644
--- a/src/pages/Order/OrderCatalog.vue
+++ b/src/pages/Order/Card/OrderCatalog.vue
@@ -1,17 +1,24 @@
 <script setup>
 import { useStateStore } from 'stores/useStateStore';
-import { useRoute } from 'vue-router';
+import { useRoute, useRouter } from 'vue-router';
 import { onMounted, onUnmounted, ref } from 'vue';
+import axios from 'axios';
 import { useI18n } from 'vue-i18n';
 import VnPaginate from 'components/ui/VnPaginate.vue';
 import CatalogItem from 'components/ui/CatalogItem.vue';
 import OrderCatalogFilter from 'pages/Order/Card/OrderCatalogFilter.vue';
+import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
 
 const route = useRoute();
+const router = useRouter();
 const stateStore = useStateStore();
 const { t } = useI18n();
+const tags = ref([]);
 
-onMounted(() => (stateStore.rightDrawer = true));
+onMounted(() => {
+    stateStore.rightDrawer = true;
+    checkOrderConfirmation();
+});
 onUnmounted(() => (stateStore.rightDrawer = false));
 
 const catalogParams = {
@@ -19,7 +26,12 @@ const catalogParams = {
     orderBy: JSON.stringify({ field: 'relevancy DESC, name', way: 'ASC', isTag: false }),
 };
 
-const tags = ref([]);
+async function checkOrderConfirmation() {
+    const response = await axios.get(`Orders/${route.params.id}`);
+    if (response.data.isConfirmed === 1) {
+        router.push(`/order/${route.params.id}/line`);
+    }
+}
 
 function extractTags(items) {
     const resultTags = [];
@@ -52,6 +64,15 @@ function extractValueTags(items) {
 </script>
 
 <template>
+    <VnSearchbar
+        data-key="OrderCatalogList"
+        :user-params="catalogParams"
+        :static-params="['orderFk', 'orderBy']"
+        :redirect="false"
+        url="Orders/CatalogFilter"
+        :label="t('Search items')"
+        :info="t('You can search items by name or id')"
+    />
     <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
         <QScrollArea class="fit text-grey-8">
             <OrderCatalogFilter
@@ -68,7 +89,6 @@ function extractValueTags(items) {
                 url="Orders/CatalogFilter"
                 :limit="50"
                 :user-params="catalogParams"
-                auto-load
                 @on-fetch="extractTags"
                 :update-router="false"
             >
@@ -106,3 +126,8 @@ function extractValueTags(items) {
     text-align: center;
 }
 </style>
+
+<i18n>
+es:
+    You can search items by name or id: Puedes buscar items por nombre o id
+</i18n>
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index c354ec94b..938cc4fe2 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -7,8 +7,8 @@ import FetchData from 'components/FetchData.vue';
 import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
 import VnSelect from 'components/common/VnSelect.vue';
 import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
-import { useValidator } from 'src/composables/useValidator';
 import VnInput from 'src/components/common/VnInput.vue';
+import getParamWhere from 'src/filters/getParamWhere';
 
 const { t } = useI18n();
 
@@ -27,19 +27,26 @@ const props = defineProps({
         required: true,
     },
 });
-
 const categoryList = ref(null);
-const selectedCategoryFk = ref(null);
-const typeList = ref(null);
+const selectedCategoryFk = ref(getParamWhere(route, 'categoryFk'));
+const typeList = ref([]);
 const selectedTypeFk = ref(null);
-const validationsStore = useValidator();
-const selectedOrder = ref(null);
-const selectedOrderField = ref(null);
-const moreFields = ref([]);
-const moreFieldsOrder = ref([]);
 const selectedTag = ref(null);
 const tagValues = ref([{}]);
 const tagOptions = ref([]);
+const vnFilterPanelRef = ref();
+const orderByList = ref([
+    { id: 'relevancy DESC, name', name: t('params.relevancy'), priority: 999 },
+    { id: 'showOrder, price', name: t('params.colorAndPrice'), priority: 999 },
+    { id: 'name', name: t('params.name'), priority: 999 },
+    { id: 'price', name: t('params.price'), priority: 999 },
+]);
+const orderWayList = ref([
+    { id: 'ASC', name: t('params.ASC') },
+    { id: 'DESC', name: t('params.DESC') },
+]);
+const orderBySelected = ref('relevancy DESC, name');
+const orderWaySelected = ref('ASC');
 
 const createValue = (val, done) => {
     if (val.length > 2) {
@@ -72,7 +79,7 @@ const selectCategory = (params, category, search) => {
     search();
 };
 
-const loadTypes = async (categoryFk) => {
+const loadTypes = async (categoryFk = selectedCategoryFk.value) => {
     const { data } = await axios.get(`Orders/${route.params.id}/getItemTypeAvailable`, {
         params: { itemCategoryId: categoryFk },
     });
@@ -84,7 +91,14 @@ const selectedCategory = computed(() =>
         (category) => category?.id === selectedCategoryFk.value
     )
 );
-
+function filterFn(val, update) {
+    update(() => {
+        const needle = val.toLowerCase();
+        tagOptions.value = props.tagValue.filter(
+            (v) => v.toLowerCase().indexOf(needle) > -1
+        );
+    });
+}
 const selectedType = computed(() => {
     return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value);
 });
@@ -95,7 +109,8 @@ function exprBuilder(param, value) {
         case 'typeFk':
             return { [param]: value };
         case 'search':
-            return { 'i.name': { like: `%${value}%` } };
+            if (/^\d+$/.test(value)) return { 'i.id': value };
+            else return { 'i.name': { like: `%${value}%` } };
     }
 }
 
@@ -132,36 +147,6 @@ const removeTagChip = (selection, params, search) => {
     search();
 };
 
-const onOrderChange = (value, params) => {
-    const tagObj = JSON.parse(params.orderBy);
-    tagObj.way = value.name;
-    params.orderBy = JSON.stringify(tagObj);
-};
-
-const onOrderFieldChange = (value, params) => {
-    const tagObj = JSON.parse(params.orderBy);
-    switch (value) {
-        case 'Relevancy':
-            tagObj.name = value + ' DESC, name';
-            params.orderBy = JSON.stringify(tagObj);
-            break;
-        case 'ColorAndPrice':
-            tagObj.name = 'showOrder, price';
-            params.orderBy = JSON.stringify(tagObj);
-            break;
-        case 'Name':
-            tagObj.name = 'name';
-            params.orderBy = JSON.stringify(tagObj);
-            break;
-        case 'Price':
-            tagObj.name = 'price';
-            params.orderBy = JSON.stringify(tagObj);
-            break;
-    }
-};
-
-const _moreFields = ['ASC', 'DESC'];
-const _moreFieldsTypes = ['Relevancy', 'ColorAndPrice', 'Name', 'Price'];
 const setCategoryList = (data) => {
     categoryList.value = (data || [])
         .filter((category) => category.display)
@@ -169,8 +154,8 @@ const setCategoryList = (data) => {
             ...category,
             icon: `vn:${(category.icon || '').split('-')[1]}`,
         }));
-    moreFields.value = useLang(_moreFields);
-    moreFieldsOrder.value = useLang(_moreFieldsTypes);
+
+    selectedCategoryFk.value && loadTypes();
 };
 
 const getCategoryClass = (category, params) => {
@@ -179,27 +164,22 @@ const getCategoryClass = (category, params) => {
     }
 };
 
-const useLang = (values) => {
-    const { models } = validationsStore;
-    const properties = models.Item?.properties || {};
-    return values.map((name) => {
-        let prop = properties[name];
-        const label = t(`params.${name}`);
-        return {
-            name,
-            label,
-            type: prop ? prop.type : null,
-        };
-    });
-};
+function addOrder(value, field, params) {
+    let { orderBy } = params;
+    orderBy = JSON.parse(orderBy);
+    orderBy[field] = value;
+    params.orderBy = JSON.stringify(orderBy);
+    vnFilterPanelRef.value.search();
+}
 </script>
 
 <template>
     <FetchData url="ItemCategories" limit="30" auto-load @on-fetch="setCategoryList" />
     <VnFilterPanel
+        ref="vnFilterPanelRef"
         :data-key="props.dataKey"
         :hidden-tags="['orderFk', 'orderBy']"
-        :unremovable-params="['orderFk', 'orderBy']"
+        :un-removable-params="['orderFk', 'orderBy']"
         :expr-builder="exprBuilder"
         :custom-tags="['tagGroups']"
         @remove="clearFilter"
@@ -289,33 +269,29 @@ const useLang = (values) => {
                 </QItemSection>
             </QItem>
             <QSeparator />
-            <QItem class="q-my-md">
-                <QItemSection>
-                    <VnSelect
-                        :label="t('Order')"
-                        v-model="selectedOrder"
-                        :options="moreFields"
-                        option-label="label"
-                        option-value="way"
-                        dense
-                        outlined
-                        rounded
-                        @update:model-value="(value) => onOrderChange(value, params)"
-                    />
-                </QItemSection>
-            </QItem>
             <QItem class="q-mb-md">
                 <QItemSection>
                     <VnSelect
                         :label="t('Order by')"
-                        v-model="selectedOrderField"
-                        :options="moreFieldsOrder"
-                        option-label="label"
-                        option-value="name"
+                        v-model="orderBySelected"
+                        :options="orderByList"
                         dense
                         outlined
                         rounded
-                        @update:model-value="(value) => onOrderFieldChange(value, params)"
+                        @update:model-value="(value) => addOrder(value, 'field', params)"
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem class="q-my-md">
+                <QItemSection>
+                    <VnSelect
+                        :label="t('Order')"
+                        v-model="orderWaySelected"
+                        :options="orderWayList"
+                        dense
+                        outlined
+                        rounded
+                        @update:model-value="(value) => addOrder(value, 'way', params)"
                     />
                 </QItemSection>
             </QItem>
@@ -352,7 +328,7 @@ const useLang = (values) => {
                     v-if="!selectedTag"
                     :label="t('params.value')"
                     v-model="value.value"
-                    :options="tagValue || []"
+                    :options="tagOptions || []"
                     option-value="value"
                     option-label="value"
                     dense
@@ -362,6 +338,8 @@ const useLang = (values) => {
                     use-input
                     class="filter-input"
                     @new-value="createValue"
+                    @filter="filterFn"
+                    @update:model-value="applyTagFilter(params, searchFn)"
                 />
                 <VnSelect
                     v-else-if="selectedTag === 1"
@@ -377,6 +355,7 @@ const useLang = (values) => {
                     use-input
                     class="filter-input"
                     @new-value="createValue"
+                    @update:model-value="applyTagFilter(params, searchFn)"
                 />
                 <VnInput
                     v-else
@@ -386,6 +365,7 @@ const useLang = (values) => {
                     outlined
                     rounded
                     class="filter-input"
+                    @keyup.enter="applyTagFilter(params, searchFn)"
                 />
                 <QIcon
                     name="delete"
@@ -400,21 +380,6 @@ const useLang = (values) => {
                     @click="tagValues.push({})"
                 />
             </QItem>
-            <QItem>
-                <QItemSection class="q-py-sm">
-                    <QBtn
-                        :label="t('Search')"
-                        class="full-width"
-                        color="primary"
-                        dense
-                        icon="search"
-                        rounded
-                        type="button"
-                        unelevated
-                        @click.stop="applyTagFilter(params, searchFn)"
-                    />
-                </QItemSection>
-            </QItem>
             <QSeparator />
         </template>
     </VnFilterPanel>
@@ -477,10 +442,10 @@ en:
         order: Order
         ASC: Ascendant
         DESC: Descendant
-        Relevancy: Relevancy
-        ColorAndPrice: Color and price
-        Name: Name
-        Price: Price
+        relevancy: Relevancy
+        colorAndPrice: Color and price
+        name: Name
+        price: Price
 es:
     params:
         type: Tipo
@@ -490,10 +455,10 @@ es:
         order: Orden
         ASC: Ascendiente
         DESC: Descendiente
-        Relevancy: Relevancia
-        ColorAndPrice: Color y precio
-        Name: Nombre
-        Price: Precio
+        relevancy: Relevancia
+        colorAndPrice: Color y precio
+        name: Nombre
+        price: Precio
     Order: Orden
     Order by: Ordenar por
     Plant: Planta
diff --git a/src/pages/Order/Card/OrderCatalogItemDialog.vue b/src/pages/Order/Card/OrderCatalogItemDialog.vue
index 047816127..46a50c021 100644
--- a/src/pages/Order/Card/OrderCatalogItemDialog.vue
+++ b/src/pages/Order/Card/OrderCatalogItemDialog.vue
@@ -5,10 +5,12 @@ import { useI18n } from 'vue-i18n';
 import axios from 'axios';
 import { useRoute } from 'vue-router';
 import useNotify from 'composables/useNotify';
+import { useArrayData } from 'composables/useArrayData';
 
 const { t } = useI18n();
-const route = useRoute();
 const { notify } = useNotify();
+const emit = defineEmits(['added']);
+const route = useRoute();
 const props = defineProps({
     prices: {
         type: Array,
@@ -16,9 +18,8 @@ const props = defineProps({
     },
 });
 
-const emit = defineEmits(['added']);
-
 const fields = ref((props.prices || []).map((item) => ({ ...item, quantity: 0 })));
+const descriptorData = useArrayData('orderData');
 
 const addToOrder = async () => {
     const items = (fields.value || []).filter((item) => Number(item.quantity) > 0);
@@ -28,19 +29,20 @@ const addToOrder = async () => {
     });
     notify(t('globals.dataSaved'), 'positive');
     emit('added');
+    descriptorData.fetch({});
 };
 </script>
 
 <template>
-    <div class="container order-catalog-item q-pb-md">
+    <div class="container order-catalog-item q-pa-md">
         <QForm @submit="addToOrder">
             <QMarkupTable class="shadow-0">
                 <tbody>
                     <tr v-for="item in fields" :key="item.warehouse">
-                        <td class="text-bold q-py-lg">
+                        <td class="text-bold q-pr-md td" style="width: 35%">
                             {{ item.warehouse }}
                         </td>
-                        <td class="text-right">
+                        <td class="text-right" style="width: 35%">
                             <span
                                 class="link"
                                 @click="
@@ -75,8 +77,7 @@ const addToOrder = async () => {
 </template>
 
 <style lang="scss" scoped>
-.container {
-    max-width: 448px;
-    width: 100%;
+.td {
+    width: 200px;
 }
 </style>
diff --git a/src/pages/Order/Card/OrderCreateDialog.vue b/src/pages/Order/Card/OrderCreateDialog.vue
new file mode 100644
index 000000000..9d5c9281e
--- /dev/null
+++ b/src/pages/Order/Card/OrderCreateDialog.vue
@@ -0,0 +1,220 @@
+<script setup>
+import { useRoute, useRouter } from 'vue-router';
+import { onMounted, ref } from 'vue';
+import { useI18n } from 'vue-i18n';
+import axios from 'axios';
+import { useState } from 'composables/useState';
+import FormModelPopup from 'components/FormModelPopup.vue';
+import VnRow from 'components/ui/VnRow.vue';
+import VnSelect from 'components/common/VnSelect.vue';
+import VnInputDate from 'components/common/VnInputDate.vue';
+import { useDialogPluginComponent } from 'quasar';
+import { reactive } from 'vue';
+import FetchData from 'components/FetchData.vue';
+
+const { t } = useI18n();
+const route = useRoute();
+const state = useState();
+const ORDER_MODEL = 'order';
+
+const router = useRouter();
+const clientList = ref([]);
+const agencyList = ref([]);
+const addressList = ref([]);
+defineEmits(['confirm', ...useDialogPluginComponent.emits]);
+
+const fetchAddressList = async (addressId) => {
+    try {
+        const { data } = await axios.get('addresses', {
+            params: {
+                filter: JSON.stringify({
+                    fields: ['id', 'nickname', 'street', 'city'],
+                    where: { id: addressId },
+                }),
+            },
+        });
+        addressList.value = data;
+        if (addressList.value?.length === 1) {
+            state.get(ORDER_MODEL).addressId = addressList.value[0].id;
+        }
+    } catch (err) {
+        console.error(`Error fetching addresses`, err);
+        return err.response;
+    }
+};
+
+const fetchAgencyList = async (landed, addressFk) => {
+    if (!landed || !addressFk) {
+        return;
+    }
+    try {
+        const { data } = await axios.get('Agencies/landsThatDay', {
+            params: {
+                addressFk,
+                landed: new Date(landed).toISOString(),
+            },
+        });
+        agencyList.value = data;
+    } catch (err) {
+        console.error(`Error fetching agencies`, err);
+        return err.response;
+    }
+};
+
+// const fetchOrderDetails = (order) => {
+//     fetchAddressList(order?.addressFk);
+//     fetchAgencyList(order?.landed, order?.addressFk);
+// };
+const $props = defineProps({
+    clientFk: {
+        type: Number,
+        default: null,
+    },
+});
+const initialFormState = reactive({
+    active: true,
+    addressId: null,
+    clientFk: $props.clientFk,
+});
+// const orderMapper = (order) => {
+//     return {
+//         addressId: order.addressFk,
+//         agencyModeId: order.agencyModeFk,
+//         landed: new Date(order.landed).toISOString(),
+//     };
+// };
+// const orderFilter = {
+//     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 onClientChange = async (clientId = $props.clientFk) => {
+    try {
+        const { data } = await axios.get(`Clients/${clientId}`);
+        await fetchAddressList(data.defaultAddressFk);
+    } catch (error) {
+        console.error('Error al cambiar el cliente:', error);
+    }
+};
+
+async function onDataSaved(_, id) {
+    await router.push({ path: `/order/${id}/catalog` });
+}
+onMounted(async () => {
+    await onClientChange();
+});
+</script>
+
+<template>
+    <FetchData
+        url="addresses"
+        @on-fetch="(data) => (clientOptions = data)"
+        :filter="{ fields: ['id', 'name', 'defaultAddressFk'], order: 'id' }"
+        auto-load
+    />
+    <FormModelPopup
+        url-create="Orders/new"
+        :title="t('Create Order')"
+        @on-data-saved="onDataSaved"
+        :model="ORDER_MODEL"
+        :filter="orderFilter"
+        :form-initial-data="initialFormState"
+    >
+        <template #form-inputs="{ data }">
+            <VnRow class="row q-gutter-md q-mb-md">
+                <VnSelect
+                    url="Clients"
+                    :label="t('order.form.clientFk')"
+                    v-model="data.clientFk"
+                    option-value="id"
+                    option-label="name"
+                    :filter="{
+                        fields: ['id', 'name', 'defaultAddressFk'],
+                    }"
+                    hide-selected
+                    @update:model-value="onClientChange"
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel>
+                                    {{ `${scope.opt.id}: ${scope.opt.name}` }}
+                                </QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
+                <VnSelect
+                    :label="t('order.form.addressFk')"
+                    v-model="data.addressId"
+                    :options="addressList"
+                    option-value="id"
+                    option-label="street"
+                    hide-selected
+                    :disable="!addressList?.length"
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel>
+                                    {{
+                                        `${scope.opt.nickname}: ${scope.opt.street},${scope.opt.city}`
+                                    }}
+                                </QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
+            </VnRow>
+            <VnRow class="row q-gutter-md q-mb-md">
+                <VnInputDate
+                    placeholder="dd-mm-aaa"
+                    :label="t('order.form.landed')"
+                    v-model="data.landed"
+                    @update:model-value="
+                        () => fetchAgencyList(data.landed, data.addressId)
+                    "
+                />
+            </VnRow>
+            <VnRow class="row q-gutter-md q-mb-md">
+                <VnSelect
+                    :label="t('order.form.agencyModeFk')"
+                    v-model="data.agencyModeId"
+                    :options="agencyList"
+                    option-value="agencyModeFk"
+                    option-label="agencyMode"
+                    hide-selected
+                    :disable="!agencyList?.length"
+                >
+                </VnSelect>
+            </VnRow>
+        </template>
+    </FormModelPopup>
+</template>
+
+<i18n>
+    es:
+        No default address found for the client: No hay ninguna dirección asociada a este cliente.
+</i18n>
diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue
index 4d84a32fc..a035971b0 100644
--- a/src/pages/Order/Card/OrderDescriptor.vue
+++ b/src/pages/Order/Card/OrderDescriptor.vue
@@ -4,13 +4,13 @@ import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { toCurrency, toDate } from 'src/filters';
 import { useState } from 'src/composables/useState';
-
 import useCardDescription from 'src/composables/useCardDescription';
-import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
-import OrderDescriptorMenu from 'pages/Order/Card/OrderDescriptorMenu.vue';
 import FetchData from 'components/FetchData.vue';
+import OrderDescriptorMenu from 'pages/Order/Card/OrderDescriptorMenu.vue';
+import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 
 const DEFAULT_ITEMS = 0;
 
@@ -25,6 +25,8 @@ 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;
@@ -57,11 +59,11 @@ const filter = {
     ],
 };
 
-const data = ref(useCardDescription());
 const setData = (entity) => {
     if (!entity) return;
+    getTotalRef.value && getTotalRef.value.fetch();
     data.value = useCardDescription(entity?.client?.name, entity?.id);
-    state.set('OrderDescriptor', entity);
+    state.set('orderData', entity);
 };
 
 const getConfirmationValue = (isConfirmed) => {
@@ -69,13 +71,17 @@ const getConfirmationValue = (isConfirmed) => {
 };
 
 const total = ref(null);
+
+function ticketFilter(order) {
+    return JSON.stringify({ id: order.id });
+}
 </script>
 
 <template>
     <FetchData
+        ref="getTotalRef"
         :url="`Orders/${entityId}/getTotal`"
         @on-fetch="(response) => (total = response)"
-        auto-load
     />
     <CardDescriptor
         ref="descriptor"
@@ -120,7 +126,7 @@ const total = ref(null);
                     color="primary"
                     :to="{
                         name: 'TicketList',
-                        query: { params: JSON.stringify({ orderFk: entity.id }) },
+                        query: { table: ticketFilter(entity) },
                     }"
                 >
                     <QTooltip>{{ t('order.summary.orderTicketList') }}</QTooltip>
diff --git a/src/pages/Order/Card/OrderDescriptorMenu.vue b/src/pages/Order/Card/OrderDescriptorMenu.vue
index 2e36aa3c5..2695da4e5 100644
--- a/src/pages/Order/Card/OrderDescriptorMenu.vue
+++ b/src/pages/Order/Card/OrderDescriptorMenu.vue
@@ -23,7 +23,7 @@ function confirmRemove() {
         .dialog({
             component: VnConfirm,
             componentProps: {
-                title: t('confirmDeletion'),
+                title: t('globals.confirmDeletion'),
                 message: t('confirmDeletionMessage'),
                 promise: remove,
             },
@@ -52,12 +52,10 @@ async function remove() {
 <i18n>
 en:
     deleteOrder: Delete order
-    confirmDeletion: Confirm deletion
     confirmDeletionMessage: Are you sure you want to delete this order?
 
 es:
     deleteOrder: Eliminar pedido
-    confirmDeletion: Confirmar eliminación
     confirmDeletionMessage: Seguro que quieres eliminar este pedido?
 
 </i18n>
diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue
index 347affb04..be47eed54 100644
--- a/src/pages/Order/Card/OrderFilter.vue
+++ b/src/pages/Order/Card/OrderFilter.vue
@@ -21,15 +21,13 @@ const salesPersonFilter = {
     fields: ['id', 'nickname'],
 };
 const salesPersonList = ref(null);
-const sourceFilter = { fields: ['value'] };
-const sourceList = ref(null);
+const sourceList = ref([]);
 </script>
 
 <template>
     <FetchData
         url="AgencyModes/isActive"
         :filter="agencyFilter"
-        limit="30"
         sort-by="name ASC"
         auto-load
         @on-fetch="(data) => (agencyList = data)"
@@ -37,7 +35,6 @@ const sourceList = ref(null);
     <FetchData
         url="Workers/search"
         :filter="salesPersonFilter"
-        limit="30"
         sort-by="nickname ASC"
         @on-fetch="(data) => (salesPersonList = data)"
         :params="{ departmentCodes: ['VT'] }"
@@ -45,8 +42,7 @@ const sourceList = ref(null);
     />
     <FetchData
         url="Orders/getSourceValues"
-        :filter="sourceFilter"
-        limit="30"
+        :filter="{ fields: ['value'] }"
         sort-by="value ASC"
         @on-fetch="(data) => (sourceList = data)"
         auto-load
@@ -59,148 +55,88 @@ const sourceList = ref(null);
             </div>
         </template>
         <template #body="{ params }">
-            <QItem>
-                <QItemSection>
-                    <VnInput
-                        is-outlined
-                        :label="t('customerId')"
-                        v-model="params.clientFk"
-                        lazy-rules
-                    >
-                        <template #prepend>
-                            <QIcon name="badge" size="sm"></QIcon>
-                        </template>
-                    </VnInput>
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection v-if="agencyList">
-                    <VnSelect
-                        :label="t('agency')"
-                        v-model="params.agencyModeFk"
-                        :options="agencyList"
-                        option-value="id"
-                        option-label="name"
-                        dense
-                        outlined
-                        rounded
-                        emit-value
-                        map-options
-                        use-input
-                        :input-debounce="0"
-                    />
-                </QItemSection>
-                <QItemSection v-else>
-                    <QSkeleton type="QInput" class="full-width" />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection v-if="salesPersonList">
-                    <VnSelect
-                        :label="t('salesPerson')"
-                        v-model="params.workerFk"
-                        :options="salesPersonList"
-                        option-value="id"
-                        option-label="name"
-                        dense
-                        outlined
-                        rounded
-                        emit-value
-                        map-options
-                        use-input
-                        :input-debounce="0"
-                    >
-                        <template #option="{ itemProps, opt }">
-                            <QItem v-bind="itemProps">
-                                <QItemSection>
-                                    <QItemLabel>{{ opt.name }}</QItemLabel>
-                                    <QItemLabel caption>
-                                        {{ opt.nickname }},{{ opt.code }}
-                                    </QItemLabel>
-                                </QItemSection>
-                            </QItem>
-                        </template>
-                    </VnSelect>
-                </QItemSection>
-                <QItemSection v-else>
-                    <QSkeleton type="QInput" class="full-width" />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInputDate
-                        v-model="params.from"
-                        :label="t('fromLanded')"
-                        dense
-                        outlined
-                        rounded
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInputDate
-                        v-model="params.to"
-                        :label="t('toLanded')"
-                        dense
-                        outlined
-                        rounded
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInput
-                        :label="t('orderId')"
-                        v-model="params.orderFk"
-                        lazy-rules
-                        is-outlined
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection v-if="sourceList">
-                    <VnSelect
-                        :label="t('application')"
-                        v-model="params.sourceApp"
-                        :options="sourceList"
-                        option-label="value"
-                        emit-value
-                        map-options
-                        use-input
-                        dense
-                        outlined
-                        rounded
-                        :input-debounce="0"
-                    />
-                </QItemSection>
-                <QItemSection v-else>
-                    <QSkeleton type="QInput" class="full-width" />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <QCheckbox
-                        v-model="params.myTeam"
-                        :label="t('myTeam')"
-                        toggle-indeterminate
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <QCheckbox
-                        v-model="params.isConfirmed"
-                        :label="t('isConfirmed')"
-                        toggle-indeterminate
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <QCheckbox v-model="params.showEmpty" :label="t('showEmpty')" />
-                </QItemSection>
-            </QItem>
+            <div class="q-px-md q-gutter-y-sm">
+                <VnInput
+                    :label="t('customerId')"
+                    v-model="params.clientFk"
+                    lazy-rules
+                    dense
+                    outlined
+                    rounded
+                />
+                <VnSelect
+                    :label="t('agency')"
+                    v-model="params.agencyModeFk"
+                    :options="agencyList"
+                    :input-debounce="0"
+                    dense
+                    outlined
+                    rounded
+                />
+                <VnSelect
+                    :label="t('salesPerson')"
+                    v-model="params.workerFk"
+                    url="Workers/search"
+                    :filter="{ departmentCodes: ['VT'] }"
+                    sort-by="nickname ASC"
+                    option-label="nickname"
+                    dense
+                    outlined
+                    rounded
+                >
+                    <template #option="{ itemProps, opt }">
+                        <QItem v-bind="itemProps">
+                            <QItemSection>
+                                <QItemLabel>{{ opt.name }}</QItemLabel>
+                                <QItemLabel caption>
+                                    {{ opt.nickname }},{{ opt.code }}
+                                </QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
+                <VnInputDate
+                    v-model="params.from"
+                    :label="t('fromLanded')"
+                    dense
+                    outlined
+                    rounded
+                />
+                <VnInputDate
+                    v-model="params.to"
+                    :label="t('toLanded')"
+                    dense
+                    outlined
+                    rounded
+                />
+                <VnInput
+                    :label="t('orderId')"
+                    v-model="params.orderFk"
+                    lazy-rules
+                    is-outlined
+                />
+                <VnSelect
+                    :label="t('application')"
+                    v-model="params.sourceApp"
+                    :options="sourceList"
+                    option-label="value"
+                    dense
+                    outlined
+                    rounded
+                    :input-debounce="0"
+                />
+                <QCheckbox
+                    v-model="params.myTeam"
+                    :label="t('myTeam')"
+                    toggle-indeterminate
+                />
+                <QCheckbox
+                    v-model="params.isConfirmed"
+                    :label="t('isConfirmed')"
+                    toggle-indeterminate
+                />
+                <QCheckbox v-model="params.showEmpty" :label="t('showEmpty')" />
+            </div>
         </template>
     </VnFilterPanel>
 </template>
diff --git a/src/pages/Order/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue
similarity index 69%
rename from src/pages/Order/OrderLines.vue
rename to src/pages/Order/Card/OrderLines.vue
index 9814eaf34..17a157797 100644
--- a/src/pages/Order/OrderLines.vue
+++ b/src/pages/Order/Card/OrderLines.vue
@@ -1,23 +1,27 @@
 <script setup>
-import { useRoute } from 'vue-router';
+import { useRoute, useRouter } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { ref, computed } from 'vue';
+import { ref, computed, watch } from 'vue';
 import { useQuasar } from 'quasar';
+import axios from 'axios';
+import { useStateStore } from 'stores/useStateStore';
+import { useArrayData } from 'composables/useArrayData';
+import { toCurrency, toDate } from 'src/filters';
 
 import VnConfirm from 'components/ui/VnConfirm.vue';
-import { toCurrency, toDate } from 'src/filters';
-import axios from 'axios';
 import VnTable from 'src/components/VnTable/VnTable.vue';
 import FetchData from 'src/components/FetchData.vue';
 import VnImg from 'src/components/ui/VnImg.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import FetchedTags from 'src/components/ui/FetchedTags.vue';
-import { useStateStore } from 'stores/useStateStore';
+import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
 
+const router = useRouter();
 const stateStore = useStateStore();
 const route = useRoute();
 const { t } = useI18n();
 const quasar = useQuasar();
+const descriptorData = useArrayData('orderData');
 const componentKey = ref(0);
 const tableLinesRef = ref();
 const order = ref();
@@ -25,6 +29,8 @@ const orderSummary = ref({
     total: null,
     vat: null,
 });
+const getTotalRef = ref();
+const getVATRef = ref();
 
 const lineFilter = ref({
     include: [
@@ -59,6 +65,13 @@ const lineFilter = ref({
                 fields: ['id', 'name'],
             },
         },
+        {
+            relation: 'order',
+            scope: {
+                fields: ['id', 'isConfirmed'],
+                where: { id: route.params.id },
+            },
+        },
     ],
     where: { orderFk: route.params.id },
 });
@@ -104,6 +117,7 @@ const columns = computed(() => [
             component: null,
         },
         format: (row) => row?.item?.name,
+        columnClass: 'expand',
     },
     {
         align: 'left',
@@ -147,7 +161,6 @@ const columns = computed(() => [
         align: 'left',
         name: 'amount',
         label: t('lines.amount'),
-        format: (row) => toCurrency(row.amount),
     },
     {
         align: 'right',
@@ -155,8 +168,9 @@ const columns = computed(() => [
         name: 'tableActions',
         actions: [
             {
-                title: t('delete'),
+                title: t('Delete'),
                 icon: 'delete',
+                show: (row) => !row.order.isConfirmed,
                 action: (row) => confirmRemove(row),
                 isPrimary: true,
             },
@@ -185,6 +199,9 @@ async function remove(item) {
         type: 'positive',
     });
     tableLinesRef.value.reload();
+    descriptorData.fetch({});
+    getTotalRef.value.fetch();
+    getVATRef.value.fetch();
 }
 
 async function confirmOrder() {
@@ -193,7 +210,22 @@ async function confirmOrder() {
         message: t('globals.confirm'),
         type: 'positive',
     });
+    router.push({
+        name: 'TicketList',
+        query: {
+            table: JSON.stringify({ clientFk: descriptorData.store.data.clientFk }),
+        },
+    });
 }
+
+watch(
+    () => router.currentRoute.value.params.id,
+    () => {
+        lineFilter.value.where.orderFk = router.currentRoute.value.params.id;
+
+        tableLinesRef.value.reload();
+    }
+);
 </script>
 
 <template>
@@ -204,78 +236,85 @@ async function confirmOrder() {
         auto-load
     />
     <FetchData
+        ref="getTotalRef"
         :key="componentKey"
         :url="`Orders/${route.params.id}/getTotal`"
         @on-fetch="(data) => (orderSummary.total = data)"
         auto-load
     />
     <FetchData
+        ref="getVATRef"
         :key="componentKey"
         :url="`Orders/${route.params.id}/getVAT`"
         @on-fetch="(data) => (orderSummary.vat = data)"
         auto-load
     />
     <QDrawer side="right" :width="270" v-model="stateStore.rightDrawer">
-        <QCard class="order-lines-summary q-pa-lg">
+        <QCard
+            class="order-lines-summary q-pa-lg"
+            v-if="orderSummary.vat && orderSummary.total"
+        >
             <p class="header text-right block">
                 {{ t('summary') }}
             </p>
             <VnLv
-                v-if="orderSummary.vat && orderSummary.total"
                 :label="t('subtotal') + ': '"
                 :value="toCurrency(orderSummary.total - orderSummary.vat)"
             />
-            <VnLv
-                v-if="orderSummary.vat"
-                :label="t('VAT') + ': '"
-                :value="toCurrency(orderSummary?.vat)"
-            />
-            <VnLv
-                v-if="orderSummary.total"
-                :label="t('total') + ': '"
-                :value="toCurrency(orderSummary?.total)"
-            />
+            <VnLv :label="t('VAT') + ': '" :value="toCurrency(orderSummary?.vat)" />
+            <VnLv :label="t('total') + ': '" :value="toCurrency(orderSummary?.total)" />
         </QCard>
     </QDrawer>
-    <QPage :key="componentKey" class="column items-center">
-        <div class="order-list full-width">
-            <div v-if="!orderSummary.total" class="no-result">
-                {{ t('globals.noResults') }}
-            </div>
-            <VnTable
-                ref="tableLinesRef"
-                data-key="OrderLines"
-                url="OrderRows"
-                :columns="columns"
-                :right-search="false"
-                :use-model="true"
-                auto-load
-                :user-filter="lineFilter"
-            >
-                <template #column-image="{ row }">
-                    <div class="image-wrapper">
-                        <VnImg :id="parseInt(row?.item?.image)" class="rounded" />
-                    </div>
-                </template>
 
-                <template #column-itemFk="{ row }">
-                    <div class="row column full-width justify-between items-start">
-                        {{ row?.item?.name }}
-                        <div v-if="row?.item?.subName" class="subName">
-                            {{ row?.item?.subName.toUpperCase() }}
-                        </div>
-                    </div>
-                    <FetchedTags :item="row?.item" :max-length="6" />
-                </template>
-            </VnTable>
-        </div>
-        <QPageSticky :offset="[20, 20]" v-if="!order?.isConfirmed" style="z-index: 2">
-            <QBtn fab icon="check" color="primary" @click="confirmOrder()" />
-            <QTooltip>
-                {{ t('confirm') }}
-            </QTooltip>
-        </QPageSticky>
-    </QPage>
+    <VnTable
+        ref="tableLinesRef"
+        data-key="OrderLines"
+        url="OrderRows"
+        :columns="columns"
+        :right-search="false"
+        :use-model="true"
+        auto-load
+        :user-filter="lineFilter"
+    >
+        <template #column-image="{ row }">
+            <div class="image-wrapper">
+                <VnImg :id="parseInt(row?.item?.image)" class="rounded" />
+            </div>
+        </template>
+        <template #column-id="{ row }">
+            <span class="link" @click.stop>
+                {{ row?.item?.id }}
+                <ItemDescriptorProxy :id="row?.item?.id" />
+            </span>
+        </template>
+        <template #column-itemFk="{ row }">
+            <div class="row column full-width justify-between items-start">
+                {{ row?.item?.name }}
+                <div v-if="row?.item?.subName" class="subName">
+                    {{ row?.item?.subName.toUpperCase() }}
+                </div>
+            </div>
+            <FetchedTags :item="row?.item" />
+        </template>
+        <template #column-amount="{ row }">
+            {{ toCurrency(row.quantity * row.price) }}
+        </template>
+        <template #column-tableActions="{ row }">
+            <QIcon
+                v-if="row.order?.isConfirmed === 0"
+                name="delete"
+                icon="delete"
+                @click="confirmRemove(row)"
+                class="cursor-pointer"
+            />
+        </template>
+    </VnTable>
+    <QPageSticky :offset="[20, 20]" v-if="!order?.isConfirmed" style="z-index: 2">
+        <QBtn fab icon="check" color="primary" @click="confirmOrder()" />
+        <QTooltip>
+            {{ t('confirm') }}
+        </QTooltip>
+    </QPageSticky>
 </template>
 
 <style lang="scss" scoped>
diff --git a/src/pages/Order/Card/OrderSearchbar.vue b/src/pages/Order/Card/OrderSearchbar.vue
index a768768a5..fa30a097f 100644
--- a/src/pages/Order/Card/OrderSearchbar.vue
+++ b/src/pages/Order/Card/OrderSearchbar.vue
@@ -10,7 +10,7 @@ const { t } = useI18n();
         data-key="OrderList"
         url="Orders/filter"
         :label="t('Search order')"
-        :info="t('You can search orders by reference')"
+        :info="t('Search orders by ticket id')"
     />
 </template>
 
@@ -18,5 +18,5 @@ const { t } = useI18n();
 <i18n>
 es:
     Search order: Buscar orden
-    You can search orders by reference: Puedes buscar por referencia de la orden
+    Search orders by ticket id: Buscar pedido por id ticket
 </i18n>
diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue
index cb708fb1d..60358f744 100644
--- a/src/pages/Order/Card/OrderSummary.vue
+++ b/src/pages/Order/Card/OrderSummary.vue
@@ -180,17 +180,19 @@ const detailsColumns = ref([
                                         <ItemDescriptorProxy :id="props.row.item?.id" />
                                     </span>
                                 </QTd>
-                                <QTd key="description" :props="props" class="description">
-                                    <div class="name">
-                                        <span>{{ props.row.item.name }}</span>
-                                        <span
-                                            v-if="props.row.item.subName"
-                                            class="subName"
-                                        >
-                                            {{ props.row.item.subName }}
-                                        </span>
+                                <QTd key="description" :props="props">
+                                    <div class="description">
+                                        <div class="name">
+                                            {{ props.row.item.name }}
+                                            <span
+                                                v-if="props.row.item.subName"
+                                                class="subName"
+                                            >
+                                                {{ props.row.item.subName }}
+                                            </span>
+                                        </div>
                                     </div>
-                                    <FetchedTags :item="props.row.item" :max-length="5" />
+                                    <FetchedTags :item="props.row.item" />
                                 </QTd>
                                 <QTd key="quantity" :props="props">
                                     {{ props.row.quantity }}
@@ -228,24 +230,13 @@ const detailsColumns = ref([
 }
 
 .description {
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
     text-align: left;
-    height: auto;
-    padding-top: 12px;
-    padding-bottom: 12px;
+    padding-top: 15px;
+    padding-bottom: 15px;
 
     .name {
-        display: flex;
-        align-items: center;
-        padding-bottom: 8px;
-
-        & > * {
-            flex: 1;
-        }
-
         .subName {
+            margin-left: 5%;
             text-transform: uppercase;
             color: var(--vn-label-color);
         }
diff --git a/src/pages/Order/Card/OrderVolume.vue b/src/pages/Order/Card/OrderVolume.vue
new file mode 100644
index 000000000..27ee24197
--- /dev/null
+++ b/src/pages/Order/Card/OrderVolume.vue
@@ -0,0 +1,156 @@
+<script setup>
+import axios from 'axios';
+import { useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import { ref, onMounted } from 'vue';
+import { dashIfEmpty } from 'src/filters';
+import { useStateStore } from 'stores/useStateStore';
+
+import FetchData from 'components/FetchData.vue';
+import FetchedTags from 'components/ui/FetchedTags.vue';
+import ItemDescriptorProxy from 'pages/Item/Card/ItemDescriptorProxy.vue';
+import VnLv from 'components/ui/VnLv.vue';
+import VnTable from 'components/VnTable/VnTable.vue';
+
+const route = useRoute();
+const { t } = useI18n();
+const volumeSummary = ref(null);
+const volumeRef = ref();
+const volumes = ref([]);
+const volumeFilter = ref({
+    include: [
+        {
+            relation: 'item',
+        },
+    ],
+    where: { orderFk: route.params.id },
+});
+
+const columns = [
+    {
+        name: 'itemFk',
+        label: t('item'),
+        align: 'left',
+    },
+    {
+        name: 'description',
+        label: t('globals.description'),
+        align: 'left',
+    },
+    {
+        name: 'quantity',
+        label: t('quantity'),
+        align: 'left',
+    },
+    {
+        name: 'volume',
+        label: t('volume'),
+        align: 'left',
+    },
+];
+
+const loadVolumes = async (rows) => {
+    if (!rows) return;
+    const { data } = await axios.get(`Orders/${route.params.id}/getVolumes`);
+    rows.forEach((order) => {
+        (data.volumes || []).forEach((volume) => {
+            if (order.itemFk === volume.itemFk) order.volume = volume.volume;
+        });
+    });
+    volumes.value = rows;
+};
+
+const stateStore = useStateStore();
+onMounted(async () => (stateStore.rightDrawer = false));
+</script>
+
+<template>
+    <FetchData
+        :url="`Orders/${route.params.id}/getTotalVolume`"
+        @on-fetch="(data) => (volumeSummary = data)"
+        auto-load
+    />
+    <QCard v-if="volumeSummary" class="order-volume-summary q-pa-lg">
+        <VnLv :label="t('total')" :value="`${volumeSummary?.totalVolume} m³`" />
+        <VnLv
+            :label="t('boxes')"
+            :value="`${dashIfEmpty(volumeSummary?.totalBoxes)} U`"
+        />
+    </QCard>
+    <VnTable
+        ref="volumeRef"
+        data-key="OrderCatalogVolume"
+        url="OrderRows"
+        :columns="columns"
+        auto-load
+        :user-filter="volumeFilter"
+        order="itemFk"
+        @on-fetch="(data) => loadVolumes(data)"
+        :right-search="false"
+        :column-search="false"
+        :disable-option="{ card: true }"
+    >
+        <template #column-itemFk="{ row }">
+            <span class="link">
+                {{ row.itemFk }}
+                <ItemDescriptorProxy :id="row.itemFk" />
+            </span>
+        </template>
+        <template #column-description="{ row }">
+            <div class="row column full-width justify-between items-start">
+                {{ row?.item?.name }}
+                <div v-if="row?.item?.subName" class="subName">
+                    {{ row?.item?.subName.toUpperCase() }}
+                </div>
+            </div>
+            <FetchedTags :item="row?.item" />
+        </template>
+        <template #column-volume="{ rowIndex }">
+            {{ volumes?.[rowIndex]?.volume }}
+        </template>
+    </VnTable>
+</template>
+
+<style lang="scss">
+.order-volume-summary {
+    .vn-label-value {
+        display: flex;
+        justify-content: flex-end;
+        gap: 2%;
+
+        .label {
+            color: var(--vn-label-color);
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+        }
+
+        .value {
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+        }
+    }
+}
+
+.subName {
+    color: var(--vn-label-color);
+    text-transform: uppercase;
+}
+</style>
+<i18n>
+en:
+    summary: Summary
+    total: Total
+    boxes: Boxes
+    item: Item
+    quantity: Quantity
+    volume: m³ per quantity
+es:
+    summary: Resumen
+    total: Total
+    boxes: Cajas
+    item: Artículo
+    quantity: Cantidad
+    volume: m³ por cantidad
+</i18n>
diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue
index 945f61f3b..d96a33ef5 100644
--- a/src/pages/Order/OrderList.vue
+++ b/src/pages/Order/OrderList.vue
@@ -3,19 +3,24 @@ import axios from 'axios';
 import { useI18n } from 'vue-i18n';
 import { computed, ref } from 'vue';
 import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
-import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
 import OrderSummary from 'pages/Order/Card/OrderSummary.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import VnTable from 'src/components/VnTable/VnTable.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
+import OrderSearchbar from './Card/OrderSearchbar.vue';
+import RightMenu from 'src/components/common/RightMenu.vue';
+import OrderFilter from './Card/OrderFilter.vue';
+import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
+import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
+import { toDateTimeFormat } from 'src/filters/date';
 
 const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
 const tableRef = ref();
-const clientList = ref([]);
 const agencyList = ref([]);
-const selectedAddress = ref();
+const addressesList = ref([]);
+const clientId = ref();
 
 const columns = computed(() => [
     {
@@ -29,7 +34,7 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'clientName',
+        name: 'clientFk',
         label: t('module.customer'),
         isTitle: true,
         cardVisible: true,
@@ -41,20 +46,26 @@ const columns = computed(() => [
         columnField: {
             component: null,
         },
+        format: (row) => row?.clientName,
     },
     {
         align: 'left',
-        name: 'name',
+        name: 'salesPersonFk',
         label: t('module.salesPerson'),
-        component: 'select',
-        attrs: {
-            url: 'Workers/activeWithInheritedRole',
-            fields: ['id', 'name'],
-            where: { role: 'salesPerson' },
-        },
-        columnField: {
-            component: null,
+        columnFilter: {
+            component: 'select',
+            inWhere: true,
+            attrs: {
+                url: 'Workers/activeWithInheritedRole',
+                fields: ['id', 'name'],
+                where: { role: 'salesPerson' },
+                useLike: false,
+                optionValue: 'id',
+                optionLabel: 'name',
+                optionFilter: 'firstName',
+            },
         },
+        format: (row) => row?.name,
     },
     {
         align: 'left',
@@ -67,7 +78,7 @@ const columns = computed(() => [
         label: t('module.created'),
         component: 'date',
         cardVisible: true,
-        format: (row) => toDate(row?.landed),
+        format: (row) => toDateTimeFormat(row?.landed),
         columnField: {
             component: null,
         },
@@ -92,17 +103,22 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'agencyName',
+        name: 'agencyModeFk',
         label: t('module.agency'),
-        component: 'select',
+        format: (row) => row?.agencyName,
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'agencyModes',
+                fields: ['id', 'name'],
+                find: {
+                    value: 'agencyModeFk',
+                    label: 'agencyName',
+                },
+            },
+        },
         cardVisible: true,
-        attrs: {
-            url: 'Agencies',
-            fields: ['id', 'name'],
-        },
-        columnField: {
-            component: null,
-        },
+        columnClass: 'expand',
     },
     {
         align: 'left',
@@ -120,27 +136,52 @@ const columns = computed(() => [
                 title: t('InvoiceOutSummary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row.id, OrderSummary),
+                isPrimary: true,
             },
         ],
     },
 ]);
 
-async function fetchClientAddress(id, data) {
-    const clientData = await axios.get(`Clients/${id}`);
-    selectedAddress.value = clientData.data.defaultAddressFk;
-    data.addressId = selectedAddress.value;
+async function fetchClientAddress(id, formData) {
+    const { data } = await axios.get(`Clients/${id}`, {
+        params: { filter: { include: { relation: 'addresses' } } },
+    });
+    addressesList.value = data.addresses;
+    formData.addressId = data.defaultAddressFk;
+    fetchAgencies(formData);
 }
+
+async function fetchAgencies({ landed, addressId }) {
+    if (!landed || !addressId) return (agencyList.value = []);
+
+    const { data } = await axios.get('Agencies/landsThatDay', {
+        params: { addressFk: addressId, landed },
+    });
+    agencyList.value = data;
+}
+
+const getDateColor = (date) => {
+    const today = Date.vnNew();
+    today.setHours(0, 0, 0, 0);
+    const timeTicket = new Date(date);
+    timeTicket.setHours(0, 0, 0, 0);
+    const comparation = today - timeTicket;
+    if (comparation == 0) return 'bg-warning';
+    if (comparation < 0) return 'bg-success';
+};
 </script>
 <template>
-    <VnSearchbar
-        data-key="OrderList"
-        :label="t('Search order')"
-        :info="t('You can search orders by reference')"
-    />
+    <OrderSearchbar />
+    <RightMenu>
+        <template #right-panel>
+            <OrderFilter data-key="OrderList" />
+        </template>
+    </RightMenu>
     <VnTable
         ref="tableRef"
         data-key="OrderList"
         url="Orders/filter"
+        :order="['landed DESC', 'clientFk ASC', 'id DESC']"
         :create="{
             urlCreate: 'Orders/new',
             title: 'Create Order',
@@ -152,36 +193,68 @@ async function fetchClientAddress(id, data) {
                 addressId: null,
             },
         }"
+        :user-params="{ showEmpty: false }"
+        :right-search="false"
         :columns="columns"
         redirect="order"
-        auto-load
     >
+        <template #column-clientFk="{ row }">
+            <span class="link" @click.stop>
+                {{ row?.clientName }}
+                <CustomerDescriptorProxy :id="row?.clientFk" />
+            </span>
+        </template>
+        <template #column-salesPersonFk="{ row }">
+            <span class="link" @click.stop>
+                {{ row?.name }}
+                <WorkerDescriptorProxy :id="row?.salesPersonFk" />
+            </span>
+        </template>
+        <template #column-landed="{ row }">
+            <span v-if="getDateColor(row.landed)">
+                <QChip :class="getDateColor(row.landed)" dense square>
+                    {{ toDate(row?.landed) }}
+                </QChip>
+            </span>
+        </template>
         <template #more-create-dialog="{ data }">
             <VnSelect
                 url="Clients"
-                v-model="data.id"
+                :include="{ relation: 'addresses' }"
+                v-model="clientId"
                 :label="t('module.customer')"
-                :options="clientList"
-                option-value="id"
-                option-label="name"
                 @update:model-value="(id) => fetchClientAddress(id, data)"
             />
             <VnSelect
-                url="Clients"
-                v-model="selectedAddress"
+                v-model="data.addressId"
+                :options="addressesList"
                 :label="t('module.address')"
-                :options="selectedAddress"
-                option-value="defaultAddressFk"
-                option-label="street"
+                option-value="id"
+                option-label="nickname"
+                @update:model-value="() => fetchAgencies(data)"
+            >
+                <template #option="scope">
+                    <QItem v-bind="scope.itemProps">
+                        <QItemSection>
+                            <QItemLabel>
+                                {{ scope.opt?.nickname }}: {{ scope.opt?.street }},
+                                {{ scope.opt?.city }}</QItemLabel
+                            >
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
+            <VnInputDate
+                v-model="data.landed"
+                :label="t('module.landed')"
+                @update:model-value="() => fetchAgencies(data)"
             />
-            <VnInputDate v-model="data.landed" :label="t('module.landed')" />
             <VnSelect
-                url="Agencies"
                 v-model="data.agencyModeId"
                 :label="t('module.agency')"
                 :options="agencyList"
-                option-value="id"
-                option-label="name"
+                option-value="agencyModeFk"
+                option-label="agencyMode"
             />
         </template>
     </VnTable>
diff --git a/src/pages/Order/OrderVolume.vue b/src/pages/Order/OrderVolume.vue
deleted file mode 100644
index 35d68de16..000000000
--- a/src/pages/Order/OrderVolume.vue
+++ /dev/null
@@ -1,156 +0,0 @@
-<script setup>
-import { useRoute } from 'vue-router';
-import { useI18n } from 'vue-i18n';
-import { ref } from 'vue';
-
-import VnPaginate from 'components/ui/VnPaginate.vue';
-import FetchData from 'components/FetchData.vue';
-import VnLv from 'components/ui/VnLv.vue';
-import CardList from 'components/ui/CardList.vue';
-import FetchedTags from 'components/ui/FetchedTags.vue';
-
-import { dashIfEmpty } from 'src/filters';
-import axios from 'axios';
-
-const route = useRoute();
-const { t } = useI18n();
-const volumeSummary = ref(null);
-
-const loadVolumes = async (rows) => {
-    const { data } = await axios.get(`Orders/${route.params.id}/getVolumes`);
-    (rows || []).forEach((order) => {
-        (data.volumes || []).forEach((volume) => {
-            if (order.itemFk === volume.itemFk) {
-                order.volume = volume.volume;
-            }
-        });
-    });
-};
-</script>
-
-<template>
-    <FetchData
-        :url="`Orders/${route.params.id}/getTotalVolume`"
-        @on-fetch="(data) => (volumeSummary = data)"
-        auto-load
-    />
-    <QPage class="column items-center q-pa-md">
-        <div class="vn-card-list">
-            <div
-                v-if="!volumeSummary?.totalVolume && !volumeSummary?.totalBoxes"
-                class="no-result"
-            >
-                {{ t('globals.noResults') }}
-            </div>
-            <QCard v-else class="order-volume-summary q-pa-lg">
-                <p class="header text-right block">
-                    {{ t('summary') }}
-                </p>
-                <VnLv :label="t('total')" :value="`${volumeSummary?.totalVolume} m³`" />
-                <VnLv
-                    :label="t('boxes')"
-                    :value="`${dashIfEmpty(volumeSummary?.totalBoxes)} U`"
-                />
-            </QCard>
-            <VnPaginate
-                data-key="OrderCatalogVolume"
-                url="OrderRows"
-                :limit="20"
-                auto-load
-                :filter="{
-                    include: {
-                        relation: 'item',
-                    },
-                    where: { orderFk: route.params.id },
-                }"
-                order="itemFk"
-                @on-fetch="(data) => loadVolumes(data)"
-            >
-                <template #body="{ rows }">
-                    <div class="catalog-list q-mt-xl">
-                        <CardList
-                            v-for="row in rows"
-                            :key="row.id"
-                            :id="row.id"
-                            :title="row?.item?.name"
-                            class="cursor-inherit"
-                        >
-                            <template #list-items>
-                                <div class="q-mb-sm">
-                                    <FetchedTags :item="row.item" :max-length="5" />
-                                </div>
-                                <VnLv :label="t('item')" :value="row.item.id" />
-                                <VnLv :label="t('subName')">
-                                    <template #value>
-                                        <span class="text-uppercase">
-                                            {{ row.item.subName }}
-                                        </span>
-                                    </template>
-                                </VnLv>
-                                <VnLv :label="t('quantity')" :value="row.quantity" />
-                                <VnLv :label="t('volume')" :value="row.volume" />
-                            </template>
-                        </CardList>
-                    </div>
-                </template>
-            </VnPaginate>
-        </div>
-    </QPage>
-</template>
-
-<style lang="scss">
-.order-volume-summary {
-    .vn-label-value {
-        display: flex;
-        justify-content: flex-end;
-        gap: 2%;
-
-        .label {
-            color: var(--vn-label-color);
-            overflow: hidden;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-        }
-
-        .value {
-            overflow: hidden;
-            text-overflow: ellipsis;
-            white-space: nowrap;
-        }
-    }
-}
-</style>
-<style lang="scss" scoped>
-.header {
-    color: $primary;
-    font-weight: bold;
-    margin-bottom: 25px;
-    font-size: 20px;
-    display: inline-block;
-}
-
-.no-result {
-    font-size: 24px;
-    font-weight: bold;
-    color: var(--vn-label-color);
-    text-align: center;
-}
-</style>
-<i18n>
-en:
-    summary: Summary
-    total: Total
-    boxes: Boxes
-    item: Item
-    subName: Subname
-    quantity: Quantity
-    volume: m³ per quantity
-es:
-    summary: Resumen
-    total: Total
-    boxes: Cajas
-    item: Artículo
-    subName: Subname
-    quantity: Cantidad
-    volume: m³ por cantidad
-</i18n>
diff --git a/src/pages/Route/Card/RouteSummary.vue b/src/pages/Route/Card/RouteSummary.vue
index d7a02833e..3f9b1a2a9 100644
--- a/src/pages/Route/Card/RouteSummary.vue
+++ b/src/pages/Route/Card/RouteSummary.vue
@@ -217,7 +217,7 @@ const ticketColumns = ref([
                         <template #body-cell-city="{ value, row }">
                             <QTd auto-width>
                                 <span
-                                    class="text-primary cursor-pointer"
+                                    class="link cursor-pointer"
                                     @click="openBuscaman(entity?.route?.vehicleFk, [row])"
                                 >
                                     {{ value }}
@@ -226,7 +226,7 @@ const ticketColumns = ref([
                         </template>
                         <template #body-cell-client="{ value, row }">
                             <QTd auto-width>
-                                <span class="text-primary cursor-pointer">
+                                <span class="link cursor-pointer">
                                     {{ value }}
                                     <CustomerDescriptorProxy :id="row?.clientFk" />
                                 </span>
@@ -234,7 +234,7 @@ const ticketColumns = ref([
                         </template>
                         <template #body-cell-ticket="{ value, row }">
                             <QTd auto-width class="text-center">
-                                <span class="text-primary cursor-pointer">
+                                <span class="link cursor-pointer">
                                     {{ value }}
                                     <TicketDescriptorProxy :id="row?.id" />
                                 </span>
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index e24ed33ed..1e20df99c 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -17,7 +17,9 @@ import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import VnTable from 'components/VnTable/VnTable.vue';
+import { usePrintService } from 'src/composables/usePrintService';
 
+const { openReport } = usePrintService();
 const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
 const quasar = useQuasar();
@@ -87,6 +89,7 @@ const columns = computed(() => [
                 label: 'agencyName',
             },
         },
+        columnClass: 'expand',
     },
     {
         align: 'left',
@@ -142,17 +145,9 @@ const columns = computed(() => [
     {
         align: 'center',
         name: 'm3',
-        label: 'volume',
+        label: t('Volume'),
         cardVisible: true,
-    },
-    {
-        align: 'left',
-        name: 'description',
-        label: t('Description'),
-        isTitle: true,
-        create: true,
-        component: 'input',
-        field: 'description',
+        columnClass: 'shrink',
     },
     {
         align: 'left',
@@ -168,12 +163,38 @@ const columns = computed(() => [
         component: 'time',
         columnFilter: false,
     },
+    {
+        align: 'center',
+        name: 'kmStart',
+        label: t('KmStart'),
+        columnClass: 'shrink',
+        create: true,
+        visible: false,
+    },
+    {
+        align: 'center',
+        name: 'kmEnd',
+        label: t('KmEnd'),
+        columnClass: 'shrink',
+        create: true,
+        visible: false,
+    },
+    {
+        align: 'left',
+        name: 'description',
+        label: t('Description'),
+        isTitle: true,
+        create: true,
+        component: 'input',
+        field: 'description',
+    },
     {
         align: 'left',
         name: 'isOk',
         label: t('Served'),
         component: 'checkbox',
         columnFilter: false,
+        columnClass: 'shrink',
     },
     {
         align: 'right',
@@ -185,7 +206,7 @@ const columns = computed(() => [
                 action: (row) => openTicketsDialog(row?.id),
             },
             {
-                title: t('Preview'),
+                title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row?.id, RouteSummary),
             },
@@ -216,18 +237,15 @@ const cloneRoutes = () => {
 const showRouteReport = () => {
     const ids = selectedRows.value.map((row) => row?.id);
     const idString = ids.join(',');
-    let url;
-
-    if (selectedRows.value.length <= 1) {
-        url = `api/Routes/${idString}/driver-route-pdf?access_token=${session.getTokenMultimedia()}`;
-    } else {
-        const params = new URLSearchParams({
-            access_token: session.getTokenMultimedia(),
+    let url = `Routes/${idString}/driver-route-pdf`;
+    let params = {};
+    if (selectedRows.value.length >= 1) {
+        params = {
             id: idString,
-        });
-        url = `api/Routes/downloadZip?${params.toString()}`;
+        };
+        url = `Routes/downloadZip`;
     }
-    window.open(url, '_blank');
+    openReport(url, params, '_blank');
 };
 
 function markAsServed() {
@@ -368,10 +386,13 @@ es:
     Worker: Trabajador
     Agency: Agencia
     Vehicle: Vehículo
+    Volume: Volumen
     Date: Fecha
     Description: Descripción
     Hour started: Hora inicio
     Hour finished: Hora fin
+    KmStart: Km inicio
+    KmEnd: Km fin
     Served: Servida
     newRoute: Nueva Ruta
     Clone Selected Routes: Clonar rutas seleccionadas
diff --git a/src/pages/Shelving/Card/ShelvingFilter.vue b/src/pages/Shelving/Card/ShelvingFilter.vue
index abc91373b..0056ffaec 100644
--- a/src/pages/Shelving/Card/ShelvingFilter.vue
+++ b/src/pages/Shelving/Card/ShelvingFilter.vue
@@ -3,6 +3,7 @@ import { ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import FetchData from 'components/FetchData.vue';
 import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
 
 const { t } = useI18n();
 const props = defineProps({
@@ -15,25 +16,13 @@ const props = defineProps({
 const emit = defineEmits(['search']);
 
 const workers = ref();
-const parkings = ref();
 
 function setWorkers(data) {
     workers.value = data;
 }
-
-function setParkings(data) {
-    parkings.value = data;
-}
 </script>
 
 <template>
-    <FetchData
-        url="Parkings"
-        :filter="{ fields: ['id', 'code'] }"
-        sort-by="code ASC"
-        @on-fetch="setParkings"
-        auto-load
-    />
     <FetchData
         url="Workers/activeWithInheritedRole"
         :filter="{ where: { role: 'salesPerson' } }"
@@ -54,44 +43,36 @@ function setParkings(data) {
         </template>
         <template #body="{ params }">
             <QItem class="q-my-sm">
-                <QItemSection v-if="!parkings">
-                    <QSkeleton type="QInput" class="full-width" />
-                </QItemSection>
-                <QItemSection v-if="parkings">
-                    <QSelect
+                <QItemSection>
+                    <VnSelect
+                        v-model="params.parkingFk"
+                        url="Parkings"
+                        :fields="['id', 'code']"
+                        :label="t('params.parkingFk')"
+                        option-value="id"
+                        option-label="code"
+                        :filter-options="['id', 'code']"
                         dense
                         outlined
                         rounded
-                        :label="t('params.parkingFk')"
-                        v-model="params.parkingFk"
-                        :options="parkings"
-                        option-value="id"
-                        option-label="code"
-                        emit-value
-                        map-options
-                        use-input
-                        :input-debounce="0"
+                        sort-by="code ASC"
                     />
                 </QItemSection>
             </QItem>
             <QItem class="q-mb-sm">
-                <QItemSection v-if="!workers">
-                    <QSkeleton type="QInput" class="full-width" />
-                </QItemSection>
-                <QItemSection v-if="workers">
-                    <QSelect
+                <QItemSection>
+                    <VnSelect
                         dense
                         outlined
                         rounded
                         :label="t('params.userFk')"
                         v-model="params.userFk"
-                        :options="workers"
+                        url="Workers/activeWithInheritedRole"
                         option-value="id"
-                        option-label="name"
-                        emit-value
-                        map-options
-                        use-input
-                        :input-debounce="0"
+                        option-label="firstName"
+                        :where="{ role: 'salesPerson' }"
+                        sort-by="firstName ASC"
+                        :use-like="false"
                     />
                 </QItemSection>
             </QItem>
diff --git a/src/pages/Shelving/Card/ShelvingForm.vue b/src/pages/Shelving/Card/ShelvingForm.vue
index dd1c4e4a2..dc0234c22 100644
--- a/src/pages/Shelving/Card/ShelvingForm.vue
+++ b/src/pages/Shelving/Card/ShelvingForm.vue
@@ -1,18 +1,18 @@
 <script setup>
 import { useI18n } from 'vue-i18n';
-import { ref } from 'vue';
+import { computed } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import VnRow from 'components/ui/VnRow.vue';
-import FetchData from 'components/FetchData.vue';
 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';
 
 const { t } = useI18n();
 const route = useRoute();
 const router = useRouter();
-const shelvingId = route.params?.id || null;
-const isNew = Boolean(!shelvingId);
+const entityId = computed(() => route.params.id ?? null);
+const isNew = Boolean(!entityId.value);
 const defaultInitialData = {
     parkingFk: null,
     priority: null,
@@ -20,30 +20,6 @@ const defaultInitialData = {
     isRecyclable: false,
 };
 
-const parkingFilter = { fields: ['id', 'code'] };
-const parkingList = ref([]);
-const parkingListCopy = ref([]);
-
-const setParkingList = (data) => {
-    parkingList.value = data;
-    parkingListCopy.value = data;
-};
-
-const parkingSelectFilter = {
-    options: parkingList,
-    filterFn: (options, value) => {
-        const search = value.trim().toLowerCase();
-
-        if (!search || search === '') {
-            return parkingListCopy.value;
-        }
-
-        return options.value.filter((option) =>
-            option.code.toLowerCase().startsWith(search)
-        );
-    },
-};
-
 const shelvingFilter = {
     include: [
         {
@@ -67,44 +43,33 @@ const onSave = (shelving, newShelving) => {
 };
 </script>
 <template>
-    <VnSubToolbar />
-    <FetchData
-        url="Parkings"
-        :filter="parkingFilter"
-        @on-fetch="setParkingList"
-        auto-load
-    />
+    <VnSubToolbar v-if="isNew" />
     <FormModel
-        :url="isNew ? null : `Shelvings/${shelvingId}`"
+        :url="isNew ? null : `Shelvings/${entityId}`"
         :url-create="isNew ? 'Shelvings' : null"
         :observe-form-changes="!isNew"
         :filter="shelvingFilter"
         model="shelving"
         :auto-load="!isNew"
-        :form-initial-data="defaultInitialData"
+        :form-initial-data="isNew ? defaultInitialData : null"
         @on-data-saved="onSave"
     >
-        <template #form="{ data, validate, filter }">
+        <template #form="{ data, validate }">
             <VnRow>
                 <VnInput
                     v-model="data.code"
                     :label="t('shelving.basicData.code')"
                     :rules="validate('Shelving.code')"
                 />
-                <QSelect
+                <VnSelect
                     v-model="data.parkingFk"
-                    :options="parkingList"
+                    url="Parkings"
                     option-value="id"
                     option-label="code"
-                    emit-value
+                    :filter-options="['id', 'code']"
+                    :fields="['id', 'code']"
                     :label="t('shelving.basicData.parking')"
-                    map-options
-                    use-input
-                    @filter="
-                        (value, update) => filter(value, update, parkingSelectFilter)
-                    "
                     :rules="validate('Shelving.parkingFk')"
-                    :input-debounce="0"
                 />
             </VnRow>
             <VnRow>
diff --git a/src/pages/Shelving/ShelvingList.vue b/src/pages/Shelving/ShelvingList.vue
index 3f16f8ef7..d29f6ff15 100644
--- a/src/pages/Shelving/ShelvingList.vue
+++ b/src/pages/Shelving/ShelvingList.vue
@@ -87,7 +87,7 @@ function exprBuilder(param, value) {
         </div>
         <QPageSticky :offset="[20, 20]">
             <RouterLink :to="{ name: 'ShelvingCreate' }">
-                <QBtn fab icon="add" color="primary" />
+                <QBtn fab icon="add" color="primary" shortcut="+" />
                 <QTooltip>
                     {{ t('shelving.list.newShelving') }}
                 </QTooltip>
diff --git a/src/pages/Supplier/Card/SupplierAddresses.vue b/src/pages/Supplier/Card/SupplierAddresses.vue
index 4b2174d0b..f46a3be19 100644
--- a/src/pages/Supplier/Card/SupplierAddresses.vue
+++ b/src/pages/Supplier/Card/SupplierAddresses.vue
@@ -87,7 +87,13 @@ const redirectToUpdateView = (addressData) => {
             </VnPaginate>
         </div>
         <QPageSticky :offset="[20, 20]">
-            <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" />
+            <QBtn
+                fab
+                icon="add"
+                color="primary"
+                @click="redirectToCreateView()"
+                shortcut="+"
+            />
             <QTooltip>
                 {{ t('New address') }}
             </QTooltip>
@@ -99,3 +105,4 @@ const redirectToUpdateView = (addressData) => {
 es:
     New address: Nueva dirección
 </i18n>
+s
diff --git a/src/pages/Supplier/Card/SupplierAddressesCreate.vue b/src/pages/Supplier/Card/SupplierAddressesCreate.vue
index df98b6091..290373039 100644
--- a/src/pages/Supplier/Card/SupplierAddressesCreate.vue
+++ b/src/pages/Supplier/Card/SupplierAddressesCreate.vue
@@ -84,7 +84,7 @@ function handleLocation(data, location) {
                 <VnRow>
                     <VnLocation
                         :rules="validate('Worker.postcode')"
-                        :roles-allowed-to-create="['deliveryAssistant']"
+                        :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
                         :location="
                             data.postalCode
                                 ? {
diff --git a/src/pages/Supplier/Card/SupplierAgencyTerm.vue b/src/pages/Supplier/Card/SupplierAgencyTerm.vue
index 26a410e8c..99b672cc4 100644
--- a/src/pages/Supplier/Card/SupplierAgencyTerm.vue
+++ b/src/pages/Supplier/Card/SupplierAgencyTerm.vue
@@ -109,7 +109,13 @@ const redirectToCreateView = () => {
         </template>
     </CrudModel>
     <QPageSticky :offset="[20, 20]">
-        <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" />
+        <QBtn
+            fab
+            icon="add"
+            color="primary"
+            @click="redirectToCreateView()"
+            shortcut="+"
+        />
         <QTooltip>
             {{ t('supplier.agencyTerms.addRow') }}
         </QTooltip>
diff --git a/src/pages/Supplier/Card/SupplierConsumption.vue b/src/pages/Supplier/Card/SupplierConsumption.vue
index 100a38b2a..8fa6a1e5c 100644
--- a/src/pages/Supplier/Card/SupplierConsumption.vue
+++ b/src/pages/Supplier/Card/SupplierConsumption.vue
@@ -208,7 +208,7 @@ onMounted(async () => {
 
                     <QTd no-hover>
                         <span>{{ buy.subName }}</span>
-                        <FetchedTags :item="buy" :max-length="5" />
+                        <FetchedTags :item="buy" />
                     </QTd>
                     <QTd no-hover> {{ dashIfEmpty(buy.quantity) }}</QTd>
                     <QTd no-hover> {{ dashIfEmpty(buy.price) }}</QTd>
diff --git a/src/pages/Supplier/Card/SupplierConsumptionFilter.vue b/src/pages/Supplier/Card/SupplierConsumptionFilter.vue
index 3fc61b15e..401bde8fa 100644
--- a/src/pages/Supplier/Card/SupplierConsumptionFilter.vue
+++ b/src/pages/Supplier/Card/SupplierConsumptionFilter.vue
@@ -1,56 +1,21 @@
 <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';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 
 const { t } = useI18n();
-const props = defineProps({
+defineProps({
     dataKey: {
         type: String,
         required: true,
     },
 });
-
-const buyersOptions = ref([]);
-const itemTypesOptions = ref([]);
-const itemCategoriesOptions = ref([]);
 </script>
 
 <template>
-    <FetchData
-        url="TicketRequests/getItemTypeWorker"
-        :filter="{
-            fields: ['id', 'nickname'],
-            order: 'nickname ASC',
-        }"
-        @on-fetch="(data) => (buyersOptions = data)"
-        auto-load
-    />
-    <FetchData
-        url="ItemTypes"
-        :filter="{
-            fields: ['id', 'name', 'categoryFk'],
-            include: 'category',
-            order: 'name ASC',
-        }"
-        @on-fetch="(data) => (itemTypesOptions = data)"
-        auto-load
-    />
-    <FetchData
-        url="ItemCategories"
-        :filter="{
-            fields: ['id', 'name'],
-            order: 'name ASC',
-        }"
-        @on-fetch="(data) => (itemCategoriesOptions = data)"
-        auto-load
-    />
-    <VnFilterPanel :data-key="props.dataKey" :search-button="true" :redirect="false">
+    <VnFilterPanel :data-key="dataKey" :search-button="true" :redirect="false">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
                 <strong>{{ t(`params.${tag.label}`) }}: </strong>
@@ -82,7 +47,9 @@ const itemCategoriesOptions = ref([]);
                         :label="t('params.buyerId')"
                         v-model="params.buyerId"
                         @update:model-value="searchFn()"
-                        :options="buyersOptions"
+                        url="TicketRequests/getItemTypeWorker"
+                        :fields="['id', 'nickname']"
+                        sort-by="nickname ASC"
                         option-value="id"
                         option-label="nickname"
                         hide-selected
@@ -98,7 +65,10 @@ const itemCategoriesOptions = ref([]);
                         :label="t('params.typeId')"
                         v-model="params.typeId"
                         @update:model-value="searchFn()"
-                        :options="itemTypesOptions"
+                        url="ItemTypes"
+                        :include="['category']"
+                        :fields="['id', 'name', 'categoryFk']"
+                        sort-by="name ASC"
                         option-value="id"
                         option-label="name"
                         hide-selected
@@ -125,7 +95,9 @@ const itemCategoriesOptions = ref([]);
                         :label="t('params.categoryId')"
                         v-model="params.categoryId"
                         @update:model-value="searchFn()"
-                        :options="itemCategoriesOptions"
+                        url="ItemCategories"
+                        :fields="['id', 'name']"
+                        sort-by="name ASC"
                         option-value="id"
                         option-label="name"
                         hide-selected
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index c2cb42c6a..60cd6770b 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -146,7 +146,7 @@ function handleLocation(data, location) {
             <VnRow>
                 <VnLocation
                     :rules="validate('Worker.postcode')"
-                    :roles-allowed-to-create="['deliveryAssistant']"
+                    :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
                     :location="{
                         postcode: data.postCode,
                         city: data.city,
diff --git a/src/pages/Supplier/Card/SupplierSummary.vue b/src/pages/Supplier/Card/SupplierSummary.vue
index 822586b47..5791db1eb 100644
--- a/src/pages/Supplier/Card/SupplierSummary.vue
+++ b/src/pages/Supplier/Card/SupplierSummary.vue
@@ -4,13 +4,11 @@ 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 { useRole } from 'src/composables/useRole';
 import { dashIfEmpty } from 'src/filters';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import VnTitle from 'src/components/common/VnTitle.vue';
 
 const route = useRoute();
-const roleState = useRole();
 const { t } = useI18n();
 
 const $props = defineProps({
@@ -32,13 +30,7 @@ async function setData(data) {
     }
 }
 
-const isAdministrative = computed(() => {
-    return roleState.hasAny(['administrative']);
-});
-
-function getUrl(section) {
-    return isAdministrative.value && `#/supplier/${entityId.value}/${section}`;
-}
+const getUrl = (section) => `#/supplier/${entityId.value}/${section}`;
 </script>
 
 <template>
diff --git a/src/pages/Ticket/Card/BasicData/BasicDataTable.vue b/src/pages/Ticket/Card/BasicData/BasicDataTable.vue
index 48b8c882f..7f2f100ad 100644
--- a/src/pages/Ticket/Card/BasicData/BasicDataTable.vue
+++ b/src/pages/Ticket/Card/BasicData/BasicDataTable.vue
@@ -245,7 +245,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                 <div class="column">
                     <span>{{ row.item.name }}</span>
                     <span class="color-vn-label">{{ row.item.subName }}</span>
-                    <FetchedTags :item="row.item" :max-length="6" />
+                    <FetchedTags :item="row.item" />
                 </div>
             </QTd>
         </template>
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
index 2d937346a..28c6fcf15 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
@@ -30,7 +30,6 @@ const { t } = useI18n();
 const agencyFetchRef = ref(null);
 const zonesFetchRef = ref(null);
 
-const clientsOptions = ref([]);
 const warehousesOptions = ref([]);
 const companiesOptions = ref([]);
 const agenciesOptions = ref([]);
@@ -273,15 +272,6 @@ const redirectToCustomerAddress = () => {
 onMounted(() => onFormModelInit());
 </script>
 <template>
-    <FetchData
-        url="Clients"
-        :filter="{
-            fields: ['id', 'name'],
-            order: 'id',
-        }"
-        @on-fetch="(data) => (clientsOptions = data)"
-        auto-load
-    />
     <FetchData
         url="Warehouses"
         @on-fetch="(data) => (warehousesOptions = data)"
@@ -317,7 +307,9 @@ onMounted(() => onFormModelInit());
                 v-model="clientId"
                 option-value="id"
                 option-label="name"
-                :options="clientsOptions"
+                url="Clients"
+                :fields="['id', 'name']"
+                sort-by="id"
                 hide-selected
                 map-options
                 :required="true"
diff --git a/src/pages/Ticket/Card/TicketCard.vue b/src/pages/Ticket/Card/TicketCard.vue
index cf15cb7fa..73b6f5543 100644
--- a/src/pages/Ticket/Card/TicketCard.vue
+++ b/src/pages/Ticket/Card/TicketCard.vue
@@ -1,17 +1,11 @@
 <script setup>
 import { useI18n } from 'vue-i18n';
-import { useRoute } from 'vue-router';
-import { computed } from 'vue';
 
 import VnCard from 'components/common/VnCard.vue';
 import TicketDescriptor from './TicketDescriptor.vue';
 import TicketFilter from '../TicketFilter.vue';
 
 const { t } = useI18n();
-const route = useRoute();
-
-const routeName = computed(() => route.name);
-const customRouteRedirectName = computed(() => routeName.value);
 </script>
 <template>
     <VnCard
@@ -21,7 +15,7 @@ const customRouteRedirectName = computed(() => routeName.value);
         :descriptor="TicketDescriptor"
         search-data-key="TicketList"
         :searchbar-props="{
-            customRouteRedirectName,
+            url: 'Tickets/filter',
             label: t('card.search'),
             info: t('card.searchInfo'),
         }"
diff --git a/src/pages/Ticket/Card/TicketComponents.vue b/src/pages/Ticket/Card/TicketComponents.vue
index 3954b5a62..6131c92db 100644
--- a/src/pages/Ticket/Card/TicketComponents.vue
+++ b/src/pages/Ticket/Card/TicketComponents.vue
@@ -310,7 +310,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                 <div class="column">
                     <span>{{ row.item.name }}</span>
                     <span class="color-vn-label">{{ row.item.subName }}</span>
-                    <FetchedTags :item="row.item" :max-length="6" />
+                    <FetchedTags :item="row.item" />
                 </div>
             </QTd>
         </template>
diff --git a/src/pages/Ticket/Card/TicketCreateTracking.vue b/src/pages/Ticket/Card/TicketCreateTracking.vue
index 87ca8dd3f..d692f550d 100644
--- a/src/pages/Ticket/Card/TicketCreateTracking.vue
+++ b/src/pages/Ticket/Card/TicketCreateTracking.vue
@@ -17,9 +17,7 @@ const { t } = useI18n();
 const state = useState();
 const user = state.getUser();
 const stateFetchDataRef = ref(null);
-
 const statesOptions = ref([]);
-const workersOptions = ref([]);
 
 const onStateFkChange = (formData) => (formData.userFk = user.value.id);
 </script>
@@ -30,12 +28,6 @@ const onStateFkChange = (formData) => (formData.userFk = user.value.id);
         auto-load
         @on-fetch="(data) => (statesOptions = data)"
     />
-    <FetchData
-        url="Workers/search"
-        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
-        auto-load
-        @on-fetch="(data) => (workersOptions = data)"
-    />
     <FormModelPopup
         :title="t('Create tracking')"
         url-create="Tickets/state"
@@ -57,7 +49,9 @@ const onStateFkChange = (formData) => (formData.userFk = user.value.id);
                 <VnSelect
                     :label="t('tracking.worker')"
                     v-model="data.userFk"
-                    :options="workersOptions"
+                    url="Workers/search"
+                    fields=" ['id', 'name']"
+                    sort-by="name ASC"
                     hide-selected
                     option-label="name"
                     option-value="id"
diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
index c7784bc2a..4cf4e633f 100644
--- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue
+++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
@@ -9,6 +9,8 @@ import SendEmailDialog from 'components/common/SendEmailDialog.vue';
 import VnConfirm from 'components/ui/VnConfirm.vue';
 import VnSmsDialog from 'components/common/VnSmsDialog.vue';
 import toDate from 'filters/toDate';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
+import { useArrayData } from 'src/composables/useArrayData';
 
 const props = defineProps({
     ticket: {
@@ -21,19 +23,22 @@ const { push, currentRoute } = useRouter();
 const { dialog, notify } = useQuasar();
 const { t } = useI18n();
 const { openReport, sendEmail } = usePrintService();
-
+const ticketSummary = useArrayData('TicketSummary');
 const ticket = ref(props.ticket);
 const ticketId = currentRoute.value.params.id;
+const weight = ref();
 const actions = {
     clone: async () => {
         const opts = { message: t('Ticket cloned'), type: 'positive' };
         let clonedTicketId;
 
         try {
-            const { data } = await axios.post(`Tickets/${ticketId}/clone`, {
-                shipped: ticket.value.shipped,
+            const { data } = await axios.post(`Tickets/cloneAll`, {
+                ticketsIds: [ticket.value.id],
+                withWarehouse: true,
+                negative: false,
             });
-            clonedTicketId = data;
+            clonedTicketId = data[0].id;
         } catch (e) {
             opts.message = t('It was not able to clone the ticket');
             opts.type = 'negative';
@@ -44,6 +49,25 @@ const actions = {
                 push({ name: 'TicketSummary', params: { id: clonedTicketId } });
         }
     },
+    setWeight: async () => {
+        try {
+            const invoiceIds = (
+                await axios.post(`Tickets/${ticketId}/setWeight`, {
+                    weight: weight.value,
+                })
+            ).data;
+
+            notify({ message: t('Weight set'), type: 'positive' });
+            if (invoiceIds.length)
+                notify({
+                    message: t('invoiceIds', { invoiceIds: invoiceIds.join() }),
+                    type: 'positive',
+                });
+            await ticketSummary.fetch({ updateRouter: false });
+        } catch (e) {
+            notify({ message: e.message, type: 'negative' });
+        }
+    },
     remove: async () => {
         try {
             await axios.post(`Tickets/${ticketId}/setDeleted`);
@@ -253,6 +277,12 @@ function openConfirmDialog(callback) {
         </QItemSection>
         <QItemSection>{{ t('To clone ticket') }}</QItemSection>
     </QItem>
+    <QItem @click="$refs.weightDialog.show()" v-ripple clickable>
+        <QItemSection avatar>
+            <QIcon name="weight" />
+        </QItemSection>
+        <QItemSection>{{ t('Set weight') }}</QItemSection>
+    </QItem>
     <template v-if="!ticket.isDeleted">
         <QSeparator />
         <QItem @click="openConfirmDialog('remove')" v-ripple clickable>
@@ -262,9 +292,25 @@ function openConfirmDialog(callback) {
             <QItemSection>{{ t('Delete ticket') }}</QItemSection>
         </QItem>
     </template>
+    <VnConfirm
+        ref="weightDialog"
+        :title="t('Set weight')"
+        :message="t('This ticket may be invoiced, do you want to continue?')"
+        :promise="actions.setWeight"
+    >
+        <template #customHTML>
+            <VnInputNumber
+                :label="t('globals.weight')"
+                v-model="weight"
+                class="full-width"
+            />
+        </template>
+    </VnConfirm>
 </template>
-
 <i18n>
+en:
+    invoiceIds: "Invoices have been generated with the following ids: {invoiceIds}"
+
 es:
     Open Delivery Note...: Abrir albarán...
     Send Delivery Note...: Enviar albarán...
@@ -282,4 +328,8 @@ es:
     To clone ticket: Clonar ticket
     Ticket cloned: Ticked clonado
     It was not able to clone the ticket: No se pudo clonar el ticket
+    Set weight: Establecer peso
+    Weight set: Peso establecido
+    This ticket may be invoiced, do you want to continue?: Es posible que se facture este ticket, desea continuar?
+    invoiceIds: "Se han generado las facturas con los siguientes ids: {invoiceIds}"
 </i18n>
diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue
index a7eb9e27e..c4ab63b39 100644
--- a/src/pages/Ticket/Card/TicketExpedition.vue
+++ b/src/pages/Ticket/Card/TicketExpedition.vue
@@ -3,7 +3,6 @@ import { onMounted, ref, computed, onUnmounted, reactive, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
-import FetchData from 'components/FetchData.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
 import TicketEditManaProxy from './TicketEditMana.vue';
@@ -35,7 +34,6 @@ const selectedExpeditions = ref([]);
 const allColumnNames = ref([]);
 const visibleColumns = ref([]);
 const newTicketWithRoute = ref(false);
-const itemsOptions = ref([]);
 
 const exprBuilder = (param, value) => {
     switch (param) {
@@ -139,7 +137,9 @@ const columns = computed(() => [
             filterValue: null,
             event: getInputEvents,
             attrs: {
-                options: itemsOptions.value,
+                url: 'Items',
+                fields: ['id', 'name'],
+                'sort-by': 'name ASC',
                 'option-value': 'id',
                 'option-label': 'name',
                 dense: true,
@@ -268,19 +268,12 @@ onMounted(async () => {
     stateStore.rightDrawer = true;
     const filteredColumns = columns.value.filter((col) => col.name !== 'history');
     allColumnNames.value = filteredColumns.map((col) => col.name);
-    // await expeditionsArrayData.fetch({ append: false });
 });
 
 onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
-    <FetchData
-        url="Items"
-        auto-load
-        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
-        @on-fetch="(data) => (itemsOptions = data)"
-    />
     <VnSubToolbar>
         <template #st-data>
             <TableVisibleColumns
diff --git a/src/pages/Ticket/Card/TicketPurchaseRequest.vue b/src/pages/Ticket/Card/TicketPurchaseRequest.vue
index 281dc46a1..8d84e2b46 100644
--- a/src/pages/Ticket/Card/TicketPurchaseRequest.vue
+++ b/src/pages/Ticket/Card/TicketPurchaseRequest.vue
@@ -252,7 +252,13 @@ const openCreateModal = () => createTicketRequestDialogRef.value.show();
             <TicketCreateRequest @on-request-created="crudModelRef.reload()" />
         </QDialog>
         <QPageSticky :offset="[20, 20]">
-            <QBtn @click="openCreateModal()" color="primary" fab icon="add" />
+            <QBtn
+                @click="openCreateModal()"
+                color="primary"
+                fab
+                icon="add"
+                shortcut="+"
+            />
             <QTooltip class="text-no-wrap">
                 {{ t('purchaseRequest.newRequest') }}
             </QTooltip>
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index cbc94b388..2ea12bb05 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -11,7 +11,6 @@ import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
 import TicketEditManaProxy from './TicketEditMana.vue';
 import VnImg from 'src/components/ui/VnImg.vue';
 
-import RightMenu from 'src/components/common/RightMenu.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
 import TicketTransfer from './TicketTransfer.vue';
@@ -39,7 +38,6 @@ const ticketConfig = ref(null);
 const isLocked = ref(false);
 const isTicketEditable = ref(false);
 const sales = ref([]);
-const itemsWithNameOptions = ref([]);
 const editableStatesOptions = ref([]);
 const selectedSales = ref([]);
 const mana = ref(null);
@@ -436,12 +434,6 @@ onUnmounted(() => (stateStore.rightDrawer = false));
         auto-load
         @on-fetch="(data) => (isLocked = data)"
     />
-    <FetchData
-        url="Items/withName"
-        :filter="{ fields: ['id', 'name'], order: 'id DESC' }"
-        auto-load
-        @on-fetch="(data) => (itemsWithNameOptions = data)"
-    />
     <FetchData
         url="States/editableStates"
         :filter="{ fields: ['code', 'name', 'id', 'alertLevel'], order: 'name ASC' }"
@@ -627,10 +619,12 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                 </div>
                 <VnSelect
                     v-else
-                    :options="itemsWithNameOptions"
                     hide-selected
                     option-label="name"
                     option-value="id"
+                    url="Items/withName"
+                    :fields="['id', 'name']"
+                    sort-by="id DESC"
                     @update:model-value="changeQuantity(row)"
                     v-model="row.itemFk"
                 >
@@ -662,7 +656,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                 <div class="column">
                     <span>{{ row.concept }}</span>
                     <span class="color-vn-label">{{ row.item?.subName }}</span>
-                    <FetchedTags v-if="row.item" :item="row.item" :max-length="6" />
+                    <FetchedTags v-if="row.item" :item="row.item" />
                     <QPopupProxy v-if="row.id && isTicketEditable">
                         <VnInput v-model="row.concept" @change="updateConcept(row)" />
                     </QPopupProxy>
diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
index 9ec6b303a..94db67be2 100644
--- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue
+++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
@@ -131,7 +131,11 @@ const createClaim = () => {
             onCreateClaimAccepted
         );
     else
-        openConfirmationModal(t('Do you want to create a claim?'), onCreateClaimAccepted);
+        openConfirmationModal(
+            t('Do you want to create a claim?'),
+            false,
+            onCreateClaimAccepted
+        );
 };
 
 const onCreateClaimAccepted = async () => {
@@ -153,14 +157,22 @@ const setReserved = async (reserved) => {
 };
 
 const createRefund = async (withWarehouse) => {
-    if (!props.sales) return;
+    if (!props.ticket) return;
 
-    const salesIds = props.sales.map((sale) => sale.id);
-    const params = { salesIds: salesIds, withWarehouse: withWarehouse, negative: true };
-    const { data } = await axios.post('Sales/clone', params);
-    const [refundTicket] = data;
-    notify(t('refundTicketCreated', { ticketId: refundTicket.id }), 'positive');
-    router.push({ name: 'TicketSale', params: { id: refundTicket.id } });
+    const params = {
+        ticketsIds: [props.ticket.id],
+        withWarehouse: withWarehouse,
+        negative: true,
+    };
+
+    try {
+        const { data } = await axios.post('Tickets/cloneAll', params);
+        const [refundTicket] = data;
+        notify(t('refundTicketCreated', { ticketId: refundTicket.id }), 'positive');
+        router.push({ name: 'TicketSale', params: { id: refundTicket.id } });
+    } catch (error) {
+        console.error(error);
+    }
 };
 </script>
 
@@ -244,7 +256,7 @@ const createRefund = async (withWarehouse) => {
             </QItem>
             <QItem clickable v-ripple>
                 <QItemSection>
-                    <QItemLabel>{{ t('Refund...') }}</QItemLabel>
+                    <QItemLabel>{{ t('Refund') }}</QItemLabel>
                 </QItemSection>
                 <QItemSection side>
                     <QIcon name="keyboard_arrow_right" />
@@ -279,7 +291,7 @@ es:
     Add claim: Crear reclamación
     Mark as reserved: Marcar como reservado
     Unmark as reserved: Desmarcar como reservado
-    Refund...: Abono...
+    Refund: Abono
     with warehouse: con almacén
     without warehouse: sin almacén
     Claim out of time: Reclamación fuera de plazo
diff --git a/src/pages/Ticket/Card/TicketSaleTracking.vue b/src/pages/Ticket/Card/TicketSaleTracking.vue
index d519bc2c6..6978d92c8 100644
--- a/src/pages/Ticket/Card/TicketSaleTracking.vue
+++ b/src/pages/Ticket/Card/TicketSaleTracking.vue
@@ -26,8 +26,6 @@ const saleTrackingFetchDataRef = ref(null);
 const sales = ref([]);
 const saleTrackings = ref([]);
 const itemShelvignsSales = ref([]);
-const shelvingsOptions = ref([]);
-const parkingsOptions = ref([]);
 const saleTrackingUrl = computed(() => `SaleTrackings/${route.params.id}/filter`);
 const oldQuantity = ref(null);
 
@@ -330,12 +328,6 @@ const qCheckBoxController = (sale, action) => {
         auto-load
         @on-fetch="(data) => (sales = data)"
     />
-    <FetchData
-        url="Shelvings"
-        auto-load
-        @on-fetch="(data) => (shelvingsOptions = data)"
-    />
-    <FetchData url="Parkings" auto-load @on-fetch="(data) => (parkingsOptions = data)" />
     <QTable
         :rows="sales"
         :columns="columns"
@@ -420,7 +412,7 @@ const qCheckBoxController = (sale, action) => {
                     <span v-if="row.subName" class="color-vn-label">
                         {{ row.subName }}
                     </span>
-                    <FetchedTags :item="row" :max-length="6" tag="value" />
+                    <FetchedTags :item="row" tag="value" />
                 </div>
             </QTd>
         </template>
@@ -500,7 +492,7 @@ const qCheckBoxController = (sale, action) => {
             <template #body-cell-shelving="{ row }">
                 <QTd auto-width>
                     <VnSelect
-                        :options="shelvingsOptions"
+                        url="Shelvings"
                         hide-selected
                         option-label="code"
                         option-value="code"
@@ -513,7 +505,7 @@ const qCheckBoxController = (sale, action) => {
             <template #body-cell-parking="{ row }">
                 <QTd auto-width>
                     <VnSelect
-                        :options="parkingsOptions"
+                        url="Parkings"
                         hide-selected
                         option-label="code"
                         option-value="id"
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index 177384663..6af782173 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -31,8 +31,7 @@ const $props = defineProps({
 const entityId = computed(() => $props.id || route.params.id);
 
 const summaryRef = ref();
-const ticket = ref();
-const salesLines = ref(null);
+const ticket = computed(() => summaryRef.value?.entity);
 const editableStates = ref([]);
 const ticketUrl = ref();
 const grafanaUrl = 'https://grafana.verdnatura.es';
@@ -40,12 +39,6 @@ const grafanaUrl = 'https://grafana.verdnatura.es';
 onMounted(async () => {
     ticketUrl.value = (await getUrl('ticket/')) + entityId.value + '/';
 });
-async function setData(data) {
-    if (data) {
-        ticket.value = data;
-        salesLines.value = data.sales;
-    }
-}
 
 function formattedAddress() {
     if (!ticket.value) return '';
@@ -89,7 +82,6 @@ async function changeState(value) {
     <CardSummary
         ref="summaryRef"
         :url="`Tickets/${entityId}/summary`"
-        @on-fetch="(data) => setData(data)"
         data-key="TicketSummary"
     >
         <template #header="{ entity }">
@@ -131,7 +123,7 @@ async function changeState(value) {
                 </QList>
             </QBtnDropdown>
         </template>
-        <template #body>
+        <template #body="{ entity }">
             <QCard class="vn-one">
                 <VnTitle
                     :url="ticketUrl + 'basic-data/step-one'"
@@ -139,57 +131,58 @@ async function changeState(value) {
                 />
                 <VnLv :label="t('ticket.summary.state')">
                     <template #value>
-                        <QChip :color="ticket.ticketState?.state?.classColor ?? 'dark'">
-                            {{ ticket.ticketState?.state?.name }}
+                        <QChip :color="entity.ticketState?.state?.classColor ?? 'dark'">
+                            {{ entity.ticketState?.state?.name }}
                         </QChip>
                     </template>
                 </VnLv>
                 <VnLv :label="t('ticket.summary.salesPerson')">
                     <template #value>
                         <VnUserLink
-                            :name="ticket.client?.salesPersonUser?.name"
-                            :worker-id="ticket.client?.salesPersonFk"
+                            :name="entity.client?.salesPersonUser?.name"
+                            :worker-id="entity.client?.salesPersonFk"
                         />
                     </template>
                 </VnLv>
                 <VnLv
                     :label="t('ticket.summary.agency')"
-                    :value="ticket.agencyMode?.name"
+                    :value="entity.agencyMode?.name"
                 />
-                <VnLv :label="t('ticket.summary.zone')" :value="ticket?.zone?.name" />
+                <VnLv :label="t('ticket.summary.zone')" :value="entity?.zone?.name" />
                 <VnLv
                     :label="t('ticket.summary.warehouse')"
-                    :value="ticket.warehouse?.name"
+                    :value="entity.warehouse?.name"
                 />
                 <VnLv
+                    v-if="ticket?.ticketCollections?.length > 0"
                     :label="t('ticket.summary.collection')"
-                    :value="ticket.ticketCollections[0]?.collectionFk"
+                    :value="ticket?.ticketCollections[0]?.collectionFk"
                 >
                     <template #value>
                         <a
-                            :href="`${grafanaUrl}/d/d552ab74-85b4-4e7f-a279-fab7cd9c6124/control-de-expediciones?orgId=1&var-collectionFk=${ticket.ticketCollections[0]?.collectionFk}`"
+                            :href="`${grafanaUrl}/d/d552ab74-85b4-4e7f-a279-fab7cd9c6124/control-de-expediciones?orgId=1&var-collectionFk=${entity.ticketCollections[0]?.collectionFk}`"
                             target="_blank"
                             class="grafana"
                         >
-                            {{ ticket.ticketCollections[0]?.collectionFk }}
+                            {{ entity.ticketCollections[0]?.collectionFk }}
                         </a>
                     </template>
                 </VnLv>
-                <VnLv :label="t('ticket.summary.route')" :value="ticket.routeFk" />
+                <VnLv :label="t('ticket.summary.route')" :value="entity.routeFk" />
                 <VnLv :label="t('ticket.summary.invoice')">
                     <template #value>
-                        <span :class="{ link: ticket.refFk }">
-                            {{ dashIfEmpty(ticket.refFk) }}
+                        <span :class="{ link: entity.refFk }">
+                            {{ dashIfEmpty(entity.refFk) }}
                             <InvoiceOutDescriptorProxy
-                                :id="ticket.invoiceOut.id"
-                                v-if="ticket.refFk"
+                                :id="entity.invoiceOut.id"
+                                v-if="entity.refFk"
                             />
                         </span>
                     </template>
                 </VnLv>
                 <VnLv
                     :label="t('ticket.summary.weight')"
-                    :value="dashIfEmpty(ticket.weight)"
+                    :value="dashIfEmpty(entity.weight)"
                 />
             </QCard>
             <QCard class="vn-one">
@@ -199,35 +192,35 @@ async function changeState(value) {
                 />
                 <VnLv
                     :label="t('ticket.summary.shipped')"
-                    :value="toDate(ticket.shipped)"
+                    :value="toDate(entity.shipped)"
                 />
                 <VnLv
                     :label="t('ticket.summary.landed')"
-                    :value="toDate(ticket.landed)"
+                    :value="toDate(entity.landed)"
                 />
-                <VnLv :label="t('globals.packages')" :value="ticket.packages" />
-                <VnLv :value="ticket.address.phone">
+                <VnLv :label="t('globals.packages')" :value="entity.packages" />
+                <VnLv :value="entity.address.phone">
                     <template #label>
                         {{ t('ticket.summary.consigneePhone') }}
-                        <VnLinkPhone :phone-number="ticket.address.phone" />
+                        <VnLinkPhone :phone-number="entity.address.phone" />
                     </template>
                 </VnLv>
-                <VnLv :value="ticket.address.mobile">
+                <VnLv :value="entity.address.mobile">
                     <template #label>
                         {{ t('ticket.summary.consigneeMobile') }}
-                        <VnLinkPhone :phone-number="ticket.address.mobile" />
+                        <VnLinkPhone :phone-number="entity.address.mobile" />
                     </template>
                 </VnLv>
-                <VnLv :value="ticket.client.phone">
+                <VnLv :value="entity.client.phone">
                     <template #label>
                         {{ t('ticket.summary.clientPhone') }}
-                        <VnLinkPhone :phone-number="ticket.client.phone" />
+                        <VnLinkPhone :phone-number="entity.client.phone" />
                     </template>
                 </VnLv>
-                <VnLv :value="ticket.client.mobile">
+                <VnLv :value="entity.client.mobile">
                     <template #label>
                         {{ t('ticket.summary.clientMobile') }}
-                        <VnLinkPhone :phone-number="ticket.client.mobile" />
+                        <VnLinkPhone :phone-number="entity.client.mobile" />
                     </template>
                 </VnLv>
                 <VnLv
@@ -235,13 +228,13 @@ async function changeState(value) {
                     :value="formattedAddress()"
                 />
             </QCard>
-            <QCard class="vn-one" v-if="ticket.notes.length">
+            <QCard class="vn-one" v-if="entity.notes.length">
                 <VnTitle
                     :url="ticketUrl + 'observation'"
                     :text="t('ticket.pageTitles.notes')"
                 />
                 <VnLv
-                    v-for="note in ticket.notes"
+                    v-for="note in entity.notes"
                     :key="note.id"
                     :label="note.observationType.description"
                     :value="note.description"
@@ -262,15 +255,15 @@ async function changeState(value) {
                 <div class="bodyCard">
                     <VnLv
                         :label="t('ticket.summary.subtotal')"
-                        :value="toCurrency(ticket.totalWithoutVat)"
+                        :value="toCurrency(entity.totalWithoutVat)"
                     />
                     <VnLv
                         :label="t('ticket.summary.vat')"
-                        :value="toCurrency(ticket.totalWithVat - ticket.totalWithoutVat)"
+                        :value="toCurrency(entity.totalWithVat - entity.totalWithoutVat)"
                     />
                     <VnLv
                         :label="t('ticket.summary.total')"
-                        :value="toCurrency(ticket.totalWithVat)"
+                        :value="toCurrency(entity.totalWithVat)"
                     />
                 </div>
             </QCard>
@@ -279,7 +272,7 @@ async function changeState(value) {
                     :url="ticketUrl + 'sale'"
                     :text="t('ticket.summary.saleLines')"
                 />
-                <QTable :rows="ticket.sales" style="text-align: center">
+                <QTable :rows="entity.sales" style="text-align: center">
                     <template #body-cell="{ value }">
                         <QTd>{{ value }}</QTd>
                     </template>
@@ -383,7 +376,11 @@ async function changeState(value) {
                             <QTd>
                                 <QBtn class="link" flat>
                                     {{ props.row.itemFk }}
-                                    <ItemDescriptorProxy :id="props.row.itemFk" />
+                                    <ItemDescriptorProxy
+                                        :id="props.row.itemFk"
+                                        :sale-fk="props.row.id"
+                                        :warehouse-fk="ticket.warehouseFk"
+                                    />
                                 </QBtn>
                             </QTd>
                             <QTd>{{ props.row.visible }}</QTd>
@@ -399,7 +396,6 @@ async function changeState(value) {
                                 <FetchedTags
                                     class="fetched-tags"
                                     :item="props.row.item"
-                                    :max-length="5"
                                 ></FetchedTags>
                             </QTd>
                             <QTd>{{ props.row.price }} €</QTd>
@@ -420,10 +416,10 @@ async function changeState(value) {
             </QCard>
             <QCard
                 class="vn-max"
-                v-if="ticket.packagings.length > 0 || ticket.services.length > 0"
+                v-if="entity.packagings.length || entity.services.length"
             >
                 <VnTitle :url="ticketUrl + 'package'" :text="t('globals.packages')" />
-                <QTable :rows="ticket.packagings" flat>
+                <QTable :rows="entity.packagings" flat>
                     <template #header="props">
                         <QTr :props="props">
                             <QTh auto-width>{{ t('ticket.summary.created') }}</QTh>
@@ -443,7 +439,7 @@ async function changeState(value) {
                     :url="ticketUrl + 'service'"
                     :text="t('ticket.summary.service')"
                 />
-                <QTable :rows="ticket.services" flat>
+                <QTable :rows="entity.services" flat>
                     <template #header="props">
                         <QTr :props="props">
                             <QTh auto-width>{{ t('ticket.summary.quantity') }}</QTh>
diff --git a/src/pages/Ticket/Card/TicketTracking.vue b/src/pages/Ticket/Card/TicketTracking.vue
index 2ddb278fa..f7cbb14e9 100644
--- a/src/pages/Ticket/Card/TicketTracking.vue
+++ b/src/pages/Ticket/Card/TicketTracking.vue
@@ -83,6 +83,8 @@ const openCreateModal = () => createTrackingDialogRef.value.show();
             :filter="paginateFilter"
             url="TicketTrackings"
             auto-load
+            order="created DESC"
+            :limit="0"
         >
             <template #body="{ rows }">
                 <QTable
@@ -112,7 +114,13 @@ const openCreateModal = () => createTrackingDialogRef.value.show();
             <TicketCreateTracking @on-request-created="paginateRef.fetch()" />
         </QDialog>
         <QPageSticky :offset="[20, 20]">
-            <QBtn @click="openCreateModal()" color="primary" fab icon="add" />
+            <QBtn
+                @click="openCreateModal()"
+                color="primary"
+                fab
+                icon="add"
+                shortcut="+"
+            />
             <QTooltip class="text-no-wrap">
                 {{ t('tracking.addState') }}
             </QTooltip>
diff --git a/src/pages/Ticket/Card/TicketTransfer.vue b/src/pages/Ticket/Card/TicketTransfer.vue
index 9a22c764c..1944b80f4 100644
--- a/src/pages/Ticket/Card/TicketTransfer.vue
+++ b/src/pages/Ticket/Card/TicketTransfer.vue
@@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
 
 import VnInput from 'src/components/common/VnInput.vue';
+import TicketTransferForm from './TicketTransferForm.vue';
 
 import { toDateFormat } from 'src/filters/date.js';
 import axios from 'axios';
@@ -135,9 +136,7 @@ onMounted(() => (_transfer.value = $props.transfer));
                 :columns="destinationTicketColumns"
                 :title="t('Destination ticket')"
                 row-key="id"
-                :pagination="{ rowsPerPage: 0 }"
                 class="full-width q-mt-md"
-                :no-data-label="t('globals.noResults')"
             >
                 <template #body-cell-address="{ row }">
                     <QTd @click.stop>
@@ -158,29 +157,11 @@ onMounted(() => (_transfer.value = $props.transfer));
                     </QTd>
                 </template>
 
+                <template #no-data>
+                    <TicketTransferForm v-bind="$props" />
+                </template>
                 <template #bottom>
-                    <QForm class="q-mt-lg full-width">
-                        <VnInput
-                            v-model.number="_transfer.ticketId"
-                            :label="t('Transfer to ticket')"
-                            :clearable="false"
-                        >
-                            <template #append>
-                                <QBtn
-                                    icon="keyboard_arrow_right"
-                                    color="primary"
-                                    @click="transferSales(_transfer.ticketId)"
-                                    style="width: 30px"
-                                />
-                            </template>
-                        </VnInput>
-                        <QBtn
-                            :label="t('New ticket')"
-                            color="primary"
-                            class="full-width q-my-lg"
-                            @click="transferSales()"
-                        />
-                    </QForm>
+                    <TicketTransferForm v-bind="$props" />
                 </template>
             </QTable>
         </QCard>
diff --git a/src/pages/Ticket/Card/TicketTransferForm.vue b/src/pages/Ticket/Card/TicketTransferForm.vue
new file mode 100644
index 000000000..9507429e6
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketTransferForm.vue
@@ -0,0 +1,86 @@
+<script setup>
+import { ref, onMounted } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useRouter } from 'vue-router';
+
+import VnInput from 'src/components/common/VnInput.vue';
+
+import axios from 'axios';
+
+const $props = defineProps({
+    mana: {
+        type: Number,
+        default: null,
+    },
+    newPrice: {
+        type: Number,
+        default: 0,
+    },
+    transfer: {
+        type: Object,
+        default: () => {},
+    },
+    ticket: {
+        type: Object,
+        default: () => {},
+    },
+});
+
+const emit = defineEmits(['refreshData']);
+
+const router = useRouter();
+const { t } = useI18n();
+
+const _transfer = ref(null);
+
+const transferSales = async (ticketId) => {
+    const params = {
+        ticketId: ticketId,
+        sales: $props.transfer.sales,
+    };
+
+    const { data } = await axios.post(
+        `tickets/${$props.ticket.id}/transferSales`,
+        params
+    );
+
+    if (data && data.id === $props.ticket.id) emit('refreshData');
+    else router.push({ name: 'TicketSale', params: { id: data.id } });
+};
+
+onMounted(() => (_transfer.value = $props.transfer));
+</script>
+
+<template>
+    {{ _transfer }}
+    <QForm class="q-mt-lg full-width">
+        <VnInput
+            v-model.number="_transfer.ticketId"
+            :label="t('Transfer to ticket')"
+            :clearable="false"
+        >
+            <template #append>
+                <QBtn
+                    icon="keyboard_arrow_right"
+                    color="primary"
+                    @click="transferSales(_transfer.ticketId)"
+                    style="width: 30px"
+                />
+            </template>
+        </VnInput>
+        <QBtn
+            :label="t('New ticket')"
+            color="primary"
+            class="full-width q-my-lg"
+            @click="transferSales()"
+        />
+    </QForm>
+</template>
+
+<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/TicketVolume.vue b/src/pages/Ticket/Card/TicketVolume.vue
index 93da31e53..68d2a1f73 100644
--- a/src/pages/Ticket/Card/TicketVolume.vue
+++ b/src/pages/Ticket/Card/TicketVolume.vue
@@ -145,7 +145,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                 <div class="column">
                     <span>{{ row.item.name }}</span>
                     <span class="color-vn-label">{{ row.item.subName }}</span>
-                    <FetchedTags :item="row.item" :max-length="6" />
+                    <FetchedTags :item="row.item" />
                 </div>
             </QTd>
         </template>
diff --git a/src/pages/Ticket/TicketAdvance.vue b/src/pages/Ticket/TicketAdvance.vue
index bf4000fdf..177b3a29b 100644
--- a/src/pages/Ticket/TicketAdvance.vue
+++ b/src/pages/Ticket/TicketAdvance.vue
@@ -133,6 +133,14 @@ const ticketColumns = computed(() => [
         sortable: true,
         columnFilter: null,
     },
+    {
+        label: t('advanceTickets.preparation'),
+        name: 'preparation',
+        field: 'preparation',
+        align: 'left',
+        sortable: true,
+        columnFilter: null,
+    },
     {
         label: t('advanceTickets.liters'),
         name: 'liters',
@@ -448,7 +456,7 @@ const handleCloseProgressDialog = () => {
 const handleCancelProgress = () => (cancelProgress.value = true);
 
 onMounted(async () => {
-    let today = Date.vnNew();
+    let today = Date.vnNew().toISOString();
     const tomorrow = new Date(today);
     tomorrow.setDate(tomorrow.getDate() + 1);
     userParams.dateFuture = tomorrow;
@@ -624,6 +632,7 @@ onMounted(async () => {
                     </QIcon>
                 </QTd>
             </template>
+
             <template #body-cell-ticketId="{ row }">
                 <QTd>
                     <QBtn flat class="link">
@@ -635,6 +644,7 @@ onMounted(async () => {
             <template #body-cell-state="{ row }">
                 <QTd>
                     <QBadge
+                        v-if="row.state"
                         text-color="black"
                         :color="row.classColor"
                         class="q-ma-none"
@@ -642,6 +652,7 @@ onMounted(async () => {
                     >
                         {{ row.state }}
                     </QBadge>
+                    <span v-else> {{ dashIfEmpty(row.state) }}</span>
                 </QTd>
             </template>
             <template #body-cell-import="{ row }">
diff --git a/src/pages/Ticket/TicketAdvanceFilter.vue b/src/pages/Ticket/TicketAdvanceFilter.vue
index c4548763a..209a1a307 100644
--- a/src/pages/Ticket/TicketAdvanceFilter.vue
+++ b/src/pages/Ticket/TicketAdvanceFilter.vue
@@ -70,7 +70,6 @@ onMounted(async () => await getItemPackingTypes());
                         v-model="params.dateFuture"
                         :label="t('params.dateFuture')"
                         is-outlined
-                        @update:model-value="searchFn()"
                     />
                 </QItemSection>
             </QItem>
@@ -80,7 +79,6 @@ onMounted(async () => await getItemPackingTypes());
                         v-model="params.dateToAdvance"
                         :label="t('params.dateToAdvance')"
                         is-outlined
-                        @update:model-value="searchFn()"
                     />
                 </QItemSection>
             </QItem>
@@ -121,10 +119,9 @@ onMounted(async () => await getItemPackingTypes());
             <QItem>
                 <QItemSection>
                     <QCheckbox
-                        :label="t('params.itemPackingTypes')"
-                        v-model="params.itemPackingTypes"
+                        :label="t('params.isFullMovable')"
+                        v-model="params.isFullMovable"
                         toggle-indeterminate
-                        :false-value="null"
                         @update:model-value="searchFn()"
                     />
                 </QItemSection>
@@ -157,7 +154,7 @@ en:
         dateToAdvance: Destination date
         futureIpt: Origin IPT
         ipt: Destination IPT
-        itemPackingTypes: 100% movable
+        isFullMovable: 100% movable
         warehouseFk: Warehouse
 es:
     Horizontal: Horizontal
@@ -168,6 +165,6 @@ es:
         dateToAdvance: Fecha destino
         futureIpt: IPT Origen
         ipt: IPT destino
-        itemPackingTypes: 100% movible
+        isFullMovable: 100% movible
         warehouseFk: Almacén
 </i18n>
diff --git a/src/pages/Ticket/TicketCreateDialog.vue b/src/pages/Ticket/TicketCreateDialog.vue
new file mode 100644
index 000000000..1493adc53
--- /dev/null
+++ b/src/pages/Ticket/TicketCreateDialog.vue
@@ -0,0 +1,226 @@
+<script setup>
+import { useRoute, useRouter } from 'vue-router';
+import { onBeforeMount, reactive, ref } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useDialogPluginComponent } from 'quasar';
+
+import FormModelPopup from 'components/FormModelPopup.vue';
+import FetchData from 'components/FetchData.vue';
+import VnRow from 'components/ui/VnRow.vue';
+import VnSelect from 'components/common/VnSelect.vue';
+import VnInputDate from 'components/common/VnInputDate.vue';
+
+import { useState } from 'composables/useState';
+import axios from 'axios';
+
+const { t } = useI18n();
+const route = useRoute();
+const router = useRouter();
+const state = useState();
+const user = state.getUser();
+defineEmits(['confirm', ...useDialogPluginComponent.emits]);
+
+const initialFormState = reactive({
+    clientId: Number(route.query?.clientFk) || null,
+    addressId: null,
+    agencyModeId: null,
+    warehouseId: user.value.warehouseFk,
+    landed: null,
+});
+const clientOptions = ref([]);
+const agenciesOptions = ref([]);
+const addressesOptions = ref([]);
+const warehousesOptions = ref([]);
+const selectedClient = ref(null);
+
+onBeforeMount(async () => {
+    await onClientSelected(initialFormState);
+});
+
+const fetchClient = async (formData) => {
+    try {
+        const filter = {
+            include: {
+                relation: 'defaultAddress',
+                scope: {
+                    fields: ['id', 'agencyModeFk'],
+                },
+            },
+            where: { id: formData.clientId },
+        };
+        const params = { filter: JSON.stringify(filter) };
+        const { data } = await axios.get('Clients', { params });
+        const [client] = data;
+        selectedClient.value = client;
+    } catch (err) {
+        console.error('Error fetching client');
+    }
+};
+
+const fetchAddresses = async (formData) => {
+    try {
+        if (!formData.clientId) return;
+
+        const filter = {
+            fields: ['nickname', 'street', 'city', 'id'],
+            where: { isActive: true },
+            order: 'nickname ASC',
+        };
+        const params = { filter: JSON.stringify(filter) };
+        const { data } = await axios.get(`Clients/${formData.clientId}/addresses`, {
+            params,
+        });
+        addressesOptions.value = data;
+
+        const { defaultAddress } = selectedClient.value;
+        formData.addressId = defaultAddress.id;
+    } catch (err) {
+        console.error(`Error fetching addresses`, err);
+        return err.response;
+    }
+};
+
+const onClientSelected = async (formData) => {
+    await fetchClient(formData);
+    await fetchAddresses(formData);
+};
+
+const fetchAvailableAgencies = async (formData) => {
+    if (!formData.warehouseId || !formData.addressId || !formData.landed) return;
+    let params = {
+        warehouseFk: formData.warehouseId,
+        addressFk: formData.addressId,
+        landed: formData.landed,
+    };
+
+    const { data } = await axios.get('Agencies/getAgenciesWithWarehouse', { params });
+
+    agenciesOptions.value = data;
+
+    const defaultAgency = agenciesOptions.value.find(
+        (agency) =>
+            agency.agencyModeFk === selectedClient.value.defaultAddress.agencyModeFk
+    );
+
+    if (defaultAgency) formData.agencyModeId = defaultAgency.agencyModeFk;
+};
+
+const redirectToTicketList = (_, { id }) => {
+    router.push({ name: 'TicketSummary', params: { id } });
+};
+</script>
+
+<template>
+    <FetchData
+        url="Clients"
+        @on-fetch="(data) => (clientOptions = data)"
+        :filter="{ fields: ['id', 'name', 'defaultAddressFk'], order: 'id' }"
+        auto-load
+    />
+    <FetchData
+        url="Warehouses"
+        @on-fetch="(data) => (warehousesOptions = data)"
+        order="name"
+        auto-load
+    />
+
+    <FormModelPopup
+        :title="t('globals.pageTitles.createTicket')"
+        url-create="Tickets/new"
+        model="ticket"
+        :form-initial-data="initialFormState"
+        @on-data-saved="redirectToTicketList"
+    >
+        <template #form-inputs="{ data }">
+            <VnRow>
+                <div class="col">
+                    <VnSelect
+                        :label="t('ticket.create.client')"
+                        v-model="data.clientId"
+                        :options="clientOptions"
+                        option-value="id"
+                        option-label="name"
+                        hide-selected
+                        @update:model-value="(client) => onClientSelected(data)"
+                    >
+                        <template #option="scope">
+                            <QItem v-bind="scope.itemProps">
+                                <QItemSection>
+                                    <QItemLabel>
+                                        {{ scope.opt.name }}
+                                    </QItemLabel>
+                                    <QItemLabel caption>
+                                        {{ `#${scope.opt.id}` }}
+                                    </QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
+                </div>
+            </VnRow>
+            <VnRow>
+                <div class="col">
+                    <VnSelect
+                        :label="t('ticket.create.address')"
+                        v-model="data.addressId"
+                        :options="addressesOptions"
+                        option-value="id"
+                        option-label="nickname"
+                        hide-selected
+                        :disable="!data.clientId"
+                        @update:model-value="() => fetchAvailableAgencies(data)"
+                    >
+                        <template #option="scope">
+                            <QItem v-bind="scope.itemProps">
+                                <QItemSection>
+                                    <QItemLabel>
+                                        {{ scope.opt.nickname }}
+                                    </QItemLabel>
+                                    <QItemLabel caption>
+                                        {{ `${scope.opt.street}, ${scope.opt.city}` }}
+                                    </QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
+                </div>
+            </VnRow>
+            <VnRow>
+                <div class="col">
+                    <VnInputDate
+                        placeholder="dd-mm-aaa"
+                        :label="t('ticket.create.landed')"
+                        v-model="data.landed"
+                        @update:model-value="() => fetchAvailableAgencies(data)"
+                    />
+                </div>
+            </VnRow>
+            <VnRow>
+                <div class="col">
+                    <VnSelect
+                        :label="t('ticket.create.warehouse')"
+                        v-model="data.warehouseId"
+                        :options="warehousesOptions"
+                        option-value="id"
+                        option-label="name"
+                        hide-selected
+                        @update:model-value="() => fetchAvailableAgencies(data)"
+                    />
+                </div>
+            </VnRow>
+            <VnRow>
+                <div class="col">
+                    <VnSelect
+                        :label="t('ticket.create.agency')"
+                        v-model="data.agencyModeId"
+                        :options="agenciesOptions"
+                        option-value="agencyModeFk"
+                        option-label="agencyMode"
+                        hide-selected
+                        :disable="!data.clientId || !data.landed || !data.warehouseId"
+                    />
+                </div>
+            </VnRow>
+        </template>
+    </FormModelPopup>
+</template>
diff --git a/src/pages/Ticket/TicketFuture.vue b/src/pages/Ticket/TicketFuture.vue
index 2fec6dc18..2078d0595 100644
--- a/src/pages/Ticket/TicketFuture.vue
+++ b/src/pages/Ticket/TicketFuture.vue
@@ -8,6 +8,8 @@ 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 TicketFutureFilter from './TicketFutureFilter.vue';
 
 import { dashIfEmpty, toCurrency } from 'src/filters';
 import { useVnConfirm } from 'composables/useVnConfirm';
@@ -37,9 +39,9 @@ const exprBuilder = (param, value) => {
             return { liters: value };
         case 'lines':
             return { lines: value };
-        case 'ipt':
+        case 'iptColFilter':
             return { ipt: { like: `%${value}%` } };
-        case 'futureIpt':
+        case 'futureIptColFilter':
             return { futureIpt: { like: `%${value}%` } };
         case 'totalWithVat':
             return { totalWithVat: value };
@@ -47,8 +49,8 @@ const exprBuilder = (param, value) => {
 };
 
 const userParams = reactive({
-    futureDated: Date.vnNew(),
-    originDated: Date.vnNew(),
+    futureScopeDays: Date.vnNew().toISOString(),
+    originScopeDays: Date.vnNew().toISOString(),
     warehouseFk: user.value.warehouseFk,
 });
 
@@ -60,8 +62,8 @@ const arrayData = useArrayData('FutureTickets', {
 const { store } = arrayData;
 
 const params = reactive({
-    futureDated: Date.vnNew(),
-    originDated: Date.vnNew(),
+    futureScopeDays: Date.vnNew(),
+    originScopeDays: Date.vnNew(),
     warehouseFk: user.value.warehouseFk,
 });
 
@@ -83,6 +85,8 @@ const getInputEvents = (col) => {
           };
 };
 
+const tickets = computed(() => store.data);
+
 const ticketColumns = computed(() => [
     {
         label: t('futureTickets.problems'),
@@ -121,7 +125,7 @@ const ticketColumns = computed(() => [
         sortable: true,
         columnFilter: {
             component: VnSelect,
-            filterParamKey: 'ipt',
+            filterParamKey: 'iptColFilter',
             type: 'select',
             filterValue: null,
             event: getInputEvents,
@@ -168,7 +172,7 @@ const ticketColumns = computed(() => [
         label: t('futureTickets.availableLines'),
         name: 'lines',
         field: 'lines',
-        align: 'left',
+        align: 'center',
         sortable: true,
         columnFilter: {
             component: VnInput,
@@ -214,7 +218,7 @@ const ticketColumns = computed(() => [
         sortable: true,
         columnFilter: {
             component: VnSelect,
-            filterParamKey: 'futureIpt',
+            filterParamKey: 'futureIptColFilter',
             type: 'select',
             filterValue: null,
             event: getInputEvents,
@@ -230,7 +234,7 @@ const ticketColumns = computed(() => [
     {
         label: t('futureTickets.futureState'),
         name: 'futureState',
-        align: 'left',
+        align: 'right',
         sortable: true,
         columnFilter: null,
         format: (val) => dashIfEmpty(val),
@@ -305,9 +309,14 @@ onMounted(async () => {
             </QBtn>
         </template>
     </VnSubToolbar>
+    <RightMenu>
+        <template #right-panel>
+            <TicketFutureFilter data-key="FutureTickets" />
+        </template>
+    </RightMenu>
     <QPage class="column items-center q-pa-md">
         <QTable
-            :rows="store.data"
+            :rows="tickets"
             :columns="ticketColumns"
             row-key="id"
             selection="multiple"
@@ -449,7 +458,7 @@ onMounted(async () => {
                 </QTd>
             </template>
             <template #body-cell-shipped="{ row }">
-                <QTd>
+                <QTd class="shipped">
                     <QBadge
                         text-color="black"
                         :color="getDateQBadgeColor(row.shipped)"
@@ -496,7 +505,7 @@ onMounted(async () => {
                 </QTd>
             </template>
             <template #body-cell-futureShipped="{ row }">
-                <QTd>
+                <QTd class="shipped">
                     <QBadge
                         text-color="black"
                         :color="getDateQBadgeColor(row.futureShipped)"
@@ -523,6 +532,9 @@ onMounted(async () => {
 </template>
 
 <style scoped lang="scss">
+.shipped {
+    min-width: 132px;
+}
 .vertical-separator {
     border-left: 4px solid white !important;
 }
diff --git a/src/pages/Ticket/TicketFutureFilter.vue b/src/pages/Ticket/TicketFutureFilter.vue
new file mode 100644
index 000000000..6345f62b3
--- /dev/null
+++ b/src/pages/Ticket/TicketFutureFilter.vue
@@ -0,0 +1,242 @@
+<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 VnSelect from 'components/common/VnSelect.vue';
+import VnInputDate from 'src/components/common/VnInputDate.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+
+import axios from 'axios';
+import { onMounted } from 'vue';
+
+const { t } = useI18n();
+const props = defineProps({
+    dataKey: {
+        type: String,
+        required: true,
+    },
+});
+
+const warehousesOptions = ref([]);
+const itemPackingTypes = ref([]);
+const stateOptions = ref([]);
+
+const getItemPackingTypes = async () => {
+    try {
+        const filter = {
+            where: { isActive: true },
+        };
+        const { data } = await axios.get('ItemPackingTypes', {
+            params: { filter: JSON.stringify(filter) },
+        });
+        itemPackingTypes.value = data.map((ipt) => ({
+            description: t(ipt.description),
+            code: ipt.code,
+        }));
+    } catch (error) {
+        console.error(error);
+    }
+};
+
+const getGroupedStates = async () => {
+    try {
+        const { data } = await axios.get('AlertLevels');
+        stateOptions.value = data.map((state) => ({
+            id: state.id,
+            name: t(`futureTickets.${state.code}`),
+            code: state.code,
+        }));
+    } catch (error) {
+        console.error(error);
+    }
+};
+
+onMounted(async () => {
+    getItemPackingTypes();
+    getGroupedStates();
+});
+</script>
+
+<template>
+    <FetchData
+        url="Warehouses"
+        @on-fetch="(data) => (warehousesOptions = data)"
+        auto-load
+    />
+    <VnFilterPanel
+        :data-key="props.dataKey"
+        :hidden-tags="['search']"
+        :un-removable-params="['warehouseFk', 'originScopeDays ', 'futureScopeDays']"
+    >
+        <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 class="q-my-sm">
+                <QItemSection>
+                    <VnInputDate
+                        v-model="params.originScopeDays"
+                        :label="t('params.originScopeDays')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem class="q-my-sm">
+                <QItemSection>
+                    <VnInputDate
+                        v-model="params.futureScopeDays"
+                        :label="t('params.futureScopeDays')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem class="q-my-sm">
+                <QItemSection>
+                    <VnInput
+                        :label="t('params.litersMax')"
+                        v-model="params.litersMax"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem class="q-my-sm">
+                <QItemSection>
+                    <VnInput
+                        :label="t('params.linesMax')"
+                        v-model="params.linesMax"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.ipt')"
+                        v-model="params.ipt"
+                        :options="itemPackingTypes"
+                        option-value="code"
+                        option-label="description"
+                        :info="t('iptInfo')"
+                        @update:model-value="searchFn()"
+                        dense
+                        outlined
+                        rounded
+                    >
+                    </VnSelect>
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.futureIpt')"
+                        v-model="params.futureIpt"
+                        :options="itemPackingTypes"
+                        option-value="code"
+                        option-label="description"
+                        :info="t('iptInfo')"
+                        @update:model-value="searchFn()"
+                        dense
+                        outlined
+                        rounded
+                    >
+                    </VnSelect>
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.state')"
+                        v-model="params.state"
+                        :options="stateOptions"
+                        option-value="id"
+                        option-label="name"
+                        @update:model-value="searchFn()"
+                        dense
+                        outlined
+                        rounded
+                    >
+                    </VnSelect>
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.futureState')"
+                        v-model="params.futureState"
+                        :options="stateOptions"
+                        option-value="id"
+                        option-label="name"
+                        @update:model-value="searchFn()"
+                        dense
+                        outlined
+                        rounded
+                    >
+                    </VnSelect>
+                </QItemSection>
+            </QItem>
+
+            <QItem>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('params.problems')"
+                        v-model="params.problems"
+                        :toggle-indeterminate="false"
+                        @update:model-value="searchFn()"
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.warehouseFk')"
+                        v-model="params.warehouseFk"
+                        :options="warehousesOptions"
+                        option-value="id"
+                        option-label="name"
+                        @update:model-value="searchFn()"
+                        dense
+                        outlined
+                        rounded
+                    >
+                    </VnSelect>
+                </QItemSection>
+            </QItem>
+        </template>
+    </VnFilterPanel>
+</template>
+
+<i18n>
+en:
+    iptInfo: IPT
+    params:
+        originScopeDays: Origin date
+        futureScopeDays: Destination date
+        futureIpt: Destination IPT
+        ipt: Origin IPT
+        warehouseFk: Warehouse
+        litersMax: Max liters
+        linesMax: Max lines
+        state: Origin grouped state
+        futureState: Destination grouped state
+        problems: With problems
+es:
+    Horizontal: Horizontal
+    Vertical: Vertical
+    iptInfo: Encajado
+    params:
+        originScopeDays: Fecha origen
+        futureScopeDays: Fecha destino
+        futureIpt: IPT destino
+        ipt: IPT Origen
+        warehouseFk: Almacén
+        litersMax: Litros máx.
+        linesMax: Líneas máx.
+        state: Estado agrupado origen
+        futureState: Estado agrupado destino
+        problems: Con problemas
+</i18n>
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index cbd102317..bd0bda6e3 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -1,6 +1,7 @@
 <script setup>
 import axios from 'axios';
 import { computed, ref, onMounted } from 'vue';
+import { useRoute } from 'vue-router';
 import { useStateStore } from 'stores/useStateStore';
 import { useI18n } from 'vue-i18n';
 import { toDate, toCurrency } from 'src/filters/index';
@@ -14,6 +15,7 @@ import VnRow from 'src/components/ui/VnRow.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import TicketFilter from './TicketFilter.vue';
 
+const route = useRoute();
 const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
 const tableRef = ref();
@@ -23,12 +25,23 @@ const agenciesOptions = ref([]);
 const selectedClient = ref();
 const stateStore = useStateStore();
 const from = Date.vnNew();
+from.setHours(0, 0, 0, 0);
 const to = Date.vnNew();
+to.setHours(23, 59, 0, 0);
 to.setDate(to.getDate() + 1);
 
 const userParams = {
-    from: from.toISOString(),
-    to: to.toISOString(),
+    from: null,
+    to: null,
+};
+// Método para inicializar las variables desde la query string
+const initializeFromQuery = () => {
+    const query = route.query.table ? JSON.parse(route.query.table) : {};
+
+    // Asigna los valores a las variables correspondientes
+    from.value = query.from || from.toISOString();
+    to.value = query.to || to.toISOString();
+    Object.assign(userParams, { from, to });
 };
 
 const columns = computed(() => [
@@ -200,23 +213,26 @@ const getColor = (row) => {
     return row?.classColor ? `bg-${row.classColor}` : 'bg-orange';
 };
 
-onMounted(() => (stateStore.rightDrawer = true));
+onMounted(() => {
+    initializeFromQuery();
+    stateStore.rightDrawer = true;
+});
 </script>
 
 <template>
     <VnSearchbar
-        data-key="Tickets"
+        data-key="Ticket"
         :label="t('Search ticket')"
         :info="t('You can search by ticket id or alias')"
     />
     <RightMenu>
         <template #right-panel>
-            <TicketFilter data-key="Tickets" />
+            <TicketFilter data-key="Ticket" />
         </template>
     </RightMenu>
     <VnTable
         ref="tableRef"
-        data-key="Tickets"
+        data-key="Ticket"
         url="Tickets/filter"
         :create="{
             urlCreate: 'Tickets/new',
@@ -225,7 +241,7 @@ onMounted(() => (stateStore.rightDrawer = true));
             formInitialData: {},
         }"
         default-mode="table"
-        order="id DESC"
+        :order="['shippedDate DESC', 'shippedHour ASC', 'zoneLanding ASC', 'id']"
         :columns="columns"
         :user-params="userParams"
         :right-search="false"
diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml
index 10a8e1fa4..305228669 100644
--- a/src/pages/Ticket/locale/en.yml
+++ b/src/pages/Ticket/locale/en.yml
@@ -93,6 +93,11 @@ futureTickets:
     moveTicketSuccess: Tickets moved successfully!
     searchInfo: Search future tickets by date
     futureTicket: Future tickets
+    FREE: Free
+    ON_PREVIOUS: ON_PREVIOUS
+    ON_PREPARATION: On preparation
+    PACKED: Packed
+    DELIVERED: Delivered
 expedition:
     id: Expedition
     item: Item
diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml
index a80692bfe..30c5550be 100644
--- a/src/pages/Ticket/locale/es.yml
+++ b/src/pages/Ticket/locale/es.yml
@@ -105,7 +105,7 @@ advanceTickets:
     futureLines: Líneas
     futureImport: Importe
     advanceTickets: Adelantar tickets con negativos
-    advanceTicketTitle: Advance tickets
+    advanceTicketTitle: Adelantar tickets
     advanceTitleSubtitle: '¿Desea adelantar {selectedTickets} tickets?'
     noDeliveryZone: No hay una zona de reparto disponible para la fecha de envío seleccionada
     moveTicketSuccess: 'Tickets movidos correctamente {ticketsNumber}'
@@ -140,6 +140,11 @@ futureTickets:
     moveTicketSuccess: Tickets movidos correctamente
     searchInfo: Buscar tickets por fecha
     futureTicket: Tickets a futuro
+    FREE: Libre
+    ON_PREVIOUS: ON_PREVIOUS
+    ON_PREPARATION: En preparación
+    PACKED: Encajado
+    DELIVERED: Servido
 ticketSale:
     id: Id
     visible: Visible
diff --git a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
index bd2561211..47b6f0aa6 100644
--- a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
+++ b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
@@ -8,7 +8,7 @@ import VnConfirm from 'components/ui/VnConfirm.vue';
 
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
-import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 
 const $props = defineProps({
     travel: {
@@ -21,7 +21,6 @@ const { t } = useI18n();
 const router = useRouter();
 const quasar = useQuasar();
 const { notify } = useNotify();
-const role = useRole();
 
 const redirectToCreateView = (queryParams) => {
     router.push({ name: 'TravelCreate', query: { travelData: queryParams } });
@@ -42,9 +41,7 @@ const cloneTravelWithEntries = async () => {
     }
 };
 
-const isBuyer = computed(() => {
-    return role.hasAny(['buyer']);
-});
+const canDelete = computed(() => useAcl().hasAny('Travel','*','WRITE'));
 
 const openDeleteEntryDialog = (id) => {
     quasar
@@ -81,7 +78,7 @@ const deleteTravel = async (id) => {
         </QItemSection>
     </QItem>
     <QItem
-        v-if="isBuyer && travel.totalEntries === 0"
+        v-if="canDelete && travel.totalEntries === 0"
         v-ripple
         clickable
         @click="openDeleteEntryDialog(travel.id)"
diff --git a/src/pages/Travel/Card/TravelThermographs.vue b/src/pages/Travel/Card/TravelThermographs.vue
index 9f224154c..6d83581ee 100644
--- a/src/pages/Travel/Card/TravelThermographs.vue
+++ b/src/pages/Travel/Card/TravelThermographs.vue
@@ -196,6 +196,7 @@ const removeThermograph = async (id) => {
             icon="add"
             color="primary"
             @click="redirectToThermographForm('create')"
+            shortcut="+"
         />
         <QTooltip class="text-no-wrap">
             {{ t('Add thermograph') }}
diff --git a/src/pages/Travel/ExtraCommunityFilter.vue b/src/pages/Travel/ExtraCommunityFilter.vue
index c51151451..a8bbde75b 100644
--- a/src/pages/Travel/ExtraCommunityFilter.vue
+++ b/src/pages/Travel/ExtraCommunityFilter.vue
@@ -20,7 +20,6 @@ const props = defineProps({
 const warehousesOptions = ref([]);
 const continentsOptions = ref([]);
 const agenciesOptions = ref([]);
-const suppliersOptions = ref([]);
 const warehousesByContinent = ref({});
 
 const add = (paramsObj, key) => {
@@ -76,12 +75,6 @@ warehouses();
         @on-fetch="(data) => (agenciesOptions = data)"
         auto-load
     />
-    <FetchData
-        url="Suppliers"
-        @on-fetch="(data) => (suppliersOptions = data)"
-        auto-load
-    />
-
     <VnFilterPanel :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
@@ -220,7 +213,7 @@ warehouses();
                     <VnSelect
                         :label="t('globals.pageTitles.supplier')"
                         v-model="params.cargoSupplierFk"
-                        :options="suppliersOptions"
+                        url="Suppliers"
                         option-value="id"
                         option-label="name"
                         hide-selected
diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue
index 8989e485c..c7ad908f9 100644
--- a/src/pages/Travel/TravelList.vue
+++ b/src/pages/Travel/TravelList.vue
@@ -10,6 +10,7 @@ import { computed } from 'vue';
 import TravelSummary from './Card/TravelSummary.vue';
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
 import { toDate } from 'src/filters';
+import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
 const { viewSummary } = useSummaryDialog();
 const router = useRouter();
 const { t } = useI18n();
@@ -46,14 +47,12 @@ const columns = computed(() => [
         name: 'id',
         label: t('travel.travelList.tableVisibleColumns.id'),
         isId: true,
-        field: 'id',
         cardVisible: true,
     },
     {
         align: 'left',
         name: 'ref',
         label: t('travel.travelList.tableVisibleColumns.ref'),
-        field: 'ref',
         component: 'input',
         columnField: {
             component: null,
@@ -65,7 +64,6 @@ const columns = computed(() => [
         align: 'left',
         name: 'agencyModeFk',
         label: t('travel.travelList.tableVisibleColumns.agency'),
-        field: 'agencyModeFk',
         component: 'select',
         attrs: {
             url: 'agencyModes',
@@ -78,37 +76,10 @@ const columns = computed(() => [
         cardVisible: true,
         create: true,
     },
-    {
-        align: 'left',
-        name: 'shipped',
-        label: t('travel.travelList.tableVisibleColumns.shipped'),
-        field: 'shipped',
-        component: 'date',
-        columnField: {
-            component: null,
-        },
-        cardVisible: true,
-        create: true,
-        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.shipped)),
-    },
-    {
-        align: 'left',
-        name: 'landed',
-        label: t('travel.travelList.tableVisibleColumns.landed'),
-        field: 'landed',
-        component: 'date',
-        columnField: {
-            component: null,
-        },
-        cardVisible: true,
-        create: true,
-        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)),
-    },
     {
         align: 'left',
         name: 'warehouseInFk',
         label: t('travel.travelList.tableVisibleColumns.warehouseIn'),
-        field: 'warehouseInFk',
         component: 'select',
         attrs: {
             url: 'warehouses',
@@ -123,11 +94,28 @@ const columns = computed(() => [
         cardVisible: true,
         create: true,
     },
+    {
+        align: 'left',
+        name: 'shipped',
+        label: t('travel.travelList.tableVisibleColumns.shipped'),
+        component: 'date',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.shipped)),
+    },
+    {
+        align: 'left',
+        name: 'shipmentHour',
+        label: t('travel.travelList.tableVisibleColumns.shipHour'),
+        cardVisible: true,
+    },
     {
         align: 'left',
         name: 'warehouseOutFk',
         label: t('travel.travelList.tableVisibleColumns.warehouseOut'),
-        field: 'warehouseOutFk',
         component: 'select',
         attrs: {
             url: 'warehouses',
@@ -140,12 +128,30 @@ const columns = computed(() => [
         cardVisible: true,
         create: true,
     },
+    {
+        align: 'left',
+        name: 'landed',
+        label: t('travel.travelList.tableVisibleColumns.landed'),
+        component: 'date',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)),
+    },
+    {
+        align: 'left',
+        name: 'landingHour',
+        label: t('travel.travelList.tableVisibleColumns.landHour'),
+        cardVisible: true,
+    },
     {
         align: 'left',
         name: 'totalEntries',
         label: t('travel.travelList.tableVisibleColumns.totalEntries'),
-        field: 'totalEntries',
         component: 'input',
+        toolTip: t('travel.travelList.tableVisibleColumns.totalEntriesTooltip'),
         columnField: {
             component: null,
         },
@@ -165,13 +171,15 @@ const columns = computed(() => [
             },
             {
                 title: t('Add entry'),
-                icon: 'contact_support',
+                icon: 'vn:ticket',
                 action: redirectCreateEntryView,
+                isPrimary: true,
             },
             {
-                title: t('View Summary'),
+                title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row.id, TravelSummary),
+                isPrimary: true,
             },
         ],
     },
@@ -202,12 +210,43 @@ const columns = computed(() => [
         redirect="travel"
         :is-editable="false"
         :use-model="true"
-    />
+    >
+        <template #column-shipped="{ row }">
+            <QBadge
+                text-color="black"
+                v-if="getDateQBadgeColor(row.shipped)"
+                :color="getDateQBadgeColor(row.shipped)"
+            >
+                {{ toDate(row.shipped) }}
+            </QBadge>
+            <span v-else>{{ toDate(row.shipped) }}</span>
+            <QIcon
+                name="flight_takeoff"
+                size="sm"
+                :class="{ 'is-active': row.isDelivered }"
+            />
+        </template>
+        <template #column-landed="{ row }">
+            <QBadge
+                text-color="black"
+                v-if="getDateQBadgeColor(row.landed)"
+                :color="getDateQBadgeColor(row.landed)"
+            >
+                {{ toDate(row.landed) }}
+            </QBadge>
+            <span v-else>{{ toDate(row.landed) }}</span>
+            <QIcon
+                name="flight_land"
+                size="sm"
+                :class="{ 'is-active': row.isReceived }"
+            />
+        </template>
+    </VnTable>
 </template>
 
 <i18n>
 en:
-    addEntry: Add entry
+    Add entry: Add entry
     searchByIdOrReference: Search by ID or reference
 
 es:
@@ -215,4 +254,12 @@ es:
     searchByIdOrReference: Buscar por ID o por referencia
     You can search by travel id or name: Buscar por envio por id o nombre
     Search travel: Buscar envio
+    Clone: Clonar
+    Add entry: Añadir Entrada
 </i18n>
+
+<style lang="scss" scoped>
+.is-active {
+    color: #c8e484;
+}
+</style>
diff --git a/src/pages/Wagon/Type/WagonCreateTray.vue b/src/pages/Wagon/Type/WagonCreateTray.vue
new file mode 100644
index 000000000..304fa83ac
--- /dev/null
+++ b/src/pages/Wagon/Type/WagonCreateTray.vue
@@ -0,0 +1,116 @@
+<script setup>
+import { ref, watch } from 'vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import FormPopup from 'src/components/FormPopup.vue';
+import VnRow from 'src/components/ui/VnRow.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import FetchData from 'src/components/FetchData.vue';
+import { useI18n } from 'vue-i18n';
+import axios from 'axios';
+
+const $props = defineProps({
+    entityId: {
+        type: Number,
+        required: true,
+    },
+    height: {
+        type: Number,
+        default: 0,
+    },
+    color: {
+        type: Array,
+        default: () => [],
+    },
+});
+const entityId = ref($props.entityId);
+const selectedTrayColor = ref();
+const trayHeight = ref();
+const wagonColors = ref([]);
+const wagonColorTranslated = ref();
+const heights = ref();
+const existingTrayHeight = ref($props.height);
+const { t } = useI18n();
+
+watch(wagonColors, () => {
+    wagonColorTranslated.value = wagonColors.value.map((color) => {
+        return { ...color, name: t(`colors.${color.name}`) };
+    });
+});
+const emit = defineEmits(['onSubmit']);
+
+async function getTrays() {
+    const { data } = await axios.get('WagonTypeTrays', undefined, {
+        filter: { wagonTypeFk: entityId.value },
+    });
+    existingTrayHeight.value = data.filter((item) => item.wagonTypeFk == entityId.value);
+    heights.value = existingTrayHeight.value.map((item) => item.height);
+}
+
+function onSubmit() {
+    emit('onSubmit', {
+        wagonTypeFk: entityId.value,
+        wagonTypeColorFk: selectedTrayColor.value,
+        height: trayHeight.value,
+    });
+}
+getTrays();
+</script>
+
+<template>
+    <FetchData
+        url="WagonTypeColors"
+        @on-fetch="(data) => (wagonColors = data)"
+        auto-load
+    />
+    <FormPopup
+        ref="createTrayFormDialogRef"
+        @on-submit="onSubmit()"
+        :title="t('Add new tray')"
+        :entity-id="selectedEntityId"
+    >
+        <template #form-inputs>
+            <VnRow class="row q-gutter-md q-mb-md">
+                <VnSelect
+                    v-model="selectedTrayColor"
+                    :options="wagonColorTranslated"
+                    option-label="name"
+                    option-value="id"
+                    id="id"
+                    :label="t('Select a tray color')"
+                    :required="true"
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps" clickable>
+                            <QItemSection>
+                                <QItemLabel>{{ scope.opt.name }}</QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
+                <VnInput v-model="trayHeight" :label="t('Height')" type="number" />
+            </VnRow>
+        </template>
+    </FormPopup>
+</template>
+
+<i18n>
+    en:
+        Select a tray: Select a tray
+        colors:
+            white: White
+            red: Red
+            green: Green
+            blue: Blue
+    es:
+        Select a tray color: Seleccione un color
+        Add new tray: Añadir nueva bandeja
+        Height: Altura
+        The minimum height between trays is 50cm: La altura mínima entre bandejas es de 50cm
+        The maximum height of the wagon is 200cm: La altura máxima del vagón es de 200cm
+        A tray with the same height already exists, try with a different height: Ya existe una bandeja con la misma altura, prueba con una diferente
+        colors:
+            white: Blanco
+            red: Rojo
+            green: Verde
+            blue: Azul
+</i18n>
diff --git a/src/pages/Wagon/Type/WagonTypeCreate.vue b/src/pages/Wagon/Type/WagonTypeCreate.vue
deleted file mode 100644
index bc9c1a40c..000000000
--- a/src/pages/Wagon/Type/WagonTypeCreate.vue
+++ /dev/null
@@ -1,433 +0,0 @@
-<script setup>
-import { computed, ref, onMounted, onUpdated } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
-import { useQuasar } from 'quasar';
-
-import VnInput from 'src/components/common/VnInput.vue';
-
-import { useI18n } from 'vue-i18n';
-import axios from 'axios';
-
-onMounted(() => fetch());
-onUpdated(() => fetch());
-
-const { t } = useI18n();
-const route = useRoute();
-const quasar = useQuasar();
-const router = useRouter();
-const $props = defineProps({
-    id: {
-        type: Number,
-        required: false,
-        default: null,
-    },
-});
-const entityId = computed(() => $props.id || route.params.id);
-
-const wagon = ref([]);
-const divisible = ref(false);
-const name = ref('');
-const colorPickerActive = ref(false);
-let originalData = { trays: [] };
-let wagonConfig;
-let wagonTypeColors;
-let currentTrayColorPicked;
-
-async function fetch() {
-    try {
-        await axios.get('WagonConfigs').then(async (res) => {
-            if (res.data) {
-                wagonConfig = res.data[0];
-            }
-        });
-
-        await axios.get(`WagonTypeColors`).then(async (res) => {
-            if (res.data) {
-                wagonTypeColors = res.data;
-                if (!entityId.value)
-                    wagon.value.push({
-                        id: 0,
-                        position: 0,
-                        color: { ...wagonTypeColors[0] },
-                        action: 'add',
-                    });
-                else {
-                    await axios
-                        .get(`WagonTypeTrays`, {
-                            params: { filter: { where: { typeFk: entityId.value } } },
-                        })
-                        .then(async (res) => {
-                            if (res.data) {
-                                for (let i = 0; i < res.data.length; i++) {
-                                    const tray = res.data[i];
-                                    wagon.value.push({
-                                        id: res.data.length - i - 1,
-                                        position: tray.height,
-                                        color: {
-                                            ...wagonTypeColors.find((color) => {
-                                                return color.id === tray.colorFk;
-                                            }),
-                                        },
-                                        action: tray.height == 0 ? 'add' : 'delete',
-                                    });
-                                }
-                                wagon.value.forEach((value) => {
-                                    originalData.trays.push({ ...value });
-                                });
-                            }
-                        });
-                }
-            }
-        });
-
-        if (entityId.value) {
-            await axios.get(`WagonTypes/${entityId.value}`).then((res) => {
-                if (res.data) {
-                    originalData.name = name.value = res.data.name;
-                    originalData.divisible = divisible.value = res.data.divisible;
-                }
-            });
-        }
-    } catch (e) {
-        //
-    }
-}
-
-function addTray() {
-    if (
-        wagon.value.find((tray) => {
-            return tray.position == null;
-        })
-    ) {
-        quasar.notify({
-            message: t('wagon.warnings.uncompleteTrays'),
-            type: 'warning',
-        });
-        return;
-    }
-
-    if (wagon.value.length < wagonConfig.maxTrays) {
-        wagon.value.unshift({
-            id: wagon.value.length,
-            position: null,
-            color: { ...wagonTypeColors[0] },
-            action: 'delete',
-        });
-    } else {
-        quasar.notify({
-            message: t('wagon.warnings.maxTrays'),
-            type: 'warning',
-        });
-    }
-}
-
-function deleteTray(trayToDelete) {
-    wagon.value = wagon.value.filter((tray) => tray.id !== trayToDelete.id);
-    reorderIds();
-}
-
-function reorderIds() {
-    for (let index = wagon.value.length - 1; index >= 0; index--) {
-        wagon.value[index].id = index;
-    }
-}
-
-async function onSubmit() {
-    try {
-        const path = entityId.value
-            ? 'WagonTypes/editWagonType'
-            : 'WagonTypes/createWagonType';
-
-        const params = {
-            id: entityId.value,
-            name: name.value,
-            divisible: divisible.value,
-            trays: wagon.value,
-        };
-
-        await axios.patch(path, params).then((res) => {
-            if (res.status == 204) router.push({ path: `/wagon/type/list` });
-        });
-    } catch (error) {
-        //
-    }
-}
-
-function onReset() {
-    name.value = entityId.value ? originalData.name : null;
-    divisible.value = entityId.value ? originalData.divisible : false;
-    wagon.value = entityId.value
-        ? [...originalData.trays]
-        : [
-              {
-                  id: 0,
-                  position: 0,
-                  color: { ...wagonTypeColors[0] },
-                  action: 'add',
-              },
-          ];
-}
-
-function doAction(tray) {
-    if (tray.action == 'add') {
-        addTray();
-    } else {
-        deleteTray(tray);
-    }
-}
-
-function showColorPicker(tray) {
-    colorPickerActive.value = true;
-    currentTrayColorPicked = wagon.value.findIndex((val) => {
-        return val.id === tray.id;
-    });
-}
-
-function updateColor(newColor) {
-    wagon.value[currentTrayColorPicked].color = {
-        ...wagonTypeColors.find((color) => {
-            return color.rgb === newColor;
-        }),
-    };
-}
-
-function onPositionBlur(tray) {
-    if (tray.position) {
-        if (tray.position == '' || tray.position < 0) {
-            tray.position = null;
-            return;
-        }
-        tray.position = parseInt(tray.position);
-        wagon.value.sort((a, b) => b.position - a.position);
-        reorderIds();
-        for (let index = wagon.value.length - 1; index > 0; index--) {
-            if (exceedMaxHeight(index - 1)) continue;
-            if (
-                wagon.value[index - 1].position - wagon.value[index].position >=
-                wagonConfig.minHeightBetweenTrays
-            ) {
-                continue;
-            } else {
-                wagon.value[index - 1].position +=
-                    wagonConfig.minHeightBetweenTrays -
-                    (wagon.value[index - 1].position - wagon.value[index].position);
-
-                quasar.notify({
-                    message:
-                        t('wagon.warnings.minHeightBetweenTrays') +
-                        wagonConfig.minHeightBetweenTrays +
-                        ' cm',
-                    type: 'warning',
-                });
-
-                exceedMaxHeight(index - 1);
-            }
-        }
-    }
-}
-
-function exceedMaxHeight(pos) {
-    if (wagon.value[pos].position > wagonConfig.maxWagonHeight) {
-        wagon.value.splice(pos, 1);
-        quasar.notify({
-            message:
-                t('wagon.warnings.maxWagonHeight') + wagonConfig.maxWagonHeight + ' cm',
-            type: 'warning',
-        });
-        return true;
-    }
-    return false;
-}
-</script>
-
-<template>
-    <QPage class="q-pa-sm q-mx-xl">
-        <QForm @submit="onSubmit()" @reset="onReset()" class="q-pa-sm">
-            <QCard class="q-pa-md">
-                <VnInput
-                    filled
-                    v-model="name"
-                    :label="t('wagon.type.name')"
-                    :rules="[(val) => !!val || t('wagon.warnings.nameNotEmpty')]"
-                />
-                <QCheckbox class="q-mb-sm" v-model="divisible" label="Divisible" />
-                <div class="wagon-tray q-mx-lg" v-for="tray in wagon" :key="tray.id">
-                    <div class="position">
-                        <QInput
-                            autofocus
-                            filled
-                            type="number"
-                            :class="{ isVisible: tray.action == 'add' }"
-                            v-model="tray.position"
-                            @blur="onPositionBlur(tray)"
-                        >
-                            <QTooltip :delay="2000">
-                                {{
-                                    t('wagon.warnings.minHeightBetweenTrays') +
-                                    wagonConfig.minHeightBetweenTrays +
-                                    ' cm'
-                                }}
-                                <QSpace />
-                                {{
-                                    t('wagon.warnings.maxWagonHeight') +
-                                    wagonConfig.maxWagonHeight +
-                                    ' cm'
-                                }}
-                            </QTooltip>
-                        </QInput>
-                    </div>
-                    <div class="shelving">
-                        <div class="shelving-half">
-                            <div class="shelving-up"></div>
-                            <div
-                                class="shelving-down"
-                                :style="{ backgroundColor: tray.color.rgb }"
-                                @click="showColorPicker(tray)"
-                            ></div>
-                        </div>
-                        <div
-                            class="shelving-divisible"
-                            :class="{ isVisible: !divisible }"
-                        ></div>
-                        <div class="shelving-half">
-                            <div class="shelving-up"></div>
-                            <div
-                                class="shelving-down"
-                                :style="{ backgroundColor: tray.color.rgb }"
-                                @click="showColorPicker(tray)"
-                            ></div>
-                        </div>
-                    </div>
-                    <div class="action-button">
-                        <QBtn
-                            flat
-                            round
-                            color="primary"
-                            :icon="tray.action"
-                            @click="doAction(tray)"
-                        />
-                    </div>
-                </div>
-                <div class="q-mb-sm wheels">
-                    <QIcon color="grey-6" name="trip_origin" size="xl" />
-                    <QIcon color="grey-6" name="trip_origin" size="xl" />
-                </div>
-                <QDialog
-                    v-model="colorPickerActive"
-                    position="right"
-                    :no-backdrop-dismiss="false"
-                >
-                    <QCard>
-                        <QCardSection>
-                            <div class="text-h6">{{ t('wagon.type.trayColor') }}</div>
-                        </QCardSection>
-                        <QCardSection class="row items-center no-wrap">
-                            <QColor
-                                flat
-                                v-model="wagon[currentTrayColorPicked].color.rgb"
-                                no-header
-                                no-footer
-                                default-view="palette"
-                                :palette="
-                                    wagonTypeColors.map((color) => {
-                                        return color.rgb;
-                                    })
-                                "
-                                @change="updateColor($event)"
-                            />
-                            <QBtn flat round icon="close" v-close-popup />
-                        </QCardSection>
-                    </QCard>
-                </QDialog>
-            </QCard>
-            <div class="q-mt-md">
-                <QBtn :label="t('wagon.type.submit')" type="submit" color="primary" />
-                <QBtn
-                    :label="t('wagon.type.reset')"
-                    type="reset"
-                    color="primary"
-                    flat
-                    class="q-ml-sm"
-                />
-            </div>
-        </QForm>
-    </QPage>
-</template>
-
-<style lang="scss" scoped>
-.q-page {
-    display: flex;
-    justify-content: center;
-    align-items: flex-start;
-}
-
-.q-form {
-    width: 70%;
-}
-
-.q-dialog {
-    .q-card {
-        width: 100%;
-    }
-}
-
-.wheels {
-    margin-left: 5%;
-    display: flex;
-    justify-content: space-around;
-}
-
-.wagon-tray {
-    display: flex;
-    height: 6rem;
-
-    .position {
-        width: 20%;
-        border-right: 1rem solid gray;
-        display: flex;
-        align-items: flex-end;
-        justify-content: flex-end;
-        padding-right: 1rem;
-    }
-
-    .shelving {
-        display: flex;
-        width: 75%;
-
-        .shelving-half {
-            width: 50%;
-            height: 100%;
-
-            .shelving-up {
-                height: 80%;
-                width: 100%;
-            }
-
-            .shelving-down {
-                height: 20%;
-                width: 100%;
-            }
-        }
-
-        .shelving-divisible {
-            width: 1%;
-            height: 100%;
-            border-left: 0.5rem dashed grey;
-            border-right: 0.5rem dashed grey;
-        }
-    }
-
-    .action-button {
-        width: 10%;
-        border-left: 1rem solid gray;
-        display: flex;
-        align-items: flex-end;
-        justify-content: flex-start;
-        padding-left: 1rem;
-    }
-
-    .isVisible {
-        display: none;
-    }
-}
-</style>
diff --git a/src/pages/Wagon/Type/WagonTypeEdit.vue b/src/pages/Wagon/Type/WagonTypeEdit.vue
new file mode 100644
index 000000000..eb8205d72
--- /dev/null
+++ b/src/pages/Wagon/Type/WagonTypeEdit.vue
@@ -0,0 +1,293 @@
+<script setup>
+import { computed, ref, watch } from 'vue';
+import { useRoute } from 'vue-router';
+import { useQuasar } from 'quasar';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
+import FormModel from 'src/components/FormModel.vue';
+import { useI18n } from 'vue-i18n';
+import axios from 'axios';
+import VnPaginate from 'components/ui/VnPaginate.vue';
+import WagonCreateTray from './WagonCreateTray.vue';
+
+const { t } = useI18n();
+const { notify } = useQuasar();
+const route = useRoute();
+const entityId = computed(() => route.params.id);
+const wagonTrays = ref([]);
+const createTrayFormDialogRef = ref();
+const selectedEntityId = ref();
+
+async function loadTrays() {
+    try {
+        const res = await axios.get('WagonTypeTrays');
+        const filteredTrays = res.data.filter(
+            (tray) => tray.wagonTypeFk === entityId.value
+        );
+        wagonTrays.value = filteredTrays;
+        return;
+    } catch (err) {
+        console.error('Error loading trays:', err);
+    }
+}
+
+async function addTray(newTray) {
+    const res = await axios.post(`WagonTypeTrays`, newTray);
+    wagonTrays.value.push(res.data);
+    notify({
+        message: t(`Tray added successfully`),
+        type: 'positive',
+    });
+}
+
+async function deleteTray(trayToDelete) {
+    await axios.delete(`WagonTypeTrays/${trayToDelete.id}`);
+    const index = wagonTrays.value.findIndex((tray) => tray.id === trayToDelete.id);
+    if (index !== -1) {
+        wagonTrays.value.splice(index, 1);
+    }
+    notify({
+        message: t('Tray deleted successfully'),
+        type: 'positive',
+    });
+}
+
+const filter = {
+    where: { wagonTypeFk: entityId.value },
+    include: {
+        relation: 'color',
+        scope: {
+            fields: ['rgb'],
+        },
+    },
+};
+
+const formFilter = { where: { wagonTypeFk: entityId.value } };
+
+const showCreateTrayForm = (id) => {
+    selectedEntityId.value = id;
+    createTrayFormDialogRef.value.show();
+};
+
+watch(
+    () => wagonTrays.value,
+    async (newVal, oldVal) => {
+        if (newVal.length !== oldVal.length) {
+            await loadTrays();
+        }
+    },
+    { deep: true }
+);
+</script>
+
+<template>
+    <VnSubToolbar />
+    <QPage class="q-pa-sm q-mx-xl">
+        <FormModel
+            :url="`WagonTypes/ ${entityId}`"
+            :url-update="`WagonTypes/ ${entityId}`"
+            :filter="formFilter"
+            model="WagonType"
+            auto-load
+        >
+            <template #form="{ data }">
+                <QCard class="q-pa-md">
+                    <VnInput
+                        filled
+                        v-model="data.name"
+                        :label="t('wagon.type.name')"
+                        :rules="[(val) => !!val || t('wagon.warnings.nameNotEmpty')]"
+                    />
+                    <QCheckbox
+                        class="q-mb-sm"
+                        v-model="data.divisible"
+                        label="Divisible"
+                    />
+
+                    <VnPaginate
+                        data-key="wagonTypeTray"
+                        url="WagonTypeTrays"
+                        order="id DESC"
+                        :filter="filter"
+                        auto-load
+                        ref="vnPaginateRef"
+                        v-bind="$attrs"
+                        :key="wagonTrays.length"
+                    >
+                        <template #body="{ rows }">
+                            <div v-for="row in rows" :key="row.id">
+                                <div class="shelving"></div>
+                                <div class="action-button">
+                                    <div class="wagon-tray q-mx-lg">
+                                        <div class="position">
+                                            <VnInput
+                                                borderless
+                                                type="number"
+                                                disable
+                                                class="input-tray q-mb-sm"
+                                                :label="t('Height') + ': '"
+                                                v-model="row.height"
+                                            />
+                                        </div>
+                                        <div class="shelving">
+                                            <div class="shelving-half">
+                                                <div class="shelving-up"></div>
+                                                <div
+                                                    class="shelving-down"
+                                                    :style="{
+                                                        backgroundColor: row.color.rgb,
+                                                    }"
+                                                ></div>
+                                            </div>
+                                            <div
+                                                class="shelving-divisible"
+                                                :class="{ isVisible: !data.divisible }"
+                                            ></div>
+                                            <div class="shelving-half">
+                                                <div class="shelving-up"></div>
+                                                <div
+                                                    class="shelving-down"
+                                                    :style="{
+                                                        backgroundColor: row.color.rgb,
+                                                    }"
+                                                ></div>
+                                            </div>
+                                        </div>
+                                        <div class="action-button">
+                                            <QBtn
+                                                v-if="row.height === 0"
+                                                flat
+                                                round
+                                                color="primary"
+                                                :icon="'add'"
+                                                class="btn-tray"
+                                                @click="showCreateTrayForm(entityId)"
+                                            />
+                                            <QBtn
+                                                v-else
+                                                flat
+                                                round
+                                                color="primary"
+                                                :icon="'delete'"
+                                                class="btn-tray"
+                                                @click="deleteTray(row)"
+                                            />
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </template>
+                    </VnPaginate>
+                    <div class="q-mb-sm wheels">
+                        <QIcon color="grey-6" name="trip_origin" size="xl" />
+                        <QIcon color="grey-6" name="trip_origin" size="xl" />
+                    </div>
+                </QCard>
+                <QDialog ref="createTrayFormDialogRef">
+                    <WagonCreateTray :entity-id="entityId" @on-submit="addTray($event)" />
+                </QDialog>
+            </template>
+        </FormModel>
+    </QPage>
+</template>
+
+<style lang="scss" scoped>
+.q-page {
+    display: flex;
+    justify-content: center;
+    align-items: flex-start;
+}
+
+.q-form {
+    width: 70%;
+}
+
+.q-dialog {
+    .q-card {
+        width: 100%;
+    }
+}
+
+.wheels {
+    margin-left: 5%;
+    display: flex;
+    justify-content: space-around;
+}
+
+.wagon-tray {
+    display: flex;
+    height: 6rem;
+
+    .position {
+        width: 26%;
+        border-right: 1rem solid gray;
+        display: flex;
+        align-items: flex-start;
+        justify-content: flex-start;
+        padding-right: 2rem;
+        padding-left: 3rem;
+    }
+
+    .shelving {
+        display: flex;
+        width: 54%;
+
+        .shelving-half {
+            width: 100%;
+            height: 100%;
+
+            .shelving-up {
+                height: 80%;
+                width: 100%;
+            }
+
+            .shelving-down {
+                height: 20%;
+                width: 100%;
+            }
+        }
+
+        .shelving-divisible {
+            width: 1%;
+            height: 100%;
+            border-left: 0.5rem dashed grey;
+            border-right: 0.5rem dashed grey;
+        }
+    }
+
+    .action-button {
+        width: 20%;
+        border-left: 1rem solid gray;
+        align-items: baseline;
+        padding-left: 3rem;
+    }
+
+    .isVisible {
+        display: none;
+    }
+}
+.btn-tray {
+    margin-right: 100%;
+    margin-top: 100%;
+}
+.input-tray {
+    margin-top: 100%;
+    margin-left: 40%;
+}
+</style>
+
+<i18n>
+    en:
+        tray: Tray
+        wagonColor: Wagon color
+        Select a tray: Select a tray
+    es:
+        tray: Bandeja
+        wagonColor: Color de la bandeja
+        Select a tray: Seleccione una bandeja
+        Create new Wagon type: Crear nuevo tipo de vagón
+        Add new tray: Añadir nueva bandeja
+        Height: Altura
+        Tray added successfully: Bandeja añadida correctamente
+        Tray deleted successfully: Bandeja eliminada correctamente
+</i18n>
diff --git a/src/pages/Wagon/Type/WagonTypeList.vue b/src/pages/Wagon/Type/WagonTypeList.vue
index 3ecca1ea3..7615dea02 100644
--- a/src/pages/Wagon/Type/WagonTypeList.vue
+++ b/src/pages/Wagon/Type/WagonTypeList.vue
@@ -1,4 +1,5 @@
 <script setup>
+import { ref, computed } from 'vue';
 import axios from 'axios';
 import { useQuasar } from 'quasar';
 import VnPaginate from 'src/components/ui/VnPaginate.vue';
@@ -6,36 +7,40 @@ import { useArrayData } from 'src/composables/useArrayData';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
 import CardList from 'components/ui/CardList.vue';
+import FormModelPopup from 'src/components/FormModelPopup.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnRow from 'src/components/ui/VnRow.vue';
 
 const quasar = useQuasar();
 const arrayData = useArrayData('WagonTypeList');
 const store = arrayData.store;
-const router = useRouter();
+const dialog = ref();
+const { push } = useRouter();
 const { t } = useI18n();
+const paginate = ref();
 
-function navigate(id) {
-    router.push({ path: `/wagon/type/${id}/edit` });
+const initialData = computed(() => {
+    return {
+        name: null,
+    };
+});
+
+function reloadData() {
+    initialData.value.name = null;
+    paginate.value.fetch();
 }
 
-function create() {
-    router.push({ path: `/wagon/type/create` });
+function navigate(id, name) {
+    push({ path: `/wagon/type/${id}/edit`, query: { name } });
 }
 
 async function remove(row) {
-    try {
-        const id = row.id;
-        await axios
-            .delete(`WagonTypes/deleteWagonType`, { params: { id } })
-            .then(async () => {
-                quasar.notify({
-                    message: t('wagon.type.removeItem'),
-                    type: 'positive',
-                });
-                store.data.splice(store.data.indexOf(row), 1);
-            });
-    } catch (error) {
-        //
-    }
+    await axios.delete(`WagonTypes/${row.id}`);
+    quasar.notify({
+        message: t('wagon.type.removeItem'),
+        type: 'positive',
+    });
+    store.data.splice(store.data.indexOf(row), 1);
 }
 </script>
 
@@ -43,8 +48,9 @@ async function remove(row) {
     <QPage class="column items-center q-pa-md">
         <div class="vn-card-list">
             <VnPaginate
+                ref="paginate"
                 data-key="WagonTypeList"
-                url="/WagonTypes"
+                url="WagonTypes"
                 order="id DESC"
                 auto-load
             >
@@ -54,12 +60,19 @@ async function remove(row) {
                         :key="row.id"
                         :title="(row.name || '').toString()"
                         :id="row.id"
-                        @click="navigate(row.id)"
+                        @click="navigate(row.id, row.name)"
                     >
+                        <template #list-items>
+                            <QCheckbox
+                                :label="t('Divisble')"
+                                :model-value="row.divisible"
+                                disable
+                            />
+                        </template>
                         <template #actions>
                             <QBtn
                                 :label="t('components.smartCard.openCard')"
-                                @click.stop="navigate(row.id)"
+                                @click.stop="navigate(row.id, row.name)"
                                 outline
                             />
                             <QBtn
@@ -73,8 +86,42 @@ async function remove(row) {
                 </template>
             </VnPaginate>
         </div>
-        <QPageSticky position="bottom-right" :offset="[18, 18]">
-            <QBtn @click="create" fab icon="add" color="primary" />
+        <QPageSticky :offset="[18, 18]">
+            <QBtn @click.stop="dialog.show()" color="primary" fab icon="add" shortcut="+">
+                <QDialog ref="dialog">
+                    <FormModelPopup
+                        :title="t('Create new Wagon type')"
+                        url-create="WagonTypes"
+                        model="WagonType"
+                        :form-initial-data="initialData"
+                        @on-data-saved="reloadData()"
+                        auto-load
+                    >
+                        <template #form-inputs="{ data }">
+                            <VnRow class="row q-gutter-md q-mb-md">
+                                <VnInput
+                                    filled
+                                    v-model="data.name"
+                                    :label="t('Name')"
+                                    :rules="[(val) => !!val || t('nameNotEmpty')]"
+                                />
+                            </VnRow>
+                        </template>
+                    </FormModelPopup>
+                </QDialog>
+            </QBtn>
+            <QTooltip>
+                {{ t('globals.new') }}
+            </QTooltip>
         </QPageSticky>
     </QPage>
 </template>
+
+<i18n>
+en:
+    nameNotEmpty: The name cannot be empty
+es:
+    Create new Wagon type: Crear nuevo tipo de vagón
+    Name: Nombre
+    nameNotEmpty: El nombre no puede estar vacío
+</i18n>
diff --git a/src/pages/Wagon/WagonList.vue b/src/pages/Wagon/WagonList.vue
index a8b6728c3..c4824b861 100644
--- a/src/pages/Wagon/WagonList.vue
+++ b/src/pages/Wagon/WagonList.vue
@@ -94,7 +94,7 @@ async function remove(row) {
             </VnPaginate>
         </div>
         <QPageSticky position="bottom-right" :offset="[18, 18]">
-            <QBtn @click="create" fab icon="add" color="primary" />
+            <QBtn @click="create" fab icon="add" color="primary" shortcut="+" />
         </QPageSticky>
     </QPage>
 </template>
diff --git a/src/pages/Worker/Card/WorkerBasicData.vue b/src/pages/Worker/Card/WorkerBasicData.vue
index 82203fc2a..d131fea3e 100644
--- a/src/pages/Worker/Card/WorkerBasicData.vue
+++ b/src/pages/Worker/Card/WorkerBasicData.vue
@@ -12,9 +12,12 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 const route = useRoute();
 const { t } = useI18n();
 
-const workersOptions = ref([]);
-const countriesOptions = ref([]);
-const educationLevelsOptions = ref([]);
+const educationLevels = ref([]);
+const countries = ref([]);
+const maritalStatus = [
+    { code: 'M', name: t('Married') },
+    { code: 'S', name: t('Single') },
+];
 
 const workerFilter = {
     include: [
@@ -29,44 +32,21 @@ const workerFilter = {
         { relation: 'department', scope: { include: { relation: 'department' } } },
     ],
 };
-const workersFilter = {
-    fields: ['id', 'nickname'],
-    order: 'nickname ASC',
-    limit: 30,
-};
-const countriesFilter = {
-    fields: ['id', 'name', 'code'],
-    order: 'name ASC',
-    limit: 30,
-};
-const educationLevelsFilter = { fields: ['id', 'name'], order: 'name ASC', limit: 30 };
-
-const maritalStatus = [
-    { code: 'M', name: t('Married') },
-    { code: 'S', name: t('Single') },
-];
 </script>
 
 <template>
     <FetchData
-        :filter="workersFilter"
-        @on-fetch="(data) => (workersOptions = data)"
-        auto-load
-        url="Workers/search"
-    />
-    <FetchData
-        :filter="countriesFilter"
-        @on-fetch="(data) => (countriesOptions = data)"
-        auto-load
-        url="Countries"
-    />
-    <FetchData
-        :filter="educationLevelsFilter"
-        @on-fetch="(data) => (educationLevelsOptions = data)"
+        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
+        @on-fetch="(data) => (educationLevels = data)"
         auto-load
         url="EducationLevels"
     />
-
+    <FetchData
+        url="Countries"
+        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
+        @on-fetch="(data) => (countries = data)"
+        auto-load
+    />
     <FormModel
         :filter="workerFilter"
         :url="`Workers/${route.params.id}`"
@@ -90,7 +70,7 @@ const maritalStatus = [
             <VnRow>
                 <VnSelect
                     :label="t('Boss')"
-                    :options="workersOptions"
+                    url="Workers/search"
                     hide-selected
                     option-label="nickname"
                     option-value="id"
@@ -121,7 +101,7 @@ const maritalStatus = [
             <VnRow>
                 <VnSelect
                     :label="t('Origin country')"
-                    :options="countriesOptions"
+                    :options="countries"
                     hide-selected
                     option-label="name"
                     option-value="id"
@@ -129,7 +109,7 @@ const maritalStatus = [
                 />
                 <VnSelect
                     :label="t('Education level')"
-                    :options="educationLevelsOptions"
+                    :options="educationLevels"
                     hide-selected
                     option-label="name"
                     option-value="id"
diff --git a/src/pages/Worker/Card/WorkerCalendarItem.vue b/src/pages/Worker/Card/WorkerCalendarItem.vue
index 91e118708..05a013d6b 100644
--- a/src/pages/Worker/Card/WorkerCalendarItem.vue
+++ b/src/pages/Worker/Card/WorkerCalendarItem.vue
@@ -152,7 +152,7 @@ const getEventAttrs = (timestamp) => {
 
     if (isFestive) {
         attrs.class = '--festive';
-        attrs.label = event.absenceId ?? timestamp.day;
+        attrs.label = timestamp.day;
     } else attrs.class = `--${type}`;
 
     return attrs;
diff --git a/src/pages/Worker/Card/WorkerCard.vue b/src/pages/Worker/Card/WorkerCard.vue
index 0abcdcafd..5f9fa0f8e 100644
--- a/src/pages/Worker/Card/WorkerCard.vue
+++ b/src/pages/Worker/Card/WorkerCard.vue
@@ -15,5 +15,6 @@ import WorkerFilter from '../WorkerFilter.vue';
             label: 'Search worker',
             info: 'You can search by worker id or name',
         }"
+        :redirect-on-error="true"
     />
 </template>
diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue
index 8fbb23ef8..be30537df 100644
--- a/src/pages/Worker/Card/WorkerDescriptor.vue
+++ b/src/pages/Worker/Card/WorkerDescriptor.vue
@@ -1,15 +1,15 @@
 <script setup>
-import { computed, ref, watch } from 'vue';
+import { computed, ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
 import WorkerChangePasswordForm from 'src/pages/Worker/Card/WorkerChangePasswordForm.vue';
-import useCardDescription from 'src/composables/useCardDescription';
 import { useState } from 'src/composables/useState';
 import axios from 'axios';
 import VnImg from 'src/components/ui/VnImg.vue';
+import EditPictureForm from 'components/EditPictureForm.vue';
 
 const $props = defineProps({
     id: {
@@ -18,6 +18,7 @@ const $props = defineProps({
         default: null,
     },
 });
+const image = ref(null);
 
 const route = useRoute();
 const { t } = useI18n();
@@ -25,6 +26,10 @@ const state = useState();
 const user = state.getUser();
 const changePasswordFormDialog = ref(null);
 const cardDescriptorRef = ref(null);
+const showEditPhotoForm = ref(false);
+const toggleEditPictureForm = () => {
+    showEditPhotoForm.value = !showEditPhotoForm.value;
+};
 
 const entityId = computed(() => {
     return $props.id || route.params.id;
@@ -32,49 +37,6 @@ const entityId = computed(() => {
 
 const worker = ref();
 const workerExcluded = ref(false);
-const filter = {
-    include: [
-        {
-            relation: 'user',
-            scope: {
-                fields: ['email', 'name', 'nickname'],
-            },
-        },
-        {
-            relation: 'department',
-            scope: {
-                include: [
-                    {
-                        relation: 'department',
-                    },
-                ],
-            },
-        },
-        {
-            relation: 'sip',
-        },
-    ],
-};
-
-const sip = ref(null);
-watch(
-    () => [worker.value?.sip?.extension, state.get('extension')],
-    ([newWorkerSip, newStateExtension], [oldWorkerSip, oldStateExtension]) => {
-        if (newStateExtension !== oldStateExtension || sip.value === oldStateExtension) {
-            sip.value = newStateExtension;
-        } else if (newWorkerSip !== oldWorkerSip && sip.value !== newStateExtension) {
-            sip.value = newWorkerSip;
-        }
-    }
-);
-
-const data = ref(useCardDescription());
-const setData = (entity) => {
-    if (!entity) return;
-    data.value = useCardDescription(entity.user?.nickname, entity.id);
-};
-
-const openChangePasswordForm = () => changePasswordFormDialog.value.show();
 
 const getIsExcluded = async () => {
     try {
@@ -99,7 +61,9 @@ const handleExcluded = async () => {
 
     workerExcluded.value = !workerExcluded.value;
 };
-
+const handlePhotoUpdated = (evt = false) => {
+    image.value.reload(evt);
+};
 const refetch = async () => await cardDescriptorRef.value.getData();
 </script>
 <template>
@@ -107,14 +71,12 @@ const refetch = async () => await cardDescriptorRef.value.getData();
         ref="cardDescriptorRef"
         module="Worker"
         data-key="workerData"
-        :url="`Workers/${entityId}`"
-        :filter="filter"
-        :title="data.title"
-        :subtitle="data.subtitle"
+        url="Workers/descriptor"
+        :filter="{ where: { id: entityId } }"
+        title="user.nickname"
         @on-fetch="
             (data) => {
                 worker = data;
-                setData(data);
                 getIsExcluded();
             }
         "
@@ -133,7 +95,7 @@ const refetch = async () => await cardDescriptorRef.value.getData();
                 v-if="!worker.user.emailVerified && user.id != worker.id"
                 v-ripple
                 clickable
-                @click="openChangePasswordForm()"
+                @click="$refs.changePasswordFormDialog.show()"
             >
                 <QItemSection>
                     {{ t('Change password') }}
@@ -144,30 +106,52 @@ const refetch = async () => await cardDescriptorRef.value.getData();
             </QItem>
         </template>
         <template #before>
-            <VnImg
-                :id="parseInt(entityId)"
-                collection="user"
-                resolution="520x520"
-                class="photo"
-            >
-                <template #error>
-                    <div
-                        class="absolute-full picture text-center q-pa-md flex flex-center"
-                    >
-                        <div>
-                            <div class="text-grey-5" style="opacity: 0.4; font-size: 5vh">
-                                <QIcon name="vn:claims" />
-                            </div>
-                            <div class="text-grey-5" style="opacity: 0.4">
-                                {{ t('worker.imageNotFound') }}
+            <div class="relative-position">
+                <VnImg
+                    ref="image"
+                    :id="parseInt(entityId)"
+                    collection="user"
+                    resolution="520x520"
+                    class="photo"
+                >
+                    <template #error>
+                        <div
+                            class="absolute-full picture text-center q-pa-md flex flex-center"
+                        >
+                            <div>
+                                <div
+                                    class="text-grey-5"
+                                    style="opacity: 0.4; font-size: 5vh"
+                                >
+                                    <QIcon name="vn:claims" />
+                                </div>
+                                <div class="text-grey-5" style="opacity: 0.4">
+                                    {{ t('worker.imageNotFound') }}
+                                </div>
                             </div>
                         </div>
-                    </div>
-                </template>
-            </VnImg>
+                    </template> </VnImg
+                ><QBtn
+                    color="primary"
+                    size="lg"
+                    round
+                    class="edit-photo-btn"
+                    @click="toggleEditPictureForm()"
+                >
+                    <QIcon name="edit" size="sm" />
+                    <QDialog ref="editPhotoFormDialog" v-model="showEditPhotoForm">
+                        <EditPictureForm
+                            collection="user"
+                            :id="entityId"
+                            @close-form="toggleEditPictureForm()"
+                            @on-photo-uploaded="handlePhotoUpdated"
+                        />
+                    </QDialog>
+                </QBtn>
+            </div>
         </template>
         <template #body="{ entity }">
-            <VnLv :label="t('worker.card.name')" :value="entity.user?.nickname" />
+            <VnLv :label="t('worker.card.user')" :value="entity.user?.name" />
             <VnLv :label="t('worker.card.email')" :value="entity.user?.email" copy />
             <VnLv
                 :label="t('worker.list.department')"
@@ -179,10 +163,10 @@ const refetch = async () => await cardDescriptorRef.value.getData();
                     <VnLinkPhone :phone-number="entity.phone" />
                 </template>
             </VnLv>
-            <VnLv :value="sip">
+            <VnLv :value="worker?.sip?.extension">
                 <template #label>
                     {{ t('worker.summary.sipExtension') }}
-                    <VnLinkPhone v-if="sip" :phone-number="sip" />
+                    <VnLinkPhone :phone-number="worker?.sip?.extension" />
                 </template>
             </VnLv>
         </template>
diff --git a/src/pages/Worker/Card/WorkerDms.vue b/src/pages/Worker/Card/WorkerDms.vue
index a4f7ef5a9..e2b62bc4f 100644
--- a/src/pages/Worker/Card/WorkerDms.vue
+++ b/src/pages/Worker/Card/WorkerDms.vue
@@ -10,6 +10,6 @@ const route = useRoute();
         delete-model="WorkerDms"
         download-model="WorkerDms"
         default-dms-code="hhrrData"
-        filter="worker"
+        filter="wd.workerFk"
     />
 </template>
diff --git a/src/pages/Worker/Card/WorkerFormation.vue b/src/pages/Worker/Card/WorkerFormation.vue
index 829326898..71c5cba5d 100644
--- a/src/pages/Worker/Card/WorkerFormation.vue
+++ b/src/pages/Worker/Card/WorkerFormation.vue
@@ -108,7 +108,7 @@ const columns = computed(() => [
         :filter="courseFilter"
         :create="{
             urlCreate: 'trainingCourses',
-            title: 'Create trainingCourse',
+            title: t('Create training course'),
             onDataSaved: () => tableRef.reload(),
             formInitialData: {
                 workerFk: entityId,
@@ -122,3 +122,7 @@ const columns = computed(() => [
         :use-model="true"
     />
 </template>
+<i18n>
+es:
+    Create training course: Crear curso de formación
+</i18n>
diff --git a/src/pages/Worker/Card/WorkerLocker.vue b/src/pages/Worker/Card/WorkerLocker.vue
index f19fc8ae6..4a19e472c 100644
--- a/src/pages/Worker/Card/WorkerLocker.vue
+++ b/src/pages/Worker/Card/WorkerLocker.vue
@@ -3,13 +3,13 @@ import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import axios from 'axios';
-import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 import FormModel from 'components/FormModel.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import { useArrayData } from 'src/composables/useArrayData';
 import FetchData from 'components/FetchData.vue';
 
-const { hasAny } = useRole();
+const { hasAny } = useAcl();
 const { t } = useI18n();
 const fetchData = ref();
 const originaLockerId = ref();
@@ -57,7 +57,11 @@ const init = async (data) => {
                 option-label="code"
                 option-value="id"
                 hide-selected
-                :readonly="!hasAny(['productionBoss', 'hr'])"
+                :readonly="
+                    !hasAny([
+                        { model: 'Worker', props: '__get__locker', accessType: 'READ' },
+                    ])
+                "
             />
         </template>
     </FormModel>
diff --git a/src/pages/Worker/Card/WorkerMedical.vue b/src/pages/Worker/Card/WorkerMedical.vue
new file mode 100644
index 000000000..6bca4ae85
--- /dev/null
+++ b/src/pages/Worker/Card/WorkerMedical.vue
@@ -0,0 +1,91 @@
+<script setup>
+import { ref, computed } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useRoute } from 'vue-router';
+import VnTable from 'components/VnTable/VnTable.vue';
+const tableRef = ref();
+const { t } = useI18n();
+const route = useRoute();
+const entityId = computed(() => route.params.id);
+
+const columns = [
+    {
+        align: 'left',
+        name: 'date',
+        label: t('worker.medical.tableVisibleColumns.date'),
+        create: true,
+        component: 'date',
+    },
+    {
+        align: 'left',
+        name: 'time',
+        label: t('worker.medical.tableVisibleColumns.time'),
+        create: true,
+        component: 'time',
+        attrs: {
+            timeOnly: true,
+        },
+    },
+    {
+        align: 'left',
+        name: 'centerFk',
+        label: t('worker.medical.tableVisibleColumns.center'),
+        create: true,
+        component: 'select',
+        attrs: {
+            url: 'medicalCenters',
+            fields: ['id', 'name'],
+        },
+    },
+    {
+        align: 'left',
+        name: 'invoice',
+        label: t('worker.medical.tableVisibleColumns.invoice'),
+        create: true,
+        component: 'input',
+    },
+    {
+        align: 'left',
+        name: 'amount',
+        label: t('worker.medical.tableVisibleColumns.amount'),
+        create: true,
+        component: 'input',
+    },
+    {
+        align: 'left',
+        name: 'isFit',
+        label: t('worker.medical.tableVisibleColumns.isFit'),
+        create: true,
+        component: 'checkbox',
+    },
+    {
+        align: 'left',
+        name: 'remark',
+        label: t('worker.medical.tableVisibleColumns.remark'),
+        create: true,
+        component: 'input',
+    },
+];
+</script>
+<template>
+    <VnTable
+        ref="tableRef"
+        data-key="WorkerMedical"
+        :url="`Workers/${entityId}/medicalReview`"
+        save-url="MedicalReviews/crud"
+        :create="{
+            urlCreate: 'medicalReviews',
+            title: t('Create medicalReview'),
+            onDataSaved: () => tableRef.reload(),
+            formInitialData: {
+                workerFk: entityId,
+            },
+        }"
+        order="date DESC"
+        :columns="columns"
+        auto-load
+        :right-search="false"
+        :is-editable="true"
+        :use-model="true"
+    />
+</template>
diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue
index 4e0abc20c..a53aac270 100644
--- a/src/pages/Worker/Card/WorkerPda.vue
+++ b/src/pages/Worker/Card/WorkerPda.vue
@@ -116,7 +116,7 @@ function reloadData() {
             </template>
         </VnPaginate>
         <QPageSticky :offset="[18, 18]">
-            <QBtn @click.stop="dialog.show()" color="primary" fab icon="add">
+            <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/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue
index 5c6261b94..0e7bfd863 100644
--- a/src/pages/Worker/Card/WorkerSummary.vue
+++ b/src/pages/Worker/Card/WorkerSummary.vue
@@ -10,7 +10,6 @@ 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 VnRow from 'src/components/ui/VnRow.vue';
 import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
 
 const route = useRoute();
@@ -35,13 +34,22 @@ const filter = {
         {
             relation: 'user',
             scope: {
-                fields: ['email', 'name', 'nickname', 'roleFk'],
-                include: {
-                    relation: 'role',
-                    scope: {
-                        fields: ['name'],
+                fields: ['name', 'nickname', 'roleFk'],
+
+                include: [
+                    {
+                        relation: 'role',
+                        scope: {
+                            fields: ['name'],
+                        },
                     },
-                },
+                    {
+                        relation: 'emailUser',
+                        scope: {
+                            fields: ['email'],
+                        },
+                    },
+                ],
             },
         },
         {
@@ -93,7 +101,6 @@ const filter = {
                         />
                     </template>
                 </VnLv>
-                <VnLv :label="t('worker.list.email')" :value="worker.user.email" copy />
                 <VnLv :label="t('worker.summary.boss')" link>
                     <template #value>
                         <VnUserLink
@@ -139,34 +146,34 @@ const filter = {
                 />
                 <VnLv :label="t('worker.summary.fi')" :value="worker.fi" />
                 <VnLv :label="t('worker.summary.birth')" :value="toDate(worker.birth)" />
-                <VnRow class="q-mt-sm" wrap>
-                    <VnLv
-                        :label="t('worker.summary.isFreelance')"
-                        :value="worker.isFreelance"
-                    />
-                    <VnLv
-                        :label="t('worker.summary.isSsDiscounted')"
-                        :value="worker.isSsDiscounted"
-                    />
-                    <VnLv
-                        :label="t('worker.summary.hasMachineryAuthorized')"
-                        :value="worker.hasMachineryAuthorized"
-                    />
-                    <VnLv
-                        :label="t('worker.summary.isDisable')"
-                        :value="worker.isDisable"
-                    />
-                </VnRow>
+                <VnLv
+                    :label="t('worker.summary.isFreelance')"
+                    :value="worker.isFreelance"
+                />
+                <VnLv
+                    :label="t('worker.summary.isSsDiscounted')"
+                    :value="worker.isSsDiscounted"
+                />
+                <VnLv
+                    :label="t('worker.summary.hasMachineryAuthorized')"
+                    :value="worker.hasMachineryAuthorized"
+                />
+                <VnLv :label="t('worker.summary.isDisable')" :value="worker.isDisable" />
             </QCard>
             <QCard class="vn-one">
                 <VnTitle :text="t('worker.summary.userData')" />
-                <VnLv :label="t('worker.summary.userId')" :value="worker.user.id" />
-                <VnLv :label="t('worker.card.name')" :value="worker.user.nickname" />
+                <VnLv :label="t('worker.summary.userId')" :value="worker?.user?.id" />
+                <VnLv :label="t('worker.card.name')" :value="worker?.user?.nickname" />
+                <VnLv
+                    :label="t('worker.list.email')"
+                    :value="worker.user?.emailUser?.email"
+                    copy
+                />
                 <VnLv :label="t('worker.summary.role')">
                     <template #value>
                         <span class="link">
-                            {{ worker.user.role.name }}
-                            <RoleDescriptorProxy :id="worker.user.role.id" />
+                            {{ worker?.user?.role?.name }}
+                            <RoleDescriptorProxy :id="worker?.user?.role?.id" />
                         </span>
                     </template>
                 </VnLv>
diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue
index 87ff44e63..abf60a078 100644
--- a/src/pages/Worker/Card/WorkerTimeControl.vue
+++ b/src/pages/Worker/Card/WorkerTimeControl.vue
@@ -13,6 +13,7 @@ import WorkerTimeControlCalendar from 'pages/Worker/Card/WorkerTimeControlCalend
 import useNotify from 'src/composables/useNotify.js';
 import axios from 'axios';
 import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 import { useWeekdayStore } from 'src/stores/useWeekdayStore';
 import { useStateStore } from 'stores/useStateStore';
 import { useState } from 'src/composables/useState';
@@ -26,7 +27,6 @@ import { date } from 'quasar';
 const route = useRoute();
 const { t, locale } = useI18n();
 const { notify } = useNotify();
-const { hasAny } = useRole();
 const _state = useState();
 const user = _state.getUser();
 const stateStore = useStateStore();
@@ -34,6 +34,10 @@ const weekdayStore = useWeekdayStore();
 const weekDays = ref([]);
 const { openConfirmationModal } = useVnConfirm();
 const { getWeekOfYear } = date;
+const defaultDate = computed(() => {
+    const timestamp = route.query.timestamp;
+    return timestamp ? new Date(timestamp * 1000) : Date.vnNew();
+});
 
 const workerTimeFormDialogRef = ref(null);
 const workerTimeReasonFormDialogRef = ref(null);
@@ -56,15 +60,17 @@ const workerTimeFormProps = reactive({
 // Array utilizado por QCalendar para seleccionar un rango de fechas
 const selectedCalendarDates = ref([]);
 // Date formateada para bindear al componente QDate
-const selectedDateFormatted = ref(toDateString(Date.vnNew()));
+const selectedDateFormatted = ref(toDateString(defaultDate.value));
 
 const arrayData = useArrayData('workerData');
 
 const worker = computed(() => arrayData.store?.data);
 
-const isHr = computed(() => hasAny(['hr']));
+const isHr = computed(() => useRole().hasAny(['hr']));
 
-const isHimSelf = computed(() => user.value.id === Number(route.params.id));
+const canSend = computed(() => useAcl().hasAny('WorkerTimeControl', 'sendMail', 'WRITE'));
+
+const isHimself = computed(() => user.value.id === Number(route.params.id));
 
 const columns = computed(() => {
     return weekdayStore.getLocales?.map((day, index) => {
@@ -423,7 +429,7 @@ onBeforeMount(() => {
 });
 
 onMounted(async () => {
-    await setDate(Date.vnNew());
+    await setDate(defaultDate.value);
     await getMailStates(selectedDate.value);
     stateStore.rightDrawer = true;
 });
@@ -443,7 +449,7 @@ onMounted(async () => {
         <div>
             <QBtnGroup push class="q-gutter-x-sm" flat>
                 <QBtn
-                    v-if="isHimSelf && state"
+                    v-if="isHimself && state"
                     :label="t('Satisfied')"
                     color="primary"
                     type="submit"
@@ -451,7 +457,7 @@ onMounted(async () => {
                     @click="isSatisfied()"
                 />
                 <QBtn
-                    v-if="isHimSelf && state"
+                    v-if="isHimself && state"
                     :label="t('Not satisfied')"
                     color="primary"
                     type="submit"
@@ -462,14 +468,14 @@ onMounted(async () => {
             </QBtnGroup>
             <QBtnGroup push class="q-gutter-x-sm q-ml-none" flat>
                 <QBtn
-                    v-if="reason && state && (isHimSelf || isHr)"
+                    v-if="reason && state && (isHimself || isHr)"
                     :label="t('Reason')"
                     color="primary"
                     type="submit"
                     @click="showReasonForm()"
                 />
                 <QBtn
-                    v-if="isHr && state !== 'CONFIRMED' && canResend"
+                    v-if="canSend && state !== 'CONFIRMED' && canResend"
                     :label="state ? t('Resend') : t('globals.send')"
                     color="primary"
                     type="submit"
@@ -547,9 +553,12 @@ onMounted(async () => {
                     <QTd
                         v-for="(day, index) in props.cols"
                         :key="index"
-                        style="padding: 20px 16px !important"
+                        :style="{
+                            padding: '20px 16px !important',
+                            'vertical-align': 'baseline',
+                        }"
                     >
-                        <div class="full-height full-width column items-center">
+                        <div class="full-width column items-center">
                             <WorkerTimeHourChip
                                 v-for="(hour, ind) in day.dayData?.hours"
                                 :key="ind"
@@ -596,7 +605,7 @@ onMounted(async () => {
             <WorkerTimeReasonForm
                 @on-submit="isUnsatisfied($event)"
                 :reason="reason"
-                :is-him-self="isHimSelf"
+                :is-himself="isHimself"
             />
         </QDialog>
     </QPage>
@@ -622,6 +631,9 @@ onMounted(async () => {
         margin-bottom: 0px;
     }
 }
+:deep(.q-td) {
+    min-width: 170px;
+}
 </style>
 
 <i18n>
diff --git a/src/pages/Worker/Card/WorkerTimeReasonForm.vue b/src/pages/Worker/Card/WorkerTimeReasonForm.vue
index 5c1ab9118..23bdba15e 100644
--- a/src/pages/Worker/Card/WorkerTimeReasonForm.vue
+++ b/src/pages/Worker/Card/WorkerTimeReasonForm.vue
@@ -9,7 +9,7 @@ const $props = defineProps({
         type: String,
         default: '',
     },
-    isHimSelf: {
+    isHimself: {
         type: Boolean,
         default: false,
     },
@@ -40,7 +40,7 @@ const closeForm = () => {
                 v-model="reasonFormData"
                 type="textarea"
                 autogrow
-                :disable="!isHimSelf"
+                :disable="!isHimself"
             />
         </template>
     </FormPopup>
diff --git a/src/pages/Worker/WorkerCreate.vue b/src/pages/Worker/WorkerCreate.vue
index 5f96c136d..b51209879 100644
--- a/src/pages/Worker/WorkerCreate.vue
+++ b/src/pages/Worker/WorkerCreate.vue
@@ -2,7 +2,6 @@
 import { onBeforeMount, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import axios from 'axios';
-import { useUserConfig } from 'src/composables/useUserConfig';
 import VnRow from 'components/ui/VnRow.vue';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
@@ -14,15 +13,25 @@ import FetchData from 'components/FetchData.vue';
 import FormModel from 'components/FormModel.vue';
 import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue';
 import VnRadio from 'src/components/common/VnRadio.vue';
+import { useState } from 'src/composables/useState';
 
 const { t } = useI18n();
+const user = useState().getUser();
 
 const companiesOptions = ref([]);
-const workersOptions = ref([]);
 const payMethodsOptions = ref([]);
 const bankEntitiesOptions = ref([]);
-const formData = ref({ isFreelance: false });
-const defaultPayMethod = ref(0);
+const formData = ref({ companyFk: user.value.companyFk, isFreelance: false });
+const defaultPayMethod = ref();
+
+onBeforeMount(async () => {
+    defaultPayMethod.value = (
+        await axios.get('WorkerConfigs/findOne', {
+            params: { field: ['payMethodFk'] },
+        })
+    ).data.payMethodFk;
+    formData.value.payMethodFk = defaultPayMethod.value;
+});
 
 function handleLocation(data, location) {
     const { town, code, provinceFk, countryFk } = location ?? {};
@@ -32,16 +41,32 @@ function handleLocation(data, location) {
     data.countryFk = countryFk;
 }
 
-onBeforeMount(async () => {
-    const userInfo = await useUserConfig().fetch();
-    formData.value.companyFk = userInfo.companyFk;
+function generateCodeUser(worker) {
+    if (!worker.firstName || !worker.lastNames) return;
 
-    const { data } = await axios.get('WorkerConfigs/findOne', {
-        params: { field: ['payMethodFk'] },
-    });
-    defaultPayMethod.value = data.payMethodFk;
-    formData.value.payMethodFk = defaultPayMethod.value;
-});
+    const totalName = worker.firstName.concat(' ' + worker.lastNames).toLowerCase();
+    const totalNameArray = totalName.split(' ');
+    let newCode = '';
+
+    for (let part of totalNameArray) newCode += part.charAt(0);
+
+    worker.code = newCode.toUpperCase().slice(0, 3);
+    worker.name = totalNameArray[0] + newCode.slice(1);
+
+    if (!worker.companyFk) worker.companyFk = user.companyFk;
+}
+
+async function autofillBic(worker) {
+    if (!worker || !worker.iban) return;
+
+    let bankEntityId = parseInt(worker.iban.substr(4, 4));
+    let filter = { where: { id: bankEntityId } };
+
+    const { data } = await axios.get(`BankEntities`, { params: { filter } });
+    const hasData = data && data[0];
+    if (hasData) worker.bankEntityFk = data[0].id;
+    else if (!hasData) worker.bankEntityFk = undefined;
+}
 </script>
 <template>
     <FetchData
@@ -49,11 +74,6 @@ onBeforeMount(async () => {
         @on-fetch="(data) => (companiesOptions = data)"
         auto-load
     />
-    <FetchData
-        url="Workers/search"
-        @on-fetch="(data) => (workersOptions = data)"
-        auto-load
-    />
     <FetchData
         url="Paymethods"
         @on-fetch="(data) => (payMethodsOptions = data)"
@@ -93,11 +113,13 @@ onBeforeMount(async () => {
                         v-model="data.firstName"
                         :label="t('worker.create.name')"
                         :rules="validate('Worker.firstName')"
+                        @update:model-value="generateCodeUser(data)"
                     />
                     <VnInput
                         v-model="data.lastNames"
                         :label="t('worker.create.lastName')"
                         :rules="validate('Worker.lastNames')"
+                        @update:model-value="generateCodeUser(data)"
                     />
                     <VnInput
                         v-model="data.code"
@@ -130,7 +152,7 @@ onBeforeMount(async () => {
                     <VnSelect
                         :label="t('worker.create.boss')"
                         v-model="data.bossFk"
-                        :options="workersOptions"
+                        url="Workers/search"
                         option-value="id"
                         option-label="name"
                         hide-selected
@@ -203,6 +225,7 @@ onBeforeMount(async () => {
                         :label="t('worker.create.iban')"
                         :rules="validate('Worker.iban')"
                         :disable="formData.isFreelance"
+                        @update:model-value="autofillBic(data)"
                     >
                         <template #append>
                             <QIcon name="info" class="cursor-info">
@@ -220,6 +243,8 @@ onBeforeMount(async () => {
                         :roles-allowed-to-create="['salesAssistant', 'hr']"
                         :rules="validate('Worker.bankEntity')"
                         :disable="formData.isFreelance"
+                        @update:model-value="autofillBic(data)"
+                        :filter-options="['bic', 'name']"
                     >
                         <template #form>
                             <CreateBankEntityForm
diff --git a/src/pages/Worker/WorkerFilter.vue b/src/pages/Worker/WorkerFilter.vue
index 0853791ef..765241341 100644
--- a/src/pages/Worker/WorkerFilter.vue
+++ b/src/pages/Worker/WorkerFilter.vue
@@ -5,6 +5,7 @@ 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({
@@ -26,7 +27,7 @@ const departments = ref();
                 <span>{{ formatFn(tag.value) }}</span>
             </div>
         </template>
-        <template #body="{ params, searchFn }">
+        <template #body="{ params }">
             <QItem>
                 <QItemSection>
                     <VnInput :label="t('FI')" v-model="params.fi" is-outlined
@@ -67,20 +68,17 @@ const departments = ref();
                     <QSkeleton type="QInput" class="full-width" />
                 </QItemSection>
                 <QItemSection v-if="departments">
-                    <QSelect
+                    <VnSelect
                         :label="t('Department')"
                         v-model="params.departmentFk"
-                        @update:model-value="searchFn()"
                         :options="departments"
                         option-value="id"
                         option-label="name"
                         emit-value
                         map-options
-                        use-input
                         dense
                         outlined
                         rounded
-                        :input-debounce="0"
                     />
                 </QItemSection>
             </QItem>
@@ -107,6 +105,7 @@ en:
         userName: User
         extension: Extension
         departmentFk: Department
+        id: ID
 es:
     params:
         search: Contiene
@@ -116,6 +115,7 @@ es:
         userName: Usuario
         extension: Extensión
         departmentFk: Departamento
+        id: ID
     FI: NIF
     First Name: Nombre
     Last Name: Apellidos
diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue
index 9d4c3acbf..4c9964c0b 100644
--- a/src/pages/Worker/WorkerList.vue
+++ b/src/pages/Worker/WorkerList.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { computed, ref } from 'vue';
+import { onBeforeMount, computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
@@ -14,28 +14,27 @@ import VnLocation from 'src/components/common/VnLocation.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
 import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue';
 import FetchData from 'src/components/FetchData.vue';
+import RightMenu from 'src/components/common/RightMenu.vue';
+import WorkerFilter from './WorkerFilter.vue';
+import { useState } from 'src/composables/useState';
+import axios from 'axios';
 
 const { t } = useI18n();
 const tableRef = ref();
 const { viewSummary } = useSummaryDialog();
 const companiesOptions = ref([]);
-const workersOptions = ref([]);
 const payMethodsOptions = ref([]);
 const bankEntitiesOptions = ref([]);
 const postcodesOptions = ref([]);
 
+const user = useState().getUser();
+const defaultPayMethod = ref();
 const columns = computed(() => [
     {
         align: 'left',
         name: 'id',
-        label: t('tableColumns.id'),
-        columnFilter: {
-            alias: 'w',
-            inWhere: true,
-        },
-        chip: {
-            condition: () => true,
-        },
+        label: t('id'),
+        field: 'id',
         isId: true,
     },
     {
@@ -44,7 +43,7 @@ const columns = computed(() => [
         label: t('tableColumns.name'),
         isTitle: true,
         columnFilter: {
-            name: 'search',
+            name: 'firstName',
         },
     },
     {
@@ -54,8 +53,7 @@ const columns = computed(() => [
         cardVisible: true,
         columnFilter: {
             component: 'select',
-            inWhere: true,
-            alias: 'wd',
+            name: 'departmentFk',
             attrs: {
                 url: 'Departments',
             },
@@ -79,7 +77,7 @@ const columns = computed(() => [
         name: 'tableActions',
         actions: [
             {
-                title: t('InvoiceOutSummary'),
+                title: t('components.smartCard.viewSummary'),
                 icon: 'preview',
                 action: (row) => viewSummary(row.id, WorkerSummary),
             },
@@ -87,6 +85,14 @@ const columns = computed(() => [
     },
 ]);
 
+onBeforeMount(async () => {
+    defaultPayMethod.value = (
+        await axios.get('WorkerConfigs/findOne', {
+            params: { field: ['payMethodFk'] },
+        })
+    ).data?.payMethodFk;
+});
+
 function handleLocation(data, location) {
     const { town, code, provinceFk, countryFk } = location ?? {};
     data.postcode = code;
@@ -103,6 +109,31 @@ function uppercaseStreetModel(data) {
         },
     };
 }
+
+function generateCodeUser(worker) {
+    if (!worker.firstName || !worker.lastNames) return;
+
+    const totalName = worker.firstName.concat(' ' + worker.lastNames).toLowerCase();
+    const totalNameArray = totalName.split(' ');
+    let newCode = '';
+
+    for (let part of totalNameArray) newCode += part.charAt(0);
+
+    worker.code = newCode.toUpperCase().slice(0, 3);
+    worker.name = totalNameArray[0] + newCode.slice(1);
+
+    if (!worker.companyFk) worker.companyFk = user.companyFk;
+}
+
+async function autofillBic(worker) {
+    if (!worker || !worker.iban) return;
+
+    let bankEntityId = parseInt(worker.iban.substr(4, 4));
+    let filter = { where: { id: bankEntityId } };
+
+    const { data } = await axios.get(`BankEntities`, { params: { filter } });
+    worker.bankEntityFk = data?.[0]?.id ?? undefined;
+}
 </script>
 <template>
     <VnSearchbar
@@ -115,11 +146,6 @@ function uppercaseStreetModel(data) {
         @on-fetch="(data) => (companiesOptions = data)"
         auto-load
     />
-    <FetchData
-        url="Workers/search"
-        @on-fetch="(data) => (workersOptions = data)"
-        auto-load
-    />
     <FetchData
         url="Paymethods"
         @on-fetch="(data) => (payMethodsOptions = data)"
@@ -130,7 +156,13 @@ function uppercaseStreetModel(data) {
         @on-fetch="(data) => (bankEntitiesOptions = data)"
         auto-load
     />
+    <RightMenu>
+        <template #right-panel>
+            <WorkerFilter data-key="Worker" />
+        </template>
+    </RightMenu>
     <VnTable
+        v-if="defaultPayMethod"
         ref="tableRef"
         data-key="Worker"
         url="Workers/filter"
@@ -139,16 +171,19 @@ function uppercaseStreetModel(data) {
             title: t('Create worker'),
             onDataSaved: ({ id }) => tableRef.redirect(id),
             formInitialData: {
+                payMethodFk: defaultPayMethod,
+                companyFk: user.companyFk,
                 isFreelance: false,
             },
         }"
         :columns="columns"
         default-mode="table"
         redirect="worker"
+        :right-search="false"
         auto-load
     >
         <template #more-create-dialog="{ data }">
-            <div class="q-pa-lg full-width" style="max-width: 1200px">
+            <div class="q-pa-lg full-width">
                 <VnRadio
                     v-model="data.isFreelance"
                     :val="false"
@@ -162,10 +197,16 @@ function uppercaseStreetModel(data) {
                     @update:model-value="delete data.payMethodFk"
                 />
                 <VnRow>
-                    <VnInput v-model="data.firstName" :label="t('worker.create.name')" />
+                    <VnInput
+                        next
+                        v-model="data.firstName"
+                        :label="t('worker.create.name')"
+                        @update:model-value="generateCodeUser(data)"
+                    />
                     <VnInput
                         v-model="data.lastNames"
                         :label="t('worker.create.lastName')"
+                        @update:model-value="generateCodeUser(data)"
                     />
                     <VnInput v-model="data.code" :label="t('worker.create.code')" />
                 </VnRow>
@@ -188,7 +229,7 @@ function uppercaseStreetModel(data) {
                     <VnSelect
                         :label="t('worker.create.boss')"
                         v-model="data.bossFk"
-                        :options="workersOptions"
+                        url="Workers/search"
                         option-value="id"
                         option-label="name"
                         hide-selected
@@ -221,7 +262,7 @@ function uppercaseStreetModel(data) {
                 </VnRow>
                 <VnRow>
                     <VnLocation
-                        :roles-allowed-to-create="['deliveryAssistant']"
+                        :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
                         :options="postcodesOptions"
                         @update:model-value="(location) => handleLocation(data, location)"
                         :disable="data.isFreelance"
@@ -252,6 +293,7 @@ function uppercaseStreetModel(data) {
                         v-model="data.iban"
                         :label="t('worker.create.iban')"
                         :disable="data.isFreelance"
+                        @update:model-value="autofillBic(data)"
                     >
                         <template #append>
                             <QIcon name="info" class="cursor-info">
@@ -268,8 +310,10 @@ function uppercaseStreetModel(data) {
                         option-label="name"
                         option-value="id"
                         hide-selected
-                        :roles-allowed-to-create="['salesAssistant', 'hr']"
+                        :acls="[{ model: 'BankEntity', props: '*', accessType: 'WRITE' }]"
                         :disable="data.isFreelance"
+                        @update:model-value="autofillBic(data)"
+                        :filter-options="['bic', 'name']"
                     >
                         <template #form>
                             <CreateBankEntityForm
diff --git a/src/pages/Zone/Card/ZoneBasicData.vue b/src/pages/Zone/Card/ZoneBasicData.vue
index a4874e5fc..512d07636 100644
--- a/src/pages/Zone/Card/ZoneBasicData.vue
+++ b/src/pages/Zone/Card/ZoneBasicData.vue
@@ -83,6 +83,7 @@ const agencyOptions = ref([]);
                     :label="t('Price')"
                     type="number"
                     min="0"
+                    required="true"
                     clearable
                 />
                 <VnInput
@@ -95,7 +96,12 @@ const agencyOptions = ref([]);
             </VnRow>
 
             <VnRow>
-                <VnInput v-model="data.inflation" :label="t('Inflation')" clearable />
+                <VnInput
+                    v-model="data.inflation"
+                    :label="t('Inflation')"
+                    type="number"
+                    clearable
+                />
                 <QCheckbox
                     v-model="data.isVolumetric"
                     :label="t('Volumetric')"
diff --git a/src/pages/Zone/Card/ZoneCard.vue b/src/pages/Zone/Card/ZoneCard.vue
index 02ec12fe7..d61c61abf 100644
--- a/src/pages/Zone/Card/ZoneCard.vue
+++ b/src/pages/Zone/Card/ZoneCard.vue
@@ -2,41 +2,37 @@
 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 ZoneSearchbar from './ZoneSearchbar.vue';
+import ZoneFilterPanel from '../ZoneFilterPanel.vue';
 
 const { t } = useI18n();
 const route = useRoute();
-
 const routeName = computed(() => route.name);
-const customRouteRedirectName = computed(() => {
-    if (routeName.value === 'ZoneLocations') return null;
-    return routeName.value;
-});
-const searchbarMakeFetch = computed(() => routeName.value !== 'ZoneEvents');
-const searchBarDataKeys = {
-    ZoneWarehouses: 'ZoneWarehouses',
-    ZoneSummary: 'ZoneSummary',
-    ZoneLocations: 'ZoneLocations',
-    ZoneEvents: 'ZoneEvents',
-};
+
+function notIsLocations(ifIsFalse, ifIsTrue) {
+    if (routeName.value != 'ZoneLocations') return ifIsFalse;
+    return ifIsTrue;
+}
 </script>
 
 <template>
     <VnCard
-        data-key="Zone"
+        data-key="zone"
+        base-url="Zones"
         :descriptor="ZoneDescriptor"
-        :search-data-key="searchBarDataKeys[routeName]"
         :filter-panel="ZoneFilterPanel"
+        :search-data-key="notIsLocations('ZoneList', 'ZoneLocations')"
         :searchbar-props="{
             url: 'Zones',
-            label: t('list.searchZone'),
+            label: notIsLocations(t('list.searchZone'), t('list.searchLocation')),
             info: t('list.searchInfo'),
+            whereFilter: notIsLocations((value) => {
+                return /^\d+$/.test(value)
+                    ? { id: value }
+                    : { name: { like: `%${value}%` } };
+            }),
         }"
-    >
-        <template #searchbar>
-            <ZoneSearchbar />
-        </template>
-    </VnCard>
+    />
 </template>
diff --git a/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue b/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue
index 8f1168ce9..22d5bcd5e 100644
--- a/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue
+++ b/src/pages/Zone/Card/ZoneDescriptorMenuItems.vue
@@ -8,13 +8,6 @@ import VnConfirm from 'components/ui/VnConfirm.vue';
 
 import axios from 'axios';
 
-const $props = defineProps({
-    zone: {
-        type: Object,
-        default: () => {},
-    },
-});
-
 const { t } = useI18n();
 const { push, currentRoute } = useRouter();
 const zoneId = currentRoute.value.params.id;
@@ -22,32 +15,21 @@ const zoneId = currentRoute.value.params.id;
 const actions = {
     clone: async () => {
         const opts = { message: t('Zone cloned'), type: 'positive' };
-        let clonedZoneId;
 
         try {
-            const { data } = await axios.post(`Zones/${zoneId}/clone`, {
-                shipped: $props.zone.value.shipped,
-            });
-            clonedZoneId = data;
+            const { data } = await axios.post(`Zones/${zoneId}/clone`, {});
+            notify(opts);
+            push(`/zone/${data.id}/basic-data`);
         } catch (e) {
             opts.message = t('It was not able to clone the zone');
             opts.type = 'negative';
-        } finally {
-            notify(opts);
-
-            if (clonedZoneId) push({ name: 'ZoneSummary', params: { id: clonedZoneId } });
         }
     },
     remove: async () => {
         try {
-            await axios.post(`Zones/${zoneId}/setDeleted`);
+            await axios.post(`Zones/${zoneId}/deleteZone`);
 
             notify({ message: t('Zone deleted'), type: 'positive' });
-            notify({
-                message: t('You can undo this action within the first hour'),
-                icon: 'info',
-            });
-
             push({ name: 'ZoneList' });
         } catch (e) {
             notify({ message: e.message, type: 'negative' });
@@ -64,30 +46,31 @@ function openConfirmDialog(callback) {
 }
 </script>
 <template>
-    <QItem @click="openConfirmDialog('clone')" v-ripple clickable>
-        <QItemSection avatar>
-            <QIcon name="content_copy" />
-        </QItemSection>
-        <QItemSection>{{ t('To clone zone') }}</QItemSection>
-    </QItem>
     <QItem @click="openConfirmDialog('remove')" v-ripple clickable>
         <QItemSection avatar>
             <QIcon name="delete" />
         </QItemSection>
         <QItemSection>{{ t('deleteZone') }}</QItemSection>
     </QItem>
+    <QItem @click="openConfirmDialog('clone')" v-ripple clickable>
+        <QItemSection avatar>
+            <QIcon name="content_copy" />
+        </QItemSection>
+        <QItemSection>{{ t('cloneZone') }}</QItemSection>
+    </QItem>
 </template>
 
 <i18n>
 en:
-    deleteZone: Delete zone
+    deleteZone: Delete
+    cloneZone: Clone
     confirmDeletion: Confirm deletion
     confirmDeletionMessage: Are you sure you want to delete this zone?
 
 es:
-    To clone zone: Clonar zone
-    deleteZone: Eliminar zona
+    cloneZone: Clonar
+    deleteZone: Eliminar
     confirmDeletion: Confirmar eliminación
     confirmDeletionMessage: Seguro que quieres eliminar este zona?
-
+    Zone deleted: Zona eliminada
 </i18n>
diff --git a/src/pages/Zone/Card/ZoneEventExclusionForm.vue b/src/pages/Zone/Card/ZoneEventExclusionForm.vue
index 721f4bbc3..0ba2e640a 100644
--- a/src/pages/Zone/Card/ZoneEventExclusionForm.vue
+++ b/src/pages/Zone/Card/ZoneEventExclusionForm.vue
@@ -58,20 +58,12 @@ const arrayData = useArrayData('ZoneEvents');
 
 const exclusionGeoCreate = async () => {
     try {
-        if (isNew.value) {
-            const params = {
-                zoneFk: parseInt(route.params.id),
-                date: dated.value,
-                geoIds: tickedNodes.value,
-            };
-            await axios.post('Zones/exclusionGeo', params);
-        } else {
-            const params = {
-                zoneExclusionFk: props.event?.zoneExclusionFk,
-                geoIds: tickedNodes.value,
-            };
-            await axios.post('Zones/updateExclusionGeo', params);
-        }
+        const params = {
+            zoneFk: parseInt(route.params.id),
+            date: dated.value,
+            geoIds: tickedNodes.value,
+        };
+        await axios.post('Zones/exclusionGeo', params);
         await refetchEvents();
     } catch (err) {
         console.error('Error creating exclusion geo: ', err);
@@ -85,7 +77,7 @@ const exclusionCreate = async () => {
                 { dated: dated.value },
             ]);
         else
-            await axios.put(`Zones/${route.params.id}/exclusions/${props.event?.id}`, {
+            await axios.post(`Zones/${route.params.id}/exclusions`, {
                 dated: dated.value,
             });
 
@@ -103,8 +95,7 @@ const onSubmit = async () => {
 const deleteEvent = async () => {
     try {
         if (!props.event) return;
-        const exclusionId = props.event?.zoneExclusionFk || props.event?.id;
-        await axios.delete(`Zones/${route.params.id}/exclusions/${exclusionId}`);
+        await axios.delete(`Zones/${route.params.id}/exclusions`);
         await refetchEvents();
     } catch (err) {
         console.error('Error deleting event: ', err);
@@ -141,7 +132,11 @@ onMounted(() => {
     >
         <template #form-inputs>
             <VnRow class="row q-gutter-md q-mb-lg">
-                <VnInputDate :label="t('eventsInclusionForm.day')" v-model="dated" />
+                <VnInputDate
+                    :label="t('eventsInclusionForm.day')"
+                    v-model="dated"
+                    :model-value="props.date"
+                />
             </VnRow>
             <div class="column q-gutter-y-sm q-mb-md">
                 <QRadio
diff --git a/src/pages/Zone/Card/ZoneEvents.vue b/src/pages/Zone/Card/ZoneEvents.vue
index e4fe5ff22..32a7db4c4 100644
--- a/src/pages/Zone/Card/ZoneEvents.vue
+++ b/src/pages/Zone/Card/ZoneEvents.vue
@@ -13,8 +13,8 @@ import { reactive } from 'vue';
 const { t } = useI18n();
 const stateStore = useStateStore();
 
-const firstDay = ref(null);
-const lastDay = ref(null);
+const firstDay = ref();
+const lastDay = ref();
 
 const events = ref([]);
 const formModeName = ref('include');
@@ -52,7 +52,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                     @click="stateStore.toggleRightDrawer()"
                     round
                     dense
-                    icon="menu"
+                    icon="dock_to_left"
                 >
                     <QTooltip bottom anchor="bottom right">
                         {{ t('globals.collapseMenu') }}
@@ -102,6 +102,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
                 color="primary"
                 fab
                 icon="add"
+                shortcut="+"
             />
             <QTooltip class="text-no-wrap">
                 {{ t('eventsInclusionForm.addEvent') }}
diff --git a/src/pages/Zone/Card/ZoneLocationsTree.vue b/src/pages/Zone/Card/ZoneLocationsTree.vue
index 70384a1bb..cb1508ed6 100644
--- a/src/pages/Zone/Card/ZoneLocationsTree.vue
+++ b/src/pages/Zone/Card/ZoneLocationsTree.vue
@@ -1,10 +1,7 @@
 <script setup>
 import { onMounted, ref, computed, watch, onUnmounted } from 'vue';
-import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
-import VnInput from 'src/components/common/VnInput.vue';
-
 import { useState } from 'src/composables/useState';
 import axios from 'axios';
 import { useArrayData } from 'composables/useArrayData';
@@ -30,7 +27,6 @@ const props = defineProps({
 
 const emit = defineEmits(['update:tickedNodes']);
 
-const { t } = useI18n();
 const route = useRoute();
 const state = useState();
 
@@ -186,16 +182,6 @@ onUnmounted(() => {
 </script>
 
 <template>
-    <VnInput
-        v-if="showSearchBar"
-        v-model="store.userParams.search"
-        :placeholder="t('globals.search')"
-        @keydown.enter.prevent="reFetch()"
-    >
-        <template #prepend>
-            <QIcon class="cursor-pointer" name="search" />
-        </template>
-    </VnInput>
     <QTree
         ref="treeRef"
         :nodes="nodes"
diff --git a/src/pages/Zone/Card/ZoneSearchbar.vue b/src/pages/Zone/Card/ZoneSearchbar.vue
index 607057d0b..06168eb62 100644
--- a/src/pages/Zone/Card/ZoneSearchbar.vue
+++ b/src/pages/Zone/Card/ZoneSearchbar.vue
@@ -19,24 +19,14 @@ const exprBuilder = (param, value) => {
                 agencyModeFk: value,
             };
         case 'search':
-            if (value) {
-                if (!isNaN(value)) {
-                    return { id: value };
-                } else {
-                    return {
-                        name: {
-                            like: `%${value}%`,
-                        },
-                    };
-                }
-            }
+            return /^\d+$/.test(value) ? { id: value } : { name: { like: `%${value}%` } };
     }
 };
 </script>
 
 <template>
     <VnSearchbar
-        data-key="ZoneList"
+        data-key="Zones"
         url="Zones"
         :filter="{
             include: { relation: 'agencyMode', scope: { fields: ['name'] } },
diff --git a/src/pages/Zone/Card/ZoneWarehouses.vue b/src/pages/Zone/Card/ZoneWarehouses.vue
index 196333d08..6b2933224 100644
--- a/src/pages/Zone/Card/ZoneWarehouses.vue
+++ b/src/pages/Zone/Card/ZoneWarehouses.vue
@@ -14,7 +14,7 @@ const { t } = useI18n();
 const route = useRoute();
 const { openConfirmationModal } = useVnConfirm();
 
-const paginateRef = ref(null);
+const paginateRef = ref();
 const createWarehouseDialogRef = ref(null);
 
 const arrayData = useArrayData('ZoneWarehouses');
@@ -111,7 +111,13 @@ const openCreateWarehouseForm = () => createWarehouseDialogRef.value.show();
             <ZoneCreateWarehouse @on-submit-create-warehouse="createZoneWarehouse" />
         </QDialog>
         <QPageSticky position="bottom-right" :offset="[18, 18]">
-            <QBtn fab icon="add" color="primary" @click="openCreateWarehouseForm()">
+            <QBtn
+                fab
+                icon="add"
+                color="primary"
+                @click="openCreateWarehouseForm()"
+                shortcut="+"
+            >
                 <QTooltip>{{ t('warehouses.add') }}</QTooltip>
             </QBtn>
         </QPageSticky>
diff --git a/src/pages/Zone/ZoneDeliveryPanel.vue b/src/pages/Zone/ZoneDeliveryPanel.vue
index 03f534701..d6c96b935 100644
--- a/src/pages/Zone/ZoneDeliveryPanel.vue
+++ b/src/pages/Zone/ZoneDeliveryPanel.vue
@@ -1,47 +1,25 @@
 <script setup>
-import { onMounted, ref, reactive } from 'vue';
+import { onMounted, ref, reactive, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 
 import VnSelect from 'src/components/common/VnSelect.vue';
-
 import { useArrayData } from 'src/composables/useArrayData';
-import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
-import { watch } from 'vue';
+import FetchData from 'src/components/FetchData.vue';
 
 const { t } = useI18n();
 const { notify } = useNotify();
 
-const deliveryMethodFk = ref(null);
-const deliveryMethods = ref([]);
+const deliveryMethodFk = ref('delivery');
+const deliveryMethods = ref({});
+const inq = ref([]);
 const formData = reactive({});
 
 const arrayData = useArrayData('ZoneDeliveryDays', {
     url: 'Zones/getEvents',
 });
 
-const fetchDeliveryMethods = async (filter) => {
-    try {
-        const params = { filter: JSON.stringify(filter) };
-        const { data } = await axios.get('DeliveryMethods', { params });
-        return data.map((deliveryMethod) => deliveryMethod.id);
-    } catch (err) {
-        console.error('Error fetching delivery methods: ', err);
-    }
-};
-
-watch(
-    () => deliveryMethodFk.value,
-    async (val) => {
-        let filter;
-        if (val === 'pickUp') filter = { where: { code: 'PICKUP' } };
-        else filter = { where: { code: { inq: ['DELIVERY', 'AGENCY'] } } };
-
-        deliveryMethods.value = await fetchDeliveryMethods(filter);
-    },
-    { immediate: true }
-);
-
+const deliveryMethodsConfig = { pickUp: ['PICKUP'], delivery: ['AGENCY', 'DELIVERY'] };
 const fetchData = async (params) => {
     try {
         const { data } = params
@@ -62,14 +40,38 @@ const onSubmit = async () => {
 };
 
 onMounted(async () => {
-    deliveryMethodFk.value = 'delivery';
     formData.geoFk = arrayData.store?.userParams?.geoFk;
     formData.agencyModeFk = arrayData.store?.userParams?.agencyModeFk;
     if (formData.geoFk || formData.agencyModeFk) await fetchData();
 });
+watch(
+    () => deliveryMethodFk.value,
+    () => {
+        inq.value = {
+            deliveryMethodFk: { inq: deliveryMethods.value[deliveryMethodFk.value] },
+        };
+    }
+);
 </script>
 
 <template>
+    <FetchData
+        url="DeliveryMethods"
+        :fields="['id', 'name', 'deliveryMethodFk']"
+        @on-fetch="
+            (data) => {
+                Object.entries(deliveryMethodsConfig).forEach(([key, value]) => {
+                    deliveryMethods[key] = data
+                        .filter((code) => value.includes(code.code))
+                        .map((method) => method.id);
+                });
+                inq = {
+                    deliveryMethodFk: { inq: deliveryMethods[deliveryMethodFk] },
+                };
+            }
+        "
+        auto-load
+    />
     <QForm @submit="onSubmit()" class="q-pa-md">
         <div class="column q-gutter-y-sm">
             <QRadio
@@ -90,7 +92,7 @@ onMounted(async () => {
                 :label="t('deliveryPanel.postcode')"
                 v-model="formData.geoFk"
                 url="Postcodes/location"
-                :fields="['geoFk', 'code', 'townFk']"
+                :fields="['geoFk', 'code', 'townFk', 'countryFk']"
                 sort-by="code, townFk"
                 option-value="geoFk"
                 option-label="code"
@@ -106,26 +108,35 @@ onMounted(async () => {
                             <QItemLabel>{{ opt.code }}</QItemLabel>
                             <QItemLabel caption
                                 >{{ opt.town?.province?.name }},
-                                {{ opt.town?.province?.country?.country }}</QItemLabel
+                                {{ opt.town?.province?.country?.name }}</QItemLabel
                             >
                         </QItemSection>
                     </QItem>
                 </template>
             </VnSelect>
             <VnSelect
-                :label="
-                    t(
-                        deliveryMethodFk === 'delivery'
-                            ? 'deliveryPanel.agency'
-                            : 'deliveryPanel.warehouse'
-                    )
-                "
+                data-key="delivery"
+                v-if="deliveryMethodFk == 'delivery'"
+                :label="t('deliveryPanel.agency')"
                 v-model="formData.agencyModeFk"
                 url="AgencyModes/isActive"
                 :fields="['id', 'name']"
-                :where="{
-                    deliveryMethodFk: { inq: deliveryMethods },
-                }"
+                :where="inq"
+                sort-by="name ASC"
+                option-value="id"
+                option-label="name"
+                hide-selected
+                dense
+                outlined
+                rounded
+            />
+            <VnSelect
+                v-else
+                :label="t('deliveryPanel.warehouse')"
+                v-model="formData.agencyModeFk"
+                url="AgencyModes/isActive"
+                :fields="['id', 'name']"
+                :where="inq"
                 sort-by="name ASC"
                 option-value="id"
                 option-label="name"
diff --git a/src/pages/Zone/ZoneFilterPanel.vue b/src/pages/Zone/ZoneFilterPanel.vue
index c84355eb0..25c55d75c 100644
--- a/src/pages/Zone/ZoneFilterPanel.vue
+++ b/src/pages/Zone/ZoneFilterPanel.vue
@@ -27,6 +27,7 @@ const agencies = ref([]);
         :data-key="props.dataKey"
         :search-button="true"
         :hidden-tags="['search']"
+        search-url="table"
     >
         <template #tags="{ tag }">
             <div class="q-gutter-x-xs">
diff --git a/src/pages/Zone/ZoneList.vue b/src/pages/Zone/ZoneList.vue
index 0272292f6..d160ea6b5 100644
--- a/src/pages/Zone/ZoneList.vue
+++ b/src/pages/Zone/ZoneList.vue
@@ -1,74 +1,120 @@
 <script setup>
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
-import { onMounted, computed } from 'vue';
+import { computed, ref, onMounted } from 'vue';
+import axios from 'axios';
+
 import { toCurrency } from 'src/filters';
-
-import VnPaginate from 'src/components/ui/VnPaginate.vue';
-import ZoneSummary from 'src/pages/Zone/Card/ZoneSummary.vue';
-
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import { toTimeFormat } from 'src/filters/date';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import useNotify from 'src/composables/useNotify.js';
+import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import { useStateStore } from 'stores/useStateStore';
-import axios from 'axios';
+import ZoneSummary from 'src/pages/Zone/Card/ZoneSummary.vue';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+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';
 
-const stateStore = useStateStore();
 const { t } = useI18n();
 const router = useRouter();
 const { notify } = useNotify();
 const { viewSummary } = useSummaryDialog();
 const { openConfirmationModal } = useVnConfirm();
+const stateStore = useStateStore();
+const tableRef = ref();
+const warehouseOptions = ref([]);
 
-const redirectToZoneSummary = (event, { id }) => {
-    router.push({ name: 'ZoneSummary', params: { id } });
+const tableFilter = {
+    include: [
+        {
+            relation: 'agencyMode',
+            scope: {
+                fields: ['id', 'name'],
+            },
+        },
+    ],
 };
 
 const columns = computed(() => [
     {
-        name: 'ID',
-        label: t('list.id'),
-        field: (row) => row.id,
-        sortable: true,
         align: 'left',
+        name: 'id',
+        label: t('list.id'),
+        chip: {
+            condition: () => true,
+        },
+        isId: true,
+        columnFilter: {
+            inWhere: true,
+        },
     },
     {
+        align: 'left',
         name: 'name',
         label: t('list.name'),
-        field: (row) => row.name,
-        sortable: true,
-        align: 'left',
+        isTitle: true,
+        create: true,
+        columnFilter: {
+            optionLabel: 'name',
+            optionValue: 'id',
+        },
     },
     {
-        name: 'agency',
+        align: 'left',
+        name: 'agencyModeFk',
         label: t('list.agency'),
-        field: (row) => row?.agencyMode?.name,
-        sortable: true,
-        align: 'left',
+        cardVisible: true,
+        columnFilter: {
+            component: 'select',
+            inWhere: true,
+            attrs: {
+                url: 'AgencyModes',
+            },
+        },
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(row?.agencyMode?.name),
     },
     {
-        name: 'close',
-        label: t('list.close'),
-        field: (row) => (row?.hour ? toTimeFormat(row?.hour) : '-'),
-        sortable: true,
         align: 'left',
-    },
-    {
         name: 'price',
         label: t('list.price'),
-        field: (row) => (row?.price ? toCurrency(row.price) : '-'),
-        sortable: true,
-        align: 'left',
+        cardVisible: true,
+        format: (row) => toCurrency(row.price),
+        columnFilter: {
+            inWhere: true,
+        },
+    },
+    {
+        align: 'left',
+        name: 'hour',
+        label: t('list.close'),
+        cardVisible: true,
+        format: (row) => toTimeFormat(row.hour),
+        hidden: true,
     },
     {
-        name: 'actions',
-        label: '',
-        sortable: false,
         align: 'right',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('list.zoneSummary'),
+                icon: 'preview',
+                action: (row) => viewSummary(row.id, ZoneSummary),
+                isPrimary: true,
+            },
+            {
+                title: t('globals.clone'),
+                icon: 'vn:clone',
+                action: (row) => handleClone(row.id),
+                isPrimary: true,
+            },
+        ],
     },
 ]);
 
@@ -84,6 +130,7 @@ const handleClone = (id) => {
         () => clone(id)
     );
 };
+
 onMounted(() => (stateStore.rightDrawer = true));
 </script>
 
@@ -91,82 +138,72 @@ onMounted(() => (stateStore.rightDrawer = true));
     <ZoneSearchbar />
     <RightMenu>
         <template #right-panel>
-            <ZoneFilterPanel data-key="ZoneList" :expr-builder="exprBuilder" />
+            <ZoneFilterPanel data-key="Zones" />
         </template>
     </RightMenu>
-    <QPage class="column items-center q-pa-md">
-        <div class="vn-card-list">
-            <VnPaginate
-                data-key="ZoneList"
-                url="Zones"
-                :filter="{
-                    include: { relation: 'agencyMode', scope: { fields: ['name'] } },
-                }"
-                :limit="20"
-                auto-load
-            >
-                <template #body="{ rows }">
-                    <div class="q-pa-md">
-                        <QTable
-                            :rows="rows"
-                            :columns="columns"
-                            row-key="clientId"
-                            class="full-width"
-                            @row-click="redirectToZoneSummary"
-                        >
-                            <template #header="props">
-                                <QTr :props="props" class="bg">
-                                    <QTh
-                                        v-for="col in props.cols"
-                                        :key="col.name"
-                                        :props="props"
-                                    >
-                                        {{ t(col.label) }}
-                                        <QTooltip v-if="col.tooltip">{{
-                                            col.tooltip
-                                        }}</QTooltip>
-                                    </QTh>
-                                </QTr>
-                            </template>
-
-                            <template #body-cell="props">
-                                <QTd :props="props">
-                                    <QTr :props="props" class="cursor-pointer">
-                                        {{ props.value }}
-                                    </QTr>
-                                </QTd>
-                            </template>
-                            <template #body-cell-actions="props">
-                                <QTd :props="props" class="q-gutter-x-sm">
-                                    <QIcon
-                                        name="vn:clone"
-                                        size="sm"
-                                        color="primary"
-                                        @click.stop="handleClone(props.row.id)"
-                                    >
-                                        <QTooltip>{{ t('globals.clone') }}</QTooltip>
-                                    </QIcon>
-                                    <QIcon
-                                        name="preview"
-                                        size="sm"
-                                        color="primary"
-                                        @click.stop="
-                                            viewSummary(props.row.id, ZoneSummary)
-                                        "
-                                    >
-                                        <QTooltip>{{ t('Preview') }}</QTooltip>
-                                    </QIcon>
-                                </QTd>
-                            </template>
-                        </QTable>
-                    </div>
-                </template>
-            </VnPaginate>
-        </div>
-        <QPageSticky position="bottom-right" :offset="[18, 18]">
-            <QBtn :to="{ path: `/zone/create` }" fab icon="add" color="primary">
-                <QTooltip>{{ t('list.create') }}</QTooltip>
-            </QBtn>
-        </QPageSticky>
-    </QPage>
+    <VnTable
+        ref="tableRef"
+        data-key="Zones"
+        url="Zones"
+        :create="{
+            urlCreate: 'Zones',
+            title: t('list.createZone'),
+            onDataSaved: ({ id }) => tableRef.redirect(`${id}/location`),
+            formInitialData: {},
+        }"
+        :user-filter="tableFilter"
+        :columns="columns"
+        redirect="zone"
+        :right-search="false"
+        auto-load
+    >
+        <template #more-create-dialog="{ data }">
+            <VnSelect
+                url="AgencyModes"
+                v-model="data.agencyModeFk"
+                option-value="id"
+                option-label="name"
+                :label="t('list.agency')"
+            />
+            <VnInput
+                v-model="data.price"
+                :label="t('list.price')"
+                min="0"
+                type="number"
+                required="true"
+            />
+            <VnInput
+                v-model="data.bonus"
+                :label="t('list.bonus')"
+                min="0"
+                type="number"
+            />
+            <VnInput
+                v-model="data.travelingDays"
+                :label="t('list.travelingDays')"
+                type="number"
+                min="0"
+            />
+            <VnInputTime v-model="data.hour" :label="t('list.close')" />
+            <VnSelect
+                url="Warehouses"
+                v-model="data.warehouseFK"
+                option-value="id"
+                option-label="name"
+                :label="t('list.warehouse')"
+                :options="warehouseOptions"
+            />
+            <QCheckbox
+                v-model="data.isVolumetric"
+                :label="t('list.isVolumetric')"
+                :toggle-indeterminate="false"
+            />
+        </template>
+    </VnTable>
 </template>
+
+<i18n>
+es:
+    Search zone: Buscar zona
+    You can search zones by id or name: Puedes buscar zonas por id o nombre
+</i18n>
diff --git a/src/pages/Zone/locale/en.yml b/src/pages/Zone/locale/en.yml
index 31eeb2b7f..2608c071c 100644
--- a/src/pages/Zone/locale/en.yml
+++ b/src/pages/Zone/locale/en.yml
@@ -18,9 +18,16 @@ list:
     create: Create zone
     openSummary: Details
     searchZone: Search zones
+    searchLocation: Search locations
     searchInfo: Search zone by id or name
     confirmCloneTitle: All it's properties will be copied
     confirmCloneSubtitle: Do you want to clone this zone?
+    travelingDays: Traveling days
+    warehouse: Warehouse
+    bonus: Bonus
+    isVolumetric: Volumetric
+    createZone: Create zone
+    zoneSummary: Summary
 create:
     name: Name
     warehouse: Warehouse
@@ -30,6 +37,8 @@ create:
     price: Price
     bonus: Bonus
     volumetric: Volumetric
+    itemMaxSize: Max m³
+    inflation: Inflation
 summary:
     agency: Agency
     price: Price
diff --git a/src/pages/Zone/locale/es.yml b/src/pages/Zone/locale/es.yml
index c670c2c08..dd919a0c5 100644
--- a/src/pages/Zone/locale/es.yml
+++ b/src/pages/Zone/locale/es.yml
@@ -18,9 +18,16 @@ list:
     create: Crear zona
     openSummary: Detalles
     searchZone: Buscar zonas
+    searchLocation: Buscar localizaciones
     searchInfo: Buscar zonas por identificador o nombre
     confirmCloneTitle: Todas sus propiedades serán copiadas
     confirmCloneSubtitle: ¿Seguro que quieres clonar esta zona?
+    travelingDays: Días de viaje
+    warehouse: Almacén
+    bonus: Bonus
+    isVolumetric: Volumétrico
+    createZone: Crear zona
+    zoneSummary: Resumen
 create:
     name: Nombre
     warehouse: Almacén
@@ -30,6 +37,8 @@ create:
     price: Precio
     bonus: Bonificación
     volumetric: Volumétrico
+    itemMaxSize: Medida máxima
+    inflation: Inflación
 summary:
     agency: Agencia
     price: Precio
diff --git a/src/router/index.js b/src/router/index.js
index 686da2dde..18541c0b2 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -60,15 +60,12 @@ export default route(function (/* { store, ssrContext } */) {
                 await useTokenConfig().fetch();
             }
             const matches = to.matched;
-            const hasRequiredRoles = matches.every((route) => {
+            const hasRequiredAcls = matches.every((route) => {
                 const meta = route.meta;
-                if (meta && meta.roles) return useRole().hasAny(meta.roles);
-                return true;
+                if (!meta?.acls) return true;
+                return useAcl().hasAny(meta.acls);
             });
-
-            if (!hasRequiredRoles) {
-                return next({ path: '/' });
-            }
+            if (!hasRequiredAcls) return next({ path: '/' });
         }
 
         next();
diff --git a/src/router/modules/Supplier.js b/src/router/modules/Supplier.js
index b711066b2..143d7c824 100644
--- a/src/router/modules/Supplier.js
+++ b/src/router/modules/Supplier.js
@@ -7,6 +7,7 @@ export default {
         title: 'suppliers',
         icon: 'vn:supplier',
         moduleName: 'Supplier',
+        keyBinding: 'p',
     },
     component: RouterView,
     redirect: { name: 'SupplierMain' },
diff --git a/src/router/modules/account.js b/src/router/modules/account.js
index cfec2b95d..7200131da 100644
--- a/src/router/modules/account.js
+++ b/src/router/modules/account.js
@@ -7,6 +7,7 @@ export default {
         title: 'users',
         icon: 'face',
         moduleName: 'Account',
+        keyBinding: 'u',
     },
     component: RouterView,
     redirect: { name: 'AccountMain' },
@@ -79,7 +80,7 @@ export default {
                     meta: {
                         title: 'accounts',
                         icon: 'accessibility',
-                        roles: ['itManagement'],
+                        acls: [{ model: 'Account', props: '*', accessType: '*' }],
                     },
                     component: () => import('src/pages/Account/AccountAccounts.vue'),
                 },
@@ -89,7 +90,7 @@ export default {
                     meta: {
                         title: 'ldap',
                         icon: 'account_tree',
-                        roles: ['itManagement'],
+                        acls: [{ model: 'LdapConfig', props: '*', accessType: '*' }],
                     },
                     component: () => import('src/pages/Account/AccountLdap.vue'),
                 },
@@ -99,7 +100,7 @@ export default {
                     meta: {
                         title: 'samba',
                         icon: 'preview',
-                        roles: ['itManagement'],
+                        acls: [{ model: 'SambaConfig', props: '*', accessType: '*' }],
                     },
                     component: () => import('src/pages/Account/AccountSamba.vue'),
                 },
diff --git a/src/router/modules/claim.js b/src/router/modules/claim.js
index cced9e24d..b58a58e8d 100644
--- a/src/router/modules/claim.js
+++ b/src/router/modules/claim.js
@@ -7,6 +7,7 @@ export default {
         title: 'claims',
         icon: 'vn:claims',
         moduleName: 'Claim',
+        keyBinding: 'r',
     },
     component: RouterView,
     redirect: { name: 'ClaimMain' },
@@ -61,7 +62,7 @@ export default {
                     meta: {
                         title: 'basicData',
                         icon: 'vn:settings',
-                        roles: ['salesPerson'],
+                        acls: [{ model: 'Claim', props: 'findById', accessType: 'READ' }],
                     },
                     component: () => import('src/pages/Claim/Card/ClaimBasicData.vue'),
                 },
@@ -98,7 +99,13 @@ export default {
                     meta: {
                         title: 'development',
                         icon: 'vn:traceability',
-                        roles: ['claimManager'],
+                        acls: [
+                            {
+                                model: 'ClaimDevelopment',
+                                props: '*',
+                                accessType: 'WRITE',
+                            },
+                        ],
                     },
                     component: () => import('src/pages/Claim/Card/ClaimDevelopment.vue'),
                 },
diff --git a/src/router/modules/customer.js b/src/router/modules/customer.js
index f364bd862..1b707f1a2 100644
--- a/src/router/modules/customer.js
+++ b/src/router/modules/customer.js
@@ -7,6 +7,7 @@ export default {
         title: 'customers',
         icon: 'vn:client',
         moduleName: 'Customer',
+        keyBinding: 'c',
     },
     component: RouterView,
     redirect: { name: 'CustomerMain' },
diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js
index 0d38ed626..365615b87 100644
--- a/src/router/modules/entry.js
+++ b/src/router/modules/entry.js
@@ -7,6 +7,7 @@ export default {
         title: 'entries',
         icon: 'vn:entry',
         moduleName: 'Entry',
+        keyBinding: 'e',
     },
     component: RouterView,
     redirect: { name: 'EntryMain' },
diff --git a/src/router/modules/invoiceIn.js b/src/router/modules/invoiceIn.js
index cd8f7de9c..168d64f37 100644
--- a/src/router/modules/invoiceIn.js
+++ b/src/router/modules/invoiceIn.js
@@ -1,5 +1,5 @@
 import { RouterView } from 'vue-router';
-
+import { setRectificative } from 'src/pages/InvoiceIn/composables/setRectificative';
 export default {
     path: '/invoice-in',
     name: 'InvoiceIn',
@@ -11,7 +11,7 @@ export default {
     component: RouterView,
     redirect: { name: 'InvoiceInMain' },
     menus: {
-        main: ['InvoiceInList'],
+        main: ['InvoiceInList', 'InvoiceInSerial'],
         card: [
             'InvoiceInBasicData',
             'InvoiceInVat',
@@ -37,6 +37,16 @@ export default {
                     },
                     component: () => import('src/pages/InvoiceIn/InvoiceInList.vue'),
                 },
+                {
+                    path: 'serial',
+                    name: 'InvoiceInSerial',
+                    meta: {
+                        title: 'serial',
+                        icon: 'view_list',
+                    },
+                    component: () =>
+                        import('src/pages/InvoiceIn/Serial/InvoiceInSerial.vue'),
+                },
                 {
                     path: 'create',
                     name: 'InvoiceInCreare',
@@ -53,6 +63,10 @@ export default {
             path: ':id',
             component: () => import('src/pages/InvoiceIn/Card/InvoiceInCard.vue'),
             redirect: { name: 'InvoiceInSummary' },
+            beforeEnter: async (to, from, next) => {
+                await setRectificative(to);
+                next();
+            },
             children: [
                 {
                     name: 'InvoiceInSummary',
@@ -70,7 +84,6 @@ export default {
                     meta: {
                         title: 'basicData',
                         icon: 'vn:settings',
-                        roles: ['salesPerson'],
                     },
                     component: () =>
                         import('src/pages/InvoiceIn/Card/InvoiceInBasicData.vue'),
diff --git a/src/router/modules/item.js b/src/router/modules/item.js
index 4bd5df4e2..48e19dd54 100644
--- a/src/router/modules/item.js
+++ b/src/router/modules/item.js
@@ -7,6 +7,7 @@ export default {
         title: 'items',
         icon: 'vn:item',
         moduleName: 'Item',
+        keyBinding: 'a',
     },
     component: RouterView,
     redirect: { name: 'ItemMain' },
diff --git a/src/router/modules/monitor.js b/src/router/modules/monitor.js
index f0db8d3f3..7342a5904 100644
--- a/src/router/modules/monitor.js
+++ b/src/router/modules/monitor.js
@@ -7,11 +7,12 @@ export default {
         title: 'monitors',
         icon: 'grid_view',
         moduleName: 'Monitor',
+        keyBinding: 'm',
     },
     component: RouterView,
     redirect: { name: 'MonitorMain' },
     menus: {
-        main: ['MonitorList'],
+        main: ['MonitorTickets', 'MonitorClientsActions'],
         card: [],
     },
     children: [
@@ -19,16 +20,27 @@ export default {
             path: '',
             name: 'MonitorMain',
             component: () => import('src/components/common/VnSectionMain.vue'),
-            redirect: { name: 'MonitorList' },
+            redirect: { name: 'MonitorTickets' },
             children: [
                 {
-                    path: 'list',
-                    name: 'MonitorList',
+                    path: 'tickets',
+                    name: 'MonitorTickets',
                     meta: {
-                        title: 'list',
-                        icon: 'grid_view',
+                        title: 'ticketsMonitor',
+                        icon: 'vn:ticket',
                     },
-                    component: () => import('src/pages/Monitor/MonitorList.vue'),
+                    component: () =>
+                        import('src/pages/Monitor/Ticket/MonitorTickets.vue'),
+                },
+                {
+                    path: 'clients-actions',
+                    name: 'MonitorClientsActions',
+                    meta: {
+                        title: 'clientsActionsMonitor',
+                        icon: 'vn:client',
+                    },
+                    component: () =>
+                        import('src/pages/Monitor/MonitorClientsActions.vue'),
                 },
             ],
         },
diff --git a/src/router/modules/order.js b/src/router/modules/order.js
index a2b874cc6..bfa37fce5 100644
--- a/src/router/modules/order.js
+++ b/src/router/modules/order.js
@@ -7,6 +7,7 @@ export default {
         title: 'order',
         icon: 'vn:basket',
         moduleName: 'Order',
+        keyBinding: 'o',
     },
     component: RouterView,
     redirect: { name: 'OrderMain' },
@@ -63,7 +64,7 @@ export default {
                         title: 'basicData',
                         icon: 'vn:settings',
                     },
-                    component: () => import('src/pages/Order/Card/OrderForm.vue'),
+                    component: () => import('src/pages/Order/Card/OrderBasicData.vue'),
                 },
                 {
                     name: 'OrderCatalog',
@@ -72,7 +73,7 @@ export default {
                         title: 'catalog',
                         icon: 'vn:basket',
                     },
-                    component: () => import('src/pages/Order/OrderCatalog.vue'),
+                    component: () => import('src/pages/Order/Card/OrderCatalog.vue'),
                 },
                 {
                     name: 'OrderVolume',
@@ -81,7 +82,7 @@ export default {
                         title: 'volume',
                         icon: 'vn:volume',
                     },
-                    component: () => import('src/pages/Order/OrderVolume.vue'),
+                    component: () => import('src/pages/Order/Card/OrderVolume.vue'),
                 },
                 {
                     name: 'OrderLines',
@@ -90,7 +91,7 @@ export default {
                         title: 'lines',
                         icon: 'vn:lines',
                     },
-                    component: () => import('src/pages/Order/OrderLines.vue'),
+                    component: () => import('src/pages/Order/Card/OrderLines.vue'),
                 },
             ],
         },
diff --git a/src/router/modules/shelving.js b/src/router/modules/shelving.js
index 70145dfb4..b7f50a3b6 100644
--- a/src/router/modules/shelving.js
+++ b/src/router/modules/shelving.js
@@ -76,7 +76,6 @@ export default {
                     meta: {
                         title: 'basicData',
                         icon: 'vn:settings',
-                        roles: ['salesPerson'],
                     },
                     component: () => import('pages/Shelving/Card/ShelvingForm.vue'),
                 },
diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js
index 4074f089f..dcc238f95 100644
--- a/src/router/modules/ticket.js
+++ b/src/router/modules/ticket.js
@@ -7,6 +7,7 @@ export default {
         title: 'tickets',
         icon: 'vn:ticket',
         moduleName: 'Ticket',
+        keyBinding: 't',
     },
     component: RouterView,
     redirect: { name: 'TicketMain' },
@@ -53,7 +54,6 @@ export default {
                     meta: {
                         title: 'createTicket',
                         icon: 'vn:ticketAdd',
-                        roles: ['developer'],
                     },
                     component: () => import('src/pages/Ticket/TicketCreate.vue'),
                 },
diff --git a/src/router/modules/wagon.js b/src/router/modules/wagon.js
index d3d14a888..e25e585eb 100644
--- a/src/router/modules/wagon.js
+++ b/src/router/modules/wagon.js
@@ -11,7 +11,7 @@ export default {
     component: RouterView,
     redirect: { name: 'WagonMain' },
     menus: {
-        main: ['WagonList', 'WagonTypeList', 'WagonCounter'],
+        main: ['WagonList', 'WagonTypeList', 'WagonCounter', 'WagonTray'],
         card: [],
     },
     children: [
@@ -81,7 +81,7 @@ export default {
                         title: 'typeCreate',
                         icon: 'create',
                     },
-                    component: () => import('src/pages/Wagon/Type/WagonTypeCreate.vue'),
+                    component: () => import('src/pages/Wagon/Type/WagonTypeList.vue'),
                 },
                 {
                     path: ':id/edit',
@@ -90,7 +90,7 @@ export default {
                         title: 'typeEdit',
                         icon: 'edit',
                     },
-                    component: () => import('src/pages/Wagon/Type/WagonTypeCreate.vue'),
+                    component: () => import('src/pages/Wagon/Type/WagonTypeEdit.vue'),
                 },
             ],
         },
diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js
index f80df5e06..b2716474b 100644
--- a/src/router/modules/worker.js
+++ b/src/router/modules/worker.js
@@ -7,6 +7,7 @@ export default {
         title: 'workers',
         icon: 'vn:worker',
         moduleName: 'Worker',
+        keyBinding: 'w',
     },
     component: RouterView,
     redirect: { name: 'WorkerMain' },
@@ -25,6 +26,7 @@ export default {
             'WorkerLocker',
             'WorkerBalance',
             'WorkerFormation',
+            'WorkerMedical',
         ],
     },
     children: [
@@ -196,6 +198,15 @@ export default {
                     },
                     component: () => import('src/pages/Worker/Card/WorkerFormation.vue'),
                 },
+                {
+                    name: 'WorkerMedical',
+                    path: 'medical',
+                    meta: {
+                        title: 'medical',
+                        icon: 'medical_information',
+                    },
+                    component: () => import('src/pages/Worker/Card/WorkerMedical.vue'),
+                },
             ],
         },
     ],
diff --git a/src/router/modules/zone.js b/src/router/modules/zone.js
index 889b47464..1f27cc76f 100644
--- a/src/router/modules/zone.js
+++ b/src/router/modules/zone.js
@@ -7,6 +7,7 @@ export default {
         title: 'zones',
         icon: 'vn:zone',
         moduleName: 'Zone',
+        keyBinding: 'z',
     },
     component: RouterView,
     redirect: { name: 'ZoneMain' },
@@ -50,33 +51,6 @@ export default {
                     },
                     component: () => import('src/pages/Zone/ZoneDeliveryDays.vue'),
                 },
-                {
-                    path: 'create',
-                    name: 'ZoneCreate',
-                    meta: {
-                        title: 'zoneCreate',
-                        icon: 'create',
-                    },
-                    component: () => import('src/pages/Zone/ZoneCreate.vue'),
-                },
-                {
-                    path: ':id/edit',
-                    name: 'ZoneEdit',
-                    meta: {
-                        title: 'zoneEdit',
-                        icon: 'edit',
-                    },
-                    component: () => import('src/pages/Zone/ZoneCreate.vue'),
-                },
-                // {
-                //     path: 'counter',
-                //     name: 'ZoneCounter',
-                //     meta: {
-                //         title: 'zoneCounter',
-                //         icon: 'add_circle',
-                //     },
-                //     component: () => import('src/pages/Zone/ZoneCounter.vue'),
-                // },
                 {
                     name: 'ZoneUpcomingDeliveries',
                     path: 'upcoming-deliveries',
diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js
index bb9a3d376..42acac013 100644
--- a/src/stores/invoiceOutGlobal.js
+++ b/src/stores/invoiceOutGlobal.js
@@ -19,6 +19,7 @@ export const useInvoiceOutGlobalStore = defineStore({
             maxShipped: null,
             clientId: null,
             printer: null,
+            serialType: null,
         },
         addresses: [],
         minInvoicingDate: null,
@@ -100,6 +101,7 @@ export const useInvoiceOutGlobalStore = defineStore({
                     maxShipped: new Date(formData.maxShipped),
                     clientId: formData.clientId ? formData.clientId : null,
                     companyFk: formData.companyFk,
+                    serialType: formData.serialType,
                 };
 
                 this.validateMakeInvoceParams(params, clientsToInvoice);
@@ -152,7 +154,13 @@ export const useInvoiceOutGlobalStore = defineStore({
                 );
                 throw new Error('Invoice date in the future');
             }
-
+            if (!params.serialType) {
+                notify(
+                    'invoiceOut.globalInvoices.errors.chooseValidSerialType',
+                    'negative'
+                );
+                throw new Error('Invalid Serial Type');
+            }
             if (!params.companyFk) {
                 notify('invoiceOut.globalInvoices.errors.chooseValidCompany', 'negative');
                 throw new Error('Invalid company');
@@ -180,6 +188,7 @@ export const useInvoiceOutGlobalStore = defineStore({
                     invoiceDate: new Date(formData.invoiceDate),
                     maxShipped: new Date(formData.maxShipped),
                     companyFk: formData.companyFk,
+                    serialType: formData.serialType,
                 };
 
                 this.status = 'invoicing';
@@ -191,12 +200,7 @@ export const useInvoiceOutGlobalStore = defineStore({
                 this.addressIndex++;
                 this.isInvoicing = false;
             } catch (err) {
-                if (
-                    err &&
-                    err.response &&
-                    err.response.status >= 400 &&
-                    err.response.status < 500
-                ) {
+                if (err?.response?.status >= 400 && err?.response?.status < 500) {
                     this.invoiceClientError(address, err.response?.data?.error?.message);
                     return;
                 } else {
@@ -243,7 +247,7 @@ export const useInvoiceOutGlobalStore = defineStore({
                     params,
                 });
 
-                if (data.data && data.data.error) throw new Error();
+                if (data?.data?.error) throw new Error();
 
                 const status = exportFile('negativeBases.csv', data, {
                     encoding: 'windows-1252',
diff --git a/src/stores/useNavigationStore.js b/src/stores/useNavigationStore.js
index 961e80377..4a819bf19 100644
--- a/src/stores/useNavigationStore.js
+++ b/src/stores/useNavigationStore.js
@@ -2,7 +2,7 @@ import axios from 'axios';
 import { ref } from 'vue';
 import { defineStore } from 'pinia';
 import { toLowerCamel } from 'src/filters';
-import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 import routes from 'src/router/modules';
 
 export const useNavigationStore = defineStore('navigationStore', () => {
@@ -26,7 +26,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
         'zone',
     ];
     const pinnedModules = ref([]);
-    const role = useRole();
+    const acl = useAcl();
 
     function getModules() {
         const modulesRoutes = ref([]);
@@ -56,6 +56,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
     function addMenuItem(module, route, parent) {
         const { meta } = route;
         let { menuChildren = null } = meta;
+        if (meta.hidden) return;
         if (menuChildren)
             menuChildren = menuChildren.map(({ name, title, icon }) => ({
                 name,
@@ -63,7 +64,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
                 title: `globals.pageTitles.${title}`,
             }));
 
-        if (meta && meta.roles && role.hasAny(meta.roles) === false) return;
+        if (meta && meta.acls && acl.hasAny(meta.acls) === false) return;
 
         const item = {
             name: route.name,
@@ -72,6 +73,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
         if (meta) {
             item.title = `globals.pageTitles.${meta.title}`;
             item.icon = meta.icon;
+            item.keyBinding = meta.keyBinding;
         }
 
         parent.push(item);
diff --git a/test/cypress/integration/claim/claimDevelopment.spec.js b/test/cypress/integration/claim/claimDevelopment.spec.js
index 903f58d4b..3b73a24d9 100755
--- a/test/cypress/integration/claim/claimDevelopment.spec.js
+++ b/test/cypress/integration/claim/claimDevelopment.spec.js
@@ -8,6 +8,8 @@ describe('ClaimDevelopment', () => {
         cy.viewport(1920, 1080);
         cy.login('developer');
         cy.visit(`/#/claim/${claimId}/development`);
+        cy.intercept('GET', /\/api\/Workers\/search/).as('workers');
+        cy.intercept('GET', /\/api\/Workers\/search/).as('workers');
         cy.waitForElement('tbody');
     });
 
@@ -32,10 +34,19 @@ describe('ClaimDevelopment', () => {
     });
 
     it('should add and remove new line', () => {
+        cy.wait(['@workers', '@workers']);
         cy.addCard();
+
         cy.get(thirdRow).should('exist');
 
-        const rowData = [false, 'Novato', 'Roces', 'Compradores', 'employeeNick', 'Tour'];
+        const rowData = [
+            false,
+            'Novato',
+            'Roces',
+            'Compradores',
+            'administrativeNick',
+            'Tour',
+        ];
         cy.fillRow(thirdRow, rowData);
 
         cy.saveCard();
diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
index 77a11969b..e1939fe5a 100644
--- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
@@ -36,8 +36,7 @@ describe('InvoiceInBasicData', () => {
     });
 
     it('should throw an error creating a new dms if a file is not attached', () => {
-        cy.get(formInputs).eq(5).click();
-        cy.get(formInputs).eq(5).type('{selectall}{backspace}');
+        cy.get(formInputs).eq(7).type('{selectall}{backspace}');
         cy.get(documentBtns).eq(0).click();
         cy.get(dialogActionBtns).eq(1).click();
         cy.get('.q-notification__message').should(
diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
index 018ae7a53..b84d743d1 100644
--- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js
@@ -3,13 +3,14 @@ describe('InvoiceInVat', () => {
     const thirdRow = 'tbody > :nth-child(3)';
     const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)';
     const dialogInputs = '.q-dialog label input';
-    const dialogBtns = '.q-dialog button';
-    const acrossInput = 'tbody tr:nth-child(1) td:nth-child(2) .default-icon';
+    const addBtn = 'tbody tr:nth-child(1) td:nth-child(2) .--add-icon';
     const randomInt = Math.floor(Math.random() * 100);
 
     beforeEach(() => {
         cy.login('developer');
         cy.visit(`/#/invoice-in/1/vat`);
+        cy.intercept('GET', '/api/InvoiceIns/1/getTotals').as('lastCall');
+        cy.wait('@lastCall');
     });
 
     it('should edit the sage iva', () => {
@@ -26,22 +27,15 @@ describe('InvoiceInVat', () => {
     });
 
     it('should remove the first line', () => {
-        cy.removeRow(2);
-    });
-
-    it('should throw an error if there are fields undefined', () => {
-        cy.get(acrossInput).click();
-        cy.get(dialogBtns).eq(2).click();
-        cy.get('.q-notification__message').should('have.text', "The code can't be empty");
+        cy.removeRow(1);
     });
 
     it('should correctly handle expense addition', () => {
-        cy.get(acrossInput).click();
+        cy.get(addBtn).click();
         cy.get(dialogInputs).eq(0).type(randomInt);
-        cy.get(dialogInputs).eq(1).click();
         cy.get(dialogInputs).eq(1).type('This is a dummy expense');
 
-        cy.get(dialogBtns).eq(2).click();
-        cy.get('.q-notification__message').should('have.text', 'Data saved');
+        cy.get('button[type="submit"]').click();
+        cy.get('.q-notification__message').should('have.text', 'Data created');
     });
 });
diff --git a/test/cypress/integration/outLogin/login.spec.js b/test/cypress/integration/outLogin/login.spec.js
index f8a9f5c64..3db223cdb 100755
--- a/test/cypress/integration/outLogin/login.spec.js
+++ b/test/cypress/integration/outLogin/login.spec.js
@@ -52,9 +52,9 @@ describe('Login', () => {
         cy.url().should('contain', '/login');
     });
 
-    it(`should get redirected to dashboard since employee can't create tickets`, () => {
-        cy.visit('/#/ticket/create', { failOnStatusCode: false });
-        cy.url().should('contain', '/#/login?redirect=/ticket/create');
+    it(`should be redirected to dashboard since the employee is not enabled to see ldap`, () => {
+        cy.visit('/#/account/ldap', { failOnStatusCode: false });
+        cy.url().should('contain', '/#/login?redirect=/account/ldap');
         cy.get('input[aria-label="Username"]').type('employee');
         cy.get('input[aria-label="Password"]').type('nightmare');
         cy.get('button[type="submit"]').click();
diff --git a/test/cypress/integration/route/routeList.spec.js b/test/cypress/integration/route/routeList.spec.js
index afc0fc395..c9d7147c2 100644
--- a/test/cypress/integration/route/routeList.spec.js
+++ b/test/cypress/integration/route/routeList.spec.js
@@ -10,12 +10,13 @@ describe('Route', () => {
 
     it('Route list create route', () => {
         cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
-        cy.get('input[name="description"]').eq(1).type('routeTestOne{enter}');
+        cy.get('input[name="description"]').type('routeTestOne{enter}');
         cy.get('.q-notification__message').should('have.text', 'Data created');
         cy.url().should('include', '/summary');
     });
 
     it('Route list search and edit', () => {
+        cy.get('#searchbar input').type('{enter}');
         cy.get('input[name="description"]').type('routeTestOne{enter}');
         cy.get('.q-table tr')
             .its('length')
diff --git a/test/cypress/integration/ticket/ticketDescriptor.spec.js b/test/cypress/integration/ticket/ticketDescriptor.spec.js
index fc920f346..516b0f13d 100644
--- a/test/cypress/integration/ticket/ticketDescriptor.spec.js
+++ b/test/cypress/integration/ticket/ticketDescriptor.spec.js
@@ -1,22 +1,22 @@
 /// <reference types="cypress" />
 describe('Ticket descriptor', () => {
     const toCloneOpt = '[role="menu"] .q-list > :nth-child(5)';
+    const setWeightOpt = '[role="menu"] .q-list > :nth-child(6)';
     const warehouseValue = ':nth-child(1) > :nth-child(6) > .value > span';
     const summaryHeader = '.summaryHeader > div';
-
+    const weight = 25;
+    const weightValue = ':nth-child(10) > .value > span';
     beforeEach(() => {
-        const ticketId = 1;
-
         cy.login('developer');
-        cy.visit(`/#/ticket/${ticketId}/summary`);
+        cy.viewport(1920, 1080);
     });
 
     it('should clone the ticket without warehouse', () => {
-        cy.openLeftMenu();
+        cy.visit('/#/ticket/1/summary');
         cy.openActionsDescriptor();
         cy.get(toCloneOpt).click();
         cy.clickConfirm();
-        cy.get(warehouseValue).contains('-');
+        cy.get(warehouseValue).contains('Warehouse One');
         cy.get(summaryHeader)
             .invoke('text')
             .then((text) => {
@@ -24,4 +24,15 @@ describe('Ticket descriptor', () => {
                 cy.wrap(owner.trim()).should('eq', 'Bruce Wayne (1101)');
             });
     });
+
+    it('should set the weight of the ticket', () => {
+        cy.visit('/#/ticket/10/summary');
+        cy.openActionsDescriptor();
+        cy.get(setWeightOpt).click();
+        cy.intercept('POST', /\/api\/Tickets\/\d+\/setWeight/).as('weight');
+        cy.get('.q-dialog input').type(weight);
+        cy.clickConfirm();
+        cy.wait('@weight');
+        cy.get(weightValue).contains(weight);
+    });
 });
diff --git a/test/cypress/integration/vnComponent/VnShortcut.spec.js b/test/cypress/integration/vnComponent/VnShortcut.spec.js
new file mode 100644
index 000000000..b49b4e964
--- /dev/null
+++ b/test/cypress/integration/vnComponent/VnShortcut.spec.js
@@ -0,0 +1,33 @@
+/// <reference types="cypress" />
+
+describe('VnShortcuts', () => {
+    const modules = {
+        item: 'a',
+        customer: 'c',
+        ticket: 't',
+        claim: 'r',
+        worker: 'w',
+        monitor: 'm',
+        order: 'o',
+        supplier: 'p',
+        entry: 'e',
+        zone: 'z',
+        account: 'u',
+    };
+    beforeEach(() => {
+        cy.login('developer');
+        cy.visit('/');
+    });
+
+    for (const [module, shortcut] of Object.entries(modules)) {
+        it(`should visit ${module} module`, () => {
+            cy.get('body').trigger('keydown', {
+                ctrlKey: true,
+                altKey: true,
+                code: `Key${shortcut.toUpperCase()}`,
+            });
+
+            cy.url().should('include', module);
+        });
+    }
+});
diff --git a/test/cypress/integration/wagonType/wagonTypeCreate.spec.js b/test/cypress/integration/wagonType/wagonTypeCreate.spec.js
index bcf7fe841..cd7ffa58f 100644
--- a/test/cypress/integration/wagonType/wagonTypeCreate.spec.js
+++ b/test/cypress/integration/wagonType/wagonTypeCreate.spec.js
@@ -3,52 +3,15 @@ describe('WagonTypeCreate', () => {
         cy.viewport(1920, 1080);
         cy.login('developer');
         cy.visit('/#/wagon/type/create');
+        cy.waitForElement('.q-page', 6000);
     });
 
-    function chooseColor(color) {
-        cy.get('div.shelving-down').eq(1).click();
-        cy.get('div.q-color-picker__cube').eq(color).click();
-        cy.get('div.q-card__section').find('button').click();
-    }
-
-    function addTray(position) {
-        cy.get('div.action-button').last().find('button').click();
-        cy.focused().type(position);
-        cy.focused().blur();
-    }
-
-    it('should create and delete a new wagon type', () => {
+    it('should create a new wagon type', () => {
+        cy.get('.q-page-sticky > div > .q-btn').click();
         cy.get('input').first().type('Example for testing');
-        cy.get('div.q-checkbox__bg').click();
-        chooseColor(1);
-
-        // Insert invalid position (not minimal height)
-        addTray(20);
-        cy.get('div[role="alert"]').should('exist');
-        chooseColor(2);
-        addTray(150);
-        chooseColor(3);
-        addTray(100);
-
-        // Insert invalid position (max height reached)
-        addTray(210);
-        cy.get('div[role="alert"]').should('exist');
-
-        // Save
         cy.get('button[type="submit"]').click();
-
-        // Check data has been saved successfully
-        cy.get(':nth-child(1) > :nth-child(1) > .justify-between > .flex > .title')
-            .contains('Example for testing')
-            .click();
-        cy.get('input').first().should('have.value', 'Example for testing');
-        cy.get('div.wagon-tray').should('have.length', 4);
-        cy.get('div.position').eq(0).find('input').should('have.value', '150');
-        cy.get('div.position').eq(1).find('input').should('have.value', '100');
-        cy.get('div.position').eq(2).find('input').should('have.value', '50');
-
-        // Delete wagon type created
-        cy.go('back');
+    });
+    it('delete a wagon type', () => {
         cy.get(
             ':nth-child(2) > :nth-child(1) > .card-list-body > .actions > .q-btn--standard'
         ).click();
diff --git a/test/cypress/integration/wagonType/wagonTypeEdit.spec.js b/test/cypress/integration/wagonType/wagonTypeEdit.spec.js
new file mode 100644
index 000000000..6e5816e51
--- /dev/null
+++ b/test/cypress/integration/wagonType/wagonTypeEdit.spec.js
@@ -0,0 +1,27 @@
+describe('WagonTypeEdit', () => {
+    const trayColorRow =
+        '.q-select > .q-field__inner > .q-field__control > .q-field__control-container';
+    beforeEach(() => {
+        cy.viewport(1920, 1080);
+        cy.login('developer');
+        cy.visit('/#/wagon/type/2/edit');
+    });
+
+    it('should edit the name and the divisible field of the wagon type', () => {
+        cy.get('.q-card');
+        cy.get('input').first().type(' changed');
+        cy.get('div.q-checkbox__bg').first().click();
+        cy.get('.q-btn--standard').click();
+    });
+
+    it('should create a tray', () => {
+        cy.get('.action-button > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get('input').last().type('150');
+        cy.get(trayColorRow).type('{downArrow}{downArrow}{enter}');
+    });
+
+    it('should delete a tray', () => {
+        cy.get('.action-button > .q-btn > .q-btn__content > .q-icon').first().click();
+        cy.reload();
+    });
+});
diff --git a/test/cypress/integration/worker/workerCreate.spec.js b/test/cypress/integration/worker/workerCreate.spec.js
index c1832ad67..50afe1892 100644
--- a/test/cypress/integration/worker/workerCreate.spec.js
+++ b/test/cypress/integration/worker/workerCreate.spec.js
@@ -2,6 +2,9 @@ describe('WorkerCreate', () => {
     const externalRadio = '.q-radio:nth-child(2)';
     const notification = '.q-notification__message';
     const developerBossId = 120;
+    const payMethodCross =
+        '.grid-create .full-width > :nth-child(9) .q-select .q-field__append:not(.q-anchor--skip)';
+    const saveBtn = '.q-mt-lg > .q-btn--standard';
 
     const internal = {
         Fi: { val: '78457139E' },
@@ -36,7 +39,8 @@ describe('WorkerCreate', () => {
 
     it('should throw an error if a pay method has not been selected', () => {
         cy.fillInForm(internal);
-        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.get(payMethodCross).click();
+        cy.get(saveBtn).click();
         cy.get(notification).should('contains.text', 'Payment method is required');
     });
 
@@ -45,14 +49,14 @@ describe('WorkerCreate', () => {
             ...internal,
             'Pay method': { val: 'PayMethod one', type: 'select' },
         });
-        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.get(saveBtn).click();
         cy.get(notification).should('contains.text', 'Data created');
     });
 
     it('should create an external', () => {
         cy.get(externalRadio).click();
         cy.fillInForm(external);
-        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.get(saveBtn).click();
         cy.get(notification).should('contains.text', 'Data created');
     });
 });
diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js
index de57c9638..8a8bea443 100644
--- a/test/cypress/integration/worker/workerList.spec.js
+++ b/test/cypress/integration/worker/workerList.spec.js
@@ -1,4 +1,7 @@
 describe('WorkerList', () => {
+    const inputName = '.q-drawer .q-form input[aria-label="First Name"]';
+    const searchBtn = '.q-drawer button:nth-child(3)';
+    const descriptorTitle = '.descriptor .title span';
     beforeEach(() => {
         cy.viewport(1280, 720);
         cy.login('developer');
@@ -6,6 +9,11 @@ describe('WorkerList', () => {
     });
 
     it('should open the worker summary', () => {
-        cy.get('.q-drawer .q-form input[aria-label="Name"]').type('jessica jones{enter}');
+        cy.get(inputName).type('jessica{enter}');
+        cy.get(searchBtn).click();
+        cy.intercept('GET', /\/api\/Workers\/\d+/).as('worker');
+        cy.wait('@worker').then(() =>
+            cy.get(descriptorTitle).should('include.text', 'Jessica')
+        );
     });
 });
diff --git a/test/cypress/integration/worker/workerLocker.spec.js b/test/cypress/integration/worker/workerLocker.spec.js
index 9a4066f54..8a169dfb2 100644
--- a/test/cypress/integration/worker/workerLocker.spec.js
+++ b/test/cypress/integration/worker/workerLocker.spec.js
@@ -1,12 +1,12 @@
 describe('WorkerLocker', () => {
-    const workerId = 1109;
+    const productionId = 49;
     const lockerCode = '2F';
     const input = '.q-card input';
     const thirdOpt = '[role="listbox"] .q-item:nth-child(1)';
     beforeEach(() => {
         cy.viewport(1280, 720);
         cy.login('productionBoss');
-        cy.visit(`/#/worker/${workerId}/locker`);
+        cy.visit(`/#/worker/${productionId}/locker`);
     });
 
     it('should allocates a locker', () => {
diff --git a/test/cypress/integration/zone/zoneBasicData.spec.js b/test/cypress/integration/zone/zoneBasicData.spec.js
new file mode 100644
index 000000000..c6151a49b
--- /dev/null
+++ b/test/cypress/integration/zone/zoneBasicData.spec.js
@@ -0,0 +1,21 @@
+describe('ZoneBasicData', () => {
+    const notification = '.q-notification__message';
+
+    beforeEach(() => {
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit('/#/zone/4/basic-data');
+    });
+
+    it('should throw an error if the name is empty', () => {
+        cy.get('.q-card > :nth-child(1)').clear();
+        cy.get('.q-btn-group > .q-btn--standard').click();
+        cy.get(notification).should('contains.text', "can't be blank");
+    });
+
+    it("should edit the basicData's zone", () => {
+        cy.get('.q-card > :nth-child(1)').type(' modified');
+        cy.get('.q-btn-group > .q-btn--standard').click();
+        cy.get(notification).should('contains.text', 'Data saved');
+    });
+});
diff --git a/test/cypress/integration/zone/zoneCreate.spec.js b/test/cypress/integration/zone/zoneCreate.spec.js
new file mode 100644
index 000000000..9618ea846
--- /dev/null
+++ b/test/cypress/integration/zone/zoneCreate.spec.js
@@ -0,0 +1,38 @@
+describe('ZoneCreate', () => {
+    const notification = '.q-notification__message';
+
+    const data = {
+        Name: { val: 'Zone pickup D' },
+        Price: { val: '3' },
+        Bonus: { val: '0' },
+        'Traveling days': { val: '0' },
+        Warehouse: { val: 'Algemesi', type: 'select' },
+        Volumetric: { val: 'true', type: 'checkbox' },
+    };
+
+    beforeEach(() => {
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit('/#/zone/list');
+        cy.get('.q-page-sticky > div > .q-btn').click();
+    });
+
+    it('should throw an error if an agency has not been selected', () => {
+        cy.fillInForm({
+            ...data,
+        });
+        cy.get('input[aria-label="Close"]').type('10:00');
+        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.get(notification).should('contains.text', 'Agency cannot be blank');
+    });
+
+    it('should create a zone', () => {
+        cy.fillInForm({
+            ...data,
+            Agency: { val: 'inhouse pickup', type: 'select' },
+        });
+        cy.get('input[aria-label="Close"]').type('10:00');
+        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.get(notification).should('contains.text', 'Data created');
+    });
+});
diff --git a/test/cypress/integration/zone/zoneList.spec.js b/test/cypress/integration/zone/zoneList.spec.js
index f35da7e5f..92c77a2c6 100644
--- a/test/cypress/integration/zone/zoneList.spec.js
+++ b/test/cypress/integration/zone/zoneList.spec.js
@@ -1,15 +1,18 @@
 describe('ZoneList', () => {
     beforeEach(() => {
-        cy.viewport(1920, 1080);
+        cy.viewport(1280, 720);
         cy.login('developer');
-        cy.visit(`/#/zone/list`);
+        cy.visit('/#/zone/list');
     });
 
-    it('should open the details', () => {
-        cy.get(':nth-child(1) > .text-right > .material-symbols-outlined').click();
+    it('should filter by agency', () => {
+        cy.get(
+            ':nth-child(1) > .column > .q-field > .q-field__inner > .q-field__control > .q-field__control-container'
+        ).type('{downArrow}{enter}');
     });
-    it('should redirect to summary', () => {
-        cy.waitForElement('.q-page');
-        cy.get('tbody > :nth-child(1)').click();
+
+    it('should open the zone summary', () => {
+        cy.get('input[aria-label="Name"]').type('zone refund');
+        cy.get('.q-scrollarea__content > .q-btn--standard > .q-btn__content').click();
     });
 });
diff --git a/test/cypress/integration/zone/zoneWarehouse.spec.js b/test/cypress/integration/zone/zoneWarehouse.spec.js
new file mode 100644
index 000000000..3ffa3f69d
--- /dev/null
+++ b/test/cypress/integration/zone/zoneWarehouse.spec.js
@@ -0,0 +1,34 @@
+describe('ZoneWarehouse', () => {
+    const data = {
+        Warehouse: { val: 'Algemesi', type: 'select' },
+    };
+    const deviceProductionField =
+        '.vn-row > :nth-child(1) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
+    const dataError = "ER_DUP_ENTRY: Duplicate entry '2-2' for key 'zoneFk'";
+
+    beforeEach(() => {
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit(`/#/zone/2/warehouses`);
+    });
+
+    it('should throw an error if the warehouse chosen is already put in the zone', () => {
+        cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get(deviceProductionField).click();
+        cy.get(deviceProductionField).type('{upArrow}{enter}');
+        cy.get('.q-notification__message').should('have.text', dataError);
+    });
+
+    it('should create a warehouse', () => {
+        cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get(deviceProductionField).click();
+        cy.fillInForm(data);
+        cy.get('.q-mt-lg > .q-btn--standard').click();
+    });
+
+    it('should delete a warehouse', () => {
+        cy.get('tbody > :nth-child(2) > :nth-child(2) > .q-icon').click();
+        cy.get('.q-card__actions > .q-btn--flat > .q-btn__content').click();
+        cy.reload();
+    });
+});
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 3cf909af5..a9a405313 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -105,6 +105,12 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
                     case 'date':
                         cy.wrap(el).type(val.split('-').join(''));
                         break;
+                    case 'time':
+                        cy.wrap(el).click();
+                        cy.get('.q-time .q-time__clock').contains(val.h).click();
+                        cy.get('.q-time .q-time__clock').contains(val.m).click();
+                        cy.get('.q-time .q-time__link').contains(val.x).click();
+                        break;
                     default:
                         cy.wrap(el).type(val);
                         break;
diff --git a/test/vitest/__tests__/composables/useAcl.spec.js b/test/vitest/__tests__/composables/useAcl.spec.js
index a2b44b5e7..6cb29984c 100644
--- a/test/vitest/__tests__/composables/useAcl.spec.js
+++ b/test/vitest/__tests__/composables/useAcl.spec.js
@@ -48,40 +48,62 @@ describe('useAcl', () => {
 
     describe('hasAny', () => {
         it('should return false if no roles matched', async () => {
-            expect(acl.hasAny('Worker', 'updateAttributes', 'WRITE')).toBeFalsy();
+            expect(
+                acl.hasAny([
+                    { model: 'Worker', props: 'updateAttributes', accessType: 'WRITE' },
+                ])
+            ).toBeFalsy();
         });
 
         it('should return false if no roles matched', async () => {
-            expect(acl.hasAny('Worker', 'holidays', 'READ')).toBeTruthy();
+            expect(
+                acl.hasAny([{ model: 'Worker', props: 'holidays', accessType: 'READ' }])
+            ).toBeTruthy();
         });
 
         describe('*', () => {
             it('should return true if an acl matched', async () => {
-                expect(acl.hasAny('Address', '*', 'WRITE')).toBeTruthy();
+                expect(
+                    acl.hasAny([{ model: 'Address', props: '*', accessType: 'WRITE' }])
+                ).toBeTruthy();
             });
 
             it('should return false if no acls matched', async () => {
-                expect(acl.hasAny('Worker', '*', 'READ')).toBeFalsy();
+                expect(
+                    acl.hasAny([{ model: 'Worker', props: '*', accessType: 'READ' }])
+                ).toBeFalsy();
             });
         });
 
         describe('$authenticated', () => {
             it('should return false if no acls matched', async () => {
-                expect(acl.hasAny('Url', 'getByUser', '*')).toBeFalsy();
+                expect(
+                    acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: '*' }])
+                ).toBeFalsy();
             });
 
             it('should return true if an acl matched', async () => {
-                expect(acl.hasAny('Url', 'getByUser', 'READ')).toBeTruthy();
+                expect(
+                    acl.hasAny([{ model: 'Url', props: 'getByUser', accessType: 'READ' }])
+                ).toBeTruthy();
             });
         });
 
         describe('$everyone', () => {
             it('should return false if no acls matched', async () => {
-                expect(acl.hasAny('TpvTransaction', 'start', 'READ')).toBeFalsy();
+                expect(
+                    acl.hasAny([
+                        { model: 'TpvTransaction', props: 'start', accessType: 'READ' },
+                    ])
+                ).toBeFalsy();
             });
 
             it('should return false if an acl matched', async () => {
-                expect(acl.hasAny('TpvTransaction', 'start', 'WRITE')).toBeTruthy();
+                expect(
+                    acl.hasAny([
+                        { model: 'TpvTransaction', props: 'start', accessType: 'WRITE' },
+                    ])
+                ).toBeTruthy();
             });
         });
     });
diff --git a/test/vitest/__tests__/pages/Login/Login.spec.js b/test/vitest/__tests__/pages/Login/Login.spec.js
index 5ab4cee9e..e90a8ee53 100644
--- a/test/vitest/__tests__/pages/Login/Login.spec.js
+++ b/test/vitest/__tests__/pages/Login/Login.spec.js
@@ -44,10 +44,6 @@ describe('Login', () => {
 
     it('should not set the token into session if any error occurred', async () => {
         vi.spyOn(axios, 'post').mockReturnValue({ data: null });
-        vi.spyOn(vm.quasar, 'notify');
-
         await vm.onSubmit();
-
-        expect(vm.quasar.notify).not.toHaveBeenCalled();
     });
 });
diff --git a/test/vitest/__tests__/pages/Wagons/WagonTypeCreate.spec.js b/test/vitest/__tests__/pages/Wagons/WagonTypeCreate.spec.js
deleted file mode 100644
index 60c199b73..000000000
--- a/test/vitest/__tests__/pages/Wagons/WagonTypeCreate.spec.js
+++ /dev/null
@@ -1,271 +0,0 @@
-import { axios, createWrapper } from 'app/test/vitest/helper';
-import WagonTypeCreate from 'pages/Wagon/Type/WagonTypeCreate.vue';
-import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
-
-describe('WagonTypeCreate', () => {
-    let vmCreate, vmEdit;
-    const entityId = 1;
-
-    beforeAll(() => {
-        vmEdit = createWrapper(WagonTypeCreate, {propsData: {
-                id: entityId,
-            }}).vm;
-        vmCreate = createWrapper(WagonTypeCreate).vm;
-        vmEdit.wagonConfig = vmCreate.wagonConfig = {maxTrays: 2 ,minHeightBetweenTrays: 50, maxWagonHeight: 200 };
-        vmEdit.wagonTypeColors = vmCreate.wagonTypeColors = [{id: 1, color:'white', rgb:'#000000'}];
-    });
-
-    afterEach(() => {
-        vi.clearAllMocks();
-    });
-
-    describe('addTray()', () => {
-        it('should throw message if there are uncomplete trays', async () => {
-            vi.spyOn(vmEdit.quasar, 'notify');
-            vmEdit.wagon = [{
-                id: 1,
-                position: null,
-                color: vmEdit.wagonTypeColors[0]
-            }];
-
-            await vmEdit.addTray();
-
-            expect(vmEdit.quasar.notify).toHaveBeenCalledWith(
-                expect.objectContaining({
-                    type: 'warning',
-                })
-            );
-        });
-
-        it('should create a new tray if the limit has not been reached', async () => {
-            vmEdit.wagon = [{
-                id: 1,
-                position: 0,
-                color: vmEdit.wagonTypeColors[0]
-            }];
-
-            await vmEdit.addTray();
-            expect(vmEdit.wagon.length).toEqual(2);
-        });
-
-        it('should throw message if there are uncomplete trays', async () => {
-            vi.spyOn(vmEdit.quasar, 'notify');
-            vmEdit.wagon = [{
-                id: 1,
-                position: 0,
-                color: vmEdit.wagonTypeColors[0]
-            },{
-                id: 2,
-                position: 50,
-                color: vmEdit.wagonTypeColors[0]
-            }];
-
-            await vmEdit.addTray();
-
-            expect(vmEdit.quasar.notify).toHaveBeenCalledWith(
-                expect.objectContaining({
-                    type: 'warning',
-                })
-            );
-        });
-    });
-
-    describe('deleteTray() reorderIds()', () => {
-        it('should delete a tray and reorder the ids', async () => {
-            const trayToDelete = {
-                id: 1,
-                position: 0,
-                color: vmEdit.wagonTypeColors[0]
-            };
-            const trayMaintained = {
-                id: 2,
-                position: 50,
-                color: vmEdit.wagonTypeColors[0]
-            };
-            vmEdit.wagon = [trayToDelete,trayMaintained];
-
-            await vmEdit.deleteTray(trayToDelete);
-
-            expect(vmEdit.wagon.length).toEqual(1);
-            expect(vmEdit.wagon[0].id).toEqual(0);
-            expect(vmEdit.wagon[0].position).toEqual(50);
-
-        });
-    });
-
-    describe('onSubmit()', () => {
-        it('should make a patch to editWagonType if have id', async () => {
-            vi.spyOn(axios, 'patch').mockResolvedValue({ data: true });
-            const wagon = {
-                id: entityId,
-                name: "Mock name",
-                divisible: true,
-                trays: [{
-                    id: 1,
-                    position: 0,
-                    color: vmEdit.wagonTypeColors[0]
-                }]
-            }
-            vmEdit.name = wagon.name;
-            vmEdit.divisible = wagon.divisible;
-            vmEdit.wagon = wagon.trays;
-
-            await vmEdit.onSubmit();
-
-            expect(axios.patch).toHaveBeenCalledWith(
-                `WagonTypes/editWagonType`, wagon
-            );
-        });
-
-        it('should make a patch to createtWagonType if not have id', async () => {
-            vi.spyOn(axios, 'patch').mockResolvedValue({ data: true });
-            const wagon = {
-                name: "Mock name",
-                divisible: true,
-                trays: [{
-                    id: 1,
-                    position: 0,
-                    color: vmCreate.wagonTypeColors[0]
-                }]
-            }
-            vmCreate.name = wagon.name;
-            vmCreate.divisible = wagon.divisible;
-            vmCreate.wagon = wagon.trays;
-
-            await vmCreate.onSubmit();
-
-            expect(axios.patch).toHaveBeenCalledWith(
-                `WagonTypes/createWagonType`, wagon
-            );
-        });
-    });
-
-    describe('onReset()', () => {
-        it('should reset if have id', async () => {
-            vmEdit.name = 'Changed name';
-            vmEdit.divisible = false;
-            vmEdit.wagon = [];
-            vmEdit.originalData = {
-                name: 'Original name',
-                divisible: true,
-                trays: [{
-                    id: 1,
-                    position: 0,
-                    color: vmEdit.wagonTypeColors[0]
-                },{
-                    id: 2,
-                    position: 50,
-                    color: vmEdit.wagonTypeColors[0]
-                }]
-            };
-
-            vmEdit.onReset();
-
-            expect(vmEdit.name).toEqual(vmEdit.originalData.name);
-            expect(vmEdit.divisible).toEqual(vmEdit.originalData.divisible);
-            expect(vmEdit.wagon).toEqual(vmEdit.originalData.trays);
-        });
-
-        it('should reset if not have id', async () => {
-            vmCreate.name = 'Changed name';
-            vmCreate.divisible = false;
-            vmCreate.wagon = [];
-
-            vmCreate.onReset();
-
-            expect(vmCreate.name).toEqual(null);
-            expect(vmCreate.divisible).toEqual(false);
-            expect(vmCreate.wagon.length).toEqual(1);
-        });
-    });
-
-    describe('onPositionBlur()', () => {
-        it('should set position null if position is negative', async () => {
-            const negativeTray = {
-                id: 1,
-                position: -1,
-                color: vmCreate.wagonTypeColors[0]
-            };
-
-            vmCreate.onPositionBlur(negativeTray);
-
-            expect(negativeTray.position).toEqual(null);
-        });
-
-        it('should set position and reorder array', async () => {
-            const trays = [{
-                id: 0,
-                position: 100,
-                color: vmCreate.wagonTypeColors[0]
-            },{
-                id: 1,
-                position: 0,
-                color: vmCreate.wagonTypeColors[0]
-            }];
-            const newTray = {
-                id: 2,
-                position: 50,
-                color: vmCreate.wagonTypeColors[0]
-            };
-            trays.push(newTray);
-            vmCreate.wagon = trays;
-
-            vmCreate.onPositionBlur(newTray);
-
-            expect(vmCreate.wagon[0].position).toEqual(100);
-            expect(vmCreate.wagon[1].position).toEqual(50);
-            expect(vmCreate.wagon[2].position).toEqual(0);
-        });
-
-        it('should throw message if not have min height between trays and should set new adequate positions', async () => {
-            vi.spyOn(vmCreate.quasar, 'notify');
-            const trays = [{
-                id: 0,
-                position: 0,
-                color: vmCreate.wagonTypeColors[0]
-            }];
-            const newTray = {
-                id: 1,
-                position: 20,
-                color: vmCreate.wagonTypeColors[0]
-            };
-            trays.push(newTray);
-            vmCreate.wagon = trays;
-
-            vmCreate.onPositionBlur(newTray);
-
-            expect(vmCreate.wagon[0].position).toEqual(50);
-            expect(vmCreate.wagon[1].position).toEqual(0);
-            expect(vmCreate.quasar.notify).toHaveBeenCalledWith(
-                expect.objectContaining({
-                    type: 'warning',
-                })
-            );
-        });
-
-        it('should throw message if max height has been exceed', async () => {
-            vi.spyOn(vmCreate.quasar, 'notify');
-            const trays = [{
-                id: 0,
-                position: 0,
-                color: vmCreate.wagonTypeColors[0]
-            }];
-            const newTray = {
-                id: 1,
-                position: 210,
-                color: vmCreate.wagonTypeColors[0]
-            };
-            trays.push(newTray);
-            vmCreate.wagon = trays;
-
-            vmCreate.onPositionBlur(newTray);
-
-            expect(vmCreate.wagon.length).toEqual(1);
-            expect(vmCreate.quasar.notify).toHaveBeenCalledWith(
-                expect.objectContaining({
-                    type: 'warning',
-                })
-            );
-        });
-    });
-});