0
0
Fork 0

Merge branch 'dev' into 7411-addInfoOnVnCheckboxAndVnInput

This commit is contained in:
Alex Moreno 2025-02-11 08:38:51 +00:00
commit c975943eb1
38 changed files with 380 additions and 159 deletions

View File

@ -0,0 +1,2 @@
export const langs = ['en', 'es'];
export const decimalPlaces = 2;

View File

@ -328,7 +328,6 @@ en:
active: Is active active: Is active
visible: Is visible visible: Is visible
floramondo: Is floramondo floramondo: Is floramondo
salesPersonFk: Buyer
categoryFk: Category categoryFk: Category
es: es:
@ -339,7 +338,6 @@ es:
active: Activo active: Activo
visible: Visible visible: Visible
floramondo: Floramondo floramondo: Floramondo
salesPersonFk: Comprador
categoryFk: Categoría categoryFk: Categoría
Plant: Planta natural Plant: Planta natural
Flower: Flor fresca Flower: Flor fresca

View File

@ -171,7 +171,8 @@ onMounted(() => {
}); });
const arrayDataKey = const arrayDataKey =
$props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label); $props.dataKey ??
($props.url?.length > 0 ? $props.url : ($attrs.name ?? $attrs.label));
const arrayData = useArrayData(arrayDataKey, { const arrayData = useArrayData(arrayDataKey, {
url: $props.url, url: $props.url,
@ -220,7 +221,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) {
@ -239,7 +240,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;
@ -272,7 +273,7 @@ async function filterHandler(val, update) {
ref.setOptionIndex(-1); ref.setOptionIndex(-1);
ref.moveOptionSelection(1, true); ref.moveOptionSelection(1, true);
} }
} },
); );
} }
@ -308,7 +309,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) {
@ -320,11 +321,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,9 +1,7 @@
<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>
@ -11,11 +9,13 @@ const url = 'Suppliers';
:label="$t('globals.supplier')" :label="$t('globals.supplier')"
v-bind="$attrs" v-bind="$attrs"
v-model="model" v-model="model"
:url="url" url="Suppliers"
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"
data-cy="vnSupplierSelect"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">

View File

@ -57,7 +57,7 @@ defineExpose({ getData });
onBeforeMount(async () => { onBeforeMount(async () => {
arrayData = useArrayData($props.dataKey, { arrayData = useArrayData($props.dataKey, {
url: $props.url, url: $props.url,
filter: $props.filter, userFilter: $props.filter,
skip: 0, skip: 0,
oneRecord: true, oneRecord: true,
}); });

View File

@ -18,7 +18,12 @@ import VnInput from 'components/common/VnInput.vue';
const emit = defineEmits(['onFetch']); const emit = defineEmits(['onFetch']);
const $attrs = useAttrs(); const originalAttrs = useAttrs();
const $attrs = computed(() => {
const { style, ...rest } = originalAttrs;
return rest;
});
const isRequired = computed(() => { const isRequired = computed(() => {
return Object.keys($attrs).includes('required') return Object.keys($attrs).includes('required')

View File

@ -352,7 +352,7 @@ globals:
from: Desde from: Desde
to: Hasta to: Hasta
supplierFk: Proveedor supplierFk: Proveedor
supplierRef: Ref. proveedor supplierRef: Nº factura
serial: Serie serial: Serie
amount: Importe amount: Importe
awbCode: AWB awbCode: AWB
@ -653,7 +653,6 @@ supplier:
tableVisibleColumns: tableVisibleColumns:
nif: NIF/CIF nif: NIF/CIF
account: Cuenta account: Cuenta
summary: summary:
responsible: Responsable responsible: Responsable
verified: Verificado verified: Verificado

View File

@ -1,12 +1,12 @@
<script setup> <script setup>
import { Dark, Quasar } from 'quasar'; import { Dark, Quasar } from 'quasar';
import { computed } from 'vue'; import { computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { localeEquivalence } from 'src/i18n/index'; import { localeEquivalence } from 'src/i18n/index';
import quasarLang from 'src/utils/quasarLang'; import quasarLang from 'src/utils/quasarLang';
import { langs } from 'src/boot/defaults/constants.js';
const { t, locale } = useI18n(); const { t, locale } = useI18n();
const userLocale = computed({ const userLocale = computed({
get() { get() {
return locale.value; return locale.value;
@ -28,7 +28,6 @@ const darkMode = computed({
Dark.set(value); Dark.set(value);
}, },
}); });
const langs = ['en', 'es'];
</script> </script>
<template> <template>

View File

@ -23,7 +23,7 @@ onMounted(async () => {
<CardDescriptor <CardDescriptor
ref="descriptor" ref="descriptor"
:url="`VnUsers/preview`" :url="`VnUsers/preview`"
:filter="filter" :filter="{ ...filter, where: { id: entityId } }"
module="Account" module="Account"
data-key="Account" data-key="Account"
title="nickname" title="nickname"

View File

@ -86,7 +86,7 @@ onMounted(async () => {
/> />
</template> </template>
</VnLv> </VnLv>
<VnLv :label="t('claim.zone')"> <VnLv v-if="entity.ticket?.zone?.id" :label="t('claim.zone')">
<template #value> <template #value>
<span class="link"> <span class="link">
{{ entity.ticket?.zone?.name }} {{ entity.ticket?.zone?.name }}
@ -98,11 +98,10 @@ onMounted(async () => {
:label="t('claim.province')" :label="t('claim.province')"
:value="entity.ticket?.address?.province?.name" :value="entity.ticket?.address?.province?.name"
/> />
<VnLv :label="t('claim.ticketId')"> <VnLv v-if="entity.ticketFk" :label="t('claim.ticketId')">
<template #value> <template #value>
<span class="link"> <span class="link">
{{ entity.ticketFk }} {{ entity.ticketFk }}
<TicketDescriptorProxy :id="entity.ticketFk" /> <TicketDescriptorProxy :id="entity.ticketFk" />
</span> </span>
</template> </template>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed } from 'vue'; import { computed, useAttrs } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import VnNotes from 'src/components/ui/VnNotes.vue'; import VnNotes from 'src/components/ui/VnNotes.vue';
@ -7,6 +7,7 @@ import VnNotes from 'src/components/ui/VnNotes.vue';
const route = useRoute(); const route = useRoute();
const state = useState(); const state = useState();
const user = state.getUser(); const user = state.getUser();
const $attrs = useAttrs();
const $props = defineProps({ const $props = defineProps({
id: { type: [Number, String], default: null }, id: { type: [Number, String], default: null },

View File

@ -131,7 +131,7 @@ const STATE_COLOR = {
prefix="claim" prefix="claim"
:array-data-props="{ :array-data-props="{
url: 'Claims/filter', url: 'Claims/filter',
order: ['cs.priority ASC', 'created ASC'], order: 'cs.priority ASC, created ASC',
}" }"
> >
<template #advanced-menu> <template #advanced-menu>

View File

@ -117,7 +117,7 @@ const toCustomerAddressEdit = (addressId) => {
data-key="CustomerAddresses" data-key="CustomerAddresses"
order="id DESC" order="id DESC"
ref="vnPaginateRef" ref="vnPaginateRef"
:user-filter="addressFilter" :filter="addressFilter"
:url="`Clients/${route.params.id}/addresses`" :url="`Clients/${route.params.id}/addresses`"
/> />
<div class="full-width flex justify-center"> <div class="full-width flex justify-center">
@ -189,11 +189,11 @@ const toCustomerAddressEdit = (addressId) => {
<QSeparator <QSeparator
class="q-mx-lg" class="q-mx-lg"
v-if="item.observations.length" v-if="item?.observations?.length"
vertical vertical
/> />
<div v-if="item.observations.length"> <div v-if="item?.observations?.length">
<div <div
:key="obIndex" :key="obIndex"
class="flex q-mb-sm" class="flex q-mb-sm"

View File

@ -61,6 +61,23 @@ const columns = computed(() => [
columnFilter: false, columnFilter: false,
cardVisible: true, cardVisible: true,
}, },
{
align: 'left',
name: 'buyerId',
label: t('customer.params.buyerId'),
component: 'select',
attrs: {
url: 'TicketRequests/getItemTypeWorker',
optionLabel: 'nickname',
optionValue: 'id',
fields: ['id', 'nickname'],
sortBy: ['nickname ASC'],
optionFilter: 'firstName',
},
cardVisible: false,
visible: false,
},
{ {
name: 'description', name: 'description',
align: 'left', align: 'left',
@ -74,6 +91,7 @@ const columns = computed(() => [
name: 'quantity', name: 'quantity',
label: t('globals.quantity'), label: t('globals.quantity'),
cardVisible: true, cardVisible: true,
visible: true,
columnFilter: { columnFilter: {
inWhere: true, inWhere: true,
}, },
@ -138,11 +156,11 @@ const updateDateParams = (value, params) => {
const campaign = campaignList.value.find((c) => c.id === value); const campaign = campaignList.value.find((c) => c.id === value);
if (!campaign) return; if (!campaign) return;
const { dated, previousDays, scopeDays } = campaign; const { dated, scopeDays } = campaign;
const _date = new Date(dated); const from = new Date(dated);
const [from, to] = dateRange(_date); from.setDate(from.getDate() - scopeDays);
params.from = new Date(from.setDate(from.getDate() - previousDays)).toISOString(); params.from = from;
params.to = new Date(to.setDate(to.getDate() + scopeDays)).toISOString(); params.to = dated;
return params; return params;
}; };
</script> </script>
@ -205,24 +223,57 @@ const updateDateParams = (value, params) => {
<template #moreFilterPanel="{ params }"> <template #moreFilterPanel="{ params }">
<div class="column no-wrap flex-center q-gutter-y-md q-mt-xs q-pr-xl"> <div class="column no-wrap flex-center q-gutter-y-md q-mt-xs q-pr-xl">
<VnSelect <VnSelect
v-model="params.campaign"
:options="campaignList"
:label="t('globals.campaign')"
:filled="true" :filled="true"
class="q-px-sm q-pt-none fit" class="q-px-sm q-pt-none fit"
url="ItemTypes"
v-model="params.typeId"
:label="t('item.list.typeName')"
:fields="['id', 'name', 'categoryFk']"
:include="'category'"
:sortBy="'name ASC'"
dense dense
option-label="code"
@update:model-value="(data) => updateDateParams(data, params)" @update:model-value="(data) => updateDateParams(data, params)"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
<QItemSection> <QItemSection>
<QItemLabel> <QItemLabel>{{ scope.opt?.name }}</QItemLabel>
{{ scope.opt?.code }} <QItemLabel caption>{{
{{ scope.opt?.category?.name
new Date(scope.opt?.dated).getFullYear() }}</QItemLabel>
}}</QItemLabel </QItemSection>
> </QItem>
</template>
</VnSelect>
<VnSelect
:filled="true"
class="q-px-sm q-pt-none fit"
url="ItemCategories"
v-model="params.categoryId"
:label="t('item.list.category')"
:fields="['id', 'name']"
:sortBy="'name ASC'"
dense
@update:model-value="(data) => updateDateParams(data, params)"
/>
<VnSelect
v-model="params.campaign"
:options="campaignList"
:label="t('globals.campaign')"
:filled="true"
class="q-px-sm q-pt-none fit"
:option-label="(opt) => t(opt.code)"
:fields="['id', 'code', 'dated', 'scopeDays']"
@update:model-value="(data) => updateDateParams(data, params)"
dense
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel> {{ t(scope.opt?.code) }} </QItemLabel>
<QItemLabel caption>
{{ new Date(scope.opt?.dated).getFullYear() }}
</QItemLabel>
</QItemSection> </QItemSection>
</QItem> </QItem>
</template> </template>
@ -247,7 +298,19 @@ const updateDateParams = (value, params) => {
</template> </template>
<i18n> <i18n>
en:
valentinesDay: Valentine's Day
mothersDay: Mother's Day
allSaints: All Saints' Day
es: es:
Enter a new search: Introduce una nueva búsqueda Enter a new search: Introduce una nueva búsqueda
Group by items: Agrupar por artículos Group by items: Agrupar por artículos
valentinesDay: Día de San Valentín
mothersDay: Día de la Madre
allSaints: Día de Todos los Santos
Campaign consumption: Consumo campaña
Campaign: Campaña
From: Desde
To: Hasta
</i18n> </i18n>

View File

@ -107,6 +107,9 @@ customer:
defaulterSinced: Defaulted Since defaulterSinced: Defaulted Since
hasRecovery: Has Recovery hasRecovery: Has Recovery
socialName: Social name socialName: Social name
typeId: Type
buyerId: Buyer
categoryId: Category
city: City city: City
phone: Phone phone: Phone
postcode: Postcode postcode: Postcode

View File

@ -108,6 +108,9 @@ customer:
hasRecovery: Tiene recobro hasRecovery: Tiene recobro
socialName: Razón social socialName: Razón social
campaign: Campaña campaign: Campaña
typeId: Familia
buyerId: Comprador
categoryId: Reino
city: Ciudad city: Ciudad
phone: Teléfono phone: Teléfono
postcode: Código postal postcode: Código postal

View File

@ -54,8 +54,8 @@ const transferEntry = async () => {
<i18n> <i18n>
en: en:
transferEntryDialog: The entries will be transferred to the next day transferEntryDialog: The entries will be transferred to the next day
transferEntry: Transfer Entry transferEntry: Partial delay
es: es:
transferEntryDialog: Se van a transferir las compras al dia siguiente transferEntryDialog: Se van a transferir las compras al dia siguiente
transferEntry: Transferir Entrada transferEntry: Retraso parcial
</i18n> </i18n>

View File

@ -125,7 +125,7 @@ function deleteFile(dmsFk) {
<VnInput <VnInput
clearable clearable
clear-icon="close" clear-icon="close"
:label="t('Supplier ref')" :label="t('invoiceIn.supplierRef')"
v-model="data.supplierRef" v-model="data.supplierRef"
/> />
</VnRow> </VnRow>
@ -149,6 +149,7 @@ function deleteFile(dmsFk) {
option-value="id" option-value="id"
option-label="id" option-label="id"
:filter-options="['id', 'name']" :filter-options="['id', 'name']"
data-cy="UnDeductibleVatSelect"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -310,7 +311,6 @@ 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.toBook') }}</QItemSection> <QItemSection>{{ t('invoiceIn.descriptorMenu.book') }}</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.toUnbook') }} {{ t('invoiceIn.descriptorMenu.unbook') }}
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem <QItem

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed } from 'vue'; import { ref, computed, onBeforeMount } 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,6 +12,7 @@ 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();
@ -26,7 +27,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',
@ -66,6 +67,8 @@ 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() {
@ -73,6 +76,10 @@ 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
@ -153,7 +160,7 @@ async function insert() {
<QTd /> <QTd />
<QTd /> <QTd />
<QTd> <QTd>
{{ getTotal(rows, 'amount', { currency: 'default' }) }} {{ toCurrency(totalAmount) }}
</QTd> </QTd>
<QTd> <QTd>
<template v-if="isNotEuro(invoiceIn.currency.code)"> <template v-if="isNotEuro(invoiceIn.currency.code)">
@ -235,7 +242,16 @@ async function insert() {
v-shortcut="'+'" v-shortcut="'+'"
size="lg" size="lg"
round round
@click="!areRows ? insert() : invoiceInFormRef.insert()" @click="
() => {
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('To book')" :label="t('Book')"
color="orange-11" color="orange-11"
text-color="black" text-color="black"
@click="book(entityId)" @click="book(entityId)"
@ -224,10 +224,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
</span> </span>
</template> </template>
</VnLv> </VnLv>
<VnLv <VnLv :label="t('invoiceIn.supplierRef')" :value="entity.supplierRef" />
: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"
@ -357,7 +354,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>
@ -392,7 +389,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>
@ -472,5 +469,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
To book: Contabilizar Book: Contabilizar
</i18n> </i18n>

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed } from 'vue'; import { ref, computed, nextTick } 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,7 +25,6 @@ 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: {
@ -97,6 +96,20 @@ 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',
@ -125,7 +138,7 @@ function taxRate(invoiceInTax) {
return ((taxTypeSage / 100) * taxableBase).toFixed(2); return ((taxTypeSage / 100) * taxableBase).toFixed(2);
} }
function autocompleteExpense(evt, row, col) { function autocompleteExpense(evt, row, col, ref) {
const val = evt.target.value; const val = evt.target.value;
if (!val) return; if (!val) return;
@ -134,22 +147,17 @@ function autocompleteExpense(evt, row, col) {
({ id }) => id == useAccountShortToStandard(param), ({ id }) => id == useAccountShortToStandard(param),
); );
expenseRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup); ref.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
} }
const taxableBaseTotal = computed(() => { function setCursor(ref) {
return getTotal(invoiceInFormRef.value.formData, 'taxableBase'); nextTick(() => {
}); const select = ref.vnSelectDialogRef
? ref.vnSelectDialogRef.vnSelectRef
const taxRateTotal = computed(() => { : ref.vnSelectRef;
return getTotal(invoiceInFormRef.value.formData, null, { select.$el.querySelector('input').setSelectionRange(0, 0);
cb: taxRate,
}); });
}); }
const combinedTotal = computed(() => {
return +taxableBaseTotal.value + +taxRateTotal.value;
});
</script> </script>
<template> <template>
<FetchData <FetchData
@ -187,14 +195,24 @@ const combinedTotal = computed(() => {
<template #body-cell-expense="{ row, col }"> <template #body-cell-expense="{ row, col }">
<QTd> <QTd>
<VnSelectDialog <VnSelectDialog
ref="expenseRef" :ref="`expenseRef-${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', 'name']" :filter-options="['id', 'name']"
:tooltip="t('Create a new expense')" :tooltip="t('Create a new expense')"
@keydown.tab="autocompleteExpense($event, row, col)" @keydown.tab="
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">
@ -210,7 +228,7 @@ const combinedTotal = computed(() => {
</QTd> </QTd>
</template> </template>
<template #body-cell-taxablebase="{ row }"> <template #body-cell-taxablebase="{ row }">
<QTd> <QTd shrink>
<VnInputNumber <VnInputNumber
clear-icon="close" clear-icon="close"
v-model="row.taxableBase" v-model="row.taxableBase"
@ -221,12 +239,16 @@ const combinedTotal = computed(() => {
<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">
@ -244,11 +266,15 @@ const combinedTotal = computed(() => {
<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">
@ -266,7 +292,7 @@ const combinedTotal = computed(() => {
</QTd> </QTd>
</template> </template>
<template #body-cell-foreignvalue="{ row }"> <template #body-cell-foreignvalue="{ row }">
<QTd> <QTd shrink>
<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.list.supplierRef'), label: t('invoiceIn.supplierRef'),
}, },
{ {
align: 'left', align: 'left',
@ -177,7 +177,7 @@ const cols = computed(() => [
:required="true" :required="true"
/> />
<VnInput <VnInput
:label="t('invoiceIn.list.supplierRef')" :label="t('invoiceIn.supplierRef')"
v-model="data.supplierRef" v-model="data.supplierRef"
/> />
<VnSelect <VnSelect

View File

@ -4,6 +4,7 @@ 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();
@ -12,29 +13,51 @@ defineExpose({ checkToBook });
const { store } = useArrayData(); const { store } = useArrayData();
async function checkToBook(id) { async function checkToBook(id) {
let directBooking = true; let messages = [];
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) directBooking = false; if (taxableBaseNotEqualDueDay && vatNotEqualDueDay)
messages.push(t('The sum of the taxable bases does not match the due dates'));
const { data: dueDaysCount } = await axios.get('InvoiceInDueDays/count', { const dueDaysCount = (
where: { await axios.get('InvoiceInDueDays/count', {
invoiceInFk: id, params: {
dueDated: { gte: Date.vnNew() }, where: JSON.stringify({
}, invoiceInFk: id,
}); dueDated: { gte: Date.vnNew() },
}),
},
})
).data?.count;
if (dueDaysCount) directBooking = false; if (dueDaysCount) messages.push(t('Some due dates are less than or equal to today'));
if (directBooking) return toBook(id); if (!messages.length) toBook(id);
else
dialog({ dialog({
component: VnConfirm, component: VnConfirm,
componentProps: { title: t('Are you sure you want to book this invoice?') }, componentProps: {
}).onOk(async () => await toBook(id)); title: t('Are you sure you want to book this invoice?'),
message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''),
},
}).onOk(() => toBook(id));
} }
async function toBook(id) { async function toBook(id) {
@ -59,4 +82,7 @@ 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,8 +19,6 @@ 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
@ -70,4 +68,3 @@ 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,12 +15,10 @@ invoiceIn:
descriptor: descriptor:
ticketList: Listado de tickets ticketList: Listado de tickets
descriptorMenu: descriptorMenu:
book: Asentar book: Contabilizar
unbook: Desasentar unbook: Descontabilizar
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
@ -68,4 +66,3 @@ invoiceIn:
isBooked: Contabilizada isBooked: Contabilizada
account: Cuenta contable account: Cuenta contable
correctingFk: Rectificativa correctingFk: Rectificativa

View File

@ -97,12 +97,19 @@ const columns = computed(() => [
}, },
{ {
align: 'left', align: 'left',
name: 'companyCode', name: 'companyFk',
label: t('globals.company'), label: t('globals.company'),
cardVisible: true, cardVisible: true,
component: 'select', component: 'select',
attrs: { url: 'Companies', optionLabel: 'code', optionValue: 'id' }, attrs: {
columnField: { component: null }, url: 'Companies',
optionLabel: 'code',
optionValue: 'id',
},
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.companyCode),
}, },
{ {
align: 'left', align: 'left',

View File

@ -65,10 +65,19 @@ 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',
@ -76,7 +85,6 @@ 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',
@ -85,7 +93,6 @@ 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',
@ -108,7 +115,6 @@ const columns = computed(() => [
}, },
{ {
label: t('item.fixedPrice.ended'), label: t('item.fixedPrice.ended'),
field: 'ended',
name: 'ended', name: 'ended',
...defaultColumnAttrs, ...defaultColumnAttrs,
columnField: { columnField: {
@ -124,7 +130,6 @@ const columns = computed(() => [
{ {
label: t('globals.warehouse'), label: t('globals.warehouse'),
field: 'warehouseFk',
name: 'warehouseFk', name: 'warehouseFk',
...defaultColumnAttrs, ...defaultColumnAttrs,
columnClass: 'shrink', columnClass: 'shrink',
@ -415,7 +420,6 @@ 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

@ -43,10 +43,9 @@ const addToOrder = async () => {
); );
state.set('orderTotal', orderTotal); state.set('orderTotal', orderTotal);
const rows = orderData.value.rows.push(...items) || [];
state.set('Order', { state.set('Order', {
...orderData.value, ...orderData.value,
rows, items,
}); });
notify(t('globals.dataSaved'), 'positive'); notify(t('globals.dataSaved'), 'positive');
emit('added', -totalQuantity(items)); emit('added', -totalQuantity(items));

View File

@ -6,7 +6,7 @@ import VehicleFilter from '../VehicleFilter.js';
<template> <template>
<VnCardBeta <VnCardBeta
data-key="Vehicle" data-key="Vehicle"
base-url="Vehicles" url="Vehicles"
:filter="VehicleFilter" :filter="VehicleFilter"
:descriptor="VehicleDescriptor" :descriptor="VehicleDescriptor"
/> />

View File

@ -136,7 +136,7 @@ const columns = computed(() => [
/> />
<FetchData <FetchData
url="Countries" url="Countries"
:filter="{ fields: ['code'] }" :filter="{ fields: ['name', 'code'] }"
@on-fetch="(data) => (countries = data)" @on-fetch="(data) => (countries = data)"
auto-load auto-load
/> />
@ -209,7 +209,7 @@ const columns = computed(() => [
v-model="data.countryCodeFk" v-model="data.countryCodeFk"
:label="$t('globals.country')" :label="$t('globals.country')"
option-value="code" option-value="code"
option-label="code" option-label="name"
:options="countries" :options="countries"
/> />
<VnInput <VnInput

View File

@ -376,6 +376,30 @@ onMounted(async () => {
</template> </template>
<template #body-cell-problems="{ row }"> <template #body-cell-problems="{ row }">
<QTd class="q-gutter-x-xs"> <QTd class="q-gutter-x-xs">
<QIcon
v-if="row.futureAgencyFk !== row.agencyFk && row.agencyFk"
color="primary"
name="vn:agency-term"
size="xs"
class="q-mr-xs"
>
<QTooltip class="column">
<span>
{{
t('advanceTickets.originAgency', {
agency: row.futureAgency,
})
}}
</span>
<span>
{{
t('advanceTickets.destinationAgency', {
agency: row.agency,
})
}}
</span>
</QTooltip>
</QIcon>
<QIcon <QIcon
v-if="row.isTaxDataChecked === 0" v-if="row.isTaxDataChecked === 0"
color="primary" color="primary"

View File

@ -53,6 +53,7 @@ const handlePhotoUpdated = (evt = false) => {
module="Worker" module="Worker"
:data-key="dataKey" :data-key="dataKey"
url="Workers/summary" url="Workers/summary"
:filter="{ where: { id: entityId } }"
title="user.nickname" title="user.nickname"
@on-fetch="getIsExcluded" @on-fetch="getIsExcluded"
> >

View File

@ -1,5 +1,7 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { computed, ref } from 'vue';
import FetchData from 'components/FetchData.vue';
import FormModel from 'src/components/FormModel.vue'; import FormModel from 'src/components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
@ -7,10 +9,33 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
const { t } = useI18n(); const { t } = useI18n();
const agencyFilter = {
fields: ['id', 'name'],
order: 'name ASC',
limit: 30,
};
const agencyOptions = ref([]);
const validAddresses = ref([]);
const filterWhere = computed(() => ({
id: { inq: validAddresses.value.map((item) => item.addressFk) },
}));
</script> </script>
<template> <template>
<FormModel :url="`Zones/${$route.params.id}`" auto-load model="zone"> <FetchData
:filter="agencyFilter"
@on-fetch="(data) => (agencyOptions = data)"
auto-load
url="AgencyModes/isActive"
/>
<FetchData
url="RoadmapAddresses"
auto-load
@on-fetch="(data) => (validAddresses = data)"
/>
<FormModel :url="`Zones/${route.params.id}`" auto-load model="zone">
<template #form="{ data, validate }"> <template #form="{ data, validate }">
<VnRow> <VnRow>
<VnInput <VnInput
@ -109,6 +134,8 @@ const { t } = useI18n();
hide-selected hide-selected
map-options map-options
:rules="validate('data.addressFk')" :rules="validate('data.addressFk')"
:filter-options="['id']"
:where="filterWhere"
/> />
</VnRow> </VnRow>
<VnRow> <VnRow>

View File

@ -22,15 +22,50 @@ const exprBuilder = (param, value) => {
return /^\d+$/.test(value) ? { id: value } : { name: { like: `%${value}%` } }; return /^\d+$/.test(value) ? { id: value } : { name: { like: `%${value}%` } };
} }
}; };
const tableFilter = {
include: [
{
relation: 'agencyMode',
scope: {
fields: ['id', 'name'],
},
},
{
relation: 'address',
scope: {
fields: ['id', 'nickname', 'provinceFk', 'postalCode'],
include: [
{
relation: 'province',
scope: {
fields: ['id', 'name'],
},
},
{
relation: 'postcode',
scope: {
fields: ['code', 'townFk'],
include: {
relation: 'town',
scope: {
fields: ['id', 'name'],
},
},
},
},
],
},
},
],
};
</script> </script>
<template> <template>
<VnSearchbar <VnSearchbar
data-key="ZonesList" data-key="ZonesList"
url="Zones" url="Zones"
:filter="{ :filter="tableFilter"
include: { relation: 'agencyMode', scope: { fields: ['name'] } },
}"
:expr-builder="exprBuilder" :expr-builder="exprBuilder"
:label="t('list.searchZone')" :label="t('list.searchZone')"
:info="t('list.searchInfo')" :info="t('list.searchInfo')"

View File

@ -4,7 +4,7 @@ import { useRouter } from 'vue-router';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import axios from 'axios'; import axios from 'axios';
import { toCurrency } from 'src/filters'; import { dashIfEmpty, toCurrency } from 'src/filters';
import { toTimeFormat } from 'src/filters/date'; import { toTimeFormat } from 'src/filters/date';
import { useVnConfirm } from 'composables/useVnConfirm'; import { useVnConfirm } from 'composables/useVnConfirm';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
@ -17,7 +17,6 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
import ZoneFilterPanel from './ZoneFilterPanel.vue'; import ZoneFilterPanel from './ZoneFilterPanel.vue';
import ZoneSearchbar from './Card/ZoneSearchbar.vue'; import ZoneSearchbar from './Card/ZoneSearchbar.vue';
import FetchData from 'src/components/FetchData.vue';
const { t } = useI18n(); const { t } = useI18n();
const router = useRouter(); const router = useRouter();
@ -26,7 +25,6 @@ const { viewSummary } = useSummaryDialog();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const tableRef = ref(); const tableRef = ref();
const warehouseOptions = ref([]); const warehouseOptions = ref([]);
const validAddresses = ref([]);
const tableFilter = { const tableFilter = {
include: [ include: [
@ -161,30 +159,18 @@ const handleClone = (id) => {
openConfirmationModal( openConfirmationModal(
t('list.confirmCloneTitle'), t('list.confirmCloneTitle'),
t('list.confirmCloneSubtitle'), t('list.confirmCloneSubtitle'),
() => clone(id) () => clone(id),
); );
}; };
function showValidAddresses(row) { function formatRow(row) {
if (row.addressFk) { if (!row?.address) return '-';
const isValid = validAddresses.value.some( return dashIfEmpty(`${row?.address?.nickname},
(address) => address.addressFk === row.addressFk ${row?.address?.postcode?.town?.name} (${row?.address?.province?.name})`);
);
if (isValid)
return `${row.address?.nickname},
${row.address?.postcode?.town?.name} (${row.address?.province?.name})`;
else return '-';
}
return '-';
} }
</script> </script>
<template> <template>
<FetchData
url="RoadmapAddresses"
auto-load
@on-fetch="(data) => (validAddresses = data)"
/>
<ZoneSearchbar /> <ZoneSearchbar />
<RightMenu> <RightMenu>
<template #right-panel> <template #right-panel>
@ -207,7 +193,7 @@ function showValidAddresses(row) {
:right-search="false" :right-search="false"
> >
<template #column-addressFk="{ row }"> <template #column-addressFk="{ row }">
{{ showValidAddresses(row) }} {{ dashIfEmpty(formatRow(row)) }}
</template> </template>
<template #more-create-dialog="{ data }"> <template #more-create-dialog="{ data }">
<VnSelect <VnSelect

View File

@ -107,7 +107,10 @@ 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('error', errorMessages.some(message.includes)); state.set(
'error',
errorMessages.some((error) => message.startsWith(error)),
);
}); });
return Router; return Router;
}); });

View File

@ -1,9 +1,9 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
describe('InvoiceInBasicData', () => { describe('InvoiceInBasicData', () => {
const formInputs = '.q-form > .q-card input';
const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select'; const firstFormSelect = '.q-card > .vn-row:nth-child(1) > .q-select';
const documentBtns = '[data-cy="dms-buttons"] button';
const dialogInputs = '.q-dialog input'; const dialogInputs = '.q-dialog input';
const resetBtn = '.q-btn-group--push > .q-btn--flat';
const getDocumentBtns = (opt) => `[data-cy="dms-buttons"] > :nth-child(${opt})`;
beforeEach(() => { beforeEach(() => {
cy.login('developer'); cy.login('developer');
@ -11,13 +11,16 @@ describe('InvoiceInBasicData', () => {
}); });
it('should edit the provideer and supplier ref', () => { it('should edit the provideer and supplier ref', () => {
cy.selectOption(firstFormSelect, 'Bros'); cy.dataCy('UnDeductibleVatSelect').type('4751000000');
cy.get('[title="Reset"]').click(); cy.get('.q-menu .q-item').contains('4751000000').click();
cy.get(formInputs).eq(1).type('{selectall}4739'); cy.get(resetBtn).click();
cy.saveCard();
cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Plants nick'); cy.waitForElement('#formModel').within(() => {
cy.get(formInputs).eq(1).invoke('val').should('eq', '4739'); cy.dataCy('vnSupplierSelect').type('Bros nick');
})
cy.get('.q-menu .q-item').contains('Bros nick').click();
cy.saveCard();
cy.get(`${firstFormSelect} input`).invoke('val').should('eq', 'Bros nick');
}); });
it('should edit, remove and create the dms data', () => { it('should edit, remove and create the dms data', () => {
@ -25,18 +28,18 @@ describe('InvoiceInBasicData', () => {
const secondInput = "I don't know what posting here!"; const secondInput = "I don't know what posting here!";
//edit //edit
cy.get(documentBtns).eq(1).click(); cy.get(getDocumentBtns(2)).click();
cy.get(dialogInputs).eq(0).type(`{selectall}${firtsInput}`); cy.get(dialogInputs).eq(0).type(`{selectall}${firtsInput}`);
cy.get('textarea').type(`{selectall}${secondInput}`); cy.get('textarea').type(`{selectall}${secondInput}`);
cy.get('[data-cy="FormModelPopup_save"]').click(); cy.get('[data-cy="FormModelPopup_save"]').click();
cy.get(documentBtns).eq(1).click(); cy.get(getDocumentBtns(2)).click();
cy.get(dialogInputs).eq(0).invoke('val').should('eq', firtsInput); cy.get(dialogInputs).eq(0).invoke('val').should('eq', firtsInput);
cy.get('textarea').invoke('val').should('eq', secondInput); cy.get('textarea').invoke('val').should('eq', secondInput);
cy.get('[data-cy="FormModelPopup_save"]').click(); cy.get('[data-cy="FormModelPopup_save"]').click();
cy.checkNotification('Data saved'); cy.checkNotification('Data saved');
//remove //remove
cy.get(documentBtns).eq(2).click(); cy.get(getDocumentBtns(3)).click();
cy.get('[data-cy="VnConfirm_confirm"]').click(); cy.get('[data-cy="VnConfirm_confirm"]').click();
cy.checkNotification('Data saved'); cy.checkNotification('Data saved');