forked from verdnatura/salix-front
fix: refs #6942 wip: formModel
This commit is contained in:
parent
467531d029
commit
5bddc6e04d
|
@ -11,6 +11,7 @@ import useNotify from 'src/composables/useNotify.js';
|
|||
import SkeletonForm from 'components/ui/SkeletonForm.vue';
|
||||
import VnConfirm from './ui/VnConfirm.vue';
|
||||
import { tMobile } from 'src/composables/tMobile';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
|
||||
const { push } = useRouter();
|
||||
const quasar = useQuasar();
|
||||
|
@ -85,28 +86,66 @@ const $props = defineProps({
|
|||
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
||||
|
||||
const componentIsRendered = ref(false);
|
||||
const arrayData = useArrayData($props.model);
|
||||
const isLoading = ref(false);
|
||||
// Si elegimos observar los cambios del form significa que inicialmente las actions estaran deshabilitadas
|
||||
const isResetting = ref(false);
|
||||
const hasChanges = ref(!$props.observeFormChanges);
|
||||
const originalData = ref({});
|
||||
const formData = computed(() => state.get($props.model));
|
||||
const formUrl = computed(() => $props.url);
|
||||
const defaultButtons = computed(() => ({
|
||||
save: {
|
||||
color: 'primary',
|
||||
icon: 'save',
|
||||
label: 'globals.save',
|
||||
},
|
||||
reset: {
|
||||
color: 'primary',
|
||||
icon: 'restart_alt',
|
||||
label: 'globals.reset',
|
||||
},
|
||||
...$props.defaultButtons,
|
||||
}));
|
||||
|
||||
onMounted(async () => {
|
||||
originalData.value = $props.formInitialData;
|
||||
nextTick(() => {
|
||||
componentIsRendered.value = true;
|
||||
});
|
||||
|
||||
nextTick(() => (componentIsRendered.value = true));
|
||||
|
||||
// Podemos enviarle al form la estructura de data inicial sin necesidad de fetchearla
|
||||
state.set($props.model, $props.formInitialData);
|
||||
if ($props.autoLoad && !$props.formInitialData) {
|
||||
await fetch();
|
||||
if ($props.autoLoad && !$props.formInitialData && $props.url) await fetch();
|
||||
else if (arrayData.store.data) {
|
||||
state.set($props.model, arrayData.store.data);
|
||||
|
||||
emit('onFetch', state.get($props.model));
|
||||
}
|
||||
|
||||
// Si así se desea disparamos el watcher del form después de 100ms, asi darle tiempo de que se haya cargado la data inicial
|
||||
// para evitar que detecte cambios cuando es data inicial default
|
||||
if ($props.observeFormChanges) {
|
||||
setTimeout(() => {
|
||||
startFormWatcher();
|
||||
}, 100);
|
||||
watch(
|
||||
() => formData.value,
|
||||
(val) => {
|
||||
hasChanges.value = !isResetting.value && val;
|
||||
isResetting.value = false;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
if (!$props.url)
|
||||
watch(
|
||||
() => arrayData.store.data,
|
||||
(val) => updateAndEmit(val, 'onFetch')
|
||||
);
|
||||
|
||||
watch(formUrl, async () => {
|
||||
originalData.value = null;
|
||||
reset();
|
||||
fetch();
|
||||
});
|
||||
|
||||
onBeforeRouteLeave((to, from, next) => {
|
||||
if (hasChanges.value && $props.observeFormChanges)
|
||||
quasar.dialog({
|
||||
|
@ -129,49 +168,14 @@ onUnmounted(() => {
|
|||
if ($props.clearStoreOnUnmount) state.unset($props.model);
|
||||
});
|
||||
|
||||
const isLoading = ref(false);
|
||||
// Si elegimos observar los cambios del form significa que inicialmente las actions estaran deshabilitadas
|
||||
const isResetting = ref(false);
|
||||
const hasChanges = ref(!$props.observeFormChanges);
|
||||
const originalData = ref({});
|
||||
const formData = computed(() => state.get($props.model));
|
||||
const formUrl = computed(() => $props.url);
|
||||
const defaultButtons = computed(() => ({
|
||||
save: {
|
||||
color: 'primary',
|
||||
icon: 'save',
|
||||
label: 'globals.save',
|
||||
},
|
||||
reset: {
|
||||
color: 'primary',
|
||||
icon: 'restart_alt',
|
||||
label: 'globals.reset',
|
||||
},
|
||||
...$props.defaultButtons,
|
||||
}));
|
||||
const startFormWatcher = () => {
|
||||
watch(
|
||||
() => formData.value,
|
||||
(val) => {
|
||||
hasChanges.value = !isResetting.value && val;
|
||||
isResetting.value = false;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
};
|
||||
|
||||
async function fetch() {
|
||||
try {
|
||||
let { data } = await axios.get($props.url, {
|
||||
params: { filter: JSON.stringify($props.filter) },
|
||||
});
|
||||
|
||||
if (Array.isArray(data)) data = data[0] ?? {};
|
||||
|
||||
state.set($props.model, data);
|
||||
originalData.value = data && JSON.parse(JSON.stringify(data));
|
||||
|
||||
emit('onFetch', state.get($props.model));
|
||||
updateAndEmit(data, 'onFetch');
|
||||
} catch (error) {
|
||||
state.set($props.model, {});
|
||||
originalData.value = {};
|
||||
|
@ -179,31 +183,30 @@ async function fetch() {
|
|||
}
|
||||
|
||||
async function save() {
|
||||
if ($props.observeFormChanges && !hasChanges.value) {
|
||||
notify('globals.noChanges', 'negative');
|
||||
return;
|
||||
}
|
||||
isLoading.value = true;
|
||||
if ($props.observeFormChanges && !hasChanges.value)
|
||||
return notify('globals.noChanges', 'negative');
|
||||
|
||||
isLoading.value = true;
|
||||
try {
|
||||
const body = $props.mapper ? $props.mapper(formData.value) : formData.value;
|
||||
const method = $props.urlCreate ? 'post' : 'patch';
|
||||
const url =
|
||||
$props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url;
|
||||
let response;
|
||||
|
||||
if ($props.saveFn) response = await $props.saveFn(body);
|
||||
else
|
||||
response = await axios[$props.urlCreate ? 'post' : 'patch'](
|
||||
$props.urlCreate || $props.urlUpdate || $props.url,
|
||||
body
|
||||
);
|
||||
else response = await axios[method](url, body);
|
||||
|
||||
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
|
||||
|
||||
emit('onDataSaved', formData.value, response?.data);
|
||||
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
||||
updateAndEmit(response?.data, 'onDataSaved');
|
||||
hasChanges.value = false;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
notify('errors.writeRequest', 'negative');
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
async function saveAndGo() {
|
||||
|
@ -212,10 +215,7 @@ async function saveAndGo() {
|
|||
}
|
||||
|
||||
function reset() {
|
||||
state.set($props.model, originalData.value);
|
||||
originalData.value = JSON.parse(JSON.stringify(originalData.value));
|
||||
|
||||
emit('onFetch', state.get($props.model));
|
||||
updateAndEmit(originalData.value, 'onFetch');
|
||||
if ($props.observeFormChanges) {
|
||||
hasChanges.value = false;
|
||||
isResetting.value = true;
|
||||
|
@ -237,17 +237,15 @@ function filter(value, update, filterOptions) {
|
|||
);
|
||||
}
|
||||
|
||||
watch(formUrl, async () => {
|
||||
originalData.value = null;
|
||||
reset();
|
||||
fetch();
|
||||
});
|
||||
function updateAndEmit(val, evt) {
|
||||
state.set($props.model, val);
|
||||
originalData.value = val && JSON.parse(JSON.stringify(val));
|
||||
if (!$props.url) arrayData.store.data = val;
|
||||
|
||||
defineExpose({
|
||||
save,
|
||||
isLoading,
|
||||
hasChanges,
|
||||
});
|
||||
emit(evt, state.get($props.model));
|
||||
}
|
||||
|
||||
defineExpose({ save, isLoading, hasChanges });
|
||||
</script>
|
||||
<template>
|
||||
<div class="column items-center full-width">
|
||||
|
|
|
@ -49,12 +49,13 @@ const { store } = arrayData;
|
|||
const entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
|
||||
const isLoading = ref(false);
|
||||
|
||||
defineExpose({
|
||||
getData,
|
||||
});
|
||||
defineExpose({ getData });
|
||||
onBeforeMount(async () => {
|
||||
await getData();
|
||||
watch($props, async () => await getData());
|
||||
watch(
|
||||
() => [$props.url, $props.filter],
|
||||
async () => await getData()
|
||||
);
|
||||
});
|
||||
|
||||
async function getData() {
|
||||
|
|
|
@ -24,6 +24,7 @@ globals:
|
|||
create: Create
|
||||
edit: Edit
|
||||
save: Save
|
||||
saveAndContinue: Save and continue
|
||||
remove: Remove
|
||||
reset: Reset
|
||||
close: Close
|
||||
|
|
|
@ -24,6 +24,7 @@ globals:
|
|||
create: Crear
|
||||
edit: Modificar
|
||||
save: Guardar
|
||||
saveAndContinue: Guardar y continuar
|
||||
remove: Eliminar
|
||||
reset: Restaurar
|
||||
close: Cerrar
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import axios from 'axios';
|
||||
|
@ -14,15 +14,13 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const { currentRoute } = useRouter();
|
||||
const { t } = useI18n();
|
||||
|
||||
const dms = ref({});
|
||||
const editDownloadDisabled = ref(false);
|
||||
const arrayData = useArrayData('InvoiceIn');
|
||||
const invoiceIn = computed(() => arrayData.store.data);
|
||||
const invoiceIn = computed(() => useArrayData('InvoiceIn').store.data);
|
||||
const userConfig = ref(null);
|
||||
const invoiceId = currentRoute.value.params.id;
|
||||
const invoiceId = computed(() => +useRoute().params.id);
|
||||
|
||||
const expenses = ref([]);
|
||||
const currencies = ref([]);
|
||||
|
@ -180,13 +178,7 @@ async function upsert() {
|
|||
auto-load
|
||||
@on-fetch="(data) => (sageWithholdings = data)"
|
||||
/>
|
||||
<FormModel
|
||||
v-if="invoiceIn"
|
||||
:url="`InvoiceIns/${invoiceId}`"
|
||||
model="InvoiceIn"
|
||||
:go-to="`/invoice-in/${invoiceId}/vat`"
|
||||
auto-load
|
||||
>
|
||||
<FormModel model="InvoiceIn" :go-to="`/invoice-in/${invoiceId}/vat`" auto-load>
|
||||
<template #form="{ data }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
|
|
|
@ -6,7 +6,6 @@ import { useQuasar } from 'quasar';
|
|||
import axios from 'axios';
|
||||
import { toCurrency, toDate } from 'src/filters';
|
||||
import { useRole } from 'src/composables/useRole';
|
||||
import useCardDescription from 'src/composables/useCardDescription';
|
||||
import { downloadFile } from 'src/composables/downloadFile';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { usePrintService } from 'composables/usePrintService';
|
||||
|
@ -20,9 +19,7 @@ import { useCapitalize } from 'src/composables/useCapitalize';
|
|||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||
import InvoiceInToBook from '../InvoiceInToBook.vue';
|
||||
|
||||
const $props = defineProps({
|
||||
id: { type: Number, default: null },
|
||||
});
|
||||
const $props = defineProps({ id: { type: Number, default: null } });
|
||||
|
||||
const { push, currentRoute } = useRouter();
|
||||
|
||||
|
@ -33,7 +30,6 @@ const { openReport, sendEmail } = usePrintService();
|
|||
const { store } = useArrayData('InvoiceIn');
|
||||
|
||||
const invoiceIn = computed(() => store.data);
|
||||
const isBooked = ref();
|
||||
const cardDescriptorRef = ref();
|
||||
const correctionDialogRef = ref();
|
||||
const entityId = computed(() => $props.id || +currentRoute.value.params.id);
|
||||
|
@ -92,11 +88,7 @@ const filter = {
|
|||
},
|
||||
],
|
||||
};
|
||||
const data = ref(useCardDescription());
|
||||
const invoiceInCorrection = reactive({
|
||||
correcting: [],
|
||||
corrected: null,
|
||||
});
|
||||
const invoiceInCorrection = reactive({ correcting: [], corrected: null });
|
||||
const routes = reactive({
|
||||
getSupplier: (id) => {
|
||||
return { name: 'SupplierCard', params: { id } };
|
||||
|
@ -177,16 +169,9 @@ async function setInvoiceCorrection(id) {
|
|||
);
|
||||
}
|
||||
|
||||
async function setData(entity) {
|
||||
data.value = useCardDescription(entity.supplierRef, entity.id);
|
||||
isBooked.value = entity.isBooked;
|
||||
const { totalDueDay } = await getTotals();
|
||||
totalAmount.value = totalDueDay;
|
||||
}
|
||||
|
||||
async function getTotals() {
|
||||
async function setTotals() {
|
||||
const { data } = await axios.get(`InvoiceIns/${entityId.value}/getTotals`);
|
||||
return data;
|
||||
totalAmount.value = data.totalDueDay;
|
||||
}
|
||||
|
||||
function openDialog() {
|
||||
|
@ -303,16 +288,17 @@ const createInvoiceInCorrection = async () => {
|
|||
auto-load
|
||||
/>
|
||||
<CardDescriptor
|
||||
v-if="invoiceIn"
|
||||
ref="cardDescriptorRef"
|
||||
module="InvoiceIn"
|
||||
:url="`InvoiceIns/${entityId}`"
|
||||
:filter="filter"
|
||||
:title="data.title"
|
||||
:subtitle="data.subtitle"
|
||||
@on-fetch="setData"
|
||||
data-key="invoiceInData"
|
||||
:title="invoiceIn.supplierRef"
|
||||
:subtitle="invoiceIn.id"
|
||||
data-key="InvoiceIn"
|
||||
@on-fetch="setTotals"
|
||||
>
|
||||
<template #menu="{ entity }">
|
||||
<template #menu>
|
||||
<InvoiceInToBook>
|
||||
<template #content="{ book }">
|
||||
<QItem
|
||||
|
@ -378,17 +364,20 @@ const createInvoiceInCorrection = async () => {
|
|||
<QItemSection>{{ t('Create rectificative invoice') }}...</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
v-if="entity.dmsFk"
|
||||
v-if="invoiceIn.dmsFk"
|
||||
v-ripple
|
||||
clickable
|
||||
@click="downloadFile(entity.dmsFk)"
|
||||
@click="downloadFile(invoiceIn.dmsFk)"
|
||||
>
|
||||
<QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<VnLv :label="t('invoiceIn.card.issued')" :value="toDate(entity.issued)" />
|
||||
<VnLv :label="t('invoiceIn.summary.booked')" :value="toDate(entity.booked)" />
|
||||
<template #body>
|
||||
<VnLv :label="t('invoiceIn.card.issued')" :value="toDate(invoiceIn.issued)" />
|
||||
<VnLv
|
||||
:label="t('invoiceIn.summary.booked')"
|
||||
:value="toDate(invoiceIn.booked)"
|
||||
/>
|
||||
<VnLv :label="t('invoiceIn.card.amount')" :value="toCurrency(totalAmount)" />
|
||||
<VnLv :label="t('invoiceIn.summary.supplier')">
|
||||
<template #value>
|
||||
|
@ -399,13 +388,13 @@ const createInvoiceInCorrection = async () => {
|
|||
</template>
|
||||
</VnLv>
|
||||
</template>
|
||||
<template #actions="{ entity }">
|
||||
<template #action>
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
size="md"
|
||||
icon="vn:supplier"
|
||||
color="primary"
|
||||
:to="routes.getSupplier(entity.supplierFk)"
|
||||
:to="routes.getSupplier(invoiceIn.supplierFk)"
|
||||
>
|
||||
<QTooltip>{{ t('invoiceIn.list.supplier') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -413,7 +402,7 @@ const createInvoiceInCorrection = async () => {
|
|||
size="md"
|
||||
icon="vn:entry"
|
||||
color="primary"
|
||||
:to="routes.getEntry(entity.entryFk)"
|
||||
:to="routes.getEntry(invoiceIn.entryFk)"
|
||||
>
|
||||
<QTooltip>{{ t('Entry') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -421,7 +410,7 @@ const createInvoiceInCorrection = async () => {
|
|||
size="md"
|
||||
icon="vn:ticket"
|
||||
color="primary"
|
||||
:to="routes.getTickets(entity.supplierFk)"
|
||||
:to="routes.getTickets(invoiceIn.supplierFk)"
|
||||
>
|
||||
<QTooltip>{{ t('invoiceOut.card.ticketList') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -11,7 +11,7 @@ import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorP
|
|||
import InvoiceIntoBook from '../InvoiceInToBook.vue';
|
||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||
|
||||
const props = defineProps({ id: { type: Number, default: 0 } });
|
||||
const props = defineProps({ id: { type: [Number, String], default: 0 } });
|
||||
const { t } = useI18n();
|
||||
|
||||
const entityId = computed(() => props.id || useRoute().params.id);
|
||||
|
@ -20,7 +20,6 @@ const invoiceIn = computed(() => useArrayData('InvoiceIn').store.data);
|
|||
const invoiceInUrl = ref();
|
||||
const amountsNotMatch = ref(null);
|
||||
const intrastatTotals = ref({ amount: 0, net: 0, stems: 0 });
|
||||
const isBooked = ref();
|
||||
|
||||
const vatColumns = ref([
|
||||
{
|
||||
|
@ -156,37 +155,26 @@ onMounted(async () => {
|
|||
invoiceInUrl.value = `${await getUrl('')}invoiceIn/${entityId.value}/`;
|
||||
});
|
||||
|
||||
function getAmountNotMatch(totals) {
|
||||
return (
|
||||
totals.totalDueDay != totals.totalTaxableBase &&
|
||||
totals.totalDueDay != totals.totalVat
|
||||
);
|
||||
}
|
||||
|
||||
function getTaxTotal(tax) {
|
||||
return tax.reduce(
|
||||
(acc, cur) => acc + taxRate(cur.taxableBase, cur.taxTypeSage?.rate),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
const init = (data) => {
|
||||
if (!data) return;
|
||||
|
||||
isBooked.value = data.isBooked;
|
||||
amountsNotMatch.value = getAmountNotMatch(data.totals);
|
||||
const { totals, invoiceInIntrastat } = data;
|
||||
amountsNotMatch.value =
|
||||
totals.totalDueDay != totals.totalTaxableBase &&
|
||||
totals.totalDueDay != totals.totalVat;
|
||||
|
||||
if (data.invoiceInIntrastat.length) {
|
||||
data.invoiceInIntrastat.forEach((val) => {
|
||||
intrastatTotals.value.amount += val.amount;
|
||||
intrastatTotals.value.net += val.net;
|
||||
intrastatTotals.value.stems += val.stems;
|
||||
});
|
||||
}
|
||||
invoiceInIntrastat.forEach((val) => {
|
||||
intrastatTotals.value.amount += val.amount;
|
||||
intrastatTotals.value.net += val.net;
|
||||
intrastatTotals.value.stems += val.stems;
|
||||
});
|
||||
};
|
||||
|
||||
const taxRate = (taxableBase = 0, rate = 0) => (rate / 100) * taxableBase;
|
||||
|
||||
const getTotalTax = (tax) =>
|
||||
tax.reduce((acc, cur) => acc + taxRate(cur.taxableBase, cur.taxTypeSage?.rate), 0);
|
||||
|
||||
const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
|
||||
</script>
|
||||
|
||||
|
@ -199,7 +187,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
|
|||
<template #header="{ entity }">
|
||||
<div>{{ entity.id }} - {{ entity.supplier?.name }}</div>
|
||||
</template>
|
||||
<template #header-right v-if="!isBooked">
|
||||
<template #header-right v-if="!invoiceIn?.isBooked">
|
||||
<InvoiceIntoBook>
|
||||
<template #content="{ book }">
|
||||
<QBtn
|
||||
|
@ -288,11 +276,9 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
|
|||
:label="t('invoiceIn.summary.company')"
|
||||
:value="entity.company?.code"
|
||||
/>
|
||||
<QCheckbox
|
||||
v-if="invoiceIn"
|
||||
<VnLv
|
||||
:label="t('invoiceIn.summary.booked')"
|
||||
v-model="invoiceIn.isBooked"
|
||||
:disable="true"
|
||||
:value="invoiceIn.isBooked"
|
||||
/>
|
||||
</QCard>
|
||||
<QCard class="vn-one">
|
||||
|
@ -352,7 +338,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
|
|||
<QTd>{{ toCurrency(entity.totals.totalTaxableBase) }}</QTd>
|
||||
<QTd></QTd>
|
||||
<QTd></QTd>
|
||||
<QTd>{{ toCurrency(getTaxTotal(entity.invoiceInTax)) }}</QTd>
|
||||
<QTd>{{ toCurrency(getTotalTax(entity.invoiceInTax)) }}</QTd>
|
||||
<QTd></QTd>
|
||||
</QTr>
|
||||
</template>
|
||||
|
|
|
@ -4,33 +4,17 @@ import { useI18n } from 'vue-i18n';
|
|||
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnCurrency from 'src/components/common/VnCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
dataKey: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
defineProps({ dataKey: { type: String, required: true } });
|
||||
const suppliers = ref([]);
|
||||
const suppliersRef = ref();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
ref="suppliersRef"
|
||||
url="Suppliers"
|
||||
:filter="{ fields: ['id', 'nickname'] }"
|
||||
order="nickname"
|
||||
limit="30"
|
||||
@on-fetch="(data) => (suppliers = data)"
|
||||
auto-load
|
||||
/>
|
||||
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
||||
<VnFilterPanel :data-key="dataKey" :search-button="true">
|
||||
<template #tags="{ tag, formatFn }">
|
||||
<div class="q-gutter-x-xs">
|
||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
||||
|
@ -38,22 +22,6 @@ const suppliersRef = ref();
|
|||
</div>
|
||||
</template>
|
||||
<template #body="{ params, searchFn }">
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('params.supplierFk')"
|
||||
v-model="params.supplierFk"
|
||||
:options="suppliers"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
@input-value="suppliersRef.fetch()"
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
</VnSelect>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
|
@ -68,21 +36,11 @@ const suppliersRef = ref();
|
|||
</VnInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<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>
|
||||
<VnInput
|
||||
:label="t('params.serial')"
|
||||
v-model="params.serial"
|
||||
:label="t('params.fi')"
|
||||
v-model="params.fi"
|
||||
is-outlined
|
||||
lazy-rules
|
||||
>
|
||||
|
@ -92,11 +50,61 @@ const suppliersRef = ref();
|
|||
</VnInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
v-model="params.supplierFk"
|
||||
url="Suppliers"
|
||||
:fields="['id', 'nickname']"
|
||||
:label="t('params.supplierFk')"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
:options="suppliers"
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
>
|
||||
</VnSelect>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
:label="t('params.account')"
|
||||
v-model="params.account"
|
||||
is-outlined
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="person" size="sm" />
|
||||
</template>
|
||||
</VnInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnCurrency v-model="params.amount" is-outlined />
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<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
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-mb-md">
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
|
@ -111,8 +119,8 @@ const suppliersRef = ref();
|
|||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
:label="t('params.fi')"
|
||||
v-model="params.fi"
|
||||
:label="t('params.serialNumber')"
|
||||
v-model="params.serialNumber"
|
||||
is-outlined
|
||||
lazy-rules
|
||||
>
|
||||
|
@ -125,8 +133,8 @@ const suppliersRef = ref();
|
|||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
:label="t('params.serialNumber')"
|
||||
v-model="params.serialNumber"
|
||||
:label="t('params.serial')"
|
||||
v-model="params.serial"
|
||||
is-outlined
|
||||
lazy-rules
|
||||
>
|
||||
|
@ -150,29 +158,6 @@ const suppliersRef = ref();
|
|||
</VnInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
:label="t('params.account')"
|
||||
v-model="params.account"
|
||||
is-outlined
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="person" size="sm" />
|
||||
</template>
|
||||
</VnInput>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate
|
||||
:label="t('Issued')"
|
||||
v-model="params.issued"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QExpansionItem>
|
||||
</template>
|
||||
</VnFilterPanel>
|
||||
|
|
Loading…
Reference in New Issue