<script setup> import { onMounted, ref, computed } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { toCurrency, toDate } from 'src/filters'; import { useArrayData } from 'src/composables/useArrayData'; import { getUrl } from 'src/composables/getUrl'; import CardSummary from 'components/ui/CardSummary.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; import InvoiceIntoBook from '../InvoiceInToBook.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; const props = defineProps({ id: { type: [Number, String], default: 0 } }); const { t } = useI18n(); const route = useRoute(); const arrayData = useArrayData(); const entityId = computed(() => props.id || +route.params.id); const invoiceIn = computed(() => arrayData.store.data); const currency = computed(() => invoiceIn.value?.currency?.code); const invoiceInUrl = ref(); const amountsNotMatch = ref(null); const intrastatTotals = ref({ amount: 0, net: 0, stems: 0 }); const vatColumns = ref([ { name: 'expense', label: 'InvoiceIn.summary.expense', field: (row) => row.expenseFk, sortable: true, align: 'left', }, { name: 'landed', label: 'InvoiceIn.summary.taxableBase', field: (row) => row.taxableBase, format: (value) => toCurrency(value), sortable: true, align: 'left', }, { name: 'vat', label: 'InvoiceIn.summary.sageVat', field: (row) => { if (row.taxTypeSage) return `#${row.taxTypeSage.id} : ${row.taxTypeSage.vat}`; }, format: (value) => value, sortable: true, align: 'left', }, { name: 'transaction', label: 'InvoiceIn.summary.sageTransaction', field: (row) => { if (row.transactionTypeSage) return `#${row.transactionTypeSage.id} : ${row.transactionTypeSage?.transaction}`; }, format: (value) => value, sortable: true, align: 'left', }, { name: 'rate', label: 'InvoiceIn.summary.rate', field: (row) => taxRate(row.taxableBase, row.taxTypeSage?.rate), format: (value) => toCurrency(value), sortable: true, align: 'left', }, { name: 'currency', label: 'InvoiceIn.summary.currency', field: (row) => row.foreignValue, format: (val) => val && toCurrency(val, currency.value), sortable: true, align: 'left', }, ]); const dueDayColumns = ref([ { name: 'date', label: 'InvoiceIn.summary.dueDay', field: (row) => toDate(row.dueDated), sortable: true, align: 'left', }, { name: 'bank', label: 'InvoiceIn.summary.bank', field: (row) => row.bank.bank, sortable: true, align: 'left', }, { name: 'amount', label: 'InvoiceIn.list.amount', field: (row) => row.amount, format: (value) => toCurrency(value), sortable: true, align: 'left', }, { name: 'landed', label: 'InvoiceIn.summary.foreignValue', field: (row) => row.foreignValue, format: (val) => val && toCurrency(val, currency.value), sortable: true, align: 'left', }, ]); const intrastatColumns = ref([ { name: 'code', label: 'InvoiceIn.summary.code', field: (row) => { return `${row.intrastat.id}: ${row.intrastat?.description}`; }, sortable: true, align: 'left', }, { name: 'amount', label: 'InvoiceIn.list.amount', field: (row) => toCurrency(row.amount), sortable: true, align: 'left', }, { name: 'net', label: 'InvoiceIn.summary.net', field: (row) => row.net, sortable: true, align: 'left', }, { name: 'stems', label: 'InvoiceIn.summary.stems', field: (row) => row.stems, format: (value) => value, sortable: true, align: 'left', }, { name: 'landed', label: 'InvoiceIn.summary.country', field: (row) => row.country?.code, format: (value) => value, sortable: true, align: 'left', }, ]); onMounted(async () => { invoiceInUrl.value = `${await getUrl('')}invoiceIn/${entityId.value}/`; }); const init = (data) => { if (!data) return; const { totals, invoiceInIntrastat } = data; amountsNotMatch.value = totals.totalDueDay != totals.totalTaxableBase && totals.totalDueDay != totals.totalVat; invoiceInIntrastat.forEach((val) => { intrastatTotals.value.amount += val.amount; intrastatTotals.value.net += val.net; intrastatTotals.value.stems += val.stems; }); }; const taxRate = (taxableBase = 0, rate = 0) => (rate / 100) * taxableBase; const getTotalTax = (tax) => tax.reduce((acc, cur) => acc + taxRate(cur.taxableBase, cur.taxTypeSage?.rate), 0); const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; </script> <template> <CardSummary data-key="InvoiceInSummary" :url="`InvoiceIns/${entityId}/summary`" @on-fetch="(data) => init(data)" > <template #header="{ entity }"> <div>{{ entity.id }} - {{ entity.supplier?.name }}</div> </template> <template #header-right v-if="!invoiceIn?.isBooked"> <InvoiceIntoBook> <template #content="{ book }"> <QBtn :label="t('To book')" color="orange-11" text-color="black" @click="book(entityId)" /> </template> </InvoiceIntoBook> </template> <template #body="{ entity }"> <!--Basic Data--> <QCard class="vn-one"> <QCardSection class="q-pa-none"> <VnTitle :url="getLink('basic-data')" :text="t('globals.pageTitles.basicData')" /> </QCardSection> <VnLv :label="t('InvoiceIn.list.supplier')" :value="entity.supplier?.name" > <template #value> <span class="link"> {{ entity.supplier?.name }} <SupplierDescriptorProxy :id="entity.supplierFk" /> </span> </template> </VnLv> <VnLv :label="t('InvoiceIn.list.supplierRef')" :value="entity.supplierRef" /> <VnLv :label="t('InvoiceIn.summary.currency')" :value="entity.currency?.code" /> <VnLv :label="t('InvoiceIn.serial')" :value="`${entity.serial}`" /> <VnLv :label="t('globals.country')" :value="entity.supplier?.country?.code" /> </QCard> <QCard class="vn-one"> <QCardSection class="q-pa-none"> <VnTitle :url="getLink('basic-data')" :text="t('globals.pageTitles.basicData')" /> </QCardSection> <VnLv :ellipsis-value="false" :label="t('InvoiceIn.summary.issued')" :value="toDate(entity.issued)" /> <VnLv :label="t('InvoiceIn.summary.operated')" :value="toDate(entity.operated)" /> <VnLv :label="t('InvoiceIn.summary.bookEntried')" :value="toDate(entity.bookEntried)" /> <VnLv :label="t('InvoiceIn.summary.bookedDate')" :value="toDate(entity.booked)" /> <VnLv :label="t('globals.isVies')" :value="entity.supplier?.isVies" /> </QCard> <QCard class="vn-one"> <QCardSection class="q-pa-none"> <VnTitle :url="getLink('basic-data')" :text="t('globals.pageTitles.basicData')" /> </QCardSection> <VnLv :label="t('InvoiceIn.summary.sage')" :value="entity.sageWithholding?.withholding" /> <VnLv :label="t('InvoiceIn.summary.vat')" :value="entity.expenseDeductible?.name" /> <VnLv :label="t('InvoiceIn.card.company')" :value="entity.company?.code" /> <VnLv :label="t('InvoiceIn.isBooked')" :value="invoiceIn?.isBooked" /> </QCard> <QCard class="vn-one"> <QCardSection class="q-pa-none"> <VnTitle :url="getLink('basic-data')" :text="t('globals.pageTitles.basicData')" /> </QCardSection> <QCardSection class="q-pa-none"> <VnLv :label="t('InvoiceIn.summary.taxableBase')" :value="toCurrency(entity.totals.totalTaxableBase)" /> <VnLv label="Total" :value="toCurrency(entity.totals.totalVat)" /> <VnLv :label="t('InvoiceIn.summary.dueTotal')"> <template #value> <QChip dense class="q-pa-xs" :color="amountsNotMatch ? 'negative' : 'transparent'" :title=" amountsNotMatch ? t('InvoiceIn.summary.noMatch') : t('InvoiceIn.summary.dueTotal') " > {{ toCurrency(entity.totals.totalDueDay) }} </QChip> </template> </VnLv> </QCardSection> </QCard> <!--Vat--> <QCard v-if="entity.invoiceInTax.length" class="vat"> <VnTitle :url="getLink('vat')" :text="t('InvoiceIn.card.vat')" /> <QTable :columns="vatColumns" :rows="entity.invoiceInTax" flat hide-pagination > <template #header="vatProps"> <QTr :props="vatProps" class="bg"> <QTh v-for="col in vatProps.cols" :key="col.name" :props="vatProps" > {{ t(col.label) }} </QTh> </QTr> </template> <template #body-cell-vat="{ value: vatCell }"> <QTd :title="vatCell" shrink> {{ vatCell }} </QTd> </template> <template #body-cell-transaction="{ value: transactionCell }"> <QTd :title="transactionCell" shrink> {{ transactionCell }} </QTd> </template> <template #bottom-row> <QTr class="bg"> <QTd></QTd> <QTd>{{ toCurrency(entity.totals.totalTaxableBase) }}</QTd> <QTd></QTd> <QTd></QTd> <QTd>{{ toCurrency(getTotalTax(entity.invoiceInTax)) }}</QTd> <QTd>{{ entity.totals.totalTaxableBaseForeignValue && toCurrency( entity.totals.totalTaxableBaseForeignValue, currency ) }}</QTd> </QTr> </template> </QTable> </QCard> <!--Due Day--> <QCard v-if="entity.invoiceInDueDay.length" class="due-day"> <VnTitle :url="getLink('due-day')" :text="t('InvoiceIn.card.dueDay')" /> <QTable :columns="dueDayColumns" :rows="entity.invoiceInDueDay" flat> <template #header="dueDayProps"> <QTr :props="dueDayProps" class="bg"> <QTh table-header-style="max-width:50%" v-for="col in dueDayProps.cols" :key="col.name" :props="dueDayProps" > {{ t(col.label) }} </QTh> </QTr> </template> <template #bottom-row> <QTr class="bg"> <QTd></QTd> <QTd></QTd> <QTd> {{ toCurrency(entity.totals.totalDueDay) }} </QTd> <QTd> {{ entity.totals.totalDueDayForeignValue && toCurrency( entity.totals.totalDueDayForeignValue, currency ) }} </QTd> </QTr> </template> </QTable> </QCard> <!--Intrastat--> <QCard v-if="entity.invoiceInIntrastat.length"> <VnTitle :url="getLink('intrastat')" :text="t('InvoiceIn.card.intrastat')" /> <QTable :columns="intrastatColumns" :rows="entity.invoiceInIntrastat" flat > <template #header="intrastatProps"> <QTr :props="intrastatProps" class="bg"> <QTh v-for="col in intrastatProps.cols" :key="col.name" :props="intrastatProps" > {{ t(col.label) }} </QTh> </QTr> </template> <template #body-cell-code="{ value: codeCell }"> <QTd :title="codeCell" shrink> {{ codeCell }} </QTd> </template> <template #bottom-row> <QTr class="bg"> <QTd></QTd> <QTd>{{ toCurrency(intrastatTotals.amount) }}</QTd> <QTd>{{ intrastatTotals.net }}</QTd> <QTd>{{ intrastatTotals.stems }}</QTd> <QTd></QTd> </QTr> </template> </QTable> </QCard> </template> </CardSummary> </template> <style lang="scss" scoped> .bg { background-color: var(--vn-accent-color); } .q-chip { color: var(--vn-text-color); } @media (min-width: $breakpoint-md) { .summaryBody { .vat { flex: 65%; } .due-day { flex: 30%; } .vat, .due-day { .q-table th { padding-right: 0; } } } } </style> <i18n> es: Search invoice: Buscar factura recibida You can search by invoice reference: Puedes buscar por referencia de la factura Totals: Totales To book: Contabilizar </i18n>