318 lines
9.9 KiB
Vue
318 lines
9.9 KiB
Vue
<script setup>
|
|
import { ref, computed, onBeforeMount } from 'vue';
|
|
import axios from 'axios';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { dateRange, toDate } from 'src/filters/index';
|
|
import { useRoute } from 'vue-router';
|
|
|
|
import VnTable from 'components/VnTable/VnTable.vue';
|
|
import FetchedTags from 'components/ui/FetchedTags.vue';
|
|
import { useArrayData } from 'src/composables/useArrayData';
|
|
import { usePrintService } from 'src/composables/usePrintService';
|
|
import { useVnConfirm } from 'src/composables/useVnConfirm';
|
|
|
|
const { openConfirmationModal } = useVnConfirm();
|
|
const { openReport, sendEmail } = usePrintService();
|
|
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
|
import VnSelect from 'components/common/VnSelect.vue';
|
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
|
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
|
|
|
const arrayData = useArrayData('Customer');
|
|
const { t } = useI18n();
|
|
const route = useRoute();
|
|
const campaignList = ref();
|
|
const showActionBtns = computed(() => handleQueryParams());
|
|
function handleQueryParams() {
|
|
const query = getQueryParams();
|
|
return query.from && query.to;
|
|
}
|
|
const columns = computed(() => [
|
|
{
|
|
name: 'search',
|
|
align: 'left',
|
|
label: t('globals.search'),
|
|
visible: false,
|
|
},
|
|
{
|
|
name: 'itemFk',
|
|
align: 'left',
|
|
label: t('globals.item'),
|
|
columnClass: 'shrink',
|
|
cardVisible: true,
|
|
columnFilter: {
|
|
name: 'itemId',
|
|
},
|
|
},
|
|
{
|
|
name: 'ticketFk',
|
|
align: 'left',
|
|
label: t('globals.ticket'),
|
|
cardVisible: true,
|
|
columnFilter: {
|
|
name: 'ticketId',
|
|
},
|
|
},
|
|
{
|
|
name: 'shipped',
|
|
align: 'left',
|
|
label: t('globals.shipped'),
|
|
format: ({ shipped }) => toDate(shipped),
|
|
columnFilter: false,
|
|
cardVisible: true,
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'buyerId',
|
|
label: t('customer.params.buyerId'),
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'TicketRequests/getItemTypeWorker',
|
|
optionLabel: 'nickname',
|
|
optionValue: 'id',
|
|
|
|
fields: ['id', 'nickname'],
|
|
sortBy: ['nickname ASC'],
|
|
optionFilter: 'firstName',
|
|
},
|
|
cardVisible: false,
|
|
visible: false,
|
|
},
|
|
{
|
|
name: 'description',
|
|
align: 'left',
|
|
label: t('globals.description'),
|
|
columnClass: 'expand',
|
|
columnFilter: {
|
|
name: 'description',
|
|
|
|
},
|
|
},
|
|
{
|
|
name: 'quantity',
|
|
label: t('globals.quantity'),
|
|
cardVisible: true,
|
|
visible: true,
|
|
columnFilter: false
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
onBeforeMount(async () => {
|
|
campaignList.value = (await axios('Campaigns/latest')).data;
|
|
});
|
|
|
|
function getQueryParams() {
|
|
return JSON.parse(route.query.consumption ?? '{}');
|
|
}
|
|
function getParams() {
|
|
const query = getQueryParams();
|
|
return {
|
|
from: query.from,
|
|
to: query.to,
|
|
recipient: arrayData.store.data.email,
|
|
recipientId: arrayData.store.data.id,
|
|
};
|
|
}
|
|
const userParams = computed(() => {
|
|
const campaign = campaignList.value[0]?.id;
|
|
const userParams = {
|
|
campaign,
|
|
...updateDateParams(campaign, { from: Date.vnNew(), to: Date.vnNew() }),
|
|
};
|
|
return userParams;
|
|
});
|
|
const openReportPdf = () => {
|
|
openReport(`Clients/${route.params.id}/campaign-metrics-pdf`, getParams());
|
|
};
|
|
|
|
const openSendEmailDialog = async () => {
|
|
openConfirmationModal(
|
|
t('The consumption report will be sent'),
|
|
t('Please, confirm'),
|
|
() => sendCampaignMetricsEmail({ address: arrayData.store.data.email }),
|
|
);
|
|
};
|
|
const sendCampaignMetricsEmail = ({ address }) => {
|
|
sendEmail(`Clients/${route.params.id}/campaign-metrics-email`, {
|
|
recipient: address,
|
|
...getParams(),
|
|
});
|
|
};
|
|
|
|
const updateDateParams = (value, params) => {
|
|
if (!value) {
|
|
params.from = null;
|
|
params.to = null;
|
|
return;
|
|
}
|
|
const campaign = campaignList.value.find((c) => c.id === value);
|
|
if (!campaign) return;
|
|
|
|
const { dated, scopeDays } = campaign;
|
|
const from = new Date(dated);
|
|
from.setDate(from.getDate() - scopeDays);
|
|
params.from = from;
|
|
params.to = dated;
|
|
return params;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<VnTable
|
|
v-if="campaignList"
|
|
data-key="CustomerConsumption"
|
|
url="Clients/consumption"
|
|
:filter="{ where: { clientFk: route.params.id } }"
|
|
:columns="columns"
|
|
search-url="consumption"
|
|
:user-params="userParams"
|
|
:default-remove="false"
|
|
:default-reset="false"
|
|
:default-save="false"
|
|
:has-sub-toolbar="true"
|
|
auto-load
|
|
>
|
|
<template #moreBeforeActions>
|
|
<QBtn
|
|
color="primary"
|
|
flat
|
|
icon-right="picture_as_pdf"
|
|
@click="openReportPdf()"
|
|
:disabled="!showActionBtns"
|
|
>
|
|
<QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
|
|
</QBtn>
|
|
<QBtn
|
|
color="primary"
|
|
flat
|
|
icon-right="email"
|
|
@click="openSendEmailDialog()"
|
|
:disabled="!showActionBtns"
|
|
>
|
|
<QTooltip>{{ t('Send to email') }}</QTooltip>
|
|
</QBtn>
|
|
</template>
|
|
<template #column-itemFk="{ row }">
|
|
<span class="link">
|
|
{{ row.itemFk }}
|
|
<ItemDescriptorProxy :id="row.itemFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-ticketFk="{ row }">
|
|
<span class="link">
|
|
{{ row.ticketFk }}
|
|
<TicketDescriptorProxy :id="row.ticketFk" />
|
|
</span>
|
|
</template>
|
|
<template #column-description="{ row }">
|
|
<div>{{ row.concept }}</div>
|
|
<div v-if="row.subName" class="subName">
|
|
{{ row.subName }}
|
|
</div>
|
|
<FetchedTags :item="row" :columns="6"/>
|
|
</template>
|
|
<template #moreFilterPanel="{ params, searchFn}">
|
|
<div class="column no-wrap flex-center q-gutter-y-md q-mt-xs q-pr-xl">
|
|
<VnSelect
|
|
:filled="true"
|
|
class="q-px-sm q-pt-none fit"
|
|
url="ItemTypes"
|
|
v-model="params.typeId"
|
|
:label="t('item.list.typeName')"
|
|
:fields="['id', 'name', 'categoryFk']"
|
|
:include="'category'"
|
|
:sortBy="'name ASC'"
|
|
dense
|
|
>
|
|
<template #option="scope">
|
|
<QItem v-bind="scope.itemProps">
|
|
<QItemSection>
|
|
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
|
<QItemLabel caption>{{
|
|
scope.opt?.category?.name
|
|
}}</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelect>
|
|
<VnSelect
|
|
:filled="true"
|
|
class="q-px-sm q-pt-none fit"
|
|
url="ItemCategories"
|
|
v-model="params.categoryId"
|
|
:label="t('item.list.category')"
|
|
:fields="['id', 'name']"
|
|
:sortBy="'name ASC'"
|
|
dense
|
|
/>
|
|
<VnSelect
|
|
v-model="params.campaign"
|
|
:options="campaignList"
|
|
:label="t('globals.campaign')"
|
|
:filled="true"
|
|
class="q-px-sm q-pt-none fit"
|
|
:option-label="(opt) => t(opt.code ?? '')"
|
|
:fields="['id', 'code', 'dated', 'scopeDays']"
|
|
@update:model-value="(data) => updateDateParams(data, params)"
|
|
dense
|
|
>
|
|
<template #option="scope">
|
|
<QItem v-bind="scope.itemProps">
|
|
<QItemSection>
|
|
<QItemLabel> {{ t(scope.opt?.code) }} </QItemLabel>
|
|
<QItemLabel caption>
|
|
{{ new Date(scope.opt?.dated).getFullYear() }}
|
|
</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelect>
|
|
<VnInputDate
|
|
v-model="params.from"
|
|
:label="t('globals.from')"
|
|
:filled="true"
|
|
class="q-px-xs q-pt-none fit"
|
|
dense
|
|
/>
|
|
<VnInputDate
|
|
v-model="params.to"
|
|
:label="t('globals.to')"
|
|
:filled="true"
|
|
class="q-px-xs q-pt-none fit"
|
|
dense
|
|
/>
|
|
<VnCheckbox
|
|
v-model="params.grouped"
|
|
:label="t('Group by items')"
|
|
class="q-px-xs q-pt-none fit"
|
|
dense
|
|
@update:modelValue="() => searchFn()"
|
|
/>
|
|
</div>
|
|
</template>
|
|
</VnTable>
|
|
</template>
|
|
|
|
<i18n>
|
|
en:
|
|
|
|
valentinesDay: Valentine's Day
|
|
mothersDay: Mother's Day
|
|
allSaints: All Saints' Day
|
|
frenchMothersDay: Mother's Day in France
|
|
es:
|
|
Enter a new search: Introduce una nueva búsqueda
|
|
Group by items: Agrupar por artículos
|
|
valentinesDay: Día de San Valentín
|
|
mothersDay: Día de la Madre
|
|
allSaints: Día de Todos los Santos
|
|
frenchMothersDay: (Francia) Día de la Madre
|
|
Campaign consumption: Consumo campaña
|
|
Campaign: Campaña
|
|
From: Desde
|
|
To: Hasta
|
|
</i18n>
|