feat: refs #7301 add exclude inventory supplier from list #982

Open
pablone wants to merge 3 commits from 7301-itemLastEntries into dev
9 changed files with 172 additions and 74 deletions

View File

@ -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>

View File

@ -16,7 +16,7 @@ import { cloneItem } from 'src/pages/Item/composables/cloneItem';
const $props = defineProps({ const $props = defineProps({
id: { id: {
type: Number, type: [Number, String],
required: false, required: false,
default: null, default: null,
}, },
@ -29,7 +29,7 @@ const $props = defineProps({
default: null, default: null,
}, },
saleFk: { saleFk: {
type: Number, type: [Number, String],
default: null, default: null,
}, },
warehouseFk: { warehouseFk: {
@ -61,7 +61,7 @@ onMounted(async () => {
const data = ref(useCardDescription()); const data = ref(useCardDescription());
const setData = async (entity) => { const setData = async (entity) => {
if (!entity) return; if (!entity) return;
data.value = useCardDescription(entity.name, entity.id); data.value = useCardDescription(entity?.name, entity?.id);
await updateStock(); await updateStock();
}; };

View File

@ -16,7 +16,7 @@ const $props = defineProps({
default: null, default: null,
}, },
entityId: { entityId: {
type: String, type: [String, Number],
default: null, default: null,
}, },
showEditButton: { showEditButton: {
@ -67,7 +67,7 @@ const handlePhotoUpdated = (evt = false) => {
<template> <template>
<div class="relative-position"> <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> <template #error>
<div class="absolute-full picture text-center q-pa-md flex flex-center"> <div class="absolute-full picture text-center q-pa-md flex flex-center">
<div> <div>

View File

@ -5,17 +5,29 @@ import { useRoute } from 'vue-router';
import { dateRange } from 'src/filters'; import { dateRange } from 'src/filters';
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue'; import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnDateBadge from 'src/components/common/VnDateBadge.vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { toDateTimeFormat } from 'src/filters/date.js';
import { dashIfEmpty } from 'src/filters'; import { dashIfEmpty } from 'src/filters';
import { toCurrency } from 'filters/index'; import { toCurrency } from 'filters/index';
import { useArrayData } from 'composables/useArrayData'; import { useArrayData } from 'composables/useArrayData';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; 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 { t } = useI18n();
const route = useRoute(); const route = useRoute();
const stateStore = useStateStore(); 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) => { const exprBuilder = (param, value) => {
switch (param) { switch (param) {
@ -36,25 +48,29 @@ const exprBuilder = (param, value) => {
} }
}; };
const from = ref(); const where = {
const to = ref(); itemFk: route.params.id,
};
if (hideInventory.value) {
console.log('entra');
Review

Quitar

Quitar
where.supplierFk = { neq: inventorySupplierFk };
console.log('where: ', where.supplierFk);
Review

Quitar

Quitar
}
const arrayData = useArrayData('ItemLastEntries', { const arrayData = useArrayData('ItemLastEntries', {
url: 'Items/lastEntriesFilter', url: 'Items/lastEntriesFilter',
order: ['landed DESC', 'buyFk DESC'], order: ['landed DESC', 'buyFk DESC'],
exprBuilder: exprBuilder, exprBuilder: exprBuilder,
userFilter: { userFilter: {
where: { where: where,
itemFk: route.params.id,
},
}, },
}); });
const itemLastEntries = ref([]); const itemLastEntries = ref([]);
const columns = computed(() => [ const columns = computed(() => [
{ {
label: t('lastEntries.ig'), label: 'Nv',
Review

uy

uy
name: 'ig', name: 'ig',
align: 'center', align: 'center',
}, },
@ -62,33 +78,38 @@ const columns = computed(() => [
label: t('itemDiary.warehouse'), label: t('itemDiary.warehouse'),
name: 'warehouse', name: 'warehouse',
field: 'warehouse', field: 'warehouse',
align: 'left', align: 'center',
}, },
{ {
label: t('lastEntries.landed'), label: t('lastEntries.landed'),
name: 'id', name: 'date',
field: 'landed', field: 'landed',
align: 'left', align: 'center',
format: (val) => toDateTimeFormat(val),
}, },
{ {
label: t('lastEntries.entry'), label: t('lastEntries.entry'),
name: 'entry', name: 'entry',
field: 'stateName', field: 'stateName',
align: 'left', align: 'center',
format: (val) => dashIfEmpty(val), format: (val) => dashIfEmpty(val),
}, },
{ {
label: t('lastEntries.pvp'), label: t('lastEntries.pvp'),
name: 'pvp', name: 'pvp',
field: 'reference', field: 'reference',
align: 'left', align: 'center',
format: (_, row) => toCurrency(row.price2) + ' / ' + toCurrency(row.price3), 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'), label: t('lastEntries.label'),
name: 'label', name: 'stickers',
field: 'stickers', field: 'stickers',
align: 'center', align: 'center',
format: (val) => dashIfEmpty(val), format: (val) => dashIfEmpty(val),
@ -96,11 +117,13 @@ const columns = computed(() => [
{ {
label: t('shelvings.packing'), label: t('shelvings.packing'),
name: 'packing', name: 'packing',
field: 'packing',
align: 'center', align: 'center',
}, },
{ {
label: t('lastEntries.grouping'), label: t('lastEntries.grouping'),
name: 'grouping', name: 'grouping',
field: 'grouping',
align: 'center', align: 'center',
}, },
{ {
@ -111,18 +134,19 @@ const columns = computed(() => [
}, },
{ {
label: t('lastEntries.quantity'), label: t('lastEntries.quantity'),
name: 'stems', name: 'quantity',
field: 'quantity', field: 'quantity',
align: 'center', align: 'center',
}, },
{ {
label: t('lastEntries.cost'), label: t('lastEntries.cost'),
name: 'cost', name: 'cost',
align: 'left', field: 'cost',
align: 'center',
}, },
{ {
label: t('lastEntries.kg'), label: 'Kg',
name: 'stems', name: 'weight',
field: 'weight', field: 'weight',
align: 'center', align: 'center',
}, },
@ -134,9 +158,9 @@ const columns = computed(() => [
}, },
{ {
label: t('lastEntries.supplier'), label: t('lastEntries.supplier'),
name: 'stems', name: 'supplier',
field: 'supplier', field: 'supplier',
align: 'left', align: 'center',
}, },
]); ]);
@ -155,16 +179,26 @@ const getDate = (date, type) => {
}; };
const updateFilter = async () => { const updateFilter = async () => {
console.log('updateFilter: ');
let filter; let filter;
if (!from.value && to.value) filter = { lte: to.value }; 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 = { gte: from.value };
else if (from.value && to.value) filter = { between: [from.value, to.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(); await fetchItemLastEntries();
}; };
onMounted(async () => { onMounted(async () => {
await getInventorySupplier();
const _from = Date.vnNew(); const _from = Date.vnNew();
_from.setDate(_from.getDate() - 75); _from.setDate(_from.getDate() - 75);
from.value = getDate(_from, 'from'); from.value = getDate(_from, 'from');
@ -174,7 +208,7 @@ onMounted(async () => {
updateFilter(); 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 (nFrom && nFrom != oFrom) nFrom = getDate(new Date(nFrom), 'from');
if (nTo && nTo != oTo) nTo = getDate(new Date(nTo), 'to'); if (nTo && nTo != oTo) nTo = getDate(new Date(nTo), 'to');
updateFilter(); updateFilter();
@ -183,7 +217,6 @@ onMounted(async () => {
onUnmounted(() => (stateStore.rightDrawer = false)); onUnmounted(() => (stateStore.rightDrawer = false));
</script> </script>
<template> <template>
<VnSubToolbar> <VnSubToolbar>
<template #st-data> <template #st-data>
@ -192,27 +225,45 @@ onUnmounted(() => (stateStore.rightDrawer = false));
dense dense
v-model="from" v-model="from"
class="q-mr-lg" 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> </template>
</VnSubToolbar> </VnSubToolbar>
<QPage class="column items-center q-pa-xd"> <QPage class="column items-center q-pa-xd">
<QTable <QTable
:rows="itemLastEntries" :rows="itemLastEntries"
:columns="columns" :columns="columns"
class="full-width q-mt-md" class="table full-width q-mt-md"
:no-data-label="t('globals.noResults')" :no-data-label="t('globals.noResults')"
> >
<template #body-cell-ig="{ row }"> <template #body-cell-ig="{ row }">
<QTd @click.stop> <QTd class="text-center">
<QCheckbox <QIcon
v-model="row.isIgnored" :name="row.isIgnored ? 'check_box' : 'check_box_outline_blank'"
:disable="true" style="color: var(--vn-label-color)"
:false-value="0" size="sm"
:true-value="1"
/> />
</QTd> </QTd>
</template> </template>
<template #body-cell-date="{ row }">
<QTd class="text-center">
<VnDateBadge :date="row.landed" />
</QTd>
</template>
<template #body-cell-entry="{ row }"> <template #body-cell-entry="{ row }">
<QTd @click.stop> <QTd @click.stop>
<div class="full-width flex justify-center"> <div class="full-width flex justify-center">
@ -234,8 +285,8 @@ onUnmounted(() => (stateStore.rightDrawer = false));
</QTd> </QTd>
</template> </template>
<template #body-cell-pvp="{ value }"> <template #body-cell-pvp="{ value }">
<QTd @click.stop <QTd @click.stop class="text-center">
><span> {{ value }}</span> <span> {{ value }}</span>
<QTooltip> <QTooltip>
{{ t('lastEntries.grouping') }}/{{ t('lastEntries.packing') }} {{ t('lastEntries.grouping') }}/{{ t('lastEntries.packing') }}
</QTooltip></QTd </QTooltip></QTd
@ -254,7 +305,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
</QTd> </QTd>
</template> </template>
<template #body-cell-cost="{ row }"> <template #body-cell-cost="{ row }">
<QTd @click.stop> <QTd @click.stop class="text-center">
<span> <span>
{{ toCurrency(row.cost, 'EUR', 3) }} {{ toCurrency(row.cost, 'EUR', 3) }}
<QTooltip> <QTooltip>
@ -272,10 +323,25 @@ onUnmounted(() => (stateStore.rightDrawer = false));
</span> </span>
</QTd> </QTd>
</template> </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> </QTable>
</QPage> </QPage>
</template> </template>
<i18n>
es:
Hide inventory supplier: Ocultar proveedor inventario
</i18n>
<style lang="scss" scoped> <style lang="scss" scoped>
.q-badge--rounded { .q-badge--rounded {
border-radius: 50%; border-radius: 50%;
@ -287,4 +353,10 @@ onUnmounted(() => (stateStore.rightDrawer = false));
padding: 0 11px; padding: 0 11px;
height: 28px; height: 28px;
} }
.th :first-child {
.td {
text-align: center;
background-color: red;
}
}
</style> </style>

View File

@ -46,7 +46,7 @@ const getUrl = (id, param) => `#/Item/${id}/${param}`;
<template #body="{ entity: { item, tags, visible, available, botanical } }"> <template #body="{ entity: { item, tags, visible, available, botanical } }">
<QCard class="vn-one photo"> <QCard class="vn-one photo">
<ItemDescriptorImage <ItemDescriptorImage
:entity-id="entityId" :entity-id="Number(entityId)"
:visible="visible" :visible="visible"
:available="available" :available="available"
:show-edit-button="false" :show-edit-button="false"

View File

@ -66,6 +66,7 @@ lastEntries:
package: Package package: Package
freight: Freight freight: Freight
comission: Comission comission: Comission
printedStickers: Pri.
itemTags: itemTags:
removeTag: Remove tag removeTag: Remove tag
addTag: Add tag addTag: Add tag

View File

@ -56,7 +56,7 @@ lastEntries:
landed: F. Entrega landed: F. Entrega
entry: Entrada entry: Entrada
pvp: PVP pvp: PVP
label: Etiquetas label: Eti.
grouping: Grouping grouping: Grouping
quantity: Cantidad quantity: Cantidad
cost: Coste cost: Coste
@ -66,6 +66,7 @@ lastEntries:
package: Embalaje package: Embalaje
freight: Porte freight: Porte
comission: Comisión comission: Comisión
printedStickers: Imp.
itemTags: itemTags:
removeTag: Quitar etiqueta removeTag: Quitar etiqueta
addTag: Añadir etiqueta addTag: Añadir etiqueta

View File

@ -10,14 +10,14 @@ import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue'; import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue';
import VnTable from 'components/VnTable/VnTable.vue'; import VnTable from 'components/VnTable/VnTable.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { toDateFormat } from 'src/filters/date.js';
import { toCurrency, dateRange, dashIfEmpty } from 'src/filters'; import { toCurrency, dateRange, dashIfEmpty } from 'src/filters';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue'; import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue';
import MonitorTicketFilter from './MonitorTicketFilter.vue'; import MonitorTicketFilter from './MonitorTicketFilter.vue';
import TicketProblems from 'src/components/TicketProblems.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 { t } = useI18n();
const autoRefresh = ref(false); const autoRefresh = ref(false);
const tableRef = ref(null); 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; let refreshTimer = null;
const autoRefreshHandler = (value) => { const autoRefreshHandler = (value) => {
@ -282,14 +269,6 @@ const totalPriceColor = (ticket) => {
if (total > 0 && total < 50) return 'warning'; 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) => const openTab = (id) =>
window.open(`#/ticket/${id}/sale`, '_blank', 'noopener, noreferrer'); window.open(`#/ticket/${id}/sale`, '_blank', 'noopener, noreferrer');
</script> </script>
@ -385,13 +364,7 @@ const openTab = (id) =>
</div> </div>
</template> </template>
<template #column-shippedDate="{ row }"> <template #column-shippedDate="{ row }">
<QBadge <VnDateBadge :date="row.shippedDate" />
v-bind="getBadgeAttrs(row.shippedDate)"
class="q-pa-sm"
style="font-size: 14px"
>
{{ formatShippedDate(row.shippedDate) }}
</QBadge>
</template> </template>
<template #column-provinceFk="{ row }"> <template #column-provinceFk="{ row }">
<span :title="row.province" v-text="row.province" /> <span :title="row.province" v-text="row.province" />

View File

@ -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);
});
});
});