forked from verdnatura/salix-front
278 lines
8.8 KiB
Vue
278 lines
8.8 KiB
Vue
<script setup>
|
|
import { onMounted, computed, onUnmounted, reactive, ref } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRoute } from 'vue-router';
|
|
|
|
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
|
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
|
|
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
|
import FetchData from 'components/FetchData.vue';
|
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|
|
|
import { useStateStore } from 'stores/useStateStore';
|
|
import { toDateFormat } from 'src/filters/date.js';
|
|
import { dashIfEmpty } from 'src/filters';
|
|
import { date } from 'quasar';
|
|
import { useState } from 'src/composables/useState';
|
|
|
|
const { t } = useI18n();
|
|
const route = useRoute();
|
|
const stateStore = useStateStore();
|
|
const state = useState();
|
|
|
|
const user = state.getUser();
|
|
const today = ref(Date.vnNew());
|
|
const warehousesOptions = ref([]);
|
|
const itemBalancesRef = ref(null);
|
|
const itemsBalanceFilter = reactive({
|
|
where: { itemFk: route.params.id, warehouseFk: null, date: null },
|
|
});
|
|
const itemBalances = ref([]);
|
|
const warehouseFk = ref(null);
|
|
const _showWhatsBeforeInventory = ref(false);
|
|
|
|
const columns = computed(() => [
|
|
{
|
|
name: 'claim',
|
|
align: 'left',
|
|
field: 'itemFk',
|
|
},
|
|
{
|
|
label: t('itemDiary.date'),
|
|
name: 'date',
|
|
field: 'shipped',
|
|
align: 'left',
|
|
},
|
|
{
|
|
label: t('itemDiary.id'),
|
|
name: 'id',
|
|
align: 'left',
|
|
},
|
|
{
|
|
label: t('itemDiary.state'),
|
|
field: 'stateName',
|
|
name: 'state',
|
|
align: 'left',
|
|
format: (val) => dashIfEmpty(val),
|
|
},
|
|
{
|
|
label: t('itemDiary.reference'),
|
|
field: 'reference',
|
|
name: 'reference',
|
|
align: 'left',
|
|
format: (val) => dashIfEmpty(val),
|
|
},
|
|
|
|
{
|
|
label: t('itemDiary.client'),
|
|
name: 'client',
|
|
align: 'left',
|
|
format: (val) => dashIfEmpty(val),
|
|
},
|
|
{
|
|
label: t('itemDiary.in'),
|
|
field: 'invalue',
|
|
name: 'in',
|
|
align: 'left',
|
|
format: (val) => dashIfEmpty(val),
|
|
},
|
|
{
|
|
label: t('itemDiary.out'),
|
|
field: 'out',
|
|
name: 'out',
|
|
align: 'left',
|
|
format: (val) => dashIfEmpty(val),
|
|
},
|
|
{
|
|
label: t('itemDiary.balance'),
|
|
name: 'balance',
|
|
align: 'left',
|
|
},
|
|
]);
|
|
|
|
const showWhatsBeforeInventory = computed({
|
|
get: () => _showWhatsBeforeInventory.value,
|
|
set: (val) => {
|
|
_showWhatsBeforeInventory.value = val;
|
|
if (!val) itemsBalanceFilter.where.date = null;
|
|
else itemsBalanceFilter.where.date = new Date();
|
|
},
|
|
});
|
|
|
|
const fetchItemBalances = async () => await itemBalancesRef.value.fetch();
|
|
|
|
const getBadgeAttrs = (_date) => {
|
|
const isSameDate = date.isSameDate(today.value, _date);
|
|
const attrs = {
|
|
'text-color': isSameDate ? 'black' : 'white',
|
|
color: isSameDate ? 'warning' : 'transparent',
|
|
};
|
|
return attrs;
|
|
};
|
|
|
|
const getIdDescriptor = (row) => {
|
|
let descriptor = EntryDescriptorProxy;
|
|
if (row.isTicket) descriptor = TicketDescriptorProxy;
|
|
return descriptor;
|
|
};
|
|
|
|
onMounted(async () => {
|
|
today.value.setHours(0, 0, 0, 0);
|
|
if (route.query.warehouseFk) warehouseFk.value = route.query.warehouseFk;
|
|
else if (user.value) warehouseFk.value = user.value.warehouseFk;
|
|
itemsBalanceFilter.where.warehouseFk = warehouseFk.value;
|
|
await fetchItemBalances();
|
|
});
|
|
|
|
onUnmounted(() => (stateStore.rightDrawer = false));
|
|
</script>
|
|
|
|
<template>
|
|
<FetchData
|
|
ref="itemBalancesRef"
|
|
url="Items/getBalance"
|
|
:filter="itemsBalanceFilter"
|
|
@on-fetch="(data) => (itemBalances = data)"
|
|
/>
|
|
<FetchData
|
|
url="Warehouses"
|
|
:filter="{ fields: ['id', 'name'], order: 'name ASC' }"
|
|
auto-load
|
|
@on-fetch="(data) => (warehousesOptions = data)"
|
|
/>
|
|
<QToolbar class="justify-end">
|
|
<div id="st-data" class="row">
|
|
<VnSelect
|
|
:label="t('itemDiary.warehouse')"
|
|
:options="warehousesOptions"
|
|
hide-selected
|
|
option-label="name"
|
|
option-value="id"
|
|
dense
|
|
v-model="itemsBalanceFilter.where.warehouseFk"
|
|
@update:model-value="fetchItemBalances"
|
|
class="q-mr-lg"
|
|
/>
|
|
<QCheckbox
|
|
:label="t('itemDiary.showBefore')"
|
|
v-model="showWhatsBeforeInventory"
|
|
@update:model-value="fetchItemBalances"
|
|
class="q-mr-lg"
|
|
/>
|
|
<VnInputDate
|
|
v-if="showWhatsBeforeInventory"
|
|
:label="t('itemDiary.since')"
|
|
dense
|
|
v-model="itemsBalanceFilter.where.date"
|
|
@update:model-value="fetchItemBalances"
|
|
/>
|
|
</div>
|
|
<QSpace />
|
|
<div id="st-actions"></div>
|
|
</QToolbar>
|
|
<QPage class="column items-center q-pa-md">
|
|
<QTable
|
|
:rows="itemBalances"
|
|
:columns="columns"
|
|
class="full-width q-mt-md"
|
|
:no-data-label="t('globals.noResults')"
|
|
>
|
|
<template #body-cell-claim="{ row }">
|
|
<QTd @click.stop>
|
|
<QBtn
|
|
v-show="row.claimFk"
|
|
flat
|
|
color="primary"
|
|
:to="{ name: 'ClaimSummary', params: { id: row.claimFk } }"
|
|
icon="vn:claims"
|
|
dense
|
|
>
|
|
<QTooltip>
|
|
{{ t('itemDiary.claim') }}: {{ row.claimFk }}
|
|
</QTooltip>
|
|
</QBtn>
|
|
</QTd>
|
|
</template>
|
|
<template #body-cell-date="{ row }">
|
|
<QTd @click.stop>
|
|
<QBadge
|
|
v-bind="getBadgeAttrs(row.shipped)"
|
|
class="q-ma-none"
|
|
dense
|
|
style="font-size: 14px"
|
|
>
|
|
{{ toDateFormat(row.shipped) }}
|
|
</QBadge>
|
|
</QTd>
|
|
</template>
|
|
<template #body-cell-id="{ row }">
|
|
<QTd @click.stop>
|
|
<component
|
|
:is="getIdDescriptor(row)"
|
|
:id="row.origin"
|
|
class="q-ma-none"
|
|
dense
|
|
style="font-size: 14px"
|
|
>
|
|
{{ row.origin }}
|
|
</component>
|
|
<span class="link">{{ row.origin }}</span>
|
|
</QTd>
|
|
</template>
|
|
<template #body-cell-client="{ row }">
|
|
<QTd @click.stop>
|
|
<QBadge
|
|
:color="row.highlighted ? 'warning' : 'transparent'"
|
|
:text-color="row.highlighted ? 'black' : 'white'"
|
|
dense
|
|
style="font-size: 14px"
|
|
>
|
|
<span v-if="row.isTicket" class="link">
|
|
{{ dashIfEmpty(row.name) }}
|
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
|
</span>
|
|
<span v-else>{{ dashIfEmpty(row.name) }}</span>
|
|
</QBadge>
|
|
</QTd>
|
|
</template>
|
|
<template #body-cell-in="{ row }">
|
|
<QTd @click.stop>
|
|
<span :class="{ 'is-in': row.invalue }">
|
|
{{ dashIfEmpty(row.invalue) }}
|
|
</span>
|
|
</QTd>
|
|
</template>
|
|
<template #body-cell-balance="{ row }">
|
|
<QTd @click.stop>
|
|
<QBadge
|
|
class="balance-negative"
|
|
:color="
|
|
row.lineFk == row.lastPreparedLineFk
|
|
? 'grey-13'
|
|
: 'transparent'
|
|
"
|
|
:text-color="
|
|
row.lineFk == row.lastPreparedLineFk
|
|
? 'black'
|
|
: row.balance < 0
|
|
? 'negative'
|
|
: ''
|
|
"
|
|
dense
|
|
style="font-size: 14px"
|
|
>
|
|
<span>{{ dashIfEmpty(row.balance) }}</span>
|
|
</QBadge>
|
|
</QTd>
|
|
</template>
|
|
</QTable>
|
|
</QPage>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.is-in {
|
|
color: $positive;
|
|
}
|
|
</style>
|