forked from verdnatura/salix-front
Implement routes tickets dialog
This commit is contained in:
parent
ba9839bc4e
commit
c013c9054f
|
@ -0,0 +1,244 @@
|
||||||
|
<script setup>
|
||||||
|
import { useDialogPluginComponent, useQuasar } from 'quasar';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
|
import TicketDescriptorProxy from "pages/Ticket/Card/TicketDescriptorProxy.vue";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const $props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits([...useDialogPluginComponent.emits]);
|
||||||
|
|
||||||
|
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
||||||
|
|
||||||
|
const columns = computed(() => [
|
||||||
|
{
|
||||||
|
name: 'ticket',
|
||||||
|
label: t('Ticket'),
|
||||||
|
field: (row) => row.id,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'client',
|
||||||
|
label: t('Client'),
|
||||||
|
field: (row) => row.nickname,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'province',
|
||||||
|
label: t('Province'),
|
||||||
|
field: (row) => row?.address?.province?.name,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'population',
|
||||||
|
label: t('Population'),
|
||||||
|
field: (row) => row?.address?.city,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pc',
|
||||||
|
label: t('PC'),
|
||||||
|
field: (row) => row?.address?.postalCode,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'address',
|
||||||
|
label: t('Address'),
|
||||||
|
field: (row) => row?.address?.street,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'zone',
|
||||||
|
label: t('Zone'),
|
||||||
|
field: (row) => row?.zone?.name,
|
||||||
|
sortable: true,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'actions',
|
||||||
|
label: '',
|
||||||
|
sortable: false,
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const refreshKey = ref(0);
|
||||||
|
const selectedRows = ref([]);
|
||||||
|
const isLoading = ref(true);
|
||||||
|
const ticketList = ref([]);
|
||||||
|
|
||||||
|
const onDataFetched = (data) => {
|
||||||
|
ticketList.value = data;
|
||||||
|
isLoading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedTicket = ref(null);
|
||||||
|
const unlinkZone = async (ticket) => {
|
||||||
|
await axios.post('Routes/unlink', {
|
||||||
|
agencyModeId: ticket?.agencyModeFk,
|
||||||
|
zoneId: ticket.zoneFk,
|
||||||
|
});
|
||||||
|
selectedTicket.value = null;
|
||||||
|
refreshKey.value++;
|
||||||
|
};
|
||||||
|
|
||||||
|
const setTicketsRoute = async () => {
|
||||||
|
if (!selectedRows.value?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updates = selectedRows.value?.map((ticket) => ({
|
||||||
|
where: {
|
||||||
|
id: ticket.id,
|
||||||
|
data: {
|
||||||
|
routeFk: $props.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
await axios.post(`Tickets/crud`, { updates });
|
||||||
|
await axios.post(`Routes/${$props.id}/updateVolume`);
|
||||||
|
emit('ok');
|
||||||
|
emit('hide');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
:key="refreshKey"
|
||||||
|
:url="`Routes/${$props.id}/getSuggestedTickets`"
|
||||||
|
@on-fetch="onDataFetched"
|
||||||
|
auto-load
|
||||||
|
/>
|
||||||
|
<QDialog
|
||||||
|
:model-value="Boolean(selectedTicket)"
|
||||||
|
@update:model-value="(value) => (!value ? (selectedTicket = null) : null)"
|
||||||
|
class="confirmation-dialog"
|
||||||
|
>
|
||||||
|
<QCard style="min-width: 350px">
|
||||||
|
<QCardSection>
|
||||||
|
<p class="text-h6 q-ma-none">{{ t('Unlink selected zone?') }}</p>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardActions align="right">
|
||||||
|
<QBtn
|
||||||
|
flat
|
||||||
|
:label="t('globals.cancel')"
|
||||||
|
v-close-popup
|
||||||
|
class="text-primary"
|
||||||
|
/>
|
||||||
|
<QBtn color="primary" v-close-popup @click="unlinkZone(selectedTicket)">
|
||||||
|
{{ t('Unlink') }}
|
||||||
|
</QBtn>
|
||||||
|
</QCardActions>
|
||||||
|
</QCard>
|
||||||
|
</QDialog>
|
||||||
|
<QDialog ref="dialogRef" @hide="onDialogHide">
|
||||||
|
<QCard class="full-width dialog">
|
||||||
|
<QCardSection class="row items-center q-pb-none">
|
||||||
|
<div class="text-h6">{{ t('Tickets to add') }}</div>
|
||||||
|
<QSpace />
|
||||||
|
<QBtn icon="close" flat round dense v-close-popup />
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection>
|
||||||
|
<QTable
|
||||||
|
v-model:selected="selectedRows"
|
||||||
|
:columns="columns"
|
||||||
|
:loading="isLoading"
|
||||||
|
:rows="ticketList"
|
||||||
|
flat
|
||||||
|
row-key="id"
|
||||||
|
selection="multiple"
|
||||||
|
:rows-per-page-options="[0]"
|
||||||
|
hide-pagination
|
||||||
|
>
|
||||||
|
<template #body-cell-ticket="props">
|
||||||
|
<QTd :props="props">
|
||||||
|
<span class="link">
|
||||||
|
{{ props.value }}
|
||||||
|
<TicketDescriptorProxy :id="props?.row?.id" />
|
||||||
|
</span>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-client="props">
|
||||||
|
<QTd :props="props">
|
||||||
|
<span class="link">
|
||||||
|
{{ props.value }}
|
||||||
|
<CustomerDescriptorProxy :id="props?.row?.clientFk" />
|
||||||
|
</span>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-actions="props">
|
||||||
|
<QTd :props="props">
|
||||||
|
<QIcon
|
||||||
|
name="link_off"
|
||||||
|
size="xs"
|
||||||
|
color="primary"
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="selectedTicket = props?.row"
|
||||||
|
>
|
||||||
|
<QTooltip
|
||||||
|
>{{
|
||||||
|
t('Unlink zone', {
|
||||||
|
zone: props?.row?.zone?.name,
|
||||||
|
agency: props?.row?.agencyMode?.name,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
</QTable>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardActions align="right">
|
||||||
|
<QBtn flat v-close-popup class="text-primary"
|
||||||
|
>{{ t('globals.cancel') }}
|
||||||
|
</QBtn>
|
||||||
|
<QBtn
|
||||||
|
color="primary"
|
||||||
|
:disable="!selectedRows?.length"
|
||||||
|
@click="setTicketsRoute"
|
||||||
|
>{{ t('globals.add') }}
|
||||||
|
</QBtn>
|
||||||
|
</QCardActions>
|
||||||
|
</QCard>
|
||||||
|
</QDialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.confirmation-dialog {
|
||||||
|
z-index: 6001 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<i18n>
|
||||||
|
en:
|
||||||
|
Unlink zone: Unlink zone {zone} from agency {agency}
|
||||||
|
es:
|
||||||
|
Tickets to add: Tickets a añadir
|
||||||
|
Client: Cliente
|
||||||
|
Province: Provincia
|
||||||
|
Population: Población
|
||||||
|
PC: CP
|
||||||
|
Address: Dirección
|
||||||
|
Zone: Zona
|
||||||
|
Unlink zone: Desvincular zona {zone} de agencia {agency}
|
||||||
|
Unlink: Desvincular
|
||||||
|
</i18n>
|
|
@ -15,12 +15,15 @@ import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
|
||||||
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
|
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
|
||||||
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
|
import RouteSummary from 'pages/Route/Card/RouteSummary.vue';
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import {useSession} from "composables/useSession";
|
import { useSession } from 'composables/useSession';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
|
import RouteListTicketsDialog from 'pages/Route/Card/RouteListTicketsDialog.vue';
|
||||||
|
import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { validate } = useValidator();
|
const { validate } = useValidator();
|
||||||
|
const quasar = useQuasar();
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
|
|
||||||
|
@ -143,8 +146,8 @@ const cloneRoutes = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const showRouteReport = () => {
|
const showRouteReport = () => {
|
||||||
const ids = selectedRows.value.map(row => row?.id)
|
const ids = selectedRows.value.map((row) => row?.id);
|
||||||
const idString = ids.join(',')
|
const idString = ids.join(',');
|
||||||
let url;
|
let url;
|
||||||
|
|
||||||
if (selectedRows.value.length <= 1) {
|
if (selectedRows.value.length <= 1) {
|
||||||
|
@ -152,12 +155,12 @@ const showRouteReport = () => {
|
||||||
} else {
|
} else {
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
access_token: session.getToken(),
|
access_token: session.getToken(),
|
||||||
id: idString
|
id: idString,
|
||||||
})
|
});
|
||||||
url = `api/Routes/downloadZip?${params.toString()}`;
|
url = `api/Routes/downloadZip?${params.toString()}`;
|
||||||
}
|
}
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
}
|
};
|
||||||
|
|
||||||
const markAsServed = () => {
|
const markAsServed = () => {
|
||||||
selectedRows.value.forEach((row) => {
|
selectedRows.value.forEach((row) => {
|
||||||
|
@ -168,6 +171,20 @@ const markAsServed = () => {
|
||||||
refreshKey.value++;
|
refreshKey.value++;
|
||||||
startingDate.value = null;
|
startingDate.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openTicketsDialog = (id) => {
|
||||||
|
if (!id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
quasar
|
||||||
|
.dialog({
|
||||||
|
component: RouteListTicketsDialog,
|
||||||
|
componentProps: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.onOk(() => refreshKey.value++);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -470,6 +487,7 @@ const markAsServed = () => {
|
||||||
size="xs"
|
size="xs"
|
||||||
color="primary"
|
color="primary"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
|
@click="openTicketsDialog(props?.row?.id)"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('Add ticket') }}</QTooltip>
|
<QTooltip>{{ t('Add ticket') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
|
|
Loading…
Reference in New Issue