From 9f8c491eda5518e8dcc4411548c57a000a806e47 Mon Sep 17 00:00:00 2001
From: Jon <jon@verdnatura.es>
Date: Thu, 6 Mar 2025 08:07:40 +0100
Subject: [PATCH] refactor: refs #8363 modified ItemFixedPrice and the e2e

---
 src/components/CrudModel.vue                  |   1 +
 src/components/EditTableCellValueForm.vue     |   4 +-
 src/pages/Item/ItemFixedPrice.vue             | 527 ++++++++----------
 src/pages/Item/ItemFixedPriceFilter.vue       |  17 +-
 .../integration/item/ItemFixedPrice.spec.js   | 101 ++--
 5 files changed, 285 insertions(+), 365 deletions(-)

diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index 8c4f70f3b..92244886c 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -333,6 +333,7 @@ watch(formUrl, async () => {
                 :disable="!selected?.length"
                 :title="t('globals.remove')"
                 v-if="$props.defaultRemove"
+                data-cy="crudModelDefaultRemoveBtn"
             />
             <QBtn
                 :label="tMobile('globals.reset')"
diff --git a/src/components/EditTableCellValueForm.vue b/src/components/EditTableCellValueForm.vue
index 172866191..2197718c1 100644
--- a/src/components/EditTableCellValueForm.vue
+++ b/src/components/EditTableCellValueForm.vue
@@ -85,14 +85,14 @@ const closeForm = () => {
                     hide-selected
                     option-label="label"
                     v-model="selectedField"
-                    data-cy="field-to-edit"
+                    data-cy="EditFixedPriceSelectOption"
                 />
                 <component
                     :is="inputs[selectedField?.component || 'input']"
                     v-bind="selectedField?.attrs || {}"
                     v-model="newValue"
                     :label="t('Value')"
-                    data-cy="value-to-edit"
+                    data-cy="EditFixedPriceValueOption"
                     style="width: 200px"
                 />
             </VnRow>
diff --git a/src/pages/Item/ItemFixedPrice.vue b/src/pages/Item/ItemFixedPrice.vue
index fdfa1d3d1..8e647a228 100644
--- a/src/pages/Item/ItemFixedPrice.vue
+++ b/src/pages/Item/ItemFixedPrice.vue
@@ -1,150 +1,171 @@
 <script setup>
-import { onMounted, ref, onUnmounted, nextTick, computed } from 'vue';
+import { onMounted, ref, onUnmounted, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
-import FetchedTags from 'components/ui/FetchedTags.vue';
-import VnInput from 'src/components/common/VnInput.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import VnInputDate from 'src/components/common/VnInputDate.vue';
-import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue';
-import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue';
-import { useQuasar } from 'quasar';
-import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
-import { tMobile } from 'src/composables/tMobile';
-import VnConfirm from 'components/ui/VnConfirm.vue';
-import FetchData from 'src/components/FetchData.vue';
-import { useStateStore } from 'stores/useStateStore';
-import { toDate } from 'src/filters';
-import { useVnConfirm } from 'composables/useVnConfirm';
-import { useState } from 'src/composables/useState';
-import useNotify from 'src/composables/useNotify.js';
 import axios from 'axios';
-import { isLower, isBigger } from 'src/filters/date.js';
+import { useQuasar } from 'quasar';
+import { useStateStore } from 'stores/useStateStore';
+import useNotify from 'src/composables/useNotify.js';
+import FetchedTags from 'components/ui/FetchedTags.vue';
+import VnConfirm from 'components/ui/VnConfirm.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import EditTableCellValueForm from 'src/components/EditTableCellValueForm.vue';
+import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import VnTable from 'src/components/VnTable/VnTable.vue';
-import { QCheckbox } from 'quasar';
+import VnColor from 'src/components/common/VnColor.vue';
+import VnImg from 'src/components/ui/VnImg.vue';
+import { toDate } from 'src/filters';
+import { isLower, isBigger } from 'src/filters/date.js';
+import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue';
+import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
 
 const quasar = useQuasar();
 const stateStore = useStateStore();
 const { t } = useI18n();
-const { openConfirmationModal } = useVnConfirm();
-const state = useState();
 const { notify } = useNotify();
 const tableRef = ref();
 const editTableCellDialogRef = ref(null);
-const user = state.getUser();
 const fixedPrices = ref([]);
-const warehousesOptions = ref([]);
-const hasSelectedRows = computed(() => rowsSelected.value.length > 0);
-const rowsSelected = ref([]);
-const itemFixedPriceFilterRef = ref();
+const selectedRows = ref([]);
+const hasSelectedRows = computed(() => selectedRows.value.length > 0);
 
 onMounted(async () => {
     stateStore.rightDrawer = true;
 });
 onUnmounted(() => (stateStore.rightDrawer = false));
 
-const defaultColumnAttrs = {
-    align: 'left',
-    sortable: true,
-};
 const columns = computed(() => [
     {
-        label: t('item.fixedPrice.itemFk'),
-        name: 'itemFk',
-        ...defaultColumnAttrs,
-        isId: true,
+        align: 'center',
+        label: t('lines.image'),
+        name: 'image',
         columnField: {
-            component: 'input',
-            type: 'number',
+            component: VnImg,
+            attrs: ({ row }) => {
+                return {
+                    id: row.itemFk,
+                };
+            },
         },
-        columnClass: 'shrink',
+        width: '45px',
+        columnFilter: false,
     },
     {
+        name: 'itemFk',
+        label: t('item.fixedPrice.itemFk'),
+        labelAbbreviation: 'ID',
+        toolTip: t('item.fixedPrice.itemFk'),
+        component: 'number',
+        columnFilter: {
+            inWhere: true,
+        },
+        width: '50px',
+    },
+    {
+        labelAbbreviation: '',
+        label: 'Color',
+        name: 'hex',
+        columnSearch: false,
+        isEditable: false,
+        width: '12px',
+        component: 'select',
+        attrs: {
+            url: 'Inks',
+            fields: ['id', 'name'],
+        },
+    },
+    {
+        align: 'left',
         label: t('globals.name'),
         name: 'name',
-        ...defaultColumnAttrs,
         create: true,
-        columnFilter: {
-            component: 'select',
-            attrs: {
-                url: 'Items',
-                fields: ['id', 'name', 'subName'],
-                optionLabel: 'name',
-                optionValue: 'name',
-                uppercase: false,
-            },
+        component: 'select',
+        attrs: {
+            url: 'Items',
+            fields: ['id', 'name', 'subName'],
+            optionLabel: 'name',
+            optionValue: 'name',
+            uppercase: false,
         },
     },
     {
         label: t('item.fixedPrice.groupingPrice'),
         name: 'rate2',
-        ...defaultColumnAttrs,
-        component: 'input',
-        type: 'number',
+        component: 'number',
+        create: true,
+        createOrder: 3,
+        width: '55px',
     },
     {
         label: t('item.fixedPrice.packingPrice'),
         name: 'rate3',
-        ...defaultColumnAttrs,
-        component: 'input',
-        type: 'number',
+        component: 'number',
+        create: true,
+        createOrder: 4,
+        width: '55px',
+    },
+    {
+        name: 'hasMinPrice',
+        label: t('item.fixedPrice.hasMinPrice'),
+        labelAbbreviation: 'MP',
+        toolTip: t('item.fixedPrice.hasMinPrice'),
+        label: t('Has min price'),
+        component: 'checkbox',
+        attrs: {
+            toggleIndeterminate: false,
+        },
+        width: '50px',
     },
-
     {
         label: t('item.fixedPrice.minPrice'),
         name: 'minPrice',
-        ...defaultColumnAttrs,
-        component: 'input',
-        type: 'number',
+        component: 'number',
+        cellEvent: {
+            'update:modelValue': async (value, oldValue, row) => {
+                updateMinPrice(value, row);
+            },
+        },
+        width: '55px',
+        style: (row) => {
+            if (!row?.hasMinPrice) return { color: 'var(--vn-label-color)' };
+        },
+        format: (row) => parseFloat(row['minPrice']).toFixed(2),
     },
     {
         label: t('item.fixedPrice.started'),
-        field: 'started',
         name: 'started',
-        format: ({ started }) => toDate(started),
-        ...defaultColumnAttrs,
-        columnField: {
-            component: 'date',
-            class: 'shrink',
-        },
+        component: 'date',
         columnFilter: {
             component: 'date',
         },
-        columnClass: 'expand',
+        create: true,
+        createOrder: 5,
+        width: '70px',
     },
     {
         label: t('item.fixedPrice.ended'),
         name: 'ended',
-        ...defaultColumnAttrs,
-        columnField: {
-            component: 'date',
-            class: 'shrink',
-        },
+        component: 'date',
         columnFilter: {
             component: 'date',
         },
-        columnClass: 'expand',
-        format: (row) => toDate(row.ended),
+        create: true,
+        createOrder: 6,
+        width: '70px',
     },
-
     {
+        align: 'center',
         label: t('globals.warehouse'),
         name: 'warehouseFk',
-        ...defaultColumnAttrs,
-        columnClass: 'shrink',
         component: 'select',
-        options: warehousesOptions,
-        columnFilter: {
-            name: 'warehouseFk',
-            inWhere: true,
-            component: 'select',
-            attrs: {
-                options: warehousesOptions,
-                'option-label': 'name',
-                'option-value': 'id',
-            },
+        attrs: {
+            url: 'Warehouses',
+            fields: ['id', 'name'],
+            optionLabel: 'name',
+            optionValue: 'id',
         },
+        create: true,
+        format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseName),
     },
     {
         align: 'right',
@@ -206,14 +227,6 @@ const editTableFieldsOptions = [
         },
     },
 ];
-const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => {
-    return inputType === 'text'
-        ? {
-              'keyup.enter': () => upsertPrice(props, resetMinPrice),
-              blur: () => upsertPrice(props, resetMinPrice),
-          }
-        : { 'update:modelValue': () => upsertPrice(props, resetMinPrice) };
-};
 
 const updateMinPrice = async (value, props) => {
     props.row.hasMinPrice = value;
@@ -234,7 +247,7 @@ const validations = ({ row }) => {
         'warehouseFk',
     ];
     const isValid = requiredFields.every(
-        (field) => row[field] !== null && row[field] !== undefined
+        (field) => row[field] !== null && row[field] !== undefined,
     );
     return isValid;
 };
@@ -261,59 +274,17 @@ async function upsertFixedPrice(row) {
     return data;
 }
 
-function checkLastVisibleRow() {
-    let lastVisibleRow = null;
-
-    getTableRows().forEach((row, index) => {
-        const rect = row.getBoundingClientRect();
-        if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
-            lastVisibleRow = index;
-        }
-    });
-
-    return lastVisibleRow;
-}
-
-const addRow = (original = null) => {
-    let copy = null;
-    const today = Date.vnNew();
-    const millisecsInDay = 86400000;
-    const daysInWeek = 7;
-    const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay);
-
-    copy = {
-        id: 0,
-        started: today,
-        ended: nextWeek,
-        hasMinPrice: 0,
-        $index: 0,
-    };
-    return { original, copy };
-};
-
-const getTableRows = () =>
-    document.getElementsByClassName('q-table')[0].querySelectorAll('tr.cursor-pointer');
-
-function highlightNewRow({ $index: index }) {
-    const row = getTableRows()[index];
-    if (row) {
-        row.classList.add('highlight');
-        setTimeout(() => {
-            row.classList.remove('highlight');
-        }, 3000);
-    }
-}
 const openEditTableCellDialog = () => {
     editTableCellDialogRef.value.show();
 };
 
 const onEditCellDataSaved = async () => {
-    rowsSelected.value = [];
+    selectedRows.value = [];
     tableRef.value.reload();
 };
 
 const removeFuturePrice = async () => {
-    rowsSelected.value.forEach(({ id }) => {
+    selectedRows.value.forEach(({ id }) => {
         const rowIndex = fixedPrices.value.findIndex(({ id }) => id === id);
         removePrice(id, rowIndex);
     });
@@ -340,46 +311,43 @@ const removePrice = async (id) => {
 const dateStyle = (date) =>
     date
         ? {
-              'bg-color': 'warning',
-              'is-outlined': true,
+              color: 'var(--vn-black-text-color)',
           }
-        : {};
+        : { 'background-color': 'transparent' };
 
-function handleOnDataSave({ CrudModelRef }) {
-    const { original, copy } = addRow(CrudModelRef.formData[checkLastVisibleRow()]);
-    if (original) {
-        CrudModelRef.formData.splice(original?.$index ?? 0, 0, copy);
-    } else {
-        CrudModelRef.insert(copy);
+async function cloneFixedPrice(rows) {
+    for (let row of rows) {
+        let clonedLine = {
+            itemFk: row.itemFk,
+            warehouseFk: row.warehouseFk,
+            rate2: row.rate2,
+            rate3: row.rate3,
+            started: row.started,
+            ended: row.ended,
+        };
+        console.log('clonedLine: ', clonedLine);
+        await axios.post('FixedPrices', clonedLine);
     }
-    nextTick(() => {
-        highlightNewRow(original ?? { $index: 0 });
-    });
 }
 </script>
 
 <template>
-    <FetchData
-        @on-fetch="(data) => (warehousesOptions = data)"
-        auto-load
-        url="Warehouses"
-        :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
-    />
     <RightMenu>
         <template #right-panel>
-            <ItemFixedPriceFilter
-                data-key="ItemFixedPrices"
-                ref="itemFixedPriceFilterRef"
-            />
+            <ItemFixedPriceFilter data-key="ItemFixedPrices" />
         </template>
     </RightMenu>
-    <VnSubToolbar>
-        <template #st-actions>
+    <VnSubToolbar />
+    <Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown()">
+        <QBtnGroup push style="column-gap: 10px">
             <QBtn
                 :disable="!hasSelectedRows"
                 @click="openEditTableCellDialog()"
                 color="primary"
                 icon="edit"
+                flat
+                :label="t('globals.edit')"
+                data-cy="FixedPriceToolbarEditBtn"
             >
                 <QTooltip>
                     {{ t('Edit fixed price(s)') }}
@@ -387,74 +355,50 @@ function handleOnDataSave({ CrudModelRef }) {
             </QBtn>
             <QBtn
                 :disable="!hasSelectedRows"
-                :label="tMobile('globals.remove')"
+                @click="cloneFixedPrice(selectedRows)"
                 color="primary"
-                icon="delete"
+                icon="vn:clone"
                 flat
-                @click="(row) => confirmRemove(row, true)"
-                :title="t('globals.remove')"
-            />
-        </template>
-    </VnSubToolbar>
+                :label="t('globals.clone')"
+                data-cy="FixedPriceToolbarCloneBtn"
+            >
+                <QTooltip>
+                    {{ t('Clone fixed price(s)') }}
+                </QTooltip>
+            </QBtn>
+        </QBtnGroup>
+    </Teleport>
     <VnTable
-        :default-remove="false"
-        :default-reset="false"
-        :default-save="false"
+        ref="tableRef"
         data-key="ItemFixedPrices"
         url="FixedPrices/filter"
-        :order="['name DESC', 'itemFk DESC']"
+        :order="'name DESC'"
         save-url="FixedPrices/crud"
-        ref="tableRef"
-        dense
-        :filter="{
-            where: {
-                warehouseFk: user.warehouseFk,
-            },
-        }"
         :columns="columns"
-        default-mode="table"
-        auto-load
         :is-editable="true"
         :right-search="false"
         :table="{
             'row-key': 'id',
             selection: 'multiple',
         }"
-        v-model:selected="rowsSelected"
-        :create-as-dialog="false"
+        v-model:selected="selectedRows"
         :create="{
-            onDataSaved: handleOnDataSave,
+            urlCreate: 'FixedPrices',
+            title: t('Create buy'),
+            formInitialData: {},
+            onDataSaved: () => tableRef.reload(),
+            showSaveAndContinueBtn: true,
         }"
         :disable-option="{ card: true }"
-        :has-sub-toolbar="false"
+        auto-load
     >
-        <template #header-selection="scope">
-            <QCheckbox v-model="scope.selected" />
+        <template #column-image="{ row }">
+            <div class="image-wrapper">
+                <VnImg :id="row.itemFk" class="rounded" />
+            </div>
         </template>
-        <template #body-selection="scope">
-            {{ scope }}
-            <QCheckbox flat v-model="scope.selected" />
-        </template>
-
-        <template #column-itemFk="props">
-            <VnSelect
-                style="max-width: 100px"
-                url="Items/withName"
-                hide-selected
-                option-label="id"
-                option-value="id"
-                v-model="props.row.itemFk"
-                v-on="getRowUpdateInputEvents(props, true, 'select')"
-            >
-                <template #option="scope">
-                    <QItem v-bind="scope.itemProps">
-                        <QItemSection>
-                            <QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
-                            <QItemLabel caption>{{ scope.opt?.name }}</QItemLabel>
-                        </QItemSection>
-                    </QItem>
-                </template>
-            </VnSelect>
+        <template #column-hex="{ row }">
+            <VnColor :colors="row?.hexJson" style="height: 100%; min-width: 2000px" />
         </template>
         <template #column-name="{ row }">
             <span class="link">
@@ -462,111 +406,78 @@ function handleOnDataSave({ CrudModelRef }) {
             </span>
             <span class="subName">{{ row.subName }}</span>
             <ItemDescriptorProxy :id="row.itemFk" />
-            <FetchedTags :item="row" :columns="3" />
+            <FetchedTags :item="row" :columns="6" />
         </template>
-        <template #column-rate2="props">
-            <QTd class="col">
-                <VnInput
-                    type="currency"
-                    style="width: 75px"
-                    v-model.number="props.row.rate2"
-                    v-on="getRowUpdateInputEvents(props)"
-                >
-                    <template #append>€</template>
-                </VnInput>
-            </QTd>
+        <template #column-started="{ row }">
+            <div class="editable-text q-pb-xxs">
+                <QBadge :style="dateStyle(isLower(row?.ended))">
+                    {{ toDate(row?.started) }}
+                </QBadge>
+            </div>
         </template>
-        <template #column-rate3="props">
-            <QTd class="col">
-                <VnInput
-                    style="width: 75px"
-                    type="currency"
-                    v-model.number="props.row.rate3"
-                    v-on="getRowUpdateInputEvents(props)"
-                >
-                    <template #append>€</template>
-                </VnInput>
-            </QTd>
+        <template #column-ended="{ row }">
+            <div class="editable-text q-pb-xxs">
+                <QBadge :style="dateStyle(isBigger(row?.ended))">
+                    {{ toDate(row?.ended) }}
+                </QBadge>
+            </div>
         </template>
-        <template #column-minPrice="props">
-            <QTd class="col">
-                <div class="row" style="align-items: center">
-                    <QCheckbox
-                        :model-value="props.row.hasMinPrice"
-                        @update:model-value="updateMinPrice($event, props)"
-                        :false-value="0"
-                        :true-value="1"
-                        :toggle-indeterminate="false"
-                    />
-                    <VnInput
-                        class="col"
-                        type="currency"
-                        mask="###.##"
-                        :disable="props.row.hasMinPrice === 0"
-                        v-model.number="props.row.minPrice"
-                        v-on="getRowUpdateInputEvents(props)"
-                    >
-                        <template #append>€</template>
-                    </VnInput>
-                </div>
-            </QTd>
-        </template>
-        <template #column-started="props">
-            <VnInputDate
-                class="vnInputDate"
-                :show-event="true"
-                v-model="props.row.started"
-                v-on="getRowUpdateInputEvents(props, false, 'date')"
-                v-bind="dateStyle(isBigger(props.row.started))"
-            />
-        </template>
-        <template #column-ended="props">
-            <VnInputDate
-                class="vnInputDate"
-                :show-event="true"
-                v-model="props.row.ended"
-                v-on="getRowUpdateInputEvents(props, false, 'date')"
-                v-bind="dateStyle(isLower(props.row.ended))"
-            />
-        </template>
-        <template #column-warehouseFk="props">
-            <QTd class="col">
-                <VnSelect
-                    style="max-width: 150px"
-                    :options="warehousesOptions"
-                    hide-selected
-                    option-label="name"
-                    option-value="id"
-                    v-model="props.row.warehouseFk"
-                    v-on="getRowUpdateInputEvents(props, false, 'select')"
-                />
-            </QTd>
-        </template>
-        <template #column-deleteAction="{ row, rowIndex }">
-            <QIcon
-                name="delete"
-                size="sm"
-                class="cursor-pointer fill-icon-on-hover"
-                color="primary"
-                @click.stop="
-                    openConfirmationModal(
-                        t('globals.rowWillBeRemoved'),
-                        t('Do you want to clone this item?'),
-                        () => removePrice(row.id, rowIndex)
-                    )
-                "
+        <template #column-create-name="{ data }">
+            <VnSelect
+                url="Items/search"
+                v-model="data.itemFk"
+                :label="t('Article')"
+                :fields="['id', 'name']"
+                :filter-options="['id', 'name']"
+                option-label="name"
+                option-value="id"
+                :required="true"
+                sort-by="name ASC"
+                data-cy="FixedPriceCreateNameSelect"
             >
-                <QTooltip class="text-no-wrap">
-                    {{ t('globals.delete') }}
-                </QTooltip>
-            </QIcon>
+                <template #option="scope">
+                    <QItem v-bind="scope.itemProps">
+                        <QItemSection>
+                            <QItemLabel>
+                                {{ scope.opt.name }}
+                            </QItemLabel>
+                            <QItemLabel caption> #{{ scope.opt.id }} </QItemLabel>
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
+        </template>
+        <template #column-create-warehouseFk="{ data }">
+            <VnSelect
+                :label="t('globals.warehouse')"
+                url="Warehouses"
+                v-model="data.warehouseFk"
+                :fields="['id', 'name']"
+                option-label="name"
+                option-value="id"
+                hide-selected
+                :required="true"
+                sort-by="name ASC"
+                data-cy="FixedPriceCreateWarehouseSelect"
+            >
+                <template #option="scope">
+                    <QItem v-bind="scope.itemProps">
+                        <QItemSection>
+                            <QItemLabel>
+                                {{ scope.opt.name }}
+                            </QItemLabel>
+                            <QItemLabel caption> #{{ scope.opt.id }} </QItemLabel>
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
         </template>
     </VnTable>
 
     <QDialog ref="editTableCellDialogRef">
         <EditTableCellValueForm
             edit-url="FixedPrices/editFixedPrice"
-            :rows="rowsSelected"
+            :rows="selectedRows"
             :fields-options="editTableFieldsOptions"
             @on-data-saved="onEditCellDataSaved()"
         />
diff --git a/src/pages/Item/ItemFixedPriceFilter.vue b/src/pages/Item/ItemFixedPriceFilter.vue
index 8d92e245d..7e1adb8bb 100644
--- a/src/pages/Item/ItemFixedPriceFilter.vue
+++ b/src/pages/Item/ItemFixedPriceFilter.vue
@@ -13,11 +13,14 @@ const props = defineProps({
         required: true,
     },
 });
-
 </script>
 
 <template>
-    <ItemsFilterPanel :data-key="props.dataKey" :custom-tags="['tags']">
+    <ItemsFilterPanel
+        :data-key="props.dataKey"
+        :search-button="true"
+        :custom-tags="['tags']"
+    >
         <template #body="{ params, searchFn }">
             <QItem class="q-my-md">
                 <QItemSection>
@@ -53,23 +56,19 @@ const props = defineProps({
                     />
                 </QItemSection>
             </QItem>
-            <QItem class="q-my-md">
+            <QItem>
                 <QItemSection>
                     <VnInputDate
-                        :label="t('params.started')"
                         v-model="params.started"
+                        :label="t('params.started')"
                         is-outlined
-                        @update:model-value="searchFn()"
                     />
                 </QItemSection>
-            </QItem>
-            <QItem class="q-my-md">
                 <QItemSection>
                     <VnInputDate
-                        :label="t('params.ended')"
                         v-model="params.ended"
+                        :label="t('params.ended')"
                         is-outlined
-                        @update:model-value="searchFn()"
                     />
                 </QItemSection>
             </QItem>
diff --git a/test/cypress/integration/item/ItemFixedPrice.spec.js b/test/cypress/integration/item/ItemFixedPrice.spec.js
index 2cf9c2caf..2fad87eac 100644
--- a/test/cypress/integration/item/ItemFixedPrice.spec.js
+++ b/test/cypress/integration/item/ItemFixedPrice.spec.js
@@ -1,10 +1,14 @@
 /// <reference types="cypress" />
-function goTo(n = 1) {
-    return `.q-virtual-scroll__content > :nth-child(${n})`;
-}
-const firstRow = goTo();
-`.q-virtual-scroll__content > :nth-child(2)`;
 describe('Handle Items FixedPrice', () => {
+    const grouping = 'Grouping price';
+    const saveEditBtn = '.q-mt-lg > .q-btn--standard';
+    const createForm = {
+        'Grouping price': { val: '5' },
+        'Packing price': { val: '5' },
+        Started: { val: '01-01-2001', type: 'date' },
+        Ended: { val: '15-01-2001', type: 'date' },
+    };
+
     beforeEach(() => {
         cy.viewport(1280, 720);
         cy.login('developer');
@@ -14,50 +18,55 @@ describe('Handle Items FixedPrice', () => {
             '.q-header > .q-toolbar > :nth-child(1) > .q-btn__content > .q-icon',
         ).click();
     });
-    it.skip('filter', function () {
+
+    it('filter by category', () => {
         cy.get('.category-filter > :nth-child(1) > .q-btn__content > .q-icon').click();
-        cy.selectOption('.list > :nth-child(2)', 'Alstroemeria');
-        cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
-
-        cy.addBtnClick();
-        cy.selectOption(`${firstRow} > :nth-child(2)`, '#13');
-        cy.get(`${firstRow} > :nth-child(4)`).find('input').type(1);
-        cy.get(`${firstRow} > :nth-child(5)`).find('input').type('2');
-        cy.selectOption(`${firstRow} > :nth-child(9)`, 'Warehouse One');
-        cy.get('.q-notification__message').should('have.text', 'Data saved');
-        /* ==== End Cypress Studio ==== */
-    });
-    it.skip('Create and delete ', function () {
-        cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
-        cy.addBtnClick();
-        cy.selectOption(`${firstRow} > :nth-child(2)`, '#11');
-        cy.get(`${firstRow} > :nth-child(4)`).type('1');
-        cy.get(`${firstRow} > :nth-child(5)`).type('2');
-        cy.selectOption(`${firstRow} > :nth-child(9)`, 'Warehouse One');
-        cy.get('.q-notification__message').should('have.text', 'Data saved');
-        cy.get('.q-gutter-x-sm > .q-btn > .q-btn__content > .q-icon').click();
-        cy.get(`${firstRow} > .text-right > .q-btn > .q-btn__content > .q-icon`).click();
-        cy.get(
-            '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block',
-        ).click();
-        cy.get('.q-notification__message').should('have.text', 'Data saved');
+        cy.get('.q-table__middle').should('be.visible').should('have.length', 1);
     });
 
-    it.skip('Massive edit', function () {
-        cy.get(' .bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner ').click();
-        cy.get('#subToolbar > .q-btn--standard').click();
-        cy.selectOption("[data-cy='field-to-edit']", 'Min price');
-        cy.dataCy('value-to-edit').find('input').type('1');
-        cy.get('.countLines').should('have.text', ' 1 ');
-        cy.get('.q-mt-lg > .q-btn--standard').click();
-        cy.get('.q-notification__message').should('have.text', 'Data saved');
+    it('should create a new fixed price, then delete it', () => {
+        cy.dataCy('vnTableCreateBtn').click();
+        cy.dataCy('FixedPriceCreateNameSelect').type('Melee weapon combat fist 15cm');
+        cy.get('.q-menu .q-item').contains('Melee weapon combat fist 15cm').click();
+        cy.dataCy('FixedPriceCreateWarehouseSelect').type('Warehouse One');
+        cy.get('.q-menu .q-item').contains('Warehouse One').click();
+        cy.get('.q-menu').then(($menu) => {
+            if ($menu.is(':visible')) {
+                cy.dataCy('FixedPriceCreateWarehouseSelect').as('focusedElement').focus();
+                cy.dataCy('FixedPriceCreateWarehouseSelect').blur();
+            }
+        });
+        cy.fillInForm(createForm);
+        cy.dataCy('FormModelPopup_save').click();
+        cy.checkNotification('Data created');
+        cy.get('[data-col-field="name"]').each(($el) => {
+            cy.wrap($el)
+                .invoke('text')
+                .then((text) => {
+                    if (text.includes('Melee weapon combat fist 15cm')) {
+                        cy.wrap($el).parent().find('.sticky').click();
+
+                        cy.dataCy('VnConfirm_confirm').click();
+                        cy.checkNotification('Data saved');
+                    }
+                });
+        });
     });
-    it.skip('Massive remove', function () {
-        cy.get(' .bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner ').click();
-        cy.get('#subToolbar > .q-btn--flat').click();
-        cy.get(
-            '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block',
-        ).click();
-        cy.get('.q-notification__message').should('have.text', 'Data saved');
+
+    it('should edit all items', () => {
+        cy.get('.bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner').click();
+        cy.dataCy('FixedPriceToolbarEditBtn').click();
+        cy.dataCy('EditFixedPriceSelectOption').type(grouping);
+        cy.get('.q-menu .q-item').contains(grouping).click();
+        cy.dataCy('EditFixedPriceValueOption').type('5');
+        cy.get(saveEditBtn).click();
+        cy.checkNotification('Data saved');
+    });
+
+    it('should remove all items', () => {
+        cy.get('.bg-header > :nth-child(1) > .q-checkbox > .q-checkbox__inner').click();
+        cy.dataCy('crudModelDefaultRemoveBtn').click();
+        cy.dataCy('VnConfirm_confirm').click();
+        cy.checkNotification('Data saved');
     });
 });