0
0
Fork 0

Merge branch 'dev' into feature/ms-28-wagons

This commit is contained in:
Kevin Martinez 2023-11-29 23:11:20 -03:00
commit cd30d6184a
22 changed files with 276 additions and 437 deletions

View File

@ -15,8 +15,6 @@
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"cSpell.words": ["axios"], "cSpell.words": ["axios"],
"editor.tabSize": 2,
"files.autoSave": "onFocusChange", "files.autoSave": "onFocusChange",
"files.trimTrailingWhitespace": true, "files.trimTrailingWhitespace": true,
"editor.hover.enabled": true, "editor.hover.enabled": true,

View File

@ -89,7 +89,12 @@ const value = computed({
ref="vnSelectRef" ref="vnSelectRef"
> >
<template v-if="isClearable" #append> <template v-if="isClearable" #append>
<QIcon name="close" @click.stop="value = null" class="cursor-pointer" /> <QIcon
name="close"
@click.stop="value = null"
class="cursor-pointer"
size="18px"
/>
</template> </template>
<template v-for="(_, slotName) in $slots" #[slotName]="slotData"> <template v-for="(_, slotName) in $slots" #[slotName]="slotData">
<slot :name="slotName" v-bind="slotData" /> <slot :name="slotName" v-bind="slotData" />

View File

@ -57,20 +57,6 @@ async function getData() {
emit('onFetch', data); emit('onFetch', data);
} }
// watch($props, async () => {
// entity.value = null;
// await fetch();
// });
const options = [
'Transferir factura a ...',
'Ver factura ...',
'Enviar factura ...',
'Eliminar factura',
'Asentar factura',
'Regenerar PDF factura',
'Abono ...',
];
const emit = defineEmits(['onFetch']); const emit = defineEmits(['onFetch']);
</script> </script>
@ -110,15 +96,21 @@ const emit = defineEmits(['onFetch']);
</QBtn> </QBtn>
</RouterLink> </RouterLink>
<QBtn color="white" dense flat icon="more_vert" round size="md"> <QBtn
color="white"
dense
flat
icon="more_vert"
round
size="md"
v-if="slots.menu"
>
<QTooltip> <QTooltip>
{{ t('components.cardDescriptor.moreOptions') }} {{ t('components.cardDescriptor.moreOptions') }}
</QTooltip> </QTooltip>
<QMenu> <QMenu>
<QList dense v-for="option in options" :key="option"> <QList>
<QItem v-ripple clickable> <slot name="menu" :entity="entity" />
{{ option }}
</QItem>
</QList> </QList>
</QMenu> </QMenu>
</QBtn> </QBtn>

View File

@ -1,33 +0,0 @@
/**
* Filtra las opciones basadas en un valor de entrada y actualiza las opciones filtradas.
*
* @param {string} val - El valor de entrada para filtrar las opciones. (la emite el evento @filter del componente QSelect)
* @param {Function} update - Función de actualización que debe ser llamada para actualizar las opciones filtradas.(la provee el evento @filter del componente QSelect)
* @param {Function} abort - Función que puede ser llamada para abortar o cancelar el filtrado actual. (la provee el evento @filter del componente QSelect)
* @param {Object} optionsToFilter - Objeto que contiene las opciones originales y filtradas.
*/
function normalizeString(text) {
return text
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');
}
export function inputSelectFilter(val, update, abort, optionsToFilter) {
if (val === '') {
update(() => {
optionsToFilter.filtered = JSON.parse(
JSON.stringify(optionsToFilter.original)
);
});
return;
}
update(() => {
const searchQuery = val.toLowerCase();
optionsToFilter.filtered = optionsToFilter.original.filter((option) =>
normalizeString(option.label).includes(normalizeString(searchQuery))
);
});
}

View File

@ -1,8 +1,10 @@
import axios from 'axios'; import axios from 'axios';
import { useState } from './useState'; import { useState } from './useState';
import useNotify from './useNotify';
export function useUserConfig() { export function useUserConfig() {
const state = useState(); const state = useState();
const { notify } = useNotify();
async function fetch() { async function fetch() {
try { try {
@ -14,6 +16,7 @@ export function useUserConfig() {
return data; return data;
} catch (error) { } catch (error) {
notify('globals.errors.userConfig', 'negative');
console.error('Error fetching user config:', error); console.error('Error fetching user config:', error);
} }
} }

View File

@ -44,6 +44,7 @@ export default {
statusInternalServerError: 'An internal server error has ocurred', statusInternalServerError: 'An internal server error has ocurred',
statusBadGateway: 'It seems that the server has fall down', statusBadGateway: 'It seems that the server has fall down',
statusGatewayTimeout: 'Could not contact the server', statusGatewayTimeout: 'Could not contact the server',
userConfig: 'Error fetching user config',
}, },
login: { login: {
title: 'Login', title: 'Login',
@ -399,9 +400,9 @@ export default {
chooseValidCompany: 'Choose a valid company', chooseValidCompany: 'Choose a valid company',
chooseValidPrinter: 'Choose a valid printer', chooseValidPrinter: 'Choose a valid printer',
fillDates: 'Invoice date and the max date should be filled', fillDates: 'Invoice date and the max date should be filled',
invoiceDateLessThanMaxDate: "Invoice date can't be less than max date", invoiceDateLessThanMaxDate: 'Invoice date can not be less than max date',
invoiceWithFutureDate: 'Exists an invoice with a future date', invoiceWithFutureDate: 'Exists an invoice with a future date',
noTicketsToInvoice: "There aren't clients to invoice", noTicketsToInvoice: 'There are not clients to invoice',
criticalInvoiceError: 'Critical invoicing error, process stopped', criticalInvoiceError: 'Critical invoicing error, process stopped',
}, },
table: { table: {

View File

@ -44,6 +44,7 @@ export default {
statusInternalServerError: 'Ha ocurrido un error interno del servidor', statusInternalServerError: 'Ha ocurrido un error interno del servidor',
statusBadGateway: 'Parece ser que el servidor ha caído', statusBadGateway: 'Parece ser que el servidor ha caído',
statusGatewayTimeout: 'No se ha podido contactar con el servidor', statusGatewayTimeout: 'No se ha podido contactar con el servidor',
userConfig: 'Error al obtener configuración de usuario',
}, },
login: { login: {
title: 'Inicio de sesión', title: 'Inicio de sesión',

View File

@ -7,6 +7,7 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import useCardDescription from 'src/composables/useCardDescription'; import useCardDescription from 'src/composables/useCardDescription';
import InvoiceOutDescriptorMenu from './InvoiceOutDescriptorMenu.vue';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -59,6 +60,9 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
@on-fetch="setData" @on-fetch="setData"
data-key="invoiceOutData" data-key="invoiceOutData"
> >
<template #menu="{ entity }">
<InvoiceOutDescriptorMenu :invoiceOut="entity" />
</template>
<template #body="{ entity }"> <template #body="{ entity }">
<VnLv :label="t('invoiceOut.card.issued')" :value="toDate(entity.issued)" /> <VnLv :label="t('invoiceOut.card.issued')" :value="toDate(entity.issued)" />
<VnLv <VnLv

View File

@ -0,0 +1,23 @@
<template>
<QItem v-ripple clickable>
<QItemSection>Transferir factura a ...</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection>Ver factura ...</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection>Enviar factura ...</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection>Eliminar factura</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection>Asentar factura</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection>Regenerar PDF factura</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection>Abono ...</QItemSection>
</QItem>
</template>

View File

@ -74,20 +74,6 @@ const columns = computed(() => {
]; ];
}); });
const cardStatusText = computed(() => {
return t(`status.${status.value}`);
});
const percentageStatusText = computed(() => {
return `${getPercentage.value}% (${getAddressNumber.value} ${t('of')} ${
getNAddresses.value
})`;
});
const pdfStatusText = computed(() => {
return `${nPdfs.value} ${t('of')} ${totalPdfs.value} PDFs`;
});
const rows = computed(() => { const rows = computed(() => {
if (!errors && !errors.length > 0) return []; if (!errors && !errors.length > 0) return [];
return errors.value.map((row) => { return errors.value.map((row) => {
@ -110,7 +96,7 @@ onUnmounted(() => {
</script> </script>
<template> <template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <QDrawer v-model="stateStore.rightDrawer" :width="256" side="right" show-if-above>
<QScrollArea class="fit text-grey-8"> <QScrollArea class="fit text-grey-8">
<InvoiceOutGlobalForm /> <InvoiceOutGlobalForm />
</QScrollArea> </QScrollArea>
@ -119,9 +105,11 @@ onUnmounted(() => {
<QPage class="column items-center q-pa-md"> <QPage class="column items-center q-pa-md">
<QCard v-if="status" class="card"> <QCard v-if="status" class="card">
<QCardSection class="card-section"> <QCardSection class="card-section">
<span class="status-text">{{ cardStatusText }}</span> <span class="status-text">{{ t(`status.${status}`) }}</span>
<span class="text">{{ percentageStatusText }}</span> <span class="text">{{
<span class="text">{{ pdfStatusText }}</span> `${getPercentage}% (${getAddressNumber} ${t('of')} ${getNAddresses})`
}}</span>
<span class="text">{{ `${nPdfs} ${t('of')} ${totalPdfs} PDFs` }}</span>
</QCardSection> </QCardSection>
</QCard> </QCard>

View File

@ -1,10 +1,10 @@
<script setup> <script setup>
import { onMounted, ref, computed, reactive } from 'vue'; import { onMounted, ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js'; import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
import { inputSelectFilter } from 'src/composables/inputSelectFilterFn.js'; import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
const { t } = useI18n(); const { t } = useI18n();
@ -16,29 +16,19 @@ const {
formInitialData, formInitialData,
invoicing, invoicing,
printer,
status, status,
} = storeToRefs(invoiceOutGlobalStore); } = storeToRefs(invoiceOutGlobalStore);
// invoiceOutGlobalStore actions // invoiceOutGlobalStore actions
const { makeInvoice, setPrinterValue, setStatusValue } = invoiceOutGlobalStore; const { makeInvoice, setStatusValue } = invoiceOutGlobalStore;
const clientsToInvoice = ref('all'); const clientsToInvoice = ref('all');
const companiesOptions = reactive({ const companiesOptions = ref([]);
original: [],
filtered: [],
});
const printersOptions = reactive({ const printersOptions = ref([]);
original: [],
filtered: [],
});
const clientsOptions = reactive({ const clientsOptions = ref([]);
original: [],
filtered: [],
});
const formData = ref({ const formData = ref({
companyFk: null, companyFk: null,
@ -50,9 +40,9 @@ const formData = ref({
const optionsInitialData = computed(() => { const optionsInitialData = computed(() => {
return ( return (
companiesOptions.original.length > 0 && companiesOptions.value.length > 0 &&
printersOptions.original.length > 0 && printersOptions.value.length > 0 &&
clientsOptions.original.length > 0 clientsOptions.value.length > 0
); );
}); });
@ -66,23 +56,15 @@ const getStatus = computed({
}); });
const onFetchCompanies = (companies) => { const onFetchCompanies = (companies) => {
companiesOptions.original = companies.map((company) => { companiesOptions.value = [...companies];
return { value: company.id, label: company.code };
});
// Cuando necesitamos que el select muestre valores inicialmente le damos un valor inicial a los filters
companiesOptions.filtered = [...companiesOptions.original];
}; };
const onFetchPrinters = (printers) => { const onFetchPrinters = (printers) => {
printersOptions.original = printers.map((printer) => { printersOptions.value = [...printers];
return { value: printer.id, label: printer.name };
});
}; };
const onFetchClients = (clients) => { const onFetchClients = (clients) => {
clientsOptions.original = clients.map((client) => { clientsOptions.value = [...clients];
return { value: client.id, label: client.name };
});
}; };
onMounted(async () => { onMounted(async () => {
@ -99,9 +81,10 @@ onMounted(async () => {
<QForm <QForm
v-if="!initialDataLoading && optionsInitialData" v-if="!initialDataLoading && optionsInitialData"
@submit="makeInvoice(formData, clientsToInvoice)" @submit="makeInvoice(formData, clientsToInvoice)"
class="q-pa-md text-white" class="form-container q-pa-md"
style="max-width: 256px"
> >
<div class="q-gutter-md"> <div class="column q-gutter-y-md">
<QRadio <QRadio
v-model="clientsToInvoice" v-model="clientsToInvoice"
dense dense
@ -116,25 +99,17 @@ onMounted(async () => {
:label="t('oneClient')" :label="t('oneClient')"
:dark="true" :dark="true"
/> />
<QSelect <VnSelectFilter
v-if="clientsToInvoice === 'one'" v-if="clientsToInvoice === 'one'"
:label="t('client')" :label="t('client')"
:options="clientsOptions.filtered" v-model="formData.clientId"
use-input :options="clientsOptions"
option-value="value" option-value="id"
option-label="label" option-label="name"
emit-value hide-selected
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense dense
outlined outlined
rounded rounded
@filter="
(val, update, abort) =>
inputSelectFilter(val, update, abort, clientsOptions)
"
v-model="formData.clientId"
/> />
<QInput <QInput
dense dense
@ -194,54 +169,36 @@ onMounted(async () => {
</QIcon> </QIcon>
</template> </template>
</QInput> </QInput>
<QSelect <VnSelectFilter
v-if="optionsInitialData"
:label="t('company')" :label="t('company')"
:options="companiesOptions.filtered"
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense
outlined
rounded
lazy-rules
@filter="
(val, update, abort) =>
inputSelectFilter(val, update, abort, companiesOptions)
"
v-model="formData.companyFk" v-model="formData.companyFk"
/> :options="companiesOptions"
<QSelect option-value="id"
:label="t('printer')" option-label="code"
:options="printersOptions.filtered" hide-selected
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense dense
outlined outlined
rounded rounded
lazy-rules />
@filter=" <VnSelectFilter
(val, update, abort) => :label="t('printer')"
inputSelectFilter(val, update, abort, printersOptions)
"
v-model="formData.printer" v-model="formData.printer"
:options="printersOptions"
option-value="id"
option-label="name"
hide-selected
dense
outlined
rounded
/> />
</div> </div>
<QBtn <QBtn
v-if="!invoicing" v-if="!invoicing"
:label="t('invoiceOut')" :label="t('invoiceOut')"
type="submit" type="submit"
color="primary" color="primary"
class="full-width q-mt-md" class="q-mt-md full-width"
unelevated unelevated
rounded rounded
dense dense
@ -250,7 +207,7 @@ onMounted(async () => {
v-if="invoicing" v-if="invoicing"
:label="t('stop')" :label="t('stop')"
color="primary" color="primary"
class="full-width q-mt-md" class="q-mt-md full-width"
unelevated unelevated
rounded rounded
dense dense
@ -259,6 +216,12 @@ onMounted(async () => {
</QForm> </QForm>
</template> </template>
<style scoped>
.form-container * {
max-width: 100%;
}
</style>
<i18n> <i18n>
{ {
"en": { "en": {

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { onMounted, onUnmounted, ref } from 'vue'; import { onMounted, onUnmounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { exportFile, useQuasar } from 'quasar'; import { exportFile, useQuasar } from 'quasar';
@ -55,6 +55,12 @@ const addElement = (element) => {
} }
}; };
watch(manageCheckboxes, (current, prev) => {
if (!current) {
arrayElements.value = [];
}
});
const downloadCsv = (rows) => { const downloadCsv = (rows) => {
const data = arrayElements.value.length ? arrayElements.value : rows; const data = arrayElements.value.length ? arrayElements.value : rows;
let file; let file;
@ -244,13 +250,6 @@ const downloadCsv = (rows) => {
.dark_icon { .dark_icon {
color: #121212; color: #121212;
} }
.disabled,
.disabled *,
[disabled],
[disabled] * {
cursor: default !important;
}
</style> </style>
<i18n> <i18n>

View File

@ -5,7 +5,7 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import invoiceOutService from 'src/services/invoiceOut.service'; import invoiceOutService from 'src/services/invoiceOut.service';
import { toCurrency } from 'src/filters'; import { toCurrency } from 'src/filters';
import { QBadge, QBtn } from 'quasar'; import { QCheckbox, QBtn } from 'quasar';
import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js'; import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
@ -39,57 +39,66 @@ const filter = ref({
const tableColumnComponents = { const tableColumnComponents = {
company: { company: {
component: 'span', component: 'span',
props: {}, props: () => {},
event: () => {}, event: () => {},
}, },
country: { country: {
component: 'span', component: 'span',
props: {}, props: () => {},
event: () => {}, event: () => {},
}, },
clientId: { clientId: {
component: QBtn, component: QBtn,
props: { flat: true, color: 'blue' }, props: () => ({ flat: true, color: 'blue' }),
event: (prop) => selectCustomerId(prop.value), event: (prop) => selectCustomerId(prop.value),
}, },
client: { client: {
component: 'span', component: 'span',
props: {}, props: () => {},
event: () => {}, event: () => {},
}, },
amount: { amount: {
component: 'span', component: 'span',
props: {}, props: () => {},
event: () => {}, event: () => {},
}, },
base: { base: {
component: 'span', component: 'span',
props: {}, props: () => {},
event: () => {}, event: () => {},
}, },
ticketId: { ticketId: {
component: 'span', component: 'span',
props: {}, props: () => {},
event: () => {}, event: () => {},
}, },
active: { active: {
component: 'span', component: QCheckbox,
props: { type: 'boolean' }, props: (prop) => ({
disable: true,
'model-value': Boolean(prop.value),
}),
event: () => {}, event: () => {},
}, },
hasToInvoice: { hasToInvoice: {
component: 'span', component: QCheckbox,
props: { type: 'boolean' }, props: (prop) => ({
disable: true,
'model-value': Boolean(prop.value),
}),
event: () => {}, event: () => {},
}, },
verifiedData: { verifiedData: {
component: 'span', component: QCheckbox,
props: { type: 'boolean' }, props: (prop) => ({
disable: true,
'model-value': Boolean(prop.value),
}),
event: () => {}, event: () => {},
}, },
comercial: { comercial: {
component: QBtn, component: QBtn,
props: { flat: true, color: 'blue' }, props: () => ({ flat: true, color: 'blue' }),
event: (prop) => selectWorkerId(prop.row.comercialId), event: (prop) => selectWorkerId(prop.row.comercialId),
}, },
}; };
@ -351,27 +360,17 @@ onMounted(async () => {
<component <component
:is="tableColumnComponents[props.col.name].component" :is="tableColumnComponents[props.col.name].component"
class="col-content" class="col-content"
v-bind="tableColumnComponents[props.col.name].props" v-bind="tableColumnComponents[props.col.name].props(props)"
@click="tableColumnComponents[props.col.name].event(props)" @click="tableColumnComponents[props.col.name].event(props)"
> >
<span <template
v-if=" v-if="
tableColumnComponents[props.col.name].props.type != props.col.name !== 'active' &&
'boolean' props.col.name !== 'hasToInvoice' &&
props.col.name !== 'verifiedData'
" "
>{{ props.value }}</template
> >
{{ props.value }}
</span>
<span v-else>
<QBadge v-if="props.value" color="grey">
<QIcon name="check" size="xs" />
</QBadge>
<QBadge v-else color="grey" outline>
<QIcon name="" size="xs" />
</QBadge>
</span>
<CustomerDescriptorProxy <CustomerDescriptorProxy
v-if="props.col.name === 'clientId'" v-if="props.col.name === 'clientId'"
:id="selectedCustomerId" :id="selectedCustomerId"

View File

@ -74,6 +74,7 @@ function viewSummary(id) {
<CardList2 <CardList2
v-for="row of rows" v-for="row of rows"
:key="row.id" :key="row.id"
:id="row.id"
:title="row.code" :title="row.code"
@click="navigate(row.id)" @click="navigate(row.id)"
> >
@ -93,16 +94,16 @@ function viewSummary(id) {
<QBtn <QBtn
:label="t('components.smartCard.openCard')" :label="t('components.smartCard.openCard')"
@click.stop="navigate(row.id)" @click.stop="navigate(row.id)"
color="primary" color="white"
type="submit" outline
type="reset"
/> />
<QBtn <QBtn
:label="t('components.smartCard.openSummary')" :label="t('components.smartCard.openSummary')"
@click.stop="viewSummary(row.id)" @click.stop="viewSummary(row.id)"
color="primary" color="primary"
flat
style="margin-top: 15px" style="margin-top: 15px"
type="reset" type="submit"
/> />
</template> </template>
</CardList2> </CardList2>

View File

@ -84,20 +84,31 @@ const isAdministrative = computed(() => {
<span> {{ supplier.note || '-' }} </span> <span> {{ supplier.note || '-' }} </span>
</template> </template>
</VnLv> </VnLv>
<VnLv :label="t('supplier.summary.notes')" class="q-mb-xs">
<template #value>
<span> {{ supplier.note || '-' }} </span>
</template>
</VnLv>
<VnLv :label="t('verified')" class="q-mb-xs">
<template #value>
<QCheckbox <QCheckbox
v-model="supplier.isSerious" v-model="supplier.isSerious"
:label="t('verified')"
disable
dense dense
disable
class="full-width q-mb-xs" class="full-width q-mb-xs"
/> />
</template>
</VnLv>
<VnLv :label="t('isActive')" class="q-mb-xs">
<template #value>
<QCheckbox <QCheckbox
v-model="supplier.isActive" v-model="supplier.isActive"
:label="t('isActive')"
disable
dense dense
disable
class="full-width q-mb-xs" class="full-width q-mb-xs"
/> />
</template>
</VnLv>
</QCard> </QCard>
<QCard class="vn-one"> <QCard class="vn-one">
<a v-if="isAdministrative" class="header link" :href="supplierUrl"> <a v-if="isAdministrative" class="header link" :href="supplierUrl">
@ -169,21 +180,4 @@ const isAdministrative = computed(() => {
</template> </template>
</CardSummary> </CardSummary>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped></style>
.notes {
width: max-content;
}
.cardSummary .summaryBody > .q-card > .taxes {
border: 2px solid gray;
padding: 0;
> .vn-label-value {
text-align: right;
display: flex;
flex-direction: row;
margin-top: 5px;
justify-content: flex-end;
padding-right: 20px;
}
}
</style>

View File

@ -50,12 +50,11 @@ const viewSummary = (id) => {
<CardList2 <CardList2
v-for="row of rows" v-for="row of rows"
:key="row.id" :key="row.id"
:showCheckbox="true"
:title="row.socialName" :title="row.socialName"
:id="row.id"
@click="navigate(row.id)" @click="navigate(row.id)"
> >
<template #list-items> <template #list-items>
<VnLv label="ID" :value="row.id" />
<VnLv label="NIF/CIF" :value="row.nif" /> <VnLv label="NIF/CIF" :value="row.nif" />
<VnLv label="Alias" :value="row.nickname" /> <VnLv label="Alias" :value="row.nickname" />
<VnLv <VnLv
@ -77,11 +76,11 @@ const viewSummary = (id) => {
/> />
</template> </template>
<template #actions> <template #actions>
<QBtn flat icon="preview" @click.stop="viewSummary(row.id)"> <QBtn
<QTooltip> :label="t('components.smartCard.openSummary')"
{{ t('components.smartCard.openSummary') }} @click.stop="viewSummary(row.id)"
</QTooltip> color="primary"
</QBtn> />
</template> </template>
</CardList2> </CardList2>
</template> </template>

View File

@ -226,20 +226,27 @@ const openEntryDescriptor = () => {};
<VnLv label="m³" :value="travel.m3" /> <VnLv label="m³" :value="travel.m3" />
<VnLv :label="t('travel.shared.totalEntries')" :value="travel.m3" /> <VnLv :label="t('travel.shared.totalEntries')" :value="travel.m3" />
<VnLv :label="t('travel.summary.delivered')" class="q-mb-xs">
<template #value>
<QCheckbox <QCheckbox
v-model="travel.isDelivered" v-model="travel.isDelivered"
:label="t('travel.summary.delivered')"
disable disable
dense dense
class="full-width q-my-xs" class="full-width q-my-xs"
/> />
</template>
</VnLv>
<VnLv :label="t('travel.summary.received')" class="q-mb-xs">
<template #value>
<QCheckbox <QCheckbox
v-model="travel.isReceived" v-model="travel.isReceived"
:label="t('travel.summary.received')"
disable disable
dense dense
class="full-width q-mb-xs" class="full-width q-mb-xs"
/> />
</template>
</VnLv>
</QCard> </QCard>
<QCard class="vn-two" v-if="entriesTableRows.length > 0"> <QCard class="vn-two" v-if="entriesTableRows.length > 0">
<a class="header" :href="travelUrl + 'entry'"> <a class="header" :href="travelUrl + 'entry'">
@ -285,21 +292,4 @@ const openEntryDescriptor = () => {};
</template> </template>
</CardSummary> </CardSummary>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped></style>
.notes {
width: max-content;
}
.cardSummary .summaryBody > .q-card > .taxes {
border: 2px solid gray;
padding: 0;
> .vn-label-value {
text-align: right;
display: flex;
flex-direction: row;
margin-top: 5px;
justify-content: flex-end;
padding-right: 20px;
}
}
</style>

View File

@ -1,11 +1,10 @@
<script setup> <script setup>
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { reactive, computed } from 'vue'; import { reactive, computed, ref } from 'vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import { useTravelStore } from 'src/stores/travel'; import { useTravelStore } from 'src/stores/travel';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { inputSelectFilter } from 'src/composables/inputSelectFilterFn.js'; import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import { toDate } from 'src/filters';
import { onBeforeMount } from 'vue'; import { onBeforeMount } from 'vue';
const { t } = useI18n(); const { t } = useI18n();
@ -22,15 +21,9 @@ const newTravelDataForm = reactive({
warehouseInFk: null, warehouseInFk: null,
}); });
const agenciesOptions = reactive({ const agenciesOptions = ref([]);
original: [],
filtered: [],
});
const warehousesOptions = reactive({ const warehousesOptions = ref([]);
original: [],
filtered: [],
});
onBeforeMount(() => { onBeforeMount(() => {
if (route.query.travelData) { if (route.query.travelData) {
@ -51,15 +44,11 @@ const createTravel = async () => {
}; };
const onFetchAgencies = (agencies) => { const onFetchAgencies = (agencies) => {
agenciesOptions.original = agencies.map((agency) => { agenciesOptions.value = [...agencies];
return { value: agency.agencyFk, label: agency.name };
});
}; };
const onFetchWarehouses = (warehouses) => { const onFetchWarehouses = (warehouses) => {
warehousesOptions.original = warehouses.map((warehouse) => { warehousesOptions.value = [...warehouses];
return { value: warehouse.id, label: warehouse.name };
});
}; };
const canSubmit = computed(() => { const canSubmit = computed(() => {
@ -88,21 +77,15 @@ const redirectToTravelList = () => {
v-model="newTravelDataForm.ref" v-model="newTravelDataForm.ref"
:label="t('travel.shared.reference')" :label="t('travel.shared.reference')"
filled filled
style="max-width: 100%"
/> />
<QSelect <VnSelectFilter
:options="agenciesOptions.filtered"
v-model="newTravelDataForm.agencyModeFk"
filled
use-input
@filter="
(val, update, abort) =>
inputSelectFilter(val, update, abort, agenciesOptions)
"
:label="t('travel.shared.agency')" :label="t('travel.shared.agency')"
transition-show="jump-up" v-model="newTravelDataForm.agencyModeFk"
transition-hide="jump-up" :options="agenciesOptions"
style="max-width: 100%" option-value="agencyFk"
option-label="name"
hide-selected
filled
/> />
<QInput <QInput
v-model="newTravelDataForm.shipped" v-model="newTravelDataForm.shipped"
@ -118,31 +101,23 @@ const redirectToTravelList = () => {
mask="date" mask="date"
:label="t('travel.shared.landed')" :label="t('travel.shared.landed')"
/> />
<QSelect <VnSelectFilter
:options="warehousesOptions.filtered"
v-model="newTravelDataForm.warehouseOutFk"
filled
use-input
@filter="
(val, update, abort) =>
inputSelectFilter(val, update, abort, warehousesOptions)
"
:label="t('travel.shared.wareHouseOut')" :label="t('travel.shared.wareHouseOut')"
transition-show="jump-up" v-model="newTravelDataForm.warehouseOutFk"
transition-hide="jump-up" :options="warehousesOptions"
/> option-value="id"
<QSelect option-label="name"
:options="warehousesOptions.filtered" hide-selected
v-model="newTravelDataForm.warehouseInFk"
filled filled
use-input />
@filter=" <VnSelectFilter
(val, update, abort) =>
inputSelectFilter(val, update, abort, warehousesOptions)
"
:label="t('travel.shared.wareHouseIn')" :label="t('travel.shared.wareHouseIn')"
transition-show="jump-up" v-model="newTravelDataForm.warehouseInFk"
transition-hide="jump-up" :options="warehousesOptions"
option-value="id"
option-label="name"
hide-selected
filled
/> />
</QCard> </QCard>
<div class="row"> <div class="row">

View File

@ -1,8 +1,8 @@
<script setup> <script setup>
import { reactive } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import { inputSelectFilter } from 'src/composables/inputSelectFilterFn.js'; import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import { toDate } from 'src/filters'; import { toDate } from 'src/filters';
@ -14,37 +14,22 @@ const props = defineProps({
}, },
}); });
const warehousesOptions = reactive({ const warehousesOptions = ref([]);
original: [],
filtered: [],
});
const continentsOptions = reactive({ const continentsOptions = ref([]);
original: [],
filtered: [],
});
const agenciesOptions = reactive({ const agenciesOptions = ref([]);
original: [],
filtered: [],
});
const onFetchWarehouses = (warehouses) => { const onFetchWarehouses = (warehouses) => {
warehousesOptions.original = warehouses.map((warehouse) => { warehousesOptions.value = [...warehouses];
return { value: warehouse.id, label: warehouse.name };
});
}; };
const onFetchContinents = (continents) => { const onFetchContinents = (continents) => {
continentsOptions.original = continents.map((continent) => { continentsOptions.value = [...continents];
return { value: continent.code, label: continent.name };
});
}; };
const onFetchAgencies = (agencies) => { const onFetchAgencies = (agencies) => {
agenciesOptions.original = agencies.map((agency) => { agenciesOptions.value = [...agencies];
return { value: agency.agencyFk, label: agency.name };
});
}; };
const add = (paramsObj, key) => { const add = (paramsObj, key) => {
@ -75,7 +60,7 @@ const decrement = (paramsObj, key) => {
</div> </div>
</template> </template>
<template #body="{ params }"> <template #body="{ params }">
<QList dense> <QList dense style="max-width: 256px" class="list">
<QItem class="q-my-sm"> <QItem class="q-my-sm">
<QItemSection> <QItemSection>
<QInput <QInput
@ -90,83 +75,46 @@ const decrement = (paramsObj, key) => {
</QItem> </QItem>
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection> <QItemSection>
<QSelect <VnSelectFilter
:label="t('params.agencyModeFk')" :label="t('params.agencyModeFk')"
:options="agenciesOptions.filtered"
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense
lazy-rules
outlined
rounded
@filter="
(val, update, abort) =>
inputSelectFilter(val, update, abort, agenciesOptions)
"
v-model="params.agencyModeFk" v-model="params.agencyModeFk"
:options="agenciesOptions"
option-value="agencyFk"
option-label="name"
hide-selected
dense
outlined
rounded
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection> <QItemSection>
<QSelect <VnSelectFilter
:label="t('travel.shared.wareHouseOut')" :label="t('params.warehouseOutFk')"
:options="warehousesOptions.filtered"
use-input
option-value="value"
option-label="label"
emit-value
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense
lazy-rules
outlined
rounded
@filter="
(val, update, abort) =>
inputSelectFilter(
val,
update,
abort,
warehousesOptions
)
"
v-model="params.warehouseOutFk" v-model="params.warehouseOutFk"
:options="warehousesOptions"
option-value="id"
option-label="name"
hide-selected
dense
outlined
rounded
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection> <QItemSection>
<QSelect <VnSelectFilter
:label="t('params.wareHouseIn')" :label="t('params.warehouseInFk')"
:options="warehousesOptions.filtered" v-model="params.warehouseInFk"
use-input :options="warehousesOptions"
option-value="value" option-value="id"
option-label="label" option-label="name"
emit-value hide-selected
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense dense
lazy-rules
outlined outlined
rounded rounded
@filter="
(val, update, abort) =>
inputSelectFilter(
val,
update,
abort,
warehousesOptions
)
"
v-model="params.warehouseInFk"
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
@ -271,30 +219,16 @@ const decrement = (paramsObj, key) => {
</QItem> </QItem>
<QItem class="q-mb-sm"> <QItem class="q-mb-sm">
<QItemSection> <QItemSection>
<QSelect <VnSelectFilter
:label="t('params.continent')" :label="t('params.continent')"
:options="continentsOptions.filtered" v-model="params.continent"
use-input :options="continentsOptions"
option-value="value" option-value="code"
option-label="label" option-label="name"
emit-value hide-selected
map-options
transition-show="jump-up"
transition-hide="jump-up"
dense dense
lazy-rules
outlined outlined
rounded rounded
@filter="
(val, update, abort) =>
inputSelectFilter(
val,
update,
abort,
continentsOptions
)
"
v-model="params.continent"
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
@ -336,6 +270,10 @@ const decrement = (paramsObj, key) => {
</template> </template>
<style scoped> <style scoped>
.list * {
max-width: 100%;
}
.input-number >>> input[type='number'] { .input-number >>> input[type='number'] {
-moz-appearance: textfield; -moz-appearance: textfield;
} }
@ -353,8 +291,8 @@ const decrement = (paramsObj, key) => {
"params": { "params": {
"search": "Id/Reference", "search": "Id/Reference",
"agencyModeFk": "Agency", "agencyModeFk": "Agency",
"wareHouseIn": "Warehouse In", "warehouseInFk": "Warehouse In",
"wareHouseOut": "Warehouse Out", "warehouseOutFk": "Warehouse Out",
"scopeDays": "Days onward", "scopeDays": "Days onward",
"landedFrom": "Landed from", "landedFrom": "Landed from",
"landedTo": "Landed to", "landedTo": "Landed to",
@ -366,8 +304,8 @@ const decrement = (paramsObj, key) => {
"params":{ "params":{
"search": "Id/Referencia", "search": "Id/Referencia",
"agencyModeFk": "Agencia", "agencyModeFk": "Agencia",
"wareHouseIn": "Alm. entrada", "warehouseInFk": "Alm. entrada",
"wareHouseOut": "Alm. salida", "warehouseOutFk": "Alm. salida",
"scopeDays": "Días adelante", "scopeDays": "Días adelante",
"landedFrom": "Llegada desde", "landedFrom": "Llegada desde",
"landedTo": "Llegada hasta", "landedTo": "Llegada hasta",

View File

@ -67,7 +67,6 @@ onMounted(async () => {
:key="row.id" :key="row.id"
:title="row.ref" :title="row.ref"
:id="row.id" :id="row.id"
:showCheckbox="true"
@click="navigateToTravelId(row.id)" @click="navigateToTravelId(row.id)"
> >
<template #list-items> <template #list-items>

View File

@ -5,7 +5,7 @@ export default {
name: 'Shelving', name: 'Shelving',
meta: { meta: {
title: 'shelving', title: 'shelving',
icon: 'vn:trolley' icon: 'vn:inventory'
}, },
component: RouterView, component: RouterView,
redirect: { name: 'ShelvingMain' }, redirect: { name: 'ShelvingMain' },

View File

@ -21,9 +21,9 @@ export const useTravelStore = defineStore({
async createTravel(travelData) { async createTravel(travelData) {
const params = { const params = {
ref: travelData.ref, ref: travelData.ref,
agencyModeFk: travelData.agencyModeFk.value, agencyModeFk: travelData.agencyModeFk,
warehouseOutFk: travelData.warehouseOutFk.value, warehouseOutFk: travelData.warehouseOutFk,
warehouseInFk: travelData.warehouseInFk.value, warehouseInFk: travelData.warehouseInFk,
landed: new Date(travelData.landed), landed: new Date(travelData.landed),
shipped: new Date(travelData.shipped), shipped: new Date(travelData.shipped),
}; };