diff --git a/cypress.config.js b/cypress.config.js
index 1924144f6..a9e27fcfd 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -14,8 +14,8 @@ export default defineConfig({
         downloadsFolder: 'test/cypress/downloads',
         video: false,
         specPattern: 'test/cypress/integration/**/*.spec.js',
-        experimentalRunAllSpecs: true,
-        watchForFileChanges: true,
+        experimentalRunAllSpecs: false,
+        watchForFileChanges: false,
         reporter: 'cypress-mochawesome-reporter',
         reporterOptions: {
             charts: true,
diff --git a/quasar.config.js b/quasar.config.js
index 6d545c026..9467c92af 100644
--- a/quasar.config.js
+++ b/quasar.config.js
@@ -30,7 +30,6 @@ export default configure(function (/* ctx */) {
         // --> boot files are part of "main.js"
         // https://v2.quasar.dev/quasar-cli/boot-files
         boot: ['i18n', 'axios', 'vnDate', 'validations', 'quasar', 'quasar.defaults'],
-
         // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
         css: ['app.scss'],
 
diff --git a/src/boot/qformMixin.js b/src/boot/qformMixin.js
index 97d80c670..cb31391b3 100644
--- a/src/boot/qformMixin.js
+++ b/src/boot/qformMixin.js
@@ -9,19 +9,19 @@ export default {
         if (!form) return;
         try {
             const inputsFormCard = form.querySelectorAll(
-                `input:not([disabled]):not([type="checkbox"])`
+                `input:not([disabled]):not([type="checkbox"])`,
             );
             if (inputsFormCard.length) {
                 focusFirstInput(inputsFormCard[0]);
             }
             const textareas = document.querySelectorAll(
-                'textarea:not([disabled]), [contenteditable]:not([disabled])'
+                'textarea:not([disabled]), [contenteditable]:not([disabled])',
             );
             if (textareas.length) {
                 focusFirstInput(textareas[textareas.length - 1]);
             }
             const inputs = document.querySelectorAll(
-                'form#formModel input:not([disabled]):not([type="checkbox"])'
+                'form#formModel input:not([disabled]):not([type="checkbox"])',
             );
             const input = inputs[0];
             if (!input) return;
diff --git a/src/boot/quasar.js b/src/boot/quasar.js
index 547517682..a8c397b83 100644
--- a/src/boot/quasar.js
+++ b/src/boot/quasar.js
@@ -51,4 +51,5 @@ export default boot(({ app }) => {
 
         await useCau(response, message);
     };
+    app.provide('app', app);
 });
diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index d569dfda1..93a2ac96a 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -64,6 +64,10 @@ const $props = defineProps({
         type: Function,
         default: null,
     },
+    beforeSaveFn: {
+        type: Function,
+        default: null,
+    },
     goTo: {
         type: String,
         default: '',
@@ -176,7 +180,11 @@ async function saveChanges(data) {
         hasChanges.value = false;
         return;
     }
-    const changes = data || getChanges();
+    let changes = data || getChanges();
+    if ($props.beforeSaveFn) {
+        changes = await $props.beforeSaveFn(changes, getChanges);
+    }
+
     try {
         await axios.post($props.saveUrl || $props.url + '/crud', changes);
     } finally {
@@ -229,12 +237,12 @@ async function remove(data) {
                 componentProps: {
                     title: t('globals.confirmDeletion'),
                     message: t('globals.confirmDeletionMessage'),
-                    newData,
+                    data: { deletes: ids },
                     ids,
+                    promise: saveChanges,
                 },
             })
             .onOk(async () => {
-                await saveChanges({ deletes: ids });
                 newData = newData.filter((form) => !ids.some((id) => id == form[pk]));
                 fetch(newData);
             });
@@ -374,6 +382,8 @@ watch(formUrl, async () => {
                 @click="onSubmit"
                 :disable="!hasChanges"
                 :title="t('globals.save')"
+                v-shortcut="'s'"
+                shortcut="s"
                 data-cy="crudModelDefaultSaveBtn"
             />
             <slot name="moreAfterActions" />
diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue
index 9fc91457a..ab50d0899 100644
--- a/src/components/FilterTravelForm.vue
+++ b/src/components/FilterTravelForm.vue
@@ -181,6 +181,7 @@ const selectTravel = ({ id }) => {
                     color="primary"
                     :disabled="isLoading"
                     :loading="isLoading"
+                    data-cy="save-filter-travel-form"
                 />
             </div>
             <QTable
@@ -191,9 +192,10 @@ const selectTravel = ({ id }) => {
                 :no-data-label="t('Enter a new search')"
                 class="q-mt-lg"
                 @row-click="(_, row) => selectTravel(row)"
+                data-cy="table-filter-travel-form"
             >
                 <template #body-cell-id="{ row }">
-                    <QTd auto-width @click.stop>
+                    <QTd auto-width @click.stop data-cy="travelFk-travel-form">
                         <QBtn flat color="blue">{{ row.id }}</QBtn>
                         <TravelDescriptorProxy :id="row.id" />
                     </QTd>
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index 59141d374..5a59f301e 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -113,7 +113,7 @@ const defaultButtons = computed(() => ({
         color: 'primary',
         icon: 'save',
         label: 'globals.save',
-        click: () => myForm.value.submit(),
+        click: () => myForm.value.onSubmit(false),
         type: 'submit',
     },
     reset: {
@@ -207,7 +207,8 @@ async function fetch() {
     }
 }
 
-async function save() {
+async function save(prevent = false) {
+    if (prevent) return;
     if ($props.observeFormChanges && !hasChanges.value)
         return notify('globals.noChanges', 'negative');
 
@@ -293,7 +294,7 @@ defineExpose({
         <QForm
             ref="myForm"
             v-if="formData"
-            @submit="save"
+            @submit="save(!!$event)"
             @reset="reset"
             class="q-pa-md"
             :style="maxWidth ? 'max-width: ' + maxWidth : ''"
diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue
index afdc6efca..98b611743 100644
--- a/src/components/FormModelPopup.vue
+++ b/src/components/FormModelPopup.vue
@@ -15,23 +15,30 @@ defineProps({
         type: String,
         default: '',
     },
+    showSaveAndContinueBtn: {
+        type: Boolean,
+        default: false,
+    },
 });
 
 const { t } = useI18n();
 
 const formModelRef = ref(null);
 const closeButton = ref(null);
-
+const isSaveAndContinue = ref(false);
 const onDataSaved = (formData, requestResponse) => {
-    if (closeButton.value) closeButton.value.click();
+    if (closeButton.value && isSaveAndContinue) closeButton.value.click();
     emit('onDataSaved', formData, requestResponse);
 };
 
 const isLoading = computed(() => formModelRef.value?.isLoading);
+const reset = computed(() => formModelRef.value?.reset);
 
 defineExpose({
     isLoading,
     onDataSaved,
+    isSaveAndContinue,
+    reset,
 });
 </script>
 
@@ -59,15 +66,22 @@ defineExpose({
                     flat
                     :disabled="isLoading"
                     :loading="isLoading"
-                    @click="emit('onDataCanceled')"
-                    v-close-popup
                     data-cy="FormModelPopup_cancel"
+                    v-close-popup
                     z-max
+                    @click="
+                        isSaveAndContinue = false;
+                        emit('onDataCanceled');
+                    "
                 />
                 <QBtn
+                    :flat="showSaveAndContinueBtn"
                     :label="t('globals.save')"
                     :title="t('globals.save')"
-                    type="submit"
+                    @click="
+                        formModelRef.save();
+                        isSaveAndContinue = false;
+                    "
                     color="primary"
                     class="q-ml-sm"
                     :disabled="isLoading"
@@ -75,6 +89,21 @@ defineExpose({
                     data-cy="FormModelPopup_save"
                     z-max
                 />
+                <QBtn
+                    v-if="showSaveAndContinueBtn"
+                    :label="t('globals.isSaveAndContinue')"
+                    :title="t('globals.isSaveAndContinue')"
+                    color="primary"
+                    class="q-ml-sm"
+                    :disabled="isLoading"
+                    :loading="isLoading"
+                    data-cy="FormModelPopup_isSaveAndContinue"
+                    z-max
+                    @click="
+                        isSaveAndContinue = true;
+                        formModelRef.save();
+                    "
+                />
             </div>
         </template>
     </FormModel>
diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue
index 48f607a30..b6209d8e2 100644
--- a/src/components/ItemsFilterPanel.vue
+++ b/src/components/ItemsFilterPanel.vue
@@ -328,7 +328,6 @@ en:
         active: Is active
         visible: Is visible
         floramondo: Is floramondo
-        salesPersonFk: Buyer
         categoryFk: Category
 
 es:
@@ -339,7 +338,6 @@ es:
         active: Activo
         visible: Visible
         floramondo: Floramondo
-        salesPersonFk: Comprador
         categoryFk: Categoría
     Plant: Planta natural
     Flower: Flor fresca
diff --git a/src/components/LeftMenuItem.vue b/src/components/LeftMenuItem.vue
index a3112b17f..c0cee44fe 100644
--- a/src/components/LeftMenuItem.vue
+++ b/src/components/LeftMenuItem.vue
@@ -26,6 +26,7 @@ const itemComputed = computed(() => {
         :to="{ name: itemComputed.name }"
         clickable
         v-ripple
+        :data-cy="`${itemComputed.name}-menu-item`"
     >
         <QItemSection avatar v-if="itemComputed.icon">
             <QIcon :name="itemComputed.icon" />
diff --git a/src/components/RefundInvoiceForm.vue b/src/components/RefundInvoiceForm.vue
index 590acede0..6dcb8b390 100644
--- a/src/components/RefundInvoiceForm.vue
+++ b/src/components/RefundInvoiceForm.vue
@@ -9,6 +9,7 @@ import VnSelect from 'components/common/VnSelect.vue';
 import FormPopup from './FormPopup.vue';
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const $props = defineProps({
     invoiceOutData: {
@@ -131,15 +132,11 @@ const refund = async () => {
                         :required="true"
                     /> </VnRow
                 ><VnRow>
-                    <div>
-                        <QCheckbox
-                            :label="t('Inherit warehouse')"
-                            v-model="invoiceParams.inheritWarehouse"
-                        />
-                        <QIcon name="info" class="cursor-info q-ml-sm" size="sm">
-                            <QTooltip>{{ t('Inherit warehouse tooltip') }}</QTooltip>
-                        </QIcon>
-                    </div>
+                    <VnCheckbox
+                        v-model="invoiceParams.inheritWarehouse"
+                        :label="t('Inherit warehouse')"
+                        :info="t('Inherit warehouse tooltip')"
+                    />
                 </VnRow>
             </template>
         </FormPopup>
diff --git a/src/components/TransferInvoiceForm.vue b/src/components/TransferInvoiceForm.vue
index aa71070d6..c4ef1454a 100644
--- a/src/components/TransferInvoiceForm.vue
+++ b/src/components/TransferInvoiceForm.vue
@@ -10,6 +10,7 @@ import VnSelect from 'components/common/VnSelect.vue';
 import FormPopup from './FormPopup.vue';
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
+import VnCheckbox from './common/VnCheckbox.vue';
 
 const $props = defineProps({
     invoiceOutData: {
@@ -186,15 +187,11 @@ const makeInvoice = async () => {
                     />
                 </VnRow>
                 <VnRow>
-                    <div>
-                        <QCheckbox
-                            :label="t('Bill destination client')"
-                            v-model="checked"
-                        />
-                        <QIcon name="info" class="cursor-info q-ml-sm" size="sm">
-                            <QTooltip>{{ t('transferInvoiceInfo') }}</QTooltip>
-                        </QIcon>
-                    </div>
+                    <VnCheckbox
+                        v-model="checked"
+                        :label="t('Bill destination client')"
+                        :info="t('transferInvoiceInfo')"
+                    />
                 </VnRow>
             </template>
         </FormPopup>
diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue
index 9e9bfad69..44364cca1 100644
--- a/src/components/VnTable/VnColumn.vue
+++ b/src/components/VnTable/VnColumn.vue
@@ -1,9 +1,8 @@
 <script setup>
 import { markRaw, computed } from 'vue';
-import { QIcon, QCheckbox } from 'quasar';
+import { QIcon, QCheckbox, QToggle } from 'quasar';
 import { dashIfEmpty } from 'src/filters';
 
-/* basic input */
 import VnSelect from 'components/common/VnSelect.vue';
 import VnSelectCache from 'components/common/VnSelectCache.vue';
 import VnInput from 'components/common/VnInput.vue';
@@ -12,8 +11,11 @@ import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInputTime from 'components/common/VnInputTime.vue';
 import VnComponent from 'components/common/VnComponent.vue';
 import VnUserLink from 'components/ui/VnUserLink.vue';
+import VnSelectEnum from '../common/VnSelectEnum.vue';
+import VnCheckbox from '../common/VnCheckbox.vue';
 
 const model = defineModel(undefined, { required: true });
+const emit = defineEmits(['blur']);
 const $props = defineProps({
     column: {
         type: Object,
@@ -39,10 +41,18 @@ const $props = defineProps({
         type: Object,
         default: null,
     },
+    autofocus: {
+        type: Boolean,
+        default: false,
+    },
     showLabel: {
         type: Boolean,
         default: null,
     },
+    eventHandlers: {
+        type: Object,
+        default: null,
+    },
 });
 
 const defaultSelect = {
@@ -99,7 +109,8 @@ const defaultComponents = {
         },
     },
     checkbox: {
-        component: markRaw(QCheckbox),
+        ref: 'checkbox',
+        component: markRaw(VnCheckbox),
         attrs: ({ model }) => {
             const defaultAttrs = {
                 disable: !$props.isEditable,
@@ -115,6 +126,10 @@ const defaultComponents = {
         },
         forceAttrs: {
             label: $props.showLabel && $props.column.label,
+            autofocus: true,
+        },
+        events: {
+            blur: () => emit('blur'),
         },
     },
     select: {
@@ -125,12 +140,19 @@ const defaultComponents = {
         component: markRaw(VnSelect),
         ...defaultSelect,
     },
+    selectEnum: {
+        component: markRaw(VnSelectEnum),
+        ...defaultSelect,
+    },
     icon: {
         component: markRaw(QIcon),
     },
     userLink: {
         component: markRaw(VnUserLink),
     },
+    toggle: {
+        component: markRaw(QToggle),
+    },
 };
 
 const value = computed(() => {
@@ -160,7 +182,28 @@ const col = computed(() => {
     return newColumn;
 });
 
-const components = computed(() => $props.components ?? defaultComponents);
+const components = computed(() => {
+    const sourceComponents = $props.components ?? defaultComponents;
+
+    return Object.keys(sourceComponents).reduce((acc, key) => {
+        const component = sourceComponents[key];
+
+        if (!component || typeof component !== 'object') {
+            acc[key] = component;
+            return acc;
+        }
+
+        acc[key] = {
+            ...component,
+            attrs: {
+                ...(component.attrs || {}),
+                autofocus: $props.autofocus,
+            },
+            event: { ...component?.event, ...$props?.eventHandlers },
+        };
+        return acc;
+    }, {});
+});
 </script>
 <template>
     <div class="row no-wrap">
diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue
index 426f5c716..2dad8fe52 100644
--- a/src/components/VnTable/VnFilter.vue
+++ b/src/components/VnTable/VnFilter.vue
@@ -1,14 +1,12 @@
 <script setup>
 import { markRaw, computed } from 'vue';
-import { QCheckbox } from 'quasar';
+import { QCheckbox, QToggle } from 'quasar';
 import { useArrayData } from 'composables/useArrayData';
-
-/* basic input */
 import VnSelect from 'components/common/VnSelect.vue';
 import VnInput from 'components/common/VnInput.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import VnInputTime from 'components/common/VnInputTime.vue';
-import VnTableColumn from 'components/VnTable/VnColumn.vue';
+import VnColumn from 'components/VnTable/VnColumn.vue';
 
 const $props = defineProps({
     column: {
@@ -27,6 +25,10 @@ const $props = defineProps({
         type: String,
         default: 'table',
     },
+    customClass: {
+        type: String,
+        default: '',
+    },
 });
 
 defineExpose({ addFilter, props: $props });
@@ -34,7 +36,7 @@ defineExpose({ addFilter, props: $props });
 const model = defineModel(undefined, { required: true });
 const arrayData = useArrayData(
     $props.dataKey,
-    $props.searchUrl ? { searchUrl: $props.searchUrl } : null
+    $props.searchUrl ? { searchUrl: $props.searchUrl } : null,
 );
 const columnFilter = computed(() => $props.column?.columnFilter);
 
@@ -46,19 +48,18 @@ const enterEvent = {
 
 const defaultAttrs = {
     filled: !$props.showTitle,
-    class: 'q-px-xs q-pb-xs q-pt-none fit',
     dense: true,
 };
 
 const forceAttrs = {
-    label: $props.showTitle ? '' : columnFilter.value?.label ?? $props.column.label,
+    label: $props.showTitle ? '' : (columnFilter.value?.label ?? $props.column.label),
 };
 
 const selectComponent = {
     component: markRaw(VnSelect),
     event: updateEvent,
     attrs: {
-        class: 'q-px-sm q-pb-xs q-pt-none fit',
+        class: `q-pt-none fit ${$props.customClass}`,
         dense: true,
         filled: !$props.showTitle,
     },
@@ -109,14 +110,24 @@ const components = {
         component: markRaw(QCheckbox),
         event: updateEvent,
         attrs: {
-            dense: true,
-            class: $props.showTitle ? 'q-py-sm q-mt-md' : 'q-px-md q-py-xs fit',
+            class: $props.showTitle ? 'q-py-sm' : 'q-px-md q-py-xs fit',
             'toggle-indeterminate': true,
+            size: 'sm',
         },
         forceAttrs,
     },
     select: selectComponent,
     rawSelect: selectComponent,
+    toggle: {
+        component: markRaw(QToggle),
+        event: updateEvent,
+        attrs: {
+            class: $props.showTitle ? 'q-py-sm' : 'q-px-md q-py-xs fit',
+            'toggle-indeterminate': true,
+            size: 'sm',
+        },
+        forceAttrs,
+    },
 };
 
 async function addFilter(value, name) {
@@ -132,19 +143,8 @@ async function addFilter(value, name) {
     await arrayData.addFilter({ params: { [field]: value } });
 }
 
-function alignRow() {
-    switch ($props.column.align) {
-        case 'left':
-            return 'justify-start items-start';
-        case 'right':
-            return 'justify-end items-end';
-        default:
-            return 'flex-center';
-    }
-}
-
 const showFilter = computed(
-    () => $props.column?.columnFilter !== false && $props.column.name != 'tableActions'
+    () => $props.column?.columnFilter !== false && $props.column.name != 'tableActions',
 );
 
 const onTabPressed = async () => {
@@ -152,13 +152,8 @@ const onTabPressed = async () => {
 };
 </script>
 <template>
-    <div
-        v-if="showFilter"
-        class="full-width"
-        :class="alignRow()"
-        style="max-height: 45px; overflow: hidden"
-    >
-        <VnTableColumn
+    <div v-if="showFilter" class="full-width flex-center" style="overflow: hidden">
+        <VnColumn
             :column="$props.column"
             default="input"
             v-model="model"
@@ -168,3 +163,8 @@ const onTabPressed = async () => {
         />
     </div>
 </template>
+<style lang="scss" scoped>
+label.vn-label-padding > .q-field__inner > .q-field__control {
+    padding: inherit !important;
+}
+</style>
diff --git a/src/components/VnTable/VnOrder.vue b/src/components/VnTable/VnOrder.vue
index 8ffdfe2bc..e3795cc4b 100644
--- a/src/components/VnTable/VnOrder.vue
+++ b/src/components/VnTable/VnOrder.vue
@@ -41,6 +41,7 @@ async function orderBy(name, direction) {
             break;
     }
     if (!direction) return await arrayData.deleteOrder(name);
+
     await arrayData.addOrder(name, direction);
 }
 
@@ -51,45 +52,60 @@ defineExpose({ orderBy });
         @mouseenter="hover = true"
         @mouseleave="hover = false"
         @click="orderBy(name, model?.direction)"
-        class="row items-center no-wrap cursor-pointer"
+        class="row items-center no-wrap cursor-pointer title"
     >
         <span :title="label">{{ label }}</span>
-        <QChip
-            v-if="name"
-            :label="!vertical ? model?.index : ''"
-            :icon="
-                (model?.index || hover) && !vertical
-                    ? model?.direction == 'DESC'
-                        ? 'arrow_downward'
-                        : 'arrow_upward'
-                    : undefined
-            "
-            :size="vertical ? '' : 'sm'"
-            :class="[
-                model?.index ? 'color-vn-text' : 'bg-transparent',
-                vertical ? 'q-px-none' : '',
-            ]"
-            class="no-box-shadow"
-            :clickable="true"
-            style="min-width: 40px"
-        >
-            <div
-                class="column flex-center"
-                v-if="vertical"
-                :style="!model?.index && 'color: #5d5d5d'"
+        <sup v-if="name && model?.index">
+            <QChip
+                :label="!vertical ? model?.index : ''"
+                :icon="
+                    (model?.index || hover) && !vertical
+                        ? model?.direction == 'DESC'
+                            ? 'arrow_downward'
+                            : 'arrow_upward'
+                        : undefined
+                "
+                :size="vertical ? '' : 'sm'"
+                :class="[
+                    model?.index ? 'color-vn-text' : 'bg-transparent',
+                    vertical ? 'q-px-none' : '',
+                ]"
+                class="no-box-shadow"
+                :clickable="true"
+                style="min-width: 40px; max-height: 30px"
             >
-                {{ model?.index }}
-                <QIcon
-                    :name="
-                        model?.index
-                            ? model?.direction == 'DESC'
-                                ? 'arrow_downward'
-                                : 'arrow_upward'
-                            : 'swap_vert'
-                    "
-                    size="xs"
-                />
-            </div>
-        </QChip>
+                <div
+                    class="column flex-center"
+                    v-if="vertical"
+                    :style="!model?.index && 'color: #5d5d5d'"
+                >
+                    {{ model?.index }}
+                    <QIcon
+                        :name="
+                            model?.index
+                                ? model?.direction == 'DESC'
+                                    ? 'arrow_downward'
+                                    : 'arrow_upward'
+                                : 'swap_vert'
+                        "
+                        size="xs"
+                    />
+                </div>
+            </QChip>
+        </sup>
     </div>
 </template>
+<style lang="scss" scoped>
+.title {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 30px;
+    width: 100%;
+    color: var(--vn-label-color);
+}
+sup {
+    vertical-align: super; /* Valor predeterminado */
+    /* También puedes usar otros valores como "baseline", "top", "text-top", etc. */
+}
+</style>
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index 04b7c0a46..3e1923b4c 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -1,22 +1,37 @@
 <script setup>
-import { ref, onBeforeMount, onMounted, computed, watch, useAttrs } from 'vue';
+import {
+    ref,
+    onBeforeMount,
+    onMounted,
+    onUnmounted,
+    computed,
+    watch,
+    h,
+    render,
+    inject,
+    useAttrs,
+} from 'vue';
+import { useArrayData } from 'src/composables/useArrayData';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
 import { useQuasar } from 'quasar';
 import { useStateStore } from 'stores/useStateStore';
 import { useFilterParams } from 'src/composables/useFilterParams';
+import { dashIfEmpty } from 'src/filters';
 
 import CrudModel from 'src/components/CrudModel.vue';
 import FormModelPopup from 'components/FormModelPopup.vue';
 
-import VnTableColumn from 'components/VnTable/VnColumn.vue';
+import VnColumn from 'components/VnTable/VnColumn.vue';
 import VnFilter from 'components/VnTable/VnFilter.vue';
 import VnTableChip from 'components/VnTable/VnChip.vue';
 import VnVisibleColumn from 'src/components/VnTable/VnVisibleColumn.vue';
 import VnLv from 'components/ui/VnLv.vue';
 import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
 import VnTableFilter from './VnTableFilter.vue';
+import { getColAlign } from 'src/composables/getColAlign';
 
+const arrayData = useArrayData(useAttrs()['data-key']);
 const $props = defineProps({
     columns: {
         type: Array,
@@ -42,10 +57,6 @@ const $props = defineProps({
         type: [Function, Boolean],
         default: null,
     },
-    rowCtrlClick: {
-        type: [Function, Boolean],
-        default: null,
-    },
     redirect: {
         type: String,
         default: null,
@@ -114,7 +125,19 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
+    withFilters: {
+        type: Boolean,
+        default: true,
+    },
+    overlay: {
+        type: Boolean,
+        default: false,
+    },
+    createComplement: {
+        type: Object,
+    },
 });
+
 const { t } = useI18n();
 const stateStore = useStateStore();
 const route = useRoute();
@@ -132,10 +155,18 @@ const showForm = ref(false);
 const splittedColumns = ref({ columns: [] });
 const columnsVisibilitySkipped = ref();
 const createForm = ref();
+const createRef = ref(null);
 const tableRef = ref();
 const params = ref(useFilterParams($attrs['data-key']).params);
 const orders = ref(useFilterParams($attrs['data-key']).orders);
+const app = inject('app');
 
+const editingRow = ref(null);
+const editingField = ref(null);
+const isTableMode = computed(() => mode.value == TABLE_MODE);
+const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
+const selectRegex = /select/;
+const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
 const tableModes = [
     {
         icon: 'view_column',
@@ -156,7 +187,8 @@ onBeforeMount(() => {
     hasParams.value = urlParams && Object.keys(urlParams).length !== 0;
 });
 
-onMounted(() => {
+onMounted(async () => {
+    if ($props.isEditable) document.addEventListener('click', clickHandler);
     mode.value =
         quasar.platform.is.mobile && !$props.disableOption?.card
             ? CARD_MODE
@@ -178,14 +210,25 @@ onMounted(() => {
     }
 });
 
+onUnmounted(async () => {
+    if ($props.isEditable) document.removeEventListener('click', clickHandler);
+});
+
 watch(
     () => $props.columns,
     (value) => splitColumns(value),
     { immediate: true },
 );
 
-const isTableMode = computed(() => mode.value == TABLE_MODE);
-const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
+defineExpose({
+    create: createForm,
+    reload,
+    redirect: redirectFn,
+    selected,
+    CrudModelRef,
+    params,
+    tableRef,
+});
 
 function splitColumns(columns) {
     splittedColumns.value = {
@@ -231,16 +274,6 @@ const rowClickFunction = computed(() => {
     return () => {};
 });
 
-const rowCtrlClickFunction = computed(() => {
-    if ($props.rowCtrlClick != undefined) return $props.rowCtrlClick;
-    if ($props.redirect)
-        return (evt, { id }) => {
-            stopEventPropagation(evt);
-            window.open(`/#/${$props.redirect}/${id}`, '_blank');
-        };
-    return () => {};
-});
-
 function redirectFn(id) {
     router.push({ path: `/${$props.redirect}/${id}` });
 }
@@ -262,21 +295,6 @@ function columnName(col) {
     return name;
 }
 
-function getColAlign(col) {
-    return 'text-' + (col.align ?? 'left');
-}
-
-const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
-defineExpose({
-    create: createForm,
-    reload,
-    redirect: redirectFn,
-    selected,
-    CrudModelRef,
-    params,
-    tableRef,
-});
-
 function handleOnDataSaved(_) {
     if (_.onDataSaved) _.onDataSaved({ CrudModelRef: CrudModelRef.value });
     else $props.create.onDataSaved(_);
@@ -304,6 +322,215 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
         }
     }
 }
+
+function isEditableColumn(column) {
+    const isEditableCol = column?.isEditable ?? true;
+    const isVisible = column?.visible ?? true;
+    const hasComponent = column?.component;
+
+    return $props.isEditable && isVisible && hasComponent && isEditableCol;
+}
+
+function hasEditableFormat(column) {
+    if (isEditableColumn(column)) return 'editable-text';
+}
+
+const clickHandler = async (event) => {
+    const clickedElement = event.target.closest('td');
+
+    const isDateElement = event.target.closest('.q-date');
+    const isTimeElement = event.target.closest('.q-time');
+    const isQselectDropDown = event.target.closest('.q-select__dropdown-icon');
+
+    if (isDateElement || isTimeElement || isQselectDropDown) return;
+
+    if (clickedElement === null) {
+        destroyInput(editingRow.value, editingField.value);
+        return;
+    }
+    const rowIndex = clickedElement.getAttribute('data-row-index');
+    const colField = clickedElement.getAttribute('data-col-field');
+    const column = $props.columns.find((col) => col.name === colField);
+
+    if (editingRow.value !== null && editingField.value !== null) {
+        if (editingRow.value === rowIndex && editingField.value === colField) {
+            return;
+        }
+
+        destroyInput(editingRow.value, editingField.value);
+    }
+    if (isEditableColumn(column))
+        await renderInput(Number(rowIndex), colField, clickedElement);
+};
+
+async function handleTabKey(event, rowIndex, colField) {
+    if (editingRow.value == rowIndex && editingField.value == colField)
+        destroyInput(editingRow.value, editingField.value);
+
+    const direction = event.shiftKey ? -1 : 1;
+    const { nextRowIndex, nextColumnName } = await handleTabNavigation(
+        rowIndex,
+        colField,
+        direction,
+    );
+
+    if (nextRowIndex < 0 || nextRowIndex >= arrayData.store.data.length) return;
+
+    event.preventDefault();
+    await renderInput(nextRowIndex, nextColumnName, null);
+}
+
+async function renderInput(rowId, field, clickedElement) {
+    editingField.value = field;
+    editingRow.value = rowId;
+
+    const originalColumn = $props.columns.find((col) => col.name === field);
+    const column = { ...originalColumn, ...{ label: '' } };
+    const row = CrudModelRef.value.formData[rowId];
+    const oldValue = CrudModelRef.value.formData[rowId][column?.name];
+
+    if (!clickedElement)
+        clickedElement = document.querySelector(
+            `[data-row-index="${rowId}"][data-col-field="${field}"]`,
+        );
+
+    Array.from(clickedElement.childNodes).forEach((child) => {
+        child.style.visibility = 'hidden';
+        child.style.position = 'relative';
+    });
+
+    const isSelect = selectRegex.test(column?.component);
+    if (isSelect) column.attrs = { ...column.attrs, 'emit-value': false };
+
+    const node = h(VnColumn, {
+        row: row,
+        class: 'temp-input',
+        column: column,
+        modelValue: row[column.name],
+        componentProp: 'columnField',
+        autofocus: true,
+        focusOnMount: true,
+        eventHandlers: {
+            'update:modelValue': async (value) => {
+                if (isSelect && value) {
+                    row[column.name] = value[column.attrs?.optionValue ?? 'id'];
+                    row[column?.name + 'TextValue'] =
+                        value[column.attrs?.optionLabel ?? 'name'];
+                    await column?.cellEvent?.['update:modelValue']?.(
+                        value,
+                        oldValue,
+                        row,
+                    );
+                } else row[column.name] = value;
+                await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
+            },
+            keyup: async (event) => {
+                if (event.key === 'Enter') handleBlur(rowId, field, clickedElement);
+            },
+            keydown: async (event) => {
+                switch (event.key) {
+                    case 'Tab':
+                        await handleTabKey(event, rowId, field);
+                        event.stopPropagation();
+                        break;
+                    case 'Escape':
+                        destroyInput(rowId, field, clickedElement);
+                        break;
+                    default:
+                        break;
+                }
+            },
+            click: (event) => {
+                column?.cellEvent?.['click']?.(event, row);
+            },
+        },
+    });
+
+    node.appContext = app._context;
+    render(node, clickedElement);
+
+    if (['checkbox', 'toggle', undefined].includes(column?.component))
+        node.el?.querySelector('span > div').focus();
+}
+
+function destroyInput(rowIndex, field, clickedElement) {
+    if (!clickedElement)
+        clickedElement = document.querySelector(
+            `[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
+        );
+    if (clickedElement) {
+        render(null, clickedElement);
+        Array.from(clickedElement.childNodes).forEach((child) => {
+            child.style.visibility = 'visible';
+            child.style.position = '';
+        });
+    }
+    if (editingRow.value !== rowIndex || editingField.value !== field) return;
+    editingRow.value = null;
+    editingField.value = null;
+}
+
+function handleBlur(rowIndex, field, clickedElement) {
+    destroyInput(rowIndex, field, clickedElement);
+}
+
+async function handleTabNavigation(rowIndex, colName, direction) {
+    const columns = $props.columns;
+    const totalColumns = columns.length;
+    let currentColumnIndex = columns.findIndex((col) => col.name === colName);
+
+    let iterations = 0;
+    let newColumnIndex = currentColumnIndex;
+
+    do {
+        iterations++;
+        newColumnIndex = (newColumnIndex + direction + totalColumns) % totalColumns;
+
+        if (isEditableColumn(columns[newColumnIndex])) break;
+    } while (iterations < totalColumns);
+
+    if (iterations >= totalColumns) {
+        return;
+    }
+
+    if (direction === 1 && newColumnIndex <= currentColumnIndex) {
+        rowIndex++;
+    } else if (direction === -1 && newColumnIndex >= currentColumnIndex) {
+        rowIndex--;
+    }
+    return { nextRowIndex: rowIndex, nextColumnName: columns[newColumnIndex].name };
+}
+
+function getCheckboxIcon(value) {
+    switch (typeof value) {
+        case 'boolean':
+            return value ? 'check' : 'close';
+        case 'number':
+            return value === 0 ? 'close' : 'check';
+        case 'undefined':
+            return 'indeterminate_check_box';
+        default:
+            return 'indeterminate_check_box';
+    }
+}
+
+function getToggleIcon(value) {
+    if (value === null) return 'help_outline';
+    return value ? 'toggle_on' : 'toggle_off';
+}
+
+function formatColumnValue(col, row, dashIfEmpty) {
+    if (col?.format) {
+        if (selectRegex.test(col?.component) && row[col?.name + 'TextValue']) {
+            return dashIfEmpty(row[col?.name + 'TextValue']);
+        } else {
+            return col.format(row, dashIfEmpty);
+        }
+    } else {
+        return dashIfEmpty(row[col?.name]);
+    }
+}
+const checkbox = ref(null);
 </script>
 <template>
     <QDrawer
@@ -311,7 +538,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
         v-model="stateStore.rightDrawer"
         side="right"
         :width="256"
-        show-if-above
+        :overlay="$props.overlay"
     >
         <QScrollArea class="fit">
             <VnTableFilter
@@ -332,7 +559,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
     <CrudModel
         v-bind="$attrs"
         :class="$attrs['class'] ?? 'q-px-md'"
-        :limit="$attrs['limit'] ?? 20"
+        :limit="$attrs['limit'] ?? 100"
         ref="CrudModelRef"
         @on-fetch="(...args) => emit('onFetch', ...args)"
         :search-url="searchUrl"
@@ -348,8 +575,12 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
             <QTable
                 ref="tableRef"
                 v-bind="table"
-                class="vnTable"
-                :class="{ 'last-row-sticky': $props.footer }"
+                :class="[
+                    'vnTable',
+                    table ? 'selection-cell' : '',
+                    $props.footer ? 'last-row-sticky' : '',
+                ]"
+                wrap-cells
                 :columns="splittedColumns.columns"
                 :rows="rows"
                 v-model:selected="selected"
@@ -363,11 +594,13 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                 @row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
                 @update:selected="emit('update:selected', $event)"
                 @selection="(details) => handleSelection(details, rows)"
+                :hide-selected-banner="true"
             >
                 <template #top-left v-if="!$props.withoutHeader">
-                    <slot name="top-left"></slot>
+                    <slot name="top-left"> </slot>
                 </template>
                 <template #top-right v-if="!$props.withoutHeader">
+                    <slot name="top-right"></slot>
                     <VnVisibleColumn
                         v-if="isTableMode"
                         v-model="splittedColumns.columns"
@@ -381,6 +614,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                         dense
                         :options="tableModes.filter((mode) => !mode.disable)"
                     />
+
                     <QBtn
                         v-if="showRightIcon"
                         icon="filter_alt"
@@ -392,32 +626,38 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                 <template #header-cell="{ col }">
                     <QTh
                         v-if="col.visible ?? true"
-                        :style="col.headerStyle"
-                        :class="col.headerClass"
+                        class="body-cell"
+                        :style="col?.width ? `max-width: ${col?.width}` : ''"
+                        style="padding: inherit"
                     >
                         <div
-                            class="column ellipsis"
-                            :class="`text-${col?.align ?? 'left'}`"
-                            :style="$props.columnSearch ? 'height: 75px' : ''"
+                            class="no-padding"
+                            :style="
+                                withFilters && $props.columnSearch ? 'height: 75px' : ''
+                            "
                         >
-                            <div class="row items-center no-wrap" style="height: 30px">
+                            <div class="text-center" style="height: 30px">
                                 <QTooltip v-if="col.toolTip">{{ col.toolTip }}</QTooltip>
                                 <VnTableOrder
                                     v-model="orders[col.orderBy ?? col.name]"
                                     :name="col.orderBy ?? col.name"
-                                    :label="col?.label"
+                                    :label="col?.labelAbbreviation ?? col?.label"
                                     :data-key="$attrs['data-key']"
                                     :search-url="searchUrl"
                                 />
                             </div>
                             <VnFilter
-                                v-if="$props.columnSearch"
+                                v-if="
+                                    $props.columnSearch &&
+                                    col.columnSearch !== false &&
+                                    withFilters
+                                "
                                 :column="col"
                                 :show-title="true"
                                 :data-key="$attrs['data-key']"
                                 v-model="params[columnName(col)]"
                                 :search-url="searchUrl"
-                                class="full-width"
+                                customClass="header-filter"
                             />
                         </div>
                     </QTh>
@@ -435,32 +675,63 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                     </QTd>
                 </template>
                 <template #body-cell="{ col, row, rowIndex }">
-                    <!-- Columns -->
                     <QTd
-                        auto-width
-                        class="no-margin"
-                        :class="[getColAlign(col), col.columnClass]"
-                        :style="col.style"
+                        class="no-margin q-px-xs"
                         v-if="col.visible ?? true"
-                        @click.ctrl="
-                            ($event) =>
-                                rowCtrlClickFunction && rowCtrlClickFunction($event, row)
-                        "
+                        :style="{
+                            'max-width': col?.width ?? false,
+                            position: 'relative',
+                        }"
+                        :class="[
+                            col.columnClass,
+                            'body-cell no-margin no-padding',
+                            getColAlign(col),
+                        ]"
+                        :data-row-index="rowIndex"
+                        :data-col-field="col?.name"
                     >
-                        <slot
-                            :name="`column-${col.name}`"
-                            :col="col"
-                            :row="row"
-                            :row-index="rowIndex"
+                        <div
+                            class="no-padding no-margin peter"
+                            style="
+                                overflow: hidden;
+                                text-overflow: ellipsis;
+                                white-space: nowrap;
+                            "
                         >
-                            <VnTableColumn
-                                :column="col"
+                            <slot
+                                :name="`column-${col.name}`"
+                                :col="col"
                                 :row="row"
-                                :is-editable="col.isEditable ?? isEditable"
-                                v-model="row[col.name]"
-                                component-prop="columnField"
-                            />
-                        </slot>
+                                :row-index="rowIndex"
+                            >
+                                <QIcon
+                                    v-if="col?.component === 'toggle'"
+                                    :name="
+                                        col?.getIcon
+                                            ? col.getIcon(row[col?.name])
+                                            : getToggleIcon(row[col?.name])
+                                    "
+                                    style="color: var(--vn-text-color)"
+                                    :class="hasEditableFormat(col)"
+                                    size="14px"
+                                />
+                                <QIcon
+                                    v-else-if="col?.component === 'checkbox'"
+                                    :name="getCheckboxIcon(row[col?.name])"
+                                    style="color: var(--vn-text-color)"
+                                    :class="hasEditableFormat(col)"
+                                    size="14px"
+                                />
+                                <span
+                                    v-else
+                                    :class="hasEditableFormat(col)"
+                                    :style="col?.style ? col.style(row) : null"
+                                    style="bottom: 0"
+                                >
+                                    {{ formatColumnValue(col, row, dashIfEmpty) }}
+                                </span>
+                            </slot>
+                        </div>
                     </QTd>
                 </template>
                 <template #body-cell-tableActions="{ col, row }">
@@ -563,7 +834,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                                                         :row="row"
                                                         :row-index="index"
                                                     >
-                                                        <VnTableColumn
+                                                        <VnColumn
                                                             :column="col"
                                                             :row="row"
                                                             :is-editable="false"
@@ -603,14 +874,17 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
                     </component>
                 </template>
                 <template #bottom-row="{ cols }" v-if="$props.footer">
-                    <QTr v-if="rows.length" style="height: 30px">
+                    <QTr v-if="rows.length" style="height: 45px">
+                        <QTh v-if="table.selection" />
                         <QTh
                             v-for="col of cols.filter((cols) => cols.visible ?? true)"
                             :key="col?.id"
-                            class="text-center"
                             :class="getColAlign(col)"
                         >
-                            <slot :name="`column-footer-${col.name}`" />
+                            <slot
+                                :name="`column-footer-${col.name}`"
+                                :isEditableColumn="isEditableColumn(col)"
+                            />
                         </QTh>
                     </QTr>
                 </template>
@@ -654,32 +928,53 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
             {{ createForm?.title }}
         </QTooltip>
     </QPageSticky>
-    <QDialog v-model="showForm" transition-show="scale" transition-hide="scale">
+    <QDialog
+        v-model="showForm"
+        transition-show="scale"
+        transition-hide="scale"
+        :full-width="createComplement?.isFullWidth ?? false"
+        @before-hide="
+            () => {
+                if (createRef.isSaveAndContinue) {
+                    showForm = true;
+                    createForm.formInitialData = { ...create.formInitialData };
+                }
+            }
+        "
+        data-cy="vn-table-create-dialog"
+    >
         <FormModelPopup
+            ref="createRef"
             v-bind="createForm"
             :model="$attrs['data-key'] + 'Create'"
             @on-data-saved="(_, res) => createForm.onDataSaved(res)"
         >
             <template #form-inputs="{ data }">
-                <div class="grid-create">
-                    <slot
-                        v-for="column of splittedColumns.create"
-                        :key="column.name"
-                        :name="`column-create-${column.name}`"
-                        :data="data"
-                        :column-name="column.name"
-                        :label="column.label"
-                    >
-                        <VnTableColumn
-                            :column="column"
-                            :row="{}"
-                            default="input"
-                            v-model="data[column.name]"
-                            :show-label="true"
-                            component-prop="columnCreate"
-                        />
-                    </slot>
-                    <slot name="more-create-dialog" :data="data" />
+                <div :style="createComplement?.containerStyle">
+                    <div>
+                        <slot name="previous-create-dialog" :data="data" />
+                    </div>
+                    <div class="grid-create" :style="createComplement?.columnGridStyle">
+                        <slot
+                            v-for="column of splittedColumns.create"
+                            :key="column.name"
+                            :name="`column-create-${column.name}`"
+                            :data="data"
+                            :column-name="column.name"
+                            :label="column.label"
+                        >
+                            <VnColumn
+                                :column="column"
+                                :row="{}"
+                                default="input"
+                                v-model="data[column.name]"
+                                :show-label="true"
+                                component-prop="columnCreate"
+                                :data-cy="`${column.name}-create-popup`"
+                            />
+                        </slot>
+                        <slot name="more-create-dialog" :data="data" />
+                    </div>
                 </div>
             </template>
         </FormModelPopup>
@@ -697,6 +992,42 @@ es:
 </i18n>
 
 <style lang="scss">
+.selection-cell {
+    table td:first-child {
+        padding: 0px;
+    }
+}
+.side-padding {
+    padding-left: 1px;
+    padding-right: 1px;
+}
+.editable-text:hover {
+    border-bottom: 1px dashed var(--q-primary);
+    @extend .side-padding;
+}
+.editable-text {
+    border-bottom: 1px dashed var(--vn-label-color);
+    @extend .side-padding;
+}
+.cell-input {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    padding-top: 0px !important;
+}
+.q-field--labeled .q-field__native,
+.q-field--labeled .q-field__prefix,
+.q-field--labeled .q-field__suffix {
+    padding-top: 20px;
+}
+
+.body-cell {
+    padding-left: 2px !important;
+    padding-right: 2px !important;
+    position: relative;
+}
 .bg-chip-secondary {
     background-color: var(--vn-page-color);
     color: var(--vn-text-color);
@@ -713,7 +1044,7 @@ es:
 
 .grid-three {
     display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(350px, max-content));
+    grid-template-columns: repeat(auto-fit, minmax(300px, max-content));
     max-width: 100%;
     grid-gap: 20px;
     margin: 0 auto;
@@ -722,7 +1053,6 @@ es:
 .grid-create {
     display: grid;
     grid-template-columns: repeat(auto-fit, minmax(150px, max-content));
-    max-width: 100%;
     grid-gap: 20px;
     margin: 0 auto;
 }
@@ -738,7 +1068,9 @@ es:
         }
     }
 }
-
+.q-table tbody tr td {
+    position: relative;
+}
 .q-table {
     th {
         padding: 0;
@@ -838,4 +1170,15 @@ es:
 .q-table__middle.q-virtual-scroll.q-virtual-scroll--vertical.scroll {
     background-color: var(--vn-section-color);
 }
+.temp-input {
+    top: 0;
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    display: flex;
+}
+
+label.header-filter > .q-field__inner > .q-field__control {
+    padding: inherit;
+}
 </style>
diff --git a/src/components/VnTable/VnTableFilter.vue b/src/components/VnTable/VnTableFilter.vue
index 63b84cd59..79b903e54 100644
--- a/src/components/VnTable/VnTableFilter.vue
+++ b/src/components/VnTable/VnTableFilter.vue
@@ -29,25 +29,29 @@ function columnName(col) {
     <VnFilterPanel v-bind="$attrs" :search-button="true" :disable-submit-event="true">
         <template #body="{ params, orders, searchFn }">
             <div
-                class="row no-wrap flex-center"
+                class="container"
                 v-for="col of columns.filter((c) => c.columnFilter ?? true)"
                 :key="col.id"
             >
-                <VnFilter
-                    ref="tableFilterRef"
-                    :column="col"
-                    :data-key="$attrs['data-key']"
-                    v-model="params[columnName(col)]"
-                    :search-url="searchUrl"
-                />
-                <VnTableOrder
-                    v-if="col?.columnFilter !== false && col?.name !== 'tableActions'"
-                    v-model="orders[col.orderBy ?? col.name]"
-                    :name="col.orderBy ?? col.name"
-                    :data-key="$attrs['data-key']"
-                    :search-url="searchUrl"
-                    :vertical="true"
-                />
+                <div class="filter">
+                    <VnFilter
+                        ref="tableFilterRef"
+                        :column="col"
+                        :data-key="$attrs['data-key']"
+                        v-model="params[columnName(col)]"
+                        :search-url="searchUrl"
+                    />
+                </div>
+                <div class="order">
+                    <VnTableOrder
+                        v-if="col?.columnFilter !== false && col?.name !== 'tableActions'"
+                        v-model="orders[col.orderBy ?? col.name]"
+                        :name="col.orderBy ?? col.name"
+                        :data-key="$attrs['data-key']"
+                        :search-url="searchUrl"
+                        :vertical="true"
+                    />
+                </div>
             </div>
             <slot
                 name="moreFilterPanel"
@@ -68,3 +72,21 @@ function columnName(col) {
         </template>
     </VnFilterPanel>
 </template>
+<style lang="scss" scoped>
+.container {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 45px;
+    gap: 10px;
+}
+
+.filter {
+    width: 70%;
+    height: 40px;
+    text-align: center;
+}
+.order {
+    width: 10%;
+}
+</style>
diff --git a/src/components/VnTable/VnVisibleColumn.vue b/src/components/VnTable/VnVisibleColumn.vue
index dad950d73..6d15c585e 100644
--- a/src/components/VnTable/VnVisibleColumn.vue
+++ b/src/components/VnTable/VnVisibleColumn.vue
@@ -32,16 +32,21 @@ const areAllChecksMarked = computed(() => {
 
 function setUserConfigViewData(data, isLocal) {
     if (!data) return;
-    // Importante: El name de las columnas de la tabla debe conincidir con el name de las variables que devuelve la view config
     if (!isLocal) localColumns.value = [];
-    // Array to Object
+
     const skippeds = $props.skip.reduce((a, v) => ({ ...a, [v]: v }), {});
 
     for (let column of columns.value) {
-        const { label, name } = column;
+        const { label, name, labelAbbreviation } = column;
         if (skippeds[name]) continue;
         column.visible = data[name] ?? true;
-        if (!isLocal) localColumns.value.push({ name, label, visible: column.visible });
+        if (!isLocal)
+            localColumns.value.push({
+                name,
+                label,
+                labelAbbreviation,
+                visible: column.visible,
+            });
     }
 }
 
@@ -152,7 +157,11 @@ onMounted(async () => {
                     <QCheckbox
                         v-for="col in localColumns"
                         :key="col.name"
-                        :label="col.label ?? col.name"
+                        :label="
+                            col?.labelAbbreviation
+                                ? col.labelAbbreviation + ` (${col.label ?? col.name})`
+                                : (col.label ?? col.name)
+                        "
                         v-model="col.visible"
                     />
                 </div>
diff --git a/src/components/__tests__/UserPanel.spec.js b/src/components/__tests__/UserPanel.spec.js
index ac20f911e..9e449745a 100644
--- a/src/components/__tests__/UserPanel.spec.js
+++ b/src/components/__tests__/UserPanel.spec.js
@@ -1,61 +1,65 @@
-import { vi, describe, expect, it, beforeEach, beforeAll, afterEach } from 'vitest';
+import { vi, describe, expect, it, beforeEach, afterEach } from 'vitest';
 import { createWrapper } from 'app/test/vitest/helper';
 import UserPanel from 'src/components/UserPanel.vue';
 import axios from 'axios';
 import { useState } from 'src/composables/useState';
 
+vi.mock('src/utils/quasarLang', () => ({
+  default: vi.fn(),
+}));
+
 describe('UserPanel', () => {
-    let wrapper;
-    let vm;
-    let state;
+  let wrapper;
+  let vm;
+  let state;
 
-    beforeEach(() => {
-        wrapper = createWrapper(UserPanel, {});
-        state = useState();
-        state.setUser({
-            id: 115,
-            name: 'itmanagement',
-            nickname: 'itManagementNick',
-            lang: 'en',
-            darkMode: false,
-            companyFk: 442,
-            warehouseFk: 1,
-        });
-        wrapper = wrapper.wrapper;
-        vm = wrapper.vm;
+  beforeEach(() => {
+    wrapper = createWrapper(UserPanel, {});
+    state = useState();
+    state.setUser({
+      id: 115,
+      name: 'itmanagement',
+      nickname: 'itManagementNick',
+      lang: 'en',
+      darkMode: false,
+      companyFk: 442,
+      warehouseFk: 1,
     });
+    wrapper = wrapper.wrapper;
+    vm = wrapper.vm;
+  });
 
-    afterEach(() => {
-        vi.clearAllMocks();
-    });
+  afterEach(() => {
+    vi.clearAllMocks();
+  });
 
-    it('should fetch warehouses data on mounted', async () => {
-        const fetchData = wrapper.findComponent({ name: 'FetchData' });
-        expect(fetchData.props('url')).toBe('Warehouses');
-        expect(fetchData.props('autoLoad')).toBe(true);
-    });
+  it('should fetch warehouses data on mounted', async () => {
+    const fetchData = wrapper.findComponent({ name: 'FetchData' });
+    expect(fetchData.props('url')).toBe('Warehouses');
+    expect(fetchData.props('autoLoad')).toBe(true);
+  });
 
-    it('should toggle dark mode correctly and update preferences', async () => {
-        await vm.saveDarkMode(true);
-        expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
-        expect(vm.user.darkMode).toBe(true);
-        vm.updatePreferences();
-        expect(vm.darkMode).toBe(true);
-    });
+  it('should toggle dark mode correctly and update preferences', async () => {
+    await vm.saveDarkMode(true);
+    expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
+    expect(vm.user.darkMode).toBe(true);
+    await vm.updatePreferences();
+    expect(vm.darkMode).toBe(true);
+  });
 
-    it('should change user language and update preferences', async () => {
-        const userLanguage = 'es';
-        await vm.saveLanguage(userLanguage);
-        expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
-        expect(vm.user.lang).toBe(userLanguage);
-        vm.updatePreferences();
-        expect(vm.locale).toBe(userLanguage);
-    });
+  it('should change user language and update preferences', async () => {
+    const userLanguage = 'es';
+    await vm.saveLanguage(userLanguage);
+    expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
+    expect(vm.user.lang).toBe(userLanguage);
+    await vm.updatePreferences();
+    expect(vm.locale).toBe(userLanguage);
+  });
 
-    it('should update user data', async () => {
-        const key = 'name';
-        const value = 'itboss';
-        await vm.saveUserData(key, value);
-        expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value });
-    });
-});
+  it('should update user data', async () => {
+    const key = 'name';
+    const value = 'itboss';
+    await vm.saveUserData(key, value);
+    expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value });
+  });
+});
\ No newline at end of file
diff --git a/src/components/common/VnCheckbox.vue b/src/components/common/VnCheckbox.vue
new file mode 100644
index 000000000..27131d45e
--- /dev/null
+++ b/src/components/common/VnCheckbox.vue
@@ -0,0 +1,43 @@
+<script setup>
+import { computed } from 'vue';
+
+const model = defineModel({ type: [Number, Boolean] });
+const $props = defineProps({
+    info: {
+        type: String,
+        default: null,
+    },
+});
+
+const checkboxModel = computed({
+    get() {
+        if (typeof model.value === 'number') {
+            return model.value !== 0;
+        }
+        return model.value;
+    },
+    set(value) {
+        if (typeof model.value === 'number') {
+            model.value = value ? 1 : 0;
+        } else {
+            model.value = value;
+        }
+    },
+});
+</script>
+<template>
+    <div>
+        <QCheckbox v-bind="$attrs" v-on="$attrs" v-model="checkboxModel" />
+        <QIcon
+            v-if="info"
+            v-bind="$attrs"
+            class="cursor-info q-ml-sm"
+            name="info"
+            size="sm"
+        >
+            <QTooltip>
+                {{ info }}
+            </QTooltip>
+        </QIcon>
+    </div>
+</template>
diff --git a/src/components/common/VnColor.vue b/src/components/common/VnColor.vue
new file mode 100644
index 000000000..8a5a787b0
--- /dev/null
+++ b/src/components/common/VnColor.vue
@@ -0,0 +1,32 @@
+<script setup>
+const $props = defineProps({
+    colors: {
+        type: String,
+        default: '{"value": []}',
+    },
+});
+
+const colorArray = JSON.parse($props.colors)?.value;
+const maxHeight = 30;
+const colorHeight = maxHeight / colorArray?.length;
+</script>
+<template>
+    <div v-if="colors" class="color-div" :style="{ height: `${maxHeight}px` }">
+        <div
+            v-for="(color, index) in colorArray"
+            :key="index"
+            :style="{
+                backgroundColor: `#${color}`,
+                height: `${colorHeight}px`,
+            }"
+        >
+            &nbsp;
+        </div>
+    </div>
+</template>
+<style scoped>
+.color-div {
+    display: flex;
+    flex-direction: column;
+}
+</style>
diff --git a/src/components/common/VnComponent.vue b/src/components/common/VnComponent.vue
index 580bcf348..d9d1ea26b 100644
--- a/src/components/common/VnComponent.vue
+++ b/src/components/common/VnComponent.vue
@@ -17,6 +17,8 @@ const $props = defineProps({
     },
 });
 
+const emit = defineEmits(['blur']);
+
 const componentArray = computed(() => {
     if (typeof $props.prop === 'object') return [$props.prop];
     return $props.prop;
@@ -54,6 +56,7 @@ function toValueAttrs(attrs) {
             v-bind="mix(toComponent).attrs"
             v-on="mix(toComponent).event ?? {}"
             v-model="model"
+            @blur="emit('blur')"
         />
     </span>
 </template>
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 78f08a479..aeb4a31fd 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -11,6 +11,7 @@ const emit = defineEmits([
     'update:options',
     'keyup.enter',
     'remove',
+    'blur',
 ]);
 
 const $props = defineProps({
@@ -136,6 +137,7 @@ const handleUppercase = () => {
             :type="$attrs.type"
             :class="{ required: isRequired }"
             @keyup.enter="emit('keyup.enter')"
+            @blur="emit('blur')"
             @keydown="handleKeydown"
             :clearable="false"
             :rules="mixinRules"
@@ -143,7 +145,7 @@ const handleUppercase = () => {
             hide-bottom-space
             :data-cy="$attrs.dataCy ?? $attrs.label + '_input'"
         >
-            <template #prepend>
+            <template #prepend v-if="$slots.prepend">
                 <slot name="prepend" />
             </template>
             <template #append>
@@ -168,11 +170,11 @@ const handleUppercase = () => {
                         }
                     "
                 ></QIcon>
-                
+
                 <QIcon
                     name="match_case"
                     size="xs"
-                    v-if="!$attrs.disabled && !($attrs.readonly) && $props.uppercase"
+                    v-if="!$attrs.disabled && !$attrs.readonly && $props.uppercase"
                     @click="handleUppercase"
                     class="uppercase-icon"
                 >
@@ -180,7 +182,7 @@ const handleUppercase = () => {
                         {{ t('Convert to uppercase') }}
                     </QTooltip>
                 </QIcon>
-                
+
                 <slot name="append" v-if="$slots.append && !$attrs.disabled" />
                 <QIcon v-if="info" name="info">
                     <QTooltip max-width="350px">
@@ -194,13 +196,15 @@ const handleUppercase = () => {
 
 <style>
 .uppercase-icon {
-  transition: color 0.3s, transform 0.2s;
-  cursor: pointer;
+    transition:
+        color 0.3s,
+        transform 0.2s;
+    cursor: pointer;
 }
 
 .uppercase-icon:hover {
-  color: #ed9937;
-  transform: scale(1.2);
+    color: #ed9937;
+    transform: scale(1.2);
 }
 </style>
 <i18n>
@@ -214,4 +218,4 @@ const handleUppercase = () => {
         maxLength: El valor excede los {value} carácteres
         inputMax: Debe ser menor a {value}
         Convert to uppercase: Convertir a mayúsculas
-</i18n>
\ No newline at end of file
+</i18n>
diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue
index a8888aad8..73c825e1e 100644
--- a/src/components/common/VnInputDate.vue
+++ b/src/components/common/VnInputDate.vue
@@ -42,7 +42,7 @@ const formattedDate = computed({
                 if (value.at(2) == '/') value = value.split('/').reverse().join('/');
                 value = date.formatDate(
                     new Date(value).toISOString(),
-                    'YYYY-MM-DDTHH:mm:ss.SSSZ'
+                    'YYYY-MM-DDTHH:mm:ss.SSSZ',
                 );
             }
             const [year, month, day] = value.split('-').map((e) => parseInt(e));
@@ -55,7 +55,7 @@ const formattedDate = computed({
                     orgDate.getHours(),
                     orgDate.getMinutes(),
                     orgDate.getSeconds(),
-                    orgDate.getMilliseconds()
+                    orgDate.getMilliseconds(),
                 );
             }
         }
@@ -64,7 +64,7 @@ const formattedDate = computed({
 });
 
 const popupDate = computed(() =>
-    model.value ? date.formatDate(new Date(model.value), 'YYYY/MM/DD') : model.value
+    model.value ? date.formatDate(new Date(model.value), 'YYYY/MM/DD') : model.value,
 );
 onMounted(() => {
     // fix quasar bug
@@ -73,7 +73,7 @@ onMounted(() => {
 watch(
     () => model.value,
     (val) => (formattedDate.value = val),
-    { immediate: true }
+    { immediate: true },
 );
 
 const styleAttrs = computed(() => {
diff --git a/src/components/common/VnInputNumber.vue b/src/components/common/VnInputNumber.vue
index 165cfae3d..274f78b21 100644
--- a/src/components/common/VnInputNumber.vue
+++ b/src/components/common/VnInputNumber.vue
@@ -8,6 +8,7 @@ defineProps({
 });
 
 const model = defineModel({ type: [Number, String] });
+const emit = defineEmits(['blur']);
 </script>
 <template>
     <VnInput
@@ -24,5 +25,6 @@ const model = defineModel({ type: [Number, String] });
                     model = parseFloat(val).toFixed(decimalPlaces);
             }
         "
+        @blur="emit('blur')"
     />
 </template>
diff --git a/src/components/common/VnPopupProxy.vue b/src/components/common/VnPopupProxy.vue
new file mode 100644
index 000000000..f386bfff8
--- /dev/null
+++ b/src/components/common/VnPopupProxy.vue
@@ -0,0 +1,38 @@
+<script setup>
+import { ref } from 'vue';
+
+defineProps({
+    label: {
+        type: String,
+        default: '',
+    },
+    icon: {
+        type: String,
+        required: true,
+        default: null,
+    },
+    color: {
+        type: String,
+        default: 'primary',
+    },
+    tooltip: {
+        type: String,
+        default: null,
+    },
+});
+const popupProxyRef = ref(null);
+</script>
+
+<template>
+    <QBtn :color="$props.color" :icon="$props.icon" :label="$t($props.label)">
+        <template #default>
+            <slot name="extraIcon"></slot>
+            <QPopupProxy ref="popupProxyRef" style="max-width: none">
+                <QCard>
+                    <slot :popup="popupProxyRef"></slot>
+                </QCard>
+            </QPopupProxy>
+            <QTooltip>{{ $t($props.tooltip) }}</QTooltip>
+        </template>
+    </QBtn>
+</template>
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index c850f2e53..339f90e0e 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -171,7 +171,8 @@ onMounted(() => {
 });
 
 const arrayDataKey =
-    $props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
+    $props.dataKey ??
+    ($props.url?.length > 0 ? $props.url : ($attrs.name ?? $attrs.label));
 
 const arrayData = useArrayData(arrayDataKey, {
     url: $props.url,
@@ -220,7 +221,7 @@ async function fetchFilter(val) {
         optionFilterValue.value ??
         (new RegExp(/\d/g).test(val)
             ? optionValue.value
-            : optionFilter.value ?? optionLabel.value);
+            : (optionFilter.value ?? optionLabel.value));
 
     let defaultWhere = {};
     if ($props.filterOptions.length) {
@@ -239,7 +240,7 @@ async function fetchFilter(val) {
 
     const { data } = await arrayData.applyFilter(
         { filter: filterOptions },
-        { updateRouter: false }
+        { updateRouter: false },
     );
     setOptions(data);
     return data;
@@ -272,7 +273,7 @@ async function filterHandler(val, update) {
                 ref.setOptionIndex(-1);
                 ref.moveOptionSelection(1, true);
             }
-        }
+        },
     );
 }
 
@@ -308,7 +309,7 @@ function handleKeyDown(event) {
         if (inputValue) {
             const matchingOption = myOptions.value.find(
                 (option) =>
-                    option[optionLabel.value].toLowerCase() === inputValue.toLowerCase()
+                    option[optionLabel.value].toLowerCase() === inputValue.toLowerCase(),
             );
 
             if (matchingOption) {
@@ -320,11 +321,11 @@ function handleKeyDown(event) {
         }
 
         const focusableElements = document.querySelectorAll(
-            'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])'
+            'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])',
         );
         const currentIndex = Array.prototype.indexOf.call(
             focusableElements,
-            event.target
+            event.target,
         );
         if (currentIndex >= 0 && currentIndex < focusableElements.length - 1) {
             focusableElements[currentIndex + 1].focus();
diff --git a/src/components/common/VnSelectCache.vue b/src/components/common/VnSelectCache.vue
index 29cf22dc5..f0f3357f6 100644
--- a/src/components/common/VnSelectCache.vue
+++ b/src/components/common/VnSelectCache.vue
@@ -14,7 +14,7 @@ const $props = defineProps({
     },
 });
 const options = ref([]);
-
+const emit = defineEmits(['blur']);
 onBeforeMount(async () => {
     const { url, optionValue, optionLabel } = useAttrs();
     const findBy = $props.find ?? url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1);
@@ -35,5 +35,5 @@ onBeforeMount(async () => {
 });
 </script>
 <template>
-    <VnSelect v-bind="$attrs" :options="$attrs.options ?? options" />
+    <VnSelect v-bind="$attrs" :options="$attrs.options ?? options" @blur="emit('blur')" />
 </template>
diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue
index a4cd0011d..41730b217 100644
--- a/src/components/common/VnSelectDialog.vue
+++ b/src/components/common/VnSelectDialog.vue
@@ -37,7 +37,6 @@ const isAllowedToCreate = computed(() => {
 
 defineExpose({ vnSelectDialogRef: select });
 </script>
-
 <template>
     <VnSelect
         ref="select"
@@ -67,7 +66,6 @@ defineExpose({ vnSelectDialogRef: select });
         </template>
     </VnSelect>
 </template>
-
 <style lang="scss" scoped>
 .default-icon {
     cursor: pointer;
diff --git a/src/components/common/VnSelectSupplier.vue b/src/components/common/VnSelectSupplier.vue
index f86db4f2d..5b52ae75b 100644
--- a/src/components/common/VnSelectSupplier.vue
+++ b/src/components/common/VnSelectSupplier.vue
@@ -1,9 +1,7 @@
 <script setup>
-import { computed } from 'vue';
 import VnSelect from 'components/common/VnSelect.vue';
 
 const model = defineModel({ type: [String, Number, Object] });
-const url = 'Suppliers';
 </script>
 
 <template>
@@ -11,11 +9,13 @@ const url = 'Suppliers';
         :label="$t('globals.supplier')"
         v-bind="$attrs"
         v-model="model"
-        :url="url"
+        url="Suppliers"
         option-value="id"
         option-label="nickname"
         :fields="['id', 'name', 'nickname', 'nif']"
+        :filter-options="['id', 'name', 'nickname', 'nif']"
         sort-by="name ASC"
+        data-cy="vnSupplierSelect"
     >
         <template #option="scope">
             <QItem v-bind="scope.itemProps">
diff --git a/src/components/common/VnSelectTravelExtended.vue b/src/components/common/VnSelectTravelExtended.vue
new file mode 100644
index 000000000..46538f5f9
--- /dev/null
+++ b/src/components/common/VnSelectTravelExtended.vue
@@ -0,0 +1,50 @@
+<script setup>
+import VnSelectDialog from './VnSelectDialog.vue';
+import FilterTravelForm from 'src/components/FilterTravelForm.vue';
+import { useI18n } from 'vue-i18n';
+import { toDate } from 'src/filters';
+const { t } = useI18n();
+
+const $props = defineProps({
+    data: {
+        type: Object,
+        required: true,
+    },
+    onFilterTravelSelected: {
+        type: Function,
+        required: true,
+    },
+});
+</script>
+<template>
+    <VnSelectDialog
+        :label="t('entry.basicData.travel')"
+        v-bind="$attrs"
+        url="Travels/filter"
+        :fields="['id', 'warehouseInName']"
+        option-value="id"
+        option-label="warehouseInName"
+        map-options
+        hide-selected
+        :required="true"
+        action-icon="filter_alt"
+        :roles-allowed-to-create="['buyer']"
+    >
+        <template #form>
+            <FilterTravelForm @travel-selected="onFilterTravelSelected(data, $event)" />
+        </template>
+        <template #option="scope">
+            <QItem v-bind="scope.itemProps">
+                <QItemSection>
+                    <QItemLabel>
+                        {{ scope.opt?.agencyModeName }} -
+                        {{ scope.opt?.warehouseInName }}
+                        ({{ toDate(scope.opt?.shipped) }}) →
+                        {{ scope.opt?.warehouseOutName }}
+                        ({{ toDate(scope.opt?.landed) }})
+                    </QItemLabel>
+                </QItemSection>
+            </QItem>
+        </template>
+    </VnSelectDialog>
+</template>
diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue
index 275d919d6..e6e7e6fa0 100644
--- a/src/components/ui/CardDescriptor.vue
+++ b/src/components/ui/CardDescriptor.vue
@@ -6,6 +6,7 @@ import { useArrayData } from 'composables/useArrayData';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import { useState } from 'src/composables/useState';
 import { useRoute } from 'vue-router';
+import { useClipboard } from 'src/composables/useClipboard';
 import VnMoreOptions from './VnMoreOptions.vue';
 
 const $props = defineProps({
@@ -29,10 +30,6 @@ const $props = defineProps({
         type: String,
         default: null,
     },
-    module: {
-        type: String,
-        default: null,
-    },
     summary: {
         type: Object,
         default: null,
@@ -46,6 +43,7 @@ const $props = defineProps({
 const state = useState();
 const route = useRoute();
 const { t } = useI18n();
+const { copyText } = useClipboard();
 const { viewSummary } = useSummaryDialog();
 let arrayData;
 let store;
@@ -57,7 +55,7 @@ defineExpose({ getData });
 onBeforeMount(async () => {
     arrayData = useArrayData($props.dataKey, {
         url: $props.url,
-        filter: $props.filter,
+        userFilter: $props.filter,
         skip: 0,
         oneRecord: true,
     });
@@ -103,6 +101,14 @@ function getValueFromPath(path) {
     return current;
 }
 
+function copyIdText(id) {
+    copyText(id, {
+        component: {
+            copyValue: id,
+        },
+    });
+}
+
 const emit = defineEmits(['onFetch']);
 
 const iconModule = computed(() => route.matched[1].meta.icon);
@@ -148,7 +154,9 @@ const toModule = computed(() =>
                         {{ t('components.smartCard.openSummary') }}
                     </QTooltip>
                 </QBtn>
-                <RouterLink :to="{ name: `${module}Summary`, params: { id: entity.id } }">
+                <RouterLink
+                    :to="{ name: `${dataKey}Summary`, params: { id: entity.id } }"
+                >
                     <QBtn
                         class="link"
                         color="white"
@@ -184,9 +192,22 @@ const toModule = computed(() =>
                             </slot>
                         </div>
                     </QItemLabel>
-                    <QItem dense>
+                    <QItem>
                         <QItemLabel class="subtitle" caption>
                             #{{ getValueFromPath(subtitle) ?? entity.id }}
+                            <QBtn
+                                round
+                                flat
+                                dense
+                                size="sm"
+                                icon="content_copy"
+                                color="primary"
+                                @click.stop="copyIdText(entity.id)"
+                            >
+                                <QTooltip>
+                                    {{ t('globals.copyId') }}
+                                </QTooltip>
+                            </QBtn>
                         </QItemLabel>
                     </QItem>
                 </QList>
@@ -294,3 +315,11 @@ const toModule = computed(() =>
     }
 }
 </style>
+<i18n>
+    en:
+        globals:
+            copyId: Copy ID
+    es:
+        globals:
+            copyId: Copiar ID
+</i18n>
diff --git a/src/components/ui/SkeletonDescriptor.vue b/src/components/ui/SkeletonDescriptor.vue
index 9679751f5..f9188221a 100644
--- a/src/components/ui/SkeletonDescriptor.vue
+++ b/src/components/ui/SkeletonDescriptor.vue
@@ -1,53 +1,32 @@
+<script setup>
+defineProps({
+    hasImage: {
+        type: Boolean,
+        default: false,
+    },
+});
+</script>
 <template>
-    <div id="descriptor-skeleton">
+    <div id="descriptor-skeleton" class="bg-vn-page">
         <div class="row justify-between q-pa-sm">
-            <QSkeleton square size="40px" />
-            <QSkeleton square size="40px" />
-            <QSkeleton square height="40px" width="20px" />
+            <QSkeleton square size="30px" v-for="i in 3" :key="i" />
         </div>
-        <div class="col justify-between q-pa-sm q-gutter-y-xs">
-            <QSkeleton square height="40px" width="150px" />
-            <QSkeleton square height="30px" width="70px" />
+        <div class="q-pa-xs" v-if="hasImage">
+            <QSkeleton square height="200px" width="100%" />
         </div>
-        <div class="col q-pl-sm q-pa-sm q-mb-md">
-            <div class="row justify-between">
-                <QSkeleton type="text" square height="30px" width="20%" />
-                <QSkeleton type="text" square height="30px" width="60%" />
-            </div>
-            <div class="row justify-between">
-                <QSkeleton type="text" square height="30px" width="20%" />
-                <QSkeleton type="text" square height="30px" width="60%" />
-            </div>
-            <div class="row justify-between">
-                <QSkeleton type="text" square height="30px" width="20%" />
-                <QSkeleton type="text" square height="30px" width="60%" />
-            </div>
-            <div class="row justify-between">
-                <QSkeleton type="text" square height="30px" width="20%" />
-                <QSkeleton type="text" square height="30px" width="60%" />
-            </div>
-            <div class="row justify-between">
-                <QSkeleton type="text" square height="30px" width="20%" />
-                <QSkeleton type="text" square height="30px" width="60%" />
-            </div>
-            <div class="row justify-between">
-                <QSkeleton type="text" square height="30px" width="20%" />
-                <QSkeleton type="text" square height="30px" width="60%" />
+        <div class="col justify-between q-pa-md q-gutter-y-xs">
+            <QSkeleton square height="25px" width="150px" />
+            <QSkeleton square height="15px" width="70px" />
+        </div>
+        <div class="q-pl-sm q-pa-sm q-mb-md">
+            <div class="row q-gutter-x-sm q-pa-none q-ma-none" v-for="i in 5" :key="i">
+                <QSkeleton type="text" square height="20px" width="30%" />
+                <QSkeleton type="text" square height="20px" width="60%" />
             </div>
         </div>
 
-        <QCardActions>
-            <QSkeleton size="40px" />
-            <QSkeleton size="40px" />
-            <QSkeleton size="40px" />
-            <QSkeleton size="40px" />
-            <QSkeleton size="40px" />
+        <QCardActions class="q-gutter-x-sm justify-between">
+            <QSkeleton size="40px" v-for="i in 5" :key="i" />
         </QCardActions>
     </div>
 </template>
-
-<style lang="scss" scoped>
-#descriptor-skeleton .q-card__actions {
-    justify-content: space-between;
-}
-</style>
diff --git a/src/components/ui/VnConfirm.vue b/src/components/ui/VnConfirm.vue
index a02b56bdb..c6f539879 100644
--- a/src/components/ui/VnConfirm.vue
+++ b/src/components/ui/VnConfirm.vue
@@ -82,7 +82,7 @@ function cancel() {
                     @click="cancel()"
                 />
             </QCardSection>
-            <QCardSection class="q-pb-none">
+            <QCardSection class="q-pb-none" data-cy="VnConfirm_message">
                 <span v-if="message !== false" v-html="message" />
             </QCardSection>
             <QCardSection class="row items-center q-pt-none">
@@ -95,6 +95,7 @@ function cancel() {
                     :disable="isLoading"
                     flat
                     @click="cancel()"
+                    data-cy="VnConfirm_cancel"
                 />
                 <QBtn
                     :label="t('globals.confirm')"
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
index 80128018a..d6b525dc8 100644
--- a/src/components/ui/VnFilterPanel.vue
+++ b/src/components/ui/VnFilterPanel.vue
@@ -293,6 +293,9 @@ const getLocale = (label) => {
     />
 </template>
 <style scoped lang="scss">
+.q-field__label.no-pointer-events.absolute.ellipsis {
+    margin-left: 6px !important;
+}
 .list {
     width: 256px;
 }
diff --git a/src/components/ui/VnMoreOptions.vue b/src/components/ui/VnMoreOptions.vue
index 39e84be2b..8a1c7a0f2 100644
--- a/src/components/ui/VnMoreOptions.vue
+++ b/src/components/ui/VnMoreOptions.vue
@@ -11,7 +11,7 @@
         <QTooltip>
             {{ $t('components.cardDescriptor.moreOptions') }}
         </QTooltip>
-        <QMenu ref="menuRef">
+        <QMenu ref="menuRef" data-cy="descriptor-more-opts-menu">
             <QList>
                 <slot name="menu" :menu-ref="$refs.menuRef" />
             </QList>
diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue
index 5b1d6e726..ec6289a67 100644
--- a/src/components/ui/VnNotes.vue
+++ b/src/components/ui/VnNotes.vue
@@ -18,7 +18,12 @@ import VnInput from 'components/common/VnInput.vue';
 
 const emit = defineEmits(['onFetch']);
 
-const $attrs = useAttrs();
+const originalAttrs = useAttrs();
+
+const $attrs = computed(() => {
+    const { style, ...rest } = originalAttrs;
+    return rest;
+});
 
 const isRequired = computed(() => {
     return Object.keys($attrs).includes('required')
diff --git a/src/components/ui/VnStockValueDisplay.vue b/src/components/ui/VnStockValueDisplay.vue
new file mode 100644
index 000000000..d8f43323b
--- /dev/null
+++ b/src/components/ui/VnStockValueDisplay.vue
@@ -0,0 +1,41 @@
+<script setup>
+import { toPercentage } from 'filters/index';
+
+import { computed } from 'vue';
+
+const props = defineProps({
+    value: {
+        type: Number,
+        required: true,
+    },
+});
+
+const valueClass = computed(() =>
+    props.value === 0 ? 'neutral' : props.value > 0 ? 'positive' : 'negative',
+);
+const iconName = computed(() =>
+    props.value === 0 ? 'equal' : props.value > 0 ? 'arrow_upward' : 'arrow_downward',
+);
+const formattedValue = computed(() => props.value);
+</script>
+<template>
+    <span :class="valueClass">
+        <QIcon :name="iconName" size="sm" class="value-icon" />
+        {{ toPercentage(formattedValue) }}
+    </span>
+</template>
+
+<style lang="scss" scoped>
+.positive {
+    color: $secondary;
+}
+.negative {
+    color: $negative;
+}
+.neutral {
+    color: $primary;
+}
+.value-icon {
+    margin-right: 4px;
+}
+</style>
diff --git a/src/composables/checkEntryLock.js b/src/composables/checkEntryLock.js
new file mode 100644
index 000000000..f964dea27
--- /dev/null
+++ b/src/composables/checkEntryLock.js
@@ -0,0 +1,65 @@
+import { useQuasar } from 'quasar';
+import { useI18n } from 'vue-i18n';
+import { useRouter } from 'vue-router';
+import axios from 'axios';
+import VnConfirm from 'components/ui/VnConfirm.vue';
+
+export async function checkEntryLock(entryFk, userFk) {
+    const { t } = useI18n();
+    const quasar = useQuasar();
+    const { push } = useRouter();
+    const { data } = await axios.get(`Entries/${entryFk}`, {
+        params: {
+            filter: JSON.stringify({
+                fields: ['id', 'locked', 'lockerUserFk'],
+                include: { relation: 'user', scope: { fields: ['id', 'nickname'] } },
+            }),
+        },
+    });
+    const entryConfig = await axios.get('EntryConfigs/findOne');
+
+    if (data?.lockerUserFk && data?.locked) {
+        const now = new Date(Date.vnNow()).getTime();
+        const lockedTime = new Date(data.locked).getTime();
+        const timeDiff = (now - lockedTime) / 1000;
+        const isMaxTimeLockExceeded = entryConfig.data.maxLockTime > timeDiff;
+
+        if (data?.lockerUserFk !== userFk && isMaxTimeLockExceeded) {
+            quasar
+                .dialog({
+                    component: VnConfirm,
+                    componentProps: {
+                        'data-cy': 'entry-lock-confirm',
+                        title: t('entry.lock.title'),
+                        message: t('entry.lock.message', {
+                            userName: data?.user?.nickname,
+                            time: timeDiff / 60,
+                        }),
+                    },
+                })
+                .onOk(
+                    async () =>
+                        await axios.patch(`Entries/${entryFk}`, {
+                            locked: Date.vnNow(),
+                            lockerUserFk: userFk,
+                        }),
+                )
+                .onCancel(() => {
+                    push({ path: `summary` });
+                });
+        }
+    } else {
+        await axios
+            .patch(`Entries/${entryFk}`, {
+                locked: Date.vnNow(),
+                lockerUserFk: userFk,
+            })
+            .then(
+                quasar.notify({
+                    message: t('entry.lock.success'),
+                    color: 'positive',
+                    group: false,
+                }),
+            );
+    }
+}
diff --git a/src/composables/getColAlign.js b/src/composables/getColAlign.js
new file mode 100644
index 000000000..c0338a984
--- /dev/null
+++ b/src/composables/getColAlign.js
@@ -0,0 +1,21 @@
+export function getColAlign(col) {
+    let align;
+    switch (col.component) {
+        case 'select':
+            align = 'left';
+            break;
+        case 'number':
+            align = 'right';
+            break;
+        case 'date':
+        case 'checkbox':
+            align = 'center';
+            break;
+        default:
+            align = col?.align;
+    }
+
+    if (/^is[A-Z]/.test(col.name) || /^has[A-Z]/.test(col.name)) align = 'center';
+
+    return 'text-' + (align ?? 'center');
+}
diff --git a/src/composables/useRole.js b/src/composables/useRole.js
index 3ec65dd0a..ff54b409c 100644
--- a/src/composables/useRole.js
+++ b/src/composables/useRole.js
@@ -27,6 +27,15 @@ export function useRole() {
 
         return false;
     }
+    function likeAny(roles) {
+        const roleStore = state.getRoles();
+        for (const role of roles) {
+            if (!roleStore.value.findIndex((rs) => rs.startsWith(role)) !== -1)
+                return true;
+        }
+
+        return false;
+    }
     function isEmployee() {
         return hasAny(['employee']);
     }
@@ -35,6 +44,7 @@ export function useRole() {
         isEmployee,
         fetch,
         hasAny,
+        likeAny,
         state,
     };
 }
diff --git a/src/css/app.scss b/src/css/app.scss
index 59e945f05..0c5dc97fa 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -21,7 +21,10 @@ body.body--light {
     .q-header .q-toolbar {
         color: var(--vn-text-color);
     }
+
+    --vn-color-negative: $negative;
 }
+
 body.body--dark {
     --vn-header-color: #5d5d5d;
     --vn-page-color: #222;
@@ -37,6 +40,8 @@ body.body--dark {
     --vn-text-color-contrast: black;
 
     background-color: var(--vn-page-color);
+
+    --vn-color-negative: $negative;
 }
 
 a {
@@ -75,7 +80,6 @@ a {
     text-decoration: underline;
 }
 
-// Removes chrome autofill background
 input:-webkit-autofill,
 select:-webkit-autofill {
     color: var(--vn-text-color);
@@ -149,11 +153,6 @@ select:-webkit-autofill {
     cursor: pointer;
 }
 
-.vn-table-separation-row {
-    height: 16px !important;
-    background-color: var(--vn-section-color) !important;
-}
-
 /* Estilo para el asterisco en campos requeridos */
 .q-field.required .q-field__label:after {
     content: ' *';
@@ -230,10 +229,12 @@ input::-webkit-inner-spin-button {
     max-width: 100%;
 }
 
-.q-table__container {
-    /* ===== Scrollbar CSS ===== /
-    / Firefox */
+.remove-bg {
+    filter: brightness(1.1);
+    mix-blend-mode: multiply;
+}
 
+.q-table__container {
     * {
         scrollbar-width: auto;
         scrollbar-color: var(--vn-label-color) transparent;
@@ -274,8 +275,6 @@ input::-webkit-inner-spin-button {
             font-size: 11pt;
         }
         td {
-            font-size: 11pt;
-            border-top: 1px solid var(--vn-page-color);
             border-collapse: collapse;
         }
     }
@@ -319,9 +318,6 @@ input::-webkit-inner-spin-button {
     max-width: fit-content;
 }
 
-.row > .column:has(.q-checkbox) {
-    max-width: fit-content;
-}
 .q-field__inner {
     .q-field__control {
         min-height: auto !important;
diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss
index d6e992437..22c6d2b56 100644
--- a/src/css/quasar.variables.scss
+++ b/src/css/quasar.variables.scss
@@ -13,7 +13,7 @@
 // Tip: Use the "Theme Builder" on Quasar's documentation website.
 // Tip: to add new colors https://quasar.dev/style/color-palette/#adding-your-own-colors
 $primary: #ec8916;
-$secondary: $primary;
+$secondary: #89be34;
 $positive: #c8e484;
 $negative: #fb5252;
 $info: #84d0e2;
@@ -30,7 +30,9 @@ $color-spacer: #7979794d;
 $border-thin-light: 1px solid $color-spacer-light;
 $primary-light: #f5b351;
 $dark-shadow-color: black;
-$layout-shadow-dark: 0 0 10px 2px #00000033, 0 0px 10px #0000003d;
+$layout-shadow-dark:
+    0 0 10px 2px #00000033,
+    0 0px 10px #0000003d;
 $spacing-md: 16px;
 $color-font-secondary: #777;
 $width-xs: 400px;
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index d615eef4c..e3b690042 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -33,6 +33,7 @@ globals:
     reset: Reset
     close: Close
     cancel: Cancel
+    isSaveAndContinue: Save and continue
     clone: Clone
     confirm: Confirm
     assign: Assign
@@ -155,6 +156,7 @@ globals:
     changeState: Change state
     raid: 'Raid {daysInForward} days'
     isVies: Vies
+    noData: No data available
     pageTitles:
         logIn: Login
         addressEdit: Update address
@@ -167,6 +169,7 @@ globals:
         workCenters: Work centers
         modes: Modes
         zones: Zones
+        negative: Negative
         zonesList: List
         deliveryDays: Delivery days
         upcomingDeliveries: Upcoming deliveries
@@ -174,6 +177,7 @@ globals:
         alias: Alias
         aliasUsers: Users
         subRoles: Subroles
+        myAccount: Mi cuenta
         inheritedRoles: Inherited Roles
         customers: Customers
         customerCreate: New customer
@@ -406,6 +410,106 @@ cau:
     subtitle: By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.
     inputLabel: Explain why this error should not appear
     askPrivileges: Ask for privileges
+entry:
+    list:
+        newEntry: New entry
+        tableVisibleColumns:
+            isExcludedFromAvailable: Exclude from inventory
+            isOrdered: Ordered
+            isConfirmed: Ready to label
+            isReceived: Received
+            isRaid: Raid
+            landed: Date
+            supplierFk: Supplier
+            reference: Ref/Alb/Guide
+            invoiceNumber: Invoice
+            agencyModeId: Agency
+            isBooked: Booked
+            companyFk: Company
+            evaNotes: Notes
+            warehouseOutFk: Origin
+            warehouseInFk: Destiny
+            entryTypeDescription: Entry type
+            invoiceAmount: Import
+            travelFk: Travel
+    summary:
+        invoiceAmount: Amount
+        commission: Commission
+        currency: Currency
+        invoiceNumber: Invoice number
+        ordered: Ordered
+        booked: Booked
+        excludedFromAvailable: Inventory
+        travelReference: Reference
+        travelAgency: Agency
+        travelShipped: Shipped
+        travelDelivered: Delivered
+        travelLanded: Landed
+        travelReceived: Received
+        buys: Buys
+        stickers: Stickers
+        package: Package
+        packing: Pack.
+        grouping: Group.
+        buyingValue: Buying value
+        import: Import
+        pvp: PVP
+    basicData:
+        travel: Travel
+        currency: Currency
+        commission: Commission
+        observation: Observation
+        booked: Booked
+        excludedFromAvailable: Inventory
+    buys:
+        observations: Observations
+        packagingFk: Box
+        color: Color
+        printedStickers: Printed stickers
+    notes:
+        observationType: Observation type
+    latestBuys:
+        tableVisibleColumns:
+            image: Picture
+            itemFk: Item ID
+            weightByPiece: Weight/Piece
+            isActive: Active
+            family: Family
+            entryFk: Entry
+            freightValue: Freight value
+            comissionValue: Commission value
+            packageValue: Package value
+            isIgnored: Is ignored
+            price2: Grouping
+            price3: Packing
+            minPrice: Min
+            ektFk: Ekt
+            packingOut: Package out
+            landing: Landing
+            isExcludedFromAvailable: Exclude from inventory
+            isRaid: Raid
+            invoiceNumber: Invoice
+            reference: Ref/Alb/Guide
+    params:
+        isExcludedFromAvailable: Excluir del inventario
+        isOrdered: Pedida
+        isConfirmed: Lista para etiquetar
+        isReceived: Recibida
+        isRaid: Redada
+        landed: Fecha
+        supplierFk: Proveedor
+        invoiceNumber: Nº Factura
+        reference: Ref/Alb/Guía
+        agencyModeId: Agencia
+        isBooked: Asentado
+        companyFk: Empresa
+        travelFk: Envio
+        evaNotes: Notas
+        warehouseOutFk: Origen
+        warehouseInFk: Destino
+        entryTypeDescription: Tipo entrada
+        invoiceAmount: Importe
+        dated: Fecha
 ticket:
     params:
         ticketFk: Ticket ID
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index ea5fa9e41..1dbe25366 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -33,9 +33,11 @@ globals:
     reset: Restaurar
     close: Cerrar
     cancel: Cancelar
+    isSaveAndContinue: Guardar y continuar
     clone: Clonar
     confirm: Confirmar
     assign: Asignar
+    replace: Sustituir
     back: Volver
     yes: Si
     no: No
@@ -48,6 +50,7 @@ globals:
     rowRemoved: Fila eliminada
     pleaseWait: Por favor espera...
     noPinnedModules: No has fijado ningún módulo
+    split: Split
     summary:
         basicData: Datos básicos
     daysOnward: Días adelante
@@ -55,8 +58,8 @@ globals:
     today: Hoy
     yesterday: Ayer
     dateFormat: es-ES
-    microsip: Abrir en MicroSIP
     noSelectedRows: No tienes ninguna línea seleccionada
+    microsip: Abrir en MicroSIP
     downloadCSVSuccess: Descarga de CSV exitosa
     reference: Referencia
     agency: Agencia
@@ -76,8 +79,10 @@ globals:
     requiredField: Campo obligatorio
     class: clase
     type: Tipo
-    reason: motivo
+    reason: Motivo
+    removeSelection: Eliminar selección
     noResults: Sin resultados
+    results: resultados
     system: Sistema
     notificationSent: Notificación enviada
     warehouse: Almacén
@@ -155,6 +160,7 @@ globals:
     changeState: Cambiar estado
     raid: 'Redada {daysInForward} días'
     isVies: Vies
+    noData: Datos no disponibles
     pageTitles:
         logIn: Inicio de sesión
         addressEdit: Modificar consignatario
@@ -166,6 +172,7 @@ globals:
         agency: Agencia
         workCenters: Centros de trabajo
         modes: Modos
+        negative: Tickets negativos
         zones: Zonas
         zonesList: Listado
         deliveryDays: Días de entrega
@@ -286,9 +293,9 @@ globals:
         buyRequest: Peticiones de compra
         wasteBreakdown: Deglose de mermas
         itemCreate: Nuevo artículo
-        tax: 'IVA'
-        botanical: 'Botánico'
-        barcode: 'Código de barras'
+        tax: IVA
+        botanical: Botánico
+        barcode: Código de barras
         itemTypeCreate: Nueva familia
         family: Familia
         lastEntries: Últimas entradas
@@ -352,7 +359,7 @@ globals:
         from: Desde
         to: Hasta
         supplierFk: Proveedor
-        supplierRef: Ref. proveedor
+        supplierRef: Nº factura
         serial: Serie
         amount: Importe
         awbCode: AWB
@@ -397,6 +404,87 @@ cau:
     subtitle: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
     inputLabel: Explique el motivo por el que no deberia aparecer este fallo
     askPrivileges: Solicitar permisos
+entry:
+    list:
+        newEntry: Nueva entrada
+        tableVisibleColumns:
+            isExcludedFromAvailable: Excluir del inventario
+            isOrdered: Pedida
+            isConfirmed: Lista para etiquetar
+            isReceived: Recibida
+            isRaid: Redada
+            landed: Fecha
+            supplierFk: Proveedor
+            invoiceNumber: Nº Factura
+            reference: Ref/Alb/Guía
+            agencyModeId: Agencia
+            isBooked: Asentado
+            companyFk: Empresa
+            travelFk: Envio
+            evaNotes: Notas
+            warehouseOutFk: Origen
+            warehouseInFk: Destino
+            entryTypeDescription: Tipo entrada
+            invoiceAmount: Importe
+    summary:
+        invoiceAmount: Importe
+        commission: Comisión
+        currency: Moneda
+        invoiceNumber: Núm. factura
+        ordered: Pedida
+        booked: Contabilizada
+        excludedFromAvailable: Inventario
+        travelReference: Referencia
+        travelAgency: Agencia
+        travelShipped: F. envio
+        travelWarehouseOut: Alm. salida
+        travelDelivered: Enviada
+        travelLanded: F. entrega
+        travelReceived: Recibida
+        buys: Compras
+        stickers: Etiquetas
+        package: Embalaje
+        packing: Pack.
+        grouping: Group.
+        buyingValue: Coste
+        import: Importe
+        pvp: PVP
+    basicData:
+        travel: Envío
+        currency: Moneda
+        observation: Observación
+        commission: Comisión
+        booked: Asentado
+        excludedFromAvailable: Inventario
+    buys:
+        observations: Observaciónes
+        packagingFk: Embalaje
+        color: Color
+        printedStickers: Etiquetas impresas
+    notes:
+        observationType: Tipo de observación
+    latestBuys:
+        tableVisibleColumns:
+            image: Foto
+            itemFk: Id Artículo
+            weightByPiece: Peso (gramos)/tallo
+            isActive: Activo
+            family: Familia
+            entryFk: Entrada
+            freightValue: Porte
+            comissionValue: Comisión
+            packageValue: Embalaje
+            isIgnored: Ignorado
+            price2: Grouping
+            price3: Packing
+            minPrice: Min
+            ektFk: Ekt
+            packingOut: Embalaje envíos
+            landing: Llegada
+            isExcludedFromAvailable: Excluir del inventario
+            isRaid: Redada
+            invoiceNumber: Nº Factura
+            reference: Ref/Alb/Guía
 ticket:
     params:
         ticketFk: ID de ticket
@@ -410,6 +498,38 @@ ticket:
         freightItemName: Nombre
         packageItemName: Embalaje
         longName: Descripción
+    pageTitles:
+        tickets: Tickets
+        list: Listado
+        ticketCreate: Nuevo ticket
+        summary: Resumen
+        basicData: Datos básicos
+        boxing: Encajado
+        sms: Sms
+        notes: Notas
+        sale: Lineas del pedido
+        dms: Gestión documental
+        negative: Tickets negativos
+        volume: Volumen
+        observation: Notas
+        ticketAdvance: Adelantar tickets
+        futureTickets: Tickets a futuro
+        expedition: Expedición
+        purchaseRequest: Petición de compra
+        weeklyTickets: Tickets programados
+        saleTracking: Líneas preparadas
+        services: Servicios
+        tracking: Estados
+        components: Componentes
+        pictures: Fotos
+        packages: Bultos
+    list:
+        nickname: Alias
+        state: Estado
+        shipped: Enviado
+        landed: Entregado
+        salesPerson: Comercial
+        total: Total
     card:
         customerId: ID cliente
         customerCard: Ficha del cliente
@@ -456,15 +576,11 @@ ticket:
         consigneeStreet: Dirección
     create:
         address: Dirección
-order:
-    field:
-        salesPersonFk: Comercial
-    form:
-        clientFk: Cliente
-        addressFk: Dirección
-        agencyModeFk: Agencia
-    list:
-        newOrder: Nuevo Pedido
+invoiceOut:
+    card:
+        issued: Fecha emisión
+        customerCard: Ficha del cliente
+        ticketList: Listado de tickets
     summary:
         issued: Fecha
         dued: Fecha límite
@@ -475,6 +591,71 @@ order:
         fee: Cuota
         tickets: Tickets
         totalWithVat: Importe
+    globalInvoices:
+        errors:
+            chooseValidClient: Selecciona un cliente válido
+            chooseValidCompany: Selecciona una empresa válida
+            chooseValidPrinter: Selecciona una impresora válida
+            chooseValidSerialType: Selecciona una tipo de serie válida
+            fillDates: La fecha de la factura y la fecha máxima deben estar completas
+            invoiceDateLessThanMaxDate: La fecha de la factura no puede ser menor que la fecha máxima
+            invoiceWithFutureDate: Existe una factura con una fecha futura
+            noTicketsToInvoice: No existen tickets para facturar
+            criticalInvoiceError: Error crítico en la facturación proceso detenido
+            invalidSerialTypeForAll: El tipo de serie debe ser global cuando se facturan todos los clientes
+        table:
+            addressId: Id dirección
+            streetAddress: Dirección fiscal
+        statusCard:
+            percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}'
+            pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs'
+    negativeBases:
+        clientId: Id cliente
+        base: Base
+        active: Activo
+        hasToInvoice: Facturar
+        verifiedData: Datos comprobados
+        comercial: Comercial
+        errors:
+            downloadCsvFailed: Error al descargar CSV
+order:
+    field:
+        salesPersonFk: Comercial
+    form:
+        clientFk: Cliente
+        addressFk: Dirección
+        agencyModeFk: Agencia
+    list:
+        newOrder: Nuevo Pedido
+    summary:
+        basket: Cesta
+        notConfirmed: No confirmada
+        created: Creado
+        createdFrom: Creado desde
+        address: Dirección
+        total: Total
+        vat: IVA
+        state: Estado
+        alias: Alias
+        items: Artículos
+        orderTicketList: Tickets del pedido
+        amount: Monto
+        confirm: Confirmar
+        confirmLines: Confirmar lineas
+shelving:
+    list:
+        parking: Parking
+        priority: Prioridad
+        newShelving: Nuevo Carro
+    summary:
+        recyclable: Reciclable
+parking:
+    pickingOrder: Orden de recogida
+    row: Fila
+    column: Columna
+    searchBar:
+        info: Puedes buscar por código de parking
+        label: Buscar parking...
 department:
     chat: Chat
     bossDepartment: Jefe de departamento
@@ -635,8 +816,8 @@ wagon:
         volumeNotEmpty: El volumen no puede estar vacío
         typeNotEmpty: El tipo no puede estar vacío
         maxTrays: Has alcanzado el número máximo de bandejas
-        minHeightBetweenTrays: 'La distancia mínima entre bandejas es '
-        maxWagonHeight: 'La altura máxima del vagón es '
+        minHeightBetweenTrays: La distancia mínima entre bandejas es
+        maxWagonHeight: La altura máxima del vagón es
         uncompleteTrays: Hay bandejas sin completar
     params:
         label: Etiqueta
@@ -653,7 +834,6 @@ supplier:
         tableVisibleColumns:
             nif: NIF/CIF
             account: Cuenta
-        
     summary:
         responsible: Responsable
         verified: Verificado
@@ -784,7 +964,7 @@ components:
     cardDescriptor:
         mainList: Listado principal
         summary: Resumen
-        moreOptions: 'Más opciones'
+        moreOptions: Más opciones
     leftMenu:
         addToPinned: Añadir a fijados
         removeFromPinned: Eliminar de fijados
diff --git a/src/pages/Account/Alias/Card/AliasDescriptor.vue b/src/pages/Account/Alias/Card/AliasDescriptor.vue
index a5793407e..671ef7fbc 100644
--- a/src/pages/Account/Alias/Card/AliasDescriptor.vue
+++ b/src/pages/Account/Alias/Card/AliasDescriptor.vue
@@ -51,7 +51,6 @@ const removeAlias = () => {
     <CardDescriptor
         ref="descriptor"
         :url="`MailAliases/${entityId}`"
-        module="Alias"
         data-key="Alias"
         title="alias"
     >
diff --git a/src/pages/Account/Card/AccountDescriptor.vue b/src/pages/Account/Card/AccountDescriptor.vue
index e354f694c..49328fe87 100644
--- a/src/pages/Account/Card/AccountDescriptor.vue
+++ b/src/pages/Account/Card/AccountDescriptor.vue
@@ -23,8 +23,7 @@ onMounted(async () => {
     <CardDescriptor
         ref="descriptor"
         :url="`VnUsers/preview`"
-        :filter="filter"
-        module="Account"
+        :filter="{ ...filter, where: { id: entityId } }"
         data-key="Account"
         title="nickname"
     >
diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue
index ab16e07ff..3b40f4224 100644
--- a/src/pages/Account/Card/AccountDescriptorMenu.vue
+++ b/src/pages/Account/Card/AccountDescriptorMenu.vue
@@ -12,6 +12,7 @@ import VnInputPassword from 'src/components/common/VnInputPassword.vue';
 import VnChangePassword from 'src/components/common/VnChangePassword.vue';
 import { useQuasar } from 'quasar';
 import { useRouter } from 'vue-router';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const $props = defineProps({
     hasAccount: {
@@ -121,18 +122,14 @@ onMounted(() => {
         :promise="sync"
     >
         <template #customHTML>
-            {{ shouldSyncPassword }}
-            <QCheckbox
-                :label="t('account.card.actions.sync.checkbox')"
+            <VnCheckbox
                 v-model="shouldSyncPassword"
-                class="full-width"
+                :label="t('account.card.actions.sync.checkbox')"
+                :info="t('account.card.actions.sync.tooltip')"
                 clearable
                 clear-icon="close"
-            >
-                <QIcon style="padding-left: 10px" color="primary" name="info" size="sm">
-                    <QTooltip>{{ t('account.card.actions.sync.tooltip') }}</QTooltip>
-                </QIcon></QCheckbox
-            >
+                color="primary"
+            />
             <VnInputPassword
                 v-if="shouldSyncPassword"
                 :label="t('login.password')"
diff --git a/src/pages/Account/Role/Card/RoleDescriptor.vue b/src/pages/Account/Role/Card/RoleDescriptor.vue
index dfcc8efc8..517517af0 100644
--- a/src/pages/Account/Role/Card/RoleDescriptor.vue
+++ b/src/pages/Account/Role/Card/RoleDescriptor.vue
@@ -35,7 +35,6 @@ const removeRole = async () => {
     <CardDescriptor
         url="VnRoles"
         :filter="{ where: { id: entityId } }"
-        module="Role"
         data-key="Role"
         :summary="$props.summary"
     >
diff --git a/src/pages/Claim/Card/ClaimDescriptor.vue b/src/pages/Claim/Card/ClaimDescriptor.vue
index f55b0c48b..4551c58fe 100644
--- a/src/pages/Claim/Card/ClaimDescriptor.vue
+++ b/src/pages/Claim/Card/ClaimDescriptor.vue
@@ -46,7 +46,6 @@ onMounted(async () => {
     <CardDescriptor
         :url="`Claims/${entityId}`"
         :filter="filter"
-        module="Claim"
         title="client.name"
         data-key="Claim"
     >
@@ -86,7 +85,7 @@ onMounted(async () => {
                     />
                 </template>
             </VnLv>
-            <VnLv :label="t('claim.zone')">
+            <VnLv v-if="entity.ticket?.zone?.id" :label="t('claim.zone')">
                 <template #value>
                     <span class="link">
                         {{ entity.ticket?.zone?.name }}
@@ -98,11 +97,10 @@ onMounted(async () => {
                 :label="t('claim.province')"
                 :value="entity.ticket?.address?.province?.name"
             />
-            <VnLv :label="t('claim.ticketId')">
+            <VnLv v-if="entity.ticketFk" :label="t('claim.ticketId')">
                 <template #value>
                     <span class="link">
                         {{ entity.ticketFk }}
-
                         <TicketDescriptorProxy :id="entity.ticketFk" />
                     </span>
                 </template>
diff --git a/src/pages/Claim/Card/ClaimNotes.vue b/src/pages/Claim/Card/ClaimNotes.vue
index 134ee33ab..cc6e33779 100644
--- a/src/pages/Claim/Card/ClaimNotes.vue
+++ b/src/pages/Claim/Card/ClaimNotes.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { computed } from 'vue';
+import { computed, useAttrs } from 'vue';
 import { useRoute } from 'vue-router';
 import { useState } from 'src/composables/useState';
 import VnNotes from 'src/components/ui/VnNotes.vue';
@@ -7,6 +7,7 @@ import VnNotes from 'src/components/ui/VnNotes.vue';
 const route = useRoute();
 const state = useState();
 const user = state.getUser();
+const $attrs = useAttrs();
 
 const $props = defineProps({
     id: { type: [Number, String], default: null },
diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue
index ba74ba212..c05583314 100644
--- a/src/pages/Claim/ClaimList.vue
+++ b/src/pages/Claim/ClaimList.vue
@@ -131,7 +131,7 @@ const STATE_COLOR = {
         prefix="claim"
         :array-data-props="{
             url: 'Claims/filter',
-            order: ['cs.priority ASC', 'created ASC'],
+            order: 'cs.priority ASC, created ASC',
         }"
     >
         <template #advanced-menu>
diff --git a/src/pages/Customer/Card/CustomerAddress.vue b/src/pages/Customer/Card/CustomerAddress.vue
index d8a1543cd..f1799d0cc 100644
--- a/src/pages/Customer/Card/CustomerAddress.vue
+++ b/src/pages/Customer/Card/CustomerAddress.vue
@@ -117,7 +117,7 @@ const toCustomerAddressEdit = (addressId) => {
         data-key="CustomerAddresses"
         order="id DESC"
         ref="vnPaginateRef"
-        :user-filter="addressFilter"
+        :filter="addressFilter"
         :url="`Clients/${route.params.id}/addresses`"
     />
     <div class="full-width flex justify-center">
@@ -189,11 +189,11 @@ const toCustomerAddressEdit = (addressId) => {
 
                     <QSeparator
                         class="q-mx-lg"
-                        v-if="item.observations.length"
+                        v-if="item?.observations?.length"
                         vertical
                     />
 
-                    <div v-if="item.observations.length">
+                    <div v-if="item?.observations?.length">
                         <div
                             :key="obIndex"
                             class="flex q-mb-sm"
diff --git a/src/pages/Customer/Card/CustomerConsumption.vue b/src/pages/Customer/Card/CustomerConsumption.vue
index 50750cf12..eef9d55b5 100644
--- a/src/pages/Customer/Card/CustomerConsumption.vue
+++ b/src/pages/Customer/Card/CustomerConsumption.vue
@@ -61,6 +61,23 @@ const columns = computed(() => [
         columnFilter: false,
         cardVisible: true,
     },
+    {
+        align: 'left',
+        name: 'buyerId',
+        label: t('customer.params.buyerId'),
+        component: 'select',
+        attrs: {
+            url: 'TicketRequests/getItemTypeWorker',
+            optionLabel: 'nickname',
+            optionValue: 'id',
+
+            fields: ['id', 'nickname'],
+            sortBy: ['nickname ASC'],
+            optionFilter: 'firstName',
+        },
+        cardVisible: false,
+        visible: false,
+    },
     {
         name: 'description',
         align: 'left',
@@ -74,6 +91,7 @@ const columns = computed(() => [
         name: 'quantity',
         label: t('globals.quantity'),
         cardVisible: true,
+        visible: true,
         columnFilter: {
             inWhere: true,
         },
@@ -138,11 +156,11 @@ const updateDateParams = (value, params) => {
     const campaign = campaignList.value.find((c) => c.id === value);
     if (!campaign) return;
 
-    const { dated, previousDays, scopeDays } = campaign;
-    const _date = new Date(dated);
-    const [from, to] = dateRange(_date);
-    params.from = new Date(from.setDate(from.getDate() - previousDays)).toISOString();
-    params.to = new Date(to.setDate(to.getDate() + scopeDays)).toISOString();
+    const { dated, scopeDays } = campaign;
+    const from = new Date(dated);
+    from.setDate(from.getDate() - scopeDays);
+    params.from = from;
+    params.to = dated;
     return params;
 };
 </script>
@@ -200,29 +218,62 @@ const updateDateParams = (value, params) => {
             <div v-if="row.subName" class="subName">
                 {{ row.subName }}
             </div>
-            <FetchedTags :item="row" :max-length="3" />
+            <FetchedTags :item="row" />
         </template>
         <template #moreFilterPanel="{ params }">
             <div class="column no-wrap flex-center q-gutter-y-md q-mt-xs q-pr-xl">
+                <VnSelect
+                    :filled="true"
+                    class="q-px-sm q-pt-none fit"
+                    url="ItemTypes"
+                    v-model="params.typeId"
+                    :label="t('item.list.typeName')"
+                    :fields="['id', 'name', 'categoryFk']"
+                    :include="'category'"
+                    :sortBy="'name ASC'"
+                    dense
+                    @update:model-value="(data) => updateDateParams(data, params)"
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
+                                <QItemLabel caption>{{
+                                    scope.opt?.category?.name
+                                }}</QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
+                <VnSelect
+                    :filled="true"
+                    class="q-px-sm q-pt-none fit"
+                    url="ItemCategories"
+                    v-model="params.categoryId"
+                    :label="t('item.list.category')"
+                    :fields="['id', 'name']"
+                    :sortBy="'name ASC'"
+                    dense
+                    @update:model-value="(data) => updateDateParams(data, params)"
+                />
                 <VnSelect
                     v-model="params.campaign"
                     :options="campaignList"
                     :label="t('globals.campaign')"
                     :filled="true"
                     class="q-px-sm q-pt-none fit"
-                    dense
-                    option-label="code"
+                    :option-label="(opt) => t(opt.code)"
+                    :fields="['id', 'code', 'dated', 'scopeDays']"
                     @update:model-value="(data) => updateDateParams(data, params)"
+                    dense
                 >
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
                             <QItemSection>
-                                <QItemLabel>
-                                    {{ scope.opt?.code }}
-                                    {{
-                                        new Date(scope.opt?.dated).getFullYear()
-                                    }}</QItemLabel
-                                >
+                                <QItemLabel> {{ t(scope.opt?.code) }} </QItemLabel>
+                                <QItemLabel caption>
+                                    {{ new Date(scope.opt?.dated).getFullYear() }}
+                                </QItemLabel>
                             </QItemSection>
                         </QItem>
                     </template>
@@ -247,7 +298,19 @@ const updateDateParams = (value, params) => {
 </template>
 
 <i18n>
+en:
+
+    valentinesDay: Valentine's Day
+    mothersDay: Mother's Day
+    allSaints: All Saints' Day
 es:
     Enter a new search: Introduce una nueva búsqueda
     Group by items: Agrupar por artículos
+    valentinesDay: Día de San Valentín
+    mothersDay: Día de la Madre
+    allSaints: Día de Todos los Santos
+    Campaign consumption: Consumo campaña
+    Campaign: Campaña
+    From: Desde
+    To: Hasta
 </i18n>
diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue
index a646ad299..89f9d9449 100644
--- a/src/pages/Customer/Card/CustomerDescriptor.vue
+++ b/src/pages/Customer/Card/CustomerDescriptor.vue
@@ -55,7 +55,6 @@ const debtWarning = computed(() => {
 
 <template>
     <CardDescriptor
-        module="Customer"
         :url="`Clients/${entityId}/getCard`"
         :summary="$props.summary"
         data-key="Customer"
@@ -110,7 +109,21 @@ const debtWarning = computed(() => {
                 >
                     <QTooltip>{{ t('customer.card.isDisabled') }}</QTooltip>
                 </QIcon>
-                <QIcon v-if="entity.isFreezed" name="vn:frozen" size="xs" color="primary">
+
+                <QIcon
+                    v-if="entity?.substitutionAllowed"
+                    name="help"
+                    size="xs"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('Allowed substitution') }}</QTooltip>
+                </QIcon>
+                <QIcon
+                    v-if="customer?.isFreezed"
+                    name="vn:frozen"
+                    size="xs"
+                    color="primary"
+                >
                     <QTooltip>{{ t('customer.card.isFrozen') }}</QTooltip>
                 </QIcon>
                 <QIcon
diff --git a/src/pages/Customer/Card/CustomerDescriptorMenu.vue b/src/pages/Customer/Card/CustomerDescriptorMenu.vue
index fb78eab69..aea45721c 100644
--- a/src/pages/Customer/Card/CustomerDescriptorMenu.vue
+++ b/src/pages/Customer/Card/CustomerDescriptorMenu.vue
@@ -61,6 +61,16 @@ const openCreateForm = (type) => {
         .join('&');
     useOpenURL(`/#/${type}/list?${params}`);
 };
+const updateSubstitutionAllowed = async () => {
+    try {
+        await axios.patch(`Clients/${route.params.id}`, {
+            substitutionAllowed: !$props.customer.substitutionAllowed,
+        });
+        notify('globals.notificationSent', 'positive');
+    } catch (error) {
+        notify(error.message, 'positive');
+    }
+};
 </script>
 
 <template>
@@ -69,6 +79,13 @@ const openCreateForm = (type) => {
             {{ t('globals.pageTitles.createTicket') }}
         </QItemSection>
     </QItem>
+    <QItem v-ripple clickable>
+        <QItemSection @click="updateSubstitutionAllowed()">{{
+            $props.customer.substitutionAllowed
+                ? t('Disable substitution')
+                : t('Allow substitution')
+        }}</QItemSection>
+    </QItem>
     <QItem v-ripple clickable>
         <QItemSection @click="showSmsDialog()">{{ t('Send SMS') }}</QItemSection>
     </QItem>
diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue
index b256c001a..bd887acb7 100644
--- a/src/pages/Customer/Card/CustomerFiscalData.vue
+++ b/src/pages/Customer/Card/CustomerFiscalData.vue
@@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnLocation from 'src/components/common/VnLocation.vue';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const { t } = useI18n();
 const route = useRoute();
@@ -110,14 +111,11 @@ function handleLocation(data, location) {
             </VnRow>
             <VnRow>
                 <QCheckbox :label="t('Has to invoice')" v-model="data.hasToInvoice" />
-                <div>
-                    <QCheckbox :label="t('globals.isVies')" v-model="data.isVies" />
-                    <QIcon name="info" class="cursor-info q-ml-sm" size="sm">
-                        <QTooltip>
-                            {{ t('whenActivatingIt') }}
-                        </QTooltip>
-                    </QIcon>
-                </div>
+                <VnCheckbox
+                    v-model="data.isVies"
+                    :label="t('globals.isVies')"
+                    :info="t('whenActivatingIt')"    
+                />
             </VnRow>
 
             <VnRow>
@@ -129,17 +127,11 @@ function handleLocation(data, location) {
             </VnRow>
 
             <VnRow>
-                <div>
-                    <QCheckbox
-                        :label="t('Is equalizated')"
-                        v-model="data.isEqualizated"
-                    />
-                    <QIcon class="cursor-info q-ml-sm" name="info" size="sm">
-                        <QTooltip>
-                            {{ t('inOrderToInvoice') }}
-                        </QTooltip>
-                    </QIcon>
-                </div>
+                <VnCheckbox                    
+                    v-model="data.isEqualizated"
+                    :label="t('Is equalizated')"
+                    :info="t('inOrderToInvoice')"
+                />
                 <QCheckbox :label="t('Daily invoice')" v-model="data.hasDailyInvoice" />
             </VnRow>
 
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index eae97d1be..21de8fa9b 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -1,4 +1,3 @@
-
 <script setup>
 import { useI18n } from 'vue-i18n';
 import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
@@ -52,11 +51,7 @@ const exprBuilder = (param, value) => {
             </QItem>
             <QItem class="q-mb-sm">
                 <QItemSection>
-                    <VnInput
-                        :label="t('globals.name')"
-                        v-model="params.name"
-                        is-outlined
-                    />
+                    <VnInput :label="t('Name')" v-model="params.name" is-outlined />
                 </QItemSection>
             </QItem>
             <QItem class="q-mb-sm">
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index 3c638b612..b8c1a743e 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -264,6 +264,7 @@ const columns = computed(() => [
         align: 'left',
         name: 'isActive',
         label: t('customer.summary.isActive'),
+        component: 'checkbox',
         chip: {
             color: null,
             condition: (value) => !value,
@@ -302,6 +303,7 @@ const columns = computed(() => [
         align: 'left',
         name: 'isFreezed',
         label: t('customer.extendedList.tableVisibleColumns.isFreezed'),
+        component: 'checkbox',
         chip: {
             color: null,
             condition: (value) => value,
@@ -419,7 +421,7 @@ function handleLocation(data, location) {
             <VnTable
                 ref="tableRef"
                 :data-key="dataKey"
-                url="Clients/filter"
+                url="Clients/extendedListFilter"
                 :create="{
                     urlCreate: 'Clients/createWithUser',
                     title: t('globals.pageTitles.customerCreate'),
diff --git a/src/pages/Customer/Defaulter/CustomerDefaulter.vue b/src/pages/Customer/Defaulter/CustomerDefaulter.vue
index eca2ad596..dc4ac9162 100644
--- a/src/pages/Customer/Defaulter/CustomerDefaulter.vue
+++ b/src/pages/Customer/Defaulter/CustomerDefaulter.vue
@@ -9,7 +9,7 @@ import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.v
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue';
-import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
 import VnTable from 'src/components/VnTable/VnTable.vue';
 import { useArrayData } from 'src/composables/useArrayData';
 
diff --git a/src/pages/Customer/components/CustomerNewPayment.vue b/src/pages/Customer/components/CustomerNewPayment.vue
index c2c38b55a..7f45cd7db 100644
--- a/src/pages/Customer/components/CustomerNewPayment.vue
+++ b/src/pages/Customer/components/CustomerNewPayment.vue
@@ -84,7 +84,7 @@ function setPaymentType(accounting) {
     viewReceipt.value = isCash.value;
     if (accountingType.value.daysInFuture)
         initialData.payed.setDate(
-            initialData.payed.getDate() + accountingType.value.daysInFuture
+            initialData.payed.getDate() + accountingType.value.daysInFuture,
         );
     maxAmount.value = accountingType.value && accountingType.value.maxAmount;
 
diff --git a/src/pages/Customer/locale/en.yml b/src/pages/Customer/locale/en.yml
index 118f04a31..b6d495335 100644
--- a/src/pages/Customer/locale/en.yml
+++ b/src/pages/Customer/locale/en.yml
@@ -107,6 +107,9 @@ customer:
         defaulterSinced: Defaulted Since
         hasRecovery: Has Recovery
         socialName: Social name
+        typeId: Type
+        buyerId: Buyer
+        categoryId: Category
         city: City
         phone: Phone
         postcode: Postcode
diff --git a/src/pages/Customer/locale/es.yml b/src/pages/Customer/locale/es.yml
index 7c33ffee8..f50d049da 100644
--- a/src/pages/Customer/locale/es.yml
+++ b/src/pages/Customer/locale/es.yml
@@ -108,6 +108,9 @@ customer:
         hasRecovery: Tiene recobro
         socialName: Razón social
         campaign: Campaña
+        typeId: Familia
+        buyerId: Comprador
+        categoryId: Reino
         city: Ciudad
         phone: Teléfono
         postcode: Código postal
diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue
index 689eea686..6462ed24a 100644
--- a/src/pages/Entry/Card/EntryBasicData.vue
+++ b/src/pages/Entry/Card/EntryBasicData.vue
@@ -1,30 +1,32 @@
 <script setup>
-import { ref } from 'vue';
+import { onMounted, ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { useRole } from 'src/composables/useRole';
+import { useState } from 'src/composables/useState';
+import { checkEntryLock } from 'src/composables/checkEntryLock';
 import FetchData from 'components/FetchData.vue';
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
-import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
-import FilterTravelForm from 'src/components/FilterTravelForm.vue';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
-import { toDate } from 'src/filters';
+import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
 import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
 
 const route = useRoute();
 const { t } = useI18n();
 const { hasAny } = useRole();
 const isAdministrative = () => hasAny(['administrative']);
+const state = useState();
+const user = state.getUser().fn();
 
 const companiesOptions = ref([]);
 const currenciesOptions = ref([]);
 
-const onFilterTravelSelected = (formData, id) => {
-    formData.travelFk = id;
-};
+onMounted(() => {
+    checkEntryLock(route.params.id, user.id);
+});
 </script>
 
 <template>
@@ -52,46 +54,24 @@ const onFilterTravelSelected = (formData, id) => {
     >
         <template #form="{ data }">
             <VnRow>
+                <VnSelectTravelExtended
+                    :data="data"
+                    v-model="data.travelFk"
+                    :onFilterTravelSelected="(data, result) => (data.travelFk = result)"
+                />
                 <VnSelectSupplier
                     v-model="data.supplierFk"
                     hide-selected
                     :required="true"
-                    map-options
                 />
-                <VnSelectDialog
-                    :label="t('entry.basicData.travel')"
-                    v-model="data.travelFk"
-                    url="Travels/filter"
-                    :fields="['id', 'warehouseInName']"
-                    option-value="id"
-                    option-label="warehouseInName"
-                    map-options
-                    hide-selected
-                    :required="true"
-                    action-icon="filter_alt"
-                >
-                    <template #form>
-                        <FilterTravelForm
-                            @travel-selected="onFilterTravelSelected(data, $event)"
-                        />
-                    </template>
-                    <template #option="scope">
-                        <QItem v-bind="scope.itemProps">
-                            <QItemSection>
-                                <QItemLabel>
-                                    {{ scope.opt?.agencyModeName }} -
-                                    {{ scope.opt?.warehouseInName }}
-                                    ({{ toDate(scope.opt?.shipped) }}) →
-                                    {{ scope.opt?.warehouseOutName }}
-                                    ({{ toDate(scope.opt?.landed) }})
-                                </QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template>
-                </VnSelectDialog>
             </VnRow>
             <VnRow>
                 <VnInput v-model="data.reference" :label="t('globals.reference')" />
+                <VnInputNumber
+                    v-model="data.invoiceAmount"
+                    :label="t('entry.summary.invoiceAmount')"
+                    :positive="false"
+                />
             </VnRow>
             <VnRow>
                 <VnInput
@@ -113,8 +93,7 @@ const onFilterTravelSelected = (formData, id) => {
                 <VnInputNumber
                     :label="t('entry.summary.commission')"
                     v-model="data.commission"
-                    step="1"
-                    autofocus
+                    :step="1"
                     :positive="false"
                 />
                 <VnSelect
@@ -161,7 +140,7 @@ const onFilterTravelSelected = (formData, id) => {
                     :label="t('entry.summary.excludedFromAvailable')"
                 />
                 <QCheckbox
-                    v-if="isAdministrative()"
+                    :disable="!isAdministrative()"
                     v-model="data.isBooked"
                     :label="t('entry.basicData.booked')"
                 />
diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue
index 6194ce5b8..e159c5356 100644
--- a/src/pages/Entry/Card/EntryBuys.vue
+++ b/src/pages/Entry/Card/EntryBuys.vue
@@ -1,478 +1,799 @@
 <script setup>
-import { ref, computed } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
+import { useStateStore } from 'stores/useStateStore';
+import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { QBtn } from 'quasar';
+import { onMounted, ref } from 'vue';
 
-import VnPaginate from 'src/components/ui/VnPaginate.vue';
-import VnSelect from 'components/common/VnSelect.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import FetchedTags from 'components/ui/FetchedTags.vue';
-import VnConfirm from 'components/ui/VnConfirm.vue';
+import { useState } from 'src/composables/useState';
+
+import FetchData from 'src/components/FetchData.vue';
+import VnTable from 'src/components/VnTable/VnTable.vue';
 import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
-import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
-
-import { useQuasar } from 'quasar';
-import { toCurrency } from 'src/filters';
+import FetchedTags from 'src/components/ui/FetchedTags.vue';
+import VnColor from 'src/components/common/VnColor.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import ItemDescriptor from 'src/pages/Item/Card/ItemDescriptor.vue';
 import axios from 'axios';
-import useNotify from 'src/composables/useNotify.js';
+import VnSelectEnum from 'src/components/common/VnSelectEnum.vue';
+import { checkEntryLock } from 'src/composables/checkEntryLock';
+import SkeletonDescriptor from 'src/components/ui/SkeletonDescriptor.vue';
 
-const quasar = useQuasar();
-const route = useRoute();
-const router = useRouter();
-const { t } = useI18n();
-const { notify } = useNotify();
-
-const rowsSelected = ref([]);
-const entryBuysPaginateRef = ref(null);
-const originalRowDataCopy = ref(null);
-
-const getInputEvents = (colField, props) => {
-    return colField === 'packagingFk'
-        ? { 'update:modelValue': () => saveChange(colField, props) }
-        : {
-              'keyup.enter': () => saveChange(colField, props),
-              blur: () => saveChange(colField, props),
-          };
-};
-
-const tableColumnComponents = computed(() => ({
-    item: {
-        component: QBtn,
-        props: {
-            color: 'primary',
-            flat: true,
-        },
-        event: () => ({}),
+const $props = defineProps({
+    id: {
+        type: Number,
+        default: null,
     },
-    quantity: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            class: 'input-number',
-            dense: true,
-        },
-        event: getInputEvents,
+    editableMode: {
+        type: Boolean,
+        default: true,
     },
-    packagingFk: {
-        component: VnSelect,
-        props: {
-            'option-value': 'id',
-            'option-label': 'id',
-            'emit-value': true,
-            'map-options': true,
-            'use-input': true,
-            'hide-selected': true,
-            url: 'Packagings',
-            fields: ['id'],
-            where: { freightItemFk: true },
-            'sort-by': 'id ASC',
-            dense: true,
-        },
-        event: getInputEvents,
+    tableHeight: {
+        type: String,
+        default: null,
     },
-    stickers: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            class: 'input-number',
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    printedStickers: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            class: 'input-number',
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    weight: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    packing: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    grouping: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    buyingValue: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    price2: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    price3: {
-        component: VnInput,
-        props: {
-            type: 'number',
-            min: 0,
-            dense: true,
-        },
-        event: getInputEvents,
-    },
-    import: {
-        component: 'span',
-        props: {},
-        event: () => ({}),
-    },
-}));
-
-const entriesTableColumns = computed(() => {
-    return [
-        {
-            label: t('globals.item'),
-            field: 'itemFk',
-            name: 'item',
-            align: 'left',
-        },
-        {
-            label: t('globals.quantity'),
-            field: 'quantity',
-            name: 'quantity',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.package'),
-            field: 'packagingFk',
-            name: 'packagingFk',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.stickers'),
-            field: 'stickers',
-            name: 'stickers',
-            align: 'left',
-        },
-        {
-            label: t('entry.buys.printedStickers'),
-            field: 'printedStickers',
-            name: 'printedStickers',
-            align: 'left',
-        },
-        {
-            label: t('globals.weight'),
-            field: 'weight',
-            name: 'weight',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.packing'),
-            field: 'packing',
-            name: 'packing',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.grouping'),
-            field: 'grouping',
-            name: 'grouping',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.buyingValue'),
-            field: 'buyingValue',
-            name: 'buyingValue',
-            align: 'left',
-            format: (value) => toCurrency(value),
-        },
-        {
-            label: t('item.fixedPrice.groupingPrice'),
-            field: 'price2',
-            name: 'price2',
-            align: 'left',
-        },
-        {
-            label: t('item.fixedPrice.packingPrice'),
-            field: 'price3',
-            name: 'price3',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.import'),
-            name: 'import',
-            align: 'left',
-            format: (_, row) => toCurrency(row.buyingValue * row.quantity),
-        },
-    ];
 });
 
-const copyOriginalRowsData = (rows) => {
-    originalRowDataCopy.value = JSON.parse(JSON.stringify(rows));
-};
-
-const saveChange = async (field, { rowIndex, row }) => {
-    if (originalRowDataCopy.value[rowIndex][field] == row[field]) return;
-    await axios.patch(`Buys/${row.id}`, row);
-    originalRowDataCopy.value[rowIndex][field] = row[field];
-};
-
-const openRemoveDialog = async () => {
-    quasar
-        .dialog({
-            component: VnConfirm,
-            componentProps: {
-                title: t('Confirm deletion'),
-                message: t(
-                    `Are you sure you want to delete this buy${
-                        rowsSelected.value.length > 1 ? 's' : ''
-                    }?`
-                ),
-                data: rowsSelected.value,
+const state = useState();
+const user = state.getUser().fn();
+const stateStore = useStateStore();
+const { t } = useI18n();
+const route = useRoute();
+const selectedRows = ref([]);
+const entityId = ref($props.id ?? route.params.id);
+const entryBuysRef = ref();
+const footerFetchDataRef = ref();
+const footer = ref({});
+const columns = [
+    {
+        align: 'center',
+        labelAbbreviation: 'NV',
+        label: t('Ignore'),
+        toolTip: t('Ignored for available'),
+        name: 'isIgnored',
+        component: 'checkbox',
+        attrs: {
+            toggleIndeterminate: false,
+        },
+        create: true,
+        width: '25px',
+    },
+    {
+        label: t('Buyer'),
+        name: 'workerFk',
+        component: 'select',
+        attrs: {
+            url: 'Workers/search',
+            fields: ['id', 'nickname'],
+            optionLabel: 'nickname',
+            optionValue: 'id',
+        },
+        visible: false,
+    },
+    {
+        label: t('Family'),
+        name: 'itemTypeFk',
+        component: 'select',
+        attrs: {
+            url: 'itemTypes',
+            fields: ['id', 'name'],
+            optionLabel: 'name',
+            optionValue: 'id',
+        },
+        visible: false,
+    },
+    {
+        name: 'id',
+        isId: true,
+        visible: false,
+        isEditable: false,
+        columnFilter: false,
+    },
+    {
+        name: 'entryFk',
+        isId: true,
+        visible: false,
+        isEditable: false,
+        disable: true,
+        create: true,
+        columnFilter: false,
+    },
+    {
+        align: 'center',
+        label: 'Id',
+        name: 'itemFk',
+        component: 'number',
+        isEditable: false,
+        width: '40px',
+    },
+    {
+        labelAbbreviation: '',
+        label: 'Color',
+        name: 'hex',
+        columnSearch: false,
+        isEditable: false,
+        width: '5px',
+        component: 'select',
+        attrs: {
+            url: 'Inks',
+            fields: ['id', 'name'],
+        },
+    },
+    {
+        align: 'center',
+        label: t('Article'),
+        name: 'name',
+        component: 'select',
+        attrs: {
+            url: 'Items',
+            fields: ['id', 'name'],
+            optionLabel: 'name',
+            optionValue: 'id',
+        },
+        width: '85px',
+        isEditable: false,
+    },
+    {
+        align: 'center',
+        label: t('Article'),
+        name: 'itemFk',
+        visible: false,
+        create: true,
+        columnFilter: false,
+    },
+    {
+        align: 'center',
+        labelAbbreviation: t('Siz.'),
+        label: t('Size'),
+        toolTip: t('Size'),
+        component: 'number',
+        name: 'size',
+        width: '35px',
+        isEditable: false,
+        style: () => {
+            return { color: 'var(--vn-label-color)' };
+        },
+    },
+    {
+        align: 'center',
+        labelAbbreviation: t('Sti.'),
+        label: t('Stickers'),
+        toolTip: t('Printed Stickers/Stickers'),
+        name: 'stickers',
+        component: 'input',
+        create: true,
+        attrs: {
+            positive: false,
+        },
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                row['quantity'] = value * row['packing'];
+                row['amount'] = row['quantity'] * row['buyingValue'];
             },
-        })
-        .onOk(async () => {
-            await deleteBuys();
-            const notifyMessage = t(
-                `Buy${rowsSelected.value.length > 1 ? 's' : ''} deleted`
-            );
-            notify(notifyMessage, 'positive');
-        });
-};
+        },
+        width: '35px',
+    },
+    {
+        align: 'center',
+        label: t('Bucket'),
+        name: 'packagingFk',
+        component: 'select',
+        attrs: {
+            url: 'packagings',
+            fields: ['id'],
+            optionLabel: 'id',
+        },
+        create: true,
+        width: '40px',
+    },
+    {
+        align: 'center',
+        label: 'Kg',
+        name: 'weight',
+        component: 'number',
+        create: true,
+        width: '35px',
+        format: (row, dashIfEmpty) => parseFloat(row['weight']).toFixed(1),
+    },
+    {
+        labelAbbreviation: 'P',
+        label: 'Packing',
+        toolTip: 'Packing',
+        name: 'packing',
+        component: 'number',
+        create: true,
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                const oldPacking = oldValue === 1 || oldValue === null ? 1 : oldValue;
+                row['weight'] = (row['weight'] * value) / oldPacking;
+                row['quantity'] = row['stickers'] * value;
+                row['amount'] = row['quantity'] * row['buyingValue'];
+            },
+        },
+        width: '20px',
+        style: (row) => {
+            if (row.groupingMode === 'grouping')
+                return { color: 'var(--vn-label-color)' };
+        },
+    },
+    {
+        labelAbbreviation: 'GM',
+        label: t('Grouping selector'),
+        toolTip: t('Grouping selector'),
+        name: 'groupingMode',
+        component: 'toggle',
+        attrs: {
+            'toggle-indeterminate': true,
+            trueValue: 'grouping',
+            falseValue: 'packing',
+            indeterminateValue: null,
+        },
+        size: 'xs',
+        width: '25px',
+        create: true,
+        rightFilter: false,
+        getIcon: (value) => {
+            switch (value) {
+                case 'grouping':
+                    return 'toggle_on';
+                case 'packing':
+                    return 'toggle_off';
+                default:
+                    return 'minimize';
+            }
+        },
+    },
+    {
+        align: 'center',
+        labelAbbreviation: 'G',
+        label: 'Grouping',
+        toolTip: 'Grouping',
+        name: 'grouping',
+        component: 'number',
+        width: '20px',
+        create: true,
+        style: (row) => {
+            if (row.groupingMode === 'packing') return { color: 'var(--vn-label-color)' };
+        },
+    },
+    {
+        align: 'center',
+        label: t('Quantity'),
+        name: 'quantity',
+        component: 'number',
+        attrs: {
+            positive: false,
+        },
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                row['amount'] = value * row['buyingValue'];
+            },
+        },
+        width: '45px',
+        create: true,
+        style: getQuantityStyle,
+    },
+    {
+        align: 'center',
+        labelAbbreviation: t('Cost'),
+        label: t('Buying value'),
+        toolTip: t('Buying value'),
+        name: 'buyingValue',
+        create: true,
+        component: 'number',
+        attrs: {
+            positive: false,
+        },
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                row['amount'] = row['quantity'] * value;
+            },
+        },
+        width: '45px',
+        format: (row) => parseFloat(row['buyingValue']).toFixed(3),
+    },
+    {
+        align: 'center',
+        label: t('Amount'),
+        name: 'amount',
+        width: '45px',
+        component: 'number',
+        attrs: {
+            positive: false,
+        },
+        isEditable: false,
+        format: (row) => parseFloat(row['amount']).toFixed(2),
+        style: getAmountStyle,
+    },
+    {
+        align: 'center',
+        labelAbbreviation: t('Pack.'),
+        label: t('Package'),
+        toolTip: t('Package'),
+        name: 'price2',
+        component: 'number',
+        width: '35px',
+        create: true,
+        format: (row) => parseFloat(row['price2']).toFixed(2),
+    },
+    {
+        align: 'center',
+        label: t('Box'),
+        name: 'price3',
+        component: 'number',
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                row['price2'] = row['price2'] * (value / oldValue);
+            },
+        },
+        width: '35px',
+        create: true,
+        format: (row) => parseFloat(row['price3']).toFixed(2),
+    },
+    {
+        align: 'center',
+        labelAbbreviation: 'Min.',
+        label: t('Minimum price'),
+        toolTip: t('Minimum price'),
+        name: 'minPrice',
+        component: 'number',
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                await axios.patch(`Items/${row['itemFk']}`, {
+                    minPrice: value,
+                });
+            },
+        },
+        width: '35px',
+        style: (row) => {
+            if (!row?.hasMinPrice) return { color: 'var(--vn-label-color)' };
+        },
+        format: (row) => parseFloat(row['minPrice']).toFixed(2),
+    },
+    {
+        align: 'center',
+        labelAbbreviation: 'CM',
+        label: t('Check min price'),
+        toolTip: t('Check min price'),
+        name: 'hasMinPrice',
+        attrs: {
+            toggleIndeterminate: false,
+        },
+        component: 'checkbox',
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                await axios.patch(`Items/${row['itemFk']}`, {
+                    hasMinPrice: value,
+                });
+            },
+        },
+        width: '25px',
+    },
+    {
+        align: 'center',
+        labelAbbreviation: t('P.Sen'),
+        label: t('Packing sent'),
+        toolTip: t('Packing sent'),
+        name: 'packingOut',
+        component: 'number',
+        isEditable: false,
+        width: '40px',
+    },
+    {
+        align: 'center',
+        labelAbbreviation: t('Com.'),
+        label: t('Comment'),
+        toolTip: t('Comment'),
+        name: 'comment',
+        component: 'input',
+        isEditable: false,
+        width: '50px',
+    },
+    {
+        align: 'center',
+        labelAbbreviation: 'Prod.',
+        label: t('Producer'),
+        toolTip: t('Producer'),
+        name: 'subName',
+        isEditable: false,
+        width: '45px',
+        style: () => {
+            return { color: 'var(--vn-label-color)' };
+        },
+    },
+    {
+        align: 'center',
+        label: t('Tags'),
+        name: 'tags',
+        width: '125px',
+        columnSearch: false,
+    },
+    {
+        align: 'center',
+        labelAbbreviation: 'Comp.',
+        label: t('Company'),
+        toolTip: t('Company'),
+        name: 'company_name',
+        component: 'input',
+        isEditable: false,
+        width: '35px',
+    },
+];
 
-const deleteBuys = async () => {
-    await axios.post('Buys/deleteBuys', { buys: rowsSelected.value });
-    entryBuysPaginateRef.value.fetch();
-};
+function getQuantityStyle(row) {
+    if (row?.quantity !== row?.stickers * row?.packing)
+        return { color: 'var(--q-negative)' };
+}
+function getAmountStyle(row) {
+    if (row?.isChecked) return { color: 'var(--q-positive)' };
+    return { color: 'var(--vn-label-color)' };
+}
 
-const importBuys = () => {
-    router.push({ name: 'EntryBuysImport' });
-};
+async function beforeSave(data, getChanges) {
+    try {
+        const changes = data.updates;
+        if (!changes) return data;
+        const patchPromises = [];
 
-const toggleGroupingMode = async (buy, mode) => {
-    const groupingMode = mode === 'grouping' ? mode : 'packing';
-    const newGroupingMode = buy.groupingMode === groupingMode ? null : groupingMode;
-    const params = {
-        groupingMode: newGroupingMode,
-    };
-    await axios.patch(`Buys/${buy.id}`, params);
-    buy.groupingMode = newGroupingMode;
-};
+        for (const change of changes) {
+            let patchData = {};
 
-const lockIconType = (groupingMode, mode) => {
-    if (mode === 'packing') {
-        return groupingMode === 'packing' ? 'lock' : 'lock_open';
-    } else {
-        return groupingMode === 'grouping' ? 'lock' : 'lock_open';
+            if ('hasMinPrice' in change.data) {
+                patchData.hasMinPrice = change.data?.hasMinPrice;
+                delete change.data.hasMinPrice;
+            }
+            if ('minPrice' in change.data) {
+                patchData.minPrice = change.data?.minPrice;
+                delete change.data.minPrice;
+            }
+
+            if (Object.keys(patchData).length > 0) {
+                const promise = axios
+                    .get('Buys/findOne', {
+                        params: {
+                            filter: {
+                                fields: ['itemFk'],
+                                where: { id: change.where.id },
+                            },
+                        },
+                    })
+                    .then((buy) => {
+                        return axios.patch(`Items/${buy.data.itemFk}`, patchData);
+                    })
+                    .catch((error) => {
+                        console.error('Error processing change: ', change, error);
+                    });
+
+                patchPromises.push(promise);
+            }
+        }
+
+        await Promise.all(patchPromises);
+
+        data.updates = changes.filter((change) => Object.keys(change.data).length > 0);
+
+        return data;
+    } catch (error) {
+        console.error('Error in beforeSave:', error);
+        throw error;
     }
-};
+}
+
+function invertQuantitySign(rows, sign) {
+    for (const row of rows) {
+        if (sign > 0) row.quantity = Math.abs(row.quantity);
+        else if (row.quantity > 0) row.quantity = -row.quantity;
+    }
+}
+function setIsChecked(rows, value) {
+    for (const row of rows) {
+        row.isChecked = value;
+    }
+    footerFetchDataRef.value.fetch();
+}
+
+async function setBuyUltimate(itemFk, data) {
+    if (!itemFk) return;
+    const buyUltimate = await axios.get(`Entries/getBuyUltimate`, {
+        params: {
+            itemFk,
+            warehouseFk: user.warehouseFk,
+            date: Date.vnNew(),
+        },
+    });
+    const buyUltimateData = buyUltimate.data[0];
+
+    const allowedKeys = columns
+        .filter((col) => col.create === true)
+        .map((col) => col.name);
+
+    allowedKeys.forEach((key) => {
+        if (buyUltimateData.hasOwnProperty(key) && key !== 'entryFk') {
+            data[key] = buyUltimateData[key];
+        }
+    });
+}
+
+onMounted(() => {
+    stateStore.rightDrawer = false;
+    if ($props.editableMode) checkEntryLock(entityId.value, user.id);
+});
 </script>
-
 <template>
-    <VnSubToolbar>
-        <template #st-actions>
-            <QBtnGroup push style="column-gap: 10px">
-                <slot name="moreBeforeActions" />
-                <QBtn
-                    :label="t('globals.remove')"
-                    color="primary"
-                    icon="delete"
-                    flat
-                    @click="openRemoveDialog()"
-                    :disable="!rowsSelected?.length"
-                    :title="t('globals.remove')"
-                />
-            </QBtnGroup>
-        </template>
-    </VnSubToolbar>
-    <VnPaginate
-        ref="entryBuysPaginateRef"
-        data-key="EntryBuys"
-        :url="`Entries/${route.params.id}/getBuys`"
-        @on-fetch="copyOriginalRowsData($event)"
-        auto-load
-    >
-        <template #body="{ rows }">
-            <QTable
-                :rows="rows"
-                :columns="entriesTableColumns"
-                selection="multiple"
-                row-key="id"
-                class="full-width q-mt-md"
-                :grid="$q.screen.lt.md"
-                v-model:selected="rowsSelected"
-                :no-data-label="t('globals.noResults')"
+    <Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown() && editableMode">
+        <QBtnGroup push style="column-gap: 1px">
+            <QBtnDropdown
+                label="+/-"
+                color="primary"
+                flat
+                :title="t('Invert quantity value')"
+                :disable="!selectedRows.length"
+                data-cy="change-quantity-sign"
             >
-                <template #body="props">
-                    <QTr>
-                        <QTd>
-                            <QCheckbox v-model="props.selected" />
-                        </QTd>
-                        <QTd
-                            v-for="col in props.cols"
-                            :key="col.name"
-                            style="max-width: 100px"
-                        >
-                            <component
-                                :is="tableColumnComponents[col.name].component"
-                                v-bind="tableColumnComponents[col.name].props"
-                                v-model="props.row[col.field]"
-                                v-on="
-                                    tableColumnComponents[col.name].event(
-                                        col.field,
-                                        props
-                                    )
-                                "
+                <QList>
+                    <QItem>
+                        <QItemSection>
+                            <QBtn
+                                flat
+                                @click="invertQuantitySign(selectedRows, -1)"
+                                data-cy="set-negative-quantity"
                             >
-                                <template
-                                    v-if="
-                                        col.name === 'grouping' || col.name === 'packing'
-                                    "
-                                    #append
-                                >
-                                    <QBtn
-                                        :icon="
-                                            lockIconType(props.row.groupingMode, col.name)
-                                        "
-                                        @click="toggleGroupingMode(props.row, col.name)"
-                                        class="cursor-pointer"
-                                        size="sm"
-                                        flat
-                                        dense
-                                        unelevated
-                                        push
-                                        :style="{
-                                            'font-variation-settings': `'FILL' ${
-                                                lockIconType(
-                                                    props.row.groupingMode,
-                                                    col.name
-                                                ) === 'lock'
-                                                    ? 1
-                                                    : 0
-                                            }`,
-                                        }"
-                                    />
-                                </template>
-                                <template
-                                    v-if="col.name === 'item' || col.name === 'import'"
-                                >
-                                    {{ col.value }}
-                                </template>
-                                <ItemDescriptorProxy
-                                    v-if="col.name === 'item'"
-                                    :id="props.row.item.id"
-                                />
-                            </component>
-                        </QTd>
-                    </QTr>
-                    <QTr no-hover class="full-width infoRow" style="column-span: all">
-                        <QTd />
-                        <QTd cols>
-                            <span>{{ props.row.item.itemType.code }}</span>
-                        </QTd>
-                        <QTd>
-                            <span>{{ props.row.item.size }}</span>
-                        </QTd>
-                        <QTd>
-                            <span>{{ toCurrency(props.row.item.minPrice) }}</span>
-                        </QTd>
-                        <QTd colspan="7">
-                            <span>{{ props.row.item.concept }}</span>
-                            <span v-if="props.row.item.subName" class="subName">
-                                {{ props.row.item.subName }}
-                            </span>
-                            <FetchedTags :item="props.row.item" />
-                        </QTd>
-                    </QTr>
-                </template>
-                <template #item="props">
-                    <div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
-                        <QCard bordered flat>
-                            <QCardSection>
-                                <QCheckbox v-model="props.selected" dense />
-                            </QCardSection>
-                            <QSeparator />
-                            <QList dense>
-                                <QItem v-for="col in props.cols" :key="col.name">
-                                    <component
-                                        :is="tableColumnComponents[col.name].component"
-                                        v-bind="tableColumnComponents[col.name].props"
-                                        v-model="props.row[col.field]"
-                                        v-on="
-                                            tableColumnComponents[col.name].event(
-                                                col.field,
-                                                props
-                                            )
-                                        "
-                                        class="full-width"
-                                    >
-                                        <template
-                                            v-if="
-                                                col.name === 'item' ||
-                                                col.name === 'import'
-                                            "
-                                        >
-                                            {{ col.label + ': ' + col.value }}
-                                        </template>
-                                    </component>
-                                </QItem>
-                            </QList>
-                        </QCard>
-                    </div>
-                </template>
-            </QTable>
+                                <span style="font-size: large">-</span>
+                            </QBtn>
+                        </QItemSection>
+                    </QItem>
+                    <QItem>
+                        <QItemSection>
+                            <QBtn
+                                flat
+                                @click="invertQuantitySign(selectedRows, 1)"
+                                data-cy="set-positive-quantity"
+                            >
+                                <span style="font-size: large">+</span>
+                            </QBtn>
+                        </QItemSection>
+                    </QItem>
+                </QList>
+            </QBtnDropdown>
+            <QBtnDropdown
+                icon="price_check"
+                color="primary"
+                flat
+                :title="t('Check buy amount')"
+                :disable="!selectedRows.length"
+                data-cy="check-buy-amount"
+            >
+                <QList>
+                    <QItem>
+                        <QItemSection>
+                            <QBtn
+                                size="sm"
+                                icon="check"
+                                flat
+                                @click="setIsChecked(selectedRows, true)"
+                                data-cy="check-amount"
+                            />
+                        </QItemSection>
+                    </QItem>
+                    <QItem>
+                        <QItemSection>
+                            <QBtn
+                                size="sm"
+                                icon="close"
+                                flat
+                                @click="setIsChecked(selectedRows, false)"
+                                data-cy="uncheck-amount"
+                            />
+                        </QItemSection>
+                    </QItem>
+                </QList>
+            </QBtnDropdown>
+        </QBtnGroup>
+    </Teleport>
+    <FetchData
+        ref="footerFetchDataRef"
+        :url="`Entries/${entityId}/getBuyList`"
+        :params="{ groupBy: 'GROUP BY b.entryFk' }"
+        @on-fetch="(data) => (footer = data[0])"
+        auto-load
+    />
+    <VnTable
+        ref="entryBuysRef"
+        data-key="EntryBuys"
+        :url="`Entries/${entityId}/getBuyList`"
+        order="name DESC"
+        save-url="Buys/crud"
+        :disable-option="{ card: true }"
+        v-model:selected="selectedRows"
+        @on-fetch="() => footerFetchDataRef.fetch()"
+        :table="
+            editableMode
+                ? {
+                      'row-key': 'id',
+                      selection: 'multiple',
+                  }
+                : {}
+        "
+        :create="
+            editableMode
+                ? {
+                      urlCreate: 'Buys',
+                      title: t('Create buy'),
+                      onDataSaved: () => {
+                          entryBuysRef.reload();
+                      },
+                      formInitialData: { entryFk: entityId, isIgnored: false },
+                      showSaveAndContinueBtn: true,
+                  }
+                : null
+        "
+        :create-complement="{
+            isFullWidth: true,
+            containerStyle: {
+                display: 'flex',
+                'flex-wrap': 'wrap',
+                gap: '16px',
+                position: 'relative',
+                height: '450px',
+            },
+            columnGridStyle: {
+                'max-width': '50%',
+                flex: 1,
+                'margin-right': '30px',
+            },
+        }"
+        :is-editable="editableMode"
+        :without-header="!editableMode"
+        :with-filters="editableMode"
+        :right-search="editableMode"
+        :row-click="false"
+        :columns="columns"
+        :beforeSaveFn="beforeSave"
+        class="buyList"
+        :table-height="$props.tableHeight ?? '84vh'"
+        auto-load
+        footer
+        data-cy="entry-buys"
+    >
+        <template #column-hex="{ row }">
+            <VnColor :colors="row?.hexJson" style="height: 100%; min-width: 2000px" />
         </template>
-    </VnPaginate>
-
-    <QPageSticky :offset="[20, 20]">
-        <QBtn fab icon="upload" color="primary" @click="importBuys()" />
-        <QTooltip class="text-no-wrap">
-            {{ t('Import buys') }}
-        </QTooltip>
-    </QPageSticky>
+        <template #column-name="{ row }">
+            <span class="link">
+                {{ row?.name }}
+                <ItemDescriptorProxy :id="row?.itemFk" />
+            </span>
+        </template>
+        <template #column-tags="{ row }">
+            <FetchedTags :item="row" :columns="3" />
+        </template>
+        <template #column-stickers="{ row }">
+            <span :class="editableMode ? 'editable-text' : ''">
+                <span style="color: var(--vn-label-color)">
+                    {{ row.printedStickers }}
+                </span>
+                <span>/{{ row.stickers }}</span>
+            </span>
+        </template>
+        <template #column-footer-stickers>
+            <div>
+                <span style="color: var(--vn-label-color)">
+                    {{ footer?.printedStickers }}</span
+                >
+                <span>/</span>
+                <span data-cy="footer-stickers">{{ footer?.stickers }}</span>
+            </div>
+        </template>
+        <template #column-footer-weight>
+            {{ footer?.weight }}
+        </template>
+        <template #column-footer-quantity>
+            <span :style="getQuantityStyle(footer)" data-cy="footer-quantity">
+                {{ footer?.quantity }}
+            </span>
+        </template>
+        <template #column-footer-amount>
+            <span :style="getAmountStyle(footer)" data-cy="footer-amount">
+                {{ footer?.amount }}
+            </span>
+        </template>
+        <template #column-create-itemFk="{ data }">
+            <VnSelect
+                url="Items/search"
+                v-model="data.itemFk"
+                :label="t('Article')"
+                :fields="['id', 'name', 'size', 'producerName']"
+                :filter-options="['id', 'name', 'size', 'producerName']"
+                option-label="name"
+                option-value="id"
+                @update:modelValue="
+                    async (value) => {
+                        await setBuyUltimate(value, data);
+                    }
+                "
+                :required="true"
+                data-cy="itemFk-create-popup"
+                sort-by="nickname DESC"
+            >
+                <template #option="scope">
+                    <QItem v-bind="scope.itemProps">
+                        <QItemSection>
+                            <QItemLabel>
+                                {{ scope.opt.name }}
+                            </QItemLabel>
+                            <QItemLabel caption>
+                                #{{ scope.opt.id }}, {{ scope.opt?.size }},
+                                {{ scope.opt?.producerName }}
+                            </QItemLabel>
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
+        </template>
+        <template #column-create-groupingMode="{ data }">
+            <VnSelectEnum
+                :label="t('Grouping mode')"
+                v-model="data.groupingMode"
+                schema="vn"
+                table="buy"
+                column="groupingMode"
+                option-value="groupingMode"
+                option-label="groupingMode"
+            />
+        </template>
+        <template #previous-create-dialog="{ data }">
+            <div
+                style="position: absolute"
+                :class="{ 'centered-container': !data.itemFk }"
+            >
+                <ItemDescriptor :id="data.itemFk" v-if="data.itemFk" />
+                <div v-else>
+                    <span>{{ t('globals.noData') }}</span>
+                </div>
+            </div>
+        </template>
+    </VnTable>
 </template>
-
-<style lang="scss" scoped>
-.q-table--horizontal-separator tbody tr:nth-child(odd) > td {
-    border-bottom-width: 0px;
-    border-top-width: 2px;
-    border-color: var(--vn-text-color);
-}
-.infoRow > td {
-    color: var(--vn-label-color);
-}
-</style>
-
 <i18n>
 es:
-    Import buys: Importar compras
-    Buy deleted: Compra eliminada
-    Buys deleted: Compras eliminadas
-    Confirm deletion: Confirmar eliminación
-    Are you sure you want to delete this buy?: Seguro que quieres eliminar esta compra?
-    Are you sure you want to delete this buys?: Seguro que quieres eliminar estas compras?
+    Article: Artículo
+    Siz.: Med.
+    Size: Medida
+    Sti.: Eti.
+    Bucket: Cubo
+    Quantity: Cantidad
+    Amount: Importe
+    Pack.: Paq.
+    Package: Paquete
+    Box: Caja
+    P.Sen: P.Env
+    Packing sent: Packing envíos
+    Com.: Ref.
+    Comment: Referencia
+    Minimum price: Precio mínimo
+    Stickers: Etiquetas
+    Printed Stickers/Stickers: Etiquetas impresas/Etiquetas
+    Cost: Cost.
+    Buying value: Coste
+    Producer: Productor
+    Company: Compañia
+    Tags: Etiquetas
+    Grouping mode: Modo de agrupación
+    C.min: P.min
+    Ignore: Ignorar
+    Ignored for available: Ignorado para disponible
+    Grouping selector: Selector de grouping
+    Check min price: Marcar precio mínimo
+    Create buy: Crear compra
+    Invert quantity value: Invertir valor de cantidad
+    Check buy amount: Marcar como correcta la cantidad de compra
 </i18n>
+<style lang="scss" scoped>
+.centered-container {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    position: absolute;
+    width: 40%;
+    height: 100%;
+}
+</style>
diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue
index 19d13e51a..69b300cb2 100644
--- a/src/pages/Entry/Card/EntryDescriptor.vue
+++ b/src/pages/Entry/Card/EntryDescriptor.vue
@@ -1,12 +1,19 @@
 <script setup>
 import { ref, computed, onMounted } from 'vue';
-import { useRoute } from 'vue-router';
+import { useRoute, useRouter } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import CardDescriptor from 'components/ui/CardDescriptor.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
 import { toDate } from 'src/filters';
 import { getUrl } from 'src/composables/getUrl';
-import EntryDescriptorMenu from './EntryDescriptorMenu.vue';
+import { useQuasar } from 'quasar';
+import { usePrintService } from 'composables/usePrintService';
+import CardDescriptor from 'components/ui/CardDescriptor.vue';
+import VnLv from 'src/components/ui/VnLv.vue';
+import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
+import axios from 'axios';
+
+const quasar = useQuasar();
+const { push } = useRouter();
+const { openReport } = usePrintService();
 
 const $props = defineProps({
     id: {
@@ -83,12 +90,63 @@ const getEntryRedirectionFilter = (entry) => {
         to,
     });
 };
+
+function showEntryReport() {
+    openReport(`Entries/${entityId.value}/entry-order-pdf`);
+}
+
+function showNotification(type, message) {
+    quasar.notify({
+        type: type,
+        message: t(message),
+    });
+}
+
+async function recalculateRates(entity) {
+    try {
+        const entryConfig = await axios.get('EntryConfigs/findOne');
+        if (entryConfig.data?.inventorySupplierFk === entity.supplierFk) {
+            showNotification(
+                'negative',
+                'Cannot recalculate prices because this is an inventory entry',
+            );
+            return;
+        }
+
+        await axios.post(`Entries/${entityId.value}/recalcEntryPrices`);
+        showNotification('positive', 'Entry prices recalculated');
+    } catch (error) {
+        showNotification('negative', 'Failed to recalculate rates');
+        console.error(error);
+    }
+}
+
+async function cloneEntry() {
+    try {
+        const response = await axios.post(`Entries/${entityId.value}/cloneEntry`);
+        push({ path: `/entry/${response.data}` });
+        showNotification('positive', 'Entry cloned');
+    } catch (error) {
+        showNotification('negative', 'Failed to clone entry');
+        console.error(error);
+    }
+}
+
+async function deleteEntry() {
+    try {
+        await axios.post(`Entries/${entityId.value}/deleteEntry`);
+        push({ path: `/entry/list` });
+        showNotification('positive', 'Entry deleted');
+    } catch (error) {
+        showNotification('negative', 'Failed to delete entry');
+        console.error(error);
+    }
+}
 </script>
 
 <template>
     <CardDescriptor
         ref="entryDescriptorRef"
-        module="Entry"
         :url="`Entries/${entityId}`"
         :userFilter="entryFilter"
         title="supplier.nickname"
@@ -96,15 +154,56 @@ const getEntryRedirectionFilter = (entry) => {
         width="lg-width"
     >
         <template #menu="{ entity }">
-            <EntryDescriptorMenu :id="entity.id" />
+            <QItem
+                v-ripple
+                clickable
+                @click="showEntryReport(entity)"
+                data-cy="show-entry-report"
+            >
+                <QItemSection>{{ t('Show entry report') }}</QItemSection>
+            </QItem>
+            <QItem
+                v-ripple
+                clickable
+                @click="recalculateRates(entity)"
+                data-cy="recalculate-rates"
+            >
+                <QItemSection>{{ t('Recalculate rates') }}</QItemSection>
+            </QItem>
+            <QItem v-ripple clickable @click="cloneEntry(entity)" data-cy="clone-entry">
+                <QItemSection>{{ t('Clone') }}</QItemSection>
+            </QItem>
+            <QItem v-ripple clickable @click="deleteEntry(entity)" data-cy="delete-entry">
+                <QItemSection>{{ t('Delete') }}</QItemSection>
+            </QItem>
         </template>
         <template #body="{ entity }">
-            <VnLv :label="t('globals.agency')" :value="entity.travel?.agency?.name" />
-            <VnLv :label="t('shipped')" :value="toDate(entity.travel?.shipped)" />
-            <VnLv :label="t('landed')" :value="toDate(entity.travel?.landed)" />
+            <VnLv :label="t('Travel')">
+                <template #value>
+                    <span class="link" v-if="entity?.travelFk">
+                        {{ entity.travel?.agency?.name }}
+                        {{ entity.travel?.warehouseOut?.code }} &rarr;
+                        {{ entity.travel?.warehouseIn?.code }}
+                        <TravelDescriptorProxy :id="entity?.travelFk" />
+                    </span>
+                </template>
+            </VnLv>
             <VnLv
-                :label="t('globals.warehouseOut')"
-                :value="entity.travel?.warehouseOut?.name"
+                :label="t('entry.summary.travelShipped')"
+                :value="toDate(entity.travel?.shipped)"
+            />
+            <VnLv
+                :label="t('entry.summary.travelLanded')"
+                :value="toDate(entity.travel?.landed)"
+            />
+            <VnLv :label="t('entry.summary.currency')" :value="entity?.currency?.code" />
+            <VnLv
+                :label="t('entry.summary.invoiceAmount')"
+                :value="entity?.invoiceAmount"
+            />
+            <VnLv
+                :label="t('entry.summary.entryType')"
+                :value="entity?.entryType?.description"
             />
         </template>
         <template #icons="{ entity }">
@@ -131,6 +230,14 @@ const getEntryRedirectionFilter = (entry) => {
                         }}</QTooltip
                     >
                 </QIcon>
+                <QIcon
+                    v-if="!entity?.travelFk"
+                    name="vn:deletedTicket"
+                    size="xs"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('This entry is deleted') }}</QTooltip>
+                </QIcon>
             </QCardActions>
         </template>
         <template #actions="{ entity }">
@@ -143,21 +250,6 @@ const getEntryRedirectionFilter = (entry) => {
                 >
                     <QTooltip>{{ t('Supplier card') }}</QTooltip>
                 </QBtn>
-                <QBtn
-                    :to="{
-                        name: 'TravelMain',
-                        query: {
-                            params: JSON.stringify({
-                                agencyModeFk: entity.travel?.agencyModeFk,
-                            }),
-                        },
-                    }"
-                    size="md"
-                    icon="local_airport"
-                    color="primary"
-                >
-                    <QTooltip>{{ t('All travels with current agency') }}</QTooltip>
-                </QBtn>
                 <QBtn
                     :to="{
                         name: 'EntryMain',
@@ -177,10 +269,24 @@ const getEntryRedirectionFilter = (entry) => {
 </template>
 <i18n>
 es:
+    Travel: Envío
     Supplier card: Ficha del proveedor
     All travels with current agency: Todos los envíos con la agencia actual
     All entries with current supplier: Todas las entradas con el proveedor actual
     Show entry report: Ver informe del pedido
     Inventory entry: Es inventario
     Virtual entry: Es una redada
+    shipped: Enviado
+    landed: Recibido
+    This entry is deleted: Esta entrada está eliminada
+    Cannot recalculate prices because this is an inventory entry: No se pueden recalcular los precios porque es una entrada de inventario
+    Entry deleted: Entrada eliminada
+    Entry cloned: Entrada clonada
+    Entry prices recalculated: Precios de la entrada recalculados
+    Failed to recalculate rates: No se pudieron recalcular las tarifas
+    Failed to clone entry: No se pudo clonar la entrada
+    Failed to delete entry: No se pudo eliminar la entrada
+    Recalculate rates: Recalcular tarifas
+    Clone: Clonar
+    Delete: Eliminar
 </i18n>
diff --git a/src/pages/Entry/Card/EntryDescriptorMenu.vue b/src/pages/Entry/Card/EntryDescriptorMenu.vue
index 03cd53358..dc759c7a8 100644
--- a/src/pages/Entry/Card/EntryDescriptorMenu.vue
+++ b/src/pages/Entry/Card/EntryDescriptorMenu.vue
@@ -54,8 +54,8 @@ const transferEntry = async () => {
 <i18n>
 en:
     transferEntryDialog: The entries will be transferred to the next day
-    transferEntry: Transfer Entry
+    transferEntry: Partial delay
 es:
     transferEntryDialog: Se van a transferir las compras al dia siguiente
-    transferEntry: Transferir Entrada
+    transferEntry: Retraso parcial
 </i18n>
diff --git a/src/pages/Entry/Card/EntryFilter.js b/src/pages/Entry/Card/EntryFilter.js
index 3ff62cf27..d9fd1c2be 100644
--- a/src/pages/Entry/Card/EntryFilter.js
+++ b/src/pages/Entry/Card/EntryFilter.js
@@ -9,6 +9,7 @@ export default {
                     'shipped',
                     'agencyModeFk',
                     'warehouseOutFk',
+                    'warehouseInFk',
                     'daysInForward',
                 ],
                 include: [
@@ -21,13 +22,13 @@ export default {
                     {
                         relation: 'warehouseOut',
                         scope: {
-                            fields: ['name'],
+                            fields: ['name', 'code'],
                         },
                     },
                     {
                         relation: 'warehouseIn',
                         scope: {
-                            fields: ['name'],
+                            fields: ['name', 'code'],
                         },
                     },
                 ],
@@ -39,5 +40,17 @@ export default {
                 fields: ['id', 'nickname'],
             },
         },
+        {
+            relation: 'currency',
+            scope: {
+                fields: ['id', 'code'],
+            },
+        },
+        {
+            relation: 'entryType',
+            scope: {
+                fields: ['code', 'description'],
+            },
+        },
     ],
 };
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index 8c46fb6e6..c40e2ba46 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -2,19 +2,17 @@
 import { onMounted, ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
+import { toDate } from 'src/filters';
+import { getUrl } from 'src/composables/getUrl';
+import axios from 'axios';
 
 import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
-
-import { toDate, toCurrency, toCelsius } from 'src/filters';
-import { getUrl } from 'src/composables/getUrl';
-import axios from 'axios';
-import FetchedTags from 'src/components/ui/FetchedTags.vue';
-import VnToSummary from 'src/components/ui/VnToSummary.vue';
-import EntryDescriptorMenu from './EntryDescriptorMenu.vue';
-import VnRow from 'src/components/ui/VnRow.vue';
+import EntryBuys from './EntryBuys.vue';
 import VnTitle from 'src/components/common/VnTitle.vue';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
+import VnToSummary from 'src/components/ui/VnToSummary.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -33,117 +31,6 @@ const entry = ref();
 const entryBuys = ref([]);
 const entryUrl = ref();
 
-onMounted(async () => {
-    entryUrl.value = (await getUrl('entry/')) + entityId.value;
-});
-
-const tableColumnComponents = {
-    quantity: {
-        component: () => 'span',
-        props: () => {},
-    },
-    stickers: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-    packagingFk: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-    weight: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-    packing: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-    grouping: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-    buyingValue: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-    amount: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-    pvp: {
-        component: () => 'span',
-        props: () => {},
-        event: () => {},
-    },
-};
-
-const entriesTableColumns = computed(() => {
-    return [
-        {
-            label: t('globals.quantity'),
-            field: 'quantity',
-            name: 'quantity',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.stickers'),
-            field: 'stickers',
-            name: 'stickers',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.package'),
-            field: 'packagingFk',
-            name: 'packagingFk',
-            align: 'left',
-        },
-        {
-            label: t('globals.weight'),
-            field: 'weight',
-            name: 'weight',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.packing'),
-            field: 'packing',
-            name: 'packing',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.grouping'),
-            field: 'grouping',
-            name: 'grouping',
-            align: 'left',
-        },
-        {
-            label: t('entry.summary.buyingValue'),
-            field: 'buyingValue',
-            name: 'buyingValue',
-            align: 'left',
-            format: (value) => toCurrency(value),
-        },
-        {
-            label: t('entry.summary.import'),
-            name: 'amount',
-            align: 'left',
-            format: (_, row) => toCurrency(row.buyingValue * row.quantity),
-        },
-        {
-            label: t('entry.summary.pvp'),
-            name: 'pvp',
-            align: 'left',
-            format: (_, row) => toCurrency(row.price2) + ' / ' + toCurrency(row.price3),
-        },
-    ];
-});
-
 async function setEntryData(data) {
     if (data) entry.value = data;
     await fetchEntryBuys();
@@ -153,14 +40,18 @@ const fetchEntryBuys = async () => {
     const { data } = await axios.get(`Entries/${entry.value.id}/getBuys`);
     if (data) entryBuys.value = data;
 };
-</script>
 
+onMounted(async () => {
+    entryUrl.value = (await getUrl('entry/')) + entityId.value;
+});
+</script>
 <template>
     <CardSummary
         ref="summaryRef"
         :url="`Entries/${entityId}/getEntry`"
         @on-fetch="(data) => setEntryData(data)"
         data-key="EntrySummary"
+        data-cy="entry-summary"
     >
         <template #header-left>
             <VnToSummary
@@ -173,159 +64,154 @@ const fetchEntryBuys = async () => {
         <template #header>
             <span>{{ entry.id }} - {{ entry.supplier.nickname }}</span>
         </template>
-        <template #menu="{ entity }">
-            <EntryDescriptorMenu :id="entity.id" />
-        </template>
         <template #body>
             <QCard class="vn-one">
                 <VnTitle
                     :url="`#/entry/${entityId}/basic-data`"
                     :text="t('globals.summary.basicData')"
                 />
-                <VnLv :label="t('entry.summary.commission')" :value="entry.commission" />
-                <VnLv
-                    :label="t('entry.summary.currency')"
-                    :value="entry.currency?.name"
-                />
-                <VnLv :label="t('globals.company')" :value="entry.company.code" />
-                <VnLv :label="t('globals.reference')" :value="entry.reference" />
-                <VnLv
-                    :label="t('entry.summary.invoiceNumber')"
-                    :value="entry.invoiceNumber"
-                />
-                <VnLv
-                    :label="t('entry.basicData.initialTemperature')"
-                    :value="toCelsius(entry.initialTemperature)"
-                />
-                <VnLv
-                    :label="t('entry.basicData.finalTemperature')"
-                    :value="toCelsius(entry.finalTemperature)"
-                />
+                <div class="card-group">
+                    <div class="card-content">
+                        <VnLv
+                            :label="t('entry.summary.commission')"
+                            :value="entry?.commission"
+                        />
+                        <VnLv
+                            :label="t('entry.summary.currency')"
+                            :value="entry?.currency?.name"
+                        />
+                        <VnLv
+                            :label="t('globals.company')"
+                            :value="entry?.company?.code"
+                        />
+                        <VnLv :label="t('globals.reference')" :value="entry?.reference" />
+                        <VnLv
+                            :label="t('entry.summary.invoiceNumber')"
+                            :value="entry?.invoiceNumber"
+                        />
+                    </div>
+                    <div class="card-content">
+                        <VnCheckbox
+                            :label="t('entry.summary.ordered')"
+                            v-model="entry.isOrdered"
+                            :disable="true"
+                            size="xs"
+                        />
+                        <VnCheckbox
+                            :label="t('globals.confirmed')"
+                            v-model="entry.isConfirmed"
+                            :disable="true"
+                            size="xs"
+                        />
+                        <VnCheckbox
+                            :label="t('entry.summary.booked')"
+                            v-model="entry.isBooked"
+                            :disable="true"
+                            size="xs"
+                        />
+                        <VnCheckbox
+                            :label="t('entry.summary.excludedFromAvailable')"
+                            v-model="entry.isExcludedFromAvailable"
+                            :disable="true"
+                            size="xs"
+                        />
+                    </div>
+                </div>
             </QCard>
-            <QCard class="vn-one">
+            <QCard class="vn-one" v-if="entry?.travelFk">
                 <VnTitle
-                    :url="`#/entry/${entityId}/basic-data`"
-                    :text="t('globals.summary.basicData')"
+                    :url="`#/travel/${entry.travel.id}/summary`"
+                    :text="t('Travel')"
                 />
-                <VnLv :label="t('entry.summary.travelReference')">
-                    <template #value>
-                        <span class="link">
-                            {{ entry.travel.ref }}
-                            <TravelDescriptorProxy :id="entry.travel.id" />
-                        </span>
-                    </template>
-                </VnLv>
-                <VnLv
-                    :label="t('entry.summary.travelAgency')"
-                    :value="entry.travel.agency?.name"
-                />
-                <VnLv
-                    :label="t('globals.shipped')"
-                    :value="toDate(entry.travel.shipped)"
-                />
-                <VnLv
-                    :label="t('globals.warehouseOut')"
-                    :value="entry.travel.warehouseOut?.name"
-                />
-                <VnLv
-                    :label="t('entry.summary.travelDelivered')"
-                    :value="entry.travel.isDelivered"
-                />
-                <VnLv :label="t('globals.landed')" :value="toDate(entry.travel.landed)" />
-                <VnLv
-                    :label="t('globals.warehouseIn')"
-                    :value="entry.travel.warehouseIn?.name"
-                />
-                <VnLv
-                    :label="t('entry.summary.travelReceived')"
-                    :value="entry.travel.isReceived"
-                />
-            </QCard>
-            <QCard class="vn-one">
-                <VnTitle :url="`#/travel/${entityId}/summary`" :text="t('Travel data')" />
-                <VnRow class="block">
-                    <VnLv :label="t('entry.summary.ordered')" :value="entry.isOrdered" />
-                    <VnLv :label="t('globals.confirmed')" :value="entry.isConfirmed" />
-                    <VnLv :label="t('entry.summary.booked')" :value="entry.isBooked" />
-                    <VnLv
-                        :label="t('entry.summary.excludedFromAvailable')"
-                        :value="entry.isExcludedFromAvailable"
-                    />
-                </VnRow>
+                <div class="card-group">
+                    <div class="card-content">
+                        <VnLv :label="t('entry.summary.travelReference')">
+                            <template #value>
+                                <span class="link">
+                                    {{ entry.travel.ref }}
+                                    <TravelDescriptorProxy :id="entry.travel.id" />
+                                </span>
+                            </template>
+                        </VnLv>
+                        <VnLv
+                            :label="t('entry.summary.travelAgency')"
+                            :value="entry.travel.agency?.name"
+                        />
+                        <VnLv
+                            :label="t('entry.summary.travelShipped')"
+                            :value="toDate(entry.travel.shipped)"
+                        />
+                        <VnLv
+                            :label="t('globals.warehouseOut')"
+                            :value="entry.travel.warehouseOut?.name"
+                        />
+                        <VnLv
+                            :label="t('entry.summary.travelLanded')"
+                            :value="toDate(entry.travel.landed)"
+                        />
+                        <VnLv
+                            :label="t('globals.warehouseIn')"
+                            :value="entry.travel.warehouseIn?.name"
+                        />
+                    </div>
+                    <div class="card-content">
+                        <VnCheckbox
+                            :label="t('entry.summary.travelDelivered')"
+                            v-model="entry.travel.isDelivered"
+                            :disable="true"
+                            size="xs"
+                        />
+                        <VnCheckbox
+                            :label="t('entry.summary.travelReceived')"
+                            v-model="entry.travel.isReceived"
+                            :disable="true"
+                            size="xs"
+                        />
+                    </div>
+                </div>
             </QCard>
             <QCard class="vn-max">
                 <VnTitle
                     :url="`#/entry/${entityId}/buys`"
                     :text="t('entry.summary.buys')"
                 />
-                <QTable
-                    :rows="entryBuys"
-                    :columns="entriesTableColumns"
-                    row-key="index"
-                    class="full-width q-mt-md"
-                    :no-data-label="t('globals.noResults')"
-                >
-                    <template #body="{ cols, row, rowIndex }">
-                        <QTr no-hover>
-                            <QTd v-for="col in cols" :key="col?.name">
-                                <component
-                                    :is="tableColumnComponents[col?.name].component()"
-                                    v-bind="tableColumnComponents[col?.name].props()"
-                                    @click="tableColumnComponents[col?.name].event()"
-                                    class="col-content"
-                                >
-                                    <template
-                                        v-if="
-                                            col?.name !== 'observation' &&
-                                            col?.name !== 'isConfirmed'
-                                        "
-                                        >{{ col.value }}</template
-                                    >
-                                    <QTooltip v-if="col.toolTip">{{
-                                        col.toolTip
-                                    }}</QTooltip>
-                                </component>
-                            </QTd>
-                        </QTr>
-                        <QTr no-hover>
-                            <QTd>
-                                <span>{{ row.item.itemType.code }}</span>
-                            </QTd>
-                            <QTd>
-                                <span>{{ row.item.id }}</span>
-                            </QTd>
-                            <QTd>
-                                <span>{{ row.item.size }}</span>
-                            </QTd>
-                            <QTd>
-                                <span>{{ toCurrency(row.item.minPrice) }}</span>
-                            </QTd>
-                            <QTd colspan="6">
-                                <span>{{ row.item.concept }}</span>
-                                <span v-if="row.item.subName" class="subName">
-                                    {{ row.item.subName }}
-                                </span>
-                                <FetchedTags :item="row.item" />
-                            </QTd>
-                        </QTr>
-                        <!-- Esta última row es utilizada para agregar un espaciado y así marcar una diferencia visual entre los diferentes buys -->
-                        <QTr v-if="rowIndex !== entryBuys.length - 1">
-                            <QTd colspan="10" class="vn-table-separation-row" />
-                        </QTr>
-                    </template>
-                </QTable>
+                <EntryBuys
+                    v-if="entityId"
+                    :id="Number(entityId)"
+                    :editable-mode="false"
+                    table-height="49vh"
+                />
             </QCard>
         </template>
     </CardSummary>
 </template>
-
 <style lang="scss" scoped>
-.separation-row {
-    background-color: var(--vn-section-color) !important;
+.card-group {
+    display: flex;
+    flex-direction: column;
+}
+
+.card-content {
+    display: flex;
+    flex-direction: column;
+    text-overflow: ellipsis;
+    > div {
+        max-height: 24px;
+    }
+}
+
+@media (min-width: 1010px) {
+    .card-group {
+        flex-direction: row;
+    }
+    .card-content {
+        flex: 1;
+        margin-right: 16px;
+    }
 }
 </style>
-
 <i18n>
 es:
-    Travel data: Datos envío
+    Travel: Envío
+    InvoiceIn data: Datos factura
 </i18n>
diff --git a/src/pages/Entry/EntryFilter.vue b/src/pages/Entry/EntryFilter.vue
index 0f632c0ef..8c60918a8 100644
--- a/src/pages/Entry/EntryFilter.vue
+++ b/src/pages/Entry/EntryFilter.vue
@@ -19,6 +19,7 @@ const props = defineProps({
 
 const currenciesOptions = ref([]);
 const companiesOptions = ref([]);
+const entryFilterPanel = ref();
 </script>
 
 <template>
@@ -38,7 +39,7 @@ const companiesOptions = ref([]);
         @on-fetch="(data) => (currenciesOptions = data)"
         auto-load
     />
-    <VnFilterPanel :data-key="props.dataKey" :search-button="true">
+    <VnFilterPanel ref="entryFilterPanel" :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
                 <strong>{{ t(`entryFilter.params.${tag.label}`) }}: </strong>
@@ -48,70 +49,65 @@ const companiesOptions = ref([]);
         <template #body="{ params, searchFn }">
             <QItem>
                 <QItemSection>
-                    <VnInput
-                        v-model="params.search"
-                        :label="t('entryFilter.params.search')"
-                        is-outlined
-                    />
+                    <QCheckbox
+                        :label="t('params.isExcludedFromAvailable')"
+                        v-model="params.isExcludedFromAvailable"
+                        toggle-indeterminate
+                    >
+                        <QTooltip>
+                            {{ t('params.isExcludedFromAvailable') }}
+                        </QTooltip>
+                    </QCheckbox>
+                </QItemSection>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('params.isOrdered')"
+                        v-model="params.isOrdered"
+                        toggle-indeterminate
+                    >
+                        <QTooltip>
+                            {{ t('entry.list.tableVisibleColumns.isOrdered') }}
+                        </QTooltip>
+                    </QCheckbox>
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInput
-                        v-model="params.reference"
-                        :label="t('entryFilter.params.reference')"
-                        is-outlined
-                    />
+                    <QCheckbox
+                        :label="t('params.isReceived')"
+                        v-model="params.isReceived"
+                        toggle-indeterminate
+                    >
+                        <QTooltip>
+                            {{ t('entry.list.tableVisibleColumns.isReceived') }}
+                        </QTooltip>
+                    </QCheckbox>
+                </QItemSection>
+                <QItemSection>
+                    <QCheckbox
+                        :label="t('entry.list.tableVisibleColumns.isConfirmed')"
+                        v-model="params.isConfirmed"
+                        toggle-indeterminate
+                    >
+                        <QTooltip>
+                            {{ t('entry.list.tableVisibleColumns.isConfirmed') }}
+                        </QTooltip>
+                    </QCheckbox>
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInput
-                        v-model="params.invoiceNumber"
-                        :label="t('entryFilter.params.invoiceNumber')"
-                        is-outlined
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnInput
-                        v-model="params.travelFk"
-                        :label="t('entryFilter.params.travelFk')"
-                        is-outlined
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnSelect
-                        :label="t('entryFilter.params.companyFk')"
-                        v-model="params.companyFk"
+                    <VnInputDate
+                        :label="t('params.landed')"
+                        v-model="params.landed"
                         @update:model-value="searchFn()"
-                        :options="companiesOptions"
-                        option-value="id"
-                        option-label="code"
-                        hide-selected
-                        dense
-                        outlined
-                        rounded
+                        is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnSelect
-                        :label="t('entryFilter.params.currencyFk')"
-                        v-model="params.currencyFk"
-                        @update:model-value="searchFn()"
-                        :options="currenciesOptions"
-                        option-value="id"
-                        option-label="name"
-                        hide-selected
-                        dense
-                        outlined
-                        rounded
-                    />
+                    <VnInput v-model="params.id" label="Id" is-outlined />
                 </QItemSection>
             </QItem>
             <QItem>
@@ -125,62 +121,165 @@ const companiesOptions = ref([]);
                         rounded
                     />
                 </QItemSection>
-            </QItem>
-            <QItem>
                 <QItemSection>
-                    <VnInputDate
-                        :label="t('entryFilter.params.created')"
-                        v-model="params.created"
-                        @update:model-value="searchFn()"
+                    <VnInput
+                        v-model="params.invoiceNumber"
+                        :label="t('params.invoiceNumber')"
                         is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInputDate
-                        :label="t('entryFilter.params.from')"
-                        v-model="params.from"
-                        @update:model-value="searchFn()"
+                    <VnInput
+                        v-model="params.reference"
+                        :label="t('entry.list.tableVisibleColumns.reference')"
                         is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInputDate
-                        :label="t('entryFilter.params.to')"
-                        v-model="params.to"
+                    <VnSelect
+                        :label="t('params.agencyModeId')"
+                        v-model="params.agencyModeId"
                         @update:model-value="searchFn()"
+                        url="AgencyModes"
+                        :fields="['id', 'name']"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.evaNotes"
+                        :label="t('params.evaNotes')"
                         is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <QCheckbox
-                        :label="t('entryFilter.params.isBooked')"
-                        v-model="params.isBooked"
-                        toggle-indeterminate
-                    />
-                </QItemSection>
-                <QItemSection>
-                    <QCheckbox
-                        :label="t('entryFilter.params.isConfirmed')"
-                        v-model="params.isConfirmed"
-                        toggle-indeterminate
+                    <VnSelect
+                        :label="t('params.warehouseOutFk')"
+                        v-model="params.warehouseOutFk"
+                        @update:model-value="searchFn()"
+                        url="Warehouses"
+                        :fields="['id', 'name']"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <QCheckbox
-                        :label="t('entryFilter.params.isOrdered')"
-                        v-model="params.isOrdered"
-                        toggle-indeterminate
+                    <VnSelect
+                        :label="t('params.warehouseInFk')"
+                        v-model="params.warehouseInFk"
+                        @update:model-value="searchFn()"
+                        url="Warehouses"
+                        :fields="['id', 'name']"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    >
+                        <template #option="scope">
+                            <QItem v-bind="scope.itemProps">
+                                <QItemSection>
+                                    <QItemLabel>
+                                        {{ scope.opt?.name }}
+                                    </QItemLabel>
+                                    <QItemLabel caption>
+                                        {{ `#${scope.opt?.id} , ${scope.opt?.nickname}` }}
+                                    </QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.invoiceNumber"
+                        :label="t('params.invoiceNumber')"
+                        is-outlined
+                    />
+                </QItemSection>
+            </QItem>
+
+            <QItem>
+                <QItemSection>
+                    <VnSelect
+                        :label="t('params.entryTypeCode')"
+                        v-model="params.entryTypeCode"
+                        @update:model-value="searchFn()"
+                        url="EntryTypes"
+                        :fields="['code', 'description']"
+                        option-value="code"
+                        option-label="description"
+                        hide-selected
+                        dense
+                        outlined
+                        rounded
+                    />
+                </QItemSection>
+            </QItem>
+            <QItem>
+                <QItemSection>
+                    <VnInput
+                        v-model="params.evaNotes"
+                        :label="t('params.evaNotes')"
+                        is-outlined
                     />
                 </QItemSection>
             </QItem>
         </template>
     </VnFilterPanel>
 </template>
+
+<i18n>
+en:
+    params:
+        isExcludedFromAvailable: Inventory
+        isOrdered: Ordered
+        isReceived: Received
+        isConfirmed: Confirmed
+        isRaid: Raid
+        landed: Date
+        id: Id
+        supplierFk: Supplier
+        invoiceNumber: Invoice number
+        reference: Ref/Alb/Guide
+        agencyModeId: Agency mode
+        evaNotes: Notes
+        warehouseOutFk: Origin
+        warehouseInFk: Destiny
+        entryTypeCode: Entry type
+        hasToShowDeletedEntries: Show deleted entries
+es:
+    params:
+        isExcludedFromAvailable: Inventario
+        isOrdered: Pedida
+        isConfirmed: Confirmado
+        isReceived: Recibida
+        isRaid: Raid
+        landed: Fecha
+        id: Id
+        supplierFk: Proveedor
+        invoiceNumber: Núm. factura
+        reference: Ref/Alb/Guía
+        agencyModeId: Modo agencia
+        evaNotes: Notas
+        warehouseOutFk: Origen
+        warehouseInFk: Destino
+        entryTypeCode: Tipo de entrada
+        hasToShowDeletedEntries: Mostrar entradas eliminadas
+</i18n>
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index 3172c6d0e..845d65604 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -1,21 +1,25 @@
 <script setup>
+import axios from 'axios';
+import VnSection from 'src/components/common/VnSection.vue';
 import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
+import { useState } from 'src/composables/useState';
+import { onBeforeMount } from 'vue';
+
 import EntryFilter from './EntryFilter.vue';
 import VnTable from 'components/VnTable/VnTable.vue';
-import { toCelsius, toDate } from 'src/filters';
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import EntrySummary from './Card/EntrySummary.vue';
 import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
-import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
-import VnSection from 'src/components/common/VnSection.vue';
+import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
+import { toDate } from 'src/filters';
 
 const { t } = useI18n();
 const tableRef = ref();
+const defaultEntry = ref({});
+const state = useState();
+const user = state.getUser();
 const dataKey = 'EntryList';
 
-const { viewSummary } = useSummaryDialog();
-const entryFilter = {
+const entryQueryFilter = {
     include: [
         {
             relation: 'suppliers',
@@ -40,44 +44,53 @@ const entryFilter = {
 
 const columns = computed(() => [
     {
-        name: 'status',
-        columnFilter: false,
+        label: 'Ex',
+        toolTip: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
+        name: 'isExcludedFromAvailable',
+        component: 'checkbox',
+        width: '35px',
+    },
+    {
+        label: 'Pe',
+        toolTip: t('entry.list.tableVisibleColumns.isOrdered'),
+        name: 'isOrdered',
+        component: 'checkbox',
+        width: '35px',
+    },
+    {
+        label: 'Le',
+        toolTip: t('entry.list.tableVisibleColumns.isConfirmed'),
+        name: 'isConfirmed',
+        component: 'checkbox',
+        width: '35px',
+    },
+    {
+        label: 'Re',
+        toolTip: t('entry.list.tableVisibleColumns.isReceived'),
+        name: 'isReceived',
+        component: 'checkbox',
+        width: '35px',
+    },
+    {
+        label: t('entry.list.tableVisibleColumns.landed'),
+        name: 'landed',
+        component: 'date',
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)),
+        width: '105px',
     },
     {
-        align: 'left',
         label: t('globals.id'),
         name: 'id',
         isId: true,
+        component: 'number',
         chip: {
             condition: () => true,
         },
     },
     {
-        align: 'left',
-        label: t('globals.reference'),
-        name: 'reference',
-        isTitle: true,
-        component: 'input',
-        columnField: {
-            component: null,
-        },
-        create: true,
-        cardVisible: true,
-    },
-    {
-        align: 'left',
-        label: t('entry.list.tableVisibleColumns.created'),
-        name: 'created',
-        create: true,
-        cardVisible: true,
-        component: 'date',
-        columnField: {
-            component: null,
-        },
-        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.created)),
-    },
-    {
-        align: 'left',
         label: t('entry.list.tableVisibleColumns.supplierFk'),
         name: 'supplierFk',
         create: true,
@@ -87,164 +100,197 @@ const columns = computed(() => [
             url: 'suppliers',
             fields: ['id', 'name'],
         },
-        columnField: {
-            component: null,
-        },
         format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.isBooked'),
-        name: 'isBooked',
-        cardVisible: true,
-        create: true,
-        component: 'checkbox',
+        label: t('entry.list.tableVisibleColumns.invoiceNumber'),
+        name: 'invoiceNumber',
+        component: 'input',
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.isConfirmed'),
-        name: 'isConfirmed',
+        label: t('entry.list.tableVisibleColumns.reference'),
+        name: 'reference',
+        isTitle: true,
+        component: 'input',
+        columnField: {
+            component: null,
+        },
         cardVisible: true,
-        create: true,
-        component: 'checkbox',
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.isOrdered'),
-        name: 'isOrdered',
-        cardVisible: true,
-        create: true,
-        component: 'checkbox',
+        label: 'AWB',
+        name: 'awbCode',
+        component: 'input',
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.companyFk'),
+        label: t('entry.list.tableVisibleColumns.agencyModeId'),
+        name: 'agencyModeId',
+        cardVisible: true,
+        component: 'select',
+        attrs: {
+            url: 'agencyModes',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(row.agencyModeName),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.evaNotes'),
+        name: 'evaNotes',
+        component: 'input',
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.warehouseOutFk'),
+        name: 'warehouseOutFk',
+        cardVisible: true,
+        component: 'select',
+        attrs: {
+            url: 'warehouses',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseOutName),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.warehouseInFk'),
+        name: 'warehouseInFk',
+        cardVisible: true,
+        component: 'select',
+        attrs: {
+            url: 'warehouses',
+            fields: ['id', 'name'],
+        },
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseInName),
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
+        name: 'entryTypeCode',
+        cardVisible: true,
+    },
+    {
         name: 'companyFk',
+        label: t('entry.list.tableVisibleColumns.companyFk'),
+        cardVisible: false,
+        visible: false,
+        create: true,
         component: 'select',
         attrs: {
-            url: 'companies',
-            fields: ['id', 'code'],
+            optionValue: 'id',
             optionLabel: 'code',
-            optionValue: 'id',
+            url: 'Companies',
         },
-        columnField: {
-            component: null,
-        },
-        create: true,
-
-        format: (row, dashIfEmpty) => dashIfEmpty(row.companyCode),
     },
     {
-        align: 'left',
-        label: t('entry.list.tableVisibleColumns.travelFk'),
         name: 'travelFk',
-        component: 'select',
-        attrs: {
-            url: 'travels',
-            fields: ['id', 'ref'],
-            optionLabel: 'ref',
-            optionValue: 'id',
-        },
-        columnField: {
-            component: null,
-        },
+        label: t('entry.list.tableVisibleColumns.travelFk'),
+        cardVisible: false,
+        visible: false,
         create: true,
-        format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
-    },
-    {
-        align: 'left',
-        label: t('entry.list.tableVisibleColumns.invoiceAmount'),
-        name: 'invoiceAmount',
-        cardVisible: true,
-    },
-    {
-        align: 'left',
-        name: 'initialTemperature',
-        label: t('entry.basicData.initialTemperature'),
-        field: 'initialTemperature',
-        format: (row) => toCelsius(row.initialTemperature),
-    },
-    {
-        align: 'left',
-        name: 'finalTemperature',
-        label: t('entry.basicData.finalTemperature'),
-        field: 'finalTemperature',
-        format: (row) => toCelsius(row.finalTemperature),
-    },
-    {
-        label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
-        name: 'isExcludedFromAvailable',
-        columnFilter: {
-            inWhere: true,
-        },
-    },
-    {
-        align: 'right',
-        name: 'tableActions',
-        actions: [
-            {
-                title: t('components.smartCard.viewSummary'),
-                icon: 'preview',
-                action: (row) => viewSummary(row.id, EntrySummary),
-                isPrimary: true,
-            },
-        ],
     },
 ]);
+function getBadgeAttrs(row) {
+    const date = row.landed;
+    let today = Date.vnNew();
+    today.setHours(0, 0, 0, 0);
+    let timeTicket = new Date(date);
+    timeTicket.setHours(0, 0, 0, 0);
+
+    let timeDiff = today - timeTicket;
+
+    if (timeDiff > 0) return { color: 'info', 'text-color': 'black' };
+    if (timeDiff < 0) return { color: 'warning', 'text-color': 'black' };
+    switch (row.entryTypeCode) {
+        case 'regularization':
+        case 'life':
+        case 'internal':
+        case 'inventory':
+            if (!row.isOrdered || !row.isConfirmed)
+                return { color: 'negative', 'text-color': 'black' };
+            break;
+        case 'product':
+        case 'packaging':
+        case 'devaluation':
+        case 'payment':
+        case 'transport':
+            if (
+                row.invoiceAmount === null ||
+                (row.invoiceNumber === null && row.reference === null) ||
+                !row.isOrdered ||
+                !row.isConfirmed
+            )
+                return { color: 'negative', 'text-color': 'black' };
+            break;
+        default:
+            break;
+    }
+    return { color: 'transparent' };
+}
+
+onBeforeMount(async () => {
+    defaultEntry.value = (await axios.get('EntryConfigs/findOne')).data;
+});
 </script>
 
 <template>
     <VnSection
         :data-key="dataKey"
-        :columns="columns"
         prefix="entry"
         url="Entries/filter"
         :array-data-props="{
             url: 'Entries/filter',
-            order: 'id DESC',
-            userFilter: entryFilter,
+            order: 'landed DESC',
+            userFilter: EntryFilter,
         }"
     >
         <template #advanced-menu>
-            <EntryFilter data-key="EntryList" />
+            <EntryFilter :data-key="dataKey" />
         </template>
         <template #body>
             <VnTable
+                v-if="defaultEntry.defaultSupplierFk"
                 ref="tableRef"
                 :data-key="dataKey"
+                url="Entries/filter"
+                :filter="entryQueryFilter"
+                order="landed DESC"
                 :create="{
                     urlCreate: 'Entries',
-                    title: t('entry.list.newEntry'),
+                    title: t('Create entry'),
                     onDataSaved: ({ id }) => tableRef.redirect(id),
-                    formInitialData: {},
+                    formInitialData: {
+                        supplierFk: defaultEntry.defaultSupplierFk,
+                        dated: Date.vnNew(),
+                        companyFk: user?.companyFk,
+                    },
                 }"
                 :columns="columns"
                 redirect="entry"
                 :right-search="false"
             >
-                <template #column-status="{ row }">
-                    <div class="row q-gutter-xs">
-                        <QIcon
-                            v-if="!!row.isExcludedFromAvailable"
-                            name="vn:inventory"
-                            color="primary"
-                        >
-                            <QTooltip>{{
-                                t(
-                                    'entry.list.tableVisibleColumns.isExcludedFromAvailable',
-                                )
-                            }}</QTooltip>
-                        </QIcon>
-                        <QIcon v-if="!!row.isRaid" name="vn:net" color="primary">
-                            <QTooltip>
-                                {{
-                                    t('globals.raid', {
-                                        daysInForward: row.daysInForward,
-                                    })
-                                }}</QTooltip
-                            >
-                        </QIcon>
-                    </div>
+                <template #column-landed="{ row }">
+                    <QBadge
+                        v-if="row?.travelFk"
+                        v-bind="getBadgeAttrs(row)"
+                        class="q-pa-sm"
+                        style="font-size: 14px"
+                    >
+                        {{ toDate(row.landed) }}
+                    </QBadge>
                 </template>
                 <template #column-supplierFk="{ row }">
                     <span class="link" @click.stop>
@@ -252,13 +298,26 @@ const columns = computed(() => [
                         <SupplierDescriptorProxy :id="row.supplierFk" />
                     </span>
                 </template>
-                <template #column-travelFk="{ row }">
-                    <span class="link" @click.stop>
-                        {{ row.travelRef }}
-                        <TravelDescriptorProxy :id="row.travelFk" />
-                    </span>
+                <template #column-create-travelFk="{ data }">
+                    <VnSelectTravelExtended
+                        :data="data"
+                        v-model="data.travelFk"
+                        :onFilterTravelSelected="
+                            (data, result) => (data.travelFk = result)
+                        "
+                        data-cy="entry-travel-select"
+                    />
                 </template>
             </VnTable>
         </template>
     </VnSection>
 </template>
+
+<i18n>
+es:
+    Inventory entry: Es inventario
+    Virtual entry: Es una redada
+    Search entries: Buscar entradas
+    You can search by entry reference: Puedes buscar por referencia de la entrada
+    Create entry: Crear entrada
+</i18n>
diff --git a/src/pages/Entry/locale/en.yml b/src/pages/Entry/locale/en.yml
index 80f3491a8..88b16cb03 100644
--- a/src/pages/Entry/locale/en.yml
+++ b/src/pages/Entry/locale/en.yml
@@ -1,21 +1,36 @@
 entry:
+    lock:
+        title: Lock entry
+        message: This entry has been locked by {userName} for {time} minutes. Do you want to unlock it?
+        success: The entry has been locked successfully
     list:
         newEntry: New entry
         tableVisibleColumns:
-            created: Creation
-            supplierFk: Supplier
-            isBooked: Booked
-            isConfirmed: Confirmed
+            isExcludedFromAvailable: Exclude from inventory
             isOrdered: Ordered
+            isConfirmed: Ready to label
+            isReceived: Received
+            isRaid: Raid
+            landed: Date
+            supplierFk: Supplier
+            reference: Ref/Alb/Guide
+            invoiceNumber: Invoice
+            agencyModeId: Agency
+            isBooked: Booked
             companyFk: Company
-            travelFk: Travel
-            isExcludedFromAvailable: Inventory
+            evaNotes: Notes
+            warehouseOutFk: Origin
+            warehouseInFk: Destiny
+            entryTypeDescription: Entry type
             invoiceAmount: Import
+            travelFk: Travel
+            dated: Dated
         inventoryEntry: Inventory entry
     summary:
         commission: Commission
         currency: Currency
         invoiceNumber: Invoice number
+        invoiceAmount: Invoice amount
         ordered: Ordered
         booked: Booked
         excludedFromAvailable: Inventory
@@ -33,6 +48,7 @@ entry:
         buyingValue: Buying value
         import: Import
         pvp: PVP
+        entryType: Entry type
     basicData:
         travel: Travel
         currency: Currency
@@ -69,17 +85,55 @@ entry:
             landing: Landing
             isExcludedFromAvailable: Es inventory
     params:
-        toShipped: To
-        fromShipped: From
-        daysOnward: Days onward
-        daysAgo: Days ago
-        warehouseInFk: Warehouse in
+        isExcludedFromAvailable: Exclude from inventory
+        isOrdered: Ordered
+        isConfirmed: Ready to label
+        isReceived: Received
+        isIgnored: Ignored
+        isRaid: Raid
+        landed: Date
+        supplierFk: Supplier
+        reference: Ref/Alb/Guide
+        invoiceNumber: Invoice
+        agencyModeId: Agency
+        isBooked: Booked
+        companyFk: Company
+        evaNotes: Notes
+        warehouseOutFk: Origin
+        warehouseInFk: Destiny
+        entryTypeDescription: Entry type
+        invoiceAmount: Import
+        travelFk: Travel
+        dated: Dated
+        itemFk: Item id
+        hex: Color
+        name: Item name
+        size: Size
+        stickers: Stickers
+        packagingFk: Packaging
+        weight: Kg
+        groupingMode: Grouping selector
+        grouping: Grouping
+        quantity: Quantity
+        buyingValue: Buying value
+        price2: Package
+        price3: Box
+        minPrice: Minumum price
+        hasMinPrice: Has minimum price
+        packingOut: Packing out
+        comment: Comment
+        subName: Supplier name
+        tags: Tags
+        company_name: Company name
+        itemTypeFk: Item type
+        workerFk: Worker id
     search: Search entries
     searchInfo: You can search by entry reference
     descriptorMenu:
         showEntryReport: Show entry report
 entryFilter:
     params:
+        isExcludedFromAvailable: Exclude from inventory
         invoiceNumber: Invoice number
         travelFk: Travel
         companyFk: Company
@@ -91,8 +145,16 @@ entryFilter:
         isBooked: Booked
         isConfirmed: Confirmed
         isOrdered: Ordered
+        isReceived: Received
         search: General search
         reference: Reference
+        landed: Landed
+        id: Id
+        agencyModeId: Agency
+        evaNotes: Notes
+        warehouseOutFk: Origin
+        warehouseInFk: Destiny
+        entryTypeCode: Entry type
 myEntries:
     id: ID
     landed: Landed
diff --git a/src/pages/Entry/locale/es.yml b/src/pages/Entry/locale/es.yml
index a5b968016..3025d64cb 100644
--- a/src/pages/Entry/locale/es.yml
+++ b/src/pages/Entry/locale/es.yml
@@ -1,21 +1,36 @@
 entry:
+    lock:
+        title: Entrada bloqueada
+        message: Esta entrada ha sido bloqueada por {userName} hace {time} minutos. ¿Quieres desbloquearla?
+        success: La entrada ha sido bloqueada correctamente
     list:
         newEntry: Nueva entrada
         tableVisibleColumns:
-            created: Creación
-            supplierFk: Proveedor
-            isBooked: Asentado
-            isConfirmed: Confirmado
+            isExcludedFromAvailable: Excluir del inventario
             isOrdered: Pedida
+            isConfirmed: Lista para etiquetar
+            isReceived: Recibida
+            isRaid: Redada
+            landed: Fecha
+            supplierFk: Proveedor
+            invoiceNumber: Nº Factura
+            reference: Ref/Alb/Guía
+            agencyModeId: Agencia
+            isBooked: Asentado
             companyFk: Empresa
             travelFk: Envio
-            isExcludedFromAvailable: Inventario
+            evaNotes: Notas
+            warehouseOutFk: Origen
+            warehouseInFk: Destino
+            entryTypeDescription: Tipo entrada
             invoiceAmount: Importe
+            dated: Fecha
         inventoryEntry: Es inventario
     summary:
         commission: Comisión
         currency: Moneda
         invoiceNumber: Núm. factura
+        invoiceAmount: Importe
         ordered: Pedida
         booked: Contabilizada
         excludedFromAvailable: Inventario
@@ -34,12 +49,13 @@ entry:
         buyingValue: Coste
         import: Importe
         pvp: PVP
+        entryType: Tipo entrada
     basicData:
         travel: Envío
         currency: Moneda
         observation: Observación
         commission: Comisión
-        booked: Asentado
+        booked: Contabilizada
         excludedFromAvailable: Inventario
         initialTemperature: Ini °C
         finalTemperature: Fin °C
@@ -69,31 +85,70 @@ entry:
             packingOut: Embalaje envíos
             landing: Llegada
             isExcludedFromAvailable: Es inventario
-    params:
-        toShipped: Hasta
-        fromShipped: Desde
-        warehouseInFk: Alm. entrada
-        daysOnward: Días adelante
-        daysAgo: Días atras
-    descriptorMenu:
-        showEntryReport: Ver informe del pedido
+
     search: Buscar entradas
     searchInfo: Puedes buscar por referencia de entrada
+    params:
+        isExcludedFromAvailable: Excluir del inventario
+        isOrdered: Pedida
+        isConfirmed: Lista para etiquetar
+        isReceived: Recibida
+        isRaid: Redada
+        isIgnored: Ignorado
+        landed: Fecha
+        supplierFk: Proveedor
+        invoiceNumber: Nº Factura
+        reference: Ref/Alb/Guía
+        agencyModeId: Agencia
+        isBooked: Asentado
+        companyFk: Empresa
+        travelFk: Envio
+        evaNotes: Notas
+        warehouseOutFk: Origen
+        warehouseInFk: Destino
+        entryTypeDescription: Tipo entrada
+        invoiceAmount: Importe
+        dated: Fecha
+        itemFk: Id artículo
+        hex: Color
+        name: Nombre artículo
+        size: Medida
+        stickers: Etiquetas
+        packagingFk: Embalaje
+        weight: Kg
+        groupinMode: Selector de grouping
+        grouping: Grouping
+        quantity: Quantity
+        buyingValue: Precio de compra
+        price2: Paquete
+        price3: Caja
+        minPrice: Precio mínimo
+        hasMinPrice: Tiene precio mínimo
+        packingOut: Packing out
+        comment: Referencia
+        subName: Nombre proveedor
+        tags: Etiquetas
+        company_name: Nombre empresa
+        itemTypeFk: Familia
+        workerFk: Comprador
 entryFilter:
     params:
-        invoiceNumber: Núm. factura
-        travelFk: Envío
-        companyFk: Empresa
-        currencyFk: Moneda
-        supplierFk: Proveedor
-        from: Desde
-        to: Hasta
-        created: Fecha creación
-        isBooked: Asentado
-        isConfirmed: Confirmado
+        isExcludedFromAvailable: Inventario
         isOrdered: Pedida
-        search: Búsqueda general
-        reference: Referencia
+        isConfirmed: Confirmado
+        isReceived: Recibida
+        isRaid: Raid
+        landed: Fecha
+        id: Id
+        supplierFk: Proveedor
+        invoiceNumber: Núm. factura
+        reference: Ref/Alb/Guía
+        agencyModeId: Modo agencia
+        evaNotes: Notas
+        warehouseOutFk: Origen
+        warehouseInFk: Destino
+        entryTypeCode: Tipo de entrada
+        hasToShowDeletedEntries: Mostrar entradas eliminadas
 myEntries:
     id: ID
     landed: F. llegada
diff --git a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
index a3beabdb6..905ddebb2 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
@@ -125,7 +125,7 @@ function deleteFile(dmsFk) {
                 <VnInput
                     clearable
                     clear-icon="close"
-                    :label="t('Supplier ref')"
+                    :label="t('invoiceIn.supplierRef')"
                     v-model="data.supplierRef"
                 />
             </VnRow>
@@ -149,6 +149,7 @@ function deleteFile(dmsFk) {
                     option-value="id"
                     option-label="id"
                     :filter-options="['id', 'name']"
+                    data-cy="UnDeductibleVatSelect"
                 >
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
@@ -310,7 +311,6 @@ function deleteFile(dmsFk) {
         supplierFk: Supplier
     es:
         supplierFk: Proveedor
-        Supplier ref: Ref. proveedor
         Expedition date: Fecha expedición
         Operation date: Fecha operación
         Undeductible VAT: Iva no deducible
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index acd55c0fa..3843f5bf7 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -90,7 +90,6 @@ async function setInvoiceCorrection(id) {
 <template>
     <CardDescriptor
         ref="cardDescriptorRef"
-        module="InvoiceIn"
         data-key="InvoiceIn"
         :url="`InvoiceIns/${entityId}`"
         :filter="filter"
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
index c3ab635c8..8b039ec27 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
@@ -186,7 +186,7 @@ const createInvoiceInCorrection = async () => {
                 clickable
                 @click="book(entityId)"
             >
-                <QItemSection>{{ t('invoiceIn.descriptorMenu.toBook') }}</QItemSection>
+                <QItemSection>{{ t('invoiceIn.descriptorMenu.book') }}</QItemSection>
             </QItem>
         </template>
     </InvoiceInToBook>
@@ -197,7 +197,7 @@ const createInvoiceInCorrection = async () => {
         @click="triggerMenu('unbook')"
     >
         <QItemSection>
-            {{ t('invoiceIn.descriptorMenu.toUnbook') }}
+            {{ t('invoiceIn.descriptorMenu.unbook') }}
         </QItemSection>
     </QItem>
     <QItem
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
index cb3271dc1..1cad40e0b 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed } from 'vue';
+import { ref, computed, onBeforeMount } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import axios from 'axios';
@@ -12,6 +12,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import useNotify from 'src/composables/useNotify.js';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnInputNumber from 'src/components/common/VnInputNumber.vue';
+import { toCurrency } from 'filters/index';
 
 const route = useRoute();
 const { notify } = useNotify();
@@ -26,7 +27,7 @@ const invoiceInFormRef = ref();
 const invoiceId = +route.params.id;
 const filter = { where: { invoiceInFk: invoiceId } };
 const areRows = ref(false);
-
+const totals = ref();
 const columns = computed(() => [
     {
         name: 'duedate',
@@ -66,6 +67,8 @@ const columns = computed(() => [
     },
 ]);
 
+const totalAmount = computed(() => getTotal(invoiceInFormRef.value.formData, 'amount'));
+
 const isNotEuro = (code) => code != 'EUR';
 
 async function insert() {
@@ -73,6 +76,10 @@ async function insert() {
     await invoiceInFormRef.value.reload();
     notify(t('globals.dataSaved'), 'positive');
 }
+
+onBeforeMount(async () => {
+    totals.value = (await axios.get(`InvoiceIns/${invoiceId}/getTotals`)).data;
+});
 </script>
 <template>
     <FetchData
@@ -153,7 +160,7 @@ async function insert() {
                         <QTd />
                         <QTd />
                         <QTd>
-                            {{ getTotal(rows, 'amount', { currency: 'default' }) }}
+                            {{ toCurrency(totalAmount) }}
                         </QTd>
                         <QTd>
                             <template v-if="isNotEuro(invoiceIn.currency.code)">
@@ -235,7 +242,16 @@ async function insert() {
             v-shortcut="'+'"
             size="lg"
             round
-            @click="!areRows ? insert() : invoiceInFormRef.insert()"
+            @click="
+                () => {
+                    if (!areRows) insert();
+                    else
+                        invoiceInFormRef.insert({
+                            amount: (totals.totalTaxableBase - totalAmount).toFixed(2),
+                            invoiceInFk: invoiceId,
+                        });
+                }
+            "
         />
     </QPageSticky>
 </template>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index e546638f2..d358601d3 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -193,7 +193,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
             <InvoiceIntoBook>
                 <template #content="{ book }">
                     <QBtn
-                        :label="t('To book')"
+                        :label="t('Book')"
                         color="orange-11"
                         text-color="black"
                         @click="book(entityId)"
@@ -224,10 +224,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                         </span>
                     </template>
                 </VnLv>
-                <VnLv
-                    :label="t('invoiceIn.list.supplierRef')"
-                    :value="entity.supplierRef"
-                />
+                <VnLv :label="t('invoiceIn.supplierRef')" :value="entity.supplierRef" />
                 <VnLv
                     :label="t('invoiceIn.summary.currency')"
                     :value="entity.currency?.code"
@@ -357,7 +354,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                                 entity.totals.totalTaxableBaseForeignValue &&
                                 toCurrency(
                                     entity.totals.totalTaxableBaseForeignValue,
-                                    currency
+                                    currency,
                                 )
                             }}</QTd>
                         </QTr>
@@ -392,7 +389,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                                     entity.totals.totalDueDayForeignValue &&
                                     toCurrency(
                                         entity.totals.totalDueDayForeignValue,
-                                        currency
+                                        currency,
                                     )
                                 }}
                             </QTd>
@@ -472,5 +469,5 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
         Search invoice: Buscar factura recibida
         You can search by invoice reference: Puedes buscar por referencia de la factura
         Totals: Totales
-        To book: Contabilizar
+        Book: Contabilizar
 </i18n>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
index edb43375f..e77453bc0 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed } from 'vue';
+import { ref, computed, nextTick } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { useArrayData } from 'src/composables/useArrayData';
@@ -25,7 +25,6 @@ const sageTaxTypes = ref([]);
 const sageTransactionTypes = ref([]);
 const rowsSelected = ref([]);
 const invoiceInFormRef = ref();
-const expenseRef = ref();
 
 defineProps({
     actionIcon: {
@@ -97,6 +96,20 @@ const columns = computed(() => [
     },
 ]);
 
+const taxableBaseTotal = computed(() => {
+    return getTotal(invoiceInFormRef.value.formData, 'taxableBase');
+});
+
+const taxRateTotal = computed(() => {
+    return getTotal(invoiceInFormRef.value.formData, null, {
+        cb: taxRate,
+    });
+});
+
+const combinedTotal = computed(() => {
+    return +taxableBaseTotal.value + +taxRateTotal.value;
+});
+
 const filter = {
     fields: [
         'id',
@@ -125,7 +138,7 @@ function taxRate(invoiceInTax) {
     return ((taxTypeSage / 100) * taxableBase).toFixed(2);
 }
 
-function autocompleteExpense(evt, row, col) {
+function autocompleteExpense(evt, row, col, ref) {
     const val = evt.target.value;
     if (!val) return;
 
@@ -134,22 +147,17 @@ function autocompleteExpense(evt, row, col) {
         ({ id }) => id == useAccountShortToStandard(param),
     );
 
-    expenseRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
+    ref.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
 }
 
-const taxableBaseTotal = computed(() => {
-    return getTotal(invoiceInFormRef.value.formData, 'taxableBase');
-});
-
-const taxRateTotal = computed(() => {
-    return getTotal(invoiceInFormRef.value.formData, null, {
-        cb: taxRate,
+function setCursor(ref) {
+    nextTick(() => {
+        const select = ref.vnSelectDialogRef
+            ? ref.vnSelectDialogRef.vnSelectRef
+            : ref.vnSelectRef;
+        select.$el.querySelector('input').setSelectionRange(0, 0);
     });
-});
-
-const combinedTotal = computed(() => {
-    return +taxableBaseTotal.value + +taxRateTotal.value;
-});
+}
 </script>
 <template>
     <FetchData
@@ -187,14 +195,24 @@ const combinedTotal = computed(() => {
                 <template #body-cell-expense="{ row, col }">
                     <QTd>
                         <VnSelectDialog
-                            ref="expenseRef"
+                            :ref="`expenseRef-${row.$index}`"
                             v-model="row[col.model]"
                             :options="col.options"
                             :option-value="col.optionValue"
                             :option-label="col.optionLabel"
                             :filter-options="['id', 'name']"
                             :tooltip="t('Create a new expense')"
-                            @keydown.tab="autocompleteExpense($event, row, col)"
+                            @keydown.tab="
+                                autocompleteExpense(
+                                    $event,
+                                    row,
+                                    col,
+                                    $refs[`expenseRef-${row.$index}`],
+                                )
+                            "
+                            @update:model-value="
+                                setCursor($refs[`expenseRef-${row.$index}`])
+                            "
                         >
                             <template #option="scope">
                                 <QItem v-bind="scope.itemProps">
@@ -210,7 +228,7 @@ const combinedTotal = computed(() => {
                     </QTd>
                 </template>
                 <template #body-cell-taxablebase="{ row }">
-                    <QTd>
+                    <QTd shrink>
                         <VnInputNumber
                             clear-icon="close"
                             v-model="row.taxableBase"
@@ -221,12 +239,16 @@ const combinedTotal = computed(() => {
                 <template #body-cell-sageiva="{ row, col }">
                     <QTd>
                         <VnSelect
+                            :ref="`sageivaRef-${row.$index}`"
                             v-model="row[col.model]"
                             :options="col.options"
                             :option-value="col.optionValue"
                             :option-label="col.optionLabel"
                             :filter-options="['id', 'vat']"
                             data-cy="vat-sageiva"
+                            @update:model-value="
+                                setCursor($refs[`sageivaRef-${row.$index}`])
+                            "
                         >
                             <template #option="scope">
                                 <QItem v-bind="scope.itemProps">
@@ -244,11 +266,15 @@ const combinedTotal = computed(() => {
                 <template #body-cell-sagetransaction="{ row, col }">
                     <QTd>
                         <VnSelect
+                            :ref="`sagetransactionRef-${row.$index}`"
                             v-model="row[col.model]"
                             :options="col.options"
                             :option-value="col.optionValue"
                             :option-label="col.optionLabel"
                             :filter-options="['id', 'transaction']"
+                            @update:model-value="
+                                setCursor($refs[`sagetransactionRef-${row.$index}`])
+                            "
                         >
                             <template #option="scope">
                                 <QItem v-bind="scope.itemProps">
@@ -266,7 +292,7 @@ const combinedTotal = computed(() => {
                     </QTd>
                 </template>
                 <template #body-cell-foreignvalue="{ row }">
-                    <QTd>
+                    <QTd shrink>
                         <VnInputNumber
                             :class="{
                                 'no-pointer-events': !isNotEuro(currency),
diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue
index e1723e3b1..0960d0d6c 100644
--- a/src/pages/InvoiceIn/InvoiceInList.vue
+++ b/src/pages/InvoiceIn/InvoiceInList.vue
@@ -29,6 +29,7 @@ const cols = computed(() => [
         name: 'isBooked',
         label: t('invoiceIn.isBooked'),
         columnFilter: false,
+        component: 'checkbox',
     },
     {
         align: 'left',
@@ -56,7 +57,7 @@ const cols = computed(() => [
     {
         align: 'left',
         name: 'supplierRef',
-        label: t('invoiceIn.list.supplierRef'),
+        label: t('invoiceIn.supplierRef'),
     },
     {
         align: 'left',
@@ -177,7 +178,7 @@ const cols = computed(() => [
                         :required="true"
                     />
                     <VnInput
-                        :label="t('invoiceIn.list.supplierRef')"
+                        :label="t('invoiceIn.supplierRef')"
                         v-model="data.supplierRef"
                     />
                     <VnSelect
diff --git a/src/pages/InvoiceIn/InvoiceInToBook.vue b/src/pages/InvoiceIn/InvoiceInToBook.vue
index 95ce8155a..5bdbe197b 100644
--- a/src/pages/InvoiceIn/InvoiceInToBook.vue
+++ b/src/pages/InvoiceIn/InvoiceInToBook.vue
@@ -4,6 +4,7 @@ import { useQuasar } from 'quasar';
 import { useI18n } from 'vue-i18n';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import { useArrayData } from 'src/composables/useArrayData';
+import qs from 'qs';
 const { notify, dialog } = useQuasar();
 const { t } = useI18n();
 
@@ -12,29 +13,51 @@ defineExpose({ checkToBook });
 const { store } = useArrayData();
 
 async function checkToBook(id) {
-    let directBooking = true;
+    let messages = [];
+
+    const hasProblemWithTax = (
+        await axios.get('InvoiceInTaxes/count', {
+            params: {
+                where: JSON.stringify({
+                    invoiceInFk: id,
+                    or: [{ taxTypeSageFk: null }, { transactionTypeSageFk: null }],
+                }),
+            },
+        })
+    ).data?.count;
+
+    if (hasProblemWithTax)
+        messages.push(t('The VAT and Transaction fields have not been informed'));
 
     const { data: totals } = await axios.get(`InvoiceIns/${id}/getTotals`);
     const taxableBaseNotEqualDueDay = totals.totalDueDay != totals.totalTaxableBase;
     const vatNotEqualDueDay = totals.totalDueDay != totals.totalVat;
 
-    if (taxableBaseNotEqualDueDay && vatNotEqualDueDay) directBooking = false;
+    if (taxableBaseNotEqualDueDay && vatNotEqualDueDay)
+        messages.push(t('The sum of the taxable bases does not match the due dates'));
 
-    const { data: dueDaysCount } = await axios.get('InvoiceInDueDays/count', {
-        where: {
-            invoiceInFk: id,
-            dueDated: { gte: Date.vnNew() },
-        },
-    });
+    const dueDaysCount = (
+        await axios.get('InvoiceInDueDays/count', {
+            params: {
+                where: JSON.stringify({
+                    invoiceInFk: id,
+                    dueDated: { gte: Date.vnNew() },
+                }),
+            },
+        })
+    ).data?.count;
 
-    if (dueDaysCount) directBooking = false;
+    if (dueDaysCount) messages.push(t('Some due dates are less than or equal to today'));
 
-    if (directBooking) return toBook(id);
-
-    dialog({
-        component: VnConfirm,
-        componentProps: { title: t('Are you sure you want to book this invoice?') },
-    }).onOk(async () => await toBook(id));
+    if (!messages.length) toBook(id);
+    else
+        dialog({
+            component: VnConfirm,
+            componentProps: {
+                title: t('Are you sure you want to book this invoice?'),
+                message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''),
+            },
+        }).onOk(() => toBook(id));
 }
 
 async function toBook(id) {
@@ -59,4 +82,7 @@ async function toBook(id) {
 es:
     Are you sure you want to book this invoice?: ¿Estás seguro de querer asentar esta factura?
     It was not able to book the invoice: No se pudo contabilizar la factura
+    Some due dates are less than or equal to today: Algún vencimiento tiene una fecha menor o igual que hoy
+    The sum of the taxable bases does not match the due dates: La suma de las bases imponibles no coincide con la de los vencimientos
+    The VAT and Transaction fields have not been informed: No se han informado los campos de iva y/o transacción
 </i18n>
diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml
index 6b21b316b..548e6c201 100644
--- a/src/pages/InvoiceIn/locale/en.yml
+++ b/src/pages/InvoiceIn/locale/en.yml
@@ -3,10 +3,10 @@ invoiceIn:
     searchInfo: Search incoming invoices by ID or supplier fiscal name
     serial: Serial
     isBooked: Is booked
+    supplierRef: Invoice nº
     list:
         ref: Reference
         supplier: Supplier
-        supplierRef: Supplier ref.
         file: File
         issued: Issued
         dueDated: Due dated
@@ -19,8 +19,6 @@ invoiceIn:
         unbook: Unbook
         delete: Delete
         clone: Clone
-        toBook: To book
-        toUnbook: To unbook
         deleteInvoice: Delete invoice
         invoiceDeleted: invoice deleted
         cloneInvoice: Clone invoice
@@ -70,4 +68,3 @@ invoiceIn:
         isBooked: Is booked
         account: Ledger account
         correctingFk: Rectificative
-        
\ No newline at end of file
diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml
index 3f27c895c..142d95f92 100644
--- a/src/pages/InvoiceIn/locale/es.yml
+++ b/src/pages/InvoiceIn/locale/es.yml
@@ -3,10 +3,10 @@ invoiceIn:
     searchInfo: Buscar facturas recibidas por ID o nombre fiscal del proveedor
     serial: Serie
     isBooked: Contabilizada
+    supplierRef: Nº factura
     list:
         ref: Referencia
         supplier: Proveedor
-        supplierRef: Ref. proveedor
         issued: F. emisión
         dueDated: F. vencimiento
         file: Fichero
@@ -15,12 +15,10 @@ invoiceIn:
     descriptor:
         ticketList: Listado de tickets
     descriptorMenu:
-        book: Asentar
-        unbook: Desasentar
+        book: Contabilizar
+        unbook: Descontabilizar
         delete: Eliminar
         clone: Clonar
-        toBook: Contabilizar
-        toUnbook: Descontabilizar
         deleteInvoice: Eliminar factura
         invoiceDeleted: Factura eliminada
         cloneInvoice: Clonar factura
@@ -68,4 +66,3 @@ invoiceIn:
         isBooked: Contabilizada
         account: Cuenta contable
         correctingFk: Rectificativa
-
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
index de614e9fc..dfaf6c109 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
@@ -36,7 +36,6 @@ function ticketFilter(invoice) {
 <template>
     <CardDescriptor
         ref="descriptor"
-        module="InvoiceOut"
         :url="`InvoiceOuts/${entityId}`"
         :filter="filter"
         title="ref"
diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue
index 9398ded64..c7d7ba9f4 100644
--- a/src/pages/InvoiceOut/InvoiceOutList.vue
+++ b/src/pages/InvoiceOut/InvoiceOutList.vue
@@ -97,12 +97,19 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'companyCode',
+        name: 'companyFk',
         label: t('globals.company'),
         cardVisible: true,
         component: 'select',
-        attrs: { url: 'Companies', optionLabel: 'code', optionValue: 'id' },
-        columnField: { component: null },
+        attrs: {
+            url: 'Companies',
+            optionLabel: 'code',
+            optionValue: 'id',
+        },
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(row.companyCode),
     },
     {
         align: 'left',
diff --git a/src/pages/Item/Card/ItemBasicData.vue b/src/pages/Item/Card/ItemBasicData.vue
index 7e5645024..df7e71684 100644
--- a/src/pages/Item/Card/ItemBasicData.vue
+++ b/src/pages/Item/Card/ItemBasicData.vue
@@ -11,6 +11,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
 import FilterItemForm from 'src/components/FilterItemForm.vue';
 import CreateIntrastatForm from './CreateIntrastatForm.vue';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -208,30 +209,20 @@ const onIntrastatCreated = (response, formData) => {
                 />
             </VnRow>
             <VnRow class="row q-gutter-md q-mb-md">
-                <div>
-                    <QCheckbox
-                        v-model="data.isFragile"
-                        :label="t('item.basicData.isFragile')"
-                        class="q-mr-sm"
-                    />
-                    <QIcon name="info" class="cursor-pointer" size="xs">
-                        <QTooltip max-width="300px">
-                            {{ t('item.basicData.isFragileTooltip') }}
-                        </QTooltip>
-                    </QIcon>
-                </div>
-                <div>
-                    <QCheckbox
-                        v-model="data.isPhotoRequested"
-                        :label="t('item.basicData.isPhotoRequested')"
-                        class="q-mr-sm"
-                    />
-                    <QIcon name="info" class="cursor-pointer" size="xs">
-                        <QTooltip>
-                            {{ t('item.basicData.isPhotoRequestedTooltip') }}
-                        </QTooltip>
-                    </QIcon>
-                </div>
+                <VnCheckbox
+                    v-model="data.isFragile"
+                    :label="t('item.basicData.isFragile')"
+                    :info="t('item.basicData.isFragileTooltip')"
+                    class="q-mr-sm"
+                    size="xs"
+                />
+                <VnCheckbox
+                    v-model="data.isPhotoRequested"
+                    :label="t('item.basicData.isPhotoRequested')"
+                    :info="t('item.basicData.isPhotoRequestedTooltip')"
+                    class="q-mr-sm"
+                    size="xs"
+                />
             </VnRow>
             <VnRow>
                 <VnInput
diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue
index 4894d94fc..a40d81589 100644
--- a/src/pages/Item/Card/ItemBotanical.vue
+++ b/src/pages/Item/Card/ItemBotanical.vue
@@ -7,8 +7,8 @@ import FetchData from 'components/FetchData.vue';
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
-import CreateGenusForm from './CreateGenusForm.vue';
-import CreateSpecieForm from './CreateSpecieForm.vue';
+import CreateGenusForm from '../components/CreateGenusForm.vue';
+import CreateSpecieForm from '../components/CreateSpecieForm.vue';
 
 const route = useRoute();
 const { t } = useI18n();
diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue
index 7e7057a90..a4c58ef4b 100644
--- a/src/pages/Item/Card/ItemDescriptor.vue
+++ b/src/pages/Item/Card/ItemDescriptor.vue
@@ -34,6 +34,10 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
+    proxyRender: {
+        type: Boolean,
+        default: false,
+    },
 });
 
 const route = useRoute();
@@ -88,7 +92,6 @@ const updateStock = async () => {
 <template>
     <CardDescriptor
         data-key="Item"
-        module="Item"
         :summary="$props.summary"
         :url="`Items/${entityId}/getCard`"
         @on-fetch="setData"
@@ -112,7 +115,7 @@ const updateStock = async () => {
                 <template #value>
                     <span class="link">
                         {{ entity.itemType?.worker?.user?.name }}
-                        <WorkerDescriptorProxy :id="entity.itemType?.worker?.id" />
+                        <WorkerDescriptorProxy :id="entity.itemType?.worker?.id ?? NaN" />
                     </span>
                 </template>
             </VnLv>
@@ -147,7 +150,7 @@ const updateStock = async () => {
             </QCardActions>
         </template>
         <template #actions="{}">
-            <QCardActions class="row justify-center">
+            <QCardActions class="row justify-center" v-if="proxyRender">
                 <QBtn
                     :to="{
                         name: 'ItemDiary',
@@ -160,6 +163,16 @@ const updateStock = async () => {
                 >
                     <QTooltip>{{ t('item.descriptor.itemDiary') }}</QTooltip>
                 </QBtn>
+                <QBtn
+                    :to="{
+                        name: 'ItemLastEntries',
+                    }"
+                    size="md"
+                    icon="vn:regentry"
+                    color="primary"
+                >
+                    <QTooltip>{{ t('item.descriptor.itemLastEntries') }}</QTooltip>
+                </QBtn>
             </QCardActions>
         </template>
     </CardDescriptor>
diff --git a/src/pages/Item/Card/ItemDescriptorProxy.vue b/src/pages/Item/Card/ItemDescriptorProxy.vue
index 2ffc9080f..f686e8221 100644
--- a/src/pages/Item/Card/ItemDescriptorProxy.vue
+++ b/src/pages/Item/Card/ItemDescriptorProxy.vue
@@ -4,7 +4,7 @@ import ItemSummary from './ItemSummary.vue';
 
 const $props = defineProps({
     id: {
-        type: Number,
+        type: [Number, String],
         required: true,
     },
     dated: {
@@ -21,9 +21,8 @@ const $props = defineProps({
     },
 });
 </script>
-
 <template>
-    <QPopupProxy>
+    <QPopupProxy style="max-width: 10px">
         <ItemDescriptor
             v-if="$props.id"
             :id="$props.id"
@@ -31,6 +30,7 @@ const $props = defineProps({
             :dated="dated"
             :sale-fk="saleFk"
             :warehouse-fk="warehouseFk"
+            :proxy-render="true"
         />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Item/Card/ItemShelving.vue b/src/pages/Item/Card/ItemShelving.vue
index 7ad60c9e0..b29e2a2a5 100644
--- a/src/pages/Item/Card/ItemShelving.vue
+++ b/src/pages/Item/Card/ItemShelving.vue
@@ -110,10 +110,16 @@ const columns = computed(() => [
         attrs: { inWhere: true },
         align: 'left',
     },
+    {
+        label: t('globals.visible'),
+        name: 'stock',
+        attrs: { inWhere: true },
+        align: 'left',
+    },
 ]);
 
 const totalLabels = computed(() =>
-    rows.value.reduce((acc, row) => acc + row.stock / row.packing, 0).toFixed(2)
+    rows.value.reduce((acc, row) => acc + row.stock / row.packing, 0).toFixed(2),
 );
 
 const removeLines = async () => {
@@ -157,7 +163,7 @@ watchEffect(selectedRows);
                     openConfirmationModal(
                         t('shelvings.removeConfirmTitle'),
                         t('shelvings.removeConfirmSubtitle'),
-                        removeLines
+                        removeLines,
                     )
                 "
             >
diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue
index 1c4382fbd..fdfa1d3d1 100644
--- a/src/pages/Item/ItemFixedPrice.vue
+++ b/src/pages/Item/ItemFixedPrice.vue
@@ -65,10 +65,19 @@ const columns = computed(() => [
         name: 'name',
         ...defaultColumnAttrs,
         create: true,
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'Items',
+                fields: ['id', 'name', 'subName'],
+                optionLabel: 'name',
+                optionValue: 'name',
+                uppercase: false,
+            },
+        },
     },
     {
         label: t('item.fixedPrice.groupingPrice'),
-        field: 'rate2',
         name: 'rate2',
         ...defaultColumnAttrs,
         component: 'input',
@@ -76,7 +85,6 @@ const columns = computed(() => [
     },
     {
         label: t('item.fixedPrice.packingPrice'),
-        field: 'rate3',
         name: 'rate3',
         ...defaultColumnAttrs,
         component: 'input',
@@ -85,7 +93,6 @@ const columns = computed(() => [
 
     {
         label: t('item.fixedPrice.minPrice'),
-        field: 'minPrice',
         name: 'minPrice',
         ...defaultColumnAttrs,
         component: 'input',
@@ -108,7 +115,6 @@ const columns = computed(() => [
     },
     {
         label: t('item.fixedPrice.ended'),
-        field: 'ended',
         name: 'ended',
         ...defaultColumnAttrs,
         columnField: {
@@ -124,7 +130,6 @@ const columns = computed(() => [
 
     {
         label: t('globals.warehouse'),
-        field: 'warehouseFk',
         name: 'warehouseFk',
         ...defaultColumnAttrs,
         columnClass: 'shrink',
@@ -415,7 +420,6 @@ function handleOnDataSave({ CrudModelRef }) {
             'row-key': 'id',
             selection: 'multiple',
         }"
-        :use-model="true"
         v-model:selected="rowsSelected"
         :create-as-dialog="false"
         :create="{
diff --git a/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue b/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue
index 0f71ad1f1..725fb30aa 100644
--- a/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue
+++ b/src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue
@@ -26,7 +26,6 @@ const entityId = computed(() => {
 </script>
 <template>
     <CardDescriptor
-        module="ItemType"
         :url="`ItemTypes/${entityId}`"
         :filter="filter"
         title="code"
diff --git a/src/pages/Item/Card/CreateGenusForm.vue b/src/pages/Item/components/CreateGenusForm.vue
similarity index 100%
rename from src/pages/Item/Card/CreateGenusForm.vue
rename to src/pages/Item/components/CreateGenusForm.vue
diff --git a/src/pages/Item/Card/CreateSpecieForm.vue b/src/pages/Item/components/CreateSpecieForm.vue
similarity index 100%
rename from src/pages/Item/Card/CreateSpecieForm.vue
rename to src/pages/Item/components/CreateSpecieForm.vue
diff --git a/src/pages/Item/components/ItemProposal.vue b/src/pages/Item/components/ItemProposal.vue
new file mode 100644
index 000000000..d2dbea7b3
--- /dev/null
+++ b/src/pages/Item/components/ItemProposal.vue
@@ -0,0 +1,332 @@
+<script setup>
+import { ref, computed } from 'vue';
+import { useI18n } from 'vue-i18n';
+import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
+import { toCurrency } from 'filters/index';
+import VnStockValueDisplay from 'src/components/ui/VnStockValueDisplay.vue';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import axios from 'axios';
+import notifyResults from 'src/utils/notifyResults';
+import FetchData from 'components/FetchData.vue';
+
+const MATCH = 'match';
+
+const { t } = useI18n();
+const $props = defineProps({
+    itemLack: {
+        type: Object,
+        required: true,
+        default: () => {},
+    },
+    replaceAction: {
+        type: Boolean,
+        required: false,
+        default: false,
+    },
+    sales: {
+        type: Array,
+        required: false,
+        default: () => [],
+    },
+});
+const proposalSelected = ref([]);
+const ticketConfig = ref({});
+const proposalTableRef = ref(null);
+
+const sale = computed(() => $props.sales[0]);
+const saleFk = computed(() => sale.value.saleFk);
+const filter = computed(() => ({
+    itemFk: $props.itemLack.itemFk,
+    sales: saleFk.value,
+}));
+
+const defaultColumnAttrs = {
+    align: 'center',
+    sortable: false,
+};
+const emit = defineEmits(['onDialogClosed', 'itemReplaced']);
+
+const conditionalValuePrice = (price) =>
+    price > 1 + ticketConfig.value.lackAlertPrice / 100 ? 'match' : 'not-match';
+
+const columns = computed(() => [
+    {
+        ...defaultColumnAttrs,
+        label: t('proposal.available'),
+        name: 'available',
+        field: 'available',
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+            columnClass: 'shrink',
+        },
+        columnClass: 'shrink',
+    },
+    {
+        ...defaultColumnAttrs,
+        label: t('proposal.counter'),
+        name: 'counter',
+        field: 'counter',
+        columnClass: 'shrink',
+        style: 'max-width: 75px',
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+            columnClass: 'shrink',
+        },
+    },
+
+    {
+        align: 'left',
+        sortable: true,
+        label: t('proposal.longName'),
+        name: 'longName',
+        field: 'longName',
+        columnClass: 'expand',
+    },
+    {
+        align: 'left',
+        sortable: true,
+        label: t('item.list.color'),
+        name: 'tag5',
+        field: 'value5',
+        columnClass: 'expand',
+    },
+    {
+        align: 'left',
+        sortable: true,
+        label: t('item.list.stems'),
+        name: 'tag6',
+        field: 'value6',
+        columnClass: 'expand',
+    },
+    {
+        align: 'left',
+        sortable: true,
+        label: t('item.list.producer'),
+        name: 'tag7',
+        field: 'value7',
+        columnClass: 'expand',
+    },
+
+    {
+        ...defaultColumnAttrs,
+        label: t('proposal.price2'),
+        name: 'price2',
+        style: 'max-width: 75px',
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+            columnClass: 'shrink',
+        },
+    },
+    {
+        ...defaultColumnAttrs,
+        label: t('proposal.minQuantity'),
+        name: 'minQuantity',
+        field: 'minQuantity',
+        style: 'max-width: 75px',
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+            columnClass: 'shrink',
+        },
+    },
+    {
+        ...defaultColumnAttrs,
+        label: t('proposal.located'),
+        name: 'located',
+        field: 'located',
+    },
+    {
+        align: 'right',
+        label: '',
+        name: 'tableActions',
+        actions: [
+            {
+                title: t('Replace'),
+                icon: 'change_circle',
+                show: (row) => isSelectionAvailable(row),
+                action: change,
+                isPrimary: true,
+            },
+        ],
+    },
+]);
+
+function extractMatchValues(obj) {
+    return Object.keys(obj)
+        .filter((key) => key.startsWith(MATCH))
+        .map((key) => parseInt(key.replace(MATCH, ''), 10));
+}
+const gradientStyle = (value) => {
+    let color = 'white';
+    const perc = parseFloat(value);
+    switch (true) {
+        case perc >= 0 && perc < 33:
+            color = 'primary';
+            break;
+        case perc >= 33 && perc < 66:
+            color = 'warning';
+            break;
+
+        default:
+            color = 'secondary';
+            break;
+    }
+    return color;
+};
+const statusConditionalValue = (row) => {
+    const matches = extractMatchValues(row);
+    const value = matches.reduce((acc, i) => acc + row[`${MATCH}${i}`], 0);
+    return 100 * (value / matches.length);
+};
+
+const isSelectionAvailable = (itemProposal) => {
+    const { price2 } = itemProposal;
+    const salePrice = sale.value.price;
+    const byPrice = (100 * price2) / salePrice > ticketConfig.value.lackAlertPrice;
+    if (byPrice) {
+        return byPrice;
+    }
+    const byQuantity =
+        (100 * itemProposal.available) / Math.abs($props.itemLack.lack) <
+        ticketConfig.value.lackAlertPrice;
+    return byQuantity;
+};
+
+async function change({ itemFk: substitutionFk }) {
+    try {
+        const promises = $props.sales.map(({ saleFk, quantity }) => {
+            const params = {
+                saleFk,
+                substitutionFk,
+                quantity,
+            };
+            return axios.post('Sales/replaceItem', params);
+        });
+        const results = await Promise.allSettled(promises);
+
+        notifyResults(results, 'saleFk');
+        emit('itemReplaced', {
+            type: 'refresh',
+            quantity: quantity.value,
+            itemProposal: proposalSelected.value[0],
+        });
+        proposalSelected.value = [];
+    } catch (error) {
+        console.error(error);
+    }
+}
+
+async function handleTicketConfig(data) {
+    ticketConfig.value = data[0];
+}
+</script>
+<template>
+    <FetchData
+        url="TicketConfigs"
+        :filter="{ fields: ['lackAlertPrice'] }"
+        @on-fetch="handleTicketConfig"
+        auto-load
+    />
+
+    <VnTable
+        v-if="ticketConfig"
+        auto-load
+        data-cy="proposalTable"
+        ref="proposalTableRef"
+        data-key="ItemsGetSimilar"
+        url="Items/getSimilar"
+        :user-filter="filter"
+        :columns="columns"
+        class="full-width q-mt-md"
+        row-key="id"
+        :row-click="change"
+        :is-editable="false"
+        :right-search="false"
+        :without-header="true"
+        :disable-option="{ card: true, table: true }"
+    >
+        <template #column-longName="{ row }">
+            <QTd
+                class="flex"
+                style="max-width: 100%; flex-shrink: 50px; flex-wrap: nowrap"
+            >
+                <div
+                    class="middle full-width"
+                    :class="[`proposal-${gradientStyle(statusConditionalValue(row))}`]"
+                >
+                    <QTooltip> {{ statusConditionalValue(row) }}% </QTooltip>
+                </div>
+                <div style="flex: 2 0 100%; align-content: center">
+                    <div>
+                        <span class="link">{{ row.longName }}</span>
+                        <ItemDescriptorProxy :id="row.id" />
+                    </div>
+                </div>
+            </QTd>
+        </template>
+        <template #column-tag5="{ row }">
+            <span :class="{ match: !row.match5 }">{{ row.value5 }}</span>
+        </template>
+        <template #column-tag6="{ row }">
+            <span :class="{ match: !row.match6 }">{{ row.value6 }}</span>
+        </template>
+        <template #column-tag7="{ row }">
+            <span :class="{ match: !row.match7 }">{{ row.value7 }}</span>
+        </template>
+        <template #column-counter="{ row }">
+            <span
+                :class="{
+                    match: row.counter === 1,
+                    'not-match': row.counter !== 1,
+                }"
+                >{{ row.counter }}</span
+            >
+        </template>
+        <template #column-minQuantity="{ row }">
+            {{ row.minQuantity }}
+        </template>
+        <template #column-price2="{ row }">
+            <div class="flex column items-center content-center">
+                <VnStockValueDisplay :value="(sales[0].price - row.price2) / 100" />
+                <span :class="[conditionalValuePrice(row.price2)]">{{
+                    toCurrency(row.price2)
+                }}</span>
+            </div>
+        </template>
+    </VnTable>
+</template>
+<style lang="scss" scoped>
+@import 'src/css/quasar.variables.scss';
+.middle {
+    float: left;
+    margin-right: 2px;
+    flex: 2 0 5px;
+}
+.match {
+    color: $negative;
+}
+.not-match {
+    color: inherit;
+}
+.proposal-warning {
+    background-color: $warning;
+}
+.proposal-secondary {
+    background-color: $secondary;
+}
+.proposal-primary {
+    background-color: $primary;
+}
+.text {
+    margin: 0.05rem;
+    padding: 1px;
+    border: 1px solid var(--vn-label-color);
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    font-size: smaller;
+}
+</style>
diff --git a/src/pages/Item/components/ItemProposalProxy.vue b/src/pages/Item/components/ItemProposalProxy.vue
new file mode 100644
index 000000000..7da0ce398
--- /dev/null
+++ b/src/pages/Item/components/ItemProposalProxy.vue
@@ -0,0 +1,56 @@
+<script setup>
+import ItemProposal from './ItemProposal.vue';
+import { useDialogPluginComponent } from 'quasar';
+
+const $props = defineProps({
+    itemLack: {
+        type: Object,
+        required: true,
+        default: () => {},
+    },
+    replaceAction: {
+        type: Boolean,
+        required: false,
+        default: false,
+    },
+    sales: {
+        type: Array,
+        required: false,
+        default: () => [],
+    },
+});
+const { dialogRef } = useDialogPluginComponent();
+const emit = defineEmits([
+    'onDialogClosed',
+    'itemReplaced',
+    ...useDialogPluginComponent.emits,
+]);
+defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() });
+</script>
+<template>
+    <QDialog ref="dialogRef" transition-show="scale" transition-hide="scale">
+        <QCard class="dialog-width">
+            <QCardSection class="row items-center q-pb-none">
+                <span class="text-h6 text-grey">{{ $t('Item proposal') }}</span>
+                <QSpace />
+                <QBtn icon="close" flat round dense v-close-popup />
+            </QCardSection>
+            <QCardSection>
+                <ItemProposal
+                    v-bind="$props"
+                    @item-replaced="
+                        (data) => {
+                            emit('itemReplaced', data);
+                            dialogRef.hide();
+                        }
+                    "
+                ></ItemProposal
+            ></QCardSection>
+        </QCard>
+    </QDialog>
+</template>
+<style lang="scss" scoped>
+.dialog-width {
+    max-width: $width-lg;
+}
+</style>
diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml
index bc73abb12..9d27fc96e 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -112,6 +112,7 @@ item:
         available: Available
         warehouseText: 'Calculated on the warehouse of { warehouseName }'
         itemDiary: Item diary
+        itemLastEntries: Last entries
         producer: Producer
         clone:
             title: All its properties will be copied
@@ -130,6 +131,7 @@ item:
         origin: Orig.
         userName: Buyer
         weight: Weight
+        color: Color
         weightByPiece: Weight/stem
         stemMultiplier: Multiplier
         producer: Producer
@@ -215,4 +217,24 @@ item:
         specie: Specie
     search: 'Search item'
     searchInfo: 'You can search by id'
-    regularizeStock: Regularize stock
\ No newline at end of file
+    regularizeStock: Regularize stock
+itemProposal: Items proposal
+proposal:
+    difference: Difference
+    title: Items proposal
+    itemFk: Item
+    longName: Name
+    subName: Producer
+    value5: value5
+    value6: value6
+    value7: value7
+    value8: value8
+    available: Available
+    minQuantity: minQuantity
+    price2: Price
+    located: Located
+    counter: Counter
+    groupingPrice: Grouping Price
+    itemOldPrice: itemOld Price
+    status: State
+    quantityToReplace: Quanity to replace
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index dd5074f5f..935f5160b 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -118,6 +118,7 @@ item:
         available: Disponible
         warehouseText: 'Calculado sobre el almacén de { warehouseName }'
         itemDiary: Registro de compra-venta
+        itemLastEntries: Últimas entradas
         producer: Productor
         clone:
             title: Todas sus propiedades serán copiadas
@@ -135,6 +136,7 @@ item:
         size: Medida
         origin: Orig.
         weight: Peso
+        color: Color
         weightByPiece: Peso/tallo
         userName: Comprador
         stemMultiplier: Multiplicador
@@ -220,5 +222,30 @@ item:
         achieved: 'Conseguido'
         concept: 'Concepto'
         state: 'Estado'
-    search: 'Buscar artículo'
-    searchInfo: 'Puedes buscar por id'
+itemProposal: Artículos similares
+proposal:
+    substitutionAvailable: Sustitución disponible
+    notSubstitutionAvailableByPrice: Sustitución no disponible, 30% de diferencia por precio o cantidad
+    compatibility: Compatibilidad
+    title: Items de sustitución para los tickets seleccionados
+    itemFk: Item
+    longName: Nombre
+    subName: Productor
+    value5: value5
+    value6: value6
+    value7: value7
+    value8: value8
+    available: Disponible
+    minQuantity: Min. cantidad
+    price2: Precio
+    located: Ubicado
+    counter: Contador
+    difference: Diferencial
+    groupingPrice: Precio Grouping
+    itemOldPrice: Precio itemOld
+    status: Estado
+    quantityToReplace: Cantidad a reemplazar
+    replace: Sustituir
+    replaceAndConfirm: Sustituir y confirmar precio
+search: 'Buscar artículo'
+searchInfo: 'Puedes buscar por id'
diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue
index 4efab56fb..873f8abb4 100644
--- a/src/pages/Monitor/MonitorOrders.vue
+++ b/src/pages/Monitor/MonitorOrders.vue
@@ -157,7 +157,7 @@ const openTab = (id) =>
                         openConfirmationModal(
                             $t('globals.deleteConfirmTitle'),
                             $t('salesOrdersTable.deleteConfirmMessage'),
-                            removeOrders
+                            removeOrders,
                         )
                     "
                 >
diff --git a/src/pages/Order/Card/OrderCatalogItemDialog.vue b/src/pages/Order/Card/OrderCatalogItemDialog.vue
index be35750a9..680f6e773 100644
--- a/src/pages/Order/Card/OrderCatalogItemDialog.vue
+++ b/src/pages/Order/Card/OrderCatalogItemDialog.vue
@@ -43,10 +43,9 @@ const addToOrder = async () => {
     );
 
     state.set('orderTotal', orderTotal);
-    const rows = orderData.value.rows.push(...items) || [];
     state.set('Order', {
         ...orderData.value,
-        rows,
+        items,
     });
     notify(t('globals.dataSaved'), 'positive');
     emit('added', -totalQuantity(items));
diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue
index 1752efe7b..0d18864dc 100644
--- a/src/pages/Order/Card/OrderDescriptor.vue
+++ b/src/pages/Order/Card/OrderDescriptor.vue
@@ -57,7 +57,6 @@ const total = ref(0);
         ref="descriptor"
         :url="`Orders/${entityId}`"
         :filter="filter"
-        module="Order"
         title="client.name"
         @on-fetch="setData"
         data-key="Order"
diff --git a/src/pages/Order/Card/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue
index 6153b2d3e..1b864de6f 100644
--- a/src/pages/Order/Card/OrderLines.vue
+++ b/src/pages/Order/Card/OrderLines.vue
@@ -238,7 +238,7 @@ watch(
         lineFilter.value.where.orderFk = router.currentRoute.value.params.id;
 
         tableLinesRef.value.reload();
-    }
+    },
 );
 </script>
 
diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue
index 21cb5ed7e..40990f329 100644
--- a/src/pages/Order/OrderList.vue
+++ b/src/pages/Order/OrderList.vue
@@ -71,8 +71,9 @@ const columns = computed(() => [
         format: (row) => row?.name,
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'isConfirmed',
+        component: 'checkbox',
         label: t('module.isConfirmed'),
     },
     {
@@ -95,7 +96,9 @@ const columns = computed(() => [
         columnField: {
             component: null,
         },
-        style: 'color="positive"',
+        style: () => {
+            return { color: 'positive' };
+        },
     },
     {
         align: 'left',
diff --git a/src/pages/Route/Agency/AgencyList.vue b/src/pages/Route/Agency/AgencyList.vue
index 4322b9bc8..5c2904bf3 100644
--- a/src/pages/Route/Agency/AgencyList.vue
+++ b/src/pages/Route/Agency/AgencyList.vue
@@ -51,7 +51,6 @@ const columns = computed(() => [
         name: 'isAnyVolumeAllowed',
         component: 'checkbox',
         cardVisible: true,
-        disable: true,
     },
     {
         align: 'right',
@@ -72,7 +71,7 @@ const columns = computed(() => [
         :data-key
         :columns="columns"
         prefix="agency"
-        :right-filter="false"
+        :right-filter="true"
         :array-data-props="{
             url: 'Agencies',
             order: 'name',
@@ -83,6 +82,7 @@ const columns = computed(() => [
             <VnTable
                 :data-key
                 :columns="columns"
+                is-editable="false"
                 :right-search="false"
                 :use-model="true"
                 redirect="route/agency"
diff --git a/src/pages/Route/Agency/Card/AgencyDescriptor.vue b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
index b9772037c..a0472c6c3 100644
--- a/src/pages/Route/Agency/Card/AgencyDescriptor.vue
+++ b/src/pages/Route/Agency/Card/AgencyDescriptor.vue
@@ -22,7 +22,6 @@ const card = computed(() => store.data);
 </script>
 <template>
     <CardDescriptor
-        module="Agency"
         data-key="Agency"
         :url="`Agencies/${entityId}`"
         :title="card?.name"
diff --git a/src/pages/Route/Card/RouteDescriptor.vue b/src/pages/Route/Card/RouteDescriptor.vue
index a8c6cc18b..829cce444 100644
--- a/src/pages/Route/Card/RouteDescriptor.vue
+++ b/src/pages/Route/Card/RouteDescriptor.vue
@@ -23,7 +23,6 @@ const entityId = computed(() => {
 </script>
 <template>
     <CardDescriptor
-        module="Route"
         :url="`Routes/${entityId}`"
         :filter="filter"
         :title="null"
diff --git a/src/pages/Route/Roadmap/RoadmapDescriptor.vue b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
index 1f1e6d6ff..baa864a15 100644
--- a/src/pages/Route/Roadmap/RoadmapDescriptor.vue
+++ b/src/pages/Route/Roadmap/RoadmapDescriptor.vue
@@ -26,12 +26,7 @@ const entityId = computed(() => {
 </script>
 
 <template>
-    <CardDescriptor
-        module="Roadmap"
-        :url="`Roadmaps/${entityId}`"
-        :filter="filter"
-        data-key="Roadmap"
-    >
+    <CardDescriptor :url="`Roadmaps/${entityId}`" :filter="filter" data-key="Roadmap">
         <template #body="{ entity }">
             <VnLv :label="t('Roadmap')" :value="entity?.name" />
             <VnLv :label="t('ETD')" :value="toDateHourMin(entity?.etd)" />
diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue
index 03d081fc8..46bc1a690 100644
--- a/src/pages/Route/RouteExtendedList.vue
+++ b/src/pages/Route/RouteExtendedList.vue
@@ -3,7 +3,7 @@ import { computed, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import { useQuasar } from 'quasar';
-import { toDate } from 'src/filters';
+import { dashIfEmpty, toDate, toHour } from 'src/filters';
 import { useRouter } from 'vue-router';
 import { usePrintService } from 'src/composables/usePrintService';
 
@@ -38,7 +38,7 @@ const routeFilter = {
 };
 const columns = computed(() => [
     {
-        align: 'left',
+        align: 'center',
         name: 'id',
         label: 'Id',
         chip: {
@@ -48,7 +48,7 @@ const columns = computed(() => [
         columnFilter: false,
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'workerFk',
         label: t('route.Worker'),
         create: true,
@@ -68,10 +68,10 @@ const columns = computed(() => [
         },
         useLike: false,
         cardVisible: true,
-        format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
+        format: (row, dashIfEmpty) => dashIfEmpty(row.workerUserName),
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'agencyModeFk',
         label: t('route.Agency'),
         isTitle: true,
@@ -87,9 +87,10 @@ const columns = computed(() => [
             },
         },
         columnClass: 'expand',
+        format: (row, dashIfEmpty) => dashIfEmpty(row.agencyName),
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'vehicleFk',
         label: t('route.Vehicle'),
         cardVisible: true,
@@ -107,29 +108,31 @@ const columns = computed(() => [
         columnFilter: {
             inWhere: true,
         },
+        format: (row, dashIfEmpty) => dashIfEmpty(row.vehiclePlateNumber),
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'dated',
         label: t('route.Date'),
         columnFilter: false,
         cardVisible: true,
         create: true,
         component: 'date',
-        format: ({ date }) => toDate(date),
+        format: ({ dated }, dashIfEmpty) =>
+            dated === '0000-00-00' ? dashIfEmpty(null) : toDate(dated),
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'from',
         label: t('route.From'),
         visible: false,
         cardVisible: true,
         create: true,
         component: 'date',
-        format: ({ date }) => toDate(date),
+        format: ({ from }) => toDate(from),
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'to',
         label: t('route.To'),
         visible: false,
@@ -146,18 +149,20 @@ const columns = computed(() => [
         columnClass: 'shrink',
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'started',
         label: t('route.hourStarted'),
         component: 'time',
         columnFilter: false,
+        format: ({ started }) => toHour(started),
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'finished',
         label: t('route.hourFinished'),
         component: 'time',
         columnFilter: false,
+        format: ({ finished }) => toHour(finished),
     },
     {
         align: 'center',
@@ -176,7 +181,7 @@ const columns = computed(() => [
         visible: false,
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'description',
         label: t('route.Description'),
         isTitle: true,
@@ -185,7 +190,7 @@ const columns = computed(() => [
         field: 'description',
     },
     {
-        align: 'left',
+        align: 'center',
         name: 'isOk',
         label: t('route.Served'),
         component: 'checkbox',
@@ -299,60 +304,62 @@ const openTicketsDialog = (id) => {
             <RouteFilter data-key="RouteList" />
         </template>
     </RightMenu>
-    <VnTable
-        class="route-list"
-        ref="tableRef"
-        data-key="RouteList"
-        url="Routes/filter"
-        :columns="columns"
-        :right-search="false"
-        :is-editable="true"
-        :filter="routeFilter"
-        redirect="route"
-        :row-click="false"
-        :create="{
-            urlCreate: 'Routes',
-            title: t('route.createRoute'),
-            onDataSaved: ({ id }) => tableRef.redirect(id),
-            formInitialData: {},
-        }"
-        save-url="Routes/crud"
-        :disable-option="{ card: true }"
-        table-height="85vh"
-        v-model:selected="selectedRows"
-        :table="{
-            'row-key': 'id',
-            selection: 'multiple',
-        }"
-    >
-        <template #moreBeforeActions>
-            <QBtn
-                icon="vn:clone"
-                color="primary"
-                class="q-mr-sm"
-                :disable="!selectedRows?.length"
-                @click="confirmationDialog = true"
-            >
-                <QTooltip>{{ t('route.Clone Selected Routes') }}</QTooltip>
-            </QBtn>
-            <QBtn
-                icon="cloud_download"
-                color="primary"
-                class="q-mr-sm"
-                :disable="!selectedRows?.length"
-                @click="showRouteReport"
-            >
-                <QTooltip>{{ t('route.Download selected routes as PDF') }}</QTooltip>
-            </QBtn>
-            <QBtn
-                icon="check"
-                color="primary"
-                class="q-mr-sm"
-                :disable="!selectedRows?.length"
-                @click="markAsServed()"
-            >
-                <QTooltip>{{ t('route.Mark as served') }}</QTooltip>
-            </QBtn>
-        </template>
-    </VnTable>
+    <QPage class="q-px-md">
+        <VnTable
+            class="route-list"
+            ref="tableRef"
+            data-key="RouteList"
+            url="Routes/filter"
+            :columns="columns"
+            :right-search="false"
+            :is-editable="true"
+            :filter="routeFilter"
+            redirect="route"
+            :row-click="false"
+            :create="{
+                urlCreate: 'Routes',
+                title: t('route.createRoute'),
+                onDataSaved: ({ id }) => tableRef.redirect(id),
+                formInitialData: {},
+            }"
+            save-url="Routes/crud"
+            :disable-option="{ card: true }"
+            table-height="85vh"
+            v-model:selected="selectedRows"
+            :table="{
+                'row-key': 'id',
+                selection: 'multiple',
+            }"
+        >
+            <template #moreBeforeActions>
+                <QBtn
+                    icon="vn:clone"
+                    color="primary"
+                    class="q-mr-sm"
+                    :disable="!selectedRows?.length"
+                    @click="confirmationDialog = true"
+                >
+                    <QTooltip>{{ t('route.Clone Selected Routes') }}</QTooltip>
+                </QBtn>
+                <QBtn
+                    icon="cloud_download"
+                    color="primary"
+                    class="q-mr-sm"
+                    :disable="!selectedRows?.length"
+                    @click="showRouteReport"
+                >
+                    <QTooltip>{{ t('route.Download selected routes as PDF') }}</QTooltip>
+                </QBtn>
+                <QBtn
+                    icon="check"
+                    color="primary"
+                    class="q-mr-sm"
+                    :disable="!selectedRows?.length"
+                    @click="markAsServed()"
+                >
+                    <QTooltip>{{ t('route.Mark as served') }}</QTooltip>
+                </QBtn>
+            </template>
+        </VnTable>
+    </QPage>
 </template>
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index bc3227f6c..9dad8ba22 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -38,6 +38,17 @@ const columns = computed(() => [
         align: 'left',
         name: 'workerFk',
         label: t('route.Worker'),
+        component: 'select',
+        attrs: {
+            url: 'Workers/activeWithInheritedRole',
+            fields: ['id', 'name'],
+            useLike: false,
+            optionFilter: 'firstName',
+            find: {
+                value: 'workerFk',
+                label: 'workerUserName',
+            },
+        },
         create: true,
         cardVisible: true,
         format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
@@ -48,6 +59,15 @@ const columns = computed(() => [
         name: 'agencyName',
         label: t('route.Agency'),
         cardVisible: true,
+        component: 'select',
+        attrs: {
+            url: 'agencyModes',
+            fields: ['id', 'name'],
+            find: {
+                value: 'agencyModeFk',
+                label: 'agencyName',
+            },
+        },
         create: true,
         columnClass: 'expand',
         columnFilter: false,
@@ -57,6 +77,17 @@ const columns = computed(() => [
         name: 'vehiclePlateNumber',
         label: t('route.Vehicle'),
         cardVisible: true,
+        component: 'select',
+        attrs: {
+            url: 'vehicles',
+            fields: ['id', 'numberPlate'],
+            optionLabel: 'numberPlate',
+            optionFilterValue: 'numberPlate',
+            find: {
+                value: 'vehicleFk',
+                label: 'vehiclePlateNumber',
+            },
+        },
         create: true,
         columnFilter: false,
     },
diff --git a/src/pages/Route/Vehicle/Card/VehicleDescriptor.vue b/src/pages/Route/Vehicle/Card/VehicleDescriptor.vue
index f31ffe847..d9a2434ab 100644
--- a/src/pages/Route/Vehicle/Card/VehicleDescriptor.vue
+++ b/src/pages/Route/Vehicle/Card/VehicleDescriptor.vue
@@ -9,7 +9,6 @@ const { notify } = useNotify();
 <template>
     <CardDescriptor
         :url="`Vehicles/${$route.params.id}`"
-        module="Vehicle"
         data-key="Vehicle"
         title="numberPlate"
         :to-module="{ name: 'VehicleList' }"
diff --git a/src/pages/Shelving/Card/ShelvingDescriptor.vue b/src/pages/Shelving/Card/ShelvingDescriptor.vue
index 9d491e36e..5e618aa7f 100644
--- a/src/pages/Shelving/Card/ShelvingDescriptor.vue
+++ b/src/pages/Shelving/Card/ShelvingDescriptor.vue
@@ -25,7 +25,6 @@ const entityId = computed(() => {
 </script>
 <template>
     <CardDescriptor
-        module="Shelving"
         :url="`Shelvings/${entityId}`"
         :filter="filter"
         title="code"
diff --git a/src/pages/Parking/Card/ParkingBasicData.vue b/src/pages/Shelving/Parking/Card/ParkingBasicData.vue
similarity index 100%
rename from src/pages/Parking/Card/ParkingBasicData.vue
rename to src/pages/Shelving/Parking/Card/ParkingBasicData.vue
diff --git a/src/pages/Parking/Card/ParkingCard.vue b/src/pages/Shelving/Parking/Card/ParkingCard.vue
similarity index 77%
rename from src/pages/Parking/Card/ParkingCard.vue
rename to src/pages/Shelving/Parking/Card/ParkingCard.vue
index 6845aeec1..b32c1b7d3 100644
--- a/src/pages/Parking/Card/ParkingCard.vue
+++ b/src/pages/Shelving/Parking/Card/ParkingCard.vue
@@ -1,6 +1,6 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
-import ParkingDescriptor from 'pages/Parking/Card/ParkingDescriptor.vue';
+import ParkingDescriptor from 'pages/Shelving/Parking/Card/ParkingDescriptor.vue';
 import filter from './ParkingFilter.js';
 </script>
 
diff --git a/src/pages/Parking/Card/ParkingDescriptor.vue b/src/pages/Shelving/Parking/Card/ParkingDescriptor.vue
similarity index 97%
rename from src/pages/Parking/Card/ParkingDescriptor.vue
rename to src/pages/Shelving/Parking/Card/ParkingDescriptor.vue
index 0b7642c1c..46c9f8ea0 100644
--- a/src/pages/Parking/Card/ParkingDescriptor.vue
+++ b/src/pages/Shelving/Parking/Card/ParkingDescriptor.vue
@@ -17,7 +17,6 @@ const entityId = computed(() => props.id || route.params.id);
 </script>
 <template>
     <CardDescriptor
-        module="Parking"
         data-key="Parking"
         :url="`Parkings/${entityId}`"
         title="code"
diff --git a/src/pages/Parking/Card/ParkingFilter.js b/src/pages/Shelving/Parking/Card/ParkingFilter.js
similarity index 100%
rename from src/pages/Parking/Card/ParkingFilter.js
rename to src/pages/Shelving/Parking/Card/ParkingFilter.js
diff --git a/src/pages/Parking/Card/ParkingLog.vue b/src/pages/Shelving/Parking/Card/ParkingLog.vue
similarity index 100%
rename from src/pages/Parking/Card/ParkingLog.vue
rename to src/pages/Shelving/Parking/Card/ParkingLog.vue
diff --git a/src/pages/Parking/Card/ParkingSummary.vue b/src/pages/Shelving/Parking/Card/ParkingSummary.vue
similarity index 100%
rename from src/pages/Parking/Card/ParkingSummary.vue
rename to src/pages/Shelving/Parking/Card/ParkingSummary.vue
diff --git a/src/pages/Parking/ParkingExprBuilder.js b/src/pages/Shelving/Parking/ParkingExprBuilder.js
similarity index 100%
rename from src/pages/Parking/ParkingExprBuilder.js
rename to src/pages/Shelving/Parking/ParkingExprBuilder.js
diff --git a/src/pages/Parking/ParkingFilter.vue b/src/pages/Shelving/Parking/ParkingFilter.vue
similarity index 100%
rename from src/pages/Parking/ParkingFilter.vue
rename to src/pages/Shelving/Parking/ParkingFilter.vue
diff --git a/src/pages/Parking/ParkingList.vue b/src/pages/Shelving/Parking/ParkingList.vue
similarity index 100%
rename from src/pages/Parking/ParkingList.vue
rename to src/pages/Shelving/Parking/ParkingList.vue
diff --git a/src/pages/Parking/locale/en.yml b/src/pages/Shelving/Parking/locale/en.yml
similarity index 100%
rename from src/pages/Parking/locale/en.yml
rename to src/pages/Shelving/Parking/locale/en.yml
diff --git a/src/pages/Parking/locale/es.yml b/src/pages/Shelving/Parking/locale/es.yml
similarity index 100%
rename from src/pages/Parking/locale/es.yml
rename to src/pages/Shelving/Parking/locale/es.yml
diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue
index 6a6feb9ef..462bdf853 100644
--- a/src/pages/Supplier/Card/SupplierDescriptor.vue
+++ b/src/pages/Supplier/Card/SupplierDescriptor.vue
@@ -62,7 +62,6 @@ const getEntryQueryParams = (supplier) => {
 
 <template>
     <CardDescriptor
-        module="Supplier"
         :url="`Suppliers/${entityId}`"
         :filter="filter"
         data-key="Supplier"
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index e569eb236..ecee5b76b 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -10,6 +10,7 @@ import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnLocation from 'src/components/common/VnLocation.vue';
 import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const route = useRoute();
 const { t } = useI18n();
@@ -182,18 +183,11 @@ function handleLocation(data, location) {
                         v-model="data.isTrucker"
                         :label="t('supplier.fiscalData.isTrucker')"
                     />
-                    <div class="row items-center">
-                        <QCheckbox v-model="data.isVies" :label="t('globals.isVies')" />
-                        <QIcon name="info" size="xs" class="cursor-pointer q-ml-sm">
-                            <QTooltip>
-                                {{
-                                    t(
-                                        'When activating it, do not enter the country code in the ID field.'
-                                    )
-                                }}
-                            </QTooltip>
-                        </QIcon>
-                    </div>
+                    <VnCheckbox
+                        v-model="data.isVies"
+                        :label="t('globals.isVies')" 
+                        :info="t('whenActivatingIt')" 
+                    />
                 </div>
             </VnRow>
         </template>
@@ -201,6 +195,8 @@ function handleLocation(data, location) {
 </template>
 
 <i18n>
+en:
+    whenActivatingIt: When activating it, do not enter the country code in the ID field.
 es:
-    When activating it, do not enter the country code in the ID field.: Al activarlo, no informar el código del país en el campo nif
+    whenActivatingIt: Al activarlo, no informar el código del país en el campo nif.
 </i18n>
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
index 44f2bf7fb..055c9a0ff 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
@@ -9,6 +9,7 @@ import FetchData from 'components/FetchData.vue';
 import { useStateStore } from 'stores/useStateStore';
 import { toCurrency } from 'filters/index';
 import { useRole } from 'src/composables/useRole';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 const haveNegatives = defineModel('have-negatives', { type: Boolean, required: true });
 const formData = defineModel({ type: Object, required: true });
@@ -182,22 +183,19 @@ onMounted(async () => {
         </QCard>
         <QCard
             v-if="haveNegatives"
-            class="q-pa-md q-mb-md q-ma-md color-vn-text"
+            class="q-pa-xs q-mb-md q-ma-md color-vn-text"
             bordered
             flat
             style="border-color: black"
         >
             <QCardSection horizontal class="flex row items-center">
-                <QCheckbox
-                    :label="t('basicData.withoutNegatives')"
+                <VnCheckbox
                     v-model="formData.withoutNegatives"
+                    :label="t('basicData.withoutNegatives')"
+                    :info="t('basicData.withoutNegativesInfo')"
                     :toggle-indeterminate="false"
+                    size="xs"
                 />
-                <QIcon name="info" size="xs" class="q-ml-sm">
-                    <QTooltip max-width="350px">
-                        {{ t('basicData.withoutNegativesInfo') }}
-                    </QTooltip>
-                </QIcon>
             </QCardSection>
         </QCard>
     </QDrawer>
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
index cf4481537..9d70fea38 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
@@ -260,7 +260,7 @@ async function getZone(options) {
         auto-load
     />
     <QForm>
-        <VnRow>
+        <VnRow class="row q-gutter-md q-mb-md no-wrap">
             <VnSelect
                 :label="t('ticketList.client')"
                 v-model="clientId"
@@ -296,7 +296,7 @@ async function getZone(options) {
                 :rules="validate('ticketList.warehouse')"
             />
         </VnRow>
-        <VnRow>
+        <VnRow class="row q-gutter-md q-mb-md no-wrap">
             <VnSelect
                 :label="t('basicData.address')"
                 v-model="addressId"
diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue
index 762db19bf..c5f3233b1 100644
--- a/src/pages/Ticket/Card/TicketDescriptor.vue
+++ b/src/pages/Ticket/Card/TicketDescriptor.vue
@@ -44,7 +44,6 @@ function ticketFilter(ticket) {
         @on-fetch="(data) => ([problems] = data)"
     />
     <CardDescriptor
-        module="Ticket"
         :url="`Tickets/${entityId}`"
         :filter="filter"
         data-key="Ticket"
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 97d87ccf8..004bcbe79 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -14,7 +14,7 @@ import VnImg from 'src/components/ui/VnImg.vue';
 
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
-import TicketTransfer from './TicketTransfer.vue';
+import TicketTransferProxy from './TicketTransferProxy.vue';
 
 import { toCurrency, toPercentage } from 'src/filters';
 import { useArrayData } from 'composables/useArrayData';
@@ -609,8 +609,9 @@ watch(
                     @click="setTransferParams()"
                     data-cy="ticketSaleTransferBtn"
                 >
-                    <QTooltip>{{ t('Transfer lines') }}</QTooltip>
-                    <TicketTransfer
+                    <QTooltip>{{ t('ticketSale.transferLines') }}</QTooltip>
+                    <TicketTransferProxy
+                        class="full-width"
                         :transfer="transfer"
                         :ticket="store.data"
                         @refresh-data="resetChanges()"
diff --git a/src/pages/Ticket/Card/TicketSplit.vue b/src/pages/Ticket/Card/TicketSplit.vue
new file mode 100644
index 000000000..e79057266
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketSplit.vue
@@ -0,0 +1,37 @@
+<script setup>
+import { ref } from 'vue';
+
+import VnInputDate from 'src/components/common/VnInputDate.vue';
+import split from './components/split';
+const emit = defineEmits(['ticketTransfered']);
+
+const $props = defineProps({
+    ticket: {
+        type: [Array, Object],
+        default: () => {},
+    },
+});
+
+const splitDate = ref(Date.vnNew());
+
+const splitSelectedRows = async () => {
+    const tickets = Array.isArray($props.ticket) ? $props.ticket : [$props.ticket];
+    await split(tickets, splitDate.value);
+    emit('ticketTransfered', tickets);
+};
+</script>
+
+<template>
+    <VnInputDate class="q-mr-sm" :label="$t('New date')" v-model="splitDate" clearable />
+    <QBtn class="q-mr-sm" color="primary" label="Split" @click="splitSelectedRows"></QBtn>
+</template>
+<style lang="scss">
+.q-table__bottom.row.items-center.q-table__bottom--nodata {
+    border-top: none;
+}
+</style>
+<i18n>
+es:
+    Sales to transfer: Líneas a transferir
+    Destination ticket: Ticket destinatario
+</i18n>
diff --git a/src/pages/Ticket/Card/TicketTransfer.vue b/src/pages/Ticket/Card/TicketTransfer.vue
index 005d74a0e..ffa964c92 100644
--- a/src/pages/Ticket/Card/TicketTransfer.vue
+++ b/src/pages/Ticket/Card/TicketTransfer.vue
@@ -1,11 +1,11 @@
 <script setup>
 import { ref, computed, onMounted } from 'vue';
 import { useI18n } from 'vue-i18n';
-
 import VnInput from 'src/components/common/VnInput.vue';
 import TicketTransferForm from './TicketTransferForm.vue';
 
 import { toDateFormat } from 'src/filters/date.js';
+const emit = defineEmits(['ticketTransfered']);
 
 const $props = defineProps({
     mana: {
@@ -21,16 +21,15 @@ const $props = defineProps({
         default: () => {},
     },
     ticket: {
-        type: Object,
+        type: [Array, Object],
         default: () => {},
     },
 });
 
+onMounted(() => (_transfer.value = $props.transfer));
 const { t } = useI18n();
-const QPopupProxyRef = ref(null);
 const transferFormRef = ref(null);
 const _transfer = ref();
-
 const transferLinesColumns = computed(() => [
     {
         label: t('ticketList.id'),
@@ -86,76 +85,74 @@ const handleRowClick = (row) => {
         transferFormRef.value.transferSales(ticketId);
     }
 };
-
-onMounted(() => (_transfer.value = $props.transfer));
 </script>
 
 <template>
-    <QPopupProxy ref="QPopupProxyRef" data-cy="ticketTransferPopup">
-        <QCard class="q-px-md" style="display: flex; width: 80vw">
-            <QTable
-                :rows="transfer.sales"
-                :columns="transferLinesColumns"
-                :title="t('Sales to transfer')"
-                row-key="id"
-                :pagination="{ rowsPerPage: 0 }"
-                class="full-width q-mt-md"
-                :no-data-label="t('globals.noResults')"
-            >
-                <template #body-cell-quantity="{ row }">
-                    <QTd @click.stop>
-                        <VnInput
-                            v-model.number="row.quantity"
-                            :clearable="false"
-                            style="max-width: 60px"
-                        />
-                    </QTd>
-                </template>
-            </QTable>
-            <QSeparator vertical spaced />
-            <QTable
-                v-if="transfer.lastActiveTickets"
-                :rows="transfer.lastActiveTickets"
-                :columns="destinationTicketColumns"
-                :title="t('Destination ticket')"
-                row-key="id"
-                class="full-width q-mt-md"
-                @row-click="(_, row) => handleRowClick(row)"
-            >
-                <template #body-cell-address="{ row }">
-                    <QTd @click.stop>
-                        <span>
-                            {{ row.nickname }}
-                            {{ row.name }}
-                            {{ row.street }}
-                            {{ row.postalCode }}
-                            {{ row.city }}
-                        </span>
-                        <QTooltip>
-                            {{ row.nickname }}
-                            {{ row.name }}
-                            {{ row.street }}
-                            {{ row.postalCode }}
-                            {{ row.city }}
-                        </QTooltip>
-                    </QTd>
-                </template>
+    <QTable
+        :rows="transfer.sales"
+        :columns="transferLinesColumns"
+        :title="t('Sales to transfer')"
+        row-key="id"
+        :pagination="{ rowsPerPage: 0 }"
+        class="full-width q-mt-md"
+        :no-data-label="t('globals.noResults')"
+    >
+        <template #body-cell-quantity="{ row }">
+            <QTd @click.stop>
+                <VnInput
+                    v-model.number="row.quantity"
+                    :clearable="false"
+                    style="max-width: 60px"
+                />
+            </QTd>
+        </template>
+    </QTable>
+    <QSeparator vertical spaced />
+    <QTable
+        v-if="transfer.lastActiveTickets"
+        :rows="transfer.lastActiveTickets"
+        :columns="destinationTicketColumns"
+        :title="t('Destination ticket')"
+        row-key="id"
+        class="full-width q-mt-md"
+        @row-click="(_, row) => handleRowClick(row)"
+        :no-data-label="t('globals.noResults')"
+        :pagination="{ rowsPerPage: 0 }"
+    >
+        <template #body-cell-address="{ row }">
+            <QTd @click.stop>
+                <span>
+                    {{ row.nickname }}
+                    {{ row.name }}
+                    {{ row.street }}
+                    {{ row.postalCode }}
+                    {{ row.city }}
+                </span>
+                <QTooltip>
+                    {{ row.nickname }}
+                    {{ row.name }}
+                    {{ row.street }}
+                    {{ row.postalCode }}
+                    {{ row.city }}
+                </QTooltip>
+            </QTd>
+        </template>
 
-                <template #no-data>
-                    <TicketTransferForm ref="transferFormRef" v-bind="$props" />
-                </template>
-                <template #bottom>
-                    <TicketTransferForm ref="transferFormRef" v-bind="$props" />
-                </template>
-            </QTable>
-        </QCard>
-    </QPopupProxy>
+        <template #no-data>
+            <TicketTransferForm ref="transferFormRef" v-bind="$props" />
+        </template>
+        <template #bottom>
+            <TicketTransferForm ref="transferFormRef" v-bind="$props" />
+        </template>
+    </QTable>
 </template>
-
+<style lang="scss">
+.q-table__bottom.row.items-center.q-table__bottom--nodata {
+    border-top: none;
+}
+</style>
 <i18n>
 es:
     Sales to transfer: Líneas a transferir
     Destination ticket: Ticket destinatario
-    Transfer to ticket: Transferir a ticket
-    New ticket: Nuevo ticket
 </i18n>
diff --git a/src/pages/Ticket/Card/TicketTransferProxy.vue b/src/pages/Ticket/Card/TicketTransferProxy.vue
new file mode 100644
index 000000000..3f3f018df
--- /dev/null
+++ b/src/pages/Ticket/Card/TicketTransferProxy.vue
@@ -0,0 +1,54 @@
+<script setup>
+import { ref } from 'vue';
+import TicketTransfer from './TicketTransfer.vue';
+import Split from './TicketSplit.vue';
+const emit = defineEmits(['ticketTransfered']);
+
+const $props = defineProps({
+    mana: {
+        type: Number,
+        default: null,
+    },
+    newPrice: {
+        type: Number,
+        default: 0,
+    },
+    transfer: {
+        type: Object,
+        default: () => {},
+    },
+    ticket: {
+        type: [Array, Object],
+        default: () => {},
+    },
+    split: {
+        type: Boolean,
+        default: false,
+    },
+});
+
+const popupProxyRef = ref(null);
+const splitRef = ref(null);
+const transferRef = ref(null);
+</script>
+
+<template>
+    <QPopupProxy ref="popupProxyRef" data-cy="ticketTransferPopup">
+        <div class="flex row items-center q-ma-lg" v-if="$props.split">
+            <Split
+                ref="splitRef"
+                @splitSelectedRows="splitSelectedRows"
+                :ticket="$props.ticket"
+            />
+        </div>
+
+        <div v-else>
+            <TicketTransfer
+                ref="transferRef"
+                :ticket="$props.ticket"
+                :sales="$props.sales"
+                :transfer="$props.transfer"
+            />
+        </div>
+    </QPopupProxy>
+</template>
diff --git a/src/pages/Ticket/Card/components/split.js b/src/pages/Ticket/Card/components/split.js
new file mode 100644
index 000000000..afa1d5cd6
--- /dev/null
+++ b/src/pages/Ticket/Card/components/split.js
@@ -0,0 +1,22 @@
+import axios from 'axios';
+import notifyResults from 'src/utils/notifyResults';
+
+export default async function (data, date) {
+    const reducedData = data.reduce((acc, item) => {
+        const existing = acc.find(({ ticketFk }) => ticketFk === item.id);
+        if (existing) {
+            existing.sales.push(item.saleFk);
+        } else {
+            acc.push({ ticketFk: item.id, sales: [item.saleFk], date });
+        }
+        return acc;
+    }, []);
+
+    const promises = reducedData.map((params) => axios.post(`Tickets/split`, params));
+
+    const results = await Promise.allSettled(promises);
+
+    notifyResults(results, 'ticketFk');
+
+    return results;
+}
diff --git a/src/pages/Ticket/Negative/TicketLackDetail.vue b/src/pages/Ticket/Negative/TicketLackDetail.vue
new file mode 100644
index 000000000..dcf835d03
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackDetail.vue
@@ -0,0 +1,198 @@
+<script setup>
+import { computed, onMounted, onUnmounted, ref } from 'vue';
+import { useI18n } from 'vue-i18n';
+import ChangeQuantityDialog from './components/ChangeQuantityDialog.vue';
+import ChangeStateDialog from './components/ChangeStateDialog.vue';
+import ChangeItemDialog from './components/ChangeItemDialog.vue';
+import TicketTransferProxy from '../Card/TicketTransferProxy.vue';
+import FetchData from 'src/components/FetchData.vue';
+import { useStateStore } from 'stores/useStateStore';
+import { useState } from 'src/composables/useState';
+
+import { useRoute } from 'vue-router';
+import TicketLackTable from './TicketLackTable.vue';
+import VnPopupProxy from 'src/components/common/VnPopupProxy.vue';
+import ItemProposalProxy from 'src/pages/Item/components/ItemProposalProxy.vue';
+
+import { useQuasar } from 'quasar';
+const quasar = useQuasar();
+const { t } = useI18n();
+const editableStates = ref([]);
+const stateStore = useStateStore();
+const tableRef = ref();
+const changeItemDialogRef = ref(null);
+const changeStateDialogRef = ref(null);
+const changeQuantityDialogRef = ref(null);
+const showProposalDialog = ref(false);
+const showChangeQuantityDialog = ref(false);
+const selectedRows = ref([]);
+const route = useRoute();
+onMounted(() => {
+    stateStore.rightDrawer = false;
+});
+onUnmounted(() => {
+    stateStore.rightDrawer = true;
+});
+
+const entityId = computed(() => route.params.id);
+const item = ref({});
+
+const itemProposalSelected = ref(null);
+const reload = async () => {
+    tableRef.value.tableRef.reload();
+};
+defineExpose({ reload });
+const filter = computed(() => ({
+    scopeDays: route.query.days,
+    showType: true,
+    alertLevelCode: 'FREE',
+    date: Date.vnNew(),
+    warehouseFk: useState().getUser().value.warehouseFk,
+}));
+const itemProposalEvt = (data) => {
+    const { itemProposal } = data;
+    itemProposalSelected.value = itemProposal;
+    reload();
+};
+
+function onBuysFetched(data) {
+    Object.assign(item.value, data[0]);
+}
+const showItemProposal = () => {
+    quasar
+        .dialog({
+            component: ItemProposalProxy,
+            componentProps: {
+                itemLack: tableRef.value.itemLack,
+                replaceAction: true,
+                sales: selectedRows.value,
+            },
+        })
+        .onOk(itemProposalEvt);
+};
+</script>
+
+<template>
+    <FetchData
+        url="States/editableStates"
+        @on-fetch="(data) => (editableStates = data)"
+        auto-load
+    />
+    <FetchData
+        :url="`Items/${entityId}/getCard`"
+        :fields="['longName']"
+        @on-fetch="(data) => (item = data)"
+        auto-load
+    />
+    <FetchData
+        :url="`Buys/latestBuysFilter`"
+        :fields="['longName']"
+        :filter="{ where: { 'i.id': entityId } }"
+        @on-fetch="onBuysFetched"
+        auto-load
+    />
+
+    <TicketLackTable
+        ref="tableRef"
+        :filter="filter"
+        @update:selection="({ value }, _) => (selectedRows = value)"
+    >
+        <template #top-right>
+            <QBtnGroup push class="q-mr-lg" style="column-gap: 1px">
+                <QBtn
+                    data-cy="transferLines"
+                    color="primary"
+                    :disable="!(selectedRows.length === 1)"
+                >
+                    <template #default>
+                        <QIcon name="vn:splitline" />
+                        <QIcon name="vn:ticket" />
+
+                        <QTooltip>{{ t('ticketSale.transferLines') }} </QTooltip>
+                        <TicketTransferProxy
+                            ref="transferFormRef"
+                            split="true"
+                            :ticket="selectedRows"
+                            :transfer="{
+                                sales: selectedRows,
+                                lastActiveTickets: selectedRows.map((row) => row.id),
+                            }"
+                            @ticket-transfered="reload"
+                        ></TicketTransferProxy>
+                    </template>
+                </QBtn>
+                <QBtn
+                    color="primary"
+                    @click="showProposalDialog = true"
+                    :disable="selectedRows.length < 1"
+                    data-cy="itemProposal"
+                >
+                    <QIcon
+                        name="import_export"
+                        class="rotate-90"
+                        @click="showItemProposal"
+                    ></QIcon>
+                    <QTooltip bottom anchor="bottom right">
+                        {{ t('itemProposal') }}
+                    </QTooltip>
+                </QBtn>
+                <VnPopupProxy
+                    data-cy="changeItem"
+                    icon="sync"
+                    :disable="selectedRows.length < 1"
+                    :tooltip="t('negative.detail.modal.changeItem.title')"
+                >
+                    <template #extraIcon> <QIcon name="vn:item" /> </template>
+                    <template v-slot="{ popup }">
+                        <ChangeItemDialog
+                            ref="changeItemDialogRef"
+                            @update-item="popup.hide()"
+                            :selected-rows="selectedRows"
+                    /></template>
+                </VnPopupProxy>
+                <VnPopupProxy
+                    data-cy="changeState"
+                    icon="sync"
+                    :disable="selectedRows.length < 1"
+                    :tooltip="t('negative.detail.modal.changeState.title')"
+                >
+                    <template #extraIcon> <QIcon name="vn:eye" /> </template>
+                    <template v-slot="{ popup }">
+                        <ChangeStateDialog
+                            ref="changeStateDialogRef"
+                            @update-state="popup.hide()"
+                            :selected-rows="selectedRows"
+                    /></template>
+                </VnPopupProxy>
+                <VnPopupProxy
+                    data-cy="changeQuantity"
+                    icon="sync"
+                    :disable="selectedRows.length < 1"
+                    :tooltip="t('negative.detail.modal.changeQuantity.title')"
+                    @click="showChangeQuantityDialog = true"
+                >
+                    <template #extraIcon> <QIcon name="exposure" /> </template>
+                    <template v-slot="{ popup }">
+                        <ChangeQuantityDialog
+                            ref="changeQuantityDialogRef"
+                            @update-quantity="popup.hide()"
+                            :selected-rows="selectedRows"
+                    /></template>
+                </VnPopupProxy> </QBtnGroup
+        ></template>
+    </TicketLackTable>
+</template>
+<style lang="scss" scoped>
+.list-enter-active,
+.list-leave-active {
+    transition: all 1s ease;
+}
+.list-enter-from,
+.list-leave-to {
+    opacity: 0;
+    background-color: $primary;
+}
+.q-table.q-table__container > div:first-child {
+    border-radius: unset;
+}
+</style>
diff --git a/src/pages/Ticket/Negative/TicketLackFilter.vue b/src/pages/Ticket/Negative/TicketLackFilter.vue
new file mode 100644
index 000000000..3762f453d
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackFilter.vue
@@ -0,0 +1,175 @@
+<script setup>
+import { ref } from 'vue';
+import { useI18n } from 'vue-i18n';
+
+import FetchData from 'components/FetchData.vue';
+import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
+import VnInput from 'src/components/common/VnInput.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+const { t } = useI18n();
+const props = defineProps({
+    dataKey: {
+        type: String,
+        required: true,
+    },
+});
+
+const to = Date.vnNew();
+to.setDate(to.getDate() + 1);
+
+const warehouses = ref();
+const categoriesOptions = ref([]);
+const itemTypesRef = ref(null);
+const itemTypesOptions = ref([]);
+
+const itemTypesFilter = {
+    fields: ['id', 'name', 'categoryFk'],
+    include: 'category',
+    order: 'name ASC',
+    where: {},
+};
+const onCategoryChange = async (categoryFk, search) => {
+    if (!categoryFk) {
+        itemTypesFilter.where.categoryFk = null;
+        delete itemTypesFilter.where.categoryFk;
+    } else {
+        itemTypesFilter.where.categoryFk = categoryFk;
+    }
+    search();
+    await itemTypesRef.value.fetch();
+};
+const emit = defineEmits(['set-user-params']);
+
+const setUserParams = (params) => {
+    emit('set-user-params', params);
+};
+</script>
+
+<template>
+    <FetchData url="Warehouses" @on-fetch="(data) => (warehouses = data)" auto-load />
+    <FetchData
+        url="ItemCategories"
+        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
+        @on-fetch="(data) => (categoriesOptions = data)"
+        auto-load
+    />
+
+    <FetchData
+        ref="itemTypesRef"
+        url="ItemTypes"
+        :filter="itemTypesFilter"
+        @on-fetch="(data) => (itemTypesOptions = data)"
+        auto-load
+    />
+
+    <VnFilterPanel
+        :data-key="props.dataKey"
+        :search-button="true"
+        @set-user-params="setUserParams"
+    >
+        <template #tags="{ tag, formatFn }">
+            <div class="q-gutter-x-xs">
+                <strong>{{ t(`negative.${tag.label}`) }}</strong>
+                <span>{{ formatFn(tag.value) }}</span>
+            </div>
+        </template>
+        <template #body="{ params, searchFn }">
+            <QList dense class="q-gutter-y-sm q-mt-sm">
+                <QItem>
+                    <QItemSection>
+                        <VnInput
+                            v-model="params.days"
+                            :label="t('negative.days')"
+                            dense
+                            is-outlined
+                            type="number"
+                            @update:model-value="
+                                (value) => {
+                                    setUserParams(params);
+                                }
+                            "
+                        />
+                    </QItemSection>
+                </QItem>
+                <QItem>
+                    <QItemSection>
+                        <VnInput
+                            v-model="params.id"
+                            :label="t('negative.id')"
+                            dense
+                            is-outlined
+                        />
+                    </QItemSection>
+                </QItem>
+                <QItem>
+                    <QItemSection>
+                        <VnInput
+                            v-model="params.producer"
+                            :label="t('negative.producer')"
+                            dense
+                            is-outlined
+                        />
+                    </QItemSection>
+                </QItem>
+                <QItem>
+                    <QItemSection>
+                        <VnInput
+                            v-model="params.origen"
+                            :label="t('negative.origen')"
+                            dense
+                            is-outlined
+                        />
+                    </QItemSection> </QItem
+                ><QItem>
+                    <QItemSection v-if="categoriesOptions">
+                        <VnSelect
+                            :label="t('negative.categoryFk')"
+                            v-model="params.categoryFk"
+                            @update:model-value="
+                                ($event) => onCategoryChange($event, searchFn)
+                            "
+                            :options="categoriesOptions"
+                            option-value="id"
+                            option-label="name"
+                            hide-selected
+                            dense
+                            outlined
+                            rounded
+                        /> </QItemSection
+                    ><QItemSection v-else>
+                        <QSkeleton class="full-width" type="QSelect" />
+                    </QItemSection>
+                </QItem>
+                <QItem>
+                    <QItemSection v-if="itemTypesOptions">
+                        <VnSelect
+                            :label="t('negative.type')"
+                            v-model="params.typeFk"
+                            @update:model-value="searchFn()"
+                            :options="itemTypesOptions"
+                            option-value="id"
+                            option-label="name"
+                            hide-selected
+                            dense
+                            outlined
+                            rounded
+                        >
+                            <template #option="scope">
+                                <QItem v-bind="scope.itemProps">
+                                    <QItemSection>
+                                        <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
+                                        <QItemLabel caption>{{
+                                            scope.opt?.category?.name
+                                        }}</QItemLabel>
+                                    </QItemSection>
+                                </QItem>
+                            </template>
+                        </VnSelect> </QItemSection
+                    ><QItemSection v-else>
+                        <QSkeleton class="full-width" type="QSelect" />
+                    </QItemSection>
+                </QItem>
+            </QList>
+        </template>
+    </VnFilterPanel>
+</template>
diff --git a/src/pages/Ticket/Negative/TicketLackList.vue b/src/pages/Ticket/Negative/TicketLackList.vue
new file mode 100644
index 000000000..d1e8b823a
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackList.vue
@@ -0,0 +1,227 @@
+<script setup>
+import { computed, ref, reactive } from 'vue';
+import { useI18n } from 'vue-i18n';
+import { useStateStore } from 'stores/useStateStore';
+import VnTable from 'components/VnTable/VnTable.vue';
+import { onBeforeMount } from 'vue';
+import { dashIfEmpty, toDate, toHour } from 'src/filters';
+import { useRouter } from 'vue-router';
+import { useState } from 'src/composables/useState';
+import { useRole } from 'src/composables/useRole';
+import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
+import RightMenu from 'src/components/common/RightMenu.vue';
+import TicketLackFilter from './TicketLackFilter.vue';
+onBeforeMount(() => {
+    stateStore.$state.rightDrawer = true;
+});
+const router = useRouter();
+const stateStore = useStateStore();
+const { t } = useI18n();
+const selectedRows = ref([]);
+const tableRef = ref();
+const filterParams = ref({});
+const negativeParams = reactive({
+    days: useRole().likeAny('buyer') ? 2 : 0,
+    warehouseFk: useState().getUser().value.warehouseFk,
+});
+const redirectToCreateView = ({ itemFk }) => {
+    router.push({
+        name: 'NegativeDetail',
+        params: { id: itemFk },
+        query: { days: filterParams.value.days ?? negativeParams.days },
+    });
+};
+const columns = computed(() => [
+    {
+        name: 'date',
+        align: 'center',
+        label: t('negative.date'),
+        format: ({ timed }) => toDate(timed),
+        sortable: true,
+        cardVisible: true,
+        isId: true,
+        columnFilter: {
+            component: 'date',
+        },
+    },
+    {
+        columnClass: 'shrink',
+        name: 'timed',
+        align: 'center',
+        label: t('negative.timed'),
+        format: ({ timed }) => toHour(timed),
+        sortable: true,
+        cardVisible: true,
+        columnFilter: {
+            component: 'time',
+        },
+    },
+    {
+        name: 'itemFk',
+        align: 'center',
+        label: t('negative.id'),
+        format: ({ itemFk }) => itemFk,
+        sortable: true,
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+            columnClass: 'shrink',
+        },
+    },
+    {
+        name: 'longName',
+        align: 'center',
+        label: t('negative.longName'),
+        field: ({ longName }) => longName,
+
+        sortable: true,
+        headerStyle: 'width: 350px',
+        cardVisible: true,
+        columnClass: 'expand',
+    },
+    {
+        name: 'producer',
+        align: 'center',
+        label: t('negative.supplier'),
+        field: ({ producer }) => dashIfEmpty(producer),
+        sortable: true,
+        columnClass: 'shrink',
+    },
+    {
+        name: 'inkFk',
+        align: 'center',
+        label: t('negative.colour'),
+        field: ({ inkFk }) => inkFk,
+        sortable: true,
+        cardVisible: true,
+    },
+    {
+        name: 'size',
+        align: 'center',
+        label: t('negative.size'),
+        field: ({ size }) => size,
+        sortable: true,
+        cardVisible: true,
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+            columnClass: 'shrink',
+        },
+    },
+    {
+        name: 'category',
+        align: 'center',
+        label: t('negative.origen'),
+        field: ({ category }) => dashIfEmpty(category),
+        sortable: true,
+        cardVisible: true,
+    },
+    {
+        name: 'lack',
+        align: 'center',
+        label: t('negative.lack'),
+        field: ({ lack }) => lack,
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+            columnClass: 'shrink',
+        },
+        sortable: true,
+        headerStyle: 'padding-center: 33px',
+        cardVisible: true,
+    },
+    {
+        name: 'tableActions',
+        align: 'center',
+        actions: [
+            {
+                title: t('Open details'),
+                icon: 'edit',
+                action: redirectToCreateView,
+                isPrimary: true,
+            },
+        ],
+    },
+]);
+
+const setUserParams = (params) => {
+    filterParams.value = params;
+};
+</script>
+
+<template>
+    <RightMenu>
+        <template #right-panel>
+            <TicketLackFilter data-key="NegativeList" @set-user-params="setUserParams" />
+        </template>
+    </RightMenu>
+    {{ filterRef }}
+    <VnTable
+        ref="tableRef"
+        data-key="NegativeList"
+        :url="`Tickets/itemLack`"
+        :order="['itemFk DESC, date DESC, timed DESC']"
+        :user-params="negativeParams"
+        auto-load
+        :columns="columns"
+        default-mode="table"
+        :right-search="false"
+        :is-editable="false"
+        :use-model="true"
+        :map-key="false"
+        :row-click="redirectToCreateView"
+        v-model:selected="selectedRows"
+        :create="false"
+        :crud-model="{
+            disableInfiniteScroll: true,
+        }"
+        :table="{
+            'row-key': 'itemFk',
+            selection: 'multiple',
+        }"
+    >
+        <template #column-itemFk="{ row }">
+            <div
+                style="display: flex; justify-content: space-around; align-items: center"
+            >
+                <span @click.stop>{{ row.itemFk }}</span>
+            </div>
+        </template>
+        <template #column-longName="{ row }">
+            <span class="link" @click.stop>
+                {{ row.longName }}
+                <ItemDescriptorProxy :id="row.itemFk" />
+            </span>
+        </template>
+    </VnTable>
+</template>
+
+<style lang="scss" scoped>
+.list {
+    max-height: 100%;
+    padding: 15px;
+    width: 100%;
+}
+
+.grid-style-transition {
+    transition:
+        transform 0.28s,
+        background-color 0.28s;
+}
+
+#true {
+    background-color: $positive;
+}
+
+#false {
+    background-color: $negative;
+}
+
+div.q-dialog__inner > div {
+    max-width: fit-content !important;
+}
+.q-btn-group > .q-btn-item:not(:first-child) {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+}
+</style>
diff --git a/src/pages/Ticket/Negative/TicketLackTable.vue b/src/pages/Ticket/Negative/TicketLackTable.vue
new file mode 100644
index 000000000..176e8f7ad
--- /dev/null
+++ b/src/pages/Ticket/Negative/TicketLackTable.vue
@@ -0,0 +1,356 @@
+<script setup>
+import FetchedTags from 'components/ui/FetchedTags.vue';
+import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
+import { computed, ref, watch } from 'vue';
+import { useI18n } from 'vue-i18n';
+import axios from 'axios';
+import FetchData from 'src/components/FetchData.vue';
+import { toDate, toHour } from 'src/filters';
+import useNotify from 'src/composables/useNotify.js';
+import ZoneDescriptorProxy from 'pages/Zone/Card/ZoneDescriptorProxy.vue';
+import { useRoute } from 'vue-router';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+import TicketDescriptorProxy from '../Card/TicketDescriptorProxy.vue';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
+
+const $props = defineProps({
+    filter: {
+        type: Object,
+        default: () => ({}),
+    },
+});
+
+watch(
+    () => $props.filter,
+    (v) => {
+        filterLack.value.where = v;
+        tableRef.value.reload(filterLack);
+    },
+);
+
+const filterLack = ref({
+    include: [
+        {
+            relation: 'workers',
+            scope: {
+                fields: ['id', 'firstName'],
+            },
+        },
+    ],
+    where: { ...$props.filter },
+    order: 'ts.alertLevelCode ASC',
+});
+
+const selectedRows = ref([]);
+const { t } = useI18n();
+const { notify } = useNotify();
+const entityId = computed(() => route.params.id);
+const item = ref({});
+const route = useRoute();
+const columns = computed(() => [
+    {
+        name: 'status',
+        align: 'center',
+        sortable: false,
+        columnClass: 'shrink',
+        columnFilter: false,
+    },
+    {
+        name: 'ticketFk',
+        label: t('negative.detail.ticketFk'),
+        align: 'center',
+        sortable: true,
+        columnFilter: {
+            component: 'input',
+            type: 'number',
+        },
+    },
+    {
+        name: 'shipped',
+        label: t('negative.detail.shipped'),
+        field: 'shipped',
+        align: 'center',
+        format: ({ shipped }) => toDate(shipped),
+        sortable: true,
+        columnFilter: {
+            component: 'date',
+            columnClass: 'shrink',
+        },
+    },
+    {
+        name: 'minTimed',
+        label: t('negative.detail.theoreticalhour'),
+        field: 'minTimed',
+        align: 'center',
+        sortable: true,
+        component: 'time',
+        columnFilter: {},
+    },
+    {
+        name: 'alertLevelCode',
+        label: t('negative.detail.state'),
+        columnFilter: {
+            name: 'alertLevelCode',
+            component: 'select',
+            attrs: {
+                url: 'AlertLevels',
+                fields: ['name', 'code'],
+                optionLabel: 'code',
+                optionValue: 'code',
+            },
+        },
+        align: 'center',
+        sortable: true,
+    },
+    {
+        name: 'zoneName',
+        label: t('negative.detail.zoneName'),
+        field: 'zoneName',
+        align: 'center',
+        sortable: true,
+    },
+    {
+        name: 'nickname',
+        label: t('negative.detail.nickname'),
+        field: 'nickname',
+        align: 'center',
+        sortable: true,
+    },
+    {
+        name: 'quantity',
+        label: t('negative.detail.quantity'),
+        field: 'quantity',
+        sortable: true,
+        component: 'input',
+        type: 'number',
+    },
+]);
+
+const emit = defineEmits(['update:selection']);
+const itemLack = ref(null);
+const fetchItemLack = ref(null);
+const tableRef = ref(null);
+defineExpose({ tableRef, itemLack });
+watch(selectedRows, () => emit('update:selection', selectedRows));
+const getInputEvents = ({ col, ...rows }) => ({
+    'update:modelValue': () => saveChange(col.name, rows),
+    'keyup.enter': () => saveChange(col.name, rows),
+});
+const saveChange = async (field, { row }) => {
+    try {
+        switch (field) {
+            case 'alertLevelCode':
+                await axios.post(`Tickets/state`, {
+                    ticketFk: row.ticketFk,
+                    code: row[field],
+                });
+                break;
+
+            case 'quantity':
+                await axios.post(`Sales/${row.saleFk}/updateQuantity`, {
+                    quantity: +row.quantity,
+                });
+                break;
+        }
+        notify('globals.dataSaved', 'positive');
+        fetchItemLack.value.fetch();
+    } catch (err) {
+        console.error('Error saving changes', err);
+        f;
+    }
+};
+
+function onBuysFetched(data) {
+    Object.assign(item.value, data[0]);
+}
+</script>
+
+<template>
+    <FetchData
+        ref="fetchItemLack"
+        :url="`Tickets/itemLack`"
+        :params="{ id: entityId }"
+        @on-fetch="(data) => (itemLack = data[0])"
+        auto-load
+    />
+    <FetchData
+        :url="`Items/${entityId}/getCard`"
+        :fields="['longName']"
+        @on-fetch="(data) => (item = data)"
+        auto-load
+    />
+    <FetchData
+        :url="`Buys/latestBuysFilter`"
+        :fields="['longName']"
+        :filter="{ where: { 'i.id': entityId } }"
+        @on-fetch="onBuysFetched"
+        auto-load
+    />
+    <VnTable
+        ref="tableRef"
+        data-key="NegativeItem"
+        :map-key="false"
+        :url="`Tickets/itemLack/${entityId}`"
+        :columns="columns"
+        auto-load
+        :create="false"
+        :create-as-dialog="false"
+        :use-model="true"
+        :filter="filterLack"
+        :order="['ts.alertLevelCode ASC']"
+        :table="{
+            'row-key': 'id',
+            selection: 'multiple',
+        }"
+        dense
+        :is-editable="true"
+        :row-click="false"
+        :right-search="false"
+        :right-search-icon="false"
+        v-model:selected="selectedRows"
+        :disable-option="{ card: true }"
+    >
+        <template #top-left>
+            <div style="display: flex; align-items: center" v-if="itemLack">
+                <!-- <VnImg :id="itemLack.itemFk" class="rounded image-wrapper"></VnImg> -->
+                <div class="flex column" style="align-items: center">
+                    <QBadge
+                        ref="badgeLackRef"
+                        class="q-ml-xs"
+                        text-color="white"
+                        :color="itemLack.lack === 0 ? 'positive' : 'negative'"
+                        :label="itemLack.lack"
+                    />
+                </div>
+                <div class="flex column left" style="align-items: flex-start">
+                    <QBtn flat class="link text-blue">
+                        {{ item?.longName ?? item.name }}
+                        <ItemDescriptorProxy :id="entityId" />
+                        <FetchedTags class="q-ml-md" :item="item" :columns="7" />
+                    </QBtn>
+                </div>
+            </div>
+        </template>
+        <template #top-right>
+            <slot name="top-right" />
+        </template>
+
+        <template #column-status="{ row }">
+            <QTd style="min-width: 150px">
+                <div class="icon-container">
+                    <QIcon
+                        v-if="row.isBasket"
+                        name="vn:basket"
+                        color="primary"
+                        class="cursor-pointer"
+                        size="xs"
+                    >
+                        <QTooltip>{{ t('negative.detail.isBasket') }}</QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.hasToIgnore"
+                        name="star"
+                        color="primary"
+                        class="cursor-pointer fill-icon"
+                        size="xs"
+                    >
+                        <QTooltip>{{ t('negative.detail.hasToIgnore') }}</QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.hasObservation"
+                        name="change_circle"
+                        color="primary"
+                        class="cursor-pointer"
+                        size="xs"
+                    >
+                        <QTooltip>{{
+                            t('negative.detail.hasObservation')
+                        }}</QTooltip> </QIcon
+                    ><QIcon
+                        v-if="row.isRookie"
+                        name="vn:Person"
+                        size="xs"
+                        color="primary"
+                        class="cursor-pointer"
+                    >
+                        <QTooltip>{{ t('negative.detail.isRookie') }}</QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.peticionCompra"
+                        name="vn:buyrequest"
+                        size="xs"
+                        color="primary"
+                        class="cursor-pointer"
+                    >
+                        <QTooltip>{{ t('negative.detail.peticionCompra') }}</QTooltip>
+                    </QIcon>
+                    <QIcon
+                        v-if="row.turno"
+                        name="vn:calendar"
+                        size="xs"
+                        color="primary"
+                        class="cursor-pointer"
+                    >
+                        <QTooltip>{{ t('negative.detail.turno') }}</QTooltip>
+                    </QIcon>
+                </div></QTd
+            >
+        </template>
+        <template #column-nickname="{ row }">
+            <span class="link" @click.stop>
+                {{ row.nickname }}
+                <CustomerDescriptorProxy :id="row.customerId" />
+            </span>
+        </template>
+        <template #column-ticketFk="{ row }">
+            <span class="q-pa-sm link">
+                {{ row.id }}
+                <TicketDescriptorProxy :id="row.id" />
+            </span>
+        </template>
+        <template #column-alertLevelCode="props">
+            <VnSelect
+                url="States/editableStates"
+                auto-load
+                hide-selected
+                option-value="id"
+                option-label="name"
+                v-model="props.row.alertLevelCode"
+                v-on="getInputEvents(props)"
+            />
+        </template>
+
+        <template #column-zoneName="{ row }">
+            <span class="link">{{ row.zoneName }}</span>
+            <ZoneDescriptorProxy :id="row.zoneFk" />
+        </template>
+        <template #column-quantity="props">
+            <VnInputNumber
+                v-model.number="props.row.quantity"
+                v-on="getInputEvents(props)"
+            ></VnInputNumber>
+        </template>
+    </VnTable>
+</template>
+<style lang="scss" scoped>
+.icon-container {
+    display: grid;
+    grid-template-columns: repeat(3, 0.2fr);
+    row-gap: 5px; /* Ajusta el espacio entre los iconos según sea necesario */
+}
+.icon-container > * {
+    width: 100%;
+    height: auto;
+}
+.list-enter-active,
+.list-leave-active {
+    transition: all 1s ease;
+}
+.list-enter-from,
+.list-leave-to {
+    opacity: 0;
+    background-color: $primary;
+}
+</style>
diff --git a/src/pages/Ticket/Negative/components/ChangeItemDialog.vue b/src/pages/Ticket/Negative/components/ChangeItemDialog.vue
new file mode 100644
index 000000000..e419b85c0
--- /dev/null
+++ b/src/pages/Ticket/Negative/components/ChangeItemDialog.vue
@@ -0,0 +1,90 @@
+<script setup>
+import { ref } from 'vue';
+import axios from 'axios';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import notifyResults from 'src/utils/notifyResults';
+const emit = defineEmits(['update-item']);
+
+const showChangeItemDialog = ref(false);
+const newItem = ref(null);
+const $props = defineProps({
+    selectedRows: {
+        type: Array,
+        default: () => [],
+    },
+});
+
+const updateItem = async () => {
+    try {
+        showChangeItemDialog.value = true;
+        const rowsToUpdate = $props.selectedRows.map(({ saleFk, quantity }) =>
+            axios.post(`Sales/replaceItem`, {
+                saleFk,
+                substitutionFk: newItem.value,
+                quantity,
+            }),
+        );
+        const result = await Promise.allSettled(rowsToUpdate);
+        notifyResults(result, 'saleFk');
+        emit('update-item', newItem.value);
+    } catch (err) {
+        console.error('Error updating item:', err);
+        return err;
+    }
+};
+</script>
+
+<template>
+    <QCard class="q-pa-sm">
+        <QCardSection class="row items-center justify-center column items-stretch">
+            {{ showChangeItemDialog }}
+            <span>{{ $t('negative.detail.modal.changeItem.title') }}</span>
+            <VnSelect
+                url="Items/WithName"
+                :fields="['id', 'name']"
+                :sort-by="['id DESC']"
+                :options="items"
+                option-label="name"
+                option-value="id"
+                v-model="newItem"
+            >
+            </VnSelect>
+        </QCardSection>
+        <QCardActions align="right">
+            <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
+            <QBtn
+                :label="$t('globals.confirm')"
+                color="primary"
+                :disable="!newItem"
+                @click="updateItem"
+                unelevated
+                autofocus
+            /> </QCardActions
+    ></QCard>
+</template>
+
+<style lang="scss" scoped>
+.list {
+    max-height: 100%;
+    padding: 15px;
+    width: 100%;
+}
+
+.grid-style-transition {
+    transition:
+        transform 0.28s,
+        background-color 0.28s;
+}
+
+#true {
+    background-color: $positive;
+}
+
+#false {
+    background-color: $negative;
+}
+
+div.q-dialog__inner > div {
+    max-width: fit-content !important;
+}
+</style>
diff --git a/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue b/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue
new file mode 100644
index 000000000..2e9aac4f0
--- /dev/null
+++ b/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue
@@ -0,0 +1,84 @@
+<script setup>
+import { ref } from 'vue';
+import axios from 'axios';
+import VnInput from 'src/components/common/VnInput.vue';
+import notifyResults from 'src/utils/notifyResults';
+
+const showChangeQuantityDialog = ref(false);
+const newQuantity = ref(null);
+const $props = defineProps({
+    selectedRows: {
+        type: Array,
+        default: () => [],
+    },
+});
+const emit = defineEmits(['update-quantity']);
+const updateQuantity = async () => {
+    try {
+        showChangeQuantityDialog.value = true;
+        const rowsToUpdate = $props.selectedRows.map(({ saleFk }) =>
+            axios.post(`Sales/${saleFk}/updateQuantity`, {
+                saleFk,
+                quantity: +newQuantity.value,
+            }),
+        );
+
+        const result = await Promise.allSettled(rowsToUpdate);
+        notifyResults(result, 'saleFk');
+
+        emit('update-quantity', newQuantity.value);
+    } catch (err) {
+        return err;
+    }
+};
+</script>
+
+<template>
+    <QCard class="q-pa-sm">
+        <QCardSection class="row items-center justify-center column items-stretch">
+            <span>{{ $t('negative.detail.modal.changeQuantity.title') }}</span>
+            <VnInput
+                type="number"
+                :min="0"
+                :label="$t('negative.detail.modal.changeQuantity.placeholder')"
+                v-model="newQuantity"
+            />
+        </QCardSection>
+        <QCardActions align="right">
+            <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
+            <QBtn
+                :label="$t('globals.confirm')"
+                color="primary"
+                :disable="!newQuantity || newQuantity < 0"
+                @click="updateQuantity"
+                unelevated
+                autofocus
+            /> </QCardActions
+    ></QCard>
+</template>
+
+<style lang="scss" scoped>
+.list {
+    max-height: 100%;
+    padding: 15px;
+    width: 100%;
+}
+
+.grid-style-transition {
+    transition:
+        transform 0.28s,
+        background-color 0.28s;
+}
+
+#true {
+    background-color: $positive;
+}
+
+#false {
+    background-color: $negative;
+}
+
+div.q-dialog__inner > div {
+    max-width: fit-content !important;
+}
+</style>
diff --git a/src/pages/Ticket/Negative/components/ChangeStateDialog.vue b/src/pages/Ticket/Negative/components/ChangeStateDialog.vue
new file mode 100644
index 000000000..1acc7e0ef
--- /dev/null
+++ b/src/pages/Ticket/Negative/components/ChangeStateDialog.vue
@@ -0,0 +1,91 @@
+<script setup>
+import { ref } from 'vue';
+import axios from 'axios';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import FetchData from 'components/FetchData.vue';
+import notifyResults from 'src/utils/notifyResults';
+
+const emit = defineEmits(['update-state']);
+const editableStates = ref([]);
+const showChangeStateDialog = ref(false);
+const newState = ref(null);
+const $props = defineProps({
+    selectedRows: {
+        type: Array,
+        default: () => [],
+    },
+});
+const updateState = async () => {
+    try {
+        showChangeStateDialog.value = true;
+        const rowsToUpdate = $props.selectedRows.map(({ id }) =>
+            axios.post(`Tickets/state`, {
+                ticketFk: id,
+                code: newState.value,
+            }),
+        );
+        const result = await Promise.allSettled(rowsToUpdate);
+        notifyResults(result, 'ticketFk');
+
+        emit('update-state', newState.value);
+    } catch (err) {
+        return err;
+    }
+};
+</script>
+
+<template>
+    <FetchData
+        url="States/editableStates"
+        @on-fetch="(data) => (editableStates = data)"
+        auto-load
+    />
+    <QCard class="q-pa-sm">
+        <QCardSection class="row items-center justify-center column items-stretch">
+            <span>{{ $t('negative.detail.modal.changeState.title') }}</span>
+            <VnSelect
+                :label="$t('negative.detail.modal.changeState.placeholder')"
+                v-model="newState"
+                :options="editableStates"
+                option-label="name"
+                option-value="code"
+            />
+        </QCardSection>
+        <QCardActions align="right">
+            <QBtn :label="$t('globals.cancel')" color="primary" flat v-close-popup />
+            <QBtn
+                :label="$t('globals.confirm')"
+                color="primary"
+                :disable="!newState"
+                @click="updateState"
+                unelevated
+                autofocus
+            /> </QCardActions
+    ></QCard>
+</template>
+
+<style lang="scss" scoped>
+.list {
+    max-height: 100%;
+    padding: 15px;
+    width: 100%;
+}
+
+.grid-style-transition {
+    transition:
+        transform 0.28s,
+        background-color 0.28s;
+}
+
+#true {
+    background-color: $positive;
+}
+
+#false {
+    background-color: $negative;
+}
+
+div.q-dialog__inner > div {
+    max-width: fit-content !important;
+}
+</style>
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index 8df19c0d9..88878076d 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -232,7 +232,7 @@ const columns = computed(() => [
 
 function resetAgenciesSelector(formData) {
     agenciesOptions.value = [];
-    if(formData) formData.agencyModeId = null;
+    if (formData) formData.agencyModeId = null;
 }
 
 function redirectToLines(id) {
@@ -240,7 +240,7 @@ function redirectToLines(id) {
     window.open(url, '_blank');
 }
 
-const onClientSelected = async (formData) => {    
+const onClientSelected = async (formData) => {
     resetAgenciesSelector(formData);
     await fetchClient(formData);
     await fetchAddresses(formData);
@@ -248,14 +248,12 @@ const onClientSelected = async (formData) => {
 
 const fetchAvailableAgencies = async (formData) => {
     resetAgenciesSelector(formData);
-    const response= await getAgencies(formData, selectedClient.value);
+    const response = await getAgencies(formData, selectedClient.value);
     if (!response) return;
-    
-    const { options, agency } =  response
-    if(options)
-        agenciesOptions.value = options;
-    if(agency)
-        formData.agencyModeId = agency;
+
+    const { options, agency } = response;
+    if (options) agenciesOptions.value = options;
+    if (agency) formData.agencyModeId = agency;
 };
 
 const fetchClient = async (formData) => {
@@ -330,7 +328,7 @@ function openBalanceDialog(ticket) {
     const description = ref([]);
     const firstTicketClientId = checkedTickets[0].clientFk;
     const isSameClient = checkedTickets.every(
-        (ticket) => ticket.clientFk === firstTicketClientId
+        (ticket) => ticket.clientFk === firstTicketClientId,
     );
 
     if (!isSameClient) {
@@ -369,7 +367,7 @@ async function onSubmit() {
             description: dialogData.value.value.description,
             clientFk: dialogData.value.value.clientFk,
             email: email[0].email,
-        }
+        },
     );
 
     if (data) notify('globals.dataSaved', 'positive');
@@ -388,32 +386,32 @@ function setReference(data) {
     switch (data) {
         case 1:
             newDescription = `${t(
-                'ticketList.creditCard'
+                'ticketList.creditCard',
             )}, ${dialogData.value.value.description.replace(
                 /^(Credit Card, |Cash, |Transfers, )/,
-                ''
+                '',
             )}`;
             break;
         case 2:
             newDescription = `${t(
-                'ticketList.cash'
+                'ticketList.cash',
             )}, ${dialogData.value.value.description.replace(
                 /^(Credit Card, |Cash, |Transfers, )/,
-                ''
+                '',
             )}`;
             break;
         case 3:
             newDescription = `${newDescription.replace(
                 /^(Credit Card, |Cash, |Transfers, )/,
-                ''
+                '',
             )}`;
             break;
         case 4:
             newDescription = `${t(
-                'ticketList.transfers'
+                'ticketList.transfers',
             )}, ${dialogData.value.value.description.replace(
                 /^(Credit Card, |Cash, |Transfers, )/,
-                ''
+                '',
             )}`;
             break;
         case 3317:
diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml
index 50f669dee..f58508df8 100644
--- a/src/pages/Ticket/locale/en.yml
+++ b/src/pages/Ticket/locale/en.yml
@@ -23,6 +23,8 @@ ticketSale:
     hasComponentLack: Component lack
     ok: Ok
     more: More
+    transferLines: Transfer lines(no basket)/ Split
+    transferBasket: Some row selected is basket
 advanceTickets:
     preparation: Preparation
     origin: Origin
@@ -189,7 +191,6 @@ ticketList:
     accountPayment: Account payment
     sendDocuware: Set delivered and send delivery note(s) to the tablet
     addPayment: Add payment
-    date: Date
     company: Company
     amount: Amount
     reference: Reference
@@ -203,8 +204,6 @@ ticketList:
     creditCard: Credit card
     transfers: Transfers
     province: Province
-    warehouse: Warehouse
-    hour: Hour
     closure: Closure
     toLines: Go to lines
     addressNickname: Address nickname
@@ -215,3 +214,79 @@ ticketList:
     notVisible: Not visible
     clientFrozen: Client frozen
     componentLack: Component lack
+negative:
+    hour: Hour
+    id: Id Article
+    longName: Article
+    supplier: Supplier
+    colour: Colour
+    size: Size
+    origen: Origin
+    value: Negative
+    itemFk: Article
+    producer: Producer
+    warehouse: Warehouse
+    warehouseFk: Warehouse
+    category: Category
+    categoryFk: Family
+    type: Type
+    typeFk: Type
+    lack: Negative
+    inkFk: inkFk
+    timed: timed
+    date: Date
+    minTimed: minTimed
+    negativeAction: Negative
+    totalNegative: Total negatives
+    days: Days
+    buttonsUpdate:
+        item: Item
+        state: State
+        quantity: Quantity
+    modalOrigin:
+        title: Update negatives
+        question: Select a state to update
+    modalSplit:
+        title: Confirm split selected
+        question: Select a state to update
+    detail:
+        saleFk: Sale
+        itemFk: Article
+        ticketFk: Ticket
+        code: Code
+        nickname: Alias
+        name: Name
+        zoneName: Agency name
+        shipped: Date
+        theoreticalhour: Theoretical hour
+        agName: Agency
+        quantity: Quantity
+        alertLevelCode: Group state
+        state: State
+        peticionCompra: Ticket request
+        isRookie: Is rookie
+        turno: Turn line
+        isBasket: Basket
+        hasObservation: Has substitution
+        hasToIgnore: VIP
+        modal:
+            changeItem:
+                title: Update item reference
+                placeholder: New item
+            changeState:
+                title: Update tickets state
+                placeholder: New state
+            changeQuantity:
+                title: Update tickets quantity
+                placeholder: New quantity
+            split:
+                title: Are you sure you want to split selected tickets?
+                subTitle: Confirm split action
+            handleSplited:
+                title: Handle splited  tickets
+                subTitle: Confirm date and agency
+    split:
+        ticket: Old ticket
+        newTicket: New ticket
+        status: Result
+        message: Message
diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml
index aee0a90b7..673b99cad 100644
--- a/src/pages/Ticket/locale/es.yml
+++ b/src/pages/Ticket/locale/es.yml
@@ -128,6 +128,8 @@ ticketSale:
     ok: Ok
     more: Más
     address: Consignatario
+    transferLines: Transferir líneas(no cesta)/ Separar
+    transferBasket: No disponible para una cesta
     size: Medida
 ticketComponents:
     serie: Serie
@@ -214,6 +216,81 @@ ticketList:
     toLines: Ir a lineas
     addressNickname: Alias consignatario
     ref: Referencia
+negative:
+    hour: Hora
+    id: Id Articulo
+    longName: Articulo
+    supplier: Productor
+    colour: Color
+    size: Medida
+    origen: Origen
+    value: Negativo
+    warehouseFk: Almacen
+    producer: Producer
+    category: Categoría
+    categoryFk: Familia
+    typeFk: Familia
+    warehouse: Almacen
+    lack: Negativo
+    inkFk: Color
+    timed: Hora
+    date: Fecha
+    minTimed: Hora
+    type: Tipo
+    negativeAction: Negativo
+    totalNegative: Total negativos
+    days: Rango de dias
+    buttonsUpdate:
+        item: artículo
+        state: Estado
+        quantity: Cantidad
+    modalOrigin:
+        title: Actualizar negativos
+        question: Seleccione un estado para guardar
+    modalSplit:
+        title: Confirmar acción de split
+        question: Selecciona un estado
+    detail:
+        saleFk: Línea
+        itemFk: Artículo
+        ticketFk: Ticket
+        code: code
+        nickname: Alias
+        name: Nombre
+        zoneName: Agencia
+        shipped: F. envío
+        theoreticalhour: Hora teórica
+        agName: Agencia
+        quantity: Cantidad
+        alertLevelCode: Estado agrupado
+        state: Estado
+        peticionCompra: Petición compra
+        isRookie: Cliente nuevo
+        turno: Linea turno
+        isBasket: Cesta
+        hasObservation: Tiene sustitución
+        hasToIgnore: VIP
+        modal:
+            changeItem:
+                title: Actualizar referencia artículo
+                placeholder: Nuevo articulo
+            changeState:
+                title: Actualizar estado
+                placeholder: Nuevo estado
+            changeQuantity:
+                title: Actualizar cantidad
+                placeholder: Nueva cantidad
+            split:
+                title: ¿Seguro de separar los tickets seleccionados?
+                subTitle: Confirma separar tickets seleccionados
+            handleSplited:
+                title: Gestionar tickets spliteados
+                subTitle: Confir fecha y agencia
+    split:
+        ticket: Ticket viejo
+        newTicket: Ticket nuevo
+        status: Estado
+        message: Mensaje
     rounding: Redondeo
     noVerifiedData: Sin datos comprobados
     purchaseRequest: Petición de compra
diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue
index 72acf91b8..922f89f33 100644
--- a/src/pages/Travel/Card/TravelDescriptor.vue
+++ b/src/pages/Travel/Card/TravelDescriptor.vue
@@ -32,7 +32,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
 
 <template>
     <CardDescriptor
-        module="Travel"
         :url="`Travels/${entityId}`"
         :title="data.title"
         :subtitle="data.subtitle"
diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue
index ffebaf5ea..de3f634e2 100644
--- a/src/pages/Worker/Card/WorkerDescriptor.vue
+++ b/src/pages/Worker/Card/WorkerDescriptor.vue
@@ -10,7 +10,7 @@ import axios from 'axios';
 import VnImg from 'src/components/ui/VnImg.vue';
 import EditPictureForm from 'components/EditPictureForm.vue';
 import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
-import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
 
 const $props = defineProps({
     id: {
@@ -50,9 +50,9 @@ const handlePhotoUpdated = (evt = false) => {
 <template>
     <CardDescriptor
         ref="cardDescriptorRef"
-        module="Worker"
         :data-key="dataKey"
         url="Workers/summary"
+        :filter="{ where: { id: entityId } }"
         title="user.nickname"
         @on-fetch="getIsExcluded"
     >
diff --git a/src/pages/Worker/Card/WorkerDescriptorProxy.vue b/src/pages/Worker/Card/WorkerDescriptorProxy.vue
index 43deb7821..a142570f9 100644
--- a/src/pages/Worker/Card/WorkerDescriptorProxy.vue
+++ b/src/pages/Worker/Card/WorkerDescriptorProxy.vue
@@ -12,11 +12,6 @@ const $props = defineProps({
 
 <template>
     <QPopupProxy>
-        <WorkerDescriptor
-            v-if="$props.id"
-            :id="$props.id"
-            :summary="WorkerSummary"
-            data-key="workerDescriptorProxy"
-        />
+        <WorkerDescriptor v-if="$props.id" :id="$props.id" :summary="WorkerSummary" />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Worker/Card/WorkerFormation.vue b/src/pages/Worker/Card/WorkerFormation.vue
index 6fd5a4eae..e05eca7f8 100644
--- a/src/pages/Worker/Card/WorkerFormation.vue
+++ b/src/pages/Worker/Card/WorkerFormation.vue
@@ -94,6 +94,7 @@ const columns = computed(() => [
         align: 'left',
         name: 'hasDiploma',
         label: t('worker.formation.tableVisibleColumns.hasDiploma'),
+        component: 'checkbox',
         create: true,
     },
     {
diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue
index 992f6ec71..78c5dfd82 100644
--- a/src/pages/Worker/Card/WorkerSummary.vue
+++ b/src/pages/Worker/Card/WorkerSummary.vue
@@ -9,7 +9,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import VnTitle from 'src/components/common/VnTitle.vue';
 import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue';
-import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
 import { useAdvancedSummary } from 'src/composables/useAdvancedSummary';
 import WorkerDescriptorMenu from './WorkerDescriptorMenu.vue';
 
diff --git a/src/pages/Department/Card/DepartmentBasicData.vue b/src/pages/Worker/Department/Card/DepartmentBasicData.vue
similarity index 100%
rename from src/pages/Department/Card/DepartmentBasicData.vue
rename to src/pages/Worker/Department/Card/DepartmentBasicData.vue
diff --git a/src/pages/Department/Card/DepartmentCard.vue b/src/pages/Worker/Department/Card/DepartmentCard.vue
similarity index 77%
rename from src/pages/Department/Card/DepartmentCard.vue
rename to src/pages/Worker/Department/Card/DepartmentCard.vue
index 64ea24d42..2e3f11521 100644
--- a/src/pages/Department/Card/DepartmentCard.vue
+++ b/src/pages/Worker/Department/Card/DepartmentCard.vue
@@ -1,6 +1,6 @@
 <script setup>
 import VnCardBeta from 'components/common/VnCardBeta.vue';
-import DepartmentDescriptor from 'pages/Department/Card/DepartmentDescriptor.vue';
+import DepartmentDescriptor from 'pages/Worker/Department/Card/DepartmentDescriptor.vue';
 </script>
 <template>
     <VnCardBeta
diff --git a/src/pages/Department/Card/DepartmentDescriptor.vue b/src/pages/Worker/Department/Card/DepartmentDescriptor.vue
similarity index 99%
rename from src/pages/Department/Card/DepartmentDescriptor.vue
rename to src/pages/Worker/Department/Card/DepartmentDescriptor.vue
index ecd7fa36c..4b7dfd9b8 100644
--- a/src/pages/Department/Card/DepartmentDescriptor.vue
+++ b/src/pages/Worker/Department/Card/DepartmentDescriptor.vue
@@ -42,7 +42,6 @@ const { openConfirmationModal } = useVnConfirm();
 <template>
     <CardDescriptor
         ref="DepartmentDescriptorRef"
-        module="Department"
         :url="`Departments/${entityId}`"
         :summary="$props.summary"
         :to-module="{ name: 'WorkerDepartment' }"
diff --git a/src/pages/Department/Card/DepartmentDescriptorProxy.vue b/src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue
similarity index 100%
rename from src/pages/Department/Card/DepartmentDescriptorProxy.vue
rename to src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue
diff --git a/src/pages/Department/Card/DepartmentSummary.vue b/src/pages/Worker/Department/Card/DepartmentSummary.vue
similarity index 100%
rename from src/pages/Department/Card/DepartmentSummary.vue
rename to src/pages/Worker/Department/Card/DepartmentSummary.vue
diff --git a/src/pages/Department/Card/DepartmentSummaryDialog.vue b/src/pages/Worker/Department/Card/DepartmentSummaryDialog.vue
similarity index 100%
rename from src/pages/Department/Card/DepartmentSummaryDialog.vue
rename to src/pages/Worker/Department/Card/DepartmentSummaryDialog.vue
diff --git a/src/pages/Worker/WorkerDepartmentTree.vue b/src/pages/Worker/WorkerDepartmentTree.vue
index 14009134b..9baf5ee57 100644
--- a/src/pages/Worker/WorkerDepartmentTree.vue
+++ b/src/pages/Worker/WorkerDepartmentTree.vue
@@ -3,7 +3,7 @@ import { onMounted, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useState } from 'src/composables/useState';
 import { useQuasar } from 'quasar';
-import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
+import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
 import CreateDepartmentChild from './CreateDepartmentChild.vue';
 import axios from 'axios';
 import { useRouter } from 'vue-router';
diff --git a/src/pages/Zone/Card/ZoneBasicData.vue b/src/pages/Zone/Card/ZoneBasicData.vue
index 5206f1e62..15d335ac8 100644
--- a/src/pages/Zone/Card/ZoneBasicData.vue
+++ b/src/pages/Zone/Card/ZoneBasicData.vue
@@ -1,5 +1,7 @@
 <script setup>
 import { useI18n } from 'vue-i18n';
+import { computed, ref } from 'vue';
+import FetchData from 'components/FetchData.vue';
 import FormModel from 'src/components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
@@ -7,10 +9,33 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 
 const { t } = useI18n();
+
+const agencyFilter = {
+    fields: ['id', 'name'],
+    order: 'name ASC',
+    limit: 30,
+};
+const agencyOptions = ref([]);
+const validAddresses = ref([]);
+
+const filterWhere = computed(() => ({
+    id: { inq: validAddresses.value.map((item) => item.addressFk) },
+}));
 </script>
 
 <template>
-    <FormModel :url="`Zones/${$route.params.id}`" auto-load model="zone">
+    <FetchData
+        :filter="agencyFilter"
+        @on-fetch="(data) => (agencyOptions = data)"
+        auto-load
+        url="AgencyModes/isActive"
+    />
+    <FetchData
+        url="RoadmapAddresses"
+        auto-load
+        @on-fetch="(data) => (validAddresses = data)"
+    />
+    <FormModel :url="`Zones/${route.params.id}`" auto-load model="zone">
         <template #form="{ data, validate }">
             <VnRow>
                 <VnInput
@@ -109,6 +134,8 @@ const { t } = useI18n();
                     hide-selected
                     map-options
                     :rules="validate('data.addressFk')"
+                    :filter-options="['id']"
+                    :where="filterWhere"
                 />
             </VnRow>
             <VnRow>
diff --git a/src/pages/Zone/Card/ZoneDescriptor.vue b/src/pages/Zone/Card/ZoneDescriptor.vue
index 49237a02b..27676212e 100644
--- a/src/pages/Zone/Card/ZoneDescriptor.vue
+++ b/src/pages/Zone/Card/ZoneDescriptor.vue
@@ -25,12 +25,7 @@ const entityId = computed(() => {
 </script>
 
 <template>
-    <CardDescriptor
-        module="Zone"
-        :url="`Zones/${entityId}`"
-        :filter="filter"
-        data-key="Zone"
-    >
+    <CardDescriptor :url="`Zones/${entityId}`" :filter="filter" data-key="Zone">
         <template #menu="{ entity }">
             <ZoneDescriptorMenuItems :zone="entity" />
         </template>
diff --git a/src/pages/Zone/Card/ZoneSearchbar.vue b/src/pages/Zone/Card/ZoneSearchbar.vue
index f7a59e97f..d1188a1e8 100644
--- a/src/pages/Zone/Card/ZoneSearchbar.vue
+++ b/src/pages/Zone/Card/ZoneSearchbar.vue
@@ -22,15 +22,50 @@ const exprBuilder = (param, value) => {
             return /^\d+$/.test(value) ? { id: value } : { name: { like: `%${value}%` } };
     }
 };
+
+const tableFilter = {
+    include: [
+        {
+            relation: 'agencyMode',
+            scope: {
+                fields: ['id', 'name'],
+            },
+        },
+        {
+            relation: 'address',
+            scope: {
+                fields: ['id', 'nickname', 'provinceFk', 'postalCode'],
+                include: [
+                    {
+                        relation: 'province',
+                        scope: {
+                            fields: ['id', 'name'],
+                        },
+                    },
+                    {
+                        relation: 'postcode',
+                        scope: {
+                            fields: ['code', 'townFk'],
+                            include: {
+                                relation: 'town',
+                                scope: {
+                                    fields: ['id', 'name'],
+                                },
+                            },
+                        },
+                    },
+                ],
+            },
+        },
+    ],
+};
 </script>
 
 <template>
     <VnSearchbar
         data-key="ZonesList"
         url="Zones"
-        :filter="{
-            include: { relation: 'agencyMode', scope: { fields: ['name'] } },
-        }"
+        :filter="tableFilter"
         :expr-builder="exprBuilder"
         :label="t('list.searchZone')"
         :info="t('list.searchInfo')"
diff --git a/src/pages/Zone/ZoneList.vue b/src/pages/Zone/ZoneList.vue
index e4a1774fe..1fa539c91 100644
--- a/src/pages/Zone/ZoneList.vue
+++ b/src/pages/Zone/ZoneList.vue
@@ -4,7 +4,7 @@ import { useRouter } from 'vue-router';
 import { computed, ref } from 'vue';
 import axios from 'axios';
 
-import { toCurrency } from 'src/filters';
+import { dashIfEmpty, toCurrency } from 'src/filters';
 import { toTimeFormat } from 'src/filters/date';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import useNotify from 'src/composables/useNotify.js';
@@ -17,7 +17,6 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import ZoneFilterPanel from './ZoneFilterPanel.vue';
 import ZoneSearchbar from './Card/ZoneSearchbar.vue';
-import FetchData from 'src/components/FetchData.vue';
 
 const { t } = useI18n();
 const router = useRouter();
@@ -26,7 +25,6 @@ const { viewSummary } = useSummaryDialog();
 const { openConfirmationModal } = useVnConfirm();
 const tableRef = ref();
 const warehouseOptions = ref([]);
-const validAddresses = ref([]);
 
 const tableFilter = {
     include: [
@@ -161,30 +159,18 @@ const handleClone = (id) => {
     openConfirmationModal(
         t('list.confirmCloneTitle'),
         t('list.confirmCloneSubtitle'),
-        () => clone(id)
+        () => clone(id),
     );
 };
 
-function showValidAddresses(row) {
-    if (row.addressFk) {
-        const isValid = validAddresses.value.some(
-            (address) => address.addressFk === row.addressFk
-        );
-        if (isValid)
-            return `${row.address?.nickname},
-            ${row.address?.postcode?.town?.name} (${row.address?.province?.name})`;
-        else return '-';
-    }
-    return '-';
+function formatRow(row) {
+    if (!row?.address) return '-';
+    return dashIfEmpty(`${row?.address?.nickname},
+            ${row?.address?.postcode?.town?.name} (${row?.address?.province?.name})`);
 }
 </script>
 
 <template>
-    <FetchData
-        url="RoadmapAddresses"
-        auto-load
-        @on-fetch="(data) => (validAddresses = data)"
-    />
     <ZoneSearchbar />
     <RightMenu>
         <template #right-panel>
@@ -207,7 +193,7 @@ function showValidAddresses(row) {
         :right-search="false"
     >
         <template #column-addressFk="{ row }">
-            {{ showValidAddresses(row) }}
+            {{ dashIfEmpty(formatRow(row)) }}
         </template>
         <template #more-create-dialog="{ data }">
             <VnSelect
diff --git a/src/router/index.js b/src/router/index.js
index f0d9487c6..4403901cb 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -107,7 +107,10 @@ export default defineRouter(function (/* { store, ssrContext } */) {
             'Failed to fetch dynamically imported module',
             'Importing a module script failed',
         ];
-        state.set('error', errorMessages.some(message.includes));
+        state.set(
+            'error',
+            errorMessages.some((error) => message.startsWith(error)),
+        );
     });
     return Router;
 });
diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js
index f362c7653..b5656dc5f 100644
--- a/src/router/modules/entry.js
+++ b/src/router/modules/entry.js
@@ -6,13 +6,7 @@ const entryCard = {
     component: () => import('src/pages/Entry/Card/EntryCard.vue'),
     redirect: { name: 'EntrySummary' },
     meta: {
-        menu: [
-            'EntryBasicData',
-            'EntryBuys',
-            'EntryNotes',
-            'EntryDms',
-            'EntryLog',
-        ],
+        menu: ['EntryBasicData', 'EntryBuys', 'EntryNotes', 'EntryDms', 'EntryLog'],
     },
     children: [
         {
@@ -91,7 +85,7 @@ export default {
             'EntryLatestBuys',
             'EntryStockBought',
             'EntryWasteRecalc',
-        ]
+        ],
     },
     component: RouterView,
     redirect: { name: 'EntryMain' },
@@ -103,7 +97,7 @@ export default {
             redirect: { name: 'EntryIndexMain' },
             children: [
                 {
-                    path:'',
+                    path: '',
                     name: 'EntryIndexMain',
                     redirect: { name: 'EntryList' },
                     component: () => import('src/pages/Entry/EntryList.vue'),
@@ -115,6 +109,7 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
+                            component: () => import('src/pages/Entry/EntryList.vue'),
                         },
                         entryCard,
                     ],
@@ -127,7 +122,7 @@ export default {
                         icon: 'add',
                     },
                     component: () => import('src/pages/Entry/EntryCreate.vue'),
-                },                
+                },
                 {
                     path: 'my',
                     name: 'MyEntries',
@@ -167,4 +162,4 @@ export default {
             ],
         },
     ],
-};
\ No newline at end of file
+};
diff --git a/src/router/modules/shelving.js b/src/router/modules/shelving.js
index 55fb04278..c085dd8dc 100644
--- a/src/router/modules/shelving.js
+++ b/src/router/modules/shelving.js
@@ -3,7 +3,7 @@ import { RouterView } from 'vue-router';
 const parkingCard = {
     name: 'ParkingCard',
     path: ':id',
-    component: () => import('src/pages/Parking/Card/ParkingCard.vue'),
+    component: () => import('src/pages/Shelving/Parking/Card/ParkingCard.vue'),
     redirect: { name: 'ParkingSummary' },
     meta: {
         menu: ['ParkingBasicData', 'ParkingLog'],
@@ -16,7 +16,7 @@ const parkingCard = {
                 title: 'summary',
                 icon: 'launch',
             },
-            component: () => import('src/pages/Parking/Card/ParkingSummary.vue'),
+            component: () => import('src/pages/Shelving/Parking/Card/ParkingSummary.vue'),
         },
         {
             path: 'basic-data',
@@ -25,7 +25,8 @@ const parkingCard = {
                 title: 'basicData',
                 icon: 'vn:settings',
             },
-            component: () => import('src/pages/Parking/Card/ParkingBasicData.vue'),
+            component: () =>
+                import('src/pages/Shelving/Parking/Card/ParkingBasicData.vue'),
         },
         {
             path: 'log',
@@ -34,7 +35,7 @@ const parkingCard = {
                 title: 'log',
                 icon: 'history',
             },
-            component: () => import('src/pages/Parking/Card/ParkingLog.vue'),
+            component: () => import('src/pages/Shelving/Parking/Card/ParkingLog.vue'),
         },
     ],
 };
@@ -127,7 +128,7 @@ export default {
                         title: 'parkingList',
                         icon: 'view_list',
                     },
-                    component: () => import('src/pages/Parking/ParkingList.vue'),
+                    component: () => import('src/pages/Shelving/Parking/ParkingList.vue'),
                     children: [
                         {
                             path: 'list',
diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js
index e5b423f64..bfcb78787 100644
--- a/src/router/modules/ticket.js
+++ b/src/router/modules/ticket.js
@@ -192,7 +192,13 @@ export default {
         icon: 'vn:ticket',
         moduleName: 'Ticket',
         keyBinding: 't',
-        menu: ['TicketList', 'TicketAdvance', 'TicketWeekly', 'TicketFuture'],
+        menu: [
+            'TicketList',
+            'TicketAdvance',
+            'TicketWeekly',
+            'TicketFuture',
+            'TicketNegative',
+        ],
     },
     component: RouterView,
     redirect: { name: 'TicketMain' },
@@ -229,6 +235,32 @@ export default {
                     },
                     component: () => import('src/pages/Ticket/TicketCreate.vue'),
                 },
+                {
+                    path: 'negative',
+                    redirect: { name: 'TicketNegative' },
+                    children: [
+                        {
+                            name: 'TicketNegative',
+                            meta: {
+                                title: 'negative',
+                                icon: 'exposure',
+                            },
+                            component: () =>
+                                import('src/pages/Ticket/Negative/TicketLackList.vue'),
+                            path: '',
+                        },
+                        {
+                            name: 'NegativeDetail',
+                            path: ':id',
+                            meta: {
+                                title: 'summary',
+                                icon: 'launch',
+                            },
+                            component: () =>
+                                import('src/pages/Ticket/Negative/TicketLackDetail.vue'),
+                        },
+                    ],
+                },
                 {
                     path: 'weekly',
                     name: 'TicketWeekly',
diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js
index faaa23fc8..3eb95a96e 100644
--- a/src/router/modules/worker.js
+++ b/src/router/modules/worker.js
@@ -201,7 +201,7 @@ const workerCard = {
 const departmentCard = {
     name: 'DepartmentCard',
     path: ':id',
-    component: () => import('src/pages/Department/Card/DepartmentCard.vue'),
+    component: () => import('src/pages/Worker/Department/Card/DepartmentCard.vue'),
     redirect: { name: 'DepartmentSummary' },
     meta: {
         moduleName: 'Department',
@@ -215,7 +215,8 @@ const departmentCard = {
                 title: 'summary',
                 icon: 'launch',
             },
-            component: () => import('src/pages/Department/Card/DepartmentSummary.vue'),
+            component: () =>
+                import('src/pages/Worker/Department/Card/DepartmentSummary.vue'),
         },
         {
             path: 'basic-data',
@@ -224,7 +225,8 @@ const departmentCard = {
                 title: 'basicData',
                 icon: 'vn:settings',
             },
-            component: () => import('src/pages/Department/Card/DepartmentBasicData.vue'),
+            component: () =>
+                import('src/pages/Worker/Department/Card/DepartmentBasicData.vue'),
         },
     ],
 };
diff --git a/src/utils/notifyResults.js b/src/utils/notifyResults.js
new file mode 100644
index 000000000..e87ad6c6f
--- /dev/null
+++ b/src/utils/notifyResults.js
@@ -0,0 +1,19 @@
+import { Notify } from 'quasar';
+
+export default function (results, key) {
+    results.forEach((result, index) => {
+        if (result.status === 'fulfilled') {
+            const data = JSON.parse(result.value.config.data);
+            Notify.create({
+                type: 'positive',
+                message: `Operación (${index + 1}) ${data[key]} completada con éxito.`,
+            });
+        } else {
+            const data = JSON.parse(result.reason.config.data);
+            Notify.create({
+                type: 'negative',
+                message: `Operación (${index + 1}) ${data[key]} fallida: ${result.reason.message}`,
+            });
+        }
+    });
+}
diff --git a/test/cypress/integration/entry/entryList.spec.js b/test/cypress/integration/entry/entryList.spec.js
new file mode 100644
index 000000000..5e2fa0c01
--- /dev/null
+++ b/test/cypress/integration/entry/entryList.spec.js
@@ -0,0 +1,226 @@
+describe('Entry', () => {
+    beforeEach(() => {
+        cy.viewport(1920, 1080);
+        cy.login('buyer');
+        cy.visit(`/#/entry/list`);
+    });
+
+    it('Filter deleted entries and other fields', () => {
+        createEntry();
+        cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
+        cy.waitForElement('[data-cy="entry-buys"]');
+        deleteEntry();
+        cy.typeSearchbar('{enter}');
+        cy.get('span[title="Date"]').click().click();
+        cy.typeSearchbar('{enter}');
+        cy.url().should('include', 'order');
+        cy.get('td[data-row-index="0"][data-col-field="landed"]').should(
+            'have.text',
+            '-',
+        );
+    });
+
+    it('Create entry, modify travel and add buys', () => {
+        createEntryAndBuy();
+        cy.get('a[data-cy="EntryBasicData-menu-item"]').click();
+        selectTravel('two');
+        cy.saveCard();
+        cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
+        deleteEntry();
+    });
+
+    it('Clone entry and recalculate rates', () => {
+        createEntry();
+
+        cy.waitForElement('[data-cy="entry-buys"]');
+
+        cy.url().then((previousUrl) => {
+            cy.get('[data-cy="descriptor-more-opts"]').click();
+            cy.get('div[data-cy="clone-entry"]').should('be.visible').click();
+
+            cy.get('.q-notification__message').eq(1).should('have.text', 'Entry cloned');
+
+            cy.url()
+                .should('not.eq', previousUrl)
+                .then(() => {
+                    cy.waitForElement('[data-cy="entry-buys"]');
+
+                    cy.get('[data-cy="descriptor-more-opts"]').click();
+                    cy.get('div[data-cy="recalculate-rates"]').click();
+
+                    cy.get('.q-notification__message')
+                        .eq(2)
+                        .should('have.text', 'Entry prices recalculated');
+
+                    cy.get('[data-cy="descriptor-more-opts"]').click();
+                    deleteEntry();
+
+                    cy.log(previousUrl);
+
+                    cy.visit(previousUrl);
+
+                    cy.waitForElement('[data-cy="entry-buys"]');
+                    deleteEntry();
+                });
+        });
+    });
+
+    it('Should notify when entry is lock by another user', () => {
+        const checkLockMessage = () => {
+            cy.get('[data-cy="entry-lock-confirm"]').should('be.visible');
+            cy.get('[data-cy="VnConfirm_message"] > span').should(
+                'contain.text',
+                'This entry has been locked by buyerNick',
+            );
+        };
+
+        createEntry();
+        goToEntryBuys();
+        cy.get('.q-notification__message')
+            .eq(1)
+            .should('have.text', 'The entry has been locked successfully');
+
+        cy.login('logistic');
+        cy.reload();
+        checkLockMessage();
+        cy.get('[data-cy="VnConfirm_cancel"]').click();
+        cy.url().should('include', 'summary');
+
+        goToEntryBuys();
+        checkLockMessage();
+        cy.get('[data-cy="VnConfirm_confirm"]').click();
+        cy.url().should('include', 'buys');
+
+        deleteEntry();
+    });
+
+    it('Edit buys and use toolbar actions', () => {
+        const COLORS = {
+            negative: 'rgb(251, 82, 82)',
+            positive: 'rgb(200, 228, 132)',
+            enabled: 'rgb(255, 255, 255)',
+            disable: 'rgb(168, 168, 168)',
+        };
+
+        const selectCell = (field, row = 0) =>
+            cy.get(`td[data-col-field="${field}"][data-row-index="${row}"]`);
+        const selectSpan = (field, row = 0) => selectCell(field, row).find('div > span');
+        const selectButton = (cySelector) => cy.get(`button[data-cy="${cySelector}"]`);
+        const clickAndType = (field, value, row = 0) =>
+            selectCell(field, row).click().type(value);
+        const checkText = (field, expectedText, row = 0) =>
+            selectCell(field, row).should('have.text', expectedText);
+        const checkColor = (field, expectedColor, row = 0) =>
+            selectSpan(field, row).should('have.css', 'color', expectedColor);
+
+        createEntryAndBuy();
+
+        selectCell('isIgnored')
+            .click()
+            .click()
+            .trigger('keydown', { key: 'Tab', keyCode: 9, which: 9 });
+        checkText('isIgnored', 'check');
+        checkColor('quantity', COLORS.negative);
+
+        clickAndType('stickers', '1');
+        checkText('quantity', '11');
+        checkText('amount', '550.00');
+        clickAndType('packing', '2');
+        checkText('packing', '12close');
+        checkText('weight', '12.0');
+        checkText('quantity', '132');
+        checkText('amount', '6600.00');
+        checkColor('packing', COLORS.enabled);
+
+        selectCell('groupingMode').click().click().click();
+        checkColor('packing', COLORS.disable);
+        checkColor('grouping', COLORS.enabled);
+
+        selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
+        checkText('amount', '132.00');
+        checkColor('minPrice', COLORS.disable);
+
+        selectCell('hasMinPrice').click().click();
+        checkColor('minPrice', COLORS.enabled);
+        selectCell('hasMinPrice').click();
+
+        cy.saveCard();
+        cy.get('span[data-cy="footer-stickers"]').should('have.text', '11');
+        cy.get('.q-notification__message').contains('Data saved');
+
+        selectButton('change-quantity-sign').should('be.disabled');
+        selectButton('check-buy-amount').should('be.disabled');
+        cy.get('tr.cursor-pointer > .q-table--col-auto-width > .q-checkbox').click();
+        selectButton('change-quantity-sign').should('be.enabled');
+        selectButton('check-buy-amount').should('be.enabled');
+
+        selectButton('change-quantity-sign').click();
+        selectButton('set-negative-quantity').click();
+        checkText('quantity', '-132');
+        selectButton('set-positive-quantity').click();
+        checkText('quantity', '132');
+        checkColor('amount', COLORS.disable);
+
+        selectButton('check-buy-amount').click();
+        selectButton('uncheck-amount').click();
+        checkColor('amount', COLORS.disable);
+
+        selectButton('check-amount').click();
+        checkColor('amount', COLORS.positive);
+        cy.saveCard();
+
+        cy.get('span[data-cy="footer-amount"]').should(
+            'have.css',
+            'color',
+            COLORS.positive,
+        );
+
+        deleteEntry();
+    });
+
+    function goToEntryBuys() {
+        const entryBuySelector = 'a[data-cy="EntryBuys-menu-item"]';
+        cy.get(entryBuySelector).should('be.visible');
+        cy.waitForElement('[data-cy="entry-buys"]');
+        cy.get(entryBuySelector).click();
+    }
+
+    function deleteEntry() {
+        cy.get('[data-cy="descriptor-more-opts"]').click();
+        cy.waitForElement('div[data-cy="delete-entry"]');
+        cy.get('div[data-cy="delete-entry"]').should('be.visible').click();
+        cy.url().should('include', 'list');
+    }
+
+    function createEntryAndBuy() {
+        createEntry();
+        createBuy();
+    }
+
+    function createEntry() {
+        cy.get('button[data-cy="vnTableCreateBtn"]').click();
+        selectTravel('one');
+        cy.get('button[data-cy="FormModelPopup_save"]').click();
+        cy.url().should('include', 'summary');
+        cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
+    }
+
+    function selectTravel(warehouse) {
+        cy.get('i[data-cy="Travel_icon"]').click();
+        cy.get('input[data-cy="Warehouse Out_select"]').type(warehouse);
+        cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
+        cy.get('button[data-cy="save-filter-travel-form"]').click();
+        cy.get('tr').eq(1).click();
+    }
+
+    function createBuy() {
+        cy.get('a[data-cy="EntryBuys-menu-item"]').click();
+        cy.get('a[data-cy="EntryBuys-menu-item"]').click();
+        cy.get('button[data-cy="vnTableCreateBtn"]').click();
+
+        cy.get('input[data-cy="itemFk-create-popup"]').type('1');
+        cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
+        cy.get('input[data-cy="Grouping mode_select"]').should('have.value', 'packing');
+        cy.get('button[data-cy="FormModelPopup_save"]').click();
+    }
+});
diff --git a/test/cypress/integration/entry/stockBought.spec.js b/test/cypress/integration/entry/stockBought.spec.js
index 078ad19cc..d2d2b414d 100644
--- a/test/cypress/integration/entry/stockBought.spec.js
+++ b/test/cypress/integration/entry/stockBought.spec.js
@@ -6,6 +6,7 @@ describe('EntryStockBought', () => {
     });
     it('Should edit the reserved space', () => {
         cy.get('.q-field__native.q-placeholder').should('have.value', '01/01/2001');
+        cy.get('td[data-col-field="reserve"]').click();
         cy.get('input[name="reserve"]').type('10{enter}');
         cy.get('button[title="Save"]').click();
         cy.get('.q-notification__message').should('have.text', 'Data saved');
@@ -26,7 +27,7 @@ describe('EntryStockBought', () => {
         cy.get(':nth-child(2) > .sticky > .q-btn > .q-btn__content > .q-icon').click();
         cy.get('.q-table__bottom.row.items-center.q-table__bottom--nodata').should(
             'have.text',
-            'warningNo data available'
+            'warningNo data available',
         );
     });
     it('Should edit travel m3 and refresh', () => {
diff --git a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
index 2016fca6d..11ca1bb59 100644
--- a/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInBasicData.spec.js
@@ -1,9 +1,9 @@
 /// <reference types="cypress" />
 describe('InvoiceInBasicData', () => {
-    const formInputs = '.q-form > .q-card input';
     const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select';
-    const documentBtns = '[data-cy="dms-buttons"] button';
     const dialogInputs = '.q-dialog input';
+    const resetBtn = '.q-btn-group--push > .q-btn--flat';
+    const getDocumentBtns = (opt) => `[data-cy="dms-buttons"]  > :nth-child(${opt})`;
 
     beforeEach(() => {
         cy.login('developer');
@@ -11,13 +11,16 @@ describe('InvoiceInBasicData', () => {
     });
 
     it('should edit the provideer and supplier ref', () => {
-        cy.selectOption(firstFormSelect, 'Bros');
-        cy.get('[title="Reset"]').click();
-        cy.get(formInputs).eq(1).type('{selectall}4739');
-        cy.saveCard();
+        cy.dataCy('UnDeductibleVatSelect').type('4751000000');
+        cy.get('.q-menu .q-item').contains('4751000000').click();
+        cy.get(resetBtn).click();
 
-        cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Plants nick');
-        cy.get(formInputs).eq(1).invoke('val').should('eq', '4739');
+        cy.waitForElement('#formModel').within(() => {
+            cy.dataCy('vnSupplierSelect').type('Bros nick');
+        })
+        cy.get('.q-menu .q-item').contains('Bros nick').click();
+        cy.saveCard();
+        cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Bros nick');
     });
 
     it('should edit, remove and create the dms data', () => {
@@ -25,18 +28,18 @@ describe('InvoiceInBasicData', () => {
         const secondInput = "I don't know what posting here!";
 
         //edit
-        cy.get(documentBtns).eq(1).click();
+        cy.get(getDocumentBtns(2)).click();
         cy.get(dialogInputs).eq(0).type(`{selectall}${firtsInput}`);
         cy.get('textarea').type(`{selectall}${secondInput}`);
         cy.get('[data-cy="FormModelPopup_save"]').click();
-        cy.get(documentBtns).eq(1).click();
+        cy.get(getDocumentBtns(2)).click();
         cy.get(dialogInputs).eq(0).invoke('val').should('eq', firtsInput);
         cy.get('textarea').invoke('val').should('eq', secondInput);
         cy.get('[data-cy="FormModelPopup_save"]').click();
         cy.checkNotification('Data saved');
 
         //remove
-        cy.get(documentBtns).eq(2).click();
+        cy.get(getDocumentBtns(3)).click();
         cy.get('[data-cy="VnConfirm_confirm"]').click();
         cy.checkNotification('Data saved');
 
@@ -46,7 +49,7 @@ describe('InvoiceInBasicData', () => {
             'test/cypress/fixtures/image.jpg',
             {
                 force: true,
-            }
+            },
         );
         cy.get('[data-cy="FormModelPopup_save"]').click();
         cy.checkNotification('Data saved');
diff --git a/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js b/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
index 5f629df0b..02b7fbb43 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutNegativeBases.spec.js
@@ -7,9 +7,7 @@ describe('InvoiceOut negative bases', () => {
     });
 
     it('should filter and download as CSV', () => {
-        cy.get(
-            ':nth-child(7) > .full-width > :nth-child(1) > .column > div.q-px-xs > .q-field > .q-field__inner > .q-field__control'
-        ).type('23{enter}');
+        cy.get('input[name="ticketFk"]').type('23{enter}');
         cy.get('#subToolbar > .q-btn').click();
         cy.checkNotification('CSV downloaded successfully');
     });
diff --git a/test/cypress/integration/item/ItemProposal.spec.js b/test/cypress/integration/item/ItemProposal.spec.js
new file mode 100644
index 000000000..b3ba9f676
--- /dev/null
+++ b/test/cypress/integration/item/ItemProposal.spec.js
@@ -0,0 +1,11 @@
+/// <reference types="cypress" />
+describe('ItemProposal', () => {
+    beforeEach(() => {
+        const ticketId = 1;
+
+        cy.login('developer');
+        cy.visit(`/#/ticket/${ticketId}/summary`);
+    });
+
+    describe('Handle item proposal selected', () => {});
+});
diff --git a/test/cypress/integration/item/itemTag.spec.js b/test/cypress/integration/item/itemTag.spec.js
index 10d68d08a..d1596f693 100644
--- a/test/cypress/integration/item/itemTag.spec.js
+++ b/test/cypress/integration/item/itemTag.spec.js
@@ -13,7 +13,7 @@ describe('Item tag', () => {
         cy.dataCy('Tag_select').eq(7).type('Tallos');
         cy.get('.q-menu .q-item').contains('Tallos').click();
         cy.get(':nth-child(8) > [label="Value"]').type('1');
-        +cy.dataCy('crudModelDefaultSaveBtn').click();
+        cy.dataCy('crudModelDefaultSaveBtn').click();
         cy.checkNotification("The tag or priority can't be repeated for an item");
     });
 
@@ -26,8 +26,11 @@ describe('Item tag', () => {
         cy.get(':nth-child(8) > [label="Value"]').type('50');
         cy.dataCy('crudModelDefaultSaveBtn').click();
         cy.checkNotification('Data saved');
-        cy.dataCy('itemTags').children(':nth-child(8)').find('.justify-center > .q-icon').click();
+        cy.dataCy('itemTags')
+            .children(':nth-child(8)')
+            .find('.justify-center > .q-icon')
+            .click();
         cy.dataCy('VnConfirm_confirm').click();
         cy.checkNotification('Data saved');
     });
-});
\ No newline at end of file
+});
diff --git a/test/cypress/integration/route/routeList.spec.js b/test/cypress/integration/route/routeList.spec.js
index 4da43ce8e..976ce7352 100644
--- a/test/cypress/integration/route/routeList.spec.js
+++ b/test/cypress/integration/route/routeList.spec.js
@@ -4,9 +4,6 @@ describe('Route', () => {
         cy.login('developer');
         cy.visit(`/#/route/extended-list`);
     });
-    const getVnSelect =
-        '> :nth-child(1) > .column > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
-    const getRowColumn = (row, column) => `:nth-child(${row}) > :nth-child(${column})`;
 
     it('Route list create route', () => {
         cy.addBtnClick();
@@ -17,15 +14,23 @@ describe('Route', () => {
 
     it('Route list search and edit', () => {
         cy.get('#searchbar input').type('{enter}');
-        cy.get('input[name="description"]').type('routeTestOne{enter}');
+        cy.get('[data-col-field="description"][data-row-index="0"]')
+            .click()
+            .type('routeTestOne{enter}');
         cy.get('.q-table tr')
             .its('length')
             .then((rowCount) => {
                 expect(rowCount).to.be.greaterThan(0);
             });
-        cy.get(getRowColumn(1, 3) + getVnSelect).type('{downArrow}{enter}');
-        cy.get(getRowColumn(1, 4) + getVnSelect).type('{downArrow}{enter}');
-        cy.get(getRowColumn(1, 5) + getVnSelect).type('{downArrow}{enter}');
+        cy.get('[data-col-field="workerFk"][data-row-index="0"]')
+            .click()
+            .type('{downArrow}{enter}');
+        cy.get('[data-col-field="agencyModeFk"][data-row-index="0"]')
+            .click()
+            .type('{downArrow}{enter}');
+        cy.get('[data-col-field="vehicleFk"][data-row-index="0"]')
+            .click()
+            .type('{downArrow}{enter}');
         cy.get('button[title="Save"]').click();
         cy.get('.q-notification__message').should('have.text', 'Data saved');
     });
diff --git a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
new file mode 100644
index 000000000..9ea1cff63
--- /dev/null
+++ b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js
@@ -0,0 +1,147 @@
+/// <reference types="cypress" />
+describe('Ticket Lack detail', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.intercept('GET', /\/api\/Tickets\/itemLack\/5.*$/, {
+            statusCode: 200,
+            body: [
+                {
+                    saleFk: 33,
+                    code: 'OK',
+                    ticketFk: 142,
+                    nickname: 'Malibu Point',
+                    shipped: '2000-12-31T23:00:00.000Z',
+                    hour: 0,
+                    quantity: 50,
+                    agName: 'Super-Man delivery',
+                    alertLevel: 0,
+                    stateName: 'OK',
+                    stateId: 3,
+                    itemFk: 5,
+                    price: 1.79,
+                    alertLevelCode: 'FREE',
+                    zoneFk: 9,
+                    zoneName: 'Zone superMan',
+                    theoreticalhour: '2011-11-01T22:59:00.000Z',
+                    isRookie: 1,
+                    turno: 1,
+                    peticionCompra: 1,
+                    hasObservation: 1,
+                    hasToIgnore: 1,
+                    isBasket: 1,
+                    minTimed: 0,
+                    customerId: 1104,
+                    customerName: 'Tony Stark',
+                    observationTypeCode: 'administrative',
+                },
+            ],
+        }).as('getItemLack');
+
+        cy.visit('/#/ticket/negative/5');
+        cy.wait('@getItemLack');
+    });
+    describe('Table actions', () => {
+        it.skip('should display only one row in the lack list', () => {
+            cy.location('href').should('contain', '#/ticket/negative/5');
+
+            cy.get('[data-cy="changeItem"]').should('be.disabled');
+            cy.get('[data-cy="changeState"]').should('be.disabled');
+            cy.get('[data-cy="changeQuantity"]').should('be.disabled');
+            cy.get('[data-cy="itemProposal"]').should('be.disabled');
+            cy.get('[data-cy="transferLines"]').should('be.disabled');
+            cy.get('tr.cursor-pointer > :nth-child(1)').click();
+            cy.get('[data-cy="changeItem"]').should('be.enabled');
+            cy.get('[data-cy="changeState"]').should('be.enabled');
+            cy.get('[data-cy="changeQuantity"]').should('be.enabled');
+            cy.get('[data-cy="itemProposal"]').should('be.enabled');
+            cy.get('[data-cy="transferLines"]').should('be.enabled');
+        });
+    });
+    describe('Item proposal', () => {
+        beforeEach(() => {
+            cy.get('tr.cursor-pointer > :nth-child(1)').click();
+
+            cy.intercept('GET', /\/api\/Items\/getSimilar\?.*$/, {
+                statusCode: 200,
+                body: [
+                    {
+                        id: 1,
+                        longName: 'Ranged weapon longbow 50cm',
+                        subName: 'Stark Industries',
+                        tag5: 'Color',
+                        value5: 'Brown',
+                        match5: 0,
+                        match6: 0,
+                        match7: 0,
+                        match8: 1,
+                        tag6: 'Categoria',
+                        value6: '+1 precission',
+                        tag7: 'Tallos',
+                        value7: '1',
+                        tag8: null,
+                        value8: null,
+                        available: 20,
+                        calc_id: 6,
+                        counter: 0,
+                        minQuantity: 1,
+                        visible: null,
+                        price2: 1,
+                    },
+                    {
+                        id: 2,
+                        longName: 'Ranged weapon longbow 100cm',
+                        subName: 'Stark Industries',
+                        tag5: 'Color',
+                        value5: 'Brown',
+                        match5: 0,
+                        match6: 1,
+                        match7: 0,
+                        match8: 1,
+                        tag6: 'Categoria',
+                        value6: '+1 precission',
+                        tag7: 'Tallos',
+                        value7: '1',
+                        tag8: null,
+                        value8: null,
+                        available: 50,
+                        calc_id: 6,
+                        counter: 1,
+                        minQuantity: 5,
+                        visible: null,
+                        price2: 10,
+                    },
+                    {
+                        id: 3,
+                        longName: 'Ranged weapon longbow 200cm',
+                        subName: 'Stark Industries',
+                        tag5: 'Color',
+                        value5: 'Brown',
+                        match5: 1,
+                        match6: 1,
+                        match7: 1,
+                        match8: 1,
+                        tag6: 'Categoria',
+                        value6: '+1 precission',
+                        tag7: 'Tallos',
+                        value7: '1',
+                        tag8: null,
+                        value8: null,
+                        available: 185,
+                        calc_id: 6,
+                        counter: 10,
+                        minQuantity: 10,
+                        visible: null,
+                        price2: 100,
+                    },
+                ],
+            }).as('getItemGetSimilar');
+            cy.get('[data-cy="itemProposal"]').click();
+            cy.wait('@getItemGetSimilar');
+        });
+        describe('Replace item if', () => {
+            it.only('Quantity is less than available', () => {
+                cy.get(':nth-child(1) > .text-right  > .q-btn').click();
+            });
+        });
+    });
+});
diff --git a/test/cypress/integration/ticket/negative/TicketLackList.spec.js b/test/cypress/integration/ticket/negative/TicketLackList.spec.js
new file mode 100644
index 000000000..01ab4f621
--- /dev/null
+++ b/test/cypress/integration/ticket/negative/TicketLackList.spec.js
@@ -0,0 +1,36 @@
+/// <reference types="cypress" />
+describe('Ticket Lack list', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.intercept('GET', /Tickets\/itemLack\?.*$/, {
+            statusCode: 200,
+            body: [
+                {
+                    itemFk: 5,
+                    longName: 'Ranged weapon pistol 9mm',
+                    warehouseFk: 1,
+                    producer: null,
+                    size: 15,
+                    category: null,
+                    warehouse: 'Warehouse One',
+                    lack: -50,
+                    inkFk: 'SLV',
+                    timed: '2025-01-25T22:59:00.000Z',
+                    minTimed: '23:59',
+                    originFk: 'Holand',
+                },
+            ],
+        }).as('getLack');
+
+        cy.visit('/#/ticket/negative');
+    });
+
+    describe('Table actions', () => {
+        it('should display only one row in the lack list', () => {
+            cy.wait('@getLack', { timeout: 10000 });
+
+            cy.get('.q-virtual-scroll__content > :nth-child(1) > .sticky').click();
+            cy.location('href').should('contain', '#/ticket/negative/5');
+        });
+    });
+});
diff --git a/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js b/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
index 343c1c127..2cd43984a 100644
--- a/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
+++ b/test/cypress/integration/wagon/wagonType/wagonTypeCreate.spec.js
@@ -9,7 +9,7 @@ describe('WagonTypeCreate', () => {
     it('should create a new wagon type and then delete it', () => {
         cy.get('.q-page-sticky > div > .q-btn').click();
         cy.get('input').first().type('Example for testing');
-        cy.get('button[type="submit"]').click();
+        cy.get('[data-cy="FormModelPopup_save"]').click();
         cy.get('[title="Remove"] > .q-btn__content > .q-icon').first().click();
     });
 });
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 2c93fbf84..aa4a1219e 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -87,36 +87,55 @@ Cypress.Commands.add('getValue', (selector) => {
 });
 
 // Fill Inputs
-Cypress.Commands.add('selectOption', (selector, option, timeout = 5000) => {
+Cypress.Commands.add('selectOption', (selector, option, timeout = 2500) => {
     cy.waitForElement(selector, timeout);
-    cy.get(selector).click();
-    cy.get(selector).invoke('data', 'url').as('dataUrl');
-    cy.get(selector)
-        .clear()
-        .type(option)
-        .then(() => {
-            cy.get('.q-menu', { timeout })
-                .should('be.visible') // Asegurarse de que el menú está visible
-                .and('exist') // Verificar que el menú existe
-                .then(() => {
-                    cy.get('@dataUrl').then((url) => {
-                        if (url) {
-                            // Esperar a que el menú no esté visible (desaparezca)
-                            cy.get('.q-menu').should('not.be.visible');
-                            // Ahora esperar a que el menú vuelva a aparecer
-                            cy.get('.q-menu').should('be.visible').and('exist');
-                        }
-                    });
-                });
-        });
 
-    // Finalmente, seleccionar la opción deseada
-    cy.get('.q-menu:visible') // Asegurarse de que estamos dentro del menú visible
-        .find('.q-item') // Encontrar los elementos de las opciones
-        .contains(option) // Verificar que existe una opción que contenga el texto deseado
-        .click(); // Hacer clic en la opción
+    cy.get(selector, { timeout })
+        .should('exist')
+        .should('be.visible')
+        .click()
+        .then(($el) => {
+            cy.wrap($el.is('input') ? $el : $el.find('input'))
+                .invoke('attr', 'aria-controls')
+                .then((ariaControl) => selectItem(selector, option, ariaControl));
+        });
 });
 
+function selectItem(selector, option, ariaControl, hasWrite = true) {
+    if (!hasWrite) cy.wait(100);
+
+    getItems(ariaControl).then((items) => {
+        const matchingItem = items
+            .toArray()
+            .find((item) => item.innerText.includes(option));
+        if (matchingItem) return cy.wrap(matchingItem).click();
+
+        if (hasWrite) cy.get(selector).clear().type(option, { delay: 0 });
+        return selectItem(selector, option, ariaControl, false);
+    });
+}
+
+function getItems(ariaControl, startTime = Cypress._.now(), timeout = 2500) {
+    // Se intenta obtener la lista de opciones del desplegable de manera recursiva
+    return cy
+        .get('#' + ariaControl, { timeout })
+        .should('exist')
+        .find('.q-item')
+        .should('exist')
+        .then(($items) => {
+            if (!$items?.length || $items.first().text().trim() === '') {
+                if (Cypress._.now() - startTime > timeout) {
+                    throw new Error(
+                        `getItems: Tiempo de espera (${timeout}ms) excedido.`,
+                    );
+                }
+                return getItems(ariaControl, startTime, timeout);
+            }
+
+            return cy.wrap($items);
+        });
+}
+
 Cypress.Commands.add('countSelectOptions', (selector, option) => {
     cy.waitForElement(selector);
     cy.get(selector).click({ force: true });
diff --git a/test/cypress/support/waitUntil.js b/test/cypress/support/waitUntil.js
index 5fb47a2d8..359f8643f 100644
--- a/test/cypress/support/waitUntil.js
+++ b/test/cypress/support/waitUntil.js
@@ -1,7 +1,7 @@
 const waitUntil = (subject, checkFunction, originalOptions = {}) => {
     if (!(checkFunction instanceof Function)) {
         throw new Error(
-            '`checkFunction` parameter should be a function. Found: ' + checkFunction
+            '`checkFunction` parameter should be a function. Found: ' + checkFunction,
         );
     }