267 lines
7.5 KiB
Vue
267 lines
7.5 KiB
Vue
<script setup>
|
|
import { computed } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
import { date } from 'quasar';
|
|
import { toDateFormat } from 'src/filters/date.js';
|
|
|
|
import { dashIfEmpty, toCurrency } from 'src/filters';
|
|
|
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
|
import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue';
|
|
|
|
import InvoiceOutDescriptorProxy from 'pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
|
import RouteDescriptorProxy from 'src/pages/Route/Card/RouteDescriptorProxy.vue';
|
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
|
import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue';
|
|
|
|
const { t } = useI18n();
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const { viewSummary } = useSummaryDialog();
|
|
const $props = defineProps({
|
|
id: {
|
|
type: Number,
|
|
default: null,
|
|
},
|
|
});
|
|
const filter = {
|
|
include: [
|
|
{
|
|
relation: 'ticketState',
|
|
scope: {
|
|
fields: ['stateFk', 'code', 'alertLevel'],
|
|
include: { relation: 'state' },
|
|
},
|
|
},
|
|
{ relation: 'invoiceOut', scope: { fields: ['id'] } },
|
|
{ relation: 'agencyMode', scope: { fields: ['name'] } },
|
|
{
|
|
relation: 'ticketSales',
|
|
scope: {
|
|
fields: ['id', 'concept', 'itemFk'],
|
|
include: { relation: 'item' },
|
|
scope: {
|
|
fields: ['id', 'name', 'itemPackingTypeFk'],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
where: { clientFk: $props.id ?? route.params.id },
|
|
order: ['shipped DESC', 'id'],
|
|
limit: 30,
|
|
};
|
|
|
|
const columns = computed(() => [
|
|
{
|
|
align: 'left',
|
|
field: 'id',
|
|
label: t('Id'),
|
|
name: 'id',
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('Nickname'),
|
|
name: 'nickname',
|
|
columnClass: 'expand',
|
|
},
|
|
{
|
|
align: 'left',
|
|
format: (row) => dashIfEmpty(row.agencyMode?.name),
|
|
columnClass: 'expand',
|
|
label: t('Agency'),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'routeFk',
|
|
columnClass: 'shrink',
|
|
label: t('Route'),
|
|
},
|
|
{
|
|
align: 'left',
|
|
field: 'packages',
|
|
label: t('Packages'),
|
|
name: 'packages',
|
|
columnClass: 'shrink',
|
|
},
|
|
{
|
|
align: 'left',
|
|
format: ({ shipped }) => date.formatDate(shipped, 'DD/MM/YYYY'),
|
|
label: t('Date'),
|
|
name: 'shipped',
|
|
},
|
|
{
|
|
align: 'left',
|
|
label: t('State'),
|
|
name: 'state',
|
|
},
|
|
{
|
|
align: 'left',
|
|
field: 'totalWithVat',
|
|
label: t('Total'),
|
|
name: 'total',
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'itemPackingTypeFk',
|
|
label: t('ticketSale.packaging'),
|
|
format: (row) => getItemPackagingType(row.ticketSales),
|
|
},
|
|
{
|
|
align: 'right',
|
|
label: '',
|
|
name: 'tableActions',
|
|
actions: [
|
|
{
|
|
title: t('customer.summary.goToLines'),
|
|
icon: 'vn:lines',
|
|
action: ({ id }) =>
|
|
window.open(
|
|
router.resolve({ params: { id }, name: 'TicketSale' }).href,
|
|
'_blank',
|
|
),
|
|
isPrimary: true,
|
|
},
|
|
{
|
|
title: t('components.smartCard.viewSummary'),
|
|
icon: 'preview',
|
|
isPrimary: true,
|
|
action: (row) => viewSummary(row.id, TicketSummary, 'lg-width'),
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const setStateColor = (ticket) => {
|
|
const { ticketState } = ticket;
|
|
if (!ticketState) return;
|
|
const codeColorMap = { OK: 'success', FREE: 'notice' };
|
|
const alertLevelColorMap = { 0: 'alert', 1: 'warning' };
|
|
if (codeColorMap[ticketState.code]) return codeColorMap[ticketState.code];
|
|
return alertLevelColorMap[ticketState.alertLevel];
|
|
};
|
|
|
|
const setTotalPriceColor = (ticket) => {
|
|
const total = parseInt(ticket.totalWithVat);
|
|
if (total > 0 && total < 50) return 'warning';
|
|
};
|
|
|
|
const setShippedColor = (date) => {
|
|
const today = Date.vnNew();
|
|
today.setHours(0, 0, 0, 0);
|
|
|
|
const ticketShipped = new Date(date);
|
|
ticketShipped.setHours(0, 0, 0, 0);
|
|
|
|
const difference = today - ticketShipped;
|
|
|
|
if (difference == 0) return 'warning';
|
|
if (difference < 0) return 'success';
|
|
};
|
|
const rowClick = ({ id }) =>
|
|
window.open(router.resolve({ params: { id }, name: 'TicketSummary' }).href, '_blank');
|
|
|
|
const getItemPackagingType = (ticketSales) => {
|
|
if (!ticketSales?.length) return '-';
|
|
|
|
const packagingTypes = ticketSales.reduce((types, sale) => {
|
|
const { itemPackingTypeFk } = sale.item;
|
|
if (
|
|
!types.includes(itemPackingTypeFk) &&
|
|
(itemPackingTypeFk === 'H' || itemPackingTypeFk === 'V')
|
|
) {
|
|
types.push(itemPackingTypeFk);
|
|
}
|
|
return types;
|
|
}, []);
|
|
|
|
return dashIfEmpty(packagingTypes.join(', ') || '-');
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<VnTable
|
|
data-key="CustomerTickets"
|
|
:filter="filter"
|
|
:right-search="false"
|
|
:column-search="false"
|
|
url="Tickets"
|
|
:columns="columns"
|
|
:without-header="true"
|
|
auto-load
|
|
:row-click="rowClick"
|
|
order="shipped DESC, id"
|
|
:disable-option="{ card: true, table: true }"
|
|
class="full-width"
|
|
:disable-infinite-scroll="true"
|
|
:search-url="false"
|
|
redirect="ticket"
|
|
>
|
|
<template #column-nickname="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ row.nickname }}
|
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
|
</span>
|
|
</template>
|
|
|
|
<template #column-routeFk="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ row.routeFk }}
|
|
<RouteDescriptorProxy :id="row.routeFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-total="{ row }">
|
|
<QBadge
|
|
class="q-pa-sm"
|
|
v-if="setTotalPriceColor(row)"
|
|
:color="setTotalPriceColor(row)"
|
|
text-color="black"
|
|
>
|
|
{{ toCurrency(row.totalWithVat) }}
|
|
</QBadge>
|
|
<span v-else> {{ toCurrency(row.totalWithVat) }}</span>
|
|
</template>
|
|
<template #column-state="{ row }">
|
|
<span v-if="row.invoiceOut" @click.stop>
|
|
<span :class="{ link: row.invoiceOut.ref }">
|
|
{{ row.invoiceOut.ref }}
|
|
<InvoiceOutDescriptorProxy :id="row.invoiceOut.id" />
|
|
</span>
|
|
</span>
|
|
<QBadge
|
|
class="q-pa-sm"
|
|
:color="setStateColor(row)"
|
|
text-color="black"
|
|
v-else-if="setStateColor(row)"
|
|
>
|
|
{{ row?.ticketState?.state.name }}
|
|
</QBadge>
|
|
<span v-else> {{ row?.ticketState?.state.name }}</span>
|
|
</template>
|
|
<template #column-shipped="{ row }">
|
|
<QBadge
|
|
class="q-pa-sm"
|
|
:color="setShippedColor(row.shipped)"
|
|
text-color="black"
|
|
v-if="setShippedColor(row.shipped)"
|
|
>
|
|
{{ toDateFormat(row.shipped) }}
|
|
</QBadge>
|
|
<span v-else> {{ toDateFormat(row.shipped) }}</span>
|
|
</template>
|
|
</VnTable>
|
|
</template>
|
|
|
|
<i18n>
|
|
es:
|
|
Id: Id
|
|
Nickname: Alias
|
|
Agency: Agencia
|
|
Route: Ruta
|
|
Packages: Bultos
|
|
Date: Fecha
|
|
State: Estado
|
|
Total: Total
|
|
</i18n>
|