forked from verdnatura/salix-front
298 lines
9.1 KiB
Vue
298 lines
9.1 KiB
Vue
<script setup>
|
|
import { onMounted, onUnmounted, ref, computed, watchEffect } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
|
import { usePrintService } from 'composables/usePrintService';
|
|
import VnTable from 'components/VnTable/VnTable.vue';
|
|
import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
|
|
import { toCurrency, toDate } from 'src/filters/index';
|
|
import { useStateStore } from 'stores/useStateStore';
|
|
import { QBtn } from 'quasar';
|
|
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
|
|
|
const { t } = useI18n();
|
|
const stateStore = useStateStore();
|
|
const { viewSummary } = useSummaryDialog();
|
|
const tableRef = ref();
|
|
const invoiceOutSerialsOptions = ref([]);
|
|
const customerOptions = ref([]);
|
|
const selectedRows = ref([]);
|
|
const hasSelectedCards = computed(() => selectedRows.value.length > 0);
|
|
const MODEL = 'InvoiceOuts';
|
|
const { openReport } = usePrintService();
|
|
|
|
const columns = computed(() => [
|
|
{
|
|
align: 'center',
|
|
name: 'id',
|
|
label: t('invoiceOutList.tableVisibleColumns.id'),
|
|
chip: {
|
|
condition: () => true,
|
|
},
|
|
isId: true,
|
|
columnFilter: {
|
|
name: 'id',
|
|
},
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'ref',
|
|
label: t('globals.reference'),
|
|
isTitle: true,
|
|
component: 'select',
|
|
attrs: {
|
|
url: MODEL,
|
|
optionLabel: 'ref',
|
|
optionValue: 'ref',
|
|
},
|
|
columnField: { component: null },
|
|
columnFilter: {
|
|
inWhere: true,
|
|
},
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'Issued',
|
|
label: t('invoiceOutList.tableVisibleColumns.issued'),
|
|
component: 'date',
|
|
format: (row) => toDate(row.issued),
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'clientFk',
|
|
label: t('invoiceOutModule.customer'),
|
|
cardVisible: true,
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'Clients',
|
|
fields: ['id', 'socialName'],
|
|
optionLabel: 'socialName',
|
|
optionValue: 'id',
|
|
},
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'companyCode',
|
|
label: t('invoiceOutModule.company'),
|
|
cardVisible: true,
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'Companies',
|
|
optionLabel: 'code',
|
|
optionValue: 'id',
|
|
},
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'amount',
|
|
label: t('invoiceOutModule.amount'),
|
|
cardVisible: true,
|
|
format: (row) => toCurrency(row.amount),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'created',
|
|
label: t('invoiceOutList.tableVisibleColumns.created'),
|
|
component: 'date',
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
format: (row) => toDate(row.created),
|
|
},
|
|
{
|
|
align: 'left',
|
|
name: 'dued',
|
|
label: t('invoiceOutList.tableVisibleColumns.dueDate'),
|
|
component: 'date',
|
|
columnField: {
|
|
component: null,
|
|
},
|
|
format: (row) => toDate(row.dued),
|
|
},
|
|
{
|
|
align: 'right',
|
|
name: 'tableActions',
|
|
actions: [
|
|
{
|
|
title: t('components.smartCard.viewSummary'),
|
|
icon: 'preview',
|
|
action: (row) => viewSummary(row.id, InvoiceOutSummary),
|
|
},
|
|
{
|
|
title: t('DownloadPdf'),
|
|
icon: 'vn:ticket',
|
|
isPrimary: true,
|
|
action: (row) => openPdf(row.id),
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
onMounted(() => (stateStore.rightDrawer = true));
|
|
onUnmounted(() => (stateStore.rightDrawer = false));
|
|
|
|
function openPdf(id) {
|
|
openReport(`${MODEL}/${id}/download`);
|
|
}
|
|
|
|
function downloadPdf() {
|
|
if (selectedRows.value.size === 0) return;
|
|
const selectedCardsArray = Array.from(selectedRows.value.values());
|
|
|
|
if (selectedRows.value.size === 1) {
|
|
const [invoiceOut] = selectedCardsArray;
|
|
openPdf(invoiceOut.id);
|
|
} else {
|
|
const invoiceOutIdsArray = selectedCardsArray.map((invoiceOut) => invoiceOut.id);
|
|
const invoiceOutIds = invoiceOutIdsArray.join(',');
|
|
|
|
const params = {
|
|
ids: invoiceOutIds,
|
|
};
|
|
|
|
openReport(`${MODEL}/downloadZip`, params);
|
|
}
|
|
}
|
|
|
|
watchEffect(selectedRows);
|
|
</script>
|
|
|
|
<template>
|
|
<VnSearchbar
|
|
:info="t('youCanSearchByInvoiceReference')"
|
|
:label="t('searchInvoice')"
|
|
data-key="invoiceOutList"
|
|
/>
|
|
<RightMenu>
|
|
<template #right-panel>
|
|
<InvoiceOutFilter data-key="invoiceOutList" />
|
|
</template>
|
|
</RightMenu>
|
|
<VnSubToolbar>
|
|
<template #st-actions>
|
|
<QBtn
|
|
color="primary"
|
|
icon-right="cloud_download"
|
|
@click="downloadPdf()"
|
|
:disable="!hasSelectedCards"
|
|
>
|
|
<QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
|
|
</QBtn>
|
|
</template>
|
|
</VnSubToolbar>
|
|
<VnTable
|
|
ref="tableRef"
|
|
data-key="invoiceOutList"
|
|
:url="`${MODEL}/filter`"
|
|
:create="{
|
|
urlCreate: 'InvoiceOuts/createManualInvoice',
|
|
title: t('Create manual invoice'),
|
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
|
formInitialData: {
|
|
active: true,
|
|
},
|
|
}"
|
|
:right-search="false"
|
|
v-model:selected="selectedRows"
|
|
order="id DESC"
|
|
:columns="columns"
|
|
redirect="invoice-out"
|
|
auto-load
|
|
:table="{
|
|
'row-key': 'id',
|
|
selection: 'multiple',
|
|
}"
|
|
>
|
|
<template #column-clientFk="{ row }">
|
|
<span class="link" @click.stop>
|
|
{{ row.clientSocialName }}
|
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
|
</span>
|
|
</template>
|
|
<template #more-create-dialog="{ data }">
|
|
<div class="flex no-wrap flex-center">
|
|
<VnSelect
|
|
url="Tickets"
|
|
v-model="data.ticketFk"
|
|
:label="t('invoiceOutList.tableVisibleColumns.ticket')"
|
|
option-label="id"
|
|
option-value="id"
|
|
>
|
|
<template #option="scope">
|
|
<QItem v-bind="scope.itemProps">
|
|
<QItemSection>
|
|
<QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
|
|
<QItemLabel caption>{{ scope.opt?.nickname }}</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelect>
|
|
<span class="q-ml-md">O</span>
|
|
</div>
|
|
<VnSelect
|
|
url="Clients"
|
|
v-model="data.clientFk"
|
|
:label="t('invoiceOutModule.customer')"
|
|
:options="customerOptions"
|
|
option-label="name"
|
|
option-value="id"
|
|
/>
|
|
<VnSelect
|
|
url="InvoiceOutSerials"
|
|
v-model="data.serial"
|
|
:label="t('invoiceOutList.tableVisibleColumns.invoiceOutSerial')"
|
|
:options="invoiceOutSerialsOptions"
|
|
option-label="description"
|
|
option-value="code"
|
|
/>
|
|
<VnInputDate
|
|
:label="t('invoiceOutList.tableVisibleColumns.dueDate')"
|
|
v-model="data.maxShipped"
|
|
/>
|
|
<VnSelect
|
|
url="TaxAreas"
|
|
v-model="data.taxArea"
|
|
:label="t('invoiceOutList.tableVisibleColumns.taxArea')"
|
|
:options="taxAreasOptions"
|
|
option-label="code"
|
|
option-value="code"
|
|
/>
|
|
<QInput
|
|
v-model="data.reference"
|
|
:label="t('invoiceOutList.tableVisibleColumns.ref')"
|
|
/>
|
|
</template>
|
|
</VnTable>
|
|
</template>
|
|
|
|
<i18n>
|
|
en:
|
|
searchInvoice: Search issued invoice
|
|
fileDenied: Browser denied file download...
|
|
fileAllowed: Successful download of CSV file
|
|
youCanSearchByInvoiceReference: You can search by invoice reference
|
|
createInvoice: Make invoice
|
|
Create manual invoice: Create manual invoice
|
|
es:
|
|
searchInvoice: Buscar factura emitida
|
|
fileDenied: El navegador denegó la descarga de archivos...
|
|
fileAllowed: Descarga exitosa de archivo CSV
|
|
youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
|
|
createInvoice: Crear factura
|
|
Create manual invoice: Crear factura manual
|
|
</i18n>
|