From 46cb18b5ef688f434ca16e06954bc6f7896b6a4d Mon Sep 17 00:00:00 2001 From: pablone <pablone@verdnatura.es> Date: Thu, 21 Nov 2024 10:19:30 +0100 Subject: [PATCH 1/2] feat: refs #7301 add exclude inventory supplier from list --- src/components/common/VnDateBadge.vue | 31 ++++ src/pages/Item/Card/ItemDescriptor.vue | 6 +- src/pages/Item/Card/ItemDescriptorImage.vue | 4 +- src/pages/Item/Card/ItemLastEntries.vue | 146 +++++++++++++----- src/pages/Item/Card/ItemSummary.vue | 2 +- src/pages/Item/locale/en.yml | 1 + src/pages/Item/locale/es.yml | 3 +- src/pages/Monitor/Ticket/MonitorTickets.vue | 33 +--- .../integration/item/itemLastEntries.spec.js | 20 +++ 9 files changed, 172 insertions(+), 74 deletions(-) create mode 100644 src/components/common/VnDateBadge.vue create mode 100644 test/cypress/integration/item/itemLastEntries.spec.js diff --git a/src/components/common/VnDateBadge.vue b/src/components/common/VnDateBadge.vue new file mode 100644 index 000000000..fd6c9e8a4 --- /dev/null +++ b/src/components/common/VnDateBadge.vue @@ -0,0 +1,31 @@ +<script setup> +import { toDateFormat } from 'src/filters/date.js'; + +defineProps({ date: { type: [Date, String], required: true } }); + +function getBadgeAttrs(date) { + 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' }; + if (timeDiff < 0) return { color: 'success', 'text-color': 'black' }; + return { color: 'transparent', 'text-color': 'white' }; +} + +function formatShippedDate(date) { + if (!date) return '-'; + const dateSplit = date.split('T'); + const [year, month, day] = dateSplit[0].split('-'); + const newDate = new Date(year, month - 1, day); + return toDateFormat(newDate); +} +</script> +<template> + <QBadge v-bind="getBadgeAttrs(date)" class="q-pa-sm" style="font-size: 14px"> + {{ formatShippedDate(date) }} + </QBadge> +</template> diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index c51b320b5..4705525fb 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -16,7 +16,7 @@ import { cloneItem } from 'src/pages/Item/composables/cloneItem'; const $props = defineProps({ id: { - type: Number, + type: [Number, String], required: false, default: null, }, @@ -29,7 +29,7 @@ const $props = defineProps({ default: null, }, saleFk: { - type: Number, + type: [Number, String], default: null, }, warehouseFk: { @@ -61,7 +61,7 @@ onMounted(async () => { const data = ref(useCardDescription()); const setData = async (entity) => { if (!entity) return; - data.value = useCardDescription(entity.name, entity.id); + data.value = useCardDescription(entity?.name, entity?.id); await updateStock(); }; diff --git a/src/pages/Item/Card/ItemDescriptorImage.vue b/src/pages/Item/Card/ItemDescriptorImage.vue index 735e5eb4f..972ba579c 100644 --- a/src/pages/Item/Card/ItemDescriptorImage.vue +++ b/src/pages/Item/Card/ItemDescriptorImage.vue @@ -16,7 +16,7 @@ const $props = defineProps({ default: null, }, entityId: { - type: String, + type: [String, Number], default: null, }, showEditButton: { @@ -67,7 +67,7 @@ const handlePhotoUpdated = (evt = false) => { <template> <div class="relative-position"> - <VnImg ref="image" :id="$props.entityId" zoom-resolution="1600x900"> + <VnImg ref="image" :id="Number($props.entityId)" zoom-resolution="1600x900"> <template #error> <div class="absolute-full picture text-center q-pa-md flex flex-center"> <div> diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue index 5c0251ea8..a7cc96921 100644 --- a/src/pages/Item/Card/ItemLastEntries.vue +++ b/src/pages/Item/Card/ItemLastEntries.vue @@ -5,17 +5,29 @@ import { useRoute } from 'vue-router'; import { dateRange } from 'src/filters'; import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue'; +import VnDateBadge from 'src/components/common/VnDateBadge.vue'; import { useStateStore } from 'stores/useStateStore'; -import { toDateTimeFormat } from 'src/filters/date.js'; import { dashIfEmpty } from 'src/filters'; import { toCurrency } from 'filters/index'; import { useArrayData } from 'composables/useArrayData'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; +import axios from 'axios'; +import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; const { t } = useI18n(); const route = useRoute(); const stateStore = useStateStore(); +const from = ref(); +const to = ref(); +const hideInventory = ref(true); +const inventorySupplierFk = ref(); + +async function getInventorySupplier() { + inventorySupplierFk.value = ( + await axios.get(`InventoryConfigs`) + )?.data[0]?.supplierFk; +} const exprBuilder = (param, value) => { switch (param) { @@ -36,25 +48,29 @@ const exprBuilder = (param, value) => { } }; -const from = ref(); -const to = ref(); +const where = { + itemFk: route.params.id, +}; + +if (hideInventory.value) { + console.log('entra'); + where.supplierFk = { neq: inventorySupplierFk }; + console.log('where: ', where.supplierFk); +} const arrayData = useArrayData('ItemLastEntries', { url: 'Items/lastEntriesFilter', order: ['landed DESC', 'buyFk DESC'], exprBuilder: exprBuilder, userFilter: { - where: { - itemFk: route.params.id, - }, + where: where, }, }); - const itemLastEntries = ref([]); const columns = computed(() => [ { - label: t('lastEntries.ig'), + label: 'Nv', name: 'ig', align: 'center', }, @@ -62,33 +78,38 @@ const columns = computed(() => [ label: t('itemDiary.warehouse'), name: 'warehouse', field: 'warehouse', - align: 'left', + align: 'center', }, { label: t('lastEntries.landed'), - name: 'id', + name: 'date', field: 'landed', - align: 'left', - format: (val) => toDateTimeFormat(val), + align: 'center', }, { label: t('lastEntries.entry'), name: 'entry', field: 'stateName', - align: 'left', + align: 'center', format: (val) => dashIfEmpty(val), }, { label: t('lastEntries.pvp'), name: 'pvp', field: 'reference', - align: 'left', + align: 'center', format: (_, row) => toCurrency(row.price2) + ' / ' + toCurrency(row.price3), }, - + { + label: t('lastEntries.printedStickers'), + name: 'printedStickers', + field: 'printedStickers', + align: 'center', + format: (val) => dashIfEmpty(val), + }, { label: t('lastEntries.label'), - name: 'label', + name: 'stickers', field: 'stickers', align: 'center', format: (val) => dashIfEmpty(val), @@ -96,11 +117,13 @@ const columns = computed(() => [ { label: t('shelvings.packing'), name: 'packing', + field: 'packing', align: 'center', }, { label: t('lastEntries.grouping'), name: 'grouping', + field: 'grouping', align: 'center', }, { @@ -111,18 +134,19 @@ const columns = computed(() => [ }, { label: t('lastEntries.quantity'), - name: 'stems', + name: 'quantity', field: 'quantity', align: 'center', }, { label: t('lastEntries.cost'), name: 'cost', - align: 'left', + field: 'cost', + align: 'center', }, { - label: t('lastEntries.kg'), - name: 'stems', + label: 'Kg', + name: 'weight', field: 'weight', align: 'center', }, @@ -134,9 +158,9 @@ const columns = computed(() => [ }, { label: t('lastEntries.supplier'), - name: 'stems', + name: 'supplier', field: 'supplier', - align: 'left', + align: 'center', }, ]); @@ -155,16 +179,26 @@ const getDate = (date, type) => { }; const updateFilter = async () => { + console.log('updateFilter: '); + let filter; if (!from.value && to.value) filter = { lte: to.value }; else if (from.value && !to.value) filter = { gte: from.value }; else if (from.value && to.value) filter = { between: [from.value, to.value] }; - arrayData.store.userFilter.where.landed = filter; + const userFilter = arrayData.store.userFilter.where; + + userFilter.landed = filter; + if (hideInventory.value) userFilter.supplierFk = { neq: inventorySupplierFk }; + else delete userFilter.supplierFk; + console.log('userFilter: ', userFilter); + await fetchItemLastEntries(); }; onMounted(async () => { + await getInventorySupplier(); + const _from = Date.vnNew(); _from.setDate(_from.getDate() - 75); from.value = getDate(_from, 'from'); @@ -174,7 +208,7 @@ onMounted(async () => { updateFilter(); - watch([from, to], ([nFrom, nTo], [oFrom, oTo]) => { + watch([from, to, hideInventory], ([nFrom, nTo], [oFrom, oTo]) => { if (nFrom && nFrom != oFrom) nFrom = getDate(new Date(nFrom), 'from'); if (nTo && nTo != oTo) nTo = getDate(new Date(nTo), 'to'); updateFilter(); @@ -183,7 +217,6 @@ onMounted(async () => { onUnmounted(() => (stateStore.rightDrawer = false)); </script> - <template> <VnSubToolbar> <template #st-data> @@ -192,27 +225,45 @@ onUnmounted(() => (stateStore.rightDrawer = false)); dense v-model="from" class="q-mr-lg" + data-cy="from" + /> + <VnInputDate + :label="t('lastEntries.to')" + v-model="to" + dense + class="q-mr-lg" + data-cy="to" + /> + <QCheckbox + :label="t('Hide inventory supplier')" + v-model="hideInventory" + dense + class="q-mr-lg" + data-cy="hideInventory" /> - <VnInputDate :label="t('lastEntries.to')" dense v-model="to" /> </template> </VnSubToolbar> <QPage class="column items-center q-pa-xd"> <QTable :rows="itemLastEntries" :columns="columns" - class="full-width q-mt-md" + class="table full-width q-mt-md" :no-data-label="t('globals.noResults')" > <template #body-cell-ig="{ row }"> - <QTd @click.stop> - <QCheckbox - v-model="row.isIgnored" - :disable="true" - :false-value="0" - :true-value="1" + <QTd class="text-center"> + <QIcon + :name="row.isIgnored ? 'check_box' : 'check_box_outline_blank'" + style="color: var(--vn-label-color)" + size="sm" /> </QTd> </template> + <template #body-cell-date="{ row }"> + <QTd class="text-center"> + <VnDateBadge :date="row.landed" /> + </QTd> + </template> <template #body-cell-entry="{ row }"> <QTd @click.stop> <div class="full-width flex justify-center"> @@ -234,8 +285,8 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </QTd> </template> <template #body-cell-pvp="{ value }"> - <QTd @click.stop - ><span> {{ value }}</span> + <QTd @click.stop class="text-center"> + <span> {{ value }}</span> <QTooltip> {{ t('lastEntries.grouping') }}/{{ t('lastEntries.packing') }} </QTooltip></QTd @@ -254,7 +305,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </QTd> </template> <template #body-cell-cost="{ row }"> - <QTd @click.stop> + <QTd @click.stop class="text-center"> <span> {{ toCurrency(row.cost, 'EUR', 3) }} <QTooltip> @@ -272,10 +323,25 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </span> </QTd> </template> + <template #body-cell-supplier="{ row }"> + <QTd @click.stop> + <div class="full-width flex justify-center"> + <SupplierDescriptorProxy + :id="row.supplierFk" + class="q-ma-none" + dense + /> + <span class="link">{{ row.supplier }}</span> + </div> + </QTd> + </template> </QTable> </QPage> </template> - +<i18n> + es: + Hide inventory supplier: Ocultar proveedor inventario +</i18n> <style lang="scss" scoped> .q-badge--rounded { border-radius: 50%; @@ -287,4 +353,10 @@ onUnmounted(() => (stateStore.rightDrawer = false)); padding: 0 11px; height: 28px; } +.th :first-child { + .td { + text-align: center; + background-color: red; + } +} </style> diff --git a/src/pages/Item/Card/ItemSummary.vue b/src/pages/Item/Card/ItemSummary.vue index db90ba06f..e47d6358a 100644 --- a/src/pages/Item/Card/ItemSummary.vue +++ b/src/pages/Item/Card/ItemSummary.vue @@ -46,7 +46,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`; <template #body="{ entity: { item, tags, visible, available, botanical } }"> <QCard class="vn-one photo"> <ItemDescriptorImage - :entity-id="entityId" + :entity-id="Number(entityId)" :visible="visible" :available="available" :show-edit-button="false" diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml index 78a1c3ff0..a56bf4d57 100644 --- a/src/pages/Item/locale/en.yml +++ b/src/pages/Item/locale/en.yml @@ -66,6 +66,7 @@ lastEntries: package: Package freight: Freight comission: Comission + printedStickers: Pri. itemTags: removeTag: Remove tag addTag: Add tag diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml index 5498f4458..f10441920 100644 --- a/src/pages/Item/locale/es.yml +++ b/src/pages/Item/locale/es.yml @@ -56,7 +56,7 @@ lastEntries: landed: F. Entrega entry: Entrada pvp: PVP - label: Etiquetas + label: Eti. grouping: Grouping quantity: Cantidad cost: Coste @@ -66,6 +66,7 @@ lastEntries: package: Embalaje freight: Porte comission: Comisión + printedStickers: Imp. itemTags: removeTag: Quitar etiqueta addTag: Añadir etiqueta diff --git a/src/pages/Monitor/Ticket/MonitorTickets.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue index e6bf242ac..aca511aa4 100644 --- a/src/pages/Monitor/Ticket/MonitorTickets.vue +++ b/src/pages/Monitor/Ticket/MonitorTickets.vue @@ -10,14 +10,14 @@ import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue'; import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue'; import VnTable from 'components/VnTable/VnTable.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; -import { toDateFormat } from 'src/filters/date.js'; import { toCurrency, dateRange, dashIfEmpty } from 'src/filters'; import RightMenu from 'src/components/common/RightMenu.vue'; import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue'; import MonitorTicketFilter from './MonitorTicketFilter.vue'; import TicketProblems from 'src/components/TicketProblems.vue'; +import VnDateBadge from 'src/components/common/VnDateBadge.vue'; -const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; // 2min in ms +const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; const { t } = useI18n(); const autoRefresh = ref(false); const tableRef = ref(null); @@ -253,19 +253,6 @@ const columns = computed(() => [ }, ]); -const getBadgeAttrs = (date) => { - 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' }; - if (timeDiff < 0) return { color: 'success', 'text-color': 'black' }; - return { color: 'transparent', 'text-color': 'white' }; -}; - let refreshTimer = null; const autoRefreshHandler = (value) => { @@ -282,14 +269,6 @@ const totalPriceColor = (ticket) => { if (total > 0 && total < 50) return 'warning'; }; -const formatShippedDate = (date) => { - if (!date) return '-'; - const dateSplit = date.split('T'); - const [year, month, day] = dateSplit[0].split('-'); - const newDate = new Date(year, month - 1, day); - return toDateFormat(newDate); -}; - const openTab = (id) => window.open(`#/ticket/${id}/sale`, '_blank', 'noopener, noreferrer'); </script> @@ -385,13 +364,7 @@ const openTab = (id) => </div> </template> <template #column-shippedDate="{ row }"> - <QBadge - v-bind="getBadgeAttrs(row.shippedDate)" - class="q-pa-sm" - style="font-size: 14px" - > - {{ formatShippedDate(row.shippedDate) }} - </QBadge> + <VnDateBadge :date="row.shippedDate" /> </template> <template #column-provinceFk="{ row }"> <span :title="row.province" v-text="row.province" /> diff --git a/test/cypress/integration/item/itemLastEntries.spec.js b/test/cypress/integration/item/itemLastEntries.spec.js new file mode 100644 index 000000000..c94cfa480 --- /dev/null +++ b/test/cypress/integration/item/itemLastEntries.spec.js @@ -0,0 +1,20 @@ +describe('ItemLastEntries', () => { + beforeEach(() => { + cy.viewport(1280, 720); + cy.login('buyer'); + cy.visit('/#/item/1/last-entries'); + cy.intercept('GET', /.*lastEntriesFilter/).as('item'); + cy.waitForElement('tbody'); + }); + + it('should filter by agency', () => { + cy.get('tbody > tr') + .its('length') + .then((rowCount) => { + cy.get('[data-cy="hideInventory"]').click(); + cy.wait('@item'); + cy.waitForElement('tbody'); + cy.get('tbody > tr').should('have.length.greaterThan', rowCount); + }); + }); +}); From 8bccb959ed8a26eec8f274696713b7a02680d3de Mon Sep 17 00:00:00 2001 From: pablone <pablone@verdnatura.es> Date: Thu, 12 Dec 2024 09:31:33 +0100 Subject: [PATCH 2/2] fix: refs #7301 unnecessary console logs from ItemLastEntries.vue --- src/pages/Item/Card/ItemLastEntries.vue | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue index 2d17248bb..533513ff7 100644 --- a/src/pages/Item/Card/ItemLastEntries.vue +++ b/src/pages/Item/Card/ItemLastEntries.vue @@ -50,9 +50,7 @@ const where = { }; if (hideInventory.value) { - console.log('entra'); where.supplierFk = { neq: inventorySupplierFk }; - console.log('where: ', where.supplierFk); } const arrayData = useArrayData('ItemLastEntries', { @@ -176,8 +174,6 @@ const getDate = (date, type) => { }; const updateFilter = async () => { - console.log('updateFilter: '); - let filter; if (!from.value && to.value) filter = { lte: to.value }; else if (from.value && !to.value) filter = { gte: from.value }; @@ -188,7 +184,6 @@ const updateFilter = async () => { userFilter.landed = filter; if (hideInventory.value) userFilter.supplierFk = { neq: inventorySupplierFk }; else delete userFilter.supplierFk; - console.log('userFilter: ', userFilter); await fetchItemLastEntries(); };