Modulo de rutas #195

Merged
jsegarra merged 49 commits from :feature/route-module into dev 2024-03-14 12:44:43 +00:00
2 changed files with 268 additions and 6 deletions
Showing only changes of commit c013c9054f - Show all commits

View File

@ -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'),
jgallego marked this conversation as resolved Outdated

en salix es city.
"Population" se refiere al número total de individuos que habitan en un área geográfica específica

en salix es city. "Population" se refiere al número total de individuos que habitan en un área geográfica específica

En Salix hay una incongruencia, en el listado de tickets se muestra "city", pero en el modal muestra "population".

Se cambio a "City".

e4553659cf

En Salix hay una incongruencia, en el listado de tickets se muestra "city", pero en el modal muestra "population". Se cambio a "City". e4553659cf1ef6c245569557901bcd3a0a680d51
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>

View File

@ -15,12 +15,15 @@ import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
import RouteFilter from 'pages/Route/Card/RouteFilter.vue';
import RouteSummary from 'pages/Route/Card/RouteSummary.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 RouteListTicketsDialog from 'pages/Route/Card/RouteListTicketsDialog.vue';
import { useQuasar } from 'quasar';
const stateStore = useStateStore();
const { t } = useI18n();
const { validate } = useValidator();
const quasar = useQuasar();
const session = useSession();
const { viewSummary } = useSummaryDialog();
@ -143,8 +146,8 @@ const cloneRoutes = () => {
};
const showRouteReport = () => {
const ids = selectedRows.value.map(row => row?.id)
const idString = ids.join(',')
const ids = selectedRows.value.map((row) => row?.id);
const idString = ids.join(',');
let url;
if (selectedRows.value.length <= 1) {
@ -152,12 +155,12 @@ const showRouteReport = () => {
} else {
const params = new URLSearchParams({
access_token: session.getToken(),
id: idString
})
id: idString,
});
url = `api/Routes/downloadZip?${params.toString()}`;
}
window.open(url, '_blank');
}
};
const markAsServed = () => {
selectedRows.value.forEach((row) => {
@ -168,6 +171,20 @@ const markAsServed = () => {
refreshKey.value++;
startingDate.value = null;
};
const openTicketsDialog = (id) => {
if (!id) {
return;
}
quasar
.dialog({
component: RouteListTicketsDialog,
componentProps: {
id,
},
})
.onOk(() => refreshKey.value++);
};
</script>
<template>
@ -470,6 +487,7 @@ const markAsServed = () => {
size="xs"
color="primary"
class="cursor-pointer"
@click="openTicketsDialog(props?.row?.id)"
>
<QTooltip>{{ t('Add ticket') }}</QTooltip>
</QIcon>