0
0
Fork 0
salix-front-mindshore-fork2/src/pages/Item/ItemRequest.vue

361 lines
11 KiB
Vue
Raw Normal View History

2024-04-11 21:04:11 +00:00
<script setup>
2024-04-16 14:47:15 +00:00
import { ref, computed, onMounted, onBeforeMount, watch } from 'vue';
2024-04-11 21:04:11 +00:00
import { useI18n } from 'vue-i18n';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
2024-04-12 11:07:33 +00:00
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
2024-04-11 21:04:11 +00:00
import VnInput from 'src/components/common/VnInput.vue';
2024-04-12 11:07:33 +00:00
import ItemRequestDenyForm from './ItemRequestDenyForm.vue';
2024-04-15 11:46:26 +00:00
import ItemRequestFilter from './ItemRequestFilter.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
2024-04-11 21:04:11 +00:00
2024-04-15 11:46:26 +00:00
import { useStateStore } from 'stores/useStateStore';
2024-04-16 14:47:15 +00:00
import { useArrayData } from 'composables/useArrayData';
2024-04-11 21:04:11 +00:00
import { toDateFormat } from 'src/filters/date';
import { toCurrency } from 'filters/index';
import useNotify from 'src/composables/useNotify.js';
2024-04-12 19:50:41 +00:00
import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
2024-04-11 21:04:11 +00:00
import axios from 'axios';
const { t } = useI18n();
const { notify } = useNotify();
2024-04-15 11:46:26 +00:00
const stateStore = useStateStore();
2024-04-11 21:04:11 +00:00
2024-04-15 11:46:26 +00:00
let filterParams = ref({});
2024-04-12 11:07:33 +00:00
const denyFormRef = ref(null);
const denyRequestId = ref(null);
2024-04-12 19:50:41 +00:00
const denyRequestIndex = ref(null);
2024-04-11 21:04:11 +00:00
const itemRequestsOptions = ref([]);
2024-04-16 14:47:15 +00:00
const arrayData = useArrayData('ItemRequests', {
url: 'TicketRequests/filter',
userParams: filterParams,
order: ['shippedDate ASC', 'isOk ASC'],
});
const store = arrayData.store;
watch(
() => store.data,
(value) => (itemRequestsOptions.value = value)
);
2024-04-11 21:04:11 +00:00
const columns = computed(() => [
{
label: t('item.buyRequest.ticketId'),
name: 'id',
field: 'id',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.shipped'),
field: 'shipped',
name: 'shipped',
align: 'left',
sortable: true,
},
{
label: t('globals.description'),
field: 'description',
name: 'description',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.requester'),
name: 'requester',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.requested'),
field: 'quantity',
name: 'requested',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.price'),
field: 'price',
name: 'price',
align: 'left',
sortable: true,
format: (val) => toCurrency(val),
},
{
label: t('item.buyRequest.attender'),
field: 'attender',
name: 'attender',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.item'),
field: 'item',
name: 'item',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.achieved'),
field: 'achieved',
name: 'achieved',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.concept'),
field: 'concept',
name: 'concept',
align: 'left',
sortable: true,
},
{
label: t('item.buyRequest.state'),
field: 'state',
name: 'state',
align: 'left',
sortable: true,
},
{
label: '',
name: 'action',
align: 'left',
columnFilter: null,
},
]);
const changeQuantity = async (request) => {
try {
if (request.saleFk) {
const params = {
quantity: request.saleQuantity,
};
await axios.patch(`Sales/${request.saleFk}`, params);
2024-04-16 14:47:15 +00:00
notify(t('globals.dataSaved'), 'positive');
2024-04-11 21:04:11 +00:00
confirmRequest(request);
} else confirmRequest(request);
} catch (error) {
2024-04-12 19:50:41 +00:00
console.error('Error changing quantity:: ', error);
2024-04-11 21:04:11 +00:00
}
};
const confirmRequest = async (request) => {
try {
if (request.itemFk && request.saleQuantity) {
const params = {
itemFk: request.itemFk,
quantity: request.saleQuantity,
};
const { data } = await axios.post(
`TicketRequests/${request.id}/confirm`,
params
);
request.itemDescription = data.concept;
request.isOk = true;
2024-04-16 14:47:15 +00:00
notify(t('globals.dataSaved'), 'positive');
2024-04-11 21:04:11 +00:00
}
} catch (error) {
2024-04-12 19:50:41 +00:00
console.error('Error confirming request:: ', error);
2024-04-11 21:04:11 +00:00
}
};
2024-04-12 11:07:33 +00:00
const getState = (isOk) => {
2024-04-18 12:19:15 +00:00
if (isOk === null) return t('Pending');
else if (isOk) return t('Accepted');
else return t('Denied');
2024-04-12 11:07:33 +00:00
};
2024-04-12 19:50:41 +00:00
const showDenyRequestForm = (requestId, rowIndex) => {
2024-04-12 11:07:33 +00:00
denyRequestId.value = requestId;
2024-04-12 19:50:41 +00:00
denyRequestIndex.value = rowIndex;
2024-04-12 11:07:33 +00:00
denyFormRef.value.show();
};
const onDenyAccept = (_, responseData) => {
2024-04-12 19:50:41 +00:00
itemRequestsOptions.value[denyRequestIndex.value].isOk = responseData.isOk;
itemRequestsOptions.value[denyRequestIndex.value].attenderFk =
responseData.attenderFk;
itemRequestsOptions.value[denyRequestIndex.value].response = responseData.response;
denyRequestId.value = null;
denyRequestIndex.value = null;
2024-04-12 11:07:33 +00:00
};
2024-04-15 11:46:26 +00:00
onMounted(async () => {
2024-04-16 14:47:15 +00:00
await arrayData.fetch({ append: false });
2024-04-15 11:46:26 +00:00
stateStore.rightDrawer = true;
});
onBeforeMount(() => {
const today = Date.vnNew();
today.setHours(0, 0, 0, 0);
const nextWeek = Date.vnNew();
nextWeek.setHours(23, 59, 59, 59);
nextWeek.setDate(nextWeek.getDate() + 7);
filterParams.value = {
from: today,
to: nextWeek,
state: 'pending',
};
});
2024-04-11 21:04:11 +00:00
</script>
<template>
2024-04-15 11:46:26 +00:00
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#searchbar">
<VnSearchbar
data-key="ItemRequests"
url="TicketRequests/filter"
:label="t('globals.search')"
:info="t('You can search by Id or alias')"
:redirect="false"
/>
</Teleport>
</template>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#actions-append">
<div class="row q-gutter-x-sm">
<QBtn
flat
@click="stateStore.toggleRightDrawer()"
round
dense
icon="menu"
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.collapseMenu') }}
</QTooltip>
</QBtn>
</div>
</Teleport>
</template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QScrollArea class="fit text-grey-8">
<ItemRequestFilter data-key="ItemRequests" />
</QScrollArea>
</QDrawer>
2024-04-11 21:04:11 +00:00
<QPage class="column items-center q-pa-md">
2024-04-16 14:47:15 +00:00
<QTable
:rows="itemRequestsOptions"
:columns="columns"
row-key="id"
:pagination="{ rowsPerPage: 0 }"
class="full-width q-mt-md"
:no-data-label="t('globals.noResults')"
2024-04-11 21:04:11 +00:00
>
2024-04-16 14:47:15 +00:00
<template #body-cell-id="{ row }">
<QTd>
<QBtn flat color="primary"> {{ row.ticketFk }}</QBtn>
<TicketDescriptorProxy :id="row.ticketFk" />
</QTd>
2024-04-11 21:04:11 +00:00
</template>
2024-04-15 11:46:26 +00:00
2024-04-16 14:47:15 +00:00
<template #body-cell-shipped="{ row }">
<QTd>
<QBadge
v-if="getDateQBadgeColor(row.shipped)"
:color="getDateQBadgeColor(row.shipped)"
text-color="black"
class="q-ma-none"
dense
style="font-size: 14px"
>
{{ toDateFormat(row.shipped) }}
</QBadge>
<span v-else>{{ toDateFormat(row.shipped) }}</span>
</QTd>
</template>
<template #body-cell-requester="{ row }">
<QTd>
<QBtn flat dense color="primary"> {{ row.requesterName }}</QBtn>
<WorkerDescriptorProxy :id="row.requesterFk" />
</QTd>
</template>
<template #body-cell-attender="{ row }">
<QTd>
<QBtn flat dense color="primary"> {{ row.attenderName }}</QBtn>
<WorkerDescriptorProxy :id="row.attenderFk" />
</QTd>
</template>
<template #body-cell-item="{ row }">
<QTd>
<VnInput
v-model.number="row.itemFk"
type="number"
:disable="row.isOk != null"
2024-04-16 14:49:59 +00:00
dense
2024-04-16 14:47:15 +00:00
/>
</QTd>
</template>
<template #body-cell-achieved="{ row }">
<QTd>
<VnInput
v-model.number="row.saleQuantity"
@change="changeQuantity(row)"
type="number"
:disable="!row.itemFk || row.isOk != null"
2024-04-16 14:49:59 +00:00
dense
2024-04-16 14:47:15 +00:00
/>
</QTd>
</template>
<template #body-cell-concept="{ row }">
<QTd>
<QBtn flat dense color="primary"> {{ row.itemDescription }}</QBtn>
<ItemDescriptorProxy :id="row.itemFk" />
</QTd>
</template>
<template #body-cell-state="{ row }">
<QTd>
<span>{{ getState(row.isOk) }}</span>
</QTd>
</template>
<template #body-cell-action="{ row, rowIndex }">
<QTd>
<QIcon
v-if="row.response?.length"
name="insert_drive_file"
color="primary"
size="sm"
>
<QTooltip>
{{ row.response }}
</QTooltip>
</QIcon>
<QIcon
v-if="row.isOk == null"
name="thumb_down"
color="primary"
size="sm"
2024-04-24 12:28:20 +00:00
class="fill-icon"
2024-04-16 14:47:15 +00:00
@click="showDenyRequestForm(row.id, rowIndex)"
>
<QTooltip>
{{ t('Discard') }}
</QTooltip>
</QIcon>
</QTd>
</template>
</QTable>
2024-04-12 11:07:33 +00:00
<QDialog ref="denyFormRef" transition-show="scale" transition-hide="scale">
<ItemRequestDenyForm
:request-id="denyRequestId"
@on-data-saved="onDenyAccept"
/>
</QDialog>
2024-04-11 21:04:11 +00:00
</QPage>
</template>
<i18n>
2024-04-12 11:07:33 +00:00
es:
Discard: Descartar
2024-04-15 11:46:26 +00:00
You can search by Id or alias: Buscar peticiones por identificador o alias
2024-04-18 12:19:15 +00:00
Denied: Denegada
Accepted: Aceptada
Pending: Pendiente
2024-04-11 21:04:11 +00:00
</i18n>