perf: refs #8197 fix and imrpove filters #1234

Merged
alexm merged 6 commits from 8197-fix_filters into dev 2025-01-21 10:48:32 +00:00
13 changed files with 237 additions and 142 deletions
Showing only changes of commit a2499f11e1 - Show all commits

View File

@ -16,6 +16,7 @@ import getUpdatedValues from './getUpdatedValues';
import getParamWhere from './getParamWhere';
import parsePhone from './parsePhone';
import isDialogOpened from './isDialogOpened';
import toCelsius from './toCelsius';
export {
getUpdatedValues,
@ -36,4 +37,5 @@ export {
dashIfEmpty,
dateRange,
getParamWhere,
toCelsius,
};

3
src/filters/toCelsius.js Normal file
View File

@ -0,0 +1,3 @@
export default function toCelsius(value) {
return value ? `${value}°C` : '';
}

View File

@ -3,7 +3,6 @@ import { ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useRole } from 'src/composables/useRole';
import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
@ -11,7 +10,7 @@ import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
import FilterTravelForm from 'src/components/FilterTravelForm.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import { toDate } from 'src/filters';
const route = useRoute();
@ -26,6 +25,7 @@ const onFilterTravelSelected = (formData, id) => {
formData.travelFk = id;
};
</script>
<template>
<FetchData
ref="companiesRef"
@ -93,14 +93,13 @@ const onFilterTravelSelected = (formData, id) => {
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel
>{{ scope.opt?.agencyModeName }} -
{{ scope.opt?.warehouseInName }} ({{
toDate(scope.opt?.shipped)
}}) &#x2192; {{ scope.opt?.warehouseOutName }} ({{
toDate(scope.opt?.landed)
}})</QItemLabel
>
<QItemLabel>
{{ scope.opt?.agencyModeName }} -
{{ scope.opt?.warehouseInName }}
({{ toDate(scope.opt?.shipped) }})
{{ scope.opt?.warehouseOutName }}
({{ toDate(scope.opt?.landed) }})
</QItemLabel>
</QItemSection>
</QItem>
</template>
@ -126,6 +125,13 @@ const onFilterTravelSelected = (formData, id) => {
/>
</VnRow>
<VnRow>
<VnInputNumber
:label="t('entry.summary.commission')"
v-model="data.commission"
step="1"
autofocus
:positive="false"
/>
<VnSelect
:label="t('entry.summary.currency')"
v-model="data.currencyFk"
@ -133,12 +139,23 @@ const onFilterTravelSelected = (formData, id) => {
option-value="id"
option-label="code"
/>
<QInput
:label="t('entry.summary.commission')"
v-model="data.commission"
type="number"
autofocus
min="0"
</VnRow>
<VnRow>
<VnInputNumber
v-model="data.initialTemperature"
name="initialTemperature"
:label="t('entry.basicData.initialTemperature')"
:step="0.5"
:decimal-places="2"
:positive="false"
/>
<VnInputNumber
v-model="data.finalTemperature"
name="finalTemperature"
:label="t('entry.basicData.finalTemperature')"
:step="0.5"
:decimal-places="2"
:positive="false"
/>
</VnRow>
<VnRow>

View File

@ -7,7 +7,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
import { toDate, toCurrency } from 'src/filters';
import { toDate, toCurrency, toCelsius } from 'src/filters';
import { getUrl } from 'src/composables/getUrl';
import axios from 'axios';
import FetchedTags from 'src/components/ui/FetchedTags.vue';
@ -193,6 +193,14 @@ const fetchEntryBuys = async () => {
:label="t('entry.summary.invoiceNumber')"
:value="entry.invoiceNumber"
/>
<VnLv
:label="t('entry.basicData.initialTemperature')"
:value="toCelsius(entry.initialTemperature)"
/>
<VnLv
:label="t('entry.basicData.finalTemperature')"
:value="toCelsius(entry.finalTemperature)"
/>
</QCard>
<QCard class="vn-one">
<VnTitle

View File

@ -3,7 +3,7 @@ import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import EntryFilter from './EntryFilter.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import { toDate } from 'src/filters';
import { toCelsius, toDate } from 'src/filters';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import EntrySummary from './Card/EntrySummary.vue';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
@ -157,6 +157,20 @@ const columns = computed(() => [
name: 'invoiceAmount',
cardVisible: true,
},
{
align: 'left',
name: 'initialTemperature',
label: t('entry.basicData.initialTemperature'),
field: 'initialTemperature',
format: (row) => toCelsius(row.initialTemperature),
},
{
align: 'left',
name: 'finalTemperature',
label: t('entry.basicData.finalTemperature'),
field: 'finalTemperature',
format: (row) => toCelsius(row.finalTemperature),
},
{
label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
name: 'isExcludedFromAvailable',

View File

@ -40,6 +40,8 @@ entry:
observation: Observation
booked: Booked
excludedFromAvailable: Inventory
initialTemperature: Ini °C
finalTemperature: Fin °C
buys:
observations: Observations
packagingFk: Box

View File

@ -41,6 +41,8 @@ entry:
commission: Comisión
booked: Asentado
excludedFromAvailable: Inventario
initialTemperature: Ini °C
finalTemperature: Fin °C
buys:
observations: Observaciónes
packagingFk: Embalaje

View File

@ -6,24 +6,16 @@ import axios from 'axios';
import { toCurrency, toDate } from 'src/filters';
import VnLv from 'src/components/ui/VnLv.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import { useCapitalize } from 'src/composables/useCapitalize';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue';
const $props = defineProps({ id: { type: Number, default: null } });
const { push, currentRoute } = useRouter();
const { currentRoute } = useRouter();
const { t } = useI18n();
const cardDescriptorRef = ref();
const correctionDialogRef = ref();
const entityId = computed(() => $props.id || +currentRoute.value.params.id);
const totalAmount = ref();
const config = ref();
const cplusRectificationTypes = ref([]);
const siiTypeInvoiceIns = ref([]);
const invoiceCorrectionTypes = ref([]);
const filter = {
include: [
@ -85,12 +77,6 @@ const routes = reactive({
return { name: 'EntryCard', params: { id } };
},
});
const correctionFormData = reactive({
invoiceReason: 2,
invoiceType: 2,
invoiceClass: 6,
});
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
onBeforeMount(async () => {
await setInvoiceCorrection(entityId.value);
@ -122,38 +108,8 @@ async function setInvoiceCorrection(id) {
(corrected) => corrected.correctingFk
);
}
const createInvoiceInCorrection = async () => {
const { data: correctingId } = await axios.post(
'InvoiceIns/corrective',
Object.assign(correctionFormData, { id: entityId.value })
);
push({ path: `/invoice-in/${correctingId}/summary` });
};
</script>
<template>
<FetchData
url="InvoiceInConfigs"
:where="{ fields: ['sageWithholdingFk'] }"
auto-load
@on-fetch="(data) => (config = data)"
/>
<FetchData
url="CplusRectificationTypes"
@on-fetch="(data) => (cplusRectificationTypes = data)"
auto-load
/>
<FetchData
url="SiiTypeInvoiceIns"
:where="{ code: { like: 'R%' } }"
@on-fetch="(data) => (siiTypeInvoiceIns = data)"
auto-load
/>
<FetchData
url="InvoiceCorrectionTypes"
@on-fetch="(data) => (invoiceCorrectionTypes = data)"
auto-load
/>
<CardDescriptor
ref="cardDescriptorRef"
module="InvoiceIn"
@ -167,7 +123,10 @@ const createInvoiceInCorrection = async () => {
</template>
<template #body="{ entity }">
<VnLv :label="t('invoicein.list.issued')" :value="toDate(entity.issued)" />
<VnLv :label="t('invoicein.summary.bookedDate')" :value="toDate(entity.booked)" />
<VnLv
:label="t('invoicein.summary.bookedDate')"
:value="toDate(entity.booked)"
/>
<VnLv :label="t('invoicein.list.amount')" :value="toCurrency(totalAmount)" />
<VnLv :label="t('invoicein.list.supplier')">
<template #value>
@ -227,65 +186,6 @@ const createInvoiceInCorrection = async () => {
</QCardActions>
</template>
</CardDescriptor>
<QDialog ref="correctionDialogRef">
<QCard>
<QCardSection>
<QItem class="q-px-none">
<span class="text-primary text-h6 full-width">
{{ t('Create rectificative invoice') }}
</span>
<QBtn icon="close" flat round dense v-close-popup />
</QItem>
</QCardSection>
<QCardSection>
<QItem>
<QItemSection>
<QInput
:label="t('Original invoice')"
v-model="entityId"
readonly
/>
<VnSelect
:label="`${useCapitalize(t('globals.class'))}`"
v-model="correctionFormData.invoiceClass"
:options="siiTypeInvoiceIns"
option-value="id"
option-label="code"
:required="true"
/>
</QItemSection>
<QItemSection>
<VnSelect
:label="`${useCapitalize(t('globals.type'))}`"
v-model="correctionFormData.invoiceType"
:options="cplusRectificationTypes"
option-value="id"
option-label="description"
:required="true"
/>
<VnSelect
:label="`${useCapitalize(t('globals.reason'))}`"
v-model="correctionFormData.invoiceReason"
:options="invoiceCorrectionTypes"
option-value="id"
option-label="description"
:required="true"
/>
</QItemSection>
</QItem>
</QCardSection>
<QCardActions class="justify-end q-mr-sm">
<QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
<QBtn
:label="t('globals.save')"
color="primary"
v-close-popup
@click="createInvoiceInCorrection"
:disable="isNotFilled"
/>
</QCardActions>
</QCard>
</QDialog>
</template>
<style lang="scss" scoped>
.q-dialog {

View File

@ -8,9 +8,12 @@ import { useAcl } from 'src/composables/useAcl';
import { downloadFile } from 'src/composables/downloadFile';
import { useArrayData } from 'src/composables/useArrayData';
import { usePrintService } from 'composables/usePrintService';
import { useCapitalize } from 'src/composables/useCapitalize';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import InvoiceInToBook from '../InvoiceInToBook.vue';
import FetchData from 'src/components/FetchData.vue';
const { hasAny } = useAcl();
const { t } = useI18n();
@ -31,6 +34,10 @@ const correctionDialogRef = ref();
const invoiceInCorrection = reactive({ correcting: [], corrected: null });
const entityId = computed(() => $props.invoice.id || +currentRoute.value.params.id);
const invoiceIn = computed(() => arrayData.store.data);
const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
const invoiceCorrectionTypes = ref([]);
const cplusRectificationTypes = ref([]);
const siiTypeInvoiceIns = ref([]);
const actions = {
unbook: {
title: t('assertAction', { action: t('invoicein.descriptorMenu.unbook') }),
@ -48,6 +55,11 @@ const actions = {
sendPdf: { cb: sendPdfInvoiceConfirmation },
correct: { cb: () => correctionDialogRef.value.show() },
};
const correctionFormData = reactive({
invoiceReason: 2,
invoiceType: 2,
invoiceClass: 8,
});
const canEditProp = (props) =>
hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]);
@ -133,9 +145,39 @@ function sendPdfInvoice({ address }) {
recipient: address,
});
}
const createInvoiceInCorrection = async () => {
const { data: correctingId } = await axios.post(
'InvoiceIns/corrective',
Object.assign(correctionFormData, { id: entityId.value })
);
push({ path: `/invoice-in/${correctingId}/summary` });
};
</script>
<template>
<FetchData
url="InvoiceCorrectionTypes"
@on-fetch="(data) => (invoiceCorrectionTypes = data)"
auto-load
/>
<FetchData
url="CplusRectificationTypes"
@on-fetch="(data) => (cplusRectificationTypes = data)"
auto-load
/>
<FetchData
url="SiiTypeInvoiceIns"
:where="{ code: { like: 'R%' } }"
@on-fetch="(data) => (siiTypeInvoiceIns = data)"
auto-load
/>
<FetchData
url="InvoiceInConfigs"
:where="{ fields: ['sageWithholdingFk'] }"
auto-load
@on-fetch="(data) => (config = data)"
/>
<InvoiceInToBook>
<template #content="{ book }">
<QItem
@ -162,7 +204,7 @@ function sendPdfInvoice({ address }) {
v-if="canEditProp('deleteById')"
v-ripple
clickable
@click="triggerMenu('invoicein.descriptorMenu.delete')"
@click="triggerMenu('delete')"
>
<QItemSection>{{ t('invoicein.descriptorMenu.deleteInvoice') }}</QItemSection>
</QItem>
@ -192,6 +234,79 @@ function sendPdfInvoice({ address }) {
<QItem v-if="invoice.dmsFk" v-ripple clickable @click="downloadFile(invoice.dmsFk)">
<QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection>
</QItem>
<QDialog ref="correctionDialogRef">
<QCard>
<QCardSection>
<QItem class="q-px-none">
<span class="text-primary text-h6 full-width">
{{ t('Create rectificative invoice') }}
</span>
<QBtn icon="close" flat round dense v-close-popup />
</QItem>
</QCardSection>
<QCardSection>
<QItem>
<QItemSection>
<QInput
:label="t('Original invoice')"
v-model="entityId"
readonly
/>
<VnSelect
:label="`${useCapitalize(t('globals.class'))}`"
v-model="correctionFormData.invoiceClass"
:options="siiTypeInvoiceIns"
option-value="id"
option-label="code"
:required="true"
/>
</QItemSection>
<QItemSection>
<VnSelect
:label="`${useCapitalize(t('globals.type'))}`"
v-model="correctionFormData.invoiceType"
:options="cplusRectificationTypes"
option-value="id"
option-label="description"
:required="true"
>
<template #option="{ itemProps, opt }">
<QItem v-bind="itemProps">
{{ console.log('opt: ', opt) }}
<QItemSection>
<QItemLabel
>{{ opt.id }} -
{{ opt.description }}</QItemLabel
>
</QItemSection>
</QItem>
<div></div>
</template>
</VnSelect>
<VnSelect
:label="`${useCapitalize(t('globals.reason'))}`"
v-model="correctionFormData.invoiceReason"
:options="invoiceCorrectionTypes"
option-value="id"
option-label="description"
:required="true"
/>
</QItemSection>
</QItem>
</QCardSection>
<QCardActions class="justify-end q-mr-sm">
<QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
<QBtn
:label="t('globals.save')"
color="primary"
v-close-popup
@click="createInvoiceInCorrection"
:disable="isNotFilled"
/>
</QCardActions>
</QCard>
</QDialog>
</template>
<i18n>

View File

@ -90,6 +90,11 @@ const columns = computed(() => [
field: (row) => row.foreignValue,
align: 'left',
},
{
name: 'total',
label: 'Total',
align: 'left',
},
]);
const filter = {
@ -131,6 +136,24 @@ function autocompleteExpense(evt, row, col) {
expenseRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
}
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;
});
</script>
<template>
<FetchData
@ -272,26 +295,20 @@ function autocompleteExpense(evt, row, col) {
<QTd />
<QTd />
<QTd>
{{ getTotal(rows, 'taxableBase', { currency: 'default' }) }}
{{ toCurrency(taxableBaseTotal) }}
</QTd>
<QTd />
<QTd />
<QTd>
{{
getTotal(rows, null, { cb: taxRate, currency: 'default' })
}}</QTd
>
{{ toCurrency(taxRateTotal) }}
</QTd>
<QTd />
<QTd>
<template v-if="isNotEuro(invoiceIn.currency.code)">
{{
getTotal(rows, 'foreignValue', {
currency: invoiceIn.currency.code,
})
}}
</template>
{{ toCurrency(combinedTotal) }}
</QTd>
</QTr>
</template>
<template #item="props">
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
<QCard bordered flat class="q-my-xs">

View File

@ -169,6 +169,7 @@ async function handleSave() {
:roles-allowed-to-create="['administrative']"
option-value="id"
hide-selected
sort-by="name ASC"
>
<template #form>
<TicketCreateServiceType

View File

@ -9,7 +9,7 @@ import VnTitle from 'src/components/common/VnTitle.vue';
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
import FetchData from 'src/components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue';
import { toDate, toCurrency } from 'src/filters';
import { toDate, toCurrency, toCelsius } from 'src/filters';
import axios from 'axios';
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
@ -97,6 +97,20 @@ const entriesTableColumns = computed(() => {
showValue: true,
},
{ label: 'm³', field: 'm3', name: 'm3', align: 'left', showValue: true },
{
label: t('entry.basicData.initialTemperature'),
field: 'initialTemperature',
name: 'initialTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{
label: t('entry.basicData.finalTemperature'),
field: 'finalTemperature',
name: 'finalTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{
label: '',
field: 'observation',
@ -127,14 +141,14 @@ const thermographsTableColumns = computed(() => {
field: 'maxTemperature',
name: 'maxTemperature',
align: 'left',
format: (val) => (val ? `${val}°` : ''),
format: (val) => toCelsius(val),
},
{
label: t('globals.minTemperature'),
field: 'minTemperature',
name: 'minTemperature',
align: 'left',
format: (val) => (val ? `${val}°` : ''),
format: (val) => toCelsius(val),
},
{
label: t('globals.state'),

View File

@ -10,7 +10,7 @@ import FetchData from 'src/components/FetchData.vue';
import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
import { toDate } from 'src/filters';
import { toDate, toCelsius } from 'src/filters';
import { downloadFile } from 'src/composables/downloadFile';
const route = useRoute();
@ -52,14 +52,14 @@ const TableColumns = computed(() => {
field: 'maxTemperature',
name: 'maxTemperature',
align: 'left',
format: (val) => (val ? `${val}°` : ''),
format: (val) => toCelsius(val),
},
{
label: t('globals.minTemperature'),
field: 'minTemperature',
name: 'minTemperature',
align: 'left',
format: (val) => (val ? `${val}°` : ''),
format: (val) => toCelsius(val),
},
{
label: t('globals.state'),