179 lines
4.0 KiB
Vue
179 lines
4.0 KiB
Vue
<template>
|
||
<form
|
||
class="report-form"
|
||
@submit="onSubmit"
|
||
>
|
||
<UiButton
|
||
icon="chevron-left"
|
||
color="secondary"
|
||
type="link"
|
||
class="mb-8"
|
||
:href="`/projects/${$route.params.projectId}/invoices`"
|
||
>
|
||
{{ $t('back_to', [project.name]) }}
|
||
</UiButton>
|
||
|
||
<h1 class="report-form__title">
|
||
Exporting data
|
||
</h1>
|
||
|
||
<div class="report-block mb-16">
|
||
<h4 class="report-block__title">
|
||
Выберите период
|
||
</h4>
|
||
|
||
<div class="report-block__actions">
|
||
<RadioButton id="period" value="today" label="За сегодня" :caption="todayText" required />
|
||
<RadioButton id="period" value="week" required label="За неделю" :caption="weekText" />
|
||
<RadioButton id="period" value="month" label="За месяц" disabled />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="report-block">
|
||
<h4 class="report-block__title">
|
||
Выберите статус операции
|
||
</h4>
|
||
|
||
<div class="report-block__actions">
|
||
<CheckboxButton id="all_statuses" label="All" />
|
||
<CheckboxButton
|
||
v-for="status in availableStatuses"
|
||
id="statuses"
|
||
:key="status"
|
||
:label="$t(`invoice_status.${status}`)"
|
||
:true-value="status"
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<UiButton
|
||
class="report-form__submit"
|
||
size="large"
|
||
native-type="submit"
|
||
:loading="isSubmitting"
|
||
:disabled="!values.period || !values.statuses.length"
|
||
>
|
||
Скачать CSV отчет
|
||
</UiButton>
|
||
</form>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { useForm } from 'vee-validate'
|
||
import dayjs from 'dayjs'
|
||
import { downloadFile } from '#imports'
|
||
|
||
definePageMeta({
|
||
middleware: ['auth'],
|
||
centerContent: true,
|
||
})
|
||
|
||
const route = useRoute()
|
||
|
||
const { data: project } = await useAsyncData(
|
||
'project',
|
||
() =>
|
||
$api(`/online_stores/${route.params.projectId}`, {
|
||
method: 'get',
|
||
}),
|
||
{},
|
||
)
|
||
|
||
if (!project.value) {
|
||
throw createError({
|
||
statusCode: 404,
|
||
statusMessage: 'Page Not Found',
|
||
})
|
||
}
|
||
|
||
const availableStatuses = ['completed', 'overpaid', 'underpaid', 'awaiting_payment', 'expired']
|
||
|
||
const { handleSubmit, isSubmitting, values, defineField } = useForm<{
|
||
period: 'today' | 'week' | 'month'
|
||
all_statuses?: boolean
|
||
'statuses': string[]
|
||
}>({
|
||
initialValues: {
|
||
statuses: [],
|
||
},
|
||
})
|
||
const [allStatuses] = defineField('all_statuses')
|
||
const [selectedStatuses] = defineField('statuses')
|
||
|
||
const todayText = dayjs().format('DD.MM.YYYY')
|
||
const weekText = `${dayjs().subtract(1, 'week').get('date')} - ${todayText}`
|
||
|
||
const onSubmit = handleSubmit(async (values) => {
|
||
delete values.all_statuses
|
||
|
||
const dateFormat = 'YYYY-MM-DD'
|
||
let dateFrom: string, dateTo: string
|
||
if (values.period === 'today') {
|
||
dateFrom = dateTo = dayjs().format(dateFormat)
|
||
}
|
||
else if (values.period === 'week') {
|
||
dateFrom = dayjs().subtract(1, 'week').format(dateFormat)
|
||
dateTo = dayjs().format(dateFormat)
|
||
}
|
||
|
||
const csv = await $api<string>('/invoices.csv', {
|
||
method: 'GET',
|
||
params: {
|
||
'onlineStoreId': route.params.projectId,
|
||
'statuses[]': values.statuses,
|
||
dateFrom,
|
||
dateTo,
|
||
},
|
||
})
|
||
|
||
downloadFile(`invoices-${dateTo}.csv`, csv)
|
||
})
|
||
|
||
watch(allStatuses, (value) => {
|
||
if (!value && selectedStatuses.value.length !== availableStatuses.length)
|
||
return
|
||
|
||
selectedStatuses.value = value ? availableStatuses : []
|
||
})
|
||
|
||
watch(selectedStatuses, (value) => {
|
||
allStatuses.value = value.length === availableStatuses.length
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.report-form {
|
||
margin: 0 auto;
|
||
width: 500px;
|
||
|
||
&__title {
|
||
margin-bottom: 32px;
|
||
}
|
||
|
||
&__submit {
|
||
width: 100%;
|
||
margin-top: 32px;
|
||
}
|
||
}
|
||
|
||
.report-block {
|
||
padding: 16px;
|
||
border-radius: 16px;
|
||
background-color: $clr-white;
|
||
|
||
&__title {
|
||
@include font(13px, 500, 18px);
|
||
|
||
color: $clr-grey-600;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
&__actions {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 16px 10px;
|
||
}
|
||
}
|
||
</style>
|