From f33c4d42bffe8d149cd4b35369a2b61b7800039e Mon Sep 17 00:00:00 2001
From: pablone <pablone@verdnatura.es>
Date: Mon, 27 Jan 2025 08:11:28 +0100
Subject: [PATCH] refactor: refs #6897 clean up unused code, enhance input
 components, and add new localization entries

---
 src/boot/quasar.js                            |   4 +-
 src/components/VnColor.vue                    |  31 --
 src/components/VnTable/VnColumn.vue           |  14 +-
 src/components/VnTable/VnFilter.vue           |  12 +-
 src/components/VnTable/VnTable.vue            | 370 ++++++++++++------
 src/components/common/VnColor.vue             |  32 ++
 src/components/common/VnComponent.vue         |   2 +
 src/components/common/VnInput.vue             |   4 -
 src/components/common/VnSelect.vue            |   3 +-
 src/components/common/VnSelectDialog.vue      |   2 -
 src/css/app.scss                              |   1 -
 src/i18n/locale/en.yml                        |  27 +-
 src/i18n/locale/es.yml                        |  25 +-
 src/pages/Customer/CustomerList.vue           |  11 -
 .../components/CustomerAddressEdit.vue        |   8 +-
 src/pages/Entry/Card/<!DOCTYPE html>.html     |  68 ----
 src/pages/Entry/Card/EntryBasicData.vue       |  50 +--
 src/pages/Entry/Card/EntryBuys.vue            | 324 +++++++++++++--
 src/pages/Entry/Card/EntryDescriptor.vue      |  72 +++-
 src/pages/Entry/Card/EntryFilter.js           |  11 +-
 src/pages/Entry/Card/EntrySummary.vue         | 238 ++++-------
 src/pages/Entry/EntryFilter.vue               | 245 +++++++-----
 src/pages/Entry/EntryList.vue                 | 340 +++++++++-------
 src/pages/Item/Card/ItemDescriptor.vue        |  16 +-
 src/pages/Item/Card/ItemDescriptorProxy.vue   |   3 +-
 src/pages/Item/locale/en.yml                  |   1 +
 src/pages/Item/locale/es.yml                  |   1 +
 27 files changed, 1165 insertions(+), 750 deletions(-)
 delete mode 100644 src/components/VnColor.vue
 create mode 100644 src/components/common/VnColor.vue
 delete mode 100644 src/pages/Entry/Card/<!DOCTYPE html>.html

diff --git a/src/boot/quasar.js b/src/boot/quasar.js
index e1e879315..a8c397b83 100644
--- a/src/boot/quasar.js
+++ b/src/boot/quasar.js
@@ -51,7 +51,5 @@ export default boot(({ app }) => {
 
         await useCau(response, message);
     };
-    app.directive('shortcut', keyShortcut);
-    app.mixin(qFormMixin);
-    app.mixin(mainShortcutMixin);
+    app.provide('app', app);
 });
diff --git a/src/components/VnColor.vue b/src/components/VnColor.vue
deleted file mode 100644
index 73c898ce3..000000000
--- a/src/components/VnColor.vue
+++ /dev/null
@@ -1,31 +0,0 @@
-<script setup>
-import { computed } from 'vue';
-
-const props = defineProps({
-    colors: {
-        type: Array,
-        required: true,
-        validator: (value) => value.length <= 3,
-    },
-});
-</script>
-<template>
-    <div class="color-div">
-        <div
-            v-for="(color, index) in colors"
-            :key="index"
-            :style="{
-                backgroundColor: color,
-                height: '10px',
-            }"
-        >
-            &nbsp;
-        </div>
-    </div>
-</template>
-<style scoped>
-.color-div {
-    display: flex;
-    flex-direction: column;
-}
-</style>
diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue
index baa576bba..0040385c5 100644
--- a/src/components/VnTable/VnColumn.vue
+++ b/src/components/VnTable/VnColumn.vue
@@ -1,6 +1,6 @@
 <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 */
@@ -48,6 +48,10 @@ const $props = defineProps({
         type: Boolean,
         default: null,
     },
+    eventHandlers: {
+        type: Object,
+        default: null,
+    },
 });
 
 const defaultSelect = {
@@ -141,6 +145,9 @@ const defaultComponents = {
     userLink: {
         component: markRaw(VnUserLink),
     },
+    toggle: {
+        component: markRaw(QToggle),
+    },
 };
 
 const value = computed(() => {
@@ -187,6 +194,7 @@ const components = computed(() => {
                 ...(component.attrs || {}),
                 autofocus: $props.autofocus,
             },
+            event: { ...component?.event, ...$props?.eventHandlers },
         };
         return acc;
     }, {});
@@ -200,7 +208,6 @@ const components = computed(() => {
             :components="components"
             :value="{ row, model }"
             v-model="model"
-            @blur="emit('blur')"
         />
         <VnComponent
             v-if="col.component"
@@ -208,7 +215,6 @@ const components = computed(() => {
             :components="components"
             :value="{ row, model }"
             v-model="model"
-            @blur="emit('blur')"
         />
         <span :title="value" v-else>{{ value }}</span>
         <VnComponent
@@ -217,7 +223,7 @@ const components = computed(() => {
             :components="components"
             :value="{ row, model }"
             v-model="model"
-            @blur="emit('blur')"
         />
+        <slot name="append" />
     </div>
 </template>
diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue
index 77fa2e246..1618f4f5a 100644
--- a/src/components/VnTable/VnFilter.vue
+++ b/src/components/VnTable/VnFilter.vue
@@ -58,7 +58,7 @@ const selectComponent = {
     component: markRaw(VnSelect),
     event: updateEvent,
     attrs: {
-        class: 'q-px-sm q-pb-xs q-pt-none fit',
+        class: 'q-pt-none fit test',
         dense: true,
         filled: !$props.showTitle,
     },
@@ -120,6 +120,7 @@ const components = {
 };
 
 async function addFilter(value, name) {
+    console.log('test');
     value ??= undefined;
     if (value && typeof value === 'object') value = model.value;
     value = value === '' ? undefined : value;
@@ -168,3 +169,12 @@ const onTabPressed = async () => {
         />
     </div>
 </template>
+<style lang="scss">
+/* label.test {
+    padding-bottom: 0px !important;
+    background-color: red;
+    } */
+label.test > .q-field__inner > .q-field__control {
+    padding: inherit;
+}
+</style>
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index b8923129f..7f5808627 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -1,23 +1,36 @@
 <script setup>
-import { ref, onBeforeMount, onMounted, computed, watch, useAttrs, nextTick } from 'vue';
+import {
+    ref,
+    onBeforeMount,
+    onMounted,
+    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 { dashIfEmpty } from 'src/filters';
 
+const arrayData = useArrayData(useAttrs()['data-key']);
 const $props = defineProps({
     columns: {
         type: Array,
@@ -115,6 +128,10 @@ const $props = defineProps({
         type: Boolean,
         default: false,
     },
+    withFilters: {
+        type: Boolean,
+        default: true,
+    },
 });
 const { t } = useI18n();
 const stateStore = useStateStore();
@@ -136,7 +153,12 @@ const createForm = ref();
 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 tableModes = [
     {
         icon: 'view_column',
@@ -156,7 +178,6 @@ onBeforeMount(() => {
     const urlParams = route.query[$props.searchUrl];
     hasParams.value = urlParams && Object.keys(urlParams).length !== 0;
 });
-
 onMounted(() => {
     mode.value =
         quasar.platform.is.mobile && !$props.disableOption?.card
@@ -185,9 +206,6 @@ watch(
     { immediate: true }
 );
 
-const isTableMode = computed(() => mode.value == TABLE_MODE);
-const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
-
 function splitColumns(columns) {
     splittedColumns.value = {
         columns: [],
@@ -306,99 +324,210 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
     }
 }
 
-const editingRow = ref(null);
-const editingField = ref(null);
+function isEditableColumn(column) {
+    const isEditableCol = column?.isEditable ?? true;
+    const isVisible = column?.visible ?? true;
+    const hasComponent = column?.component;
 
-const handleClick = (event) => {
+    return $props.isEditable && isVisible && hasComponent && isEditableCol;
+}
+
+function hasEditableFormat(column) {
+    if (isEditableColumn(column)) return 'editable-text';
+}
+
+const handleClick = async (event) => {
     const clickedElement = event.target.closest('td');
 
     if (!clickedElement) return;
 
     const rowIndex = clickedElement.getAttribute('data-row-index');
+    console.log('HandleRowIndex: ', rowIndex);
     const colField = clickedElement.getAttribute('data-col-field');
+    console.log('HandleColField: ', colField);
 
     if (rowIndex !== null && colField) {
-        startEditing(Number(rowIndex), colField);
-    }
-};
-const vnEditableCell = ref(null);
-const startEditing = async (rowId, field) => {
-    const col = $props.columns.find((col) => col.name === field);
-    if (col?.isEditable === false) return;
-    editingRow.value = rowId;
-    editingField.value = field;
-    if (col.component === 'checkbox') {
-        await nextTick();
-        const inputElement = vnEditableCell.value?.$el?.querySelector('span > div');
-        inputElement.focus();
+        console.log('handleClick STARTEDEDITING');
+        const column = $props.columns.find((col) => col.name === colField);
+        console.log('isEditableColumn(column): ', isEditableColumn(column));
+        if (!isEditableColumn(column)) return;
+        await startEditing(Number(rowIndex), colField, clickedElement);
+        if (column.component !== 'checkbox') console.log();
     }
 };
 
-const stopEditing = (rowIndex, field) => {
+async function startEditing(rowId, field, clickedElement) {
+    console.log('startEditing: ', field);
+    if (rowId === editingRow.value && field === editingField.value) return;
+    editingRow.value = rowId;
+    editingField.value = field;
+
+    const column = $props.columns.find((col) => col.name === field);
+    console.log('LaVerdaderacolumn: ', column);
+    const row = CrudModelRef.value.formData[rowId];
+    const oldValue = CrudModelRef.value.formData[rowId][column?.name];
+    console.log('changes: ', CrudModelRef.value.getChanges());
+
+    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 = 'absolute';
+    });
+
+    console.log('row[column.name]: ', row[column.name]);
+    const node = h(VnColumn, {
+        row: row,
+        column: column,
+        modelValue: row[column.name],
+        componentProp: 'columnField',
+        autofocus: true,
+        focusOnMount: true,
+        eventHandlers: {
+            'update:modelValue': (value) => {
+                console.log('update:modelValue: ', value);
+                row[column.name] = value;
+
+                column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
+            },
+            onMouseDown: (event) => {
+                console.log('mouseDown: ', field);
+                if (column.component === 'checkbox') event.stopPropagation();
+            },
+            blur: () => {
+                /* const focusElement = document.activeElement;
+                const rowIndex = focusElement.getAttribute('data-row-index');
+                const colField = focusElement.getAttribute('data-col-field'); 
+                console.log('rowIndex: ', rowIndex);
+                console.log('colField: ', colField);
+                console.log('editingField.value: ', editingField.value);
+                console.log('editingRow.value: ', editingRow.value);
+
+                handleBlur(rowId, field, clickedElement);
+                column?.cellEvent?.blur?.(row); */
+            },
+            keyup: async (event) => {
+                console.log('keyup: ', field);
+                if (event.key === 'Enter') handleBlur(rowId, field, clickedElement);
+            },
+            keydown: async (event) => {
+                switch (event.key) {
+                    case 'Tab':
+                        console.log('TabTest: ', field);
+                        await handleTabKey(event, rowId, field);
+                        event.stopPropagation();
+                        if (column.component === 'checkbox')
+                            handleBlur(rowId, field, clickedElement);
+                        break;
+                    case 'Escape':
+                        console.log('Escape: ', field);
+                        stopEditing(rowId, field, clickedElement);
+                        break;
+                    default:
+                        break;
+                }
+            },
+            click: (event) => {
+                /* event.stopPropagation();
+                console.log('click: ', field);
+
+                if (column.component === 'checkbox') {
+                    const allowNull = column?.toggleIndeterminate ?? true;
+                    const currentValue = row[column.name];
+
+                    let newValue;
+
+                    if (allowNull) {
+                        if (currentValue === null) {
+                            newValue = true;
+                        } else if (currentValue) {
+                            newValue = false;
+                        } else {
+                            newValue = null;
+                        }
+                    } else {
+                        newValue = !currentValue;
+                    }
+                    row[column.name] = newValue;
+
+                    column?.cellEvent?.['update:modelValue']?.(newValue, row);
+                }
+                column?.cellEvent?.['click']?.(event, row); */
+            },
+        },
+    });
+
+    node.appContext = app._context;
+    render(node, clickedElement);
+
+    if (column.component === 'checkbox') node.el?.querySelector('span > div').focus();
+}
+
+function stopEditing(rowIndex, field, clickedElement) {
+    console.log('stopEditing: ', 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;
-};
+}
 
-const handleTab = async (rowIndex, colName) => {
+function handleBlur(rowIndex, field, clickedElement) {
+    console.log('handleBlur: ', field);
+    stopEditing(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 newColumnIndex = currentColumnIndex + 1;
-    while (
-        columns[newColumnIndex]?.visible === false ||
-        columns[newColumnIndex]?.isEditable === false ||
-        !columns[newColumnIndex]?.component
-    ) {
-        newColumnIndex++;
-        if (newColumnIndex >= columns.length) newColumnIndex = 0;
-    }
 
-    if (currentColumnIndex >= newColumnIndex) rowIndex++;
+    let iterations = 0;
+    let newColumnIndex = currentColumnIndex;
 
-    await startEditing(rowIndex, columns[newColumnIndex].name);
-};
+    do {
+        iterations++;
+        newColumnIndex = (newColumnIndex + direction + totalColumns) % totalColumns;
 
-const handleShiftTab = async (rowIndex, colName) => {
-    console.log('handleShiftTab: ');
-    const columns = $props.columns;
-    const currentColumnIndex = columns.findIndex((col) => col.name === colName);
+        if (isEditableColumn(columns[newColumnIndex])) break;
+    } while (iterations < totalColumns);
 
-    if (currentColumnIndex === -1) return;
-
-    let prevColumnIndex = currentColumnIndex - 1;
-    let prevRowIndex = rowIndex;
-
-    while (prevColumnIndex >= 0 && columns[prevColumnIndex]?.isEditable === false) {
-        prevColumnIndex--;
-    }
-
-    if (prevColumnIndex < 0) {
-        prevColumnIndex = columns.length - 1;
-        prevRowIndex -= 1;
-
-        while (prevRowIndex >= 0 && columns[prevColumnIndex]?.isEditable === false) {
-            prevColumnIndex--;
-            if (prevColumnIndex < 0) {
-                prevColumnIndex = columns.length - 1;
-                prevRowIndex--;
-            }
-        }
-    }
-
-    if (prevRowIndex < 0) {
-        stopEditing(rowIndex, colName);
+    if (iterations >= totalColumns) {
+        console.warn('No editable columns found.');
         return;
     }
 
-    await startEditing(prevRowIndex, columns[prevColumnIndex]?.name);
-    console.log('finishHandleShiftTab');
-};
+    if (direction === 1 && newColumnIndex <= currentColumnIndex) {
+        rowIndex++;
+    } else if (direction === -1 && newColumnIndex >= currentColumnIndex) {
+        rowIndex--;
+    }
+    console.log('next: ', columns[newColumnIndex].name, 'rowIndex: ', rowIndex);
+    return { nextRowIndex: rowIndex, nextColumnName: columns[newColumnIndex].name };
+}
+
+async function handleTabKey(event, rowIndex, colName) {
+    const direction = event.shiftKey ? -1 : 1;
+    const { nextRowIndex, nextColumnName } = await handleTabNavigation(
+        rowIndex,
+        colName,
+        direction
+    );
+
+    if (nextRowIndex < 0 || nextRowIndex >= arrayData.store.data.length) return;
+
+    event.preventDefault();
+    await startEditing(nextRowIndex, nextColumnName, null);
+}
 
-const handleTabKey = async (event, rowIndex, colName) => {
-    if (event.shiftKey) await handleShiftTab(rowIndex, colName);
-    else await handleTab(rowIndex, colName);
-};
 function getCheckboxIcon(value) {
     switch (typeof value) {
         case 'boolean':
@@ -408,25 +537,35 @@ function getCheckboxIcon(value) {
                 ? 'indeterminate_check_box'
                 : 'unknown_med';
         case 'number':
-            return value > 0 ? 'check' : 'close';
+            return value === 0 ? 'close' : 'check';
         case 'object':
             return value === null ? 'help_outline' : 'unknown_med';
         case 'undefined':
             return 'help_outline';
         default:
-            return 'unknown_med';
+            return 'indeterminate_check_box';
     }
 }
 
-function shouldDisplayReadonly(col, rowIndex) {
-    return (
-        !col?.component ||
-        editingRow.value !== rowIndex ||
-        editingField.value !== col?.name
-    );
-}
+/* function getCheckboxIcon(value) {
+    switch (typeof value) {
+        case 'boolean':
+            return value ? 'check_box' : 'check_box_outline_blank';
+        case 'string':
+            return value.toLowerCase() === 'partial'
+                ? 'indeterminate_check_box'
+                : 'unknown_med';
+        case 'number':
+            return value === 0 ? 'check_box_outline_blank' : 'check_box';
+        case 'object':
+            return value === null ? 'help_outline' : 'unknown_med';
+        case 'undefined':
+            return 'help_outline';
+        default:
+            return 'indeterminate_check_box';
+    }
+} */
 </script>
-
 <template>
     <QDrawer
         v-if="$props.rightSearch"
@@ -477,7 +616,7 @@ function shouldDisplayReadonly(col, rowIndex) {
                 @row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
                 @update:selected="emit('update:selected', $event)"
                 @selection="(details) => handleSelection(details, rows)"
-                @click="handleClick"
+                v-on="isEditable ? { click: handleClick } : {}"
             >
                 <template #top-left v-if="!$props.withoutHeader">
                     <slot name="top-left"> </slot>
@@ -496,13 +635,6 @@ function shouldDisplayReadonly(col, rowIndex) {
                         dense
                         :options="tableModes.filter((mode) => !mode.disable)"
                     />
-                    <QBtn
-                        v-if="showRightIcon"
-                        icon="filter_alt"
-                        class="bg-vn-section-color q-ml-sm"
-                        dense
-                        @click="stateStore.toggleRightDrawer()"
-                    />
                 </template>
                 <template #header-cell="{ col }">
                     <QTh
@@ -512,7 +644,9 @@ function shouldDisplayReadonly(col, rowIndex) {
                     >
                         <div
                             class="no-padding"
-                            :style="$props.columnSearch ? 'height: 75px' : ''"
+                            :style="
+                                withFilters && $props.columnSearch ? 'height: 75px' : ''
+                            "
                         >
                             <div class="text-center" style="height: 30px">
                                 <QTooltip v-if="col.toolTip">{{ col.toolTip }}</QTooltip>
@@ -525,13 +659,17 @@ function shouldDisplayReadonly(col, rowIndex) {
                                 />
                             </div>
                             <VnFilter
-                                v-if="$props.columnSearch && col.columnSearch !== false"
+                                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"
+                                class="full-width test"
                             />
                         </div>
                     </QTh>
@@ -550,7 +688,6 @@ function shouldDisplayReadonly(col, rowIndex) {
                 </template>
                 <template #body-cell="{ col, row, rowIndex }">
                     <QTd
-                        auto-width
                         class="no-margin q-px-xs"
                         v-if="col.visible ?? true"
                         :style="{
@@ -566,7 +703,6 @@ function shouldDisplayReadonly(col, rowIndex) {
                         :data-col-field="col?.name"
                     >
                         <div
-                            v-if="shouldDisplayReadonly(col, rowIndex)"
                             class="no-padding no-margin"
                             style="
                                 overflow: hidden;
@@ -584,18 +720,12 @@ function shouldDisplayReadonly(col, rowIndex) {
                                     v-if="col?.component === 'checkbox'"
                                     :name="getCheckboxIcon(row[col?.name])"
                                     style="color: var(--vn-text-color)"
-                                    size="var(--font-size)"
-                                    :class="
-                                        isEditable &&
-                                        (col?.component ? 'editable-text' : '')
-                                    "
+                                    :class="hasEditableFormat(col)"
+                                    size="17px"
                                 />
                                 <span
                                     v-else
-                                    :class="
-                                        isEditable &&
-                                        (col?.component ? 'editable-text' : '')
-                                    "
+                                    :class="hasEditableFormat(col)"
                                     :style="col?.style ? col.style(row) : null"
                                     style="bottom: 0"
                                 >
@@ -607,27 +737,6 @@ function shouldDisplayReadonly(col, rowIndex) {
                                 </span>
                             </slot>
                         </div>
-                        <div v-else>
-                            <VnTableColumn
-                                ref="vnEditableCell"
-                                :column="col"
-                                :row="row"
-                                :is-editable="col.isEditable ?? isEditable"
-                                v-model="row[col.name]"
-                                component-prop="columnField"
-                                class="cell-input q-px-xs"
-                                @blur="stopEditing(rowIndex, col?.name)"
-                                @keyup.enter="stopEditing(rowIndex, col?.name)"
-                                @keydown.tab.prevent="
-                                    handleTabKey($event, rowIndex, col?.name)
-                                "
-                                @keydown.shift.tab.prevent="
-                                    handleShiftTab(rowIndex, col?.name)
-                                "
-                                @keydown.escape="stopEditing(rowIndex, col?.name)"
-                                :autofocus="true"
-                            />
-                        </div>
                     </QTd>
                 </template>
                 <template #body-cell-tableActions="{ col, row }">
@@ -751,7 +860,7 @@ function shouldDisplayReadonly(col, rowIndex) {
                                                         :row="row"
                                                         :row-index="index"
                                                     >
-                                                        <VnTableColumn
+                                                        <VnColumn
                                                             :column="col"
                                                             :row="row"
                                                             :is-editable="false"
@@ -792,7 +901,8 @@ function shouldDisplayReadonly(col, rowIndex) {
                     </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"
@@ -838,7 +948,7 @@ function shouldDisplayReadonly(col, rowIndex) {
                         :column-name="column.name"
                         :label="column.label"
                     >
-                        <VnTableColumn
+                        <VnColumn
                             :column="column"
                             :row="{}"
                             default="input"
diff --git a/src/components/common/VnColor.vue b/src/components/common/VnColor.vue
new file mode 100644
index 000000000..00e662bb8
--- /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 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 d9d1ea26b..c1700fd45 100644
--- a/src/components/common/VnComponent.vue
+++ b/src/components/common/VnComponent.vue
@@ -45,6 +45,7 @@ function toValueAttrs(attrs) {
 }
 </script>
 <template>
+    <slot name="test" />
     <span
         v-for="toComponent of componentArray"
         :key="toComponent.name"
@@ -57,6 +58,7 @@ function toValueAttrs(attrs) {
             v-on="mix(toComponent).event ?? {}"
             v-model="model"
             @blur="emit('blur')"
+            @mouse-down="() => console.log('mouse-down')"
         />
     </span>
 </template>
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 1b896611a..7981ac683 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -70,10 +70,6 @@ const focus = () => {
     vnInputRef.value.focus();
 };
 
-defineExpose({
-    focus,
-});
-
 const mixinRules = [
     requiredFieldRule,
     ...($attrs.rules ?? []),
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index 2dbb43f1e..8aa725b4a 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -6,7 +6,7 @@ import { useRequired } from 'src/composables/useRequired';
 import dataByOrder from 'src/utils/dataByOrder';
 import { QItemLabel } from 'quasar';
 
-const emit = defineEmits(['update:modelValue', 'update:options', 'remove', 'blur']);
+const emit = defineEmits(['update:modelValue', 'update:options', 'remove']);
 const $attrs = useAttrs();
 const { t } = useI18n();
 
@@ -327,7 +327,6 @@ function handleKeyDown(event) {
         :option-value="optionValue"
         v-bind="{ ...$attrs, ...styleAttrs }"
         @filter="filterHandler"
-        @blur="() => emit('blur')"
         :emit-value="nullishToTrue($attrs['emit-value'])"
         :map-options="nullishToTrue($attrs['map-options'])"
         :use-input="nullishToTrue($attrs['use-input'])"
diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue
index 12322c3fa..5944a1ea7 100644
--- a/src/components/common/VnSelectDialog.vue
+++ b/src/components/common/VnSelectDialog.vue
@@ -34,7 +34,6 @@ const isAllowedToCreate = computed(() => {
     return role.hasAny($props.rolesAllowedToCreate);
 });
 </script>
-
 <template>
     <VnSelect
         v-model="value"
@@ -63,7 +62,6 @@ const isAllowedToCreate = computed(() => {
         </template>
     </VnSelect>
 </template>
-
 <style lang="scss" scoped>
 .default-icon {
     cursor: pointer;
diff --git a/src/css/app.scss b/src/css/app.scss
index 79088b2b2..7461d7c73 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -76,7 +76,6 @@ a {
     text-decoration: underline;
 }
 
-// Removes chrome autofill background
 input:-webkit-autofill,
 select:-webkit-autofill {
     color: var(--vn-text-color);
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index 4a78811e6..82ac717de 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -392,16 +392,26 @@ entry:
     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
     summary:
+        invoiceAmount: Amount
         commission: Commission
         currency: Currency
         invoiceNumber: Invoice number
@@ -454,7 +464,10 @@ entry:
             ektFk: Ekt
             packingOut: Package out
             landing: Landing
-            isExcludedFromAvailable: Es inventory
+            isExcludedFromAvailable: Exclude from inventory
+            isRaid: Raid
+            invoiceNumber: Invoice
+            reference: Ref/Alb/Guide
 ticket:
     card:
         customerId: Customer ID
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index 2bfe7ec4b..c94bb5a46 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -392,16 +392,26 @@ entry:
     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
     summary:
+        invoiceAmount: Importe
         commission: Comisión
         currency: Moneda
         invoiceNumber: Núm. factura
@@ -455,7 +465,10 @@ entry:
             ektFk: Ekt
             packingOut: Embalaje envíos
             landing: Llegada
-            isExcludedFromAvailable: Es inventario
+            isExcludedFromAvailable: Excluir del inventario
+            isRaid: Redada
+            invoiceNumber: Nº Factura
+            reference: Ref/Alb/Guía
 ticket:
     card:
         customerId: ID cliente
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index fdfd7ff9c..85e81bac6 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -100,17 +100,6 @@ const columns = computed(() => [
         columnFilter: {
             component: 'number',
         },
-        columnField: {
-            component: null,
-            after: {
-                component: markRaw(VnLinkPhone),
-                attrs: ({ model }) => {
-                    return {
-                        'phone-number': model,
-                    };
-                },
-            },
-        },
     },
     {
         align: 'left',
diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index 150ef3b84..f73e42449 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -247,8 +247,14 @@ function handleLocation(data, location) {
                     :label="t('Longitude')"
                     clearable
                     v-model="data.longitude"
+                    :decimal-places="6"
+                />
+                <VnInputNumber
+                    :label="t('Latitude')"
+                    clearable
+                    v-model="data.latitude"
+                    :decimal-places="6"
                 />
-                <VnInputNumber :label="t('Latitude')" clearable v-model="data.latitude" />
             </VnRow>
             <h4 class="q-mb-xs">{{ t('Notes') }}</h4>
             <VnRow
diff --git a/src/pages/Entry/Card/<!DOCTYPE html>.html b/src/pages/Entry/Card/<!DOCTYPE html>.html
deleted file mode 100644
index 3652ce443..000000000
--- a/src/pages/Entry/Card/<!DOCTYPE html>.html	
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-    <head>
-        <meta charset="UTF-8" />
-        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-        <title>Checkbox Focus with Button</title>
-        <style>
-            body {
-                font-family: Arial, sans-serif;
-            }
-            .checkbox-container {
-                display: flex;
-                align-items: center;
-                margin-bottom: 20px;
-            }
-            input[type='checkbox'] {
-                width: 20px;
-                height: 20px;
-            }
-            label {
-                margin-left: 10px;
-            }
-            /* Estilos para el foco */
-            input[type='checkbox']:focus {
-                outline: 2px solid blue;
-                outline-offset: 2px;
-            }
-        </style>
-    </head>
-    <body>
-        <div class="checkbox-container">
-            <input type="checkbox" id="myCheckbox" />
-            <label for="myCheckbox">Acepto los términos y condiciones</label>
-        </div>
-
-        <!-- Botón para enfocar el checkbox -->
-        <button id="focusButton">Dar foco al checkbox</button>
-
-        <script>
-            const checkbox = document.getElementById('myCheckbox');
-            const focusButton = document.getElementById('focusButton');
-
-            // Manejador de eventos para cuando el checkbox recibe el foco
-            checkbox.addEventListener('focus', () => {
-                console.log('El checkbox tiene el foco');
-            });
-
-            // Manejador de eventos para cuando el checkbox pierde el foco
-            checkbox.addEventListener('blur', () => {
-                console.log('El checkbox perdió el foco');
-            });
-
-            // Manejador de eventos para cuando se cambia el estado del checkbox
-            checkbox.addEventListener('change', (event) => {
-                if (event.target.checked) {
-                    console.log('El checkbox está marcado');
-                } else {
-                    console.log('El checkbox no está marcado');
-                }
-            });
-
-            // Dar foco al checkbox cuando se presiona el botón
-            focusButton.addEventListener('click', () => {
-                checkbox.focus();
-            });
-        </script>
-    </body>
-</html>
diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue
index 147287837..87bb3bfec 100644
--- a/src/pages/Entry/Card/EntryBasicData.vue
+++ b/src/pages/Entry/Card/EntryBasicData.vue
@@ -9,6 +9,7 @@ import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
 import FilterTravelForm from 'src/components/FilterTravelForm.vue';
 
@@ -51,28 +52,6 @@ const onFilterTravelSelected = (formData, id) => {
     >
         <template #form="{ data }">
             <VnRow>
-                <VnSelect
-                    :label="t('globals.supplier')"
-                    v-model="data.supplierFk"
-                    url="Suppliers"
-                    option-value="id"
-                    option-label="nickname"
-                    :fields="['id', 'nickname']"
-                    hide-selected
-                    :required="true"
-                    map-options
-                >
-                    <template #option="scope">
-                        <QItem v-bind="scope.itemProps">
-                            <QItemSection>
-                                <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
-                                <QItemLabel caption>
-                                    {{ scope.opt?.nickname }}, {{ scope.opt?.id }}
-                                </QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template>
-                </VnSelect>
                 <VnSelectDialog
                     :label="t('entry.basicData.travel')"
                     v-model="data.travelFk"
@@ -105,9 +84,36 @@ const onFilterTravelSelected = (formData, id) => {
                         </QItem>
                     </template>
                 </VnSelectDialog>
+                <VnSelect
+                    :label="t('globals.supplier')"
+                    v-model="data.supplierFk"
+                    url="Suppliers"
+                    option-value="id"
+                    option-label="nickname"
+                    :fields="['id', 'nickname']"
+                    hide-selected
+                    :required="true"
+                    map-options
+                >
+                    <template #option="scope">
+                        <QItem v-bind="scope.itemProps">
+                            <QItemSection>
+                                <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
+                                <QItemLabel caption>
+                                    {{ scope.opt?.nickname }}, {{ scope.opt?.id }}
+                                </QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                    </template>
+                </VnSelect>
             </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
diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue
index f470cf08a..9ea150cd9 100644
--- a/src/pages/Entry/Card/EntryBuys.vue
+++ b/src/pages/Entry/Card/EntryBuys.vue
@@ -2,21 +2,36 @@
 import { useStateStore } from 'stores/useStateStore';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-import { onMounted, ref } from 'vue';
+import { h, onMounted, ref } from 'vue';
 
-import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
+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 FetchedTags from 'components/ui/FetchedTags.vue';
-import VnColor from 'src/components/VnColor.vue';
+import FetchedTags from 'src/components/ui/FetchedTags.vue';
+import VnColor from 'src/components/common/VnColor.vue';
+import { QCheckbox } from 'quasar';
+const $props = defineProps({
+    id: {
+        type: Number,
+        default: null,
+    },
+    editableMode: {
+        type: Boolean,
+        default: true,
+    },
+});
 
 const { t } = useI18n();
 const stateStore = useStateStore();
 const route = useRoute();
 const selectedRows = ref([]);
+const entityId = ref($props.id ?? route.params.id);
+console.log('entityId: ', entityId.value);
+
+const footer = ref({});
 const columns = [
     {
-        name: 'buyFk',
+        name: 'id',
         isId: true,
         visible: false,
         isEditable: false,
@@ -26,6 +41,7 @@ const columns = [
         label: 'Nv',
         name: 'isIgnored',
         component: 'checkbox',
+        toggleIndeterminate: false,
         width: '35px',
     },
     {
@@ -33,6 +49,7 @@ const columns = [
         label: 'Id',
         name: 'itemFk',
         component: 'input',
+        isEditable: false,
         create: true,
         width: '45px',
     },
@@ -52,7 +69,8 @@ const columns = [
     },
     {
         align: 'center',
-        label: t('Size'),
+        label: t('Siz.'),
+        toolTip: t('Size'),
         name: 'size',
         width: '35px',
         isEditable: false,
@@ -63,8 +81,18 @@ const columns = [
     {
         align: 'center',
         label: t('Sti.'),
+        toolTip: t('Printed Stickers/Stickers'),
         name: 'stickers',
         component: 'number',
+        attrs: {
+            positive: false,
+        },
+        cellEvent: {
+            'update:modelValue': (value, oldValue, row) => {
+                row['quantity'] = value * row['packing'];
+                row['amount'] = row['quantity'] * row['buyingValue'];
+            },
+        },
         width: '35px',
     },
     {
@@ -92,11 +120,49 @@ const columns = [
         label: 'Pack',
         name: 'packing',
         component: 'number',
+        cellEvent: {
+            'update:modelValue': (value, oldValue, row) => {
+                console.log('oldValue: ', oldValue);
+                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: '35px',
         style: (row) => {
             if (row.groupingMode === 'grouping')
                 return { color: 'var(--vn-label-color)' };
         },
+        /* append: {
+            name: 'groupingMode',
+            h: (row) =>
+                h(QCheckbox, {
+                    'data-name': 'groupingMode',
+                    modelValue: row['groupingMode'] === 'packing',
+                    size: 'sm',
+                    'onUpdate:modelValue': (value) => {
+                        console.log('entra');
+                        if (value) row['groupingMode'] = 'packing';
+                        else row['groupingMode'] = 'grouping';
+                    },
+                    onClick: (event) => {
+                        console.log('eventOnClick: ', event);
+                    },
+                }),
+        }, */
+    },
+    {
+        align: 'center',
+        label: 'Group',
+        name: 'groupingMode',
+        component: 'toggle',
+        attrs: {
+            trueValue: 'grouping',
+            falseValue: 'packing',
+            indeterminateValue: null,
+        },
+        width: '35px',
     },
     {
         align: 'center',
@@ -113,17 +179,31 @@ const columns = [
         label: t('Quantity'),
         name: 'quantity',
         component: 'number',
-        width: '50px',
-        style: (row) => {
-            if (row?.quantity !== row?.stickers * row?.packing)
-                return { color: 'var(--q-negative)' };
+        attrs: {
+            positive: false,
         },
+        cellEvent: {
+            'update:modelValue': (value, oldValue, row) => {
+                row['amount'] = value * row['buyingValue'];
+            },
+        },
+        width: '50px',
+        style: getQuantityStyle,
     },
     {
         align: 'center',
-        label: 'Cost.',
+        label: t('Cost'),
+        toolTip: t('Buying value'),
         name: 'buyingValue',
         component: 'number',
+        attrs: {
+            positive: false,
+        },
+        cellEvent: {
+            'update:modelValue': (value, oldValue, row) => {
+                row['amount'] = row['quantity'] * value;
+            },
+        },
         width: '50px',
     },
     {
@@ -131,13 +211,17 @@ const columns = [
         label: t('Amount'),
         name: 'amount',
         width: '50px',
-        style: () => {
-            return { color: 'var(--vn-label-color)' };
+        component: 'number',
+        attrs: {
+            positive: false,
         },
+        isEditable: false,
+        style: getAmountStyle,
     },
     {
         align: 'center',
-        label: t('Package'),
+        label: t('Pack.'),
+        toolTip: t('Package'),
         name: 'price2',
         component: 'number',
         width: '35px',
@@ -147,13 +231,40 @@ const columns = [
         label: t('Box'),
         name: 'price3',
         component: 'number',
+        cellEvent: {
+            'update:modelValue': (value, row) => {
+                /*
+                Call db.execV("UPDATE vn.item SET " & _
+                        "typeFk = # " & _
+                        ",producerFk  = # " & _
+                        ",minPrice = # " & _
+                        ",box = # " & _
+                        ",hasMinPrice = # " & _
+                        ",comment = # " & _
+                    "WHERE id = # " _
+                    , Me.tipo_id _
+                    , Me.producer_id _
+                    , Me.PVP _
+                    , Me.caja _
+                    , Me.Min _
+                    , Nz(Me.reference, 0) _
+                    , Me.Id_Article _
+                    )
+                Me.Tarifa2 = Me.Tarifa2 * (Me.Tarifa3 / Me.Tarifa3.OldValue)
+                Call actualizar_compra
+                Me.sincro = True
+                */
+            },
+        },
         width: '35px',
     },
     {
         align: 'center',
         label: 'Min.',
+        toolTip: t('Minimum price'),
         name: 'minPrice',
         component: 'number',
+        isEditable: false,
         width: '35px',
         style: (row) => {
             if (row?.hasMinPrice)
@@ -163,21 +274,27 @@ const columns = [
     {
         align: 'center',
         label: t('P.Sen'),
+        toolTip: t('Packing sent'),
         name: 'packingOut',
         component: 'number',
+        isEditable: false,
         width: '40px',
     },
     {
         align: 'center',
         label: t('Com.'),
+        toolTip: t('Comment'),
         name: 'comment',
         component: 'input',
+        isEditable: false,
         width: '55px',
     },
     {
         align: 'center',
         label: 'Prod.',
+        toolTip: t('Producer'),
         name: 'subName',
+        isEditable: false,
         width: '45px',
         style: () => {
             return { color: 'var(--vn-label-color)' };
@@ -185,43 +302,148 @@ const columns = [
     },
     {
         align: 'center',
-        label: 'Tags',
+        label: t('Tags'),
         name: 'tags',
-        width: '120px',
+        width: '125px',
         columnSearch: false,
     },
     {
         align: 'center',
         label: 'Comp.',
+        toolTip: t('Company'),
         name: 'company_name',
+        component: 'input',
+        isEditable: false,
         width: '35px',
     },
 ];
+
+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)' };
+}
+
 onMounted(() => {
+    console.log('viewMode: ', $props.editableMode);
     stateStore.rightDrawer = false;
 });
 </script>
 <template>
-    <VnSubToolbar />
+    <QToggle
+        toggle-indeterminate
+        toggle-order="ft"
+        v-model="cyan"
+        label="'ft' order + toggle-indeterminate"
+        color="cyan"
+    />
+    <Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown() && editableMode">
+        <QBtnGroup push style="column-gap: 1px">
+            <QBtn icon="calculate" color="primary" flat @click="console.log('calculate')">
+                <QTooltip>{{ t('tableActions.openBucketCalculator') }}</QTooltip>
+            </QBtn>
+            <QBtnDropdown
+                icon="box_edit"
+                color="primary"
+                flat
+                tool-tip="test"
+                @click="console.log('request_quote')"
+                :title="t('tableActions.setSaleMode')"
+            >
+                <div>
+                    <QList>
+                        <QItem clickable v-close-popup @click="setSaleMode('packing')">
+                            <QItemSection>
+                                <QItemLabel>Packing</QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                        <QItem clickable v-close-popup @click="setSaleMode('packing')">
+                            <QItemSection>
+                                <QItemLabel>Grouping</QItemLabel>
+                            </QItemSection>
+                        </QItem>
+                        <QItem label="Grouping" />
+                    </QList>
+                </div>
+            </QBtnDropdown>
+            <QBtn
+                icon="invert_colors"
+                color="primary"
+                flat
+                @click="console.log('price_check')"
+            >
+                <QTooltip>{{ t('tableActions.openCalculator') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                icon="exposure_neg_1"
+                color="primary"
+                flat
+                @click="console.log('request_quote')"
+                title="test"
+            >
+                <QTooltip>{{ t('tableActions.invertQuantitySign') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                icon="price_check"
+                color="primary"
+                flat
+                @click="console.log('request_quote')"
+            >
+                <QTooltip>{{ t('tableActions.checkAmount') }}</QTooltip>
+            </QBtn>
+            <QBtn
+                icon="price_check"
+                color="primary"
+                flat
+                @click="console.log('request_quote')"
+            >
+                <QTooltip>{{ t('tableActions.setMinPrice') }}</QTooltip>
+            </QBtn>
+        </QBtnGroup>
+    </Teleport>
+    <FetchData
+        ref="footerFetchDataRef"
+        :url="`Entries/${entityId}/getBuyList`"
+        :params="{ groupBy: 'GROUP BY b.entryFk' }"
+        @on-fetch="
+            (data) => {
+                console.log('data: ', data);
+                footer = data[0];
+            }
+        "
+        auto-load
+    />
     <VnTable
         ref="tableRef"
         data-key="EntryBuys"
-        :url="`Entries/${route.params.id}/getBuys`"
+        :url="`Entries/${entityId}/getBuyList`"
+        save-url="Buys/crud"
         :disable-option="{ card: true }"
         v-model:selected="selectedRows"
-        :table="{
-            'row-key': 'id',
-            selection: 'multiple',
-        }"
+        :table="
+            editableMode
+                ? {
+                      'row-key': 'id',
+                      selection: 'multiple',
+                  }
+                : {}
+        "
+        :is-editable="editableMode"
+        :without-header="!editableMode"
+        :with-filters="editableMode"
         :right-search="false"
         :row-click="false"
         :columns="columns"
         class="buyList"
-        is-editable
+        table-height="84vh"
         auto-load
+        footer
     >
-        <template #column-hex>
-            <VnColor :colors="['#ff0000', '#ffff00', '#ff0000']" style="height: 100%" />
+        <template #column-hex="{ row }">
+            <VnColor :colors="row?.hexJson" style="height: 100%" />
         </template>
         <template #column-name="{ row }">
             <span class="link">
@@ -233,29 +455,57 @@ onMounted(() => {
             <FetchedTags :item="row" :columns="3" />
         </template>
         <template #column-stickers="{ row }">
-            <span style="color: var(--vn-label-color)">{{ row.printedStickers }}</span>
-            <span>/{{ row.stickers }}</span>
+            <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>/{{ footer?.stickers }}</span>
+            </div>
+        </template>
+        <template #column-footer-weight>
+            {{ footer?.weight }}
+        </template>
+        <template #column-footer-quantity>
+            <span :style="getQuantityStyle(footer)">
+                {{ footer?.quantity }}
+            </span>
+        </template>
+        <template #column-footer-amount>
+            <span :style="getAmountStyle(footer)">
+                {{ footer?.amount }}
+            </span>
         </template>
     </VnTable>
 </template>
-<style lang="scss" scoped>
-.q-checkbox__inner--dark {
-    &__inner {
-        border-radius: 0% !important;
-        background-color: rosybrown;
-    }
-}
-</style>
 <i18n>
 es:
-    Article: Artículo3
-    Size: Med.
+    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
+    Printed Stickers/Stickers: Etiquetas impresas/Etiquetas
+    Cost: Cost.
+    Buying value: Coste
+    Producer: Productor
+    Company: Compañia
+    Tags: Etiquetas
 </i18n>
diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue
index eca78771f..3d183ad98 100644
--- a/src/pages/Entry/Card/EntryDescriptor.vue
+++ b/src/pages/Entry/Card/EntryDescriptor.vue
@@ -1,17 +1,17 @@
 <script setup>
 import { ref, computed, onMounted } from 'vue';
-import { ref, computed, onMounted } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
-
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
-import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
-
 import { toDate } from 'src/filters';
 import { usePrintService } from 'composables/usePrintService';
 import { getUrl } from 'src/composables/getUrl';
 import filter from './EntryFilter.js';
+import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
+import axios from 'axios';
+import { useRouter } from 'vue-router';
+const { push } = useRouter();
 
 const $props = defineProps({
     id: {
@@ -55,9 +55,22 @@ const getEntryRedirectionFilter = (entry) => {
     });
 };
 
-const showEntryReport = () => {
-    openReport(`Entries/${route.params.id}/entry-order-pdf`);
-};
+function showEntryReport() {
+    openReport(`Entries/${entityId.value}/entry-order-pdf`);
+}
+function recalculateRates() {
+    console.log('recalculateRates');
+}
+async function cloneEntry() {
+    console.log('cloneEntry');
+    await axios
+        .post(`Entries/${entityId.value}/cloneEntry`)
+        .then((response) => push(`/entry/${response.data[0].vNewEntryFk}`));
+}
+async function deleteEntry() {
+    console.log('deleteEntry');
+    await axios.post(`Entries/${entityId.value}/deleteEntry`).then(() => push(`/entry/`));
+}
 </script>
 
 <template>
@@ -73,14 +86,39 @@ const showEntryReport = () => {
             <QItem v-ripple clickable @click="showEntryReport(entity)">
                 <QItemSection>{{ t('Show entry report') }}</QItemSection>
             </QItem>
+            <QItem v-ripple clickable @click="recalculateRates(entity)">
+                <QItemSection>{{ t('Recalculate rates') }}</QItemSection>
+            </QItem>
+            <QItem v-ripple clickable @click="cloneEntry(entity)">
+                <QItemSection>{{ t('Clone') }}</QItemSection>
+            </QItem>
+            <QItem v-ripple clickable @click="deleteEntry(entity)">
+                <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"
             />
         </template>
         <template #icons="{ entity }">
@@ -107,6 +145,14 @@ const showEntryReport = () => {
                         }}</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 }">
@@ -153,6 +199,7 @@ const showEntryReport = () => {
 </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
@@ -162,4 +209,5 @@ es:
     Virtual entry: Es una redada
     shipped: Enviado
     landed: Recibido
+    This entry is deleted: Esta entrada está eliminada
 </i18n>
diff --git a/src/pages/Entry/Card/EntryFilter.js b/src/pages/Entry/Card/EntryFilter.js
index 3ff62cf27..3b2a888aa 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,11 @@ export default {
                 fields: ['id', 'nickname'],
             },
         },
+        {
+            relation: 'currency',
+            scope: {
+                fields: ['id', 'code'],
+            },
+        },
     ],
 };
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index a8091fba2..8caa9acf5 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -2,15 +2,15 @@
 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 } from 'src/filters';
-import { getUrl } from 'src/composables/getUrl';
-import axios from 'axios';
-import FetchedTags from 'src/components/ui/FetchedTags.vue';
+import EntryBuys from './EntryBuys.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
 import VnToSummary from 'src/components/ui/VnToSummary.vue';
 
 const route = useRoute();
@@ -30,117 +30,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();
@@ -150,8 +39,11 @@ 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"
@@ -168,34 +60,64 @@ const fetchEntryBuys = async () => {
             />
         </template>
         <template #header>
-            <span>{{ entry.id }} - {{ entry.supplier.nickname }}</span>
+            <span>{{ entry.id }} - {{ entry?.supplier?.nickname }}</span>
         </template>
         <template #body>
             <QCard class="vn-one">
-                <router-link
-                    :to="{ name: 'EntryBasicData', params: { id: entityId } }"
-                    class="header header-link"
-                >
-                    {{ t('globals.summary.basicData') }}
-                    <QIcon name="open_in_new" />
-                </router-link>
+                <VnTitle
+                    :url="`#/entry/{{ entityId }}/basicData`"
+                    :text="t('globals.summary.basicData')"
+                />
                 <div class="card-group">
                     <div class="card-content">
                         <VnLv
                             :label="t('entry.summary.commission')"
-                            :value="entry.commission"
+                            :value="entry?.commission"
                         />
                         <VnLv
                             :label="t('entry.summary.currency')"
-                            :value="entry.currency?.name"
+                            :value="entry?.currency?.name"
                         />
-                        <VnLv :label="t('globals.company')" :value="entry.company.code" />
-                        <VnLv :label="t('globals.reference')" :value="entry.reference" />
+                        <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"
+                            :value="entry?.invoiceNumber"
                         />
                     </div>
+                    <div class="card-content">
+                        <QCheckbox
+                            :label="t('entry.summary.ordered')"
+                            v-model="entry.isOrdered"
+                            :disable="true"
+                        />
+                        <QCheckbox
+                            :label="t('globals.confirmed')"
+                            v-model="entry.isConfirmed"
+                            :disable="true"
+                        />
+                        <QCheckbox
+                            :label="t('entry.summary.booked')"
+                            v-model="entry.isBooked"
+                            :disable="true"
+                        />
+                        <QCheckbox
+                            :label="t('entry.summary.excludedFromAvailable')"
+                            v-model="entry.isExcludedFromAvailable"
+                            :disable="true"
+                        />
+                    </div>
+                </div>
+            </QCard>
+            <QCard class="vn-one" v-if="entry?.travelFk">
+                <VnTitle
+                    :url="`#/travel/{{ entry.travel.id }}/summary`"
+                    :text="t('globals.summary.basicData')"
+                />
+                <div class="card-group">
                     <div class="card-content">
                         <VnLv :label="t('entry.summary.travelReference')">
                             <template #value>
@@ -210,18 +132,23 @@ const fetchEntryBuys = async () => {
                             :value="entry.travel.agency?.name"
                         />
                         <VnLv
-                            :label="t('shipped')"
+                            :label="t('entry.summary.travelShipped')"
                             :value="toDate(entry.travel.shipped)"
                         />
                         <VnLv
                             :label="t('globals.warehouseOut')"
                             :value="entry.travel.warehouseOut?.name"
                         />
-                        <VnLv :label="t('landed')" :value="toDate(entry.travel.landed)" />
+                        <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">
                         <QCheckbox
                             :label="t('entry.summary.travelDelivered')"
                             v-model="entry.travel.isDelivered"
@@ -235,59 +162,35 @@ const fetchEntryBuys = async () => {
                     </div>
                 </div>
             </QCard>
-            <QCard class="vn-one">
-                <router-link
-                    :to="{ name: 'TravelSummary', params: { id: entry.travel.id } }"
-                    class="header header-link"
-                >
-                    {{ t('Travel data') }}
-                    <QIcon name="open_in_new" />
-                </router-link>
-                <QCheckbox
-                    :label="t('entry.summary.ordered')"
-                    v-model="entry.isOrdered"
-                    :disable="true"
-                />
-                <QCheckbox
-                    :label="t('globals.confirmed')"
-                    v-model="entry.isConfirmed"
-                    :disable="true"
-                />
-                <QCheckbox
-                    :label="t('entry.summary.booked')"
-                    v-model="entry.isBooked"
-                    :disable="true"
-                />
-                <QCheckbox
-                    :label="t('entry.summary.excludedFromAvailable')"
-                    v-model="entry.isExcludedFromAvailable"
-                    :disable="true"
+            <QCard class="vn-max">
+                <VnTitle
+                    :url="`#/entry/{{ entityId }}/buys`"
+                    :text="t('entry.summary.buys')"
                 />
+                <EntryBuys v-if="entityId" :id="entityId" :editable-mode="false" />
             </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 {
-    margin-bottom: 16px; /* Para dar espacio entre las secciones */
+    display: flex;
+    flex-direction: column;
+    text-overflow: ellipsis;
 }
 
 @media (min-width: 1010px) {
     .card-group {
-        flex-direction: row; /* Coloca los contenidos en fila cuando el ancho es mayor a 600px */
+        flex-direction: row;
     }
     .card-content {
-        flex: 1; /* Haz que las secciones ocupen el mismo espacio */
-        margin-right: 16px; /* Espaciado entre las dos primeras tarjetas */
+        flex: 1;
+        margin-right: 16px;
     }
 }
 </style>
@@ -295,4 +198,5 @@ const fetchEntryBuys = async () => {
 <i18n>
 es:
     Travel data: Datos envío
+    InvoiceIn data: Datos factura
 </i18n>
diff --git a/src/pages/Entry/EntryFilter.vue b/src/pages/Entry/EntryFilter.vue
index f50810eb7..3cad020ed 100644
--- a/src/pages/Entry/EntryFilter.vue
+++ b/src/pages/Entry/EntryFilter.vue
@@ -18,6 +18,7 @@ const props = defineProps({
 
 const currenciesOptions = ref([]);
 const companiesOptions = ref([]);
+const entryFilterPanel = ref();
 </script>
 
 <template>
@@ -37,7 +38,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(`params.${tag.label}`) }}: </strong>
@@ -47,70 +48,82 @@ const companiesOptions = ref([]);
         <template #body="{ params, searchFn }">
             <QItem>
                 <QItemSection>
-                    <VnInput
-                        v-model="params.search"
-                        :label="t('entryFilter.filter.search')"
-                        is-outlined
-                    />
+                    <QCheckbox
+                        :label="t('params.isExcludedFromAvailable')"
+                        v-model="params.isExcludedFromAvailable"
+                        toggle-indeterminate
+                    >
+                        <QTooltip>
+                            {{
+                                t(
+                                    'entry.list.tableVisibleColumns.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.filter.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('params.isRaid')"
+                        v-model="params.isRaid"
+                        toggle-indeterminate
+                    >
+                        <QTooltip>
+                            {{ t('entry.list.tableVisibleColumns.isRaid') }}
+                        </QTooltip>
+                    </QCheckbox>
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInput
-                        v-model="params.invoiceNumber"
-                        :label="t('params.invoiceNumber')"
-                        is-outlined
-                    />
+                    <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.travelFk"
-                        :label="t('params.travelFk')"
-                        is-outlined
-                    />
-                </QItemSection>
-            </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnSelect
-                        :label="t('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('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>
@@ -143,56 +156,90 @@ const companiesOptions = ref([]);
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInputDate
-                        :label="t('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('params.from')"
-                        v-model="params.from"
-                        @update:model-value="searchFn()"
+                    <VnInput
+                        v-model="params.reference"
+                        :label="t('entryFilter.filter.reference')"
                         is-outlined
                     />
                 </QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnInputDate
-                        :label="t('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('params.isBooked')"
-                        v-model="params.isBooked"
-                        toggle-indeterminate
-                    />
-                </QItemSection>
-                <QItemSection>
-                    <QCheckbox
-                        :label="t('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('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
+                    />
+                </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>
@@ -203,30 +250,38 @@ const companiesOptions = ref([]);
 <i18n>
 en:
     params:
-        
-        invoiceNumber: Invoice number
-        travelFk: Travel
-        companyFk: Company
-        currencyFk: Currency
-        supplierFk: Supplier
-        from: From
-        to: To
-        created: Created
-        isBooked: Booked
-        isConfirmed: Confirmed
+        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:
-       
-        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
+        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 ff79cf685..6cb912ca7 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -1,23 +1,24 @@
 <script setup>
-import { onMounted, ref, computed } from 'vue';
+import axios from 'axios';
+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 VnSearchbar from 'src/components/ui/VnSearchbar.vue';
-import { useStateStore } from 'stores/useStateStore';
 import VnTable from 'components/VnTable/VnTable.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import { toDate } from 'src/filters';
-import { useSummaryDialog } from 'src/composables/useSummaryDialog';
-import EntrySummary from './Card/EntrySummary.vue';
 import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
-import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
 
-const stateStore = useStateStore();
 const { t } = useI18n();
 const tableRef = ref();
+const defaultEntry = ref({});
+const state = useState();
+const user = state.getUser();
 
-const { viewSummary } = useSummaryDialog();
-const entryFilter = {
+const entryQueryFilter = {
     include: [
         {
             relation: 'suppliers',
@@ -42,11 +43,50 @@ const entryFilter = {
 
 const columns = computed(() => [
     {
-        name: 'status',
-        columnFilter: false,
+        align: 'center',
+        label: 'Ex',
+        toolTip: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
+        name: 'isExcludedFromAvailable',
+        component: 'checkbox',
+        width: '35px',
     },
     {
-        align: 'left',
+        align: 'center',
+        label: 'Pe',
+        toolTip: t('entry.list.tableVisibleColumns.isOrdered'),
+        name: 'isOrdered',
+        component: 'checkbox',
+        width: '35px',
+    },
+    {
+        align: 'center',
+        label: 'Le',
+        toolTip: t('entry.list.tableVisibleColumns.isConfirmed'),
+        name: 'isConfirmed',
+        component: 'checkbox',
+        width: '35px',
+    },
+    {
+        align: 'center',
+        label: 'Re',
+        toolTip: t('entry.list.tableVisibleColumns.isReceived'),
+        name: 'isReceived',
+        component: 'checkbox',
+        width: '35px',
+    },
+    {
+        align: 'center',
+        label: t('entry.list.tableVisibleColumns.landed'),
+        name: 'landed',
+        component: 'date',
+        columnField: {
+            component: null,
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)),
+        width: '105px',
+    },
+    {
+        align: 'right',
         label: t('globals.id'),
         name: 'id',
         isId: true,
@@ -54,30 +94,6 @@ const columns = computed(() => [
             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'),
@@ -89,117 +105,168 @@ const columns = computed(() => [
             url: 'suppliers',
             fields: ['id', 'name'],
         },
-        columnField: {
-            component: null,
-        },
         format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
     },
     {
-        align: 'center',
-        label: t('entry.list.tableVisibleColumns.isBooked'),
-        name: 'isBooked',
-        cardVisible: true,
-        create: true,
-        component: 'checkbox',
-    },
-    {
-        align: 'center',
-        label: t('entry.list.tableVisibleColumns.isConfirmed'),
-        name: 'isConfirmed',
-        cardVisible: true,
-        create: true,
-        component: 'checkbox',
-    },
-    {
-        align: 'center',
-        label: t('entry.list.tableVisibleColumns.isOrdered'),
-        name: 'isOrdered',
-        cardVisible: true,
-        create: true,
-        component: 'checkbox',
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.invoiceNumber'),
+        name: 'invoiceNumber',
+        component: 'input',
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.companyFk'),
-        name: 'companyFk',
+        label: t('entry.list.tableVisibleColumns.reference'),
+        name: 'reference',
+        isTitle: true,
+        component: 'input',
+        columnField: {
+            component: null,
+        },
+        cardVisible: true,
+    },
+    {
+        align: 'left',
+        label: 'AWB',
+        name: 'awbCode',
+        component: 'input',
+    },
+    {
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.agencyModeId'),
+        name: 'agencyModeId',
+        cardVisible: true,
         component: 'select',
         attrs: {
-            url: 'companies',
-            fields: ['id', 'code'],
-            optionLabel: 'code',
-            optionValue: 'id',
+            url: 'agencyModes',
+            fields: ['id', 'name'],
         },
         columnField: {
             component: null,
         },
-        create: true,
-
-        format: (row, dashIfEmpty) => dashIfEmpty(row.companyCode),
+        format: (row, dashIfEmpty) => dashIfEmpty(row.agencyModeName),
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.travelFk'),
-        name: 'travelFk',
+        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: 'travels',
-            fields: ['id', 'ref'],
-            optionLabel: 'ref',
-            optionValue: 'id',
+            url: 'warehouses',
+            fields: ['id', 'name'],
         },
         columnField: {
             component: null,
         },
-        create: true,
-        format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
+        format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseOutName),
     },
     {
         align: 'left',
-        label: t('entry.list.tableVisibleColumns.invoiceAmount'),
-        name: 'invoiceAmount',
+        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: 'center',
-        label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
-        name: 'isExcludedFromAvailable',
-        chip: {
-            color: null,
-            condition: (value) => value,
-            icon: 'vn:inventory',
-        },
+        align: 'left',
+        label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
+        name: 'entryTypeCode',
+        cardVisible: true,
         columnFilter: {
-            inWhere: true,
-        },
-        component: 'checkbox',
-    },
-    {
-        align: 'center',
-        label: t('entry.list.tableVisibleColumns.isRaid'),
-        name: 'isRaid',
-        chip: {
-            color: null,
-            condition: (value) => value,
-            icon: 'vn:net',
-        },
-        columnFilter: {
-            inWhere: true,
-        },
-        component: 'checkbox',
-    },
-    {
-        align: 'right',
-        name: 'tableActions',
-        actions: [
-            {
-                title: t('components.smartCard.viewSummary'),
-                icon: 'preview',
-                action: (row) => viewSummary(row.id, EntrySummary),
-                isPrimary: true,
+            component: 'select',
+            attrs: {
+                optionValue: 'code',
+                optionLabel: 'description',
+                url: 'entryTypes',
+                fields: ['code', 'description'],
             },
-        ],
+        },
+        format: (row, dashIfEmpty) => dashIfEmpty(row.entryTypeDescription),
+    },
+    {
+        name: 'dated',
+        label: t('entry.list.tableVisibleColumns.dated'),
+        component: 'date',
+        cardVisible: false,
+        visible: false,
+        create: true,
+    },
+    {
+        name: 'companyFk',
+        label: t('entry.list.tableVisibleColumns.companyFk'),
+        cardVisible: false,
+        visible: false,
+        create: true,
+        component: 'select',
+        attrs: {
+            optionValue: 'id',
+            optionLabel: 'code',
+            url: 'Companies',
+        },
+    },
+    {
+        name: 'travelFk',
+        label: t('entry.list.tableVisibleColumns.travelFk'),
+        cardVisible: false,
+        visible: false,
+        create: 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: '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;
+    }
+    if (timeDiff < 0) return { color: 'info', 'text-color': 'black' };
+    return { color: 'transparent' };
+}
+
+onBeforeMount(async () => {
+    defaultEntry.value = (await axios.get('EntryConfigs/findOne')).data;
+});
 </script>
 <template>
     <VnSearchbar
@@ -214,40 +281,35 @@ const columns = computed(() => [
         </template>
     </RightMenu>
     <VnTable
+        v-if="defaultEntry.defaultSupplierFk"
         ref="tableRef"
         data-key="EntryList"
         url="Entries/filter"
-        :filter="entryFilter"
+        :filter="entryQueryFilter"
         :create="{
             urlCreate: 'Entries',
             title: t('Create entry'),
             onDataSaved: ({ id }) => tableRef.redirect(id),
-            formInitialData: {},
+            formInitialData: {
+                supplierFk: defaultEntry.defaultSupplierFk,
+                dated: Date.vnNew(),
+                companyFk: user?.companyFk,
+            },
         }"
         order="id DESC"
         :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>
@@ -255,12 +317,6 @@ 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>
     </VnTable>
 </template>
 
diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue
index 4705525fb..a51d76e9c 100644
--- a/src/pages/Item/Card/ItemDescriptor.vue
+++ b/src/pages/Item/Card/ItemDescriptor.vue
@@ -36,6 +36,10 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
+    proxyRender: {
+        type: Boolean,
+        default: false,
+    },
 });
 
 const { openCloneDialog } = cloneItem();
@@ -171,7 +175,7 @@ const openRegularizeStockForm = () => {
             </QCardActions>
         </template>
         <template #actions="{}">
-            <QCardActions class="row justify-center">
+            <QCardActions class="row justify-center" v-if="proxyRender">
                 <QBtn
                     :to="{
                         name: 'ItemDiary',
@@ -184,6 +188,16 @@ const openRegularizeStockForm = () => {
                 >
                     <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 3891c9f17..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: {
@@ -30,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/locale/en.yml b/src/pages/Item/locale/en.yml
index ac5010a12..42961db3d 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -117,6 +117,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
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index 96c8cbc9a..d4dd30123 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -119,6 +119,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