diff --git a/CHANGELOG.md b/CHANGELOG.md
index 03812d252..e110e4cd6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,87 @@
+# Version 24.50 - 2024-12-10
+
+### Added 🆕
+
+-   feat: add reportFileName option by:Javier Segarra
+-   feat: all clients just with global series by:jgallego
+-   feat: improve Merge branch 'test' into dev by:Javier Segarra
+-   feat: manual invoice in two lines by:jgallego
+-   feat: manualInvoice with address by:jgallego
+-   feat: randomize functions and example by:Javier Segarra
+-   feat: refs #6999 added search when user tabs on a filter with value by:Jon
+-   feat: refs #6999 added tab to search in VnTable filter by:Jon
+-   feat: refs #7346 #7346 improve form by:Javier Segarra
+-   feat: refs #7346 address ordered by:jgallego
+-   feat: refs #7346 radioButton by:jgallego
+-   feat: refs #7346 style radioButton by:jgallego
+-   feat: refs #7346 traducciones en cammelCase (7346-manualInvoice) by:jgallego
+-   feat: refs #8038 added new functionality in VnSelect and refactor styles by:Jon
+-   feat: refs #8061 #8061 updates by:Javier Segarra
+-   feat: refs #8087 reactive data by:jorgep
+-   feat: refs #8087 refs#8087 Redadas en travel by:Carlos Andrés
+-   feat: refs #8138 add component ticket problems by:pablone
+-   feat: refs #8163 add max length and more tests by:wbuezas
+-   feat: refs #8163 add prop by:wbuezas
+-   feat: refs #8163 add VnInput insert functionality and e2e test by:wbuezas
+-   feat: refs #8163 limit with maxLength by:Javier Segarra
+-   feat: refs #8163 maxLength SupplierFD account by:Javier Segarra
+-   feat: refs #8163 maxLengthVnInput by:Javier Segarra
+-   feat: refs #8163 use VnAccountNumber in VnAccountNumber by:Javier Segarra
+-   feat: refs #8166 show notification by:jorgep
+
+### Changed 📦
+
+-   feat: refs #8038 added new functionality in VnSelect and refactor styles by:Jon
+-   perf: add dataCy by:Javier Segarra
+-   perf: refs #7346 #7346 Imrpove interface dialog by:Javier Segarra
+-   perf: refs #7346 #7346 use v-show instead v-if by:Javier Segarra
+-   perf: refs #8036 currentFilter by:alexm
+-   perf: refs #8061 filter autonomy by:Javier Segarra
+-   perf: refs #8061 solve conflicts and random posCode it by:Javier Segarra
+-   perf: refs #8061 use opts from VnSelect by:Javier Segarra
+-   perf: refs #8163 #8061 createNewPostCodeForm by:Javier Segarra
+-   perf: remove console by:Javier Segarra
+-   perf: remove timeout by:Javier Segarra
+-   perf: test command fillInForm by:Javier Segarra
+-   refactor: refs #8162 remove comment by:wbuezas
+-   refactor: remove unnecesary things by:wbuezas
+
+### Fixed 🛠️
+
+-   fix: #8016 fetching data by:Javier Segarra
+-   fix: icons by:jgallego
+-   fix: refs #7229 download file by:jorgep
+-   fix: refs #7229 remove catch by:jorgep
+-   fix: refs #7229 set url by:jorgep
+-   fix: refs #7229 test by:jorgep
+-   fix: refs #7229 url by:jorgep
+-   fix: refs #7229 url + test by:jorgep
+-   fix: refs #7304 7304 clean warning by:carlossa
+-   fix: refs #7304 fix list by:carlossa
+-   fix: refs #7304 fix warning by:carlossa
+-   fix: refs #7346 traslations by:jgallego
+-   fix: refs #7529 add save by:carlossa
+-   fix: refs #7529 fix e2e by:carlossa
+-   fix: refs #7529 fix front by:carlossa
+-   fix: refs #7529 fix scss by:carlossa
+-   fix: refs #7529 fix te2e by:carlossa
+-   fix: refs #7529 fix workerPit e2e by:carlossa
+-   fix: refs #7529 front by:carlossa
+-   fix: refs #8036 apply exprBuilder after save filters by:alexm
+-   fix: refs #8036 only add where when required by:alexm
+-   fix: refs #8038 solve conflicts by:Jon
+-   fix: refs #8061 improve code dependencies (origin/8061_improve_newCP) by:Javier Segarra
+-   fix: refs #8138 move component from ui folder by:pablone
+-   fix: refs #8138 sme minor issues by:pablone
+-   fix: refs #8163 #8061 createNewPostCodeForm by:Javier Segarra
+-   fix: refs #8163 minor problem when keypress by:Javier Segarra
+-   fix: refs #8166 show zone error by:jorgep
+-   fix: removed selectedClient by:jgallego
+-   refs #7529 fix workerPit by:carlossa
+-   revert: refs #8061 test #8061 updates by:Javier Segarra
+-   test: fix own test by:Javier Segarra
+-   test: refs #8162 #8162 fix TicketList spec by:Javier Segarra
+
 # Version 24.48 - 2024-11-25
 
 ### Added 🆕
diff --git a/Jenkinsfile b/Jenkinsfile
index 1766e3aea..c20da8ab2 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -4,7 +4,8 @@ def PROTECTED_BRANCH
 
 def BRANCH_ENV = [
     test: 'test',
-    master: 'production'
+    master: 'production',
+    beta: 'production'
 ]
 
 node {
@@ -15,7 +16,8 @@ node {
         PROTECTED_BRANCH = [
             'dev',
             'test',
-            'master'
+            'master',
+            'beta'
         ].contains(env.BRANCH_NAME)
 
         // https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
diff --git a/package.json b/package.json
index 04b75a0b0..39d49519b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "salix-front",
-    "version": "24.50.0",
+    "version": "24.52.0",
     "description": "Salix frontend",
     "productName": "Salix",
     "author": "Verdnatura",
@@ -64,4 +64,4 @@
         "vite": "^5.1.4",
         "vitest": "^0.31.1"
     }
-}
\ No newline at end of file
+}
diff --git a/src/boot/mainShortcutMixin.js b/src/boot/mainShortcutMixin.js
new file mode 100644
index 000000000..481077e37
--- /dev/null
+++ b/src/boot/mainShortcutMixin.js
@@ -0,0 +1,36 @@
+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;
+            if (!ctrlKey || !altKey) {
+                isNotified = false;
+            }
+        };
+
+        window.addEventListener('keydown', handleKeyDown);
+        window.addEventListener('keyup', handleKeyUp);
+    },
+};
diff --git a/src/boot/qformMixin.js b/src/boot/qformMixin.js
index fc7852369..8a75e1af7 100644
--- a/src/boot/qformMixin.js
+++ b/src/boot/qformMixin.js
@@ -1,30 +1,52 @@
-import { getCurrentInstance } from 'vue';
-
+function focusFirstInput(input) {
+    input.focus();
+    return;
+}
 export default {
     mounted: function () {
-        const vm = getCurrentInstance();
-        if (vm.type.name === 'QForm') {
-            if (!['searchbarForm', 'filterPanelForm'].includes(this.$el?.id)) {
-                // TODO: AUTOFOCUS IS NOT FOCUSING
-                const that = this;
-                this.$el.addEventListener('keyup', function (evt) {
-                    if (evt.key === 'Enter') {
-                        const input = evt.target;
-                        if (input.type == 'textarea' && evt.shiftKey) {
-                            evt.preventDefault();
-                            let { selectionStart, selectionEnd } = input;
-                            input.value =
-                                input.value.substring(0, selectionStart) +
-                                '\n' +
-                                input.value.substring(selectionEnd);
-                            selectionStart = selectionEnd = selectionStart + 1;
-                            return;
-                        }
-                        evt.preventDefault();
-                        that.onSubmit();
-                    }
-                });
+        const that = this;
+
+        const form = document.querySelector('.q-form#formModel');
+        if (!form) return;
+        try {
+            const inputsFormCard = form.querySelectorAll(
+                `input:not([disabled]):not([type="checkbox"])`
+            );
+            if (inputsFormCard.length) {
+                focusFirstInput(inputsFormCard[0]);
             }
+            const textareas = document.querySelectorAll(
+                'textarea:not([disabled]), [contenteditable]:not([disabled])'
+            );
+            if (textareas.length) {
+                focusFirstInput(textareas[textareas.length - 1]);
+            }
+            const inputs = document.querySelectorAll(
+                'form#formModel input:not([disabled]):not([type="checkbox"])'
+            );
+            const input = inputs[0];
+            if (!input) return;
+
+            focusFirstInput(input);
+        } catch (error) {
+            console.error(error);
         }
+        form.addEventListener('keyup', function (evt) {
+            if (evt.key === 'Enter') {
+                const input = evt.target;
+                if (input.type == 'textarea' && evt.shiftKey) {
+                    evt.preventDefault();
+                    let { selectionStart, selectionEnd } = input;
+                    input.value =
+                        input.value.substring(0, selectionStart) +
+                        '\n' +
+                        input.value.substring(selectionEnd);
+                    selectionStart = selectionEnd = selectionStart + 1;
+                    return;
+                }
+                evt.preventDefault();
+                that.onSubmit();
+            }
+        });
     },
 };
diff --git a/src/boot/quasar.js b/src/boot/quasar.js
index 01fe68d8b..547517682 100644
--- a/src/boot/quasar.js
+++ b/src/boot/quasar.js
@@ -1,15 +1,18 @@
+import axios from 'axios';
 import { boot } from 'quasar/wrappers';
 import qFormMixin from './qformMixin';
 import keyShortcut from './keyShortcut';
-import useNotify from 'src/composables/useNotify.js';
-import { CanceledError } from 'axios';
-
-const { notify } = useNotify();
+import { QForm } from 'quasar';
+import { QLayout } from 'quasar';
+import mainShortcutMixin from './mainShortcutMixin';
+import { useCau } from 'src/composables/useCau';
 
 export default boot(({ app }) => {
-    app.mixin(qFormMixin);
+    QForm.mixins = [qFormMixin];
+    QLayout.mixins = [mainShortcutMixin];
+
     app.directive('shortcut', keyShortcut);
-    app.config.errorHandler = (error) => {
+    app.config.errorHandler = async (error) => {
         let message;
         const response = error.response;
         const responseData = response?.data;
@@ -40,12 +43,12 @@ export default boot(({ app }) => {
         }
 
         console.error(error);
-        if (error instanceof CanceledError) {
+        if (error instanceof axios.CanceledError) {
             const env = process.env.NODE_ENV;
             if (env && env !== 'development') return;
             message = 'Duplicate request';
         }
 
-        notify(message ?? 'globals.error', 'negative', 'error');
+        await useCau(response, message);
     };
 });
diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue
index d3d6708f0..c656fcb2f 100644
--- a/src/components/CreateNewPostcodeForm.vue
+++ b/src/components/CreateNewPostcodeForm.vue
@@ -25,7 +25,6 @@ const townsFetchDataRef = ref(false);
 const townFilter = ref({});
 
 const countriesRef = ref(false);
-const provincesFetchDataRef = ref(false);
 const provincesOptions = ref([]);
 const townsOptions = ref([]);
 const town = ref({});
@@ -71,9 +70,6 @@ async function setProvince(id, data) {
     await fetchTowns();
 }
 async function onProvinceCreated(data) {
-    await provincesFetchDataRef.value.fetch({
-        where: { countryFk: postcodeFormData.countryFk },
-    });
     postcodeFormData.provinceFk = data.id;
 }
 function provinceByCountry(countryFk = postcodeFormData.countryFk) {
@@ -92,7 +88,6 @@ function setTown(newTown, data) {
     data.countryFk = newTown?.province?.countryFk ?? newTown;
 }
 async function onCityCreated(newTown, formData) {
-    await provincesFetchDataRef.value.fetch();
     newTown.province = provincesOptions.value.find(
         (province) => province.id === newTown.provinceFk
     );
@@ -125,14 +120,6 @@ async function filterTowns(name) {
 </script>
 
 <template>
-    <FetchData
-        ref="provincesFetchDataRef"
-        @on-fetch="handleProvinces"
-        :sort-by="['name ASC']"
-        :limit="30"
-        auto-load
-        url="Provinces/location"
-    />
     <FetchData
         ref="townsFetchDataRef"
         :sort-by="['name ASC']"
@@ -205,6 +192,11 @@ async function filterTowns(name) {
                     :country-fk="data.countryFk"
                     :province-selected="data.provinceFk"
                     @update:model-value="(value) => setProvince(value, data)"
+                    @update:options="
+                        (data) => {
+                            provincesOptions = data;
+                        }
+                    "
                     v-model="data.provinceFk"
                     @on-province-created="onProvinceCreated"
                     required
diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index eff4c9095..e2608d86f 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -250,7 +250,7 @@ function getChanges() {
     for (const [i, row] of formData.value.entries()) {
         if (!row[pk]) {
             creates.push(row);
-        } else if (originalData.value) {
+        } else if (originalData.value[i]) {
             const data = getDifferences(originalData.value[i], row);
             if (!isEmpty(data)) {
                 updates.push({
diff --git a/src/components/EditTableCellValueForm.vue b/src/components/EditTableCellValueForm.vue
index 7755df9ab..172866191 100644
--- a/src/components/EditTableCellValueForm.vue
+++ b/src/components/EditTableCellValueForm.vue
@@ -85,12 +85,14 @@ const closeForm = () => {
                     hide-selected
                     option-label="label"
                     v-model="selectedField"
+                    data-cy="field-to-edit"
                 />
                 <component
                     :is="inputs[selectedField?.component || 'input']"
                     v-bind="selectedField?.attrs || {}"
                     v-model="newValue"
                     :label="t('Value')"
+                    data-cy="value-to-edit"
                     style="width: 200px"
                 />
             </VnRow>
diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue
index d91f07535..afdc6efca 100644
--- a/src/components/FormModelPopup.vue
+++ b/src/components/FormModelPopup.vue
@@ -62,6 +62,7 @@ defineExpose({
                     @click="emit('onDataCanceled')"
                     v-close-popup
                     data-cy="FormModelPopup_cancel"
+                    z-max
                 />
                 <QBtn
                     :label="t('globals.save')"
@@ -72,6 +73,7 @@ defineExpose({
                     :disabled="isLoading"
                     :loading="isLoading"
                     data-cy="FormModelPopup_save"
+                    z-max
                 />
             </div>
         </template>
diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue
index 405577095..084feb377 100644
--- a/src/components/ItemsFilterPanel.vue
+++ b/src/components/ItemsFilterPanel.vue
@@ -9,6 +9,8 @@ import VnSelect from 'components/common/VnSelect.vue';
 import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
 
 import axios from 'axios';
+import { getParamWhere } from 'src/filters';
+import { useRoute } from 'vue-router';
 
 const { t } = useI18n();
 const props = defineProps({
@@ -26,28 +28,21 @@ const props = defineProps({
     },
 });
 
-const itemCategories = ref([]);
-const selectedCategoryFk = ref(null);
-const selectedTypeFk = ref(null);
+const route = useRoute();
+
 const itemTypesOptions = ref([]);
 const suppliersOptions = ref([]);
 const tagOptions = ref([]);
 const tagValues = ref([]);
+const categoryList = ref(null);
+const selectedCategoryFk = ref(getParamWhere(route.query.table, 'categoryFk', false));
+const selectedTypeFk = ref(getParamWhere(route.query.table, 'typeFk', false));
 
-const categoryList = computed(() => {
-    return (itemCategories.value || [])
-        .filter((category) => category.display)
-        .map((category) => ({
-            ...category,
-            icon: `vn:${(category.icon || '').split('-')[1]}`,
-        }));
-});
-
-const selectedCategory = computed(() =>
-    (itemCategories.value || []).find(
+const selectedCategory = computed(() => {
+    return (categoryList.value || []).find(
         (category) => category?.id === selectedCategoryFk.value
-    )
-);
+    );
+});
 
 const selectedType = computed(() => {
     return (itemTypesOptions.value || []).find(
@@ -87,7 +82,7 @@ const applyTags = (params, search) => {
     search();
 };
 
-const fetchItemTypes = async (id) => {
+const fetchItemTypes = async (id = selectedCategoryFk.value) => {
     const filter = {
         fields: ['id', 'name', 'categoryFk'],
         where: { categoryFk: id },
@@ -126,15 +121,19 @@ const removeTag = (index, params, search) => {
     (tagValues.value || []).splice(index, 1);
     applyTags(params, search);
 };
+const setCategoryList = (data) => {
+    categoryList.value = (data || [])
+        .filter((category) => category.display)
+        .map((category) => ({
+            ...category,
+            icon: `vn:${(category.icon || '').split('-')[1]}`,
+        }));
+    fetchItemTypes();
+};
 </script>
 
 <template>
-    <FetchData
-        url="ItemCategories"
-        limit="30"
-        auto-load
-        @on-fetch="(data) => (itemCategories = data)"
-    />
+    <FetchData url="ItemCategories" limit="30" auto-load @on-fetch="setCategoryList" />
     <FetchData
         url="Suppliers"
         limit="30"
diff --git a/src/components/LeftMenu.vue b/src/components/LeftMenu.vue
index ab2931dfd..31ad9ebed 100644
--- a/src/components/LeftMenu.vue
+++ b/src/components/LeftMenu.vue
@@ -177,6 +177,7 @@ function normalize(text) {
                         class="full-width"
                         filled
                         dense
+                        autofocus
                     />
                 </QItem>
                 <QSeparator />
diff --git a/src/components/VnSelectProvince.vue b/src/components/VnSelectProvince.vue
index 7d1297abf..d73ee964e 100644
--- a/src/components/VnSelectProvince.vue
+++ b/src/components/VnSelectProvince.vue
@@ -7,7 +7,7 @@ import VnSelectDialog from 'components/common/VnSelectDialog.vue';
 import FetchData from 'components/FetchData.vue';
 import CreateNewProvinceForm from './CreateNewProvinceForm.vue';
 
-const emit = defineEmits(['onProvinceCreated', 'onProvinceFetched']);
+const emit = defineEmits(['onProvinceCreated', 'onProvinceFetched', 'update:options']);
 const $props = defineProps({
     countryFk: {
         type: Number,
@@ -41,6 +41,7 @@ async function onProvinceCreated(_, data) {
 }
 async function handleProvinces(data) {
     provincesOptions.value = data;
+    emit('update:options', data);
 }
 
 watch(
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index 5bc634022..52a9e3fed 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -618,6 +618,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                                     $props.rowClick && $props.rowClick(row);
                                 }
                             "
+                            style="height: 100%"
                         >
                             <QCardSection
                                 vertical
diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue
index af273150e..a8840f243 100644
--- a/src/components/common/VnLocation.vue
+++ b/src/components/common/VnLocation.vue
@@ -2,7 +2,7 @@
 import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
 import VnSelectDialog from 'components/common/VnSelectDialog.vue';
 import { useI18n } from 'vue-i18n';
-import { ref } from 'vue';
+import { computed } from 'vue';
 import { useAttrs } from 'vue';
 import { useRequired } from 'src/composables/useRequired';
 const { t } = useI18n();
@@ -43,7 +43,7 @@ const formatLocation = (obj, properties) => {
     return filteredParts.join(', ');
 };
 
-const modelValue = ref(
+const modelValue = computed(() =>
     props.location ? formatLocation(props.location, locationProperties) : null
 );
 
diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue
index 8c71c0997..9eca3c711 100644
--- a/src/components/common/VnLog.vue
+++ b/src/components/common/VnLog.vue
@@ -238,6 +238,7 @@ async function openPointRecord(id, modelLog) {
     pointRecord.value = parseProps(propNames, locale, data);
 }
 async function setLogTree(data) {
+    if (!data) return;
     logTree.value = getLogTree(data);
 }
 
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index e116be32a..e5ac05231 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -268,7 +268,7 @@ async function onScroll({ to, direction, from, index }) {
 defineExpose({ opts: myOptions });
 
 function handleKeyDown(event) {
-    if (event.key === 'Tab') {
+    if (event.key === 'Tab' && !event.shiftKey) {
         event.preventDefault();
 
         const inputValue = vnSelectRef.value?.inputValue;
@@ -286,6 +286,17 @@ function handleKeyDown(event) {
             }
             vnSelectRef.value?.hidePopup();
         }
+
+        const focusableElements = document.querySelectorAll(
+            'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'
+        );
+        const currentIndex = Array.prototype.indexOf.call(
+            focusableElements,
+            event.target
+        );
+        if (currentIndex >= 0 && currentIndex < focusableElements.length - 1) {
+            focusableElements[currentIndex + 1].focus();
+        }
     }
 }
 </script>
diff --git a/src/components/common/VnSelectWorker.vue b/src/components/common/VnSelectWorker.vue
new file mode 100644
index 000000000..b0fef4443
--- /dev/null
+++ b/src/components/common/VnSelectWorker.vue
@@ -0,0 +1,85 @@
+<script setup>
+import { computed, useAttrs } from 'vue';
+import VnSelect from 'components/common/VnSelect.vue';
+import VnAvatar from 'src/components/ui/VnAvatar.vue';
+
+const emit = defineEmits(['update:modelValue']);
+const $props = defineProps({
+    hasAvatar: {
+        type: Boolean,
+        default: false,
+    },
+    hasInfo: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: [String, Number, Object],
+        default: null,
+    },
+});
+
+const $attrs = useAttrs();
+
+const value = computed({
+    get() {
+        return $props.modelValue;
+    },
+    set(val) {
+        emit('update:modelValue', val);
+    },
+});
+
+const url = computed(() => {
+    let url = 'Workers/search';
+    const { departmentCodes } = $attrs.params ?? {};
+    if (!departmentCodes) return url;
+    const params = new URLSearchParams({
+        departmentCodes: JSON.stringify(departmentCodes),
+    });
+
+    return url.concat(`?${params.toString()}`);
+});
+</script>
+
+<template>
+    <VnSelect
+        :label="$t('globals.worker')"
+        v-bind="$attrs"
+        v-model="value"
+        :url="url"
+        option-value="id"
+        option-label="nickname"
+        :fields="['id', 'name', 'nickname', 'code']"
+        sort-by="nickname ASC"
+    >
+        <template #prepend v-if="$props.hasAvatar">
+            <VnAvatar :worker-id="value" color="primary" :title="title" />
+        </template>
+        <template #append v-if="$props.hasInfo">
+            <QIcon name="info" class="cursor-pointer">
+                <QTooltip>{{ $t($props.hasInfo) }}</QTooltip>
+            </QIcon>
+        </template>
+        <template #option="scope">
+            <QItem v-bind="scope.itemProps">
+                <QItemSection>
+                    <QItemLabel>
+                        {{ scope.opt.name }}
+                    </QItemLabel>
+                    <QItemLabel v-if="!scope.opt.id">
+                        {{ scope.opt.nickname }}
+                    </QItemLabel>
+                    <QItemLabel caption v-else>
+                        {{ scope.opt.nickname }}, {{ scope.opt.code }}
+                    </QItemLabel>
+                </QItemSection>
+            </QItem>
+        </template>
+    </VnSelect>
+</template>
+
+<i18n>
+es:
+    Responsible for approving invoices: Responsable de aprobar las facturas
+</i18n>
diff --git a/src/components/ui/CatalogItem.vue b/src/components/ui/CatalogItem.vue
index 7dca19770..74a36ff2e 100644
--- a/src/components/ui/CatalogItem.vue
+++ b/src/components/ui/CatalogItem.vue
@@ -67,7 +67,7 @@ const dialog = ref(null);
                             <QTooltip>{{ t('globals.add') }}</QTooltip>
                             <QPopupProxy ref="dialog">
                                 <OrderCatalogItemDialog
-                                    :prices="item.prices"
+                                    :item="item"
                                     @added="() => dialog.hide()"
                                 />
                             </QPopupProxy>
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
index 8c0dbda94..67f6f387b 100644
--- a/src/components/ui/VnFilterPanel.vue
+++ b/src/components/ui/VnFilterPanel.vue
@@ -61,6 +61,7 @@ const emit = defineEmits([
     'update:modelValue',
     'refresh',
     'clear',
+    'search',
     'init',
     'remove',
     'setUserParams',
@@ -78,7 +79,7 @@ const userParams = ref({});
 defineExpose({ search, sanitizer, params: userParams });
 
 onMounted(() => {
-    userParams.value = $props.modelValue ?? {};
+    if (!userParams.value) userParams.value = $props.modelValue ?? {};
     emit('init', { params: userParams.value });
 });
 
@@ -104,7 +105,8 @@ watch(
 
 watch(
     () => arrayData.store.userParams,
-    (val, oldValue) => (val || oldValue) && setUserParams(val)
+    (val, oldValue) => (val || oldValue) && setUserParams(val),
+    { immediate: true }
 );
 
 watch(
diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue
index bcbf0945e..e308ea9bb 100644
--- a/src/components/ui/VnNotes.vue
+++ b/src/components/ui/VnNotes.vue
@@ -6,7 +6,6 @@ import { useI18n } from 'vue-i18n';
 import { useQuasar } from 'quasar';
 
 import { toDateHourMin } from 'src/filters';
-import { useState } from 'src/composables/useState';
 
 import VnPaginate from 'components/ui/VnPaginate.vue';
 import VnUserLink from 'components/ui/VnUserLink.vue';
@@ -26,9 +25,7 @@ const $props = defineProps({
 });
 
 const { t } = useI18n();
-const state = useState();
 const quasar = useQuasar();
-const currentUser = ref(state.getUser());
 const newNote = reactive({ text: null, observationTypeFk: null });
 const observationTypes = ref([]);
 const vnPaginateRef = ref();
diff --git a/src/composables/useCau.js b/src/composables/useCau.js
new file mode 100644
index 000000000..29319bd9a
--- /dev/null
+++ b/src/composables/useCau.js
@@ -0,0 +1,73 @@
+import VnInput from 'src/components/common/VnInput.vue';
+import { useVnConfirm } from 'src/composables/useVnConfirm';
+import axios from 'axios';
+import { ref } from 'vue';
+import { i18n } from 'src/boot/i18n';
+import useNotify from 'src/composables/useNotify.js';
+
+export async function useCau(res, message) {
+    const { notify } = useNotify();
+    const { openConfirmationModal } = useVnConfirm();
+    const { config, headers, request, status, statusText, data } = res || {};
+    const { params, url, method, signal, headers: confHeaders } = config || {};
+    const { message: resMessage, code, name } = data?.error || {};
+
+    const additionalData = {
+        path: location.hash,
+        message: resMessage,
+        code,
+        request: request?.responseURL,
+        status,
+        name,
+        statusText: statusText,
+        config: {
+            url,
+            method,
+            params,
+            headers: confHeaders,
+            aborted: signal?.aborted,
+            version: headers?.['salix-version'],
+        },
+    };
+    const opts = {
+        actions: [
+            {
+                icon: 'support_agent',
+                color: 'primary',
+                dense: true,
+                flat: false,
+                round: true,
+                handler: async () => {
+                    const locale = i18n.global.t;
+                    const reason = ref(
+                        code == 'ACCESS_DENIED' ? locale('cau.askPrivileges') : ''
+                    );
+                    openConfirmationModal(
+                        locale('cau.title'),
+                        locale('cau.subtitle'),
+                        async () => {
+                            await axios.post('OsTickets/send-to-support', {
+                                reason: reason.value,
+                                additionalData,
+                            });
+                        },
+                        null,
+                        {
+                            component: VnInput,
+                            props: {
+                                modelValue: reason,
+                                'onUpdate:modelValue': (val) => (reason.value = val),
+                                label: locale('cau.inputLabel'),
+                                class: 'full-width',
+                                required: true,
+                                autofocus: true,
+                            },
+                        }
+                    );
+                },
+            },
+        ],
+    };
+
+    notify(message ?? 'globals.error', 'negative', 'error', opts);
+}
diff --git a/src/composables/useNotify.js b/src/composables/useNotify.js
index 2f0e1c257..309156d2a 100644
--- a/src/composables/useNotify.js
+++ b/src/composables/useNotify.js
@@ -2,7 +2,7 @@ import { Notify } from 'quasar';
 import { i18n } from 'src/boot/i18n';
 
 export default function useNotify() {
-    const notify = (message, type, icon) => {
+    const notify = (message, type, icon, opts = {}) => {
         const defaultIcons = {
             warning: 'warning',
             negative: 'error',
@@ -13,6 +13,7 @@ export default function useNotify() {
             message: i18n.global.t(message),
             type: type,
             icon: icon ? icon : defaultIcons[type],
+            ...opts,
         });
     };
 
diff --git a/src/composables/useRole.js b/src/composables/useRole.js
index d1a6d6ef3..3ec65dd0a 100644
--- a/src/composables/useRole.js
+++ b/src/composables/useRole.js
@@ -20,7 +20,7 @@ export function useRole() {
 
     function hasAny(roles) {
         const roleStore = state.getRoles();
-
+        if (typeof roles === 'string') roles = [roles];
         for (const role of roles) {
             if (roleStore.value.indexOf(role) !== -1) return true;
         }
diff --git a/src/composables/useVnConfirm.js b/src/composables/useVnConfirm.js
index 76c3f4f28..4438ad11d 100644
--- a/src/composables/useVnConfirm.js
+++ b/src/composables/useVnConfirm.js
@@ -1,22 +1,29 @@
+import { h } from 'vue';
+import { Dialog } from 'quasar';
 import VnConfirm from 'components/ui/VnConfirm.vue';
-import { useQuasar } from 'quasar';
 
 export function useVnConfirm() {
-    const quasar = useQuasar();
-
-    const openConfirmationModal = (title, message, promise, successFn) => {
-        quasar
-            .dialog({
-                component: VnConfirm,
-                componentProps: {
+    const openConfirmationModal = (
+        title,
+        message,
+        promise,
+        successFn,
+        customHTML = {}
+    ) => {
+        const { component, props } = customHTML;
+        Dialog.create({
+            component: h(
+                VnConfirm,
+                {
                     title: title,
                     message: message,
                     promise: promise,
                 },
-            })
-            .onOk(async () => {
-                if (successFn) successFn();
-            });
+                { customHTML: () => h(component, props) }
+            ),
+        }).onOk(async () => {
+            if (successFn) successFn();
+        });
     };
 
     return { openConfirmationModal };
diff --git a/src/filters/getParamWhere.js b/src/filters/getParamWhere.js
index ef00a93ae..baba46f69 100644
--- a/src/filters/getParamWhere.js
+++ b/src/filters/getParamWhere.js
@@ -1,4 +1,3 @@
-// parsing JSON safely
 function parseJSON(str, fallback) {
     try {
         return JSON.parse(str ?? '{}');
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index b4765a20d..cea5c76ad 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -332,6 +332,7 @@ globals:
         fi: FI
         myTeam: My team
         departmentFk: Department
+        countryFk: Country
     changePass: Change password
     deleteConfirmTitle: Delete selected elements
     changeState: Change state
@@ -369,6 +370,11 @@ resetPassword:
     repeatPassword: Repeat password
     passwordNotMatch: Passwords don't match
     passwordChanged: Password changed
+cau:
+    title: Send cau
+    subtitle: By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.
+    inputLabel: Explain why this error should not appear
+    askPrivileges: Ask for privileges
 entry:
     list:
         newEntry: New entry
@@ -398,8 +404,8 @@ entry:
         buys: Buys
         stickers: Stickers
         package: Package
-        packing: Packing
-        grouping: Grouping
+        packing: Pack.
+        grouping: Group.
         buyingValue: Buying value
         import: Import
         pvp: PVP
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index be2b76a06..289e514bb 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -336,6 +336,7 @@ globals:
         SSN: NSS
         fi: NIF
         myTeam: Mi equipo
+        countryFk: País
     changePass: Cambiar contraseña
     deleteConfirmTitle: Eliminar los elementos seleccionados
     changeState: Cambiar estado
@@ -371,6 +372,11 @@ resetPassword:
     repeatPassword: Repetir contraseña
     passwordNotMatch: Las contraseñas no coinciden
     passwordChanged: Contraseña cambiada
+cau:
+    title: Enviar cau
+    subtitle: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
+    inputLabel: Explique el motivo por el que no deberia aparecer este fallo
+    askPrivileges: Solicitar permisos
 entry:
     list:
         newEntry: Nueva entrada
@@ -401,8 +407,8 @@ entry:
         buys: Compras
         stickers: Etiquetas
         package: Embalaje
-        packing: Packing
-        grouping: Grouping
+        packing: Pack.
+        grouping: Group.
         buyingValue: Coste
         import: Importe
         pvp: PVP
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index 754b084fc..2a84e5aa1 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -1,50 +1,10 @@
 <script setup>
-import { useQuasar } from 'quasar';
 import Navbar from 'src/components/NavBar.vue';
-import { useRouter } from 'vue-router';
-import routes from 'src/router/modules';
-import { onMounted } from 'vue';
-
-const quasar = useQuasar();
-
-onMounted(() => {
-    let isNotified = false;
-
-    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;
-
-        if (!ctrlKey || !altKey) {
-            isNotified = false;
-        }
-    };
-
-    window.addEventListener('keydown', handleKeyDown);
-    window.addEventListener('keyup', handleKeyUp);
-});
 </script>
-
 <template>
     <QLayout view="hHh LpR fFf" v-shortcut>
         <Navbar />
         <RouterView></RouterView>
-        <QFooter v-if="quasar.platform.is.mobile"></QFooter>
+        <QFooter v-if="$q.platform.is.mobile"></QFooter>
     </QLayout>
 </template>
diff --git a/src/pages/Account/AccountFilter.vue b/src/pages/Account/AccountFilter.vue
index 46fac875a..50c3ee1ac 100644
--- a/src/pages/Account/AccountFilter.vue
+++ b/src/pages/Account/AccountFilter.vue
@@ -31,7 +31,6 @@ const rolesOptions = ref([]);
     <VnFilterPanel
         :data-key="props.dataKey"
         :search-button="true"
-        :hidden-tags="['search']"
         :redirect="false"
         search-url="table"
     >
diff --git a/src/pages/Account/AccountList.vue b/src/pages/Account/AccountList.vue
index cbaaf8e26..341dd92a2 100644
--- a/src/pages/Account/AccountList.vue
+++ b/src/pages/Account/AccountList.vue
@@ -7,6 +7,7 @@ import AccountSummary from './Card/AccountSummary.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import AccountFilter from './AccountFilter.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
+import VnInput from 'src/components/common/VnInput.vue';
 const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
 const tableRef = ref();
@@ -22,10 +23,27 @@ const columns = computed(() => [
         field: 'id',
         cardVisible: true,
     },
+    {
+        align: 'left',
+        name: 'name',
+        label: t('Name'),
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+        create: true,
+    },
     {
         align: 'left',
         name: 'roleFk',
-        label: t('role'),
+        label: t('Role'),
+        component: 'select',
+        attrs: {
+            url: 'VnRoles',
+            optionValue: 'id',
+            optionLabel: 'name',
+        },
         columnFilter: {
             component: 'select',
             name: 'roleFk',
@@ -35,7 +53,11 @@ const columns = computed(() => [
                 optionLabel: 'name',
             },
         },
+        columnField: {
+            component: null,
+        },
         format: ({ role }, dashIfEmpty) => dashIfEmpty(role?.name),
+        create: true,
     },
     {
         align: 'left',
@@ -51,20 +73,32 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'name',
-        label: t('Name'),
+        name: 'email',
+        label: t('Email'),
         component: 'input',
         columnField: {
             component: null,
         },
-        cardVisible: true,
         create: true,
+        visible: false,
     },
     {
         align: 'left',
-        name: 'email',
-        label: t('email'),
-        component: 'input',
+        name: 'password',
+        label: t('Password'),
+        columnField: {
+            component: null,
+        },
+        attrs: {},
+        required: true,
+        visible: false,
+    },
+
+    {
+        align: 'left',
+        name: 'active',
+        label: t('Active'),
+        component: 'checkbox',
         create: true,
         visible: false,
     },
@@ -101,7 +135,6 @@ const exprBuilder = (param, value) => {
     }
 };
 </script>
-
 <template>
     <VnSearchbar
         data-key="AccountList"
@@ -119,6 +152,12 @@ const exprBuilder = (param, value) => {
         ref="tableRef"
         data-key="AccountList"
         url="VnUsers/preview"
+        :create="{
+            urlCreate: 'VnUsers',
+            title: t('Create user'),
+            onDataSaved: ({ id }) => tableRef.redirect(id),
+            formInitialData: {},
+        }"
         :filter="filter"
         order="id DESC"
         :columns="columns"
@@ -127,7 +166,19 @@ const exprBuilder = (param, value) => {
         :use-model="true"
         :right-search="false"
         auto-load
-    />
+    >
+        <template #more-create-dialog="{ data }">
+            <QCardSection>
+                <VnInput
+                    :label="t('Password')"
+                    v-model="data.password"
+                    type="password"
+                    :required="true"
+                    autocomplete="new-password"
+                />
+            </QCardSection>
+        </template>
+    </VnTable>
 </template>
 
 <i18n>
@@ -135,4 +186,7 @@ const exprBuilder = (param, value) => {
         Id: Id
         Nickname: Nickname
         Name: Nombre
+        Password: Contraseña
+        Active: Activo
+        Role: Rol
 </i18n>
diff --git a/src/pages/Account/Acls/AclFilter.vue b/src/pages/Account/Acls/AclFilter.vue
index 8609672b6..8035f92b8 100644
--- a/src/pages/Account/Acls/AclFilter.vue
+++ b/src/pages/Account/Acls/AclFilter.vue
@@ -37,11 +37,7 @@ onBeforeMount(() => {
         @on-fetch="(data) => (rolesOptions = data)"
         auto-load
     />
-    <VnFilterPanel
-        :data-key="props.dataKey"
-        :search-button="true"
-        :hidden-tags="['search']"
-    >
+    <VnFilterPanel :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
                 <strong>{{ t(`acls.aclFilter.${tag.label}`) }}: </strong>
diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue
index 6f1d2ca1f..1780b4247 100644
--- a/src/pages/Account/Card/AccountDescriptorMenu.vue
+++ b/src/pages/Account/Card/AccountDescriptorMenu.vue
@@ -8,7 +8,7 @@ import { useAcl } from 'src/composables/useAcl';
 import { useArrayData } from 'src/composables/useArrayData';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import VnChangePassword from 'src/components/common/VnChangePassword.vue';
-import useNotify from 'src/composables/useNotify.js';
+import { useQuasar } from 'quasar';
 
 const $props = defineProps({
     hasAccount: {
@@ -21,7 +21,7 @@ const { t } = useI18n();
 const { hasAccount } = toRefs($props);
 const { openConfirmationModal } = useVnConfirm();
 const route = useRoute();
-const { notify } = useNotify();
+const { notify } = useQuasar();
 const account = computed(() => useArrayData('AccountId').store.data[0]);
 account.value.hasAccount = hasAccount.value;
 const entityId = computed(() => +route.params.id);
diff --git a/src/pages/Account/Role/AccountRolesFilter.vue b/src/pages/Account/Role/AccountRolesFilter.vue
index ff4411897..cbe7a70c8 100644
--- a/src/pages/Account/Role/AccountRolesFilter.vue
+++ b/src/pages/Account/Role/AccountRolesFilter.vue
@@ -13,12 +13,7 @@ const props = defineProps({
 </script>
 
 <template>
-    <VnFilterPanel
-        :data-key="props.dataKey"
-        :search-button="true"
-        :hidden-tags="['search']"
-        :redirect="false"
-    >
+    <VnFilterPanel :data-key="props.dataKey" :search-button="true" :redirect="false">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
                 <strong>{{ t(`role.${tag.label}`) }}: </strong>
diff --git a/src/pages/Customer/Card/CustomerBasicData.vue b/src/pages/Customer/Card/CustomerBasicData.vue
index 1abb9f170..33f9732e2 100644
--- a/src/pages/Customer/Card/CustomerBasicData.vue
+++ b/src/pages/Customer/Card/CustomerBasicData.vue
@@ -8,7 +8,7 @@ import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
-import VnAvatar from 'src/components/ui/VnAvatar.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 import { getDifferences, getUpdatedValues } from 'src/filters';
 
 const route = useRoute();
@@ -16,7 +16,6 @@ const { t } = useI18n();
 
 const businessTypes = ref([]);
 const contactChannels = ref([]);
-const title = ref();
 const handleSalesModelValue = (val) => ({
     or: [
         { id: val },
@@ -119,41 +118,17 @@ function onBeforeSave(formData, originalData) {
                 />
             </VnRow>
             <VnRow>
-                <VnSelect
-                    url="Workers/search"
-                    v-model="data.salesPersonFk"
+                <VnSelectWorker
                     :label="t('customer.summary.salesPerson')"
+                    v-model="data.salesPersonFk"
                     :params="{
                         departmentCodes: ['VT', 'shopping'],
                     }"
-                    :fields="['id', 'nickname']"
-                    sort-by="nickname ASC"
-                    option-label="nickname"
-                    option-value="id"
+                    :has-avatar="true"
                     :rules="validate('client.salesPersonFk')"
                     :expr-builder="exprBuilder"
                     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>
+                />
                 <VnSelect
                     v-model="data.contactChannelFk"
                     :options="contactChannels"
diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue
index 2cad13115..ae4c7f3ab 100644
--- a/src/pages/Customer/Card/CustomerSummary.vue
+++ b/src/pages/Customer/Card/CustomerSummary.vue
@@ -1,12 +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, dashOrCurrency } 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 VnLinkMail from 'src/components/ui/VnLinkMail.vue';
@@ -102,7 +101,7 @@ const sumRisk = ({ clientRisks }) => {
                 <VnLv :value="entity.email" copy
                     ><template #label>
                         {{ t('globals.params.email') }}
-                        <VnLinkMail email="entity.email"></VnLinkMail> </template
+                        <VnLinkMail :email="entity.email"></VnLinkMail> </template
                 ></VnLv>
                 <VnLv
                     :label="t('customer.summary.salesPerson')"
diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue
index ea901c65a..3c4106846 100644
--- a/src/pages/Customer/Card/CustomerWebAccess.vue
+++ b/src/pages/Customer/Card/CustomerWebAccess.vue
@@ -29,7 +29,8 @@ async function hasCustomerRole() {
         :filter="filter"
         model="customer"
         :mapper="
-            ({ active, name, email }) => {
+            ({ account }) => {
+                const { name, email, active } = account;
                 return {
                     active,
                     name,
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index cd567d415..96f670542 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -3,6 +3,7 @@ import { useI18n } from 'vue-i18n';
 import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
 import VnSelect from 'components/common/VnSelect.vue';
 import VnInput from 'src/components/common/VnInput.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 defineProps({
@@ -65,19 +66,14 @@ const exprBuilder = (param, value) => {
             </QItem>
             <QItem class="q-mb-sm">
                 <QItemSection>
-                    <VnSelect
-                        url="Workers/search"
+                    <VnSelectWorker
+                        :label="t('Salesperson')"
+                        v-model="params.salesPersonFk"
                         :params="{
                             departmentCodes: ['VT'],
                         }"
-                        auto-load
-                        :label="t('Salesperson')"
                         :expr-builder="exprBuilder"
-                        v-model="params.salesPersonFk"
                         @update:model-value="searchFn()"
-                        option-value="id"
-                        option-label="name"
-                        sort-by="nickname ASC"
                         emit-value
                         map-options
                         use-input
@@ -86,18 +82,7 @@ const exprBuilder = (param, value) => {
                         outlined
                         rounded
                         :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>
             </QItem>
             <QItem class="q-mb-sm">
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index 865287aeb..e86e35966 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -2,7 +2,6 @@
 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';
@@ -12,7 +11,7 @@ import RightMenu from 'src/components/common/RightMenu.vue';
 import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
 import { toDate } from 'src/filters';
 import CustomerFilter from './CustomerFilter.vue';
-import VnAvatar from 'src/components/ui/VnAvatar.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const router = useRouter();
@@ -422,40 +421,17 @@ function handleLocation(data, location) {
         auto-load
     >
         <template #more-create-dialog="{ data }">
-            <VnSelect
-                url="Workers/search"
-                v-model="data.salesPersonFk"
+            <VnSelectWorker
                 :label="t('customer.summary.salesPerson')"
+                v-model="data.salesPersonFk"
                 :params="{
                     departmentCodes: ['VT', 'shopping'],
                 }"
-                :fields="['id', 'nickname', 'code']"
-                sort-by="nickname ASC"
-                option-label="nickname"
-                option-value="id"
+                :has-avatar="true"
+                :id-value="data.salesPersonFk"
                 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
                 :acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
                 v-model="data.location"
diff --git a/src/pages/Department/Card/DepartmentBasicData.vue b/src/pages/Department/Card/DepartmentBasicData.vue
index 07bccd971..22ce06821 100644
--- a/src/pages/Department/Card/DepartmentBasicData.vue
+++ b/src/pages/Department/Card/DepartmentBasicData.vue
@@ -6,6 +6,7 @@ import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -48,14 +49,9 @@ const { t } = useI18n();
                 />
             </VnRow>
             <VnRow>
-                <VnSelect
+                <VnSelectWorker
                     :label="t('department.bossDepartment')"
                     v-model="data.workerFk"
-                    url="Workers/search"
-                    option-value="id"
-                    option-label="name"
-                    hide-selected
-                    map-options
                     :rules="validate('department.workerFk')"
                 />
                 <VnSelect
diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue
index c8fffb0ef..0aeae622d 100644
--- a/src/pages/InvoiceOut/InvoiceOutList.vue
+++ b/src/pages/InvoiceOut/InvoiceOutList.vue
@@ -52,7 +52,9 @@ const columns = computed(() => [
         label: t('invoiceOutList.tableVisibleColumns.id'),
         chip: { condition: () => true },
         isId: true,
-        columnFilter: { name: 'search' },
+        columnFilter: {
+            name: 'id',
+        },
     },
     {
         align: 'left',
@@ -84,8 +86,15 @@ const columns = computed(() => [
         label: t('globals.client'),
         cardVisible: true,
         component: 'select',
-        attrs: { url: 'Clients', fields: ['id', 'name'] },
-        columnField: { component: null },
+        attrs: {
+            url: 'Clients',
+            fields: ['id', 'socialName'],
+            optionLabel: 'socialName',
+            optionValue: 'id',
+        },
+        columnField: {
+            component: null,
+        },
     },
     {
         align: 'left',
diff --git a/src/pages/InvoiceOut/locale/es.yml b/src/pages/InvoiceOut/locale/es.yml
index bf5126641..106168a5d 100644
--- a/src/pages/InvoiceOut/locale/es.yml
+++ b/src/pages/InvoiceOut/locale/es.yml
@@ -11,7 +11,7 @@ invoiceOutList:
         ref: Referencia
         issued: Fecha emisión
         created: F. creación
-        dueDate: F. máxima
+        dueDate: Fecha vencimiento
         invoiceOutSerial: Serial
         ticket: Ticket
         taxArea: Area
diff --git a/src/pages/Item/Card/ItemBarcode.vue b/src/pages/Item/Card/ItemBarcode.vue
index 197e9142f..6db5943c7 100644
--- a/src/pages/Item/Card/ItemBarcode.vue
+++ b/src/pages/Item/Card/ItemBarcode.vue
@@ -2,12 +2,15 @@
 import { ref, nextTick } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
+import axios from 'axios';
 
 import CrudModel from 'src/components/CrudModel.vue';
 import VnInput from 'src/components/common/VnInput.vue';
+import useNotify from 'src/composables/useNotify.js';
 
 const route = useRoute();
 const { t } = useI18n();
+const { notify } = useNotify();
 
 const itemBarcodeRef = ref(null);
 
@@ -23,6 +26,24 @@ const focusLastInput = () => {
         if (lastInput) lastInput.focus();
     });
 };
+
+const removeRow = (row) => {
+    itemBarcodeRef.value.remove([row]);
+};
+
+const submit = async (rows) => {
+    const params = rows[rows.length - 1];
+    let { data } = await axios.get('ItemBarcodes');
+    const code = params.code;
+
+    if (data.some((codes) => codes.code === code)) {
+        notify(t('Codes can not be repeated'), 'negative');
+        itemBarcodeRef.value.reset();
+        return;
+    }
+    await axios.patch(`ItemBarcodes`, params);
+    notify(t('globals.dataSaved'), 'positive');
+};
 </script>
 <template>
     <div class="full-width flex justify-center">
@@ -39,6 +60,7 @@ const focusLastInput = () => {
                 ref="itemBarcodeRef"
                 url="ItemBarcodes"
                 auto-load
+                :save-fn="submit"
             >
                 <template #body="{ rows }">
                     <QCard class="q-px-lg q-py-md">
@@ -54,7 +76,7 @@ const focusLastInput = () => {
                                 focusable-input
                             />
                             <QIcon
-                                @click="itemBarcodeRef.remove([row])"
+                                @click="removeRow(row)"
                                 class="cursor-pointer q-ml-md"
                                 color="primary"
                                 name="delete"
@@ -89,4 +111,5 @@ es:
     Code: Código
     Remove barcode: Quitar código de barras
     Add barcode: Añadir código de barras
+    Codes can not be repeated: Los códigos no puden ser repetidos
 </i18n>
diff --git a/src/pages/Item/Card/ItemBasicData.vue b/src/pages/Item/Card/ItemBasicData.vue
index 1b0342668..a1788617f 100644
--- a/src/pages/Item/Card/ItemBasicData.vue
+++ b/src/pages/Item/Card/ItemBasicData.vue
@@ -70,6 +70,7 @@ const onIntrastatCreated = (response, formData) => {
                     option-label="name"
                     hide-selected
                     map-options
+                    required
                 >
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue
index c4b561772..57774f75e 100644
--- a/src/pages/Item/Card/ItemBotanical.vue
+++ b/src/pages/Item/Card/ItemBotanical.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, onMounted, reactive, computed } from 'vue';
+import { ref, reactive, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
diff --git a/src/pages/Item/Card/ItemDescriptorImage.vue b/src/pages/Item/Card/ItemDescriptorImage.vue
index 735e5eb4f..422725a38 100644
--- a/src/pages/Item/Card/ItemDescriptorImage.vue
+++ b/src/pages/Item/Card/ItemDescriptorImage.vue
@@ -67,7 +67,7 @@ const handlePhotoUpdated = (evt = false) => {
 
 <template>
     <div class="relative-position">
-        <VnImg ref="image" :id="$props.entityId" zoom-resolution="1600x900">
+        <VnImg ref="image" :id="parseInt($props.entityId)" zoom-resolution="1600x900">
             <template #error>
                 <div class="absolute-full picture text-center q-pa-md flex flex-center">
                     <div>
diff --git a/src/pages/Item/Card/ItemDiary.vue b/src/pages/Item/Card/ItemDiary.vue
index a3ac6645e..b94ff9255 100644
--- a/src/pages/Item/Card/ItemDiary.vue
+++ b/src/pages/Item/Card/ItemDiary.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, computed, onUnmounted, reactive, ref, nextTick, watch } from 'vue';
+import { onMounted, computed, reactive, ref, nextTick, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
 
@@ -12,20 +12,18 @@ import FetchData from 'components/FetchData.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 
-import { useStateStore } from 'stores/useStateStore';
 import { toDateFormat } from 'src/filters/date.js';
 import { dashIfEmpty } from 'src/filters';
 import { date } from 'quasar';
 import { useState } from 'src/composables/useState';
 import { useArrayData } from 'src/composables/useArrayData';
 import axios from 'axios';
+import VnSubToolbar from 'components/ui/VnSubToolbar.vue';
 
 const { t } = useI18n();
 const route = useRoute();
 const router = useRouter();
-const stateStore = useStateStore();
 const state = useState();
-
 const user = state.getUser();
 const today = ref(Date.vnNew());
 const warehousesOptions = ref([]);
@@ -145,8 +143,6 @@ onMounted(async () => {
     await updateWarehouse(warehouseFk.value);
 });
 
-onUnmounted(() => (stateStore.rightDrawer = false));
-
 watch(
     () => router.currentRoute.value.params.id,
     (newId) => {
@@ -205,8 +201,8 @@ async function updateWarehouse(warehouseFk) {
         auto-load
         @on-fetch="(data) => (warehousesOptions = data)"
     />
-    <template v-if="stateStore.isHeaderMounted()">
-        <Teleport to="#st-data">
+    <VnSubToolbar class="q-mb-md">
+        <template #st-data>
             <div class="row">
                 <VnSelect
                     :label="t('itemDiary.warehouse')"
@@ -235,9 +231,8 @@ async function updateWarehouse(warehouseFk) {
                     @update:model-value="fetchItemBalances"
                 />
             </div>
-        </Teleport>
-        <Teleport to="#st-actions"> </Teleport>
-    </template>
+        </template>
+    </VnSubToolbar>
     <QPage class="column items-center q-pa-md">
         <QTable
             :rows="itemBalances"
diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue
index 22fb9adc7..d4d0647e3 100644
--- a/src/pages/Item/Card/ItemLastEntries.vue
+++ b/src/pages/Item/Card/ItemLastEntries.vue
@@ -1,12 +1,10 @@
 <script setup>
-import { onMounted, computed, onUnmounted, ref, watch } from 'vue';
+import { onMounted, computed, ref, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 import { dateRange } from 'src/filters';
 import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
-
-import { useStateStore } from 'stores/useStateStore';
 import { toDateTimeFormat } from 'src/filters/date.js';
 import { dashIfEmpty } from 'src/filters';
 import { toCurrency } from 'filters/index';
@@ -15,7 +13,6 @@ import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 
 const { t } = useI18n();
 const route = useRoute();
-const stateStore = useStateStore();
 
 const exprBuilder = (param, value) => {
     switch (param) {
@@ -180,8 +177,6 @@ onMounted(async () => {
         updateFilter();
     });
 });
-
-onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
diff --git a/src/pages/Item/Card/ItemShelving.vue b/src/pages/Item/Card/ItemShelving.vue
index 27e265e6b..7ad60c9e0 100644
--- a/src/pages/Item/Card/ItemShelving.vue
+++ b/src/pages/Item/Card/ItemShelving.vue
@@ -1,19 +1,15 @@
 <script setup>
-import { onMounted, ref, computed, reactive } from 'vue';
+import { onMounted, ref, computed, reactive, watchEffect } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
-
-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';
-
 import { toDateFormat } from 'src/filters/date.js';
-import { dashIfEmpty } from 'src/filters';
 import { useArrayData } from 'src/composables/useArrayData';
 import useNotify from 'src/composables/useNotify.js';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import axios from 'axios';
 import { useStateStore } from 'stores/useStateStore';
+import VnTable from 'src/components/VnTable/VnTable.vue';
 
 const stateStore = useStateStore();
 
@@ -21,8 +17,9 @@ const route = useRoute();
 const { t } = useI18n();
 const { notify } = useNotify();
 const { openConfirmationModal } = useVnConfirm();
-
-const rowsSelected = ref([]);
+const tableRef = ref();
+const selectedRows = ref([]);
+const hasSelectedCards = computed(() => selectedRows.value.length > 0);
 
 const exprBuilder = (param, value) => {
     switch (param) {
@@ -36,6 +33,11 @@ const exprBuilder = (param, value) => {
 };
 
 const params = reactive({ itemFk: route.params.id });
+const filter = reactive({
+    where: {
+        itemFk: route.params.id,
+    },
+});
 
 const arrayData = useArrayData('ItemShelvings', {
     url: 'ItemShelvingPlacementSupplyStocks',
@@ -44,123 +46,69 @@ const arrayData = useArrayData('ItemShelvings', {
 });
 const rows = computed(() => arrayData.store.data || []);
 
-const applyColumnFilter = async (col) => {
-    const paramKey = col.columnFilter?.filterParamKey || col.field;
-    params[paramKey] = col.columnFilter.filterValue;
-    await arrayData.addFilter({ filter: null, params });
-};
-
-const getInputEvents = (col) => {
-    return col.columnFilter.type === 'select'
-        ? { 'update:modelValue': () => applyColumnFilter(col) }
-        : {
-              'keyup.enter': () => applyColumnFilter(col),
-          };
-};
-
 const columns = computed(() => [
     {
         label: t('shelvings.created'),
         name: 'created',
-        field: 'created',
         align: 'left',
-        sortable: true,
-        columnFilter: null,
-        format: (val) => toDateFormat(val),
+        columnFilter: false,
+        format: (row) => toDateFormat(row.created),
     },
 
     {
         label: t('shelvings.item'),
-        name: 'item',
-        field: 'itemFk',
+        name: 'itemFk',
         align: 'left',
-        sortable: true,
-        columnFilter: null,
+        columnFilter: false,
     },
     {
         label: t('shelvings.concept'),
-        name: 'concept',
+        name: 'longName',
         align: 'left',
-        sortable: true,
-        columnFilter: null,
+        columnFilter: false,
     },
     {
         label: t('shelvings.parking'),
         name: 'parking',
-        field: 'parking',
         align: 'left',
-        sortable: true,
-        format: (val) => dashIfEmpty(val),
-        columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                url: 'parkings',
-                fields: ['code'],
-                'sort-by': 'code ASC',
-                'option-value': 'code',
-                'option-label': 'code',
-                dense: true,
-            },
+        component: 'select',
+        attrs: {
+            url: 'parkings',
+            fields: ['code'],
+            'sort-by': 'code ASC',
+            'option-value': 'code',
+            'option-label': 'code',
+            dense: true,
         },
+        columnField: { component: null },
     },
     {
         label: t('shelvings.shelving'),
         name: 'shelving',
-        field: 'shelving',
         align: 'left',
-        sortable: true,
-        format: (val) => dashIfEmpty(val),
-        columnFilter: {
-            component: VnSelect,
-            type: 'select',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                url: 'shelvings',
-                fields: ['code'],
-                'sort-by': 'code ASC',
-                'option-value': 'code',
-                'option-label': 'code',
-                dense: true,
-            },
+        component: 'select',
+        attrs: {
+            url: 'shelvings',
+            fields: ['code'],
+            'sort-by': 'code ASC',
+            'option-value': 'code',
+            'option-label': 'code',
+            dense: true,
         },
+        columnField: { component: null },
     },
     {
         label: t('shelvings.label'),
         name: 'label',
         align: 'left',
-        sortable: true,
-        format: (_, row) => (row.stock / row.packing).toFixed(2),
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterParamKey: 'label',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
+        columnFilter: { inWhere: true },
+        format: (row) => (row.stock / row.packing).toFixed(2),
     },
     {
         label: t('shelvings.packing'),
-        field: 'packing',
         name: 'packing',
+        attrs: { inWhere: true },
         align: 'left',
-        sortable: true,
-        columnFilter: {
-            component: VnInput,
-            type: 'text',
-            filterValue: null,
-            event: getInputEvents,
-            attrs: {
-                dense: true,
-            },
-        },
-        format: (val) => dashIfEmpty(val),
     },
 ]);
 
@@ -169,15 +117,16 @@ const totalLabels = computed(() =>
 );
 
 const removeLines = async () => {
-    const itemShelvingIds = rowsSelected.value.map((row) => row.itemShelvingFk);
+    const itemShelvingIds = selectedRows.value.map((row) => row.itemShelvingFk);
     await axios.post('ItemShelvings/deleteItemShelvings', { itemShelvingIds });
-    rowsSelected.value = [];
+    selectedRows.value = [];
     notify('shelvings.shelvingsRemoved', 'positive');
-    await arrayData.fetch({ append: false });
+    await tableRef.value.reload();
 };
 onMounted(async () => {
     await arrayData.fetch({ append: false });
 });
+watchEffect(selectedRows);
 </script>
 
 <template>
@@ -203,7 +152,7 @@ onMounted(async () => {
             <QBtn
                 color="primary"
                 icon="delete"
-                :disabled="!rowsSelected.length"
+                :disabled="!hasSelectedCards"
                 @click="
                     openConfirmationModal(
                         t('shelvings.removeConfirmTitle'),
@@ -219,41 +168,27 @@ onMounted(async () => {
         </Teleport>
     </template>
     <QPage class="column items-center q-pa-md">
-        <QTable
-            :rows="rows"
+        <VnTable
+            ref="tableRef"
+            data-key="ItemShelving"
             :columns="columns"
-            row-key="id"
-            :pagination="{ rowsPerPage: 0 }"
-            class="full-width q-mt-md"
-            selection="multiple"
-            v-model:selected="rowsSelected"
-            :no-data-label="t('globals.noResults')"
+            :url="`ItemShelvingPlacementSupplyStocks`"
+            :filter="filter"
+            :expr-builder="exprBuilder"
+            :right-search="false"
+            v-model:selected="selectedRows"
+            :table="{
+                'row-key': 'itemShelvingFk',
+                selection: 'multiple',
+            }"
+            auto-load
         >
-            <template #top-row="{ cols }">
-                <QTr>
-                    <QTd />
-                    <QTd
-                        v-for="(col, index) in cols"
-                        :key="index"
-                        style="max-width: 100px"
-                    >
-                        <component
-                            :is="col.columnFilter.component"
-                            v-if="col.columnFilter"
-                            v-model="col.columnFilter.filterValue"
-                            v-bind="col.columnFilter.attrs"
-                            v-on="col.columnFilter.event(col)"
-                            dense
-                        />
-                    </QTd>
-                </QTr>
-            </template>
-            <template #body-cell-concept="{ row }">
-                <QTd @click.stop>
-                    <span class="link">{{ row.longName }}</span>
+            <template #column-longName="{ row }">
+                <span class="link" @click.stop>
+                    {{ row.longName }}
                     <ItemDescriptorProxy :id="row.itemFk" />
-                </QTd>
+                </span>
             </template>
-        </QTable>
+        </VnTable>
     </QPage>
 </template>
diff --git a/src/pages/Item/Card/ItemSummary.vue b/src/pages/Item/Card/ItemSummary.vue
index db90ba06f..7606e6a22 100644
--- a/src/pages/Item/Card/ItemSummary.vue
+++ b/src/pages/Item/Card/ItemSummary.vue
@@ -89,7 +89,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`;
             <QCard class="vn-one">
                 <VnTitle
                     :url="getUrl(entityId, 'basic-data')"
-                    :text="t('item.summary.otherData')"
+                    :text="t('item.summary.basicData')"
                 />
                 <VnLv
                     :label="t('item.summary.intrastatCode')"
diff --git a/src/pages/Item/Card/ItemTags.vue b/src/pages/Item/Card/ItemTags.vue
index a077c72c6..fbb0e01a7 100644
--- a/src/pages/Item/Card/ItemTags.vue
+++ b/src/pages/Item/Card/ItemTags.vue
@@ -8,7 +8,6 @@ import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import FetchData from 'components/FetchData.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
-
 import axios from 'axios';
 
 const route = useRoute();
@@ -60,6 +59,10 @@ const insertTag = (rows) => {
     itemTagsRef.value.formData[itemTagsRef.value.formData.length - 1].priority =
         getHighestPriority(rows);
 };
+
+const submitTags = async (data) => {
+    itemTagsRef.value.onSubmit(data);
+};
 </script>
 
 <template>
@@ -77,7 +80,6 @@ const insertTag = (rows) => {
                 data-key="ItemTags"
                 model="ItemTags"
                 url="ItemTags"
-                update-url="Tags/onSubmit"
                 :data-required="{
                     $index: undefined,
                     itemFk: route.params.id,
@@ -147,6 +149,7 @@ const insertTag = (rows) => {
                                 v-model="row.value"
                                 :label="t('itemTags.value')"
                                 :is-clearable="false"
+                                @keyup.enter.stop="submitTags(row)"
                             />
                             <VnInput
                                 :label="t('itemBasicData.relevancy')"
@@ -154,6 +157,7 @@ const insertTag = (rows) => {
                                 v-model="row.priority"
                                 :required="true"
                                 :rules="validate('itemTag.priority')"
+                                @keyup.enter.stop="submitTags(row)"
                             />
                             <div class="row justify-center" style="flex: 0">
                                 <QIcon
@@ -189,3 +193,8 @@ const insertTag = (rows) => {
         </QPage>
     </div>
 </template>
+
+<i18n>
+es:
+    Tags can not be repeated: Las etiquetas no pueden repetirse
+</i18n>
diff --git a/src/pages/Item/Card/ItemTax.vue b/src/pages/Item/Card/ItemTax.vue
index 84b5f63f4..8060481f0 100644
--- a/src/pages/Item/Card/ItemTax.vue
+++ b/src/pages/Item/Card/ItemTax.vue
@@ -28,7 +28,7 @@ const taxesFilter = {
     ],
 };
 
-const ItemTaxRef = ref(null);
+const ItemTaxRef = ref();
 const taxesOptions = ref([]);
 
 const submitTaxes = async (data) => {
@@ -36,7 +36,10 @@ const submitTaxes = async (data) => {
         id: tax.id,
         taxClassFk: tax.taxClassFk,
     }));
-
+    if (payload.some((item) => item.taxClassFk === null)) {
+        notify(t('Tax class cannot be blank'), 'negative');
+        return;
+    }
     await axios.post(`Items/updateTaxes`, payload);
     notify(t('globals.dataSaved'), 'positive');
 };
diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue
index 8bf5d33bd..09fccfd6d 100644
--- a/src/pages/Item/ItemFixedPrice.vue
+++ b/src/pages/Item/ItemFixedPrice.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, reactive, onUnmounted, nextTick, computed } from 'vue';
+import { onMounted, ref, onUnmounted, nextTick, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import FetchedTags from 'components/ui/FetchedTags.vue';
@@ -37,11 +37,9 @@ const fixedPrices = ref([]);
 const warehousesOptions = ref([]);
 const rowsSelected = ref([]);
 const itemFixedPriceFilterRef = ref();
-const params = reactive({});
 
 onMounted(async () => {
     stateStore.rightDrawer = true;
-    params.warehouseFk = user.value.warehouseFk;
 });
 onUnmounted(() => (stateStore.rightDrawer = false));
 
@@ -137,8 +135,17 @@ const columns = computed(() => [
         ...defaultColumnAttrs,
         columnClass: 'shrink',
         component: 'select',
-
         options: warehousesOptions,
+        columnFilter: {
+            name: 'warehouseFk',
+            inWhere: true,
+            component: 'select',
+            attrs: {
+                options: warehousesOptions,
+                'option-label': 'name',
+                'option-value': 'id',
+            },
+        },
     },
     {
         align: 'right',
@@ -210,8 +217,6 @@ const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => {
 };
 
 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
     props.row.hasMinPrice = value;
     await upsertPrice({
         row: props.row,
@@ -220,12 +225,33 @@ const updateMinPrice = async (value, props) => {
     });
 };
 
+const validations = ({ row }) => {
+    const requiredFields = [
+        'itemFk',
+        'started',
+        'ended',
+        'rate2',
+        'rate3',
+        'warehouseFk',
+    ];
+    const isValid = requiredFields.every(
+        (field) => row[field] !== null && row[field] !== undefined
+    );
+    return isValid;
+};
 const upsertPrice = async (props, resetMinPrice = false) => {
-    const { row } = props;
-    if (tableRef.value.CrudModelRef.getChanges().updates.length > 0) {
-        if (resetMinPrice) row.hasMinPrice = 0;
-        await upsertFixedPrice(row);
+    const isValid = validations({ ...props });
+    if (!isValid) {
+        return;
     }
+    const { row } = props;
+    const changes = tableRef.value.CrudModelRef.getChanges();
+    if (changes?.updates?.length > 0) {
+        if (resetMinPrice) row.hasMinPrice = 0;
+    }
+    if (!changes.updates && !changes.creates) return;
+    const data = await upsertFixedPrice(row);
+    tableRef.value.CrudModelRef.formData[props.rowIndex] = data;
 };
 
 async function upsertFixedPrice(row) {
@@ -233,13 +259,6 @@ async function upsertFixedPrice(row) {
     return data;
 }
 
-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;
 
@@ -255,39 +274,18 @@ function checkLastVisibleRow() {
 
 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);
+    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(),
-        };
+    copy = {
+        id: 0,
+        started: today,
+        ended: nextWeek,
+        hasMinPrice: 0,
+        $index: 0,
+    };
     return { original, copy };
 };
 
@@ -300,7 +298,7 @@ function highlightNewRow({ $index: index }) {
         row.classList.add('highlight');
         setTimeout(() => {
             row.classList.remove('highlight');
-        }, 3000); // Duración de la animación en milisegundos
+        }, 3000);
     }
 }
 const openEditTableCellDialog = () => {
@@ -411,9 +409,13 @@ function handleOnDataSave({ CrudModelRef }) {
             url="FixedPrices/filter"
             :order="['itemFk DESC', 'name DESC']"
             save-url="FixedPrices/crud"
-            :user-params="{ warehouseFk: user.warehouseFk }"
             ref="tableRef"
             dense
+            :filter="{
+                where: {
+                    warehouseFk: user.warehouseFk,
+                },
+            }"
             :columns="columns"
             default-mode="table"
             auto-load
@@ -427,7 +429,6 @@ function handleOnDataSave({ CrudModelRef }) {
                 disableInfiniteScroll: true,
             }"
             v-model:selected="rowsSelected"
-            :row-click="saveOnRowChange"
             :create-as-dialog="false"
             :create="{
                 onDataSaved: handleOnDataSave,
diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue
index 30b4893bd..30454a0c3 100644
--- a/src/pages/Item/ItemList.vue
+++ b/src/pages/Item/ItemList.vue
@@ -55,17 +55,6 @@ const columns = computed(() => [
         label: '',
         name: 'image',
         align: 'left',
-        columnField: {
-            component: VnImg,
-            attrs: ({ row }) => {
-                return {
-                    id: row?.id,
-                    zoomResolution: '1600x900',
-                    zoom: true,
-                    class: 'rounded',
-                };
-            },
-        },
         columnFilter: false,
         cardVisible: true,
     },
@@ -184,7 +173,7 @@ const columns = computed(() => [
         cardVisible: true,
     },
     {
-        label: t('globals.origin'),
+        label: t('item.list.origin'),
         name: 'origin',
         align: 'left',
         component: 'select',
@@ -228,7 +217,8 @@ const columns = computed(() => [
         },
     },
     {
-        label: t('item.list.weightByPiece'),
+        label: t('item.list.weight'),
+        toolTip: t('item.list.weightByPiece'),
         name: 'weightByPiece',
         align: 'left',
         component: 'input',
@@ -322,7 +312,6 @@ const columns = computed(() => [
         ref="tableRef"
         data-key="ItemList"
         url="Items/filter"
-        url-create="Items"
         :create="{
             urlCreate: 'Items',
             title: t('Create Item'),
@@ -333,12 +322,19 @@ const columns = computed(() => [
         }"
         :order="['isActive DESC', 'name', 'id']"
         :columns="columns"
-        auto-load
         redirect="Item"
         :is-editable="false"
         :right-search="false"
-        :filer="itemFilter"
+        :filter="itemFilter"
     >
+        <template #column-image="{ row }">
+            <VnImg
+                :id="row?.id"
+                zoom-resolution="1600x900"
+                :zoom="true"
+                class="rounded"
+            />
+        </template>
         <template #column-id="{ row }">
             <span class="link" @click.stop>
                 {{ row.id }}
@@ -348,7 +344,7 @@ const columns = computed(() => [
         <template #column-userName="{ row }">
             <span class="link" @click.stop>
                 {{ row.userName }}
-                <WorkerDescriptorProxy :id="row.workerFk" />
+                <WorkerDescriptorProxy :id="row.buyerFk" />
             </span>
         </template>
         <template #column-description="{ row }">
diff --git a/src/pages/Item/ItemListFilter.vue b/src/pages/Item/ItemListFilter.vue
index c8357ba33..484265b49 100644
--- a/src/pages/Item/ItemListFilter.vue
+++ b/src/pages/Item/ItemListFilter.vue
@@ -199,7 +199,17 @@ onMounted(async () => {
                         dense
                         outlined
                         rounded
-                    />
+                    >
+                        <template #option="scope">
+                            <QItem v-bind="scope.itemProps">
+                                <QItemSection>
+                                    <QItemLabel>{{
+                                        t(`params.${scope.opt?.name}`)
+                                    }}</QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
                 </QItemSection>
             </QItem>
             <QItem>
@@ -434,6 +444,13 @@ en:
         description: Description
         name: Name
         id: Id
+        Accessories: Accessories
+        Artificial: Artificial
+        Flower: Flower
+        Fruit: Fruit
+        Green: Green
+        Handmade: Handmade
+        Plant: Plant
 es:
     More fields: Más campos
     params:
@@ -450,4 +467,11 @@ es:
         description: Descripción
         name: Nombre
         id: Id
+        Accessories: Accesorios
+        Artificial: Artificial
+        Flower: Flor
+        Fruit: Fruta
+        Green: Verde
+        Handmade: Hecho a mano
+        Plant: Planta
 </i18n>
diff --git a/src/pages/Item/ItemRequest.vue b/src/pages/Item/ItemRequest.vue
index 4f037529a..734fe26de 100644
--- a/src/pages/Item/ItemRequest.vue
+++ b/src/pages/Item/ItemRequest.vue
@@ -5,13 +5,16 @@ import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.v
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 import { useStateStore } from 'stores/useStateStore';
 import { useArrayData } from 'composables/useArrayData';
-import { dashIfEmpty, toCurrency } from 'filters/index';
+import { toCurrency } from 'filters/index';
 import useNotify from 'src/composables/useNotify.js';
 import axios from 'axios';
 import ItemRequestDenyForm from './ItemRequestDenyForm.vue';
 import { toDate } from 'src/filters';
 import VnTable from 'components/VnTable/VnTable.vue';
 import VnInput from 'src/components/common/VnInput.vue';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
+import ItemRequestFilter from './ItemRequestFilter.vue';
+import RightMenu from 'src/components/common/RightMenu.vue';
 const { t } = useI18n();
 const { notify } = useNotify();
 const stateStore = useStateStore();
@@ -228,6 +231,11 @@ onMounted(async () => {
 </script>
 
 <template>
+    <RightMenu>
+        <template #right-panel>
+            <ItemRequestFilter data-key="itemRequest" />
+        </template>
+    </RightMenu>
     <VnTable
         ref="tableRef"
         data-key="itemRequest"
@@ -239,6 +247,7 @@ onMounted(async () => {
         auto-load
         :disable-option="{ card: true }"
         chip-locale="item.params"
+        :right-search="false"
     >
         <template #column-ticketFk="{ row }">
             <span class="link">
@@ -306,30 +315,28 @@ onMounted(async () => {
             />
         </template>
         <template #column-denyOptions="{ row, rowIndex }">
-            <QTd class="sticky no-padding">
-                <QIcon
-                    v-if="row.response?.length"
-                    name="insert_drive_file"
-                    color="primary"
-                    size="sm"
-                >
-                    <QTooltip>
-                        {{ row.response }}
-                    </QTooltip>
-                </QIcon>
-                <QIcon
-                    v-if="row.isOk == null"
-                    name="thumb_down"
-                    color="primary"
-                    size="sm"
-                    class="fill-icon"
-                    @click="showDenyRequestForm(row.id, rowIndex)"
-                >
-                    <QTooltip>
-                        {{ t('Discard') }}
-                    </QTooltip>
-                </QIcon>
-            </QTd>
+            <QIcon
+                v-if="row.response?.length"
+                name="insert_drive_file"
+                color="primary"
+                size="sm"
+            >
+                <QTooltip>
+                    {{ row.response }}
+                </QTooltip>
+            </QIcon>
+            <QIcon
+                v-if="row.isOk == null"
+                name="thumb_down"
+                color="primary"
+                size="sm"
+                class="fill-icon"
+                @click="showDenyRequestForm(row.id, rowIndex)"
+            >
+                <QTooltip>
+                    {{ t('Discard') }}
+                </QTooltip>
+            </QIcon>
         </template>
     </VnTable>
     <QDialog ref="denyFormRef" transition-show="scale" transition-hide="scale">
diff --git a/src/pages/Item/ItemRequestFilter.vue b/src/pages/Item/ItemRequestFilter.vue
index 64bc0e575..ea1a6e760 100644
--- a/src/pages/Item/ItemRequestFilter.vue
+++ b/src/pages/Item/ItemRequestFilter.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref } from 'vue';
+import { onMounted, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { dateRange } from 'src/filters';
 import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
@@ -7,6 +7,8 @@ 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';
+import { useArrayData } from 'src/composables/useArrayData';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const props = defineProps({
@@ -21,7 +23,8 @@ const stateOptions = [
     { code: 'accepted', name: t('accepted') },
     { code: 'denied', name: t('denied') },
 ];
-
+const arrayData = useArrayData(props.dataKey);
+const fieldFiltersValues = ref([]);
 const itemTypesOptions = ref([]);
 const warehousesOptions = ref([]);
 
@@ -56,6 +59,19 @@ const decrement = (paramsObj, key) => {
 
     paramsObj[key]--;
 };
+
+onMounted(async () => {
+    if (arrayData.store?.userParams) {
+        fieldFiltersValues.value = Object.entries(arrayData.store.userParams).map(
+            ([key, value]) => ({
+                name: key,
+                value,
+                selectedField: { name: key, label: t(`params.${key}`) },
+            })
+        );
+    }
+    exprBuilder('state', arrayData.store?.userParams?.state);
+});
 </script>
 
 <template>
@@ -145,33 +161,17 @@ const decrement = (paramsObj, key) => {
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnSelect
+                    <VnSelectWorker
                         :label="t('params.requesterFk')"
                         v-model="params.requesterFk"
                         @update:model-value="searchFn()"
-                        url="Workers/search"
                         :fields="['id', 'name']"
-                        order="name ASC"
                         :params="{ departmentCodes: ['VT'] }"
-                        option-value="id"
-                        option-label="name"
                         hide-selected
                         dense
                         outlined
                         rounded
-                    >
-                        <template #option="scope">
-                            <QItem v-bind="scope.itemProps">
-                                <QItemSection>
-                                    <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
-                                    <QItemLabel caption
-                                        >{{ scope.opt?.nickname }},
-                                        {{ scope.opt?.code }}</QItemLabel
-                                    >
-                                </QItemSection>
-                            </QItem>
-                        </template>
-                    </VnSelect>
+                    />
                 </QItemSection>
             </QItem>
             <QItem>
diff --git a/src/pages/Item/ItemType/ItemTypeSearchbar.vue b/src/pages/Item/ItemType/ItemTypeSearchbar.vue
index 87903a517..749033d43 100644
--- a/src/pages/Item/ItemType/ItemTypeSearchbar.vue
+++ b/src/pages/Item/ItemType/ItemTypeSearchbar.vue
@@ -10,7 +10,6 @@ const { t } = useI18n();
         url="ItemTypes"
         :label="t('Search item type')"
         :info="t('Search itemType by id, name or code')"
-        search-url="table"
     />
 </template>
 <i18n>
diff --git a/src/pages/Item/ItemTypeList.vue b/src/pages/Item/ItemTypeList.vue
index 149de482d..4cea931e2 100644
--- a/src/pages/Item/ItemTypeList.vue
+++ b/src/pages/Item/ItemTypeList.vue
@@ -6,6 +6,7 @@ import VnTable from 'components/VnTable/VnTable.vue';
 import FetchData from 'components/FetchData.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import ItemTypeFilter from './ItemType/ItemTypeFilter.vue';
+import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
 
 const { t } = useI18n();
 const tableRef = ref();
@@ -31,13 +32,14 @@ const columns = computed(() => [
     {
         align: 'left',
         name: 'name',
-        label: t('name'),
+        label: t('globals.name'),
         cardVisible: true,
         create: true,
     },
     {
         align: 'left',
         label: t('worker'),
+        name: 'workerFk',
         create: true,
         component: 'select',
         attrs: {
@@ -45,20 +47,20 @@ const columns = computed(() => [
             optionLabel: 'nickname',
             optionValue: 'id',
         },
+        format: (row) => row.worker?.user?.name,
         cardVisible: true,
-        visible: true,
-        columnField: {
-            component: 'userLink',
-            attrs: ({ row }) => {
-                return {
-                    workerId: row?.worker?.id,
-                    name: row.worker?.user?.name,
-                    defaultName: true,
-                };
-            },
-        },
+        columnField: { component: null },
         columnFilter: {
-            name: 'workerFk',
+            attrs: {
+                url: 'Workers/activeWithInheritedRole',
+                fields: ['id', 'name'],
+                where: { role: 'buyer' },
+                optionFilter: 'firstName',
+                optionLabel: 'name',
+                optionValue: 'id',
+                useLike: false,
+            },
+            inWhere: true,
         },
     },
     {
@@ -135,24 +137,27 @@ const columns = computed(() => [
         :columns="columns"
         auto-load
         :right-search="false"
-        :is-editable="false"
-        :use-model="true"
         redirect="item/item-type"
-    />
+    >
+        <template #column-workerFk="{ row }">
+            <span class="link" @click.stop>
+                {{ row.worker?.user?.name }}
+                <WorkerDescriptorProxy :id="row.workerFk" />
+            </span>
+        </template>
+    </VnTable>
 </template>
 
 <i18n>
     es:
         id: Id
         code: Código
-        name: Nombre
         worker: Trabajador
         ItemCategory: Reino
         Temperature: Temperatura
         Create ItemTypes: Crear familia
     en:
         code: Code
-        name: Name
         worker: Worker
         ItemCategory: ItemCategory
         Temperature: Temperature
diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml
index 78a1c3ff0..9b667fcaa 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -95,6 +95,15 @@ item:
         mine: For me
         state: State
         myTeam: My team
+        shipped: Shipped
+        description: Description
+        quantity: Quantity
+        price: Price
+        item: Item
+        achieved: Achieved
+        concept: Concept
+        denyOptions: Deny
+        scopeDays: Scope days
     searchbar:
         label: Search item
     descriptor:
@@ -112,7 +121,7 @@ item:
             title: All its properties will be copied
             subTitle: Do you want to clone this item?
     list:
-        id: Identifier
+        id: Id
         grouping: Grouping
         packing: Packing
         description: Description
@@ -122,8 +131,9 @@ item:
         intrastat: Intrastat
         isActive: Active
         size: Size
-        origin: Origin
+        origin: Orig.
         userName: Buyer
+        weight: Weight
         weightByPiece: Weight/Piece
         stemMultiplier: Multiplier
         producer: Producer
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index 5498f4458..eb3ddd4de 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -97,6 +97,15 @@ item:
         mine: Para mi
         state: Estado
         myTeam: Mi equipo
+        shipped: Enviado
+        description: Descripción
+        quantity: Cantidad
+        price: Precio
+        item: Artículo
+        achieved: Conseguido
+        concept: Concepto
+        denyOptions: Denegado
+        scopeDays: Días en adelante
     searchbar:
         label: Buscar artículo
     descriptor:
@@ -114,7 +123,7 @@ item:
             title: Todas sus propiedades serán copiadas
             subTitle: ¿Desea clonar este artículo?
     list:
-        id: Identificador
+        id: Id
         grouping: Grouping
         packing: Packing
         description: Descripción
@@ -124,7 +133,8 @@ item:
         intrastat: Intrastat
         isActive: Activo
         size: Medida
-        origin: Origen
+        origin: Orig.
+        weight: Peso
         weightByPiece: Peso (gramos)/tallo
         userName: Comprador
         stemMultiplier: Multiplicador
diff --git a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
index 3247da014..8377d73ef 100644
--- a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
+++ b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
@@ -9,6 +9,7 @@ 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';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 defineProps({ dataKey: { type: String, required: true } });
 const { t, te } = useI18n();
@@ -59,7 +60,11 @@ const getLocale = (label) => {
         </template>
         <template #customTags="{ params, searchFn, formatFn }">
             <VnFilterPanelChip
-                v-if="params.scopeDays !== null"
+                v-if="
+                    params.scopeDays !== undefined ||
+                    params.scopeDays !== '' ||
+                    params.scopeDays !== null
+                "
                 removable
                 @remove="handleScopeDays(params, null, searchFn)"
             >
@@ -108,33 +113,16 @@ const getLocale = (label) => {
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnSelect
+                    <VnSelectWorker
                         outlined
                         dense
                         rounded
                         :label="t('globals.params.salesPersonFk')"
                         v-model="params.salesPersonFk"
-                        url="Workers/search"
                         :params="{ departmentCodes: ['VT'] }"
-                        is-outlined
-                        option-value="id"
-                        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>
+                    </VnSelectWorker>
                 </QItemSection>
             </QItem>
             <QItem>
@@ -197,6 +185,18 @@ const getLocale = (label) => {
                     />
                 </QItemSection>
             </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        outlined
+                        dense
+                        rounded
+                        :label="t('globals.params.countryFk')"
+                        v-model="params.countryFk"
+                        url="Countries"
+                    />
+                </QItemSection>
+            </QItem>
             <QItem>
                 <QItemSection>
                     <VnSelect
diff --git a/src/pages/Order/Card/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue
index a71065521..453037f15 100644
--- a/src/pages/Order/Card/OrderCatalog.vue
+++ b/src/pages/Order/Card/OrderCatalog.vue
@@ -1,7 +1,7 @@
 <script setup>
 import { useStateStore } from 'stores/useStateStore';
 import { useRoute, useRouter } from 'vue-router';
-import { onMounted, onUnmounted, ref, computed, watch } from 'vue';
+import { onMounted, ref, computed, watch, provide } from 'vue';
 import axios from 'axios';
 import { useI18n } from 'vue-i18n';
 import VnPaginate from 'src/components/ui/VnPaginate.vue';
@@ -18,6 +18,7 @@ const dataKey = 'OrderCatalogList';
 const arrayData = useArrayData(dataKey);
 const store = arrayData.store;
 const tags = ref([]);
+const itemRefs = ref({});
 
 let catalogParams = {
     orderFk: route.params.id,
@@ -29,8 +30,6 @@ onMounted(() => {
     checkOrderConfirmation();
 });
 
-onUnmounted(() => (stateStore.rightDrawer = false));
-
 async function checkOrderConfirmation() {
     const response = await axios.get(`Orders/${route.params.id}`);
     if (response.data.isConfirmed === 1) {
@@ -76,6 +75,19 @@ watch(
     },
     { immediate: true }
 );
+const onItemSaved = (updatedItem) => {
+    requestAnimationFrame(() => {
+        scrollToItem(updatedItem.items[0].itemFk);
+    });
+};
+
+const scrollToItem = async (id) => {
+    const element = itemRefs.value[id]?.$el;
+    if (element) {
+        element.scrollIntoView({ behavior: 'smooth', block: 'center' });
+    }
+};
+provide('onItemSaved', onItemSaved);
 </script>
 
 <template>
@@ -115,6 +127,7 @@ watch(
                         <CatalogItem
                             v-for="row in rows"
                             :key="row.id"
+                            :ref="(el) => (itemRefs[row.id] = el)"
                             :item="row"
                             is-catalog
                             class="fill-icon"
diff --git a/src/pages/Order/Card/OrderCatalogItemDialog.vue b/src/pages/Order/Card/OrderCatalogItemDialog.vue
index 09a25fcb8..b1cd8ed6b 100644
--- a/src/pages/Order/Card/OrderCatalogItemDialog.vue
+++ b/src/pages/Order/Card/OrderCatalogItemDialog.vue
@@ -1,41 +1,53 @@
 <script setup>
-import toCurrency from '../../../filters/toCurrency';
-import { ref } from 'vue';
+import toCurrency from 'src/filters/toCurrency';
+import { inject, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import axios from 'axios';
 import { useRoute } from 'vue-router';
 import useNotify from 'composables/useNotify';
 import { useArrayData } from 'composables/useArrayData';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
 
 const { t } = useI18n();
 const { notify } = useNotify();
 const emit = defineEmits(['added']);
 const route = useRoute();
 const props = defineProps({
-    prices: {
+    item: {
         type: Array,
         required: true,
     },
 });
-
-const fields = ref((props.prices || []).map((item) => ({ ...item, quantity: 0 })));
+const onItemSaved = inject('onItemSaved');
+const prices = ref((props.item.prices || []).map((item) => ({ ...item, quantity: 0 })));
 const descriptorData = useArrayData('orderData');
 const isLoading = ref(false);
 const addToOrder = async () => {
     if (isLoading.value) return;
     isLoading.value = true;
-    const items = (fields.value || []).filter((item) => Number(item.quantity) > 0);
+    const items = (prices.value || []).filter((item) => Number(item.quantity) > 0);
     await axios.post('/OrderRows/addToOrder', {
         items,
         orderFk: Number(route.params.id),
     });
     notify(t('globals.dataSaved'), 'positive');
-    emit('added');
-    descriptorData.fetch({});
+    await descriptorData.fetch({});
+    onItemSaved({ ...props, items, saved: true });
+    emit('added', items);
     isLoading.value = false;
 };
 const canAddToOrder = () => {
-    return (fields.value || []).some((item) => Number(item.quantity) > 0);
+    let canAddToOrder = (prices.value || []).some((price) => Number(price.quantity) > 0);
+    if (canAddToOrder) {
+        const excedQuantity = prices.value.reduce(
+            (acc, { quantity }) => acc + quantity,
+            0
+        );
+        if (excedQuantity > props.item.available) {
+            canAddToOrder = false;
+        }
+    }
+    return canAddToOrder;
 };
 </script>
 
@@ -44,30 +56,33 @@ const canAddToOrder = () => {
         <QForm @submit="addToOrder">
             <QMarkupTable class="shadow-0">
                 <tbody>
-                    <tr v-for="item in fields" :key="item.warehouse">
+                    <tr v-for="price in prices" :key="price.warehouse">
                         <td class="text-bold q-pr-md td" style="width: 35%">
-                            {{ item.warehouse }}
+                            {{ price.warehouse }}
                         </td>
                         <td class="text-right" style="width: 35%">
                             <span
                                 class="link"
-                                @click="
+                                @click.shift="
                                     () => {
-                                        item.quantity += item.grouping;
+                                        price.quantity -= price.grouping;
+                                    }
+                                "
+                                @click.exact="
+                                    () => {
+                                        price.quantity += price.grouping;
                                     }
                                 "
                             >
-                                {{ item.grouping }}
+                                {{ price.grouping }}
                             </span>
-                            x {{ toCurrency(item.price) }}
+                            x {{ toCurrency(price.price) }}
                         </td>
                         <td class="text-right">
-                            <QInput
-                                v-model.number="item.quantity"
-                                type="number"
-                                :step="item.grouping"
+                            <VnInputNumber
+                                v-model.number="price.quantity"
+                                :step="price.grouping"
                                 min="0"
-                                dense
                             />
                         </td>
                     </tr>
diff --git a/src/pages/Order/Card/OrderCreateDialog.vue b/src/pages/Order/Card/OrderCreateDialog.vue
index c78b04d7f..9a53b9e30 100644
--- a/src/pages/Order/Card/OrderCreateDialog.vue
+++ b/src/pages/Order/Card/OrderCreateDialog.vue
@@ -1,9 +1,8 @@
 <script setup>
 import { useRouter } from 'vue-router';
-import { reactive, onMounted, ref } from 'vue';
+import { reactive, 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';
@@ -11,29 +10,12 @@ import VnInputDate from 'components/common/VnInputDate.vue';
 import { useDialogPluginComponent } from 'quasar';
 
 const { t } = useI18n();
-const state = useState();
 const ORDER_MODEL = 'order';
 
 const router = useRouter();
 const agencyList = ref([]);
-const addressList = ref([]);
 defineEmits(['confirm', ...useDialogPluginComponent.emits]);
 
-const fetchAddressList = async (addressId) => {
-    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;
-    }
-};
-
 const fetchAgencyList = async (landed, addressFk) => {
     if (!landed || !addressFk) {
         return;
@@ -59,17 +41,9 @@ const initialFormState = reactive({
     clientFk: $props.clientFk,
 });
 
-const onClientChange = async (clientId = $props.clientFk) => {
-    const { data } = await axios.get(`Clients/${clientId}`);
-    await fetchAddressList(data.defaultAddressFk);
-};
-
 async function onDataSaved(_, id) {
     await router.push({ path: `/order/${id}/catalog` });
 }
-onMounted(async () => {
-    await onClientChange();
-});
 </script>
 
 <template>
@@ -90,10 +64,9 @@ onMounted(async () => {
                     option-value="id"
                     option-label="name"
                     :filter="{
-                        fields: ['id', 'name', 'defaultAddressFk'],
+                        fields: ['id', 'name'],
                     }"
                     hide-selected
-                    @update:model-value="onClientChange"
                 >
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
@@ -110,7 +83,7 @@ onMounted(async () => {
                     :label="t('order.form.addressFk')"
                     v-model="data.addressId"
                     url="addresses"
-                    :fields="['id', 'nickname', 'defaultAddressFk', 'street', 'city']"
+                    :fields="['id', 'nickname', 'street', 'city']"
                     sort-by="id"
                     option-value="id"
                     option-label="street"
diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue
index 917369919..dc86600ac 100644
--- a/src/pages/Order/Card/OrderFilter.vue
+++ b/src/pages/Order/Card/OrderFilter.vue
@@ -6,6 +6,7 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
 import VnSelect from 'components/common/VnSelect.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInput from 'components/common/VnInput.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const props = defineProps({
@@ -61,28 +62,16 @@ const sourceList = ref([]);
                     outlined
                     rounded
                 />
-                <VnSelect
-                    :label="t('salesPerson')"
+                <VnSelectWorker
+                    :label="t('globals.salesPerson')"
                     v-model="params.workerFk"
-                    url="Workers/search"
-                    :filter="{ departmentCodes: ['VT'] }"
-                    sort-by="nickname ASC"
-                    option-label="nickname"
+                    :params="{
+                        departmentCodes: ['VT'],
+                    }"
                     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')"
diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue
index c47a9b2ec..dfeb0f6e2 100644
--- a/src/pages/Order/OrderList.vue
+++ b/src/pages/Order/OrderList.vue
@@ -1,7 +1,7 @@
 <script setup>
 import axios from 'axios';
 import { useI18n } from 'vue-i18n';
-import { computed, onMounted, ref } from 'vue';
+import { computed, ref, onMounted } from 'vue';
 import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
 import OrderSummary from 'pages/Order/Card/OrderSummary.vue';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
@@ -15,14 +15,13 @@ import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vu
 import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
 import { toDateTimeFormat } from 'src/filters/date';
 import { useRoute } from 'vue-router';
-import dataByOrder from 'src/utils/dataByOrder';
 
 const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
 const tableRef = ref();
 const agencyList = ref([]);
-const addressesList = ref([]);
 const route = useRoute();
+const addressOptions = ref([]);
 const columns = computed(() => [
     {
         align: 'left',
@@ -148,16 +147,12 @@ onMounted(() => {
     const id = JSON.parse(clientId);
     fetchClientAddress(id.clientFk);
 });
+
 async function fetchClientAddress(id, formData = {}) {
-    const { data } = await axios.get(`Clients/${id}`, {
-        params: {
-            filter: {
-                order: ['isDefaultAddress DESC', 'isActive DESC', 'nickname ASC'],
-                include: { relation: 'addresses' },
-            },
-        },
-    });
-    addressesList.value = data.addresses;
+    const { data } = await axios.get(
+        `Clients/${id}/addresses?filter[order]=isActive DESC`
+    );
+    addressOptions.value = data;
     formData.addressId = data.defaultAddressFk;
     fetchAgencies(formData);
 }
@@ -168,7 +163,7 @@ async function fetchAgencies({ landed, addressId }) {
     const { data } = await axios.get('Agencies/landsThatDay', {
         params: { addressFk: addressId, landed },
     });
-    agencyList.value = dataByOrder(data, 'agencyMode ASC');
+    agencyList.value = data;
 }
 
 const getDateColor = (date) => {
@@ -252,34 +247,29 @@ const getDateColor = (date) => {
             </VnSelect>
             <VnSelect
                 v-model="data.addressId"
-                :options="addressesList"
+                :options="addressOptions"
                 :label="t('module.address')"
                 option-value="id"
                 option-label="nickname"
                 @update:model-value="() => fetchAgencies(data)"
             >
                 <template #option="scope">
-                    <QItem
-                        v-bind="scope.itemProps"
-                        :class="{ disabled: !scope.opt.isActive }"
-                    >
-                        <QItemSection style="min-width: min-content" avatar>
-                            <QIcon
-                                v-if="
-                                    scope.opt.isActive && data.addressId === scope.opt.id
-                                "
-                                size="sm"
-                                color="grey"
-                                name="star"
-                                class="fill-icon"
-                            />
-                        </QItemSection>
+                    <QItem v-bind="scope.itemProps">
                         <QItemSection>
-                            <QItemLabel>
-                                {{ scope.opt.nickname }}
-                            </QItemLabel>
-                            <QItemLabel caption>
-                                {{ `${scope.opt.street}, ${scope.opt.city}` }}
+                            <QItemLabel
+                                :class="{
+                                    'color-vn-label': !scope.opt?.isActive,
+                                }"
+                            >
+                                {{
+                                    `${
+                                        !scope.opt?.isActive
+                                            ? t('basicData.inactive')
+                                            : ''
+                                    } `
+                                }}
+                                {{ scope.opt?.nickname }}: {{ scope.opt?.street }},
+                                {{ scope.opt?.city }}
                             </QItemLabel>
                         </QItemSection>
                     </QItem>
diff --git a/src/pages/Route/Card/RouteFilter.vue b/src/pages/Route/Card/RouteFilter.vue
index a6cd149f1..6f65313d3 100644
--- a/src/pages/Route/Card/RouteFilter.vue
+++ b/src/pages/Route/Card/RouteFilter.vue
@@ -4,6 +4,7 @@ import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
 import VnSelect from 'components/common/VnSelect.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInput from 'components/common/VnInput.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const props = defineProps({
@@ -31,29 +32,13 @@ const emit = defineEmits(['search']);
         <template #body="{ params }">
             <QItem class="q-my-sm">
                 <QItemSection>
-                    <VnSelect
-                        :label="t('Worker')"
+                    <VnSelectWorker
                         v-model="params.workerFk"
-                        url="Workers/search"
-                        sort-by="nickname ASC"
-                        option-value="id"
-                        option-label="nickname"
                         dense
                         outlined
                         rounded
                         :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>
             </QItem>
             <QItem class="q-my-sm">
diff --git a/src/pages/Route/Card/RouteForm.vue b/src/pages/Route/Card/RouteForm.vue
index 8c89718fa..aa5caf1ef 100644
--- a/src/pages/Route/Card/RouteForm.vue
+++ b/src/pages/Route/Card/RouteForm.vue
@@ -11,6 +11,7 @@ import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInput from 'components/common/VnInput.vue';
 import axios from 'axios';
 import VnInputTime from 'components/common/VnInputTime.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const route = useRoute();
@@ -94,26 +95,7 @@ const onSave = (data, response) => {
     >
         <template #form="{ data }">
             <VnRow>
-                <VnSelect
-                    :label="t('Worker')"
-                    v-model="data.workerFk"
-                    url="Workers/search"
-                    sort-by="nickname ASC"
-                    option-value="id"
-                    option-label="nickname"
-                    :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>
+                <VnSelectWorker v-model="data.workerFk" />
                 <VnSelect
                     :label="t('Vehicle')"
                     v-model="data.vehicleFk"
diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue
index dbf646935..38e907ce0 100644
--- a/src/pages/Route/RouteExtendedList.vue
+++ b/src/pages/Route/RouteExtendedList.vue
@@ -223,10 +223,10 @@ function navigate(id) {
     router.push({ path: `/route/${id}` });
 }
 
-const cloneRoutes = () => {
+const cloneRoutes = async () => {
     if (!selectedRows.value.length || !startingDate.value) return;
-    axios.post('Routes/clone', {
-        created: startingDate.value,
+    await axios.post('Routes/clone', {
+        dated: startingDate.value,
         ids: selectedRows.value.map((row) => row?.id),
     });
     startingDate.value = null;
@@ -274,7 +274,6 @@ const openTicketsDialog = (id) => {
             <QCardSection>
                 <p class="text-h6 q-ma-none">{{ t('route.Select the starting date') }}</p>
             </QCardSection>
-
             <QCardSection class="q-pt-none">
                 <VnInputDate
                     :label="t('route.Stating date')"
diff --git a/src/pages/Shelving/ShelvingList.vue b/src/pages/Shelving/ShelvingList.vue
index d29f6ff15..a6ea50cf4 100644
--- a/src/pages/Shelving/ShelvingList.vue
+++ b/src/pages/Shelving/ShelvingList.vue
@@ -2,7 +2,7 @@
 import VnPaginate from 'components/ui/VnPaginate.vue';
 import { useStateStore } from 'stores/useStateStore';
 import { useI18n } from 'vue-i18n';
-import { onMounted, onUnmounted } from 'vue';
+import { onMounted } from 'vue';
 import CardList from 'components/ui/CardList.vue';
 import VnLv from 'components/ui/VnLv.vue';
 import { useRouter } from 'vue-router';
@@ -21,7 +21,6 @@ const filter = {
 };
 
 onMounted(() => (stateStore.rightDrawer = true));
-onUnmounted(() => (stateStore.rightDrawer = false));
 
 function navigate(id) {
     router.push({ path: `/shelving/${id}` });
diff --git a/src/pages/Supplier/Card/SupplierBasicData.vue b/src/pages/Supplier/Card/SupplierBasicData.vue
index 70f6432dd..842109656 100644
--- a/src/pages/Supplier/Card/SupplierBasicData.vue
+++ b/src/pages/Supplier/Card/SupplierBasicData.vue
@@ -5,6 +5,7 @@ import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -30,31 +31,11 @@ const companySizes = [
                     :rules="validate('supplier.nickname')"
                     clearable
                 />
-                <VnSelect
-                    :label="t('supplier.basicData.workerFk')"
+                <VnSelectWorker
                     v-model="data.workerFk"
-                    url="Workers/search"
-                    sort-by="nickname ASC"
+                    has-info="Responsible for approving invoices"
                     :rules="validate('supplier.workerFk')"
-                >
-                    <template #append>
-                        <QIcon name="info" class="cursor-pointer">
-                            <QTooltip>{{
-                                t('Responsible for approving invoices')
-                            }}</QTooltip>
-                        </QIcon>
-                    </template>
-                    <template #option="scope">
-                        <QItem v-bind="scope.itemProps">
-                            <QItemSection>
-                                <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
-                                <QItemLabel caption>
-                                    {{ scope.opt?.nickname }}, {{ scope.opt?.id }}
-                                </QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template>
-                </VnSelect>
+                />
                 <VnSelect
                     :label="t('supplier.basicData.size')"
                     v-model="data.companySize"
@@ -102,6 +83,5 @@ const companySizes = [
 
 <i18n>
 es:
-    Responsible for approving invoices: Responsable de aprobar las facturas
     Small(1-5), Medium(6-50), Big(> 50): Pequeño(1-5), Mediano(6-50), Grande(> 50)
 </i18n>
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
index ab96a6e75..0f6cc5772 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
+import { ref, computed, onMounted, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 
 import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
@@ -134,8 +134,6 @@ onMounted(() => {
     loadDefaultTicketAction();
     ticketHaveNegatives();
 });
-
-onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
diff --git a/src/pages/Ticket/Card/TicketComponents.vue b/src/pages/Ticket/Card/TicketComponents.vue
index b88dd89e8..8fab1968b 100644
--- a/src/pages/Ticket/Card/TicketComponents.vue
+++ b/src/pages/Ticket/Card/TicketComponents.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
+import { ref, computed, onMounted, watch, nextTick } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
@@ -168,8 +168,6 @@ const getTicketVolume = async () => {
 onMounted(() => {
     stateStore.rightDrawer = true;
 });
-
-onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
diff --git a/src/pages/Ticket/Card/TicketCreateTracking.vue b/src/pages/Ticket/Card/TicketCreateTracking.vue
index 3ea762c6c..5c1e916f2 100644
--- a/src/pages/Ticket/Card/TicketCreateTracking.vue
+++ b/src/pages/Ticket/Card/TicketCreateTracking.vue
@@ -9,6 +9,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import FetchData from 'components/FetchData.vue';
 
 import { useState } from 'src/composables/useState';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const emit = defineEmits(['onRequestCreated']);
 
@@ -46,29 +47,7 @@ const onStateFkChange = (formData) => (formData.userFk = user.value.id);
                     option-label="name"
                     option-value="id"
                 />
-                <VnSelect
-                    :label="t('expedition.worker')"
-                    v-model="data.userFk"
-                    url="Workers/search"
-                    fields=" ['id', 'name']"
-                    sort-by="name ASC"
-                    hide-selected
-                    option-label="name"
-                    option-value="id"
-                >
-                    <template #option="{ opt, itemProps }">
-                        <QItem v-bind="itemProps">
-                            <QItemSection>
-                                <QItemLabel>
-                                    {{ opt.name }}
-                                </QItemLabel>
-                                <QItemLabel caption>
-                                    {{ opt.nickname }}, {{ opt.code }}
-                                </QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template></VnSelect
-                >
+                <VnSelectWorker v-model="data.userFk" :fields="['id', 'name']" />
             </VnRow>
         </template>
     </FormModelPopup>
diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
index 60a703f84..38e2af612 100644
--- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue
+++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
@@ -1,6 +1,6 @@
 <script setup>
 import axios from 'axios';
-import { computed, ref, toRefs } from 'vue';
+import { computed, onMounted, ref, toRefs, watch } from 'vue';
 import { useQuasar } from 'quasar';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
@@ -24,6 +24,15 @@ const props = defineProps({
     },
 });
 
+onMounted(() => {
+    restoreTicket();
+});
+
+watch(
+    () => props.ticket,
+    () => restoreTicket
+);
+
 const { push, currentRoute } = useRouter();
 const { dialog, notify } = useQuasar();
 const { t } = useI18n();
@@ -42,6 +51,7 @@ const hasPdf = ref();
 const weight = ref();
 const hasDocuwareFile = ref();
 const quasar = useQuasar();
+const canRestoreTicket = ref(false);
 const actions = {
     clone: async () => {
         const opts = { message: t('Ticket cloned'), type: 'positive' };
@@ -373,6 +383,54 @@ async function uploadDocuware(force) {
 
     if (data) notify({ message: t('PDF sent!'), type: 'positive' });
 }
+
+const restoreTicket = async () => {
+    const filter = {
+        fields: ['id', 'originFk', 'creationDate', 'newInstance'],
+        where: {
+            originFk: ticketId.value,
+            newInstance: { like: '%"isDeleted":true%' },
+        },
+        order: 'creationDate DESC',
+        limit: 1,
+    };
+    const params = { filter: JSON.stringify(filter) };
+
+    const { data } = await axios.get(`TicketLogs`, { params });
+
+    if (data && data.length) {
+        const now = Date.vnNew();
+        const maxDate = new Date(data[0].creationDate);
+        maxDate.setHours(maxDate.getHours() + 1);
+        if (now <= maxDate) {
+            return (canRestoreTicket.value = true);
+        }
+        return (canRestoreTicket.value = false);
+    }
+    return (canRestoreTicket.value = false);
+};
+
+async function openRestoreConfirmation(force) {
+    if (!force)
+        return quasar
+            .dialog({
+                component: VnConfirm,
+                componentProps: {
+                    title: t('Are you sure you want to restore the ticket?'),
+                    message: t('You are going to restore this ticket'),
+                },
+            })
+            .onOk(async () => {
+                ticketToRestore();
+            });
+}
+
+async function ticketToRestore() {
+    const { data } = await axios.post(`Tickets/${ticketId.value}/restore`);
+    if (data) {
+        notify({ message: t('Ticket restored'), type: 'positive' });
+    }
+}
 </script>
 <template>
     <FetchData
@@ -560,6 +618,12 @@ async function uploadDocuware(force) {
         </QItemSection>
         <QItemSection>{{ t('Show Proforma') }}</QItemSection>
     </QItem>
+    <QItem v-if="canRestoreTicket" @click="openRestoreConfirmation()" v-ripple clickable>
+        <QItemSection avatar>
+            <QIcon name="restore" />
+        </QItemSection>
+        <QItemSection>{{ t('Restore ticket') }}</QItemSection>
+    </QItem>
     <QItem
         v-if="isEditable"
         @click="showChangeTimeDialog = !showChangeTimeDialog"
@@ -746,4 +810,8 @@ es:
     You are going to delete this ticket: Vas a eliminar este ticket
     as PDF signed: como PDF firmado
     Are you sure you want to replace this delivery note?: ¿Seguro que quieres reemplazar este albarán?
+    Restore ticket: Restaurar ticket
+    Are you sure you want to restore the ticket?: ¿Seguro que quieres restaurar el ticket?
+    You are going to restore this ticket: Vas a restaurar este ticket
+    Ticket restored: Ticket restaurado
 </i18n>
diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue
index b7f1f4dd0..38010a997 100644
--- a/src/pages/Ticket/Card/TicketExpedition.vue
+++ b/src/pages/Ticket/Card/TicketExpedition.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, computed, onUnmounted } from 'vue';
+import { onMounted, ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
@@ -197,8 +197,6 @@ onMounted(async () => {
     const filteredColumns = columns.value.filter((col) => col.name !== 'history');
     allColumnNames.value = filteredColumns.map((col) => col.name);
 });
-
-onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index b534170c9..a7e0f6171 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, computed, onUnmounted, watch } from 'vue';
+import { onMounted, ref, computed, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter, useRoute } from 'vue-router';
 import { useQuasar } from 'quasar';
@@ -421,8 +421,6 @@ onMounted(async () => {
     getConfig();
 });
 
-onUnmounted(() => (stateStore.rightDrawer = false));
-
 const items = ref([]);
 const newRow = ref({});
 
@@ -770,7 +768,7 @@ watch(
         </template>
         <template #column-item="{ row }">
             <div class="row column full-width justify-between items-start">
-                {{ row?.item?.name }}
+                {{ row?.concept }}
                 <div v-if="row?.item?.subName" class="subName">
                     {{ row?.item?.subName.toUpperCase() }}
                 </div>
diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
index bd2099756..4cc96e9e2 100644
--- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue
+++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
@@ -11,7 +11,7 @@ import VnInput from 'src/components/common/VnInput.vue';
 import useNotify from 'src/composables/useNotify.js';
 import axios from 'axios';
 import { toDateFormat } from 'src/filters/date';
-import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 import { useVnConfirm } from 'composables/useVnConfirm';
 
 const emit = defineEmits(['updateDiscounts', 'getMana', 'refreshTable']);
@@ -48,7 +48,7 @@ const { push } = useRouter();
 const { t } = useI18n();
 const { dialog } = useQuasar();
 const { notify } = useNotify();
-const role = useRole();
+const acl = useAcl();
 const btnDropdownRef = ref(null);
 const { openConfirmationModal } = useVnConfirm();
 
@@ -58,8 +58,10 @@ const isClaimable = computed(() => {
     if (ticket.value) {
         const landedPlusWeek = new Date(ticket.value.landed);
         landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
-        const hasClaimManagerRole = role.hasAny('claimManager');
-        return landedPlusWeek >= Date.vnNew() || hasClaimManagerRole;
+        const createAfterDeadline = acl.hasAny([
+            { model: 'Claim', props: 'createAfterDeadline', accessType: 'WRITE' },
+        ]);
+        return landedPlusWeek >= Date.vnNew() || createAfterDeadline;
     }
     return false;
 });
diff --git a/src/pages/Ticket/Card/TicketVolume.vue b/src/pages/Ticket/Card/TicketVolume.vue
index 7aeeec952..20eced98e 100644
--- a/src/pages/Ticket/Card/TicketVolume.vue
+++ b/src/pages/Ticket/Card/TicketVolume.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
+import { ref, computed, onMounted, watch, nextTick } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
@@ -90,8 +90,6 @@ const applyVolumes = async (salesData) => {
 };
 
 onMounted(() => (stateStore.rightDrawer = true));
-
-onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
diff --git a/src/pages/Ticket/TicketAdvanceFilter.vue b/src/pages/Ticket/TicketAdvanceFilter.vue
index a1d301f35..6528bf380 100644
--- a/src/pages/Ticket/TicketAdvanceFilter.vue
+++ b/src/pages/Ticket/TicketAdvanceFilter.vue
@@ -57,7 +57,6 @@ onMounted(async () => await getItemPackingTypes());
         search-url="advanceTickets"
         :data-key="props.dataKey"
         :search-button="true"
-        :hidden-tags="['search']"
         :unremovable-params="['warehouseFk', 'dateFuture', 'dateToAdvance']"
     >
         <template #tags="{ tag, formatFn }">
diff --git a/src/pages/Ticket/TicketFutureFilter.vue b/src/pages/Ticket/TicketFutureFilter.vue
index ffe967272..d28b0af71 100644
--- a/src/pages/Ticket/TicketFutureFilter.vue
+++ b/src/pages/Ticket/TicketFutureFilter.vue
@@ -59,7 +59,6 @@ onMounted(async () => {
     />
     <VnFilterPanel
         :data-key="props.dataKey"
-        :hidden-tags="['search']"
         :un-removable-params="['warehouseFk', 'originScopeDays ', 'futureScopeDays']"
     >
         <template #tags="{ tag, formatFn }">
diff --git a/src/pages/Ticket/TicketWeekly.vue b/src/pages/Ticket/TicketWeekly.vue
index 306f414df..0e18fe028 100644
--- a/src/pages/Ticket/TicketWeekly.vue
+++ b/src/pages/Ticket/TicketWeekly.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, computed, onUnmounted } from 'vue';
+import { onMounted, ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnSelectCache from 'src/components/common/VnSelectCache.vue';
@@ -170,8 +170,6 @@ onMounted(async () => {
     const filteredColumns = columns.value.filter((col) => col.name !== 'actions');
     allColumnNames.value = filteredColumns.map((col) => col.name);
 });
-
-onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
diff --git a/src/pages/Travel/ExtraCommunity.vue b/src/pages/Travel/ExtraCommunity.vue
index 9286f5e3e..675a44979 100644
--- a/src/pages/Travel/ExtraCommunity.vue
+++ b/src/pages/Travel/ExtraCommunity.vue
@@ -57,7 +57,7 @@ const travelKgPercentages = ref([]);
 const tableColumnComponents = {
     id: {
         component: QBtn,
-        attrs: { flat: true, color: 'primary' },
+        attrs: { flat: true, color: 'primary', dense: true },
     },
     cargoSupplierNickname: {
         component: QBtn,
@@ -178,6 +178,7 @@ const columns = computed(() => [
         align: 'left',
         showValue: false,
         sortable: true,
+        style: 'min-width: 170px;',
     },
     {
         label: t('globals.packages'),
@@ -237,7 +238,7 @@ const columns = computed(() => [
         format: (value) => toDate(value),
     },
     {
-        label: t('globals.wareHhuseIn'),
+        label: t('globals.warehouseIn'),
         field: 'warehouseInName',
         name: 'warehouseInName',
         align: 'left',
@@ -506,7 +507,7 @@ const getColor = (percentage) => {
                         :key="col.name"
                         :props="props"
                         @click="stopEventPropagation($event, col)"
-                        auto-width
+                        :style="col.style"
                     >
                         <component
                             :is="tableColumnComponents[col.name].component"
@@ -581,7 +582,7 @@ const getColor = (percentage) => {
                     }"
                 >
                     <QTd>
-                        <QBtn flat class="link">{{ entry.id }} </QBtn>
+                        <QBtn dense flat class="link">{{ entry.id }} </QBtn>
                         <EntryDescriptorProxy :id="entry.id" />
                     </QTd>
                     <QTd>
@@ -637,6 +638,18 @@ const getColor = (percentage) => {
 
 :deep(.q-table) {
     border-collapse: collapse;
+
+    th {
+        padding: 0;
+    }
+    tbody tr td {
+        &:nth-child(1) {
+            max-width: 65px;
+        }
+        &:nth-child(4) {
+            padding: 0;
+        }
+    }
 }
 
 .q-td :deep(input) {
@@ -684,7 +697,6 @@ const getColor = (percentage) => {
     width: max-content;
 }
 </style>
-
 <i18n>
 en:
     searchExtraCommunity: Search for extra community shipping
diff --git a/src/pages/Worker/Card/WorkerBalance.vue b/src/pages/Worker/Card/WorkerBalance.vue
index 25ab92c9b..95e0b986e 100644
--- a/src/pages/Worker/Card/WorkerBalance.vue
+++ b/src/pages/Worker/Card/WorkerBalance.vue
@@ -15,6 +15,9 @@ const columns = computed(() => [
         name: 'paymentDate',
         label: t('worker.balance.tableVisibleColumns.paymentDate'),
         create: true,
+        columnCreate: {
+            required: true,
+        },
         component: 'date',
         field: 'paymentDate',
         cardVisible: true,
@@ -24,6 +27,9 @@ const columns = computed(() => [
         name: 'incomeTypeFk',
         label: t('worker.balance.tableVisibleColumns.incomeType'),
         create: true,
+        columnCreate: {
+            required: true,
+        },
         component: 'select',
         attrs: {
             options: payrollComponents,
@@ -37,6 +43,9 @@ const columns = computed(() => [
         name: 'debit',
         label: t('worker.balance.tableVisibleColumns.debit'),
         create: true,
+        columnCreate: {
+            required: true,
+        },
         component: 'input',
         field: 'debit',
         cardVisible: true,
@@ -46,6 +55,9 @@ const columns = computed(() => [
         name: 'credit',
         label: t('worker.balance.tableVisibleColumns.credit'),
         create: true,
+        columnCreate: {
+            required: true,
+        },
         component: 'input',
         field: 'credit',
         cardVisible: true,
diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue
index 13f9e9795..73ea34fe9 100644
--- a/src/pages/Worker/Card/WorkerDescriptor.vue
+++ b/src/pages/Worker/Card/WorkerDescriptor.vue
@@ -206,6 +206,8 @@ const handlePhotoUpdated = (evt = false) => {
 
 <i18n>
 es:
+    Go to client: Ir a cliente
+    Go to user: Ir al usuario
     Click to allow the user to be disabled: Marcar para deshabilitar
     Click to exclude the user from getting disabled: Marcar para no deshabilitar
 </i18n>
diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue
index 94f4e0d95..3ceee2493 100644
--- a/src/pages/Worker/Card/WorkerPda.vue
+++ b/src/pages/Worker/Card/WorkerPda.vue
@@ -133,6 +133,7 @@ function reloadData() {
                                     option-value="id"
                                     id="deviceProductionFk"
                                     hide-selected
+                                    data-cy="pda-dialog-select"
                                 >
                                     <template #option="scope">
                                         <QItem v-bind="scope.itemProps">
diff --git a/src/pages/Worker/WorkerCreate.vue b/src/pages/Worker/WorkerCreate.vue
index 5676837dd..a4c6c2a06 100644
--- a/src/pages/Worker/WorkerCreate.vue
+++ b/src/pages/Worker/WorkerCreate.vue
@@ -14,6 +14,7 @@ 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';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const user = useState().getUser();
@@ -149,27 +150,11 @@ async function autofillBic(worker) {
                         hide-selected
                         :rules="validate('Worker.company')"
                     />
-                    <VnSelect
+                    <VnSelectWorker
                         :label="t('worker.summary.boss')"
                         v-model="data.bossFk"
-                        url="Workers/search"
-                        option-value="id"
-                        option-label="name"
-                        hide-selected
                         :rules="validate('Worker.boss')"
-                    >
-                        <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>
+                    />
                 </VnRow>
                 <VnRow>
                     <VnInput
diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue
index 81b231710..bd1c27938 100644
--- a/src/pages/Worker/WorkerList.vue
+++ b/src/pages/Worker/WorkerList.vue
@@ -18,6 +18,7 @@ import RightMenu from 'src/components/common/RightMenu.vue';
 import WorkerFilter from './WorkerFilter.vue';
 import { useState } from 'src/composables/useState';
 import axios from 'axios';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const tableRef = ref();
@@ -260,26 +261,10 @@ async function autofillBic(worker) {
                         option-label="code"
                         hide-selected
                     />
-                    <VnSelect
+                    <VnSelectWorker
                         :label="t('worker.summary.boss')"
                         v-model="data.bossFk"
-                        url="Workers/search"
-                        option-value="id"
-                        option-label="name"
-                        hide-selected
-                    >
-                        <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>
+                    />
                 </VnRow>
                 <VnRow>
                     <VnInput v-model="data.fi" :label="t('worker.create.fi')" />
@@ -376,6 +361,7 @@ async function autofillBic(worker) {
 
 <i18n>
 es:
+    Create worker: Crear trabajador
     Search worker: Buscar trabajador
     You can search by worker id or name: Puedes buscar por id o nombre del trabajador
 </i18n>
diff --git a/src/pages/Zone/Card/ZoneBasicData.vue b/src/pages/Zone/Card/ZoneBasicData.vue
index 535f2393d..731e03ba7 100644
--- a/src/pages/Zone/Card/ZoneBasicData.vue
+++ b/src/pages/Zone/Card/ZoneBasicData.vue
@@ -32,7 +32,12 @@ const agencyOptions = ref([]);
     <FormModel :url="`Zones/${route.params.id}`" auto-load model="zone">
         <template #form="{ data, validate }">
             <VnRow>
-                <VnInput :label="t('Name')" clearable v-model="data.name" />
+                <VnInput
+                    data-cy="zone-basic-data-name"
+                    :label="t('Name')"
+                    clearable
+                    v-model="data.name"
+                />
             </VnRow>
 
             <VnRow>
diff --git a/src/pages/Zone/Card/ZoneEvents.vue b/src/pages/Zone/Card/ZoneEvents.vue
index 6d5b37096..0685c264f 100644
--- a/src/pages/Zone/Card/ZoneEvents.vue
+++ b/src/pages/Zone/Card/ZoneEvents.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, onUnmounted } from 'vue';
+import { ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 
 import ZoneEventsPanel from './ZoneEventsPanel.vue';
@@ -40,8 +40,6 @@ const onZoneEventFormClose = () => {
     showZoneEventForm.value = false;
     zoneEventsFormProps.value = {};
 };
-
-onUnmounted(() => (stateStore.rightDrawer = false));
 </script>
 
 <template>
diff --git a/src/pages/Zone/ZoneFilterPanel.vue b/src/pages/Zone/ZoneFilterPanel.vue
index 55d21756d..3a35527ab 100644
--- a/src/pages/Zone/ZoneFilterPanel.vue
+++ b/src/pages/Zone/ZoneFilterPanel.vue
@@ -28,11 +28,7 @@ const agencies = ref([]);
         @on-fetch="(data) => (agencies = data)"
         auto-load
     />
-    <VnFilterPanel
-        :data-key="props.dataKey"
-        :search-button="true"
-        :hidden-tags="['search']"
-    >
+    <VnFilterPanel :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag }">
             <div class="q-gutter-x-xs">
                 <strong>{{ t(`filterPanel.${tag.label}`) }}: </strong>
diff --git a/src/router/modules/travel.js b/src/router/modules/travel.js
index 627692be8..dff693d2f 100644
--- a/src/router/modules/travel.js
+++ b/src/router/modules/travel.js
@@ -75,9 +75,9 @@ export default {
                 },
                 {
                     name: 'TravelHistory',
-                    path: 'history',
+                    path: 'log',
                     meta: {
-                        title: 'history',
+                        title: 'log',
                         icon: 'history',
                     },
                     component: () => import('src/pages/Travel/Card/TravelLog.vue'),
diff --git a/src/router/modules/zone.js b/src/router/modules/zone.js
index 1f27cc76f..c5ebe762e 100644
--- a/src/router/modules/zone.js
+++ b/src/router/modules/zone.js
@@ -106,7 +106,7 @@ export default {
                 },
                 {
                     name: 'ZoneHistory',
-                    path: 'history',
+                    path: 'log',
                     meta: {
                         title: 'log',
                         icon: 'history',
diff --git a/test/cypress/integration/client/clientBasicData.spec.js b/test/cypress/integration/client/clientBasicData.spec.js
index efaad33c2..bed28dc22 100644
--- a/test/cypress/integration/client/clientBasicData.spec.js
+++ b/test/cypress/integration/client/clientBasicData.spec.js
@@ -7,8 +7,8 @@ describe('Client basic data', () => {
     });
     it('Should load layout', () => {
         cy.get('.q-card').should('be.visible');
-        cy.dataCy('customerPhone').filter('input').should('be.visible');
-        cy.dataCy('customerPhone').filter('input').type('123456789');
+        cy.dataCy('customerPhone').find('input').should('be.visible');
+        cy.dataCy('customerPhone').find('input').type('123456789');
         cy.get('.q-btn-group > .q-btn--standard').click();
         cy.intercept('PATCH', '/api/Clients/1102', (req) => {
             const { body } = req;
diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/client/clientList.spec.js
index e89b5fc77..ce07deb16 100644
--- a/test/cypress/integration/client/clientList.spec.js
+++ b/test/cypress/integration/client/clientList.spec.js
@@ -22,10 +22,10 @@ describe('Client list', () => {
         const data = {
             Name: { val: `Name ${randomInt}` },
             'Social name': { val: `TEST ${randomInt}` },
-            'Tax number': { val: `20852${randomInt.length}3Z` },
+            'Tax number': { val: `20852${randomInt}3Z` },
             'Web user': { val: `user_test_${randomInt}` },
             Street: { val: `C/ STREET ${randomInt}` },
-            Email: { val: 'user.test@1.com' },
+            Email: { val: `user.test${randomInt}@cypress.com` },
             'Sales person': { val: 'employee', type: 'select' },
             Location: { val: '46000, Valencia(Province one), España', type: 'select' },
             'Business type': { val: 'Otros', type: 'select' },
@@ -34,7 +34,7 @@ describe('Client list', () => {
 
         cy.get('.q-mt-lg > .q-btn--standard').click();
 
-        cy.checkNotification('Data saved');
+        cy.checkNotification('Data created');
         cy.url().should('include', '/summary');
     });
     it('Client list search client', () => {
diff --git a/test/cypress/integration/item/ItemFixedPrice.spec.js b/test/cypress/integration/item/ItemFixedPrice.spec.js
new file mode 100644
index 000000000..824ecf7a0
--- /dev/null
+++ b/test/cypress/integration/item/ItemFixedPrice.spec.js
@@ -0,0 +1,63 @@
+/// <reference types="cypress" />
+function goTo(n = 1) {
+    return `.q-virtual-scroll__content > :nth-child(${n})`;
+}
+const firstRow = goTo();
+`.q-virtual-scroll__content > :nth-child(2)`;
+describe('Handle Items FixedPrice', () => {
+    beforeEach(() => {
+        cy.viewport(1280, 720);
+        cy.login('developer');
+        cy.visit('/#/item/fixed-price', { timeout: 5000 });
+        cy.waitForElement('.q-table');
+        cy.get(
+            '.q-header > .q-toolbar > :nth-child(1) > .q-btn__content > .q-icon'
+        ).click();
+    });
+    it('filter', function () {
+        cy.get('.category-filter > :nth-child(1) > .q-btn__content > .q-icon').click();
+        cy.selectOption('.list > :nth-child(2)', 'Alstroemeria');
+        cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
+
+        cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+        cy.selectOption(`${firstRow} > :nth-child(2)`, '#13');
+        cy.get(`${firstRow} > :nth-child(4)`).find('input').type(1);
+        cy.get(`${firstRow} > :nth-child(5)`).find('input').type('2');
+        cy.selectOption(`${firstRow} > :nth-child(9)`, 'Warehouse One');
+        cy.get('.q-notification__message').should('have.text', 'Data saved');
+        /* ==== End Cypress Studio ==== */
+    });
+    it('Create and delete ', function () {
+        cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
+        cy.selectOption(`${firstRow} > :nth-child(2)`, '#11');
+        cy.get(`${firstRow} > :nth-child(4)`).type('1');
+        cy.get(`${firstRow} > :nth-child(5)`).type('2');
+        cy.selectOption(`${firstRow} > :nth-child(9)`, 'Warehouse One');
+        cy.get('.q-notification__message').should('have.text', 'Data saved');
+        cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
+        cy.get(`${firstRow} > .text-right > .q-btn > .q-btn__content > .q-icon`).click();
+        cy.get(
+            '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block'
+        ).click();
+        cy.get('.q-notification__message').should('have.text', 'Data saved');
+    });
+
+    it('Massive edit', function () {
+        cy.get(' .bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner ').click();
+        cy.get('#subToolbar > .q-btn--standard').click();
+        cy.selectOption("[data-cy='field-to-edit']", 'Min price');
+        cy.dataCy('value-to-edit').find('input').type('1');
+        cy.get('.countLines').should('have.text', ' 1 ');
+        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.get('.q-notification__message').should('have.text', 'Data saved');
+    });
+    it('Massive remove', function () {
+        cy.get(' .bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner ').click();
+        cy.get('#subToolbar > .q-btn--flat').click();
+        cy.get(
+            '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block'
+        ).click();
+        cy.get('.q-notification__message').should('have.text', 'Data saved');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js
index bbdbcea92..c1d1a0655 100644
--- a/test/cypress/integration/ticket/ticketList.spec.js
+++ b/test/cypress/integration/ticket/ticketList.spec.js
@@ -37,7 +37,7 @@ describe('TicketList', () => {
         cy.dataCy('ticketSummary').should('exist');
     });
 
-    it('Client list create new client', () => {
+    it.only('Client list create new client', () => {
         cy.dataCy('vnTableCreateBtn').should('exist');
         cy.dataCy('vnTableCreateBtn').click();
         const data = {
@@ -47,7 +47,8 @@ describe('TicketList', () => {
             Landed: { val: '01-01-2024', type: 'date' },
         };
         cy.fillInForm(data);
-        cy.get('.q-mt-lg > .q-btn--standard').click();
+        cy.dataCy('Agency_select').click();
+        cy.dataCy('FormModelPopup_save').click();
         cy.checkNotification('Data created');
         cy.url().should('match', /\/ticket\/\d+\/summary/);
     });
diff --git a/test/cypress/integration/worker/workerPda.spec.js b/test/cypress/integration/worker/workerPda.spec.js
index fe8efa834..dc1ca6224 100644
--- a/test/cypress/integration/worker/workerPda.spec.js
+++ b/test/cypress/integration/worker/workerPda.spec.js
@@ -1,6 +1,5 @@
 describe('WorkerPda', () => {
-    const deviceProductionField =
-        '.vn-row > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
+    const select = '[data-cy="pda-dialog-select"]';
     beforeEach(() => {
         cy.viewport(1920, 1080);
         cy.login('developer');
@@ -9,7 +8,8 @@ describe('WorkerPda', () => {
 
     it('assign pda', () => {
         cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click();
-        cy.get(deviceProductionField).type('{downArrow}{enter}');
+        cy.get(select).click();
+        cy.get(select).type('{downArrow}{enter}');
         cy.get('.q-notification__message').should('have.text', 'Data created');
     });
 
diff --git a/test/cypress/integration/zone/zoneBasicData.spec.js b/test/cypress/integration/zone/zoneBasicData.spec.js
index c6151a49b..6229039b7 100644
--- a/test/cypress/integration/zone/zoneBasicData.spec.js
+++ b/test/cypress/integration/zone/zoneBasicData.spec.js
@@ -1,5 +1,6 @@
 describe('ZoneBasicData', () => {
     const notification = '.q-notification__message';
+    const priceBasicData = '[data-cy="Price_input"]';
 
     beforeEach(() => {
         cy.viewport(1280, 720);
@@ -8,14 +9,20 @@ describe('ZoneBasicData', () => {
     });
 
     it('should throw an error if the name is empty', () => {
-        cy.get('.q-card > :nth-child(1)').clear();
+        cy.get('[data-cy="zone-basic-data-name"] input').type('{selectall}{backspace}');
         cy.get('.q-btn-group > .q-btn--standard').click();
         cy.get(notification).should('contains.text', "can't be blank");
     });
 
+    it('should throw an error if the price is empty', () => {
+        cy.get(priceBasicData).clear();
+        cy.get('.q-btn-group > .q-btn--standard').click();
+        cy.get(notification).should('contains.text', 'cannot 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');
+        cy.checkNotification('Data saved');
     });
 });
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 21121d9df..2b13a7144 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -110,14 +110,14 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
                 const { type, val } = field;
                 switch (type) {
                     case 'select':
-                        cy.wrap(el).type(val);
+                        cy.get(el).click();
                         cy.get('.q-menu .q-item').contains(val).click();
                         break;
                     case 'date':
-                        cy.wrap(el).type(val.split('-').join(''));
+                        cy.get(el).type(val.split('-').join(''));
                         break;
                     case 'time':
-                        cy.wrap(el).click();
+                        cy.get(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();
diff --git a/test/vitest/helper.js b/test/vitest/helper.js
index 4bfae5dc8..ce057c7c3 100644
--- a/test/vitest/helper.js
+++ b/test/vitest/helper.js
@@ -44,7 +44,18 @@ vi.mock('vue-router', () => ({
 vi.mock('axios');
 
 vi.spyOn(useValidator, 'useValidator').mockImplementation(() => {
-    return { validate: vi.fn() };
+    return {
+        validate: vi.fn(),
+        validations: () => ({
+            format: vi.fn(),
+            presence: vi.fn(),
+            required: vi.fn(),
+            length: vi.fn(),
+            numericality: vi.fn(),
+            min: vi.fn(),
+            custom: vi.fn(),
+        }),
+    };
 });
 
 class FormDataMock {