285 lines
7.8 KiB
Vue
285 lines
7.8 KiB
Vue
<script setup>
|
|
import { ref, computed, watch, reactive } from 'vue';
|
|
import axios from 'axios';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRoute } from 'vue-router';
|
|
|
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
|
import { dashIfEmpty } from 'src/filters';
|
|
import { toDateFormat } from 'src/filters/date.js';
|
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
|
import VnInput from 'src/components/common/VnInput.vue';
|
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
import FetchData from 'src/components/FetchData.vue';
|
|
import { useVnConfirm } from 'composables/useVnConfirm';
|
|
import useNotify from 'src/composables/useNotify.js';
|
|
import { onMounted } from 'vue';
|
|
import { useStateStore } from 'src/stores/useStateStore';
|
|
|
|
const route = useRoute();
|
|
const stateStore = useStateStore();
|
|
const { t } = useI18n();
|
|
const tableRef = ref();
|
|
const attendersOptions = ref([]);
|
|
const { openConfirmationModal } = useVnConfirm();
|
|
const { notify } = useNotify();
|
|
|
|
watch(
|
|
() => route.params.id,
|
|
async (val) => {
|
|
crudModelFilter.where.ticketFk = val;
|
|
tableRef.value.reload();
|
|
}
|
|
);
|
|
|
|
const crudModelFilter = reactive({
|
|
include: [
|
|
{
|
|
relation: 'atender',
|
|
scope: {
|
|
include: {
|
|
relation: 'user',
|
|
scope: {
|
|
fields: ['nickname'],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
relation: 'requester',
|
|
scope: {
|
|
include: {
|
|
relation: 'user',
|
|
scope: {
|
|
fields: ['nickname'],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
relation: 'sale',
|
|
},
|
|
],
|
|
fields: [
|
|
'id',
|
|
'description',
|
|
'created',
|
|
'requesterFk',
|
|
'attenderFk',
|
|
'quantity',
|
|
'price',
|
|
'saleFk',
|
|
'isOk',
|
|
],
|
|
order: ['created ASC'],
|
|
where: {
|
|
ticketFk: route.params.id,
|
|
},
|
|
});
|
|
|
|
const columns = computed(() => [
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.id'),
|
|
name: 'id',
|
|
chip: {
|
|
condition: () => true,
|
|
},
|
|
isId: true,
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.description'),
|
|
name: 'description',
|
|
columnClass: 'expand',
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.created'),
|
|
name: 'created',
|
|
format: (row) => toDateFormat(row.created),
|
|
cardVisible: true,
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.requester'),
|
|
name: 'requesterFk',
|
|
cardVisible: true,
|
|
format: (row) => dashIfEmpty(row.requester?.user?.nickname),
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.atender'),
|
|
name: 'attenderFk',
|
|
cardVisible: true,
|
|
format: (row) => dashIfEmpty(row.atender?.user?.nickname),
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.quantity'),
|
|
name: 'quantity',
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.price'),
|
|
name: 'price',
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.saleFk'),
|
|
name: 'saleFk',
|
|
cardVisible: true,
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('purchaseRequest.state'),
|
|
name: 'isOk',
|
|
cardVisible: true,
|
|
},
|
|
{
|
|
align: 'right',
|
|
name: 'tableActions',
|
|
actions: [
|
|
{
|
|
title: t('globals.delete'),
|
|
icon: 'delete',
|
|
isPrimary: true,
|
|
action: (row) =>
|
|
openConfirmationModal(
|
|
t('You are going to delete this ticket purchase request'),
|
|
t(
|
|
'This ticket will be removed from ticket purchase requests! Continue anyway?'
|
|
),
|
|
() => removeLine(row.id)
|
|
),
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const getRequestState = (state) => {
|
|
switch (state) {
|
|
case null:
|
|
return 'New';
|
|
case false:
|
|
return 'Denied';
|
|
case true:
|
|
return 'Accepted';
|
|
}
|
|
};
|
|
|
|
const isEditable = (isOk) => isOk !== null;
|
|
|
|
async function removeLine(id) {
|
|
try {
|
|
await axios.delete(`TicketRequests/${id}`);
|
|
notify(t('globals.dataSaved'), 'positive');
|
|
location.reload();
|
|
} catch (err) {
|
|
console.error('Error ', err);
|
|
}
|
|
}
|
|
|
|
onMounted(() => (stateStore.rightDrawer = false));
|
|
</script>
|
|
|
|
<template>
|
|
<FetchData
|
|
url="TicketRequests/getItemTypeWorker"
|
|
:filter="{ fields: ['id', 'nickname'], order: 'nickname ASC' }"
|
|
auto-load
|
|
@on-fetch="(data) => (attendersOptions = data)"
|
|
/>
|
|
<VnTable
|
|
ref="tableRef"
|
|
data-key="PurchaseRequests"
|
|
url="TicketRequests"
|
|
:create="{
|
|
urlCreate: 'TicketRequests',
|
|
title: t('Create request'),
|
|
onDataSaved: ({ id }) => tableRef.reload(id),
|
|
formInitialData: {
|
|
ticketFk: route.params.id,
|
|
},
|
|
}"
|
|
save-url="TicketRequests/crud"
|
|
:filter="crudModelFilter"
|
|
:columns="columns"
|
|
:is-editable="true"
|
|
:right-search="false"
|
|
:column-search="false"
|
|
auto-load
|
|
>
|
|
<template #column-description="{ row }">
|
|
<VnInput v-model="row.description" :disable="isEditable(row.isOk)" />
|
|
</template>
|
|
<template #column-requesterFk="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ row.requester?.user?.nickname }}
|
|
<WorkerDescriptorProxy :id="row.requesterFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-attenderFk="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ row.atender?.user?.nickname }}
|
|
<WorkerDescriptorProxy :id="row.attenderFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-quantity="{ row }">
|
|
<VnInput v-model="row.quantity" :disable="isEditable(row.isOk)" />
|
|
</template>
|
|
<template #column-price="{ row }">
|
|
<span @click.stop>
|
|
<VnInput v-model="row.price" :disable="isEditable(row.isOk)">
|
|
{{ row.price }}
|
|
</VnInput>
|
|
</span>
|
|
</template>
|
|
<template #column-saleFk="{ row }">
|
|
<QTd style="width: 3%">
|
|
<span class="link" @click.stop>
|
|
{{ dashIfEmpty(row.sale?.itemFk) }}
|
|
<ItemDescriptorProxy :id="row.sale?.itemFk" /> </span
|
|
></QTd>
|
|
</template>
|
|
<template #column-isOk="{ row }">
|
|
{{ t(getRequestState(row.isOk)) }}
|
|
</template>
|
|
|
|
<template #more-create-dialog="{ data }">
|
|
<VnInput
|
|
v-model="data.description"
|
|
:label="t('purchaseRequest.description')"
|
|
/>
|
|
<VnSelect
|
|
:label="t('purchaseRequest.atender')"
|
|
v-model="data.attenderFk"
|
|
:options="attendersOptions"
|
|
hide-selected
|
|
option-label="nickname"
|
|
option-value="id"
|
|
/>
|
|
<VnInput
|
|
v-model="data.quantity"
|
|
:label="t('purchaseRequest.quantity')"
|
|
type="number"
|
|
min="1"
|
|
/>
|
|
<VnInput
|
|
v-model="data.price"
|
|
:label="t('purchaseRequest.price')"
|
|
type="number"
|
|
min="0"
|
|
/>
|
|
</template>
|
|
</VnTable>
|
|
</template>
|
|
|
|
<i18n>
|
|
es:
|
|
New: Nueva
|
|
Denied: Denegada
|
|
Accepted: Aceptada
|
|
</i18n>
|