feat: refs #8277 add invoice confirmation dialog and total amount calculation in EntryControl

This commit is contained in:
Jorge Penadés 2025-03-28 09:49:44 +01:00
parent 232cb7b4f4
commit 1117d3d07a
3 changed files with 64 additions and 19 deletions

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, computed, markRaw, useTemplateRef, onBeforeMount } from 'vue';
import { ref, computed, markRaw, useTemplateRef, onBeforeMount, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { toDate, toCurrency } from 'src/filters';
import { useArrayData } from 'src/composables/useArrayData';
@ -15,8 +15,10 @@ import useNotify from 'src/composables/useNotify';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import VnDms from 'src/components/common/VnDms.vue';
import { useState } from 'src/composables/useState';
import { useQuasar } from 'quasar';
const { t } = useI18n();
const quasar = useQuasar();
const { notify } = useNotify();
const user = useState().getUser();
const dialog = ref();
@ -36,6 +38,11 @@ const entryTypes = ref([]);
const entryAccounts = ref([]);
const warehouses = ref([]);
const selectedRows = ref([]);
const totalAmount = ref();
const totalSelectedAmount = computed(() => {
if (!selectedRows.value.length) return 0;
return selectedRows.value.reduce((acc, entry) => acc + entry.amount, 0);
});
let selectedGestDoc;
let supplierRef;
const columns = computed(() => [
@ -209,6 +216,14 @@ onBeforeMount(() => {
isBooked.value = arrayData.store.userParams.isBooked || false;
});
watch(selectedRows, (nVal, oVal) => {
if (nVal.length > oVal.length && nVal.at(-1).invoiceInFk)
quasar.dialog({
component: VnConfirm,
componentProps: { title: t('entry.control.hasInvoice') },
});
});
function filterByDaysAgo(val) {
if (!val) val = DEFAULTDAYS;
else if (val > MAXDAYS) val = MAXDAYS;
@ -233,27 +248,37 @@ async function preAccount() {
// Is It agricultural?
const selectedAgri = entries.at(0);
// If It's agricultural, get the supplierRef
if (selectedAgri.isAgricultural) {
const year = new Date(selectedAgri.landed).getFullYear();
supplierRef = (
await axios.get('InvoiceIns/getMaxRef', {
params: { companyFk: selectedAgri.companyFk, year },
})
).data;
try {
if (selectedAgri.isAgricultural) {
const year = new Date(selectedAgri.landed).getFullYear();
supplierRef = (
await axios.get('InvoiceIns/getMaxRef', {
params: { companyFk: selectedAgri.companyFk, year },
})
).data;
if (!supplierRef) supplierRef = year + '001';
return createInvoice(true);
} else if (selectedGestDoc) {
// If There's a allocated file for an entry? Ask to (update/updlod) the file
dialog.value.show();
} else {
// If There's no gestDoc, upload the file
uploadFile();
return createInvoice(true);
} else if (selectedGestDoc) {
// If There's an allocated file for an entry? Ask to (update/updload) the file
supplierRef = +(
await axios.get(`Dms/${selectedGestDoc.gestDocFk}`, {
params: { filter: JSON.stringify({ fields: { reference: true } }) },
})
).data?.reference;
dialog.value.show();
} else {
// If There's no gestDoc, upload the file
uploadFile();
}
} catch (e) {
throw e;
}
}
async function updateFile() {
await axios.post(`Dms/${selectedGestDoc.gestDocFk}/updateFile`, { dmsTypeId: 1 });
table.value.reload();
await createInvoice(false);
}
async function uploadFile() {
@ -272,17 +297,19 @@ async function uploadFile() {
}
async function createInvoice(isAgricultural) {
let err;
try {
await axios.post(`Entries/preAccount`, {
ids: selectedRows.value.map((entry) => entry.id),
supplierRef,
isAgricultural,
});
// Una vez marcada las entradas como contabilizadas, no permitir contabilizarla otra vez?? Carlos
} catch (e) {
throw e;
} finally {
table.value.reload();
supplierRef = null;
selectedGestDoc = null;
}
}
</script>
@ -328,9 +355,9 @@ async function createInvoice(isAgricultural) {
v-model:selected="selectedRows"
:data-key
:columns
:url
:search-url="dataKey"
ref="table"
:url
:disable-option="{ card: true }"
redirect="Entry"
:order="['landed DESC']"
@ -338,6 +365,11 @@ async function createInvoice(isAgricultural) {
:user-params="{ daysAgo, isBooked }"
:row-click="false"
:table="{ selection: 'multiple' }"
:limit="0"
:footer="true"
@on-fetch="
(data) => (totalAmount = data.reduce((acc, entry) => acc + entry.amount, 0))
"
>
<template #top-left>
<QBtn
@ -373,6 +405,10 @@ async function createInvoice(isAgricultural) {
<SupplierDescriptorProxy :id="row.supplierFk" />
</span>
</template>
<template #column-footer-amount>
<div v-text="toCurrency(totalSelectedAmount)" />
<div v-text="toCurrency(totalAmount)" />
</template>
</VnTable>
<VnConfirm
ref="dialog"
@ -385,8 +421,15 @@ async function createInvoice(isAgricultural) {
color="primary"
@click="updateFile"
autofocus
v-close-popup
/>
<QBtn
:label="t('globals.no')"
color="primary"
flat
@click="uploadFile"
v-close-popup
/>
<QBtn :label="t('globals.no')" color="primary" flat @click="uploadFile" />
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
</template>
</VnConfirm>

View File

@ -140,6 +140,7 @@ entry:
search: Search
searchInfo: You can search by supplier name or nickname
preAccount: Pre-account
hasInvoice: This entry has already an invoice in
dialog:
title: Pre-account entries
message: Do you want the invoice to inherit the entry document?

View File

@ -91,6 +91,7 @@ entry:
search: Buscar
searchInfo: Puedes buscar por nombre o alias de proveedor
preAccount: Precontabilizar
hasInvoice: Esta entrada ya tiene una f. recibida
dialog:
title: Precontabilizar entradas
message: ¿Desea que la factura herede el documento de la entrada?