Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix-front into 7283-itemSectionsMigration
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Jorge Penadés 2024-08-09 12:34:04 +02:00
commit bf11a184c2
20 changed files with 267 additions and 327 deletions

View File

@ -151,7 +151,7 @@ const col = computed(() => {
}; };
} }
if ( if (
(newColumn.name.startsWith('is') || newColumn.name.startsWith('has')) && (/^is[A-Z]/.test(newColumn.name) || /^has[A-Z]/.test(newColumn.name)) &&
newColumn.component == null newColumn.component == null
) )
newColumn.component = 'checkbox'; newColumn.component = 'checkbox';

View File

@ -1,34 +0,0 @@
<script setup>
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useCapitalize } from 'src/composables/useCapitalize';
import VnInput from 'src/components/common/VnInput.vue';
const props = defineProps({
modelValue: { type: [String, Number], default: '' },
});
const { t } = useI18n();
const emit = defineEmits(['update:modelValue']);
const amount = computed({
get() {
return props.modelValue;
},
set(val) {
emit('update:modelValue', val);
},
});
</script>
<template>
<VnInput
v-model="amount"
type="number"
step="any"
:label="useCapitalize(t('amount'))"
/>
</template>
<i18n>
es:
amount: importe
</i18n>

View File

@ -262,6 +262,7 @@ globals:
unsavedPopup: unsavedPopup:
title: Unsaved changes will be lost title: Unsaved changes will be lost
subtitle: Are you sure exit without saving? subtitle: Are you sure exit without saving?
createInvoiceIn: Create invoice in
errors: errors:
statusUnauthorized: Access denied statusUnauthorized: Access denied
statusInternalServerError: An internal server error has ocurred statusInternalServerError: An internal server error has ocurred

View File

@ -264,6 +264,8 @@ globals:
unsavedPopup: unsavedPopup:
title: Los cambios que no haya guardado se perderán title: Los cambios que no haya guardado se perderán
subtitle: ¿Seguro que quiere salir sin guardar? subtitle: ¿Seguro que quiere salir sin guardar?
createInvoiceIn: Crear factura recibida
errors: errors:
statusUnauthorized: Acceso denegado statusUnauthorized: Acceso denegado
statusInternalServerError: Ha ocurrido un error interno del servidor statusInternalServerError: Ha ocurrido un error interno del servidor

View File

@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue'; import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const { t } = useI18n(); const { t } = useI18n();
const props = defineProps({ const props = defineProps({
@ -47,7 +47,11 @@ const props = defineProps({
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnCurrency v-model="params.amount" is-outlined /> <VnInputNumber
:label="t('Amount')"
v-model="params.amount"
is-outlined
/>
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem> <QItem>

View File

@ -130,8 +130,6 @@ onBeforeMount(async () => {
}); });
onBeforeRouteUpdate(async (to, from) => { onBeforeRouteUpdate(async (to, from) => {
invoiceInCorrection.correcting.length = 0;
invoiceInCorrection.corrected = null;
if (to.params.id !== from.params.id) { if (to.params.id !== from.params.id) {
await setInvoiceCorrection(to.params.id); await setInvoiceCorrection(to.params.id);
const { data } = await axios.get(`InvoiceIns/${to.params.id}/getTotals`); const { data } = await axios.get(`InvoiceIns/${to.params.id}/getTotals`);
@ -140,6 +138,8 @@ onBeforeRouteUpdate(async (to, from) => {
}); });
async function setInvoiceCorrection(id) { async function setInvoiceCorrection(id) {
invoiceInCorrection.correcting.length = 0;
invoiceInCorrection.corrected = null;
const { data: correctingData } = await axios.get('InvoiceInCorrections', { const { data: correctingData } = await axios.get('InvoiceInCorrections', {
params: { filter: { where: { correctingFk: id } } }, params: { filter: { where: { correctingFk: id } } },
}); });
@ -198,7 +198,6 @@ async function cloneInvoice() {
const isAdministrative = () => hasAny(['administrative']); const isAdministrative = () => hasAny(['administrative']);
const isAgricultural = () => { const isAgricultural = () => {
console.error(config);
if (!config.value) return false; if (!config.value) return false;
return ( return (
invoiceIn.value?.supplier?.sageFarmerWithholdingFk === invoiceIn.value?.supplier?.sageFarmerWithholdingFk ===

View File

@ -8,9 +8,11 @@ import { useArrayData } from 'src/composables/useArrayData';
import CrudModel from 'src/components/CrudModel.vue'; import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const route = useRoute(); const route = useRoute();
const { notify } = useNotify(); const { notify } = useNotify();
@ -22,9 +24,6 @@ const rowsSelected = ref([]);
const banks = ref([]); const banks = ref([]);
const invoiceInFormRef = 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(() => [ const columns = computed(() => [
@ -104,42 +103,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
> >
<template #body-cell-duedate="{ row }"> <template #body-cell-duedate="{ row }">
<QTd> <QTd>
<QInput <VnInputDate v-model="row.dueDated" />
v-model="row.dueDated"
mask="date"
:placeholder="placeholder"
clearable
clear-icon="close"
>
<template #append>
<QIcon name="event" class="cursor-pointer">
<QPopupProxy
cover
transition-show="scale"
transition-hide="scale"
>
<QDate v-model="row.dueDated" landscape>
<div
class="row items-center justify-end q-gutter-sm"
>
<QBtn
:label="t('globals.cancel')"
color="primary"
flat
v-close-popup
/>
<QBtn
:label="t('globals.confirm')"
color="primary"
flat
v-close-popup
/>
</div>
</QDate>
</QPopupProxy>
</QIcon>
</template>
</QInput>
</QTd> </QTd>
</template> </template>
<template #body-cell-bank="{ row, col }"> <template #body-cell-bank="{ row, col }">
@ -164,7 +128,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
</template> </template>
<template #body-cell-amount="{ row }"> <template #body-cell-amount="{ row }">
<QTd> <QTd>
<VnCurrency <VnInputNumber
v-model="row.amount" v-model="row.amount"
:is-outlined="false" :is-outlined="false"
clearable clearable
@ -174,7 +138,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
</template> </template>
<template #body-cell-foreignvalue="{ row }"> <template #body-cell-foreignvalue="{ row }">
<QTd> <QTd>
<QInput <VnInputNumber
:class="{ :class="{
'no-pointer-events': !isNotEuro(invoiceIn.currency.code), 'no-pointer-events': !isNotEuro(invoiceIn.currency.code),
}" }"
@ -207,51 +171,11 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
<QSeparator /> <QSeparator />
<QList> <QList>
<QItem> <QItem>
<QInput <VnInputDate
class="full-width" class="full-width"
:label="t('Date')" :label="t('Date')"
v-model="props.row.dueDated" v-model="props.row.dueDated"
mask="date" />
:placeholder="placeholder"
clearable
clear-icon="close"
>
<template #append>
<QIcon name="event" class="cursor-pointer">
<QPopupProxy
cover
transition-show="scale"
transition-hide="scale"
>
<QDate
v-model="props.row.dueDated"
landscape
>
<div
class="row items-center justify-end q-gutter-sm"
>
<QBtn
:label="
t('globals.cancel')
"
color="primary"
flat
v-close-popup
/>
<QBtn
:label="
t('globals.confirm')
"
color="primary"
flat
v-close-popup
/>
</div>
</QDate>
</QPopupProxy>
</QIcon>
</template>
</QInput>
</QItem> </QItem>
<QItem> <QItem>
<VnSelect <VnSelect
@ -274,16 +198,14 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount,
</VnSelect> </VnSelect>
</QItem> </QItem>
<QItem> <QItem>
<QInput <VnInputNumber
:label="t('Amount')" :label="t('Amount')"
class="full-width" class="full-width"
v-model="props.row.amount" v-model="props.row.amount"
clearable
clear-icon="close"
/> />
</QItem> </QItem>
<QItem> <QItem>
<QInput <VnInputNumber
:label="t('Foreign value')" :label="t('Foreign value')"
class="full-width" class="full-width"
:class="{ :class="{

View File

@ -7,6 +7,7 @@ import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import { useArrayData } from 'src/composables/useArrayData'; import { useArrayData } from 'src/composables/useArrayData';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const { t } = useI18n(); const { t } = useI18n();
@ -115,11 +116,7 @@ const formatOpt = (row, { model, options }, prop) => {
> >
<template #body-cell="{ row, col }"> <template #body-cell="{ row, col }">
<QTd> <QTd>
<QInput <VnInputNumber v-model="row[col.name]" />
v-model="row[col.name]"
clearable
clear-icon="close"
/>
</QTd> </QTd>
</template> </template>
<template #body-cell-code="{ row, col }"> <template #body-cell-code="{ row, col }">
@ -203,7 +200,7 @@ const formatOpt = (row, { model, options }, prop) => {
]" ]"
:key="index" :key="index"
> >
<QInput <VnInputNumber
:label="t(value)" :label="t(value)"
class="full-width" class="full-width"
v-model="props.row[value]" v-model="props.row[value]"

View File

@ -120,7 +120,6 @@ const intrastatColumns = ref([
}, },
sortable: true, sortable: true,
align: 'left', align: 'left',
style: 'width: 10px',
}, },
{ {
name: 'amount', name: 'amount',
@ -128,7 +127,6 @@ const intrastatColumns = ref([
field: (row) => toCurrency(row.amount, currency.value), field: (row) => toCurrency(row.amount, currency.value),
sortable: true, sortable: true,
align: 'left', align: 'left',
style: 'width: 10px',
}, },
{ {
name: 'net', name: 'net',
@ -415,6 +413,11 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
</QTh> </QTh>
</QTr> </QTr>
</template> </template>
<template #body-cell-code="{ value: codeCell }">
<QTd :title="codeCell" shrink>
{{ codeCell }}
</QTd>
</template>
<template #bottom-row> <template #bottom-row>
<QTr class="bg"> <QTr class="bg">
<QTd></QTd> <QTd></QTd>

View File

@ -9,7 +9,8 @@ import { toCurrency } from 'src/filters';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import CrudModel from 'src/components/CrudModel.vue'; import CrudModel from 'src/components/CrudModel.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const { t } = useI18n(); const { t } = useI18n();
const quasar = useQuasar(); const quasar = useQuasar();
@ -205,7 +206,7 @@ const formatOpt = (row, { model, options }, prop) => {
:grid="$q.screen.lt.sm" :grid="$q.screen.lt.sm"
> >
<template #body-cell-expense="{ row, col }"> <template #body-cell-expense="{ row, col }">
<QTd auto-width> <QTd>
<VnSelect <VnSelect
v-model="row[col.model]" v-model="row[col.model]"
:options="col.options" :options="col.options"
@ -223,6 +224,7 @@ const formatOpt = (row, { model, options }, prop) => {
name="close" name="close"
@click.stop="value = null" @click.stop="value = null"
class="cursor-pointer" class="cursor-pointer"
size="xs"
/> />
<QIcon <QIcon
@click.stop.prevent="newExpenseRef.show()" @click.stop.prevent="newExpenseRef.show()"
@ -240,7 +242,7 @@ const formatOpt = (row, { model, options }, prop) => {
</template> </template>
<template #body-cell-taxablebase="{ row }"> <template #body-cell-taxablebase="{ row }">
<QTd> <QTd>
<VnCurrency <VnInputNumber
:class="{ :class="{
'no-pointer-events': isNotEuro(invoiceIn.currency.code), 'no-pointer-events': isNotEuro(invoiceIn.currency.code),
}" }"
@ -308,7 +310,7 @@ const formatOpt = (row, { model, options }, prop) => {
</template> </template>
<template #body-cell-foreignvalue="{ row }"> <template #body-cell-foreignvalue="{ row }">
<QTd> <QTd>
<QInput <VnInputNumber
:class="{ :class="{
'no-pointer-events': !isNotEuro(invoiceIn.currency.code), 'no-pointer-events': !isNotEuro(invoiceIn.currency.code),
}" }"
@ -356,7 +358,7 @@ const formatOpt = (row, { model, options }, prop) => {
</VnSelect> </VnSelect>
</QItem> </QItem>
<QItem> <QItem>
<VnCurrency <VnInputNumber
:label="t('Taxable base')" :label="t('Taxable base')"
:class="{ :class="{
'no-pointer-events': isNotEuro( 'no-pointer-events': isNotEuro(
@ -421,7 +423,7 @@ const formatOpt = (row, { model, options }, prop) => {
{{ toCurrency(taxRate(props.row), currency) }} {{ toCurrency(taxRate(props.row), currency) }}
</QItem> </QItem>
<QItem> <QItem>
<QInput <VnInputNumber
:label="t('Foreign value')" :label="t('Foreign value')"
class="full-width" class="full-width"
:class="{ :class="{
@ -453,7 +455,11 @@ const formatOpt = (row, { model, options }, prop) => {
</QCardSection> </QCardSection>
<QCardSection class="q-pt-none"> <QCardSection class="q-pt-none">
<QItem> <QItem>
<QInput :label="`${t('Code')}*`" v-model="newExpense.code" /> <VnInput
:label="`${t('Code')}*`"
v-model="newExpense.code"
:required="true"
/>
<QCheckbox <QCheckbox
dense dense
size="sm" size="sm"
@ -462,7 +468,7 @@ const formatOpt = (row, { model, options }, prop) => {
/> />
</QItem> </QItem>
<QItem> <QItem>
<QInput <VnInput
:label="`${t('Descripction')}*`" :label="`${t('Descripction')}*`"
v-model="newExpense.description" v-model="newExpense.description"
/> />

View File

@ -26,8 +26,7 @@ const newInvoiceIn = reactive({
companyFk: user.value.companyFk || null, companyFk: user.value.companyFk || null,
issued: Date.vnNew(), issued: Date.vnNew(),
}); });
const suppliersOptions = ref([]); const companies = ref([]);
const companiesOptions = ref([]);
const redirectToInvoiceInBasicData = (__, { id }) => { const redirectToInvoiceInBasicData = (__, { id }) => {
router.push({ name: 'InvoiceInBasicData', params: { id } }); router.push({ name: 'InvoiceInBasicData', params: { id } });
@ -35,19 +34,12 @@ const redirectToInvoiceInBasicData = (__, { id }) => {
</script> </script>
<template> <template>
<FetchData
url="Suppliers"
:filter="{ fields: ['id', 'nickname'] }"
order="nickname"
@on-fetch="(data) => (suppliersOptions = data)"
auto-load
/>
<FetchData <FetchData
ref="companiesRef" ref="companiesRef"
url="Companies" url="Companies"
:filter="{ fields: ['id', 'code'] }" :filter="{ fields: ['id', 'code'] }"
order="code" order="code"
@on-fetch="(data) => (companiesOptions = data)" @on-fetch="(data) => (companies = data)"
auto-load auto-load
/> />
<template v-if="stateStore.isHeaderMounted()"> <template v-if="stateStore.isHeaderMounted()">
@ -69,9 +61,10 @@ const redirectToInvoiceInBasicData = (__, { id }) => {
<template #form="{ data, validate }"> <template #form="{ data, validate }">
<VnRow> <VnRow>
<VnSelect <VnSelect
url="Suppliers"
:fields="['id', 'nickname']"
:label="t('Supplier')" :label="t('Supplier')"
v-model="data.supplierFk" v-model="data.supplierFk"
:options="suppliersOptions"
option-value="id" option-value="id"
option-label="nickname" option-label="nickname"
hide-selected hide-selected
@ -98,7 +91,7 @@ const redirectToInvoiceInBasicData = (__, { id }) => {
<VnSelect <VnSelect
:label="t('Company')" :label="t('Company')"
v-model="data.companyFk" v-model="data.companyFk"
:options="companiesOptions" :options="companies"
option-value="id" option-value="id"
option-label="code" option-label="code"
map-options map-options

View File

@ -6,8 +6,8 @@ import VnSelect from 'components/common/VnSelect.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const { t } = useI18n(); const { t } = useI18n();
defineProps({ dataKey: { type: String, required: true } }); defineProps({ dataKey: { type: String, required: true } });
@ -28,6 +28,22 @@ const activities = ref([]);
</div> </div>
</template> </template>
<template #body="{ params, searchFn }"> <template #body="{ params, searchFn }">
<QItem>
<QItemSection>
<VnSelect
v-model="params.supplierFk"
url="Suppliers"
:fields="['id', 'nickname']"
:label="t('params.supplierFk')"
option-value="id"
option-label="nickname"
dense
outlined
rounded
:filter-options="['id', 'name']"
/>
</QItemSection>
</QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnInput <VnInput
@ -50,17 +66,30 @@ const activities = ref([]);
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnSelect <VnInput
v-model="params.supplierFk" :label="t('params.serialNumber')"
url="Suppliers" v-model="params.serialNumber"
:fields="['id', 'nickname']" is-outlined
:label="t('params.supplierFk')" lazy-rules
option-value="id" />
option-label="nickname" </QItemSection>
dense </QItem>
outlined <QItem>
rounded <QItemSection>
:filter-options="['id', 'name']" <VnInput
:label="t('params.serial')"
v-model="params.serial"
is-outlined
lazy-rules
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInputDate
:label="t('Issued')"
v-model="params.issued"
is-outlined
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
@ -76,39 +105,20 @@ const activities = ref([]);
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnCurrency v-model="params.amount" is-outlined /> <VnInput
</QItemSection> :label="t('params.awb')"
</QItem> v-model="params.awbCode"
<QItem>
<QItemSection>
<VnInputDate :label="t('From')" v-model="params.from" is-outlined />
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInputDate :label="t('To')" v-model="params.to" is-outlined />
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInputDate
:label="t('Issued')"
v-model="params.issued"
is-outlined is-outlined
lazy-rules
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnSelect <VnInputNumber
:label="t('params.supplierActivityFk')" :label="t('Amount')"
v-model="params.supplierActivityFk" v-model="params.amount"
dense is-outlined
outlined
rounded
option-value="code"
option-label="name"
:options="activities"
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
@ -133,32 +143,16 @@ const activities = ref([]);
<QExpansionItem :label="t('More options')" expand-separator> <QExpansionItem :label="t('More options')" expand-separator>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnInput <VnInputDate
:label="t('params.serialNumber')" :label="t('From')"
v-model="params.serialNumber" v-model="params.from"
is-outlined is-outlined
lazy-rules
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnInput <VnInputDate :label="t('To')" v-model="params.to" is-outlined />
:label="t('params.serial')"
v-model="params.serial"
is-outlined
lazy-rules
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
:label="t('params.awb')"
v-model="params.awbCode"
is-outlined
lazy-rules
/>
</QItemSection> </QItemSection>
</QItem> </QItem>
</QExpansionItem> </QExpansionItem>

View File

@ -1,18 +1,19 @@
<script setup> <script setup>
import { onMounted, onUnmounted } from 'vue'; import { ref, computed, onMounted, onUnmounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { downloadFile } from 'src/composables/downloadFile'; import { downloadFile } from 'src/composables/downloadFile';
import { toDate, toCurrency } from 'src/filters/index'; import { toDate, toCurrency } from 'src/filters/index';
import VnPaginate from 'src/components/ui/VnPaginate.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import CardList from 'src/components/ui/CardList.vue';
import InvoiceInFilter from './InvoiceInFilter.vue'; import InvoiceInFilter from './InvoiceInFilter.vue';
import InvoiceInSummary from './Card/InvoiceInSummary.vue'; import InvoiceInSummary from './Card/InvoiceInSummary.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import RightMenu from 'src/components/common/RightMenu.vue'; import RightMenu from 'src/components/common/RightMenu.vue';
import InvoiceInSearchbar from 'src/pages/InvoiceIn/InvoiceInSearchbar.vue'; import InvoiceInSearchbar from 'src/pages/InvoiceIn/InvoiceInSearchbar.vue';
import VnTable from 'src/components/VnTable/VnTable.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
const stateStore = useStateStore(); const stateStore = useStateStore();
const { viewSummary } = useSummaryDialog(); const { viewSummary } = useSummaryDialog();
@ -20,8 +21,91 @@ const { t } = useI18n();
onMounted(async () => (stateStore.rightDrawer = true)); onMounted(async () => (stateStore.rightDrawer = true));
onUnmounted(() => (stateStore.rightDrawer = false)); onUnmounted(() => (stateStore.rightDrawer = false));
</script>
const tableRef = ref();
const cols = computed(() => [
{
align: 'left',
name: 'id',
label: 'Id',
},
{
align: 'left',
name: 'supplierFk',
label: t('invoiceIn.list.supplier'),
columnFilter: {
component: 'select',
attrs: {
url: 'Suppliers',
fields: ['id', 'name'],
},
},
columnClass: 'expand',
},
{
align: 'left',
name: 'supplierRef',
label: t('invoiceIn.list.supplierRef'),
},
{
align: 'left',
name: 'serialNumber',
label: t('invoiceIn.list.serialNumber'),
},
{
align: 'left',
name: 'serial',
label: t('invoiceIn.list.serial'),
},
{
align: 'left',
label: t('invoiceIn.list.issued'),
name: 'issued',
component: null,
columnFilter: {
component: 'date',
},
format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.issued)),
},
{
align: 'left',
name: 'isBooked',
label: t('invoiceIn.list.isBooked'),
columnFilter: false,
},
{
align: 'left',
name: 'awbCode',
label: t('invoiceIn.list.awb'),
},
{
align: 'left',
name: 'amount',
label: t('invoiceIn.list.amount'),
format: ({ amount }) => toCurrency(amount),
},
{
align: 'right',
name: 'tableActions',
actions: [
{
title: t('components.smartCard.openSummary'),
icon: 'preview',
type: 'submit',
action: (row) => viewSummary(row.id, InvoiceInSummary),
},
{
title: t('globals.download'),
icon: 'download',
type: 'submit',
isPrimary: true,
action: (row) => downloadFile(row.dmsFk),
},
],
},
]);
</script>
<template> <template>
<InvoiceInSearchbar /> <InvoiceInSearchbar />
<RightMenu> <RightMenu>
@ -29,92 +113,63 @@ onUnmounted(() => (stateStore.rightDrawer = false));
<InvoiceInFilter data-key="InvoiceInList" /> <InvoiceInFilter data-key="InvoiceInList" />
</template> </template>
</RightMenu> </RightMenu>
<QPage class="column items-center q-pa-md"> <VnTable
<div class="vn-card-list"> ref="tableRef"
<VnPaginate data-key="InvoiceInList"
data-key="InvoiceInList" url="InvoiceIns/filter"
url="InvoiceIns/filter" :order="['issued DESC', 'id DESC']"
order="issued DESC, id DESC" :create="{
auto-load urlCreate: 'InvoiceIns',
title: t('globals.createInvoiceIn'),
onDataSaved: ({ id }) => tableRef.redirect(id),
formInitialData: {},
}"
redirect="invoice-in"
:columns="cols"
:right-search="false"
:disable-option="{ card: true }"
:auto-load="!!$route.query.params"
>
<template #column-supplierFk="{ row }">
<span class="link" @click.stop>
{{ row.supplierName }}
<SupplierDescriptorProxy :id="row.supplierFk" />
</span>
</template>
<template #more-create-dialog="{ data }">
<VnSelect
v-model="data.supplierFk"
url="Suppliers"
:fields="['id', 'nickname']"
:label="t('Supplier')"
option-value="id"
option-label="nickname"
:filter-options="['id', 'name']"
:required="true"
> >
<template #body="{ rows }"> <template #option="scope">
<CardList <QItem v-bind="scope.itemProps">
v-for="(row, index) of rows" <QItemSection>
:key="index" <QItemLabel>{{ scope.opt?.nickname }}</QItemLabel>
:title="row.supplierRef" <QItemLabel caption> #{{ scope.opt?.id }} </QItemLabel>
@click="$router.push({ path: `/invoice-in/${row.id}` })" </QItemSection>
:id="row.id" </QItem>
>
<template #list-items>
<VnLv
:label="t('invoiceIn.list.supplierRef')"
:value="row.supplierRef"
/>
<VnLv
:label="t('invoiceIn.list.supplier')"
:value="row.supplierName"
@click.stop
>
<template #value>
<span class="link">
{{ row.supplierName }}
<SupplierDescriptorProxy :id="row.supplierFk" />
</span>
</template>
</VnLv>
<VnLv
:label="t('invoiceIn.list.serialNumber')"
:value="row.serialNumber"
/>
<VnLv
:label="t('invoiceIn.list.serial')"
:value="row.serial"
/>
<VnLv
:label="t('invoiceIn.list.issued')"
:value="toDate(row.issued)"
/>
<VnLv :label="t('invoiceIn.list.awb')" :value="row.awbCode" />
<VnLv
:label="t('invoiceIn.list.amount')"
:value="toCurrency(row.amount)"
/>
<VnLv
:label="t('invoiceIn.list.isBooked')"
:value="!!row.isBooked"
/>
</template>
<template #actions>
<QBtn
:label="t('components.smartCard.openCard')"
@click.stop="
$router.push({ path: `/invoice-in/${row.id}` })
"
outline
type="reset"
/>
<QBtn
:label="t('components.smartCard.openSummary')"
@click.stop="viewSummary(row.id, InvoiceInSummary)"
color="primary"
type="submit"
class="q-mt-sm"
/>
<QBtn
:label="t('globals.download')"
class="q-mt-sm"
@click.stop="downloadFile(row.dmsFk)"
type="submit"
color="primary"
/>
</template>
</CardList>
</template> </template>
</VnPaginate> </VnSelect>
</div> <VnInput
</QPage> :label="t('invoiceIn.summary.supplierRef')"
<QPageSticky position="bottom-right" :offset="[20, 20]"> v-model="data.supplierRef"
<QBtn color="primary" icon="add" size="lg" round :href="`/#/invoice-in/create`" /> />
</QPageSticky> <VnSelect
url="Companies"
:label="t('Company')"
:fields="['id', 'code']"
v-model="data.companyFk"
option-value="id"
option-label="code"
:required="true"
/>
<VnInputDate :label="t('invoiceIn.summary.issued')" v-model="data.issued" />
</template>
</VnTable>
</template> </template>

View File

@ -6,7 +6,7 @@ import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue'; import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const { t } = useI18n(); const { t } = useI18n();
const props = defineProps({ const props = defineProps({
@ -58,7 +58,7 @@ function setWorkers(data) {
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnCurrency <VnInputNumber
:label="t('Amount')" :label="t('Amount')"
v-model="params.amount" v-model="params.amount"
is-outlined is-outlined

View File

@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import VnCurrency from 'src/components/common/VnCurrency.vue'; import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const { t } = useI18n(); const { t } = useI18n();
const props = defineProps({ const props = defineProps({
@ -86,7 +86,7 @@ const props = defineProps({
</QItem> </QItem>
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnCurrency <VnInputNumber
v-model="params.amount" v-model="params.amount"
:label="t('invoiceOut.negativeBases.amount')" :label="t('invoiceOut.negativeBases.amount')"
is-outlined is-outlined

View File

@ -214,7 +214,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
@click="openDmsUploadDialog" @click="openDmsUploadDialog"
> >
<QTooltip> <QTooltip>
{{ t('Create invoiceIn') }} {{ t('globals.createInvoiceIn') }}
</QTooltip> </QTooltip>
</QBtn> </QBtn>
</QCard> </QCard>
@ -267,7 +267,6 @@ onUnmounted(() => (stateStore.rightDrawer = false));
es: es:
Search autonomous: Buscar autónomos Search autonomous: Buscar autónomos
You can search by autonomous reference: Puedes buscar por referencia del autónomo You can search by autonomous reference: Puedes buscar por referencia del autónomo
Create invoiceIn: Crear factura recibida
Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo
Date: Fecha Date: Fecha
Agency route: Agencia Ruta Agency route: Agencia Ruta

View File

@ -177,7 +177,7 @@ const getEntryQueryParams = (supplier) => {
icon="vn:invoice-in-create" icon="vn:invoice-in-create"
color="primary" color="primary"
> >
<QTooltip>{{ t('Create invoiceIn') }}</QTooltip> <QTooltip>{{ t('globals.createInvoiceIn') }}</QTooltip>
</QBtn> </QBtn>
</QCardActions> </QCardActions>
</template> </template>
@ -188,7 +188,6 @@ const getEntryQueryParams = (supplier) => {
es: es:
All entries with current supplier: Todas las entradas con proveedor actual All entries with current supplier: Todas las entradas con proveedor actual
Go to client: Ir a cliente Go to client: Ir a cliente
Create invoiceIn: Crear factura recibida
Go to module index: Ir al índice del módulo Go to module index: Ir al índice del módulo
Inactive supplier: Proveedor inactivo Inactive supplier: Proveedor inactivo
Unverified supplier: Proveedor no verificado Unverified supplier: Proveedor no verificado

View File

@ -1,8 +1,9 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
describe('InvoiceInIntrastat', () => { describe('InvoiceInIntrastat', () => {
const inputBtns = 'label button'; const firstRow = 'tbody > :nth-child(1)';
const thirdRow = 'tbody > :nth-child(3)'; const thirdRow = 'tbody > :nth-child(3)';
const firstLineCode = 'tbody > :nth-child(1) > :nth-child(2)'; const firstRowCode = `${firstRow} > :nth-child(2)`;
const firstRowAmount = `${firstRow} > :nth-child(3)`;
beforeEach(() => { beforeEach(() => {
cy.login('developer'); cy.login('developer');
@ -10,10 +11,10 @@ describe('InvoiceInIntrastat', () => {
}); });
it('should edit the first line', () => { it('should edit the first line', () => {
cy.selectOption(firstLineCode, 'Plantas vivas: Esqueje/injerto, Vid'); cy.selectOption(firstRowCode, 'Plantas vivas: Esqueje/injerto, Vid');
cy.get(inputBtns).eq(1).click(); cy.get(firstRowAmount).clear();
cy.saveCard(); cy.saveCard();
cy.get(`${firstLineCode} span`).should( cy.get(`${firstRowCode} span`).should(
'have.text', 'have.text',
'6021010:Plantas vivas: Esqueje/injerto, Vid' '6021010:Plantas vivas: Esqueje/injerto, Vid'
); );

View File

@ -1,23 +1,23 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
describe('InvoiceInList', () => { describe('InvoiceInList', () => {
const firstCard = '.q-card:nth-child(1)'; const firstRow = 'tbody.q-virtual-scroll__content tr:nth-child(1)';
const firstChipId = const firstId = `${firstRow} > td:nth-child(1) span`;
':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content'; const firstDetailBtn = `${firstRow} .q-btn:nth-child(1)`;
const firstDetailBtn = '.q-card:nth-child(1) .q-btn:nth-child(2)';
const summaryHeaders = '.summaryBody .header-link'; const summaryHeaders = '.summaryBody .header-link';
beforeEach(() => { beforeEach(() => {
cy.viewport(1920, 1080); cy.viewport(1920, 1080);
cy.login('developer'); cy.login('developer');
cy.visit(`/#/invoice-in/list`); cy.visit(`/#/invoice-in/list`);
cy.get('#searchbar input').type('{enter}');
}); });
it('should redirect on clicking a invoice', () => { it('should redirect on clicking a invoice', () => {
cy.get(firstChipId) cy.get(firstId)
.invoke('text') .invoke('text')
.then((content) => { .then((content) => {
const id = content.replace(/\D/g, ''); const id = content.replace(/\D/g, '');
cy.get(firstCard).click(); cy.get(firstRow).click();
cy.url().should('include', `/invoice-in/${id}/summary`); cy.url().should('include', `/invoice-in/${id}/summary`);
}); });
}); });

View File

@ -4,8 +4,7 @@ describe('InvoiceInVat', () => {
const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)'; const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)';
const dialogInputs = '.q-dialog label input'; const dialogInputs = '.q-dialog label input';
const dialogBtns = '.q-dialog button'; const dialogBtns = '.q-dialog button';
const acrossInput = const acrossInput = 'tbody tr:nth-child(1) td:nth-child(2) .default-icon';
':nth-child(1) > .q-td.q-table--col-auto-width > .q-field > .q-field__inner > .q-field__control > :nth-child(2) > .default-icon';
const randomInt = Math.floor(Math.random() * 100); const randomInt = Math.floor(Math.random() * 100);
beforeEach(() => { beforeEach(() => {