#6896 fix Order module problems #817

Merged
jon merged 18 commits from Fix_OrderModuleProblems into dev 2024-10-29 11:20:14 +00:00
10 changed files with 87 additions and 74 deletions
Showing only changes of commit 419d3d2d45 - Show all commits

View File

@ -185,6 +185,9 @@ async function remove(key) {
} }
function formatValue(value) { function formatValue(value) {
if (typeof value === 'object') {
return value;
}
if (typeof value === 'boolean') return value ? t('Yes') : t('No'); if (typeof value === 'boolean') return value ? t('Yes') : t('No');
if (isNaN(value) && !isNaN(Date.parse(value))) return toDate(value); if (isNaN(value) && !isNaN(Date.parse(value))) return toDate(value);
@ -193,6 +196,13 @@ function formatValue(value) {
function sanitizer(params) { function sanitizer(params) {
for (const [key, value] of Object.entries(params)) { for (const [key, value] of Object.entries(params)) {
if (key == 'and') {
value.forEach((andValue) => {
params = { ...params, ...andValue };
});
delete params[key];
}
if (value && typeof value === 'object') { if (value && typeof value === 'object') {
const param = Object.values(value)[0]; const param = Object.values(value)[0];
if (typeof param == 'string') params[key] = param.replaceAll('%', ''); if (typeof param == 'string') params[key] = param.replaceAll('%', '');
@ -211,7 +221,7 @@ function sanitizer(params) {
icon="search" icon="search"
@click="search()" @click="search()"
></QBtn> ></QBtn>
<QForm @submit="search" id="filterPanelForm" @keyup.enter="search()"> <QForm @submit="search(true)" id="filterPanelForm" @keyup.enter="search(true)">
<QList dense> <QList dense>
<QItem class="q-mt-xs"> <QItem class="q-mt-xs">
<QItemSection top> <QItemSection top>

View File

@ -9,6 +9,7 @@ import { useStateStore } from 'src/stores/useStateStore';
const quasar = useQuasar(); const quasar = useQuasar();
const { t } = useI18n(); const { t } = useI18n();
const state = useStateStore(); const state = useStateStore();
const emit = defineEmits(['on-search']);
jon marked this conversation as resolved Outdated

No sigue el standard

No sigue el standard
const props = defineProps({ const props = defineProps({
dataKey: { dataKey: {
@ -118,6 +119,7 @@ async function search() {
delete filter.params.search; delete filter.params.search;
} }
await arrayData.applyFilter(filter); await arrayData.applyFilter(filter);
emit('on-search', store.data);
} }
</script> </script>
<template> <template>

View File

@ -705,6 +705,8 @@ order:
quantity: Quantity quantity: Quantity
price: Price price: Price
amount: Amount amount: Amount
confirm: Confirm
confirmLines: Confirm lines
department: department:
pageTitles: pageTitles:
basicData: Basic data basicData: Basic data

View File

@ -679,13 +679,15 @@ order:
vat: IVA vat: IVA
state: Estado state: Estado
alias: Alias alias: Alias
items: Items items: Artículos
orderTicketList: Tickets del pedido orderTicketList: Tickets del pedido
details: Detalles details: Detalles
item: Item item: Item
quantity: Cantidad quantity: Cantidad
price: Precio price: Precio
amount: Monto amount: Monto
confirm: Confirmar
confirmLines: Confirmar lineas
shelving: shelving:
list: list:
parking: Parking parking: Parking

View File

@ -86,11 +86,8 @@ function extractValueTags(items) {
<div class="full-width"> <div class="full-width">
Review

Añadimos clearable al input de cuando le das al mas

Añadimos clearable al input de cuando le das al mas
<VnPaginate <VnPaginate
data-key="OrderCatalogList" data-key="OrderCatalogList"
url="Orders/CatalogFilter"
:limit="50"
:user-params="catalogParams"
@on-fetch="extractTags"
:update-router="false" :update-router="false"
@on-change="extractTags"
> >
<template #body="{ rows }"> <template #body="{ rows }">
<div class="catalog-list"> <div class="catalog-list">
@ -102,6 +99,7 @@ function extractValueTags(items) {
:key="row.id" :key="row.id"
:item="row" :item="row"
is-catalog is-catalog
class="fill-icon"
/> />
</div> </div>
</template> </template>

View File

@ -1,12 +1,11 @@
<script setup> <script setup>
Review

Nos juntamos porque creo que me siguen sin funcionar como es debido cuando refresco la ventana.
Se mantiene categoria, pero si seleccionas tipo y F5, se pierde todo.
El tema de las etiquetas o tagGroups, no aparece al refrescar

Si lo ves muy complejo se lo pasamos a William

Nos juntamos porque creo que me siguen sin funcionar como es debido cuando refresco la ventana. Se mantiene categoria, pero si seleccionas tipo y F5, se pierde todo. El tema de las etiquetas o tagGroups, no aparece al refrescar Si lo ves muy complejo se lo pasamos a William
import { computed, ref } from 'vue'; import { computed, ref, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import axios from 'axios'; import axios from 'axios';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue'; import VnSelect from 'components/common/VnSelect.vue';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import getParamWhere from 'src/filters/getParamWhere'; import getParamWhere from 'src/filters/getParamWhere';
@ -48,6 +47,15 @@ const orderWayList = ref([
const orderBySelected = ref('relevancy DESC, name'); const orderBySelected = ref('relevancy DESC, name');
const orderWaySelected = ref('ASC'); const orderWaySelected = ref('ASC');
const routeQuery = JSON.parse(route?.query.params ?? '{}');
const params = ref({});
jon marked this conversation as resolved Outdated

puede confundirse con la variable de la 189

puede confundirse con la variable de la 189
onMounted(() => {
const filter = routeQuery.filter;
jon marked this conversation as resolved Outdated

si solo lo usas una vez porque no eliminas esta variable y lo pones en la siguiente linea? si tampoco haces ninguna validación

si solo lo usas una vez porque no eliminas esta variable y lo pones en la siguiente linea? si tampoco haces ninguna validación
params.value = JSON.parse(filter ?? '{}')?.where ?? {};
if (Object.keys(params.value).length > 0) vnFilterPanelRef.value.search();
});
const createValue = (val, done) => { const createValue = (val, done) => {
if (val.length > 2) { if (val.length > 2) {
if (!tagOptions.value.includes(val)) { if (!tagOptions.value.includes(val)) {
@ -61,19 +69,15 @@ const resetCategory = () => {
typeList.value = null; typeList.value = null;
}; };
const clearFilter = (key) => { const selectCategory = (category, search) => {
if (key === 'categoryFk') { if (!params.value?.filter) params.value.filter = { where: {} };
const where = params.value.filter.where;
if (where.categoryFk === category?.id) {
resetCategory(); resetCategory();
} where.categoryFk = null;
};
const selectCategory = (params, category, search) => {
if (params.categoryFk === category?.id) {
resetCategory();
params.categoryFk = null;
} else { } else {
selectedCategoryFk.value = category?.id; selectedCategoryFk.value = category?.id;
params.categoryFk = category?.id; where.categoryFk = category?.id;
loadTypes(category?.id); loadTypes(category?.id);
} }
search(); search();
@ -103,17 +107,6 @@ const selectedType = computed(() => {
return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value); return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value);
}); });
function exprBuilder(param, value) {
switch (param) {
case 'categoryFk':
case 'typeFk':
return { [param]: value };
case 'search':
if (/^\d+$/.test(value)) return { 'i.id': value };
else return { 'i.name': { like: `%${value}%` } };
}
}
const applyTagFilter = (params, search) => { const applyTagFilter = (params, search) => {
if (!tagValues.value?.length) { if (!tagValues.value?.length) {
params.tagGroups = null; params.tagGroups = null;
@ -138,15 +131,6 @@ const applyTagFilter = (params, search) => {
tagValues.value = [{}]; tagValues.value = [{}];
}; };
const removeTagChip = (selection, params, search) => {
if (params.tagGroups) {
params.tagGroups = (params.tagGroups || []).filter(
(value) => value !== selection
);
}
search();
};
const setCategoryList = (data) => { const setCategoryList = (data) => {
categoryList.value = (data || []) categoryList.value = (data || [])
.filter((category) => category.display) .filter((category) => category.display)
@ -178,12 +162,11 @@ function addOrder(value, field, params) {
<VnFilterPanel <VnFilterPanel
ref="vnFilterPanelRef" ref="vnFilterPanelRef"
:data-key="props.dataKey" :data-key="props.dataKey"
:hidden-tags="['orderFk', 'orderBy']" v-model="params"
:un-removable-params="['orderFk', 'orderBy']"
:expr-builder="exprBuilder"
:custom-tags="['tagGroups']"
@remove="clearFilter"
:redirect="false" :redirect="false"
:hidden-tags="['orderFk', 'orderBy', 'filter', 'search', 'or', 'and']"
:un-removable-params="['orderFk', 'orderBy']"
:disable-submit-event="true"
> >
<template #tags="{ tag, formatFn }"> <template #tags="{ tag, formatFn }">
<strong v-if="tag.label === 'categoryFk'"> <strong v-if="tag.label === 'categoryFk'">
@ -192,30 +175,17 @@ function addOrder(value, field, params) {
<strong v-else-if="tag.label === 'typeFk'"> <strong v-else-if="tag.label === 'typeFk'">
{{ t(selectedType?.name || '') }} {{ t(selectedType?.name || '') }}
</strong> </strong>
<div v-else-if="tag.label === 'tagGroups'" class="q-gutter-x-xs">
<strong v-if="JSON.parse(tag.value).tagSelection.name"

podrias hacer una funcion o computed para JSON.parse

podrias hacer una funcion o computed para JSON.parse
>{{ JSON.parse(tag.value).tagSelection?.name }}:
</strong>
<span>{{ JSON.parse(tag.value).values[0].value }}</span>
</div>
<div v-else class="q-gutter-x-xs"> <div v-else class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong> <strong>{{ t(`params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span> <span>{{ formatFn(tag.value) }}</span>
</div> </div>
</template> </template>
<template #customTags="{ tags: customTags, params, searchFn }">
<template v-for="tag in customTags" :key="tag.label">
<template v-if="tag.label === 'tagGroups'">
<VnFilterPanelChip
v-for="chip in tag.value"
:key="chip"
removable
@remove="removeTagChip(chip, params, searchFn)"
>
<strong> {{ JSON.parse(chip).tagSelection?.name }}: </strong>
<span>{{
(JSON.parse(chip).values || [])
.map((item) => item.value)
.join(' | ')
}}</span>
</VnFilterPanelChip>
</template>
</template>
</template>
<template #body="{ params, searchFn }"> <template #body="{ params, searchFn }">
<QItem class="category-filter q-mt-md"> <QItem class="category-filter q-mt-md">
<div <div
@ -226,7 +196,7 @@ function addOrder(value, field, params) {
<QIcon <QIcon
:name="category.icon" :name="category.icon"
class="category-icon" class="category-icon"
@click="selectCategory(params, category, searchFn)" @click="selectCategory(category, searchFn)"
> >
<QTooltip> <QTooltip>
{{ t(category.name) }} {{ t(category.name) }}
@ -320,7 +290,7 @@ function addOrder(value, field, params) {
> >
<FetchData <FetchData
v-if="selectedTag" v-if="selectedTag"
:url="`Tags/${selectedTag}/filterValue`" :url="`Tags/${selectedTag.id}/filterValue`"
limit="30" limit="30"
auto-load auto-load
@on-fetch="(data) => (tagOptions = data)" @on-fetch="(data) => (tagOptions = data)"
@ -343,7 +313,7 @@ function addOrder(value, field, params) {
@update:model-value="applyTagFilter(params, searchFn)" @update:model-value="applyTagFilter(params, searchFn)"
/> />
<VnSelect <VnSelect
v-else-if="selectedTag === 1" v-else-if="selectedTag.id === 1"
:label="t('params.value')" :label="t('params.value')"
v-model="value.value" v-model="value.value"
:options="tagOptions || []" :options="tagOptions || []"

View File

@ -71,10 +71,6 @@ const getConfirmationValue = (isConfirmed) => {
}; };
const total = ref(null); const total = ref(null);
function ticketFilter(order) {
return JSON.stringify({ id: order.id });
}
</script> </script>
<template> <template>
@ -126,7 +122,11 @@ function ticketFilter(order) {
color="primary" color="primary"
:to="{ :to="{
name: 'TicketList', name: 'TicketList',
query: { table: ticketFilter(entity) }, query: {
table: JSON.stringify({
orderFk: entity.id,
}),
},
}" }"
> >
<QTooltip>{{ t('order.summary.orderTicketList') }}</QTooltip> <QTooltip>{{ t('order.summary.orderTicketList') }}</QTooltip>

View File

@ -23,8 +23,8 @@ function confirmRemove() {
.dialog({ .dialog({
component: VnConfirm, component: VnConfirm,
componentProps: { componentProps: {
title: t('globals.confirmDeletion'), title: t('You are going to delete this order'),
message: t('confirmDeletionMessage'), message: t('Continue anyway?'),
promise: remove, promise: remove,
}, },
}) })
@ -57,5 +57,6 @@ en:
es: es:
deleteOrder: Eliminar pedido deleteOrder: Eliminar pedido
confirmDeletionMessage: Seguro que quieres eliminar este pedido? confirmDeletionMessage: Seguro que quieres eliminar este pedido?
You are going to delete this order: El pedido se eliminará
Continue anyway?: ¿Continuar de todos modos?
</i18n> </i18n>

View File

@ -168,7 +168,7 @@ const columns = computed(() => [
name: 'tableActions', name: 'tableActions',
actions: [ actions: [
{ {
title: t('Delete'), title: t('Remove item'),
icon: 'delete', icon: 'delete',
show: (row) => !row.order.isConfirmed, show: (row) => !row.order.isConfirmed,
action: (row) => confirmRemove(row), action: (row) => confirmRemove(row),
@ -397,4 +397,5 @@ es:
confirmDeletion: Confirmar eliminación, confirmDeletion: Confirmar eliminación,
confirmDeletionMessage: Seguro que quieres eliminar este artículo? confirmDeletionMessage: Seguro que quieres eliminar este artículo?
confirm: Confirmar confirm: Confirmar
Remove item: Eliminar artículo
</i18n> </i18n>

View File

@ -2,7 +2,10 @@
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import axios from 'axios';
import { dashIfEmpty, toCurrency, toDateHourMinSec } from 'src/filters'; import { dashIfEmpty, toCurrency, toDateHourMinSec } from 'src/filters';
import { useArrayData } from 'composables/useArrayData';
import VnLv from 'components/ui/VnLv.vue'; import VnLv from 'components/ui/VnLv.vue';
import CardSummary from 'components/ui/CardSummary.vue'; import CardSummary from 'components/ui/CardSummary.vue';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
@ -21,6 +24,9 @@ const $props = defineProps({
}); });
const entityId = computed(() => $props.id || route.params.id); const entityId = computed(() => $props.id || route.params.id);
const summary = ref();
const quasar = useQuasar();
const descriptorData = useArrayData('orderData');
const detailsColumns = ref([ const detailsColumns = ref([
{ {
name: 'item', name: 'item',
@ -49,6 +55,16 @@ const detailsColumns = ref([
field: (row) => toCurrency(row?.quantity * row?.price), field: (row) => toCurrency(row?.quantity * row?.price),
}, },
]); ]);
async function confirmOrder() {

Tenemos duplicidad al usar este axios.post, lo movemos un archivo global.
si tienes dudas, puedes revisar setRectificative

Tenemos duplicidad al usar este axios.post, lo movemos un archivo global. si tienes dudas, puedes revisar setRectificative
await axios.post(`Orders/${route.params.id}/confirm`);
quasar.notify({
message: t('globals.confirm'),
type: 'positive',
});
summary.value.fetch({});
descriptorData.fetch({});
}
</script> </script>
<template> <template>
@ -62,6 +78,17 @@ const detailsColumns = ref([
{{ t('order.summary.basket') }} #{{ entity?.id }} - {{ t('order.summary.basket') }} #{{ entity?.id }} -
{{ entity?.client?.name }} ({{ entity?.clientFk }}) {{ entity?.client?.name }} ({{ entity?.clientFk }})
</template> </template>
<template #header-right>
<QBtn
flat
text-color="white"
:disabled="isConfirmed"
:label="t('order.summary.confirm')"
@click="confirmOrder()"
>
<QTooltip>{{ t('order.summary.confirmLines') }}</QTooltip>
</QBtn>
</template>
<template #body="{ entity }"> <template #body="{ entity }">
<QCard class="vn-one"> <QCard class="vn-one">
<VnTitle <VnTitle