+
@@ -19,7 +19,4 @@ const $props = defineProps({
a {
font-size: large;
}
-.titleBox {
- padding-bottom: 2%;
-}
diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue
index d2ba21888..0e74016cd 100644
--- a/src/components/ui/CardDescriptor.vue
+++ b/src/components/ui/CardDescriptor.vue
@@ -5,6 +5,7 @@ import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
import { useArrayData } from 'composables/useArrayData';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { useState } from 'src/composables/useState';
+import { useRoute } from 'vue-router';
const $props = defineProps({
url: {
@@ -15,21 +16,21 @@ const $props = defineProps({
type: Object,
default: null,
},
- module: {
- type: String,
- required: true,
- },
title: {
type: String,
default: '',
},
subtitle: {
type: Number,
- default: 0,
+ default: null,
},
dataKey: {
type: String,
- default: '',
+ default: null,
+ },
+ module: {
+ type: String,
+ default: null,
},
summary: {
type: Object,
@@ -40,21 +41,27 @@ const $props = defineProps({
const state = useState();
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
-const arrayData = useArrayData($props.dataKey || $props.module, {
- url: $props.url,
- filter: $props.filter,
- skip: 0,
-});
-const { store } = arrayData;
-const entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
+let arrayData;
+let store;
+let entity;
const isLoading = ref(false);
-defineExpose({
- getData,
-});
+defineExpose({ getData });
+
onBeforeMount(async () => {
- await getData();
- watch($props, async () => await getData());
+ arrayData = useArrayData($props.dataKey, {
+ url: $props.url,
+ filter: $props.filter,
+ skip: 0,
+ });
+ store = arrayData.store;
+ entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
+ // It enables to load data only once if the module is the same as the dataKey
+ if ($props.dataKey !== useRoute().meta.moduleName) await getData();
+ watch(
+ () => [$props.url, $props.filter],
+ async () => await getData()
+ );
});
async function getData() {
@@ -132,7 +139,7 @@ const emit = defineEmits(['onFetch']);
- {{ $props.title }}
+ {{ entity[title] ?? $props.title }}
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index ef7fb0ae6..95bd871aa 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -24,6 +24,7 @@ globals:
create: Create
edit: Edit
save: Save
+ saveAndContinue: Save and continue
remove: Remove
reset: Reset
close: Close
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index d78e1762c..0cbcc984b 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -24,6 +24,7 @@ globals:
create: Crear
edit: Modificar
save: Guardar
+ saveAndContinue: Guardar y continuar
remove: Eliminar
reset: Restaurar
close: Cerrar
diff --git a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
index a963f1792..bd7d758b4 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInBasicData.vue
@@ -9,18 +9,21 @@ import { downloadFile } from 'src/composables/downloadFile';
import FormModel from 'components/FormModel.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import FetchData from 'src/components/FetchData.vue';
-import VnRow from 'src/components/ui/VnRow.vue';
+import VnRow from 'components/ui/VnRow.vue';
+import VnInputDate from 'src/components/common/VnInputDate.vue';
+import VnInput from 'src/components/common/VnInput.vue';
const quasar = useQuasar();
-const route = useRoute();
const { t } = useI18n();
const dms = ref({});
+const route = useRoute();
const editDownloadDisabled = ref(false);
-const arrayData = useArrayData('InvoiceIn');
-const invoiceIn = computed(() => arrayData.store.data);
+const invoiceIn = computed(() => useArrayData(route.meta.moduleName).store.data);
const userConfig = ref(null);
+const invoiceId = computed(() => +route.params.id);
+const expenses = ref([]);
const currencies = ref([]);
const currenciesRef = ref();
const companies = ref([]);
@@ -31,14 +34,11 @@ const warehouses = ref([]);
const warehousesRef = ref();
const allowTypesRef = ref();
const allowedContentTypes = ref([]);
+const sageWithholdings = ref([]);
const inputFileRef = ref();
const editDmsRef = ref();
const createDmsRef = ref();
-const requiredFieldRule = (val) => val || t('globals.requiredField');
-const dateMask = '####-##-##';
-const fillMask = '_';
-
async function checkFileExists(dmsId) {
if (!dmsId) return;
try {
@@ -173,11 +173,17 @@ async function upsert() {
@on-fetch="(data) => (userConfig = data)"
auto-load
/>
+ (expenses = data)" />
+ (sageWithholdings = data)"
+ />
@@ -201,7 +207,7 @@ async function upsert() {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+ />
-
-
+
+
+ {{ `${scope.opt.id}: ${scope.opt.name}` }}
+
+
+
+ {{ t('Create document') }}
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
+
+
+
@@ -411,7 +330,7 @@ async function upsert() {
-
-
@@ -522,7 +441,7 @@ async function upsert() {
-
@@ -545,7 +464,7 @@ async function upsert() {
:options="warehouses"
option-value="id"
option-label="name"
- :rules="[requiredFieldRule]"
+ :required="true"
/>
-
import { ref, computed } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
+import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useArrayData } from 'src/composables/useArrayData';
import { useCapitalize } from 'src/composables/useCapitalize';
@@ -8,12 +8,11 @@ import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
-const router = useRouter();
-const route = useRoute();
+const { push, currentRoute } = useRouter();
const { t } = useI18n();
-const invoiceId = route.params.id;
-const arrayData = useArrayData('InvoiceIn');
+const invoiceId = +currentRoute.value.params.id;
+const arrayData = useArrayData(currentRoute.value.meta.moduleName);
const invoiceIn = computed(() => arrayData.store.data);
const invoiceInCorrectionRef = ref();
const filter = {
@@ -74,7 +73,7 @@ const rowsSelected = ref([]);
const requiredFieldRule = (val) => val || t('globals.requiredField');
-const onSave = (data) => data.deletes && router.push(`/invoice-in/${invoiceId}/summary`);
+const onSave = (data) => data.deletes && push(`/invoice-in/${invoiceId}/summary`);
-import { ref, reactive, computed, onBeforeMount, watch } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
+import { ref, reactive, computed, onBeforeMount } from 'vue';
+import { useRouter, onBeforeRouteLeave } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import axios from 'axios';
import { toCurrency, toDate } from 'src/filters';
import { useRole } from 'src/composables/useRole';
-import useCardDescription from 'src/composables/useCardDescription';
import { downloadFile } from 'src/composables/downloadFile';
import { useArrayData } from 'src/composables/useArrayData';
import { usePrintService } from 'composables/usePrintService';
@@ -17,27 +16,23 @@ import SendEmailDialog from 'components/common/SendEmailDialog.vue';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import { useCapitalize } from 'src/composables/useCapitalize';
+import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
+import InvoiceInToBook from '../InvoiceInToBook.vue';
-const $props = defineProps({
- id: {
- type: Number,
- required: false,
- default: null,
- },
-});
+const $props = defineProps({ id: { type: Number, default: null } });
+
+const { push, currentRoute } = useRouter();
-const route = useRoute();
-const router = useRouter();
const quasar = useQuasar();
const { hasAny } = useRole();
const { t } = useI18n();
const { openReport, sendEmail } = usePrintService();
-const arrayData = useArrayData('InvoiceIn');
+const { store } = useArrayData(currentRoute.value.meta.moduleName);
-const invoiceIn = computed(() => arrayData.store.data);
+const invoiceIn = computed(() => store.data);
const cardDescriptorRef = ref();
const correctionDialogRef = ref();
-const entityId = computed(() => $props.id || +route.params.id);
+const entityId = computed(() => $props.id || +currentRoute.value.params.id);
const totalAmount = ref();
const currentAction = ref();
const config = ref();
@@ -45,28 +40,21 @@ const cplusRectificationTypes = ref([]);
const siiTypeInvoiceOuts = ref([]);
const invoiceCorrectionTypes = ref([]);
const actions = {
- book: {
- title: 'Are you sure you want to book this invoice?',
- cb: checkToBook,
- action: toBook,
+ unbook: {
+ title: t('assertAction', { action: t('unbook') }),
+ action: toUnbook,
},
delete: {
- title: 'Are you sure you want to delete this invoice?',
+ title: t('assertAction', { action: t('delete') }),
action: deleteInvoice,
},
clone: {
- title: 'Are you sure you want to clone this invoice?',
+ title: t('assertAction', { action: t('clone') }),
action: cloneInvoice,
},
- showPdf: {
- cb: showPdfInvoice,
- },
- sendPdf: {
- cb: sendPdfInvoiceConfirmation,
- },
- correct: {
- cb: () => correctionDialogRef.value.show(),
- },
+ showPdf: { cb: showPdfInvoice },
+ sendPdf: { cb: sendPdfInvoiceConfirmation },
+ correct: { cb: () => correctionDialogRef.value.show() },
};
const filter = {
include: [
@@ -94,11 +82,7 @@ const filter = {
},
],
};
-const data = ref(useCardDescription());
-const invoiceInCorrection = reactive({
- correcting: [],
- corrected: null,
-});
+const invoiceInCorrection = reactive({ correcting: [], corrected: null });
const routes = reactive({
getSupplier: (id) => {
return { name: 'SupplierCard', params: { id } };
@@ -139,16 +123,17 @@ const correctionFormData = reactive({
});
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
-onBeforeMount(async () => await setInvoiceCorrection(entityId.value));
+onBeforeMount(async () => {
+ await setInvoiceCorrection(entityId.value);
+ const { data } = await axios.get(`InvoiceIns/${entityId.value}/getTotals`);
+ totalAmount.value = data.totalDueDay;
+});
-watch(
- () => route.params.id,
- async (newId) => {
- invoiceInCorrection.correcting.length = 0;
- invoiceInCorrection.corrected = null;
- if (newId) await setInvoiceCorrection(entityId.value);
- }
-);
+onBeforeRouteLeave(async (to, from) => {
+ invoiceInCorrection.correcting.length = 0;
+ invoiceInCorrection.corrected = null;
+ if (to.params.id !== from.params.id) await setInvoiceCorrection(entityId.value);
+});
async function setInvoiceCorrection(id) {
const [{ data: correctingData }, { data: correctedData }] = await Promise.all([
@@ -179,17 +164,6 @@ async function setInvoiceCorrection(id) {
);
}
-async function setData(entity) {
- data.value = useCardDescription(entity.supplierRef, entity.id);
- const { totalDueDay } = await getTotals();
- totalAmount.value = totalDueDay;
-}
-
-async function getTotals() {
- const { data } = await axios.get(`InvoiceIns/${entityId.value}/getTotals`);
- return data;
-}
-
function openDialog() {
quasar.dialog({
component: VnConfirm,
@@ -200,38 +174,17 @@ function openDialog() {
});
}
-async function checkToBook() {
- let directBooking = true;
+async function toUnbook() {
+ const { data } = await axios.post(`InvoiceIns/${entityId.value}/toUnbook`);
+ const { isLinked, bookEntry, accountingEntries } = data;
- const totals = await getTotals();
- const taxableBaseNotEqualDueDay = totals.totalDueDay != totals.totalTaxableBase;
- const vatNotEqualDueDay = totals.totalDueDay != totals.totalVat;
+ const type = isLinked ? 'warning' : 'positive';
+ const message = isLinked
+ ? t('isLinked', { bookEntry, accountingEntries })
+ : t('isNotLinked', { bookEntry });
- if (taxableBaseNotEqualDueDay && vatNotEqualDueDay) directBooking = false;
-
- const { data: dueDaysCount } = await axios.get('InvoiceInDueDays/count', {
- where: {
- invoiceInFk: entityId.value,
- dueDated: { gte: Date.vnNew() },
- },
- });
-
- if (dueDaysCount) directBooking = false;
-
- if (!directBooking) openDialog();
- else toBook();
-}
-
-async function toBook() {
- await axios.post(`InvoiceIns/${entityId.value}/toBook`);
-
- quasar.notify({
- type: 'positive',
- message: t('globals.dataSaved'),
- });
-
- await cardDescriptorRef.value.getData();
- setTimeout(() => location.reload(), 500);
+ quasar.notify({ type, message });
+ if (!isLinked) store.data.isBooked = false;
}
async function deleteInvoice() {
@@ -240,7 +193,7 @@ async function deleteInvoice() {
type: 'positive',
message: t('Invoice deleted'),
});
- router.push({ path: '/invoice-in' });
+ push({ path: '/invoice-in' });
}
async function cloneInvoice() {
@@ -249,11 +202,9 @@ async function cloneInvoice() {
type: 'positive',
message: t('Invoice cloned'),
});
- router.push({ path: `/invoice-in/${data.id}/summary` });
+ push({ path: `/invoice-in/${data.id}/summary` });
}
-const requiredFieldRule = (val) => val || t('globals.requiredField');
-
const isAdministrative = () => hasAny(['administrative']);
const isAgricultural = () =>
@@ -299,10 +250,9 @@ const createInvoiceInCorrection = async () => {
'InvoiceIns/corrective',
Object.assign(correctionFormData, { id: entityId.value })
);
- router.push({ path: `/invoice-in/${correctingId}/summary` });
+ push({ path: `/invoice-in/${correctingId}/summary` });
};
-
{
+
+
+
+ {{ t('To book') }}
+
+
+
- {{ t('To book') }}
+
+ {{ t('To unbook') }}
+
{
>
{{ t('components.smartCard.downloadFile') }}
-
- {{ t('components.smartCard.downloadFile') }}
-
-
+
+
+
+ {{ entity?.supplier?.nickname }}
+
+
+
+
-
+
{
:options="siiTypeInvoiceOuts"
option-value="id"
option-label="code"
- :rules="[requiredFieldRule]"
+ :required="true"
/>
@@ -496,7 +457,7 @@ const createInvoiceInCorrection = async () => {
:options="cplusRectificationTypes"
option-value="id"
option-label="description"
- :rules="[requiredFieldRule]"
+ :required="true"
/>
{
:options="invoiceCorrectionTypes"
option-value="id"
option-label="description"
- :rules="[requiredFieldRule]"
+ :required="true"
/>
@@ -544,11 +505,18 @@ const createInvoiceInCorrection = async () => {
}
+en:
+ isNotLinked: The entry {bookEntry} has been deleted with {accountingEntries} entries
+ isLinked: The entry {bookEntry} has been linked to Sage. Please contact administration for further information
+ assertAction: Are you sure you want to {action} this invoice?
es:
+ book: asentar
+ unbook: desasentar
+ delete: eliminar
+ clone: clonar
To book: Contabilizar
- Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
+ To unbook: Descontabilizar
Delete invoice: Eliminar factura
- Are you sure you want to delete this invoice?: Estas seguro de querer eliminar esta factura?
Invoice deleted: Factura eliminada
Clone invoice: Clonar factura
Invoice cloned: Factura clonada
@@ -560,4 +528,7 @@ es:
Rectificative invoice: Factura rectificativa
Original invoice: Factura origen
Entry: entrada
+ isNotLinked: Se ha eliminado el asiento nº {bookEntry} con {accountingEntries} apuntes
+ isLinked: El asiento {bookEntry} fue enlazado a Sage, por favor contacta con administración
+ assertAction: Estas seguro de querer {action} esta factura?
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
index 0e68b740f..de59b142e 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
@@ -9,24 +9,21 @@ import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue';
+import { toCurrency } from 'src/filters';
const route = useRoute();
const { t } = useI18n();
-const arrayData = useArrayData('InvoiceIn');
+const arrayData = useArrayData(route.meta.moduleName);
const invoiceIn = computed(() => arrayData.store.data);
const rowsSelected = ref([]);
const banks = ref([]);
const invoiceInFormRef = ref();
-const invoiceId = route.params.id;
+const invoiceId = +route.params.id;
const placeholder = 'yyyy/mm/dd';
-const filter = {
- where: {
- invoiceInFk: invoiceId,
- },
-};
+const filter = { where: { invoiceInFk: invoiceId } };
const columns = computed(() => [
{
@@ -73,6 +70,7 @@ async function insert() {
await axios.post('/InvoiceInDueDays/new', { id: +invoiceId });
await invoiceInFormRef.value.reload();
}
+const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, 0);
+
+
+
+
+
+
+ {{
+ toCurrency(getTotalAmount(rows), invoiceIn.currency.code)
+ }}
+
+
+
+
@@ -294,7 +305,11 @@ async function insert() {
-
+
es:
Date: Fecha
diff --git a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
index 6bdc1c0b5..1d1205d9e 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue
@@ -6,26 +6,21 @@ import { toCurrency } from 'src/filters';
import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
+import { useArrayData } from 'src/composables/useArrayData';
const { t } = useI18n();
-const route = useRoute();
+const route = useRoute();
+const currency = computed(
+ () => useArrayData(route.meta.moduleName).store.data?.currency?.code
+);
const invoceInIntrastat = ref([]);
-const amountTotal = computed(() => getTotal('amount'));
-const netTotal = computed(() => getTotal('net'));
-const stemsTotal = computed(() => getTotal('stems'));
const rowsSelected = ref([]);
const countries = ref([]);
const intrastats = ref([]);
const invoiceInFormRef = ref();
-
-const filter = {
- where: {
- invoiceInFk: route.params.id,
- },
-};
-
+const invoiceInId = computed(() => +route.params.id);
+const filter = { where: { invoiceInFk: invoiceInId.value } };
const columns = computed(() => [
{
name: 'code',
@@ -77,13 +72,8 @@ const columns = computed(() => [
},
]);
-function getTotal(type) {
- if (!invoceInIntrastat.value.length) return 0.0;
- return invoceInIntrastat.value.reduce(
- (total, intrastat) => total + intrastat[type],
- 0.0
- );
-}
+const getTotal = (data, key) =>
+ data.reduce((acc, cur) => acc + +String(cur[key]).replace(',', '.'), 0);
(intrastats = data)"
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
(invoceInIntrastat = data)"
@@ -172,6 +144,22 @@ function getTotal(type) {
/>
+
+
+
+
+
+ {{ toCurrency(getTotal(rows, 'amount'), currency) }}
+
+
+ {{ getTotal(rows, 'net') }}
+
+
+ {{ getTotal(rows, 'stems') }}
+
+
+
+
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index d58dad2b4..3ee90b5c2 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -3,32 +3,24 @@ 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';
-onMounted(async () => {
- salixUrl.value = await getUrl('');
- invoiceInUrl.value = salixUrl.value + `invoiceIn/${entityId.value}/`;
-});
-
-const route = useRoute();
+const props = defineProps({ id: { type: [Number, String], default: 0 } });
const { t } = useI18n();
+const route = useRoute();
-const $props = defineProps({
- id: {
- type: Number,
- default: 0,
- },
-});
-
-const entityId = computed(() => $props.id || route.params.id);
-
-const salixUrl = ref();
+const entityId = computed(() => props.id || +route.params.id);
+const invoiceIn = computed(() => useArrayData(route.meta.moduleName).store.data);
+const currency = computed(() => invoiceIn.value?.currency?.code);
const invoiceInUrl = ref();
const amountsNotMatch = ref(null);
-const intrastatTotals = ref({});
+const intrastatTotals = ref({ amount: 0, net: 0, stems: 0 });
const vatColumns = ref([
{
@@ -42,14 +34,16 @@ const vatColumns = ref([
name: 'landed',
label: 'invoiceIn.summary.taxableBase',
field: (row) => row.taxableBase,
- format: (value) => toCurrency(value),
+ format: (value) => toCurrency(value, currency.value),
sortable: true,
align: 'left',
},
{
name: 'vat',
label: 'invoiceIn.summary.sageVat',
- field: (row) => row.taxTypeSage?.vat,
+ field: (row) => {
+ if (row.taxTypeSage) return `#${row.taxTypeSage.id} : ${row.taxTypeSage.vat}`;
+ },
format: (value) => value,
sortable: true,
align: 'left',
@@ -57,7 +51,10 @@ const vatColumns = ref([
{
name: 'transaction',
label: 'invoiceIn.summary.sageTransaction',
- field: (row) => row.transactionTypeSage?.transaction,
+ field: (row) => {
+ if (row.transactionTypeSage)
+ return `#${row.transactionTypeSage.id} : ${row.transactionTypeSage?.transaction}`;
+ },
format: (value) => value,
sortable: true,
align: 'left',
@@ -66,9 +63,9 @@ const vatColumns = ref([
name: 'rate',
label: 'invoiceIn.summary.rate',
field: (row) => taxRate(row.taxableBase, row.taxTypeSage?.rate),
- format: (value) => toCurrency(value),
+ format: (value) => toCurrency(value, currency.value),
sortable: true,
- align: 'left',
+ align: 'center',
},
{
name: 'currency',
@@ -99,7 +96,7 @@ const dueDayColumns = ref([
name: 'amount',
label: 'invoiceIn.summary.amount',
field: (row) => row.amount,
- format: (value) => toCurrency(value),
+ format: (value) => toCurrency(value, currency.value),
sortable: true,
align: 'left',
},
@@ -122,13 +119,15 @@ const intrastatColumns = ref([
},
sortable: true,
align: 'left',
+ style: 'width: 10px',
},
{
name: 'amount',
label: 'invoiceIn.summary.amount',
- field: (row) => toCurrency(row.amount),
+ field: (row) => toCurrency(row.amount, currency.value),
sortable: true,
align: 'left',
+ style: 'width: 10px',
},
{
name: 'net',
@@ -155,58 +154,55 @@ const intrastatColumns = ref([
},
]);
-function getAmountNotMatch(totals) {
- return (
+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
- );
-}
+ totals.totalDueDay != totals.totalVat;
-function getIntrastatTotals(intrastat) {
- const totals = {
- amount: intrastat.reduce((acc, cur) => acc + cur.amount, 0),
- net: intrastat.reduce((acc, cur) => acc + cur.net, 0),
- stems: intrastat.reduce((acc, cur) => acc + cur.stems, 0),
- };
+ invoiceInIntrastat.forEach((val) => {
+ intrastatTotals.value.amount += val.amount;
+ intrastatTotals.value.net += val.net;
+ intrastatTotals.value.stems += val.stems;
+ });
+};
- return totals;
-}
+const taxRate = (taxableBase = 0, rate = 0) => (rate / 100) * taxableBase;
-function getTaxTotal(tax) {
- return tax.reduce(
- (acc, cur) => acc + taxRate(cur.taxableBase, cur.taxTypeSage?.rate),
- 0
- );
-}
+const getTotalTax = (tax) =>
+ tax.reduce((acc, cur) => acc + taxRate(cur.taxableBase, cur.taxTypeSage?.rate), 0);
-function setData(entity) {
- if (!entity) return false;
-
- amountsNotMatch.value = getAmountNotMatch(entity.totals);
-
- if (entity.invoiceInIntrastat.length)
- intrastatTotals.value = { ...getIntrastatTotals(entity.invoiceInIntrastat) };
-}
-
-function taxRate(taxableBase = 0, rate = 0) {
- return (rate / 100) * taxableBase;
-}
-
-function getLink(param) {
- return `#/invoice-in/${entityId.value}/${param}`;
-}
+const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
setData(data)"
+ @on-fetch="(data) => init(data)"
>
-
- {{ invoiceIn.id }} - {{ invoiceIn.supplier?.name }}
+
+ {{ entity.id }} - {{ entity.supplier?.name }}
-
+
+
+
+
+
+
+
+
@@ -217,19 +213,26 @@ function getLink(param) {
+ :value="entity.supplier?.name"
+ >
+
+
+ {{ entity.supplier?.name }}
+
+
+
+
@@ -242,19 +245,19 @@ function getLink(param) {
@@ -266,20 +269,19 @@ function getLink(param) {
-
@@ -290,58 +292,62 @@ function getLink(param) {
/>
-
-
-
-
-
-
- {{ toCurrency(invoiceIn.totals.totalDueDay) }}
-
-
-
-
+
+
+
+
+
+ {{ toCurrency(entity.totals.totalDueDay, currency) }}
+
+
+
-
+
-
-
-
+
+
+
{{ t(col.label) }}
-
- {{ toCurrency(invoiceIn.totals.totalTaxableBase) }}
-
{{
- toCurrency(getTaxTotal(invoiceIn.invoiceInTax))
+ toCurrency(entity.totals.totalTaxableBase, currency)
+ }}
+
+
+ {{
+ toCurrency(getTotalTax(entity.invoiceInTax, currency))
}}
@@ -349,17 +355,17 @@ function getLink(param) {
-
+
-
-
-
-
+
+
+
+
{{ t(col.label) }}
@@ -368,26 +374,32 @@ function getLink(param) {
- {{ toCurrency(invoiceIn.totals.totalDueDay) }}
+
+ {{ toCurrency(entity.totals.totalDueDay, currency) }}
+
-
+
-
-
-
+
+
+
{{ t(col.label) }}
@@ -395,7 +407,7 @@ function getLink(param) {
- {{ toCurrency(intrastatTotals.amount) }}
+ {{ toCurrency(intrastatTotals.amount, currency) }}
{{ intrastatTotals.net }}
{{ intrastatTotals.stems }}
@@ -410,13 +422,28 @@ function getLink(param) {
.bg {
background-color: var(--vn-accent-color);
}
-.bordered {
- border: 1px solid var(--vn-text-color);
- max-width: 18em;
+@media (min-width: $breakpoint-md) {
+ .summaryBody {
+ .vat {
+ flex: 65%;
+ }
+
+ .due-day {
+ flex: 30%;
+ }
+ .vat,
+ .due-day {
+ .q-table th {
+ padding-right: 0;
+ }
+ }
+ }
}
es:
Search invoice: Buscar factura recibida
You can search by invoice reference: Puedes buscar por referencia de la factura
+ Totals: Totales
+ To book: Contabilizar
diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
index ae3aa9349..6fc844eff 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
@@ -11,13 +11,14 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import CrudModel from 'src/components/CrudModel.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue';
-const route = useRoute();
+const router = useRoute();
const { t } = useI18n();
const quasar = useQuasar();
-const arrayData = useArrayData('InvoiceIn');
+const arrayData = useArrayData(router.meta.moduleName);
const invoiceIn = computed(() => arrayData.store.data);
-
+const invoiceId = +router.params.id;
+const currency = computed(() => invoiceIn.value?.currency?.code);
const expenses = ref([]);
const sageTaxTypes = ref([]);
const sageTransactionTypes = ref([]);
@@ -55,7 +56,7 @@ const columns = computed(() => [
{
name: 'taxablebase',
label: t('Taxable base'),
- field: (row) => toCurrency(row.taxableBase),
+ field: (row) => toCurrency(row.taxableBase, currency.value),
model: 'taxableBase',
sortable: true,
tabIndex: 2,
@@ -68,7 +69,7 @@ const columns = computed(() => [
options: sageTaxTypes.value,
model: 'taxTypeSageFk',
optionValue: 'id',
- optionLabel: 'vat',
+ optionLabel: 'id',
sortable: true,
tabindex: 3,
align: 'left',
@@ -80,7 +81,7 @@ const columns = computed(() => [
options: sageTransactionTypes.value,
model: 'transactionTypeSageFk',
optionValue: 'id',
- optionLabel: 'transaction',
+ optionLabel: 'id',
sortable: true,
tabIndex: 4,
align: 'left',
@@ -90,7 +91,7 @@ const columns = computed(() => [
label: t('Rate'),
sortable: true,
tabIndex: 5,
- field: (row) => toCurrency(taxRate(row, row.taxTypeSageFk)),
+ field: (row) => toCurrency(taxRate(row, row.taxTypeSageFk), currency.value),
align: 'left',
},
{
@@ -114,7 +115,7 @@ const filter = {
'transactionTypeSageFk',
],
where: {
- invoiceInFk: route.params.id,
+ invoiceInFk: invoiceId,
},
};
@@ -161,6 +162,9 @@ async function addExpense() {
});
}
}
+const getTotalTaxableBase = (rows) =>
+ rows.reduce((acc, { taxableBase }) => acc + +taxableBase, 0);
+const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0);
@@ -303,6 +308,19 @@ async function addExpense() {
/>
+
+
+
+
+
+ {{ toCurrency(getTotalTaxableBase(rows), currency) }}
+
+
+
+ {{ toCurrency(getTotalRate(rows), currency) }}
+
+
+
@@ -391,7 +409,7 @@ async function addExpense() {
- {{ toCurrency(taxRate(props.row)) }}
+ {{ toCurrency(taxRate(props.row), currency) }}