From 65e48f6194e42ba9332ed07f9e92c314ec8dee62 Mon Sep 17 00:00:00 2001
From: pablone <pablone@verdnatura.es>
Date: Wed, 12 Feb 2025 19:43:45 +0100
Subject: [PATCH 1/2] feat: refs #6897 refactor VnColor and EntryList
 components; update FormModelPopup button visibility

---
 src/components/FormModelPopup.vue  | 27 ++++++-----
 src/components/VnTable/VnTable.vue |  8 ++--
 src/components/common/VnColor.vue  |  4 +-
 src/i18n/locale/en.yml             |  1 +
 src/i18n/locale/es.yml             |  1 +
 src/pages/Entry/Card/EntryBuys.vue | 76 +++++++++++++++++++++---------
 src/pages/Entry/EntryList.vue      | 12 +----
 7 files changed, 79 insertions(+), 50 deletions(-)

diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue
index 30aaa3513..3ae71a341 100644
--- a/src/components/FormModelPopup.vue
+++ b/src/components/FormModelPopup.vue
@@ -58,19 +58,6 @@ defineExpose({
             <p>{{ subtitle }}</p>
             <slot name="form-inputs" :data="data" :validate="validate" />
             <div class="q-mt-lg row justify-end">
-                <QBtn
-                    v-if="showSaveAndContinueBtn"
-                    :label="t('globals.isSaveAndContinue')"
-                    :title="t('globals.isSaveAndContinue')"
-                    type="submit"
-                    color="primary"
-                    class="q-ml-sm"
-                    :disabled="isLoading"
-                    :loading="isLoading"
-                    data-cy="FormModelPopup_isSaveAndContinue"
-                    z-max
-                    @click="() => (isSaveAndContinue = true)"
-                />
                 <QBtn
                     :label="t('globals.cancel')"
                     :title="t('globals.cancel')"
@@ -90,6 +77,20 @@ defineExpose({
                     "
                 />
                 <QBtn
+                    v-if="showSaveAndContinueBtn"
+                    :label="t('globals.isSaveAndContinue')"
+                    :title="t('globals.isSaveAndContinue')"
+                    type="submit"
+                    color="primary"
+                    class="q-ml-sm"
+                    :disabled="isLoading"
+                    :loading="isLoading"
+                    data-cy="FormModelPopup_isSaveAndContinue"
+                    z-max
+                    @click="() => (isSaveAndContinue = true)"
+                />
+                <QBtn
+                    v-else
                     :label="t('globals.save')"
                     :title="t('globals.save')"
                     type="submit"
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index 7e0757f6c..3e1923b4c 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -340,8 +340,9 @@ const clickHandler = async (event) => {
 
     const isDateElement = event.target.closest('.q-date');
     const isTimeElement = event.target.closest('.q-time');
+    const isQselectDropDown = event.target.closest('.q-select__dropdown-icon');
 
-    if (isDateElement || isTimeElement) return;
+    if (isDateElement || isTimeElement || isQselectDropDown) return;
 
     if (clickedElement === null) {
         destroyInput(editingRow.value, editingField.value);
@@ -411,7 +412,7 @@ async function renderInput(rowId, field, clickedElement) {
         focusOnMount: true,
         eventHandlers: {
             'update:modelValue': async (value) => {
-                if (isSelect) {
+                if (isSelect && value) {
                     row[column.name] = value[column.attrs?.optionValue ?? 'id'];
                     row[column?.name + 'TextValue'] =
                         value[column.attrs?.optionLabel ?? 'name'];
@@ -593,6 +594,7 @@ const checkbox = ref(null);
                 @row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
                 @update:selected="emit('update:selected', $event)"
                 @selection="(details) => handleSelection(details, rows)"
+                :hide-selected-banner="true"
             >
                 <template #top-left v-if="!$props.withoutHeader">
                     <slot name="top-left"> </slot>
@@ -1042,7 +1044,7 @@ es:
 
 .grid-three {
     display: grid;
-    grid-template-columns: repeat(auto-fit, minmax(150px, max-content));
+    grid-template-columns: repeat(auto-fit, minmax(300px, max-content));
     max-width: 100%;
     grid-gap: 20px;
     margin: 0 auto;
diff --git a/src/components/common/VnColor.vue b/src/components/common/VnColor.vue
index 00e662bb8..8a5a787b0 100644
--- a/src/components/common/VnColor.vue
+++ b/src/components/common/VnColor.vue
@@ -2,7 +2,7 @@
 const $props = defineProps({
     colors: {
         type: String,
-        default: '{"value":[]}',
+        default: '{"value": []}',
     },
 });
 
@@ -11,7 +11,7 @@ const maxHeight = 30;
 const colorHeight = maxHeight / colorArray?.length;
 </script>
 <template>
-    <div class="color-div" :style="{ height: `${maxHeight}px` }">
+    <div v-if="colors" class="color-div" :style="{ height: `${maxHeight}px` }">
         <div
             v-for="(color, index) in colorArray"
             :key="index"
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index 44759769a..e3b690042 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -156,6 +156,7 @@ globals:
     changeState: Change state
     raid: 'Raid {daysInForward} days'
     isVies: Vies
+    noData: No data available
     pageTitles:
         logIn: Login
         addressEdit: Update address
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index 2f8e6c1d1..1dbe25366 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -160,6 +160,7 @@ globals:
     changeState: Cambiar estado
     raid: 'Redada {daysInForward} días'
     isVies: Vies
+    noData: Datos no disponibles
     pageTitles:
         logIn: Inicio de sesión
         addressEdit: Modificar consignatario
diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue
index 76e1bb860..e159c5356 100644
--- a/src/pages/Entry/Card/EntryBuys.vue
+++ b/src/pages/Entry/Card/EntryBuys.vue
@@ -156,10 +156,10 @@ const columns = [
     {
         align: 'center',
         labelAbbreviation: t('Sti.'),
-        label: t('Printed Stickers/Stickers'),
+        label: t('Stickers'),
         toolTip: t('Printed Stickers/Stickers'),
         name: 'stickers',
-        component: 'number',
+        component: 'input',
         create: true,
         attrs: {
             positive: false,
@@ -179,7 +179,7 @@ const columns = [
         component: 'select',
         attrs: {
             url: 'packagings',
-            fields: ['id', 'volume'],
+            fields: ['id'],
             optionLabel: 'id',
         },
         create: true,
@@ -192,10 +192,10 @@ const columns = [
         component: 'number',
         create: true,
         width: '35px',
+        format: (row, dashIfEmpty) => parseFloat(row['weight']).toFixed(1),
     },
     {
-        align: 'center',
-        labelAbbreviation: 'Pack',
+        labelAbbreviation: 'P',
         label: 'Packing',
         toolTip: 'Packing',
         name: 'packing',
@@ -209,14 +209,13 @@ const columns = [
                 row['amount'] = row['quantity'] * row['buyingValue'];
             },
         },
-        width: '35px',
+        width: '20px',
         style: (row) => {
             if (row.groupingMode === 'grouping')
                 return { color: 'var(--vn-label-color)' };
         },
     },
     {
-        align: 'center',
         labelAbbreviation: 'GM',
         label: t('Grouping selector'),
         toolTip: t('Grouping selector'),
@@ -229,7 +228,7 @@ const columns = [
             indeterminateValue: null,
         },
         size: 'xs',
-        width: '30px',
+        width: '25px',
         create: true,
         rightFilter: false,
         getIcon: (value) => {
@@ -245,12 +244,12 @@ const columns = [
     },
     {
         align: 'center',
-        labelAbbreviation: 'Group',
+        labelAbbreviation: 'G',
         label: 'Grouping',
         toolTip: 'Grouping',
         name: 'grouping',
         component: 'number',
-        width: '35px',
+        width: '20px',
         create: true,
         style: (row) => {
             if (row.groupingMode === 'packing') return { color: 'var(--vn-label-color)' };
@@ -290,6 +289,7 @@ const columns = [
             },
         },
         width: '45px',
+        format: (row) => parseFloat(row['buyingValue']).toFixed(3),
     },
     {
         align: 'center',
@@ -301,6 +301,7 @@ const columns = [
             positive: false,
         },
         isEditable: false,
+        format: (row) => parseFloat(row['amount']).toFixed(2),
         style: getAmountStyle,
     },
     {
@@ -312,6 +313,7 @@ const columns = [
         component: 'number',
         width: '35px',
         create: true,
+        format: (row) => parseFloat(row['price2']).toFixed(2),
     },
     {
         align: 'center',
@@ -325,6 +327,7 @@ const columns = [
         },
         width: '35px',
         create: true,
+        format: (row) => parseFloat(row['price3']).toFixed(2),
     },
     {
         align: 'center',
@@ -344,6 +347,7 @@ const columns = [
         style: (row) => {
             if (!row?.hasMinPrice) return { color: 'var(--vn-label-color)' };
         },
+        format: (row) => parseFloat(row['minPrice']).toFixed(2),
     },
     {
         align: 'center',
@@ -518,7 +522,7 @@ onMounted(() => {
     <Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown() && editableMode">
         <QBtnGroup push style="column-gap: 1px">
             <QBtnDropdown
-                icon="exposure_neg_1"
+                label="+/-"
                 color="primary"
                 flat
                 :title="t('Invert quantity value')"
@@ -533,7 +537,7 @@ onMounted(() => {
                                 @click="invertQuantitySign(selectedRows, -1)"
                                 data-cy="set-negative-quantity"
                             >
-                                <span style="font-size: medium">-1</span>
+                                <span style="font-size: large">-</span>
                             </QBtn>
                         </QItemSection>
                     </QItem>
@@ -544,7 +548,7 @@ onMounted(() => {
                                 @click="invertQuantitySign(selectedRows, 1)"
                                 data-cy="set-positive-quantity"
                             >
-                                <span style="font-size: medium">1</span>
+                                <span style="font-size: large">+</span>
                             </QBtn>
                         </QItemSection>
                     </QItem>
@@ -558,11 +562,11 @@ onMounted(() => {
                 :disable="!selectedRows.length"
                 data-cy="check-buy-amount"
             >
-                <QTooltip>{{}}</QTooltip>
                 <QList>
                     <QItem>
                         <QItemSection>
                             <QBtn
+                                size="sm"
                                 icon="check"
                                 flat
                                 @click="setIsChecked(selectedRows, true)"
@@ -573,6 +577,7 @@ onMounted(() => {
                     <QItem>
                         <QItemSection>
                             <QBtn
+                                size="sm"
                                 icon="close"
                                 flat
                                 @click="setIsChecked(selectedRows, false)"
@@ -662,7 +667,7 @@ onMounted(() => {
             <FetchedTags :item="row" :columns="3" />
         </template>
         <template #column-stickers="{ row }">
-            <span class="editable-text">
+            <span :class="editableMode ? 'editable-text' : ''">
                 <span style="color: var(--vn-label-color)">
                     {{ row.printedStickers }}
                 </span>
@@ -693,20 +698,36 @@ onMounted(() => {
         </template>
         <template #column-create-itemFk="{ data }">
             <VnSelect
-                url="Items"
+                url="Items/search"
                 v-model="data.itemFk"
                 :label="t('Article')"
-                :fields="['id', 'name']"
+                :fields="['id', 'name', 'size', 'producerName']"
+                :filter-options="['id', 'name', 'size', 'producerName']"
                 option-label="name"
                 option-value="id"
                 @update:modelValue="
                     async (value) => {
-                        setBuyUltimate(value, data);
+                        await setBuyUltimate(value, data);
                     }
                 "
                 :required="true"
                 data-cy="itemFk-create-popup"
-            />
+                sort-by="nickname DESC"
+            >
+                <template #option="scope">
+                    <QItem v-bind="scope.itemProps">
+                        <QItemSection>
+                            <QItemLabel>
+                                {{ scope.opt.name }}
+                            </QItemLabel>
+                            <QItemLabel caption>
+                                #{{ scope.opt.id }}, {{ scope.opt?.size }},
+                                {{ scope.opt?.producerName }}
+                            </QItemLabel>
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
         </template>
         <template #column-create-groupingMode="{ data }">
             <VnSelectEnum
@@ -720,9 +741,14 @@ onMounted(() => {
             />
         </template>
         <template #previous-create-dialog="{ data }">
-            <div style="position: absolute">
+            <div
+                style="position: absolute"
+                :class="{ 'centered-container': !data.itemFk }"
+            >
                 <ItemDescriptor :id="data.itemFk" v-if="data.itemFk" />
-                <SkeletonDescriptor v-if="!data.itemFk" :has-image="true" />
+                <div v-else>
+                    <span>{{ t('globals.noData') }}</span>
+                </div>
             </div>
         </template>
     </VnTable>
@@ -744,6 +770,7 @@ es:
     Com.: Ref.
     Comment: Referencia
     Minimum price: Precio mínimo
+    Stickers: Etiquetas
     Printed Stickers/Stickers: Etiquetas impresas/Etiquetas
     Cost: Cost.
     Buying value: Coste
@@ -761,7 +788,12 @@ es:
     Check buy amount: Marcar como correcta la cantidad de compra
 </i18n>
 <style lang="scss" scoped>
-.test {
+.centered-container {
+    display: flex;
     justify-content: center;
+    align-items: center;
+    position: absolute;
+    width: 40%;
+    height: 100%;
 }
 </style>
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index c2b9e8bba..845d65604 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -182,14 +182,6 @@ const columns = computed(() => [
         name: 'entryTypeCode',
         cardVisible: true,
     },
-    {
-        name: 'dated',
-        label: t('entry.list.tableVisibleColumns.dated'),
-        component: 'date',
-        cardVisible: false,
-        visible: false,
-        create: true,
-    },
     {
         name: 'companyFk',
         label: t('entry.list.tableVisibleColumns.companyFk'),
@@ -220,7 +212,8 @@ function getBadgeAttrs(row) {
 
     let timeDiff = today - timeTicket;
 
-    if (timeDiff > 0) return { color: 'warning', 'text-color': 'black' };
+    if (timeDiff > 0) return { color: 'info', 'text-color': 'black' };
+    if (timeDiff < 0) return { color: 'warning', 'text-color': 'black' };
     switch (row.entryTypeCode) {
         case 'regularization':
         case 'life':
@@ -245,7 +238,6 @@ function getBadgeAttrs(row) {
         default:
             break;
     }
-    if (timeDiff < 0) return { color: 'info', 'text-color': 'black' };
     return { color: 'transparent' };
 }
 
-- 
2.40.1


From 8539e933897551edf5af974e5263953ad301bb50 Mon Sep 17 00:00:00 2001
From: pablone <pablone@verdnatura.es>
Date: Thu, 13 Feb 2025 08:42:13 +0100
Subject: [PATCH 2/2] feat: refs #6897 update FormModelPopup button logic and
 add entryList tests

---
 src/components/FormModelPopup.vue             | 26 +++++++++----------
 .../{entrylist.spec.js => entryList.spec.js}  |  8 +++---
 .../integration/route/routeList.spec.js       | 26 +++++++++++--------
 3 files changed, 32 insertions(+), 28 deletions(-)
 rename test/cypress/integration/entry/{entrylist.spec.js => entryList.spec.js} (98%)

diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue
index 3ae71a341..5cc7f06d2 100644
--- a/src/components/FormModelPopup.vue
+++ b/src/components/FormModelPopup.vue
@@ -76,6 +76,19 @@ defineExpose({
                         }
                     "
                 />
+                <QBtn
+                    :flat="showSaveAndContinueBtn"
+                    :label="t('globals.save')"
+                    :title="t('globals.save')"
+                    type="submit"
+                    color="primary"
+                    class="q-ml-sm"
+                    :disabled="isLoading"
+                    :loading="isLoading"
+                    data-cy="FormModelPopup_save"
+                    z-max
+                    @click="() => (isSaveAndContinue = false)"
+                />
                 <QBtn
                     v-if="showSaveAndContinueBtn"
                     :label="t('globals.isSaveAndContinue')"
@@ -89,19 +102,6 @@ defineExpose({
                     z-max
                     @click="() => (isSaveAndContinue = true)"
                 />
-                <QBtn
-                    v-else
-                    :label="t('globals.save')"
-                    :title="t('globals.save')"
-                    type="submit"
-                    color="primary"
-                    class="q-ml-sm"
-                    :disabled="isLoading"
-                    :loading="isLoading"
-                    data-cy="FormModelPopup_save"
-                    z-max
-                    @click="() => (isSaveAndContinue = false)"
-                />
             </div>
         </template>
     </FormModel>
diff --git a/test/cypress/integration/entry/entrylist.spec.js b/test/cypress/integration/entry/entryList.spec.js
similarity index 98%
rename from test/cypress/integration/entry/entrylist.spec.js
rename to test/cypress/integration/entry/entryList.spec.js
index 2eb9a7013..5e2fa0c01 100644
--- a/test/cypress/integration/entry/entrylist.spec.js
+++ b/test/cypress/integration/entry/entryList.spec.js
@@ -124,12 +124,12 @@ describe('Entry', () => {
 
         clickAndType('stickers', '1');
         checkText('quantity', '11');
-        checkText('amount', '550');
+        checkText('amount', '550.00');
         clickAndType('packing', '2');
         checkText('packing', '12close');
-        checkText('weight', '12');
+        checkText('weight', '12.0');
         checkText('quantity', '132');
-        checkText('amount', '6600');
+        checkText('amount', '6600.00');
         checkColor('packing', COLORS.enabled);
 
         selectCell('groupingMode').click().click().click();
@@ -137,7 +137,7 @@ describe('Entry', () => {
         checkColor('grouping', COLORS.enabled);
 
         selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
-        checkText('amount', '132');
+        checkText('amount', '132.00');
         checkColor('minPrice', COLORS.disable);
 
         selectCell('hasMinPrice').click().click();
diff --git a/test/cypress/integration/route/routeList.spec.js b/test/cypress/integration/route/routeList.spec.js
index 421bdbcc8..976ce7352 100644
--- a/test/cypress/integration/route/routeList.spec.js
+++ b/test/cypress/integration/route/routeList.spec.js
@@ -4,9 +4,6 @@ describe('Route', () => {
         cy.login('developer');
         cy.visit(`/#/route/extended-list`);
     });
-    const getVnSelect =
-        '> :nth-child(1) > .column > .q-field > .q-field__inner > .q-field__control > .q-field__control-container';
-    const getRowColumn = (row, column) => `:nth-child(${row}) > :nth-child(${column})`;
 
     it('Route list create route', () => {
         cy.addBtnClick();
@@ -16,18 +13,25 @@ describe('Route', () => {
     });
 
     it('Route list search and edit', () => {
-        cy.get('#searchbar input').type('{enter}'); /* 
-        cy.get('td[data-col-field="description"]').click(); */
-        cy.get('input[name="description"]').type('routeTestOne{enter}');
-        /*  cy.get('.q-table tr')
+        cy.get('#searchbar input').type('{enter}');
+        cy.get('[data-col-field="description"][data-row-index="0"]')
+            .click()
+            .type('routeTestOne{enter}');
+        cy.get('.q-table tr')
             .its('length')
             .then((rowCount) => {
                 expect(rowCount).to.be.greaterThan(0);
             });
-        cy.get(getRowColumn(1, 3) + getVnSelect).type('{downArrow}{enter}');
-        cy.get(getRowColumn(1, 4) + getVnSelect).type('{downArrow}{enter}');
-        cy.get(getRowColumn(1, 5) + getVnSelect).type('{downArrow}{enter}');
+        cy.get('[data-col-field="workerFk"][data-row-index="0"]')
+            .click()
+            .type('{downArrow}{enter}');
+        cy.get('[data-col-field="agencyModeFk"][data-row-index="0"]')
+            .click()
+            .type('{downArrow}{enter}');
+        cy.get('[data-col-field="vehicleFk"][data-row-index="0"]')
+            .click()
+            .type('{downArrow}{enter}');
         cy.get('button[title="Save"]').click();
-        cy.get('.q-notification__message').should('have.text', 'Data saved'); */
+        cy.get('.q-notification__message').should('have.text', 'Data saved');
     });
 });
-- 
2.40.1