#6943 - FIX Customer module #628

Merged
jsegarra merged 49 commits from 6943_fix_customerSummaryTable into dev 2024-09-12 05:28:19 +00:00
12 changed files with 249 additions and 68 deletions
Showing only changes of commit e45e551526 - Show all commits

View File

@ -67,7 +67,7 @@ const $props = defineProps({
},
hasSubToolbar: {
type: Boolean,
default: true,
default: null,
},
disableOption: {
type: Object,
@ -341,7 +341,7 @@ defineExpose({
:search-url="searchUrl"
:disable-infinite-scroll="isTableMode"
@save-changes="reload"
:has-sub-toolbar="$attrs['hasSubToolbar'] ?? isEditable"
:has-sub-toolbar="$props.hasSubToolbar ?? isEditable"
:auto-load="hasParams || $attrs['auto-load']"
>
<template

View File

@ -127,11 +127,6 @@ const dialog = ref(null);
flex-direction: column;
gap: 4px;
.subName {
color: var(--vn-label-color);
text-transform: uppercase;
}
p {
margin-bottom: 0;
}

View File

@ -3,6 +3,7 @@ import { onMounted, ref, computed, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useArrayData } from 'composables/useArrayData';
import { useRoute } from 'vue-router';
import { date } from 'quasar';
import toDate from 'filters/toDate';
import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue';
@ -190,6 +191,7 @@ async function remove(key) {
}
function formatValue(value) {
if (value instanceof Date) return date.formatDate(value, 'DD/MM/YYYY');
if (typeof value === 'boolean') return value ? t('Yes') : t('No');
if (isNaN(value) && !isNaN(Date.parse(value))) return toDate(value);

View File

@ -86,12 +86,26 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
Object.assign(filter, store.userFilter, exprFilter);
let where;
if (filter?.where || store.filter?.where)
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
// ARRAY DATA FALLA AL JUNTAR WHERE'S
jsegarra marked this conversation as resolved Outdated

si se queda un fixme deja el numero del redmine asociado,

si se queda un fixme deja el numero del redmine asociado,

Se puso esta lógica para cuando querias ir al listado de tickets pero se ha modificado el componente TicketList.
Elimino este código que además estaba mal porque tenia una , en vez de operadores lógicos

Se puso esta lógica para cuando querias ir al listado de tickets pero se ha modificado el componente TicketList. Elimino este código que además estaba mal porque tenia una , en vez de operadores lógicos
2d8322c6da3f53e322fc0577889f42be32cf7a2f
console.log(
'userParams?.filter?.where: ',
userParams?.filter?.where,
filter?.where,
store.filter?.where
);
if ((userParams?.filter?.where, filter?.where || store.filter?.where))
where = Object.assign(
userParams?.filter?.where ?? {},
filter?.where ?? {},
store.filter?.where ?? {}
);
Object.assign(filter, store.filter);
filter.where = where;
console.log('where: ', where);
const params = { filter };
console.log('params: ', params);
delete userParams?.filter;
Object.assign(params, userParams);
params.filter.skip = store.skip;
if (store.order && store.order.length) params.filter.order = store.order;

View File

@ -268,3 +268,8 @@ input::-webkit-inner-spin-button {
max-width: 400px;
}
}
.subName {
color: var(--vn-label-color);
text-transform: uppercase;
}

View File

@ -93,6 +93,10 @@ globals:
since: Since
from: From
to: To
quantity: Quantity
item: Item
ticket: Ticket
campaign: Campaign
pageTitles:
logIn: Login
summary: Summary

View File

@ -93,6 +93,10 @@ globals:
since: Desde
from: Desde
to: Hasta
quantity: Cantidad
item: Artículo
ticket: Ticket
campaign: Campaña
pageTitles:
logIn: Inicio de sesión
summary: Resumen

View File

@ -1,14 +1,20 @@
<script setup>
import { computed } from 'vue';
import { useRoute } from 'vue-router';
import VnCard from 'components/common/VnCard.vue';
import CustomerDescriptor from './CustomerDescriptor.vue';
import CustomerFilter from '../CustomerFilter.vue';
const route = useRoute();
const routeName = computed(() => route.name);
</script>
<template>
<VnCard
data-key="Client"
base-url="Clients"
:descriptor="CustomerDescriptor"
:filter-panel="CustomerFilter"
:filter-panel="routeName != 'CustomerConsumption' && CustomerFilter"
search-data-key="CustomerList"
:searchbar-props="{
url: 'Clients/extendedListFilter',

View File

@ -1,17 +1,183 @@
<script setup>
import { ref, computed, onBeforeMount } from 'vue';
import axios from 'axios';
import { useI18n } from 'vue-i18n';
import CustomerConsumptionFilter from './CustomerConsumptionFilter.vue';
import { useStateStore } from 'src/stores/useStateStore';
import { toDate } from 'src/filters/index';
import { useRoute } from 'vue-router';
import VnTable from 'components/VnTable/VnTable.vue';
import FetchedTags from 'components/ui/FetchedTags.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
const { t } = useI18n();
const route = useRoute();
const campaignList = ref();
const columns = computed(() => [
{
name: 'search',
align: 'left',
label: t('globals.search'),
visible: false,
},
{
name: 'itemFk',
align: 'left',
label: t('globals.item'),
columnClass: 'shrink',
columnFilter: {
name: 'itemId',
},
},
{
name: 'ticketFk',
align: 'left',
label: t('globals.ticket'),
columnFilter: {
inWhere: true,
},
},
{
name: 'shipped',
align: 'left',
label: t('globals.shipped'),
format: ({ shipped }) => toDate(shipped),
columnFilter: false,
},
{
name: 'description',
align: 'left',
label: t('globals.description'),
},
{
name: 'quantity',
label: t('globals.quantity'),
},
{
name: 'grouped',
label: t('Group by items'),
component: 'checkbox',
visible: false,
orderBy: false,
},
]);
onBeforeMount(async () => {
campaignList.value = (await axios('Campaigns/latest')).data;
});
const filter = computed(() => {
const minDate = Date.vnNew();
minDate.setHours(0, 0, 0, 0);
minDate.setMonth(minDate.getMonth() - 2);
const maxDate = Date.vnNew();
maxDate.setHours(23, 59, 59, 59);
return {
campaign: campaignList.value[0]?.id,
from: minDate,
to: maxDate,
filter: {
where: {
clientFk: route.params.id,
},
},
};
});
</script>
<template>
<Teleport to="#right-panel" v-if="useStateStore().isHeaderMounted()">
<CustomerConsumptionFilter data-key="CustomerConsumption" />
</Teleport>
<VnTable
v-if="campaignList"
data-key="CustomerConsumption"
url="Clients/consumption"
:order="['itemTypeFk', 'itemName', 'itemSize', 'description']"
:columns="columns"
search-url="consumption"
:user-params="filter"
:default-remove="false"
:default-reset="false"
:default-save="false"
:has-sub-toolbar="true"
auto-load
>
<template #moreBeforeActions>
<QBtn
color="primary"
icon="delete"
flat
@click="remove(selected)"
:disable="!selected?.length"
:title="t('globals.remove')"
/>
</template>
<template #column-itemFk="{ row }">
<span class="link">
{{ row.itemFk }}
<ItemDescriptorProxy :id="row.itemFk" />
</span>
</template>
<template #column-ticketFk="{ row }">
<span class="link">
{{ row.ticketFk }}
<TicketDescriptorProxy :id="row.ticketFk" />
</span>
</template>
<template #column-description="{ row }">
<div>{{ row.concept }}</div>
<div v-if="row.subName" class="subName">
{{ row.subName }}
</div>
<FetchedTags :item="row" :max-length="3" />
</template>
<template #moreFilterPanel="{ params }">
<div class="column no-wrap flex-center q-gutter-y-md q-mt-xs q-pr-xl">
<VnSelect
v-model="params.campaign"
:options="campaignList"
:label="t('globals.campaign')"
:filled="true"
class="q-px-sm q-pt-none fit"
dense
option-label="code"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>
{{ scope.opt?.code }}
{{
new Date(scope.opt?.dated).getFullYear()
}}</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnInputDate
v-model="params.to"
:label="t('globals.from')"
:filled="true"
class="q-px-xs q-pt-none fit"
dense
/>
<VnInputDate
v-model="params.from"
:label="t('globals.from')"
:filled="true"
class="q-px-xs q-pt-none fit"
dense
/>
</div>
</template>
</VnTable>
</template>
<i18n>
es:
Enter a new search: Introduce una nueva búsqueda
Group by items: Agrupar por artículos
</i18n>

View File

@ -10,7 +10,7 @@ const { t } = useI18n();
defineProps({ dataKey: { type: String, required: true } });
</script>
<template>
<VnFilterPanel :data-key="dataKey" :search-button="true">
<VnFilterPanel :data-key="dataKey" search-url="consumption">
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`params.${tag.label}`) }}: </strong>

View File

@ -26,27 +26,20 @@ const filter = {
limit: 20,
};
const basicSpan = {
component: 'span',
props: () => {},
event: () => {},
};
const tableColumnComponents = {
sent: {
component: 'span',
props: () => {},
event: () => {},
},
description: {
component: 'span',
props: () => {},
event: () => {},
},
sent: basicSpan,
description: basicSpan,
worker: {
component: QBtn,
props: () => ({ flat: true, color: 'blue', noCaps: true }),
event: () => {},
},
company: {
component: 'span',
props: () => {},
props: () => ({ class: 'link' }),
event: () => {},
},
company: basicSpan,
};
const columns = computed(() => [
@ -90,41 +83,34 @@ const toCustomerSamplesCreate = () => {
url="ClientSamples"
/>
<div class="full-width flex justify-center">
<QPage class="card-width q-pa-lg">
<QTable
:columns="columns"
:pagination="{ rowsPerPage: 12 }"
:rows="rows"
class="full-width q-mt-md"
row-key="id"
:no-data-label="t('globals.noResults')"
>
<template #body-cell="props">
<QTd :props="props">
<QTr :props="props" class="cursor-pointer">
<component
:is="tableColumnComponents[props.col.name].component"
class="col-content"
v-bind="
tableColumnComponents[props.col.name].props(props)
"
@click="
tableColumnComponents[props.col.name].event(props)
"
>
{{ props.value }}
<WorkerDescriptorProxy
:id="props.row.userFk"
v-if="props.col.name === 'worker'"
/>
</component>
</QTr>
</QTd>
</template>
</QTable>
</QPage>
</div>
<QTable
:columns="columns"
:pagination="{ rowsPerPage: 12 }"
:rows="rows"
class="full-width q-mt-md"
row-key="id"
:no-data-label="t('globals.noResults')"
>
<template #body-cell="props">
<QTd auto-width :props="props">
<span :props="props" class="cursor-pointer">
<component
:is="tableColumnComponents[props.col.name].component"
class="col-content"
v-bind="tableColumnComponents[props.col.name].props(props)"
@click="tableColumnComponents[props.col.name].event(props)"
:title="props.value"
>
{{ props.value }}
<WorkerDescriptorProxy
:id="props.row.userFk"
v-if="props.col.name === 'worker'"
/>
</component>
</span>
</QTd>
</template>
</QTable>
<QPageSticky :offset="[18, 18]">
<QBtn @click.stop="toCustomerSamplesCreate()" color="primary" fab icon="add" />

View File

@ -33,7 +33,6 @@ async function onSubmit() {
};
try {
console.log('newPassword: ', newPassword);
await axios.post(
'VnUsers/reset-password',
{ newPassword: newPassword.value },