209 lines
6.2 KiB
Vue
209 lines
6.2 KiB
Vue
<script setup>
|
|
import { ref, computed, onBeforeMount } from 'vue';
|
|
import { useRoute } from 'vue-router';
|
|
import { useI18n } from 'vue-i18n';
|
|
import axios from 'axios';
|
|
import { useArrayData } from 'src/composables/useArrayData';
|
|
import { getTotal } from 'src/composables/getTotal';
|
|
import useNotify from 'src/composables/useNotify.js';
|
|
import { toCurrency } from 'filters/index';
|
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
|
|
|
const route = useRoute();
|
|
const { notify } = useNotify();
|
|
const { t } = useI18n();
|
|
const arrayData = useArrayData();
|
|
const invoiceIn = computed(() => arrayData.store.data);
|
|
const currency = computed(() => invoiceIn.value?.currency?.code);
|
|
const rowsSelected = ref([]);
|
|
const invoiceInDueDayTableRef = ref();
|
|
const invoiceId = +route.params.id;
|
|
const filter = { where: { invoiceInFk: invoiceId } };
|
|
const areRows = ref(false);
|
|
const totalTaxableBase = ref();
|
|
const totalVat = ref();
|
|
|
|
const tableRows = computed(
|
|
() => invoiceInDueDayTableRef.value?.CrudModelRef?.formData || [],
|
|
);
|
|
const totalAmount = computed(() => getTotal(tableRows.value, 'amount'));
|
|
|
|
const noMatch = computed(
|
|
() =>
|
|
totalAmount.value != totalTaxableBase.value &&
|
|
totalAmount.value != totalVat.value,
|
|
);
|
|
|
|
const columns = computed(() => [
|
|
{
|
|
name: 'dueDated',
|
|
label: t('Date'),
|
|
sortable: true,
|
|
tabIndex: 1,
|
|
align: 'left',
|
|
component: 'date',
|
|
isEditable: true,
|
|
create: true,
|
|
},
|
|
{
|
|
name: 'bankFk',
|
|
label: t('Bank'),
|
|
sortable: true,
|
|
tabIndex: 2,
|
|
align: 'left',
|
|
component: 'select',
|
|
attrs: {
|
|
url: 'Accountings',
|
|
optionLabel: 'bank',
|
|
optionValue: 'id',
|
|
fields: ['id', 'bank'],
|
|
'emit-value': true,
|
|
},
|
|
format: ({ bank }) => bank?.bank,
|
|
isEditable: true,
|
|
create: true,
|
|
},
|
|
{
|
|
name: 'amount',
|
|
label: t('Amount'),
|
|
sortable: true,
|
|
tabIndex: 3,
|
|
align: 'left',
|
|
component: 'number',
|
|
attrs: {
|
|
clearable: true,
|
|
'clear-icon': 'close',
|
|
},
|
|
isEditable: true,
|
|
create: true,
|
|
},
|
|
{
|
|
name: 'foreignValue',
|
|
label: t('Foreign value'),
|
|
sortable: true,
|
|
tabIndex: 4,
|
|
align: 'left',
|
|
component: 'number',
|
|
isEditable: isNotEuro(currency.value),
|
|
create: true,
|
|
},
|
|
]);
|
|
|
|
const isNotEuro = (code) => code != 'EUR';
|
|
|
|
async function insert() {
|
|
await axios.post('/InvoiceInDueDays/new', { id: +invoiceId });
|
|
await invoiceInDueDayTableRef.value.reload();
|
|
notify(t('globals.dataSaved'), 'positive');
|
|
}
|
|
async function setTaxableBase() {
|
|
const ref = invoiceInDueDayTableRef.value;
|
|
if (ref) ref.create = null;
|
|
const { data } = await axios.get(`InvoiceIns/${invoiceId}/getTotals`);
|
|
totalTaxableBase.value = data.totalTaxableBase;
|
|
totalVat.value = data.totalVat;
|
|
}
|
|
|
|
onBeforeMount(async () => await setTaxableBase());
|
|
</script>
|
|
<template>
|
|
<div class="invoice-in-due-day">
|
|
<VnTable
|
|
v-if="invoiceIn"
|
|
ref="invoiceInDueDayTableRef"
|
|
data-key="InvoiceInDueDays"
|
|
url="InvoiceInDueDays"
|
|
save-url="InvoiceInDueDays/crud"
|
|
:filter="filter"
|
|
:user-filter="{
|
|
include: { relation: 'bank', scope: { fields: ['id', 'bank'] } },
|
|
}"
|
|
auto-load
|
|
:data-required="{ invoiceInFk: invoiceId }"
|
|
v-model:selected="rowsSelected"
|
|
@on-fetch="(data) => (areRows = !!data.length)"
|
|
@save-changes="setTaxableBase"
|
|
:columns="columns"
|
|
:is-editable="true"
|
|
:table="{ selection: 'multiple', 'row-key': '$index' }"
|
|
footer
|
|
:right-search="false"
|
|
:column-search="false"
|
|
:disable-option="{ card: true }"
|
|
class="q-pa-none"
|
|
>
|
|
<template #column-footer-amount>
|
|
<QChip
|
|
dense
|
|
:color="noMatch ? 'negative' : 'transparent'"
|
|
class="q-pa-xs"
|
|
:title="noMatch ? t('invoiceIn.noMatch', { totalTaxableBase }) : ''"
|
|
>
|
|
{{ toCurrency(totalAmount) }}
|
|
</QChip>
|
|
</template>
|
|
<template #column-footer-foreignValue>
|
|
<template v-if="isNotEuro(currency)">
|
|
{{
|
|
getTotal(tableRows, 'foreignValue', {
|
|
currency: currency,
|
|
})
|
|
}}
|
|
</template>
|
|
</template>
|
|
</VnTable>
|
|
<QPageSticky :offset="[20, 20]" style="z-index: 2">
|
|
<QBtn
|
|
@click="
|
|
() => {
|
|
if (!areRows) return insert();
|
|
|
|
invoiceInDueDayTableRef.create = {
|
|
urlCreate: 'InvoiceInDueDays',
|
|
onDataSaved: () => invoiceInDueDayTableRef.reload(),
|
|
title: t('Create due day'),
|
|
formInitialData: {
|
|
invoiceInFk: invoiceId,
|
|
dueDated: Date.vnNew(),
|
|
amount: (totalTaxableBase - totalAmount).toFixed(2),
|
|
},
|
|
};
|
|
invoiceInDueDayTableRef.showForm = true;
|
|
}
|
|
"
|
|
color="primary"
|
|
fab
|
|
icon="add"
|
|
v-shortcut="'+'"
|
|
data-cy="invoiceInDueDayAdd"
|
|
/>
|
|
<QTooltip class="text-no-wrap">
|
|
{{ t('Create due day') }}
|
|
</QTooltip>
|
|
</QPageSticky>
|
|
</div>
|
|
</template>
|
|
<style lang="scss" scoped>
|
|
.q-chip {
|
|
color: var(--vn-text-color);
|
|
}
|
|
|
|
.invoice-in-due-day {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
:deep(.full-width) {
|
|
max-width: 900px;
|
|
}
|
|
</style>
|
|
<i18n>
|
|
es:
|
|
Date: Fecha
|
|
Bank: Caja
|
|
Amount: Importe
|
|
Foreign value: Divisa
|
|
invoiceIn.noMatch: El total {totalTaxableBase} no coincide con el importe
|
|
Create due day: Crear Vencimiento
|
|
</i18n>
|