Compare commits

..

8 Commits

Author SHA1 Message Date
PAU ROVIRA ROSALENY e41ed4eff5 Merge branch 'dev' into 7065-testUserPanel
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-07 09:39:35 +00:00
PAU ROVIRA ROSALENY be894f52c1 Merge branch 'dev' into 7065-testUserPanel
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-07 07:51:49 +00:00
PAU ROVIRA ROSALENY e77e96ffed Merge branch 'dev' into 7065-testUserPanel
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-07 06:02:05 +00:00
PAU ROVIRA ROSALENY 035979cb70 Merge branch 'dev' into 7065-testUserPanel
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-06 11:09:59 +00:00
PAU ROVIRA ROSALENY 828bb61f52 Merge branch 'dev' into 7065-testUserPanel
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-06 09:51:52 +00:00
PAU ROVIRA ROSALENY 9767668798 Merge branch 'dev' into 7065-testUserPanel
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-06 09:33:05 +00:00
PAU ROVIRA ROSALENY 4ad2f936e8 Merge branch 'dev' into 7065-testUserPanel
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-06 07:44:51 +00:00
PAU ROVIRA ROSALENY 85140999ab Actualizar src/components/__tests__/UserPanel.spec.js
gitea/salix-front/pipeline/pr-dev This commit looks good Details
2025-02-06 06:56:29 +00:00
15 changed files with 133 additions and 194 deletions

View File

@ -1,61 +1,65 @@
import { vi, describe, expect, it, beforeEach, beforeAll, afterEach } from 'vitest'; import { vi, describe, expect, it, beforeEach, afterEach } from 'vitest';
import { createWrapper } from 'app/test/vitest/helper'; import { createWrapper } from 'app/test/vitest/helper';
import UserPanel from 'src/components/UserPanel.vue'; import UserPanel from 'src/components/UserPanel.vue';
import axios from 'axios'; import axios from 'axios';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
vi.mock('src/utils/quasarLang', () => ({
default: vi.fn(),
}));
describe('UserPanel', () => { describe('UserPanel', () => {
let wrapper; let wrapper;
let vm; let vm;
let state; let state;
beforeEach(() => { beforeEach(() => {
wrapper = createWrapper(UserPanel, {}); wrapper = createWrapper(UserPanel, {});
state = useState(); state = useState();
state.setUser({ state.setUser({
id: 115, id: 115,
name: 'itmanagement', name: 'itmanagement',
nickname: 'itManagementNick', nickname: 'itManagementNick',
lang: 'en', lang: 'en',
darkMode: false, darkMode: false,
companyFk: 442, companyFk: 442,
warehouseFk: 1, warehouseFk: 1,
});
wrapper = wrapper.wrapper;
vm = wrapper.vm;
}); });
wrapper = wrapper.wrapper;
vm = wrapper.vm;
});
afterEach(() => { afterEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
}); });
it('should fetch warehouses data on mounted', async () => { it('should fetch warehouses data on mounted', async () => {
const fetchData = wrapper.findComponent({ name: 'FetchData' }); const fetchData = wrapper.findComponent({ name: 'FetchData' });
expect(fetchData.props('url')).toBe('Warehouses'); expect(fetchData.props('url')).toBe('Warehouses');
expect(fetchData.props('autoLoad')).toBe(true); expect(fetchData.props('autoLoad')).toBe(true);
}); });
it('should toggle dark mode correctly and update preferences', async () => { it('should toggle dark mode correctly and update preferences', async () => {
await vm.saveDarkMode(true); await vm.saveDarkMode(true);
expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true }); expect(axios.patch).toHaveBeenCalledWith('/UserConfigs/115', { darkMode: true });
expect(vm.user.darkMode).toBe(true); expect(vm.user.darkMode).toBe(true);
vm.updatePreferences(); await vm.updatePreferences();
expect(vm.darkMode).toBe(true); expect(vm.darkMode).toBe(true);
}); });
it('should change user language and update preferences', async () => { it('should change user language and update preferences', async () => {
const userLanguage = 'es'; const userLanguage = 'es';
await vm.saveLanguage(userLanguage); await vm.saveLanguage(userLanguage);
expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage }); expect(axios.patch).toHaveBeenCalledWith('/VnUsers/115', { lang: userLanguage });
expect(vm.user.lang).toBe(userLanguage); expect(vm.user.lang).toBe(userLanguage);
vm.updatePreferences(); await vm.updatePreferences();
expect(vm.locale).toBe(userLanguage); expect(vm.locale).toBe(userLanguage);
}); });
it('should update user data', async () => { it('should update user data', async () => {
const key = 'name'; const key = 'name';
const value = 'itboss'; const value = 'itboss';
await vm.saveUserData(key, value); await vm.saveUserData(key, value);
expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value }); expect(axios.post).toHaveBeenCalledWith('UserConfigs/setUserConfig', { [key]: value });
}); });
}); });

View File

@ -171,8 +171,7 @@ onMounted(() => {
}); });
const arrayDataKey = const arrayDataKey =
$props.dataKey ?? $props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
($props.url?.length > 0 ? $props.url : ($attrs.name ?? $attrs.label));
const arrayData = useArrayData(arrayDataKey, { const arrayData = useArrayData(arrayDataKey, {
url: $props.url, url: $props.url,
@ -221,7 +220,7 @@ async function fetchFilter(val) {
optionFilterValue.value ?? optionFilterValue.value ??
(new RegExp(/\d/g).test(val) (new RegExp(/\d/g).test(val)
? optionValue.value ? optionValue.value
: (optionFilter.value ?? optionLabel.value)); : optionFilter.value ?? optionLabel.value);
let defaultWhere = {}; let defaultWhere = {};
if ($props.filterOptions.length) { if ($props.filterOptions.length) {
@ -240,7 +239,7 @@ async function fetchFilter(val) {
const { data } = await arrayData.applyFilter( const { data } = await arrayData.applyFilter(
{ filter: filterOptions }, { filter: filterOptions },
{ updateRouter: false }, { updateRouter: false }
); );
setOptions(data); setOptions(data);
return data; return data;
@ -273,7 +272,7 @@ async function filterHandler(val, update) {
ref.setOptionIndex(-1); ref.setOptionIndex(-1);
ref.moveOptionSelection(1, true); ref.moveOptionSelection(1, true);
} }
}, }
); );
} }
@ -309,7 +308,7 @@ function handleKeyDown(event) {
if (inputValue) { if (inputValue) {
const matchingOption = myOptions.value.find( const matchingOption = myOptions.value.find(
(option) => (option) =>
option[optionLabel.value].toLowerCase() === inputValue.toLowerCase(), option[optionLabel.value].toLowerCase() === inputValue.toLowerCase()
); );
if (matchingOption) { if (matchingOption) {
@ -321,11 +320,11 @@ function handleKeyDown(event) {
} }
const focusableElements = document.querySelectorAll( const focusableElements = document.querySelectorAll(
'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])', 'a:not([disabled]), button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])'
); );
const currentIndex = Array.prototype.indexOf.call( const currentIndex = Array.prototype.indexOf.call(
focusableElements, focusableElements,
event.target, event.target
); );
if (currentIndex >= 0 && currentIndex < focusableElements.length - 1) { if (currentIndex >= 0 && currentIndex < focusableElements.length - 1) {
focusableElements[currentIndex + 1].focus(); focusableElements[currentIndex + 1].focus();

View File

@ -1,7 +1,9 @@
<script setup> <script setup>
import { computed } from 'vue';
import VnSelect from 'components/common/VnSelect.vue'; import VnSelect from 'components/common/VnSelect.vue';
const model = defineModel({ type: [String, Number, Object] }); const model = defineModel({ type: [String, Number, Object] });
const url = 'Suppliers';
</script> </script>
<template> <template>
@ -9,11 +11,10 @@ const model = defineModel({ type: [String, Number, Object] });
:label="$t('globals.supplier')" :label="$t('globals.supplier')"
v-bind="$attrs" v-bind="$attrs"
v-model="model" v-model="model"
url="Suppliers" :url="url"
option-value="id" option-value="id"
option-label="nickname" option-label="nickname"
:fields="['id', 'name', 'nickname', 'nif']" :fields="['id', 'name', 'nickname', 'nif']"
:filter-options="['id', 'name', 'nickname', 'nif']"
sort-by="name ASC" sort-by="name ASC"
> >
<template #option="scope"> <template #option="scope">

View File

@ -352,7 +352,7 @@ globals:
from: Desde from: Desde
to: Hasta to: Hasta
supplierFk: Proveedor supplierFk: Proveedor
supplierRef: Nº factura supplierRef: Ref. proveedor
serial: Serie serial: Serie
amount: Importe amount: Importe
awbCode: AWB awbCode: AWB

View File

@ -125,7 +125,7 @@ function deleteFile(dmsFk) {
<VnInput <VnInput
clearable clearable
clear-icon="close" clear-icon="close"
:label="t('invoiceIn.supplierRef')" :label="t('Supplier ref')"
v-model="data.supplierRef" v-model="data.supplierRef"
/> />
</VnRow> </VnRow>
@ -310,6 +310,7 @@ function deleteFile(dmsFk) {
supplierFk: Supplier supplierFk: Supplier
es: es:
supplierFk: Proveedor supplierFk: Proveedor
Supplier ref: Ref. proveedor
Expedition date: Fecha expedición Expedition date: Fecha expedición
Operation date: Fecha operación Operation date: Fecha operación
Undeductible VAT: Iva no deducible Undeductible VAT: Iva no deducible

View File

@ -186,7 +186,7 @@ const createInvoiceInCorrection = async () => {
clickable clickable
@click="book(entityId)" @click="book(entityId)"
> >
<QItemSection>{{ t('invoiceIn.descriptorMenu.book') }}</QItemSection> <QItemSection>{{ t('invoiceIn.descriptorMenu.toBook') }}</QItemSection>
</QItem> </QItem>
</template> </template>
</InvoiceInToBook> </InvoiceInToBook>
@ -197,7 +197,7 @@ const createInvoiceInCorrection = async () => {
@click="triggerMenu('unbook')" @click="triggerMenu('unbook')"
> >
<QItemSection> <QItemSection>
{{ t('invoiceIn.descriptorMenu.unbook') }} {{ t('invoiceIn.descriptorMenu.toUnbook') }}
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem <QItem

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed, onBeforeMount } from 'vue'; import { ref, computed } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
@ -12,7 +12,6 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue'; import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import { toCurrency } from 'filters/index';
const route = useRoute(); const route = useRoute();
const { notify } = useNotify(); const { notify } = useNotify();
@ -27,7 +26,7 @@ const invoiceInFormRef = ref();
const invoiceId = +route.params.id; const invoiceId = +route.params.id;
const filter = { where: { invoiceInFk: invoiceId } }; const filter = { where: { invoiceInFk: invoiceId } };
const areRows = ref(false); const areRows = ref(false);
const totals = ref();
const columns = computed(() => [ const columns = computed(() => [
{ {
name: 'duedate', name: 'duedate',
@ -67,8 +66,6 @@ const columns = computed(() => [
}, },
]); ]);
const totalAmount = computed(() => getTotal(invoiceInFormRef.value.formData, 'amount'));
const isNotEuro = (code) => code != 'EUR'; const isNotEuro = (code) => code != 'EUR';
async function insert() { async function insert() {
@ -76,10 +73,6 @@ async function insert() {
await invoiceInFormRef.value.reload(); await invoiceInFormRef.value.reload();
notify(t('globals.dataSaved'), 'positive'); notify(t('globals.dataSaved'), 'positive');
} }
onBeforeMount(async () => {
totals.value = (await axios.get(`InvoiceIns/${invoiceId}/getTotals`)).data;
});
</script> </script>
<template> <template>
<FetchData <FetchData
@ -160,7 +153,7 @@ onBeforeMount(async () => {
<QTd /> <QTd />
<QTd /> <QTd />
<QTd> <QTd>
{{ toCurrency(totalAmount) }} {{ getTotal(rows, 'amount', { currency: 'default' }) }}
</QTd> </QTd>
<QTd> <QTd>
<template v-if="isNotEuro(invoiceIn.currency.code)"> <template v-if="isNotEuro(invoiceIn.currency.code)">
@ -242,16 +235,7 @@ onBeforeMount(async () => {
v-shortcut="'+'" v-shortcut="'+'"
size="lg" size="lg"
round round
@click=" @click="!areRows ? insert() : invoiceInFormRef.insert()"
() => {
if (!areRows) insert();
else
invoiceInFormRef.insert({
amount: (totals.totalTaxableBase - totalAmount).toFixed(2),
invoiceInFk: invoiceId,
});
}
"
/> />
</QPageSticky> </QPageSticky>
</template> </template>

View File

@ -193,7 +193,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
<InvoiceIntoBook> <InvoiceIntoBook>
<template #content="{ book }"> <template #content="{ book }">
<QBtn <QBtn
:label="t('Book')" :label="t('To book')"
color="orange-11" color="orange-11"
text-color="black" text-color="black"
@click="book(entityId)" @click="book(entityId)"
@ -224,7 +224,10 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
</span> </span>
</template> </template>
</VnLv> </VnLv>
<VnLv :label="t('invoiceIn.supplierRef')" :value="entity.supplierRef" /> <VnLv
:label="t('invoiceIn.list.supplierRef')"
:value="entity.supplierRef"
/>
<VnLv <VnLv
:label="t('invoiceIn.summary.currency')" :label="t('invoiceIn.summary.currency')"
:value="entity.currency?.code" :value="entity.currency?.code"
@ -354,7 +357,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
entity.totals.totalTaxableBaseForeignValue && entity.totals.totalTaxableBaseForeignValue &&
toCurrency( toCurrency(
entity.totals.totalTaxableBaseForeignValue, entity.totals.totalTaxableBaseForeignValue,
currency, currency
) )
}}</QTd> }}</QTd>
</QTr> </QTr>
@ -389,7 +392,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
entity.totals.totalDueDayForeignValue && entity.totals.totalDueDayForeignValue &&
toCurrency( toCurrency(
entity.totals.totalDueDayForeignValue, entity.totals.totalDueDayForeignValue,
currency, currency
) )
}} }}
</QTd> </QTd>
@ -469,5 +472,5 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
Search invoice: Buscar factura recibida Search invoice: Buscar factura recibida
You can search by invoice reference: Puedes buscar por referencia de la factura You can search by invoice reference: Puedes buscar por referencia de la factura
Totals: Totales Totals: Totales
Book: Contabilizar To book: Contabilizar
</i18n> </i18n>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed, nextTick } from 'vue'; import { ref, computed } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
@ -25,6 +25,7 @@ const sageTaxTypes = ref([]);
const sageTransactionTypes = ref([]); const sageTransactionTypes = ref([]);
const rowsSelected = ref([]); const rowsSelected = ref([]);
const invoiceInFormRef = ref(); const invoiceInFormRef = ref();
const expenseRef = ref();
defineProps({ defineProps({
actionIcon: { actionIcon: {
@ -96,20 +97,6 @@ const columns = computed(() => [
}, },
]); ]);
const taxableBaseTotal = computed(() => {
return getTotal(invoiceInFormRef.value.formData, 'taxableBase');
});
const taxRateTotal = computed(() => {
return getTotal(invoiceInFormRef.value.formData, null, {
cb: taxRate,
});
});
const combinedTotal = computed(() => {
return +taxableBaseTotal.value + +taxRateTotal.value;
});
const filter = { const filter = {
fields: [ fields: [
'id', 'id',
@ -138,7 +125,7 @@ function taxRate(invoiceInTax) {
return ((taxTypeSage / 100) * taxableBase).toFixed(2); return ((taxTypeSage / 100) * taxableBase).toFixed(2);
} }
function autocompleteExpense(evt, row, col, ref) { function autocompleteExpense(evt, row, col) {
const val = evt.target.value; const val = evt.target.value;
if (!val) return; if (!val) return;
@ -147,17 +134,22 @@ function autocompleteExpense(evt, row, col, ref) {
({ id }) => id == useAccountShortToStandard(param), ({ id }) => id == useAccountShortToStandard(param),
); );
ref.vnSelectDialogRef.vnSelectRef.toggleOption(lookup); expenseRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
} }
function setCursor(ref) { const taxableBaseTotal = computed(() => {
nextTick(() => { return getTotal(invoiceInFormRef.value.formData, 'taxableBase');
const select = ref.vnSelectDialogRef });
? ref.vnSelectDialogRef.vnSelectRef
: ref.vnSelectRef; const taxRateTotal = computed(() => {
select.$el.querySelector('input').setSelectionRange(0, 0); return getTotal(invoiceInFormRef.value.formData, null, {
cb: taxRate,
}); });
} });
const combinedTotal = computed(() => {
return +taxableBaseTotal.value + +taxRateTotal.value;
});
</script> </script>
<template> <template>
<FetchData <FetchData
@ -195,24 +187,14 @@ function setCursor(ref) {
<template #body-cell-expense="{ row, col }"> <template #body-cell-expense="{ row, col }">
<QTd> <QTd>
<VnSelectDialog <VnSelectDialog
:ref="`expenseRef-${row.$index}`" ref="expenseRef"
v-model="row[col.model]" v-model="row[col.model]"
:options="col.options" :options="col.options"
:option-value="col.optionValue" :option-value="col.optionValue"
:option-label="col.optionLabel" :option-label="col.optionLabel"
:filter-options="['id', 'name']" :filter-options="['id', 'name']"
:tooltip="t('Create a new expense')" :tooltip="t('Create a new expense')"
@keydown.tab=" @keydown.tab="autocompleteExpense($event, row, col)"
autocompleteExpense(
$event,
row,
col,
$refs[`expenseRef-${row.$index}`],
)
"
@update:model-value="
setCursor($refs[`expenseRef-${row.$index}`])
"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -228,7 +210,7 @@ function setCursor(ref) {
</QTd> </QTd>
</template> </template>
<template #body-cell-taxablebase="{ row }"> <template #body-cell-taxablebase="{ row }">
<QTd shrink> <QTd>
<VnInputNumber <VnInputNumber
clear-icon="close" clear-icon="close"
v-model="row.taxableBase" v-model="row.taxableBase"
@ -239,16 +221,12 @@ function setCursor(ref) {
<template #body-cell-sageiva="{ row, col }"> <template #body-cell-sageiva="{ row, col }">
<QTd> <QTd>
<VnSelect <VnSelect
:ref="`sageivaRef-${row.$index}`"
v-model="row[col.model]" v-model="row[col.model]"
:options="col.options" :options="col.options"
:option-value="col.optionValue" :option-value="col.optionValue"
:option-label="col.optionLabel" :option-label="col.optionLabel"
:filter-options="['id', 'vat']" :filter-options="['id', 'vat']"
data-cy="vat-sageiva" data-cy="vat-sageiva"
@update:model-value="
setCursor($refs[`sageivaRef-${row.$index}`])
"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -266,15 +244,11 @@ function setCursor(ref) {
<template #body-cell-sagetransaction="{ row, col }"> <template #body-cell-sagetransaction="{ row, col }">
<QTd> <QTd>
<VnSelect <VnSelect
:ref="`sagetransactionRef-${row.$index}`"
v-model="row[col.model]" v-model="row[col.model]"
:options="col.options" :options="col.options"
:option-value="col.optionValue" :option-value="col.optionValue"
:option-label="col.optionLabel" :option-label="col.optionLabel"
:filter-options="['id', 'transaction']" :filter-options="['id', 'transaction']"
@update:model-value="
setCursor($refs[`sagetransactionRef-${row.$index}`])
"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -292,7 +266,7 @@ function setCursor(ref) {
</QTd> </QTd>
</template> </template>
<template #body-cell-foreignvalue="{ row }"> <template #body-cell-foreignvalue="{ row }">
<QTd shrink> <QTd>
<VnInputNumber <VnInputNumber
:class="{ :class="{
'no-pointer-events': !isNotEuro(currency), 'no-pointer-events': !isNotEuro(currency),

View File

@ -56,7 +56,7 @@ const cols = computed(() => [
{ {
align: 'left', align: 'left',
name: 'supplierRef', name: 'supplierRef',
label: t('invoiceIn.supplierRef'), label: t('invoiceIn.list.supplierRef'),
}, },
{ {
align: 'left', align: 'left',
@ -177,7 +177,7 @@ const cols = computed(() => [
:required="true" :required="true"
/> />
<VnInput <VnInput
:label="t('invoiceIn.supplierRef')" :label="t('invoiceIn.list.supplierRef')"
v-model="data.supplierRef" v-model="data.supplierRef"
/> />
<VnSelect <VnSelect

View File

@ -4,7 +4,6 @@ import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnConfirm from 'src/components/ui/VnConfirm.vue'; import VnConfirm from 'src/components/ui/VnConfirm.vue';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import qs from 'qs';
const { notify, dialog } = useQuasar(); const { notify, dialog } = useQuasar();
const { t } = useI18n(); const { t } = useI18n();
@ -13,51 +12,29 @@ defineExpose({ checkToBook });
const { store } = useArrayData(); const { store } = useArrayData();
async function checkToBook(id) { async function checkToBook(id) {
let messages = []; let directBooking = true;
const hasProblemWithTax = (
await axios.get('InvoiceInTaxes/count', {
params: {
where: JSON.stringify({
invoiceInFk: id,
or: [{ taxTypeSageFk: null }, { transactionTypeSageFk: null }],
}),
},
})
).data?.count;
if (hasProblemWithTax)
messages.push(t('The VAT and Transaction fields have not been informed'));
const { data: totals } = await axios.get(`InvoiceIns/${id}/getTotals`); const { data: totals } = await axios.get(`InvoiceIns/${id}/getTotals`);
const taxableBaseNotEqualDueDay = totals.totalDueDay != totals.totalTaxableBase; const taxableBaseNotEqualDueDay = totals.totalDueDay != totals.totalTaxableBase;
const vatNotEqualDueDay = totals.totalDueDay != totals.totalVat; const vatNotEqualDueDay = totals.totalDueDay != totals.totalVat;
if (taxableBaseNotEqualDueDay && vatNotEqualDueDay) if (taxableBaseNotEqualDueDay && vatNotEqualDueDay) directBooking = false;
messages.push(t('The sum of the taxable bases does not match the due dates'));
const dueDaysCount = ( const { data: dueDaysCount } = await axios.get('InvoiceInDueDays/count', {
await axios.get('InvoiceInDueDays/count', { where: {
params: { invoiceInFk: id,
where: JSON.stringify({ dueDated: { gte: Date.vnNew() },
invoiceInFk: id, },
dueDated: { gte: Date.vnNew() }, });
}),
},
})
).data?.count;
if (dueDaysCount) messages.push(t('Some due dates are less than or equal to today')); if (dueDaysCount) directBooking = false;
if (!messages.length) toBook(id); if (directBooking) return toBook(id);
else
dialog({ dialog({
component: VnConfirm, component: VnConfirm,
componentProps: { componentProps: { title: t('Are you sure you want to book this invoice?') },
title: t('Are you sure you want to book this invoice?'), }).onOk(async () => await toBook(id));
message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''),
},
}).onOk(() => toBook(id));
} }
async function toBook(id) { async function toBook(id) {
@ -82,7 +59,4 @@ async function toBook(id) {
es: es:
Are you sure you want to book this invoice?: ¿Estás seguro de querer asentar esta factura? Are you sure you want to book this invoice?: ¿Estás seguro de querer asentar esta factura?
It was not able to book the invoice: No se pudo contabilizar la factura It was not able to book the invoice: No se pudo contabilizar la factura
Some due dates are less than or equal to today: Algún vencimiento tiene una fecha menor o igual que hoy
The sum of the taxable bases does not match the due dates: La suma de las bases imponibles no coincide con la de los vencimientos
The VAT and Transaction fields have not been informed: No se han informado los campos de iva y/o transacción
</i18n> </i18n>

View File

@ -3,10 +3,10 @@ invoiceIn:
searchInfo: Search incoming invoices by ID or supplier fiscal name searchInfo: Search incoming invoices by ID or supplier fiscal name
serial: Serial serial: Serial
isBooked: Is booked isBooked: Is booked
supplierRef: Invoice nº
list: list:
ref: Reference ref: Reference
supplier: Supplier supplier: Supplier
supplierRef: Supplier ref.
file: File file: File
issued: Issued issued: Issued
dueDated: Due dated dueDated: Due dated
@ -19,6 +19,8 @@ invoiceIn:
unbook: Unbook unbook: Unbook
delete: Delete delete: Delete
clone: Clone clone: Clone
toBook: To book
toUnbook: To unbook
deleteInvoice: Delete invoice deleteInvoice: Delete invoice
invoiceDeleted: invoice deleted invoiceDeleted: invoice deleted
cloneInvoice: Clone invoice cloneInvoice: Clone invoice
@ -68,3 +70,4 @@ invoiceIn:
isBooked: Is booked isBooked: Is booked
account: Ledger account account: Ledger account
correctingFk: Rectificative correctingFk: Rectificative

View File

@ -3,10 +3,10 @@ invoiceIn:
searchInfo: Buscar facturas recibidas por ID o nombre fiscal del proveedor searchInfo: Buscar facturas recibidas por ID o nombre fiscal del proveedor
serial: Serie serial: Serie
isBooked: Contabilizada isBooked: Contabilizada
supplierRef: Nº factura
list: list:
ref: Referencia ref: Referencia
supplier: Proveedor supplier: Proveedor
supplierRef: Ref. proveedor
issued: F. emisión issued: F. emisión
dueDated: F. vencimiento dueDated: F. vencimiento
file: Fichero file: Fichero
@ -15,10 +15,12 @@ invoiceIn:
descriptor: descriptor:
ticketList: Listado de tickets ticketList: Listado de tickets
descriptorMenu: descriptorMenu:
book: Contabilizar book: Asentar
unbook: Descontabilizar unbook: Desasentar
delete: Eliminar delete: Eliminar
clone: Clonar clone: Clonar
toBook: Contabilizar
toUnbook: Descontabilizar
deleteInvoice: Eliminar factura deleteInvoice: Eliminar factura
invoiceDeleted: Factura eliminada invoiceDeleted: Factura eliminada
cloneInvoice: Clonar factura cloneInvoice: Clonar factura
@ -66,3 +68,4 @@ invoiceIn:
isBooked: Contabilizada isBooked: Contabilizada
account: Cuenta contable account: Cuenta contable
correctingFk: Rectificativa correctingFk: Rectificativa

View File

@ -65,19 +65,10 @@ const columns = computed(() => [
name: 'name', name: 'name',
...defaultColumnAttrs, ...defaultColumnAttrs,
create: true, create: true,
columnFilter: {
component: 'select',
attrs: {
url: 'Items',
fields: ['id', 'name', 'subName'],
optionLabel: 'name',
optionValue: 'name',
uppercase: false,
},
},
}, },
{ {
label: t('item.fixedPrice.groupingPrice'), label: t('item.fixedPrice.groupingPrice'),
field: 'rate2',
name: 'rate2', name: 'rate2',
...defaultColumnAttrs, ...defaultColumnAttrs,
component: 'input', component: 'input',
@ -85,6 +76,7 @@ const columns = computed(() => [
}, },
{ {
label: t('item.fixedPrice.packingPrice'), label: t('item.fixedPrice.packingPrice'),
field: 'rate3',
name: 'rate3', name: 'rate3',
...defaultColumnAttrs, ...defaultColumnAttrs,
component: 'input', component: 'input',
@ -93,6 +85,7 @@ const columns = computed(() => [
{ {
label: t('item.fixedPrice.minPrice'), label: t('item.fixedPrice.minPrice'),
field: 'minPrice',
name: 'minPrice', name: 'minPrice',
...defaultColumnAttrs, ...defaultColumnAttrs,
component: 'input', component: 'input',
@ -115,6 +108,7 @@ const columns = computed(() => [
}, },
{ {
label: t('item.fixedPrice.ended'), label: t('item.fixedPrice.ended'),
field: 'ended',
name: 'ended', name: 'ended',
...defaultColumnAttrs, ...defaultColumnAttrs,
columnField: { columnField: {
@ -130,6 +124,7 @@ const columns = computed(() => [
{ {
label: t('globals.warehouse'), label: t('globals.warehouse'),
field: 'warehouseFk',
name: 'warehouseFk', name: 'warehouseFk',
...defaultColumnAttrs, ...defaultColumnAttrs,
columnClass: 'shrink', columnClass: 'shrink',
@ -420,6 +415,7 @@ function handleOnDataSave({ CrudModelRef }) {
'row-key': 'id', 'row-key': 'id',
selection: 'multiple', selection: 'multiple',
}" }"
:use-model="true"
v-model:selected="rowsSelected" v-model:selected="rowsSelected"
:create-as-dialog="false" :create-as-dialog="false"
:create="{ :create="{

View File

@ -107,10 +107,7 @@ export default defineRouter(function (/* { store, ssrContext } */) {
'Failed to fetch dynamically imported module', 'Failed to fetch dynamically imported module',
'Importing a module script failed', 'Importing a module script failed',
]; ];
state.set( state.set('error', errorMessages.some(message.includes));
'error',
errorMessages.some((error) => message.startsWith(error)),
);
}); });
return Router; return Router;
}); });