Tickets future #461

Merged
jsegarra merged 10 commits from :feature/TicketsFuture into dev 2024-06-25 12:30:35 +00:00
6 changed files with 499 additions and 1 deletions
Showing only changes of commit 06e8e819f4 - Show all commits

View File

@ -442,6 +442,7 @@ ticket:
sms: Sms
notes: Notes
sale: Sale
futureTickets: Future tickets
list:
nickname: Nickname
state: State

View File

@ -440,6 +440,7 @@ ticket:
sms: Sms
notes: Notas
sale: Lineas del pedido
futureTickets: Tickets a futuro
list:
nickname: Alias
state: Estado

View File

@ -0,0 +1,443 @@
<script setup>
import { onMounted, ref, computed, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { dashIfEmpty, toCurrency } from 'src/filters';
import { useVnConfirm } from 'composables/useVnConfirm';
import { useArrayData } from 'composables/useArrayData';
import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
import useNotify from 'src/composables/useNotify.js';
import { useState } from 'src/composables/useState';
import { toDateTimeFormat } from 'src/filters/date.js';
const state = useState();
const { t } = useI18n();
const { openConfirmationModal } = useVnConfirm();
const { notify } = useNotify();
const user = state.getUser();
const agencyModesOptions = ref([]);
const selectedTickets = ref([]);
const exprBuilder = (param, value) => {
switch (param) {
case 'id':
return { id: value };
case 'futureId':
return { futureId: value };
case 'liters':
return { liters: value };
case 'lines':
return { lines: value };
case 'ipt':
return { ipt: { like: `%${value}%` } };
case 'futureIpt':
return { futureIpt: { like: `%${value}%` } };
case 'totalWithVat':
return { totalWithVat: value };
}
};
const userParams = reactive({
futureDated: Date.vnNew(),
originDated: Date.vnNew(),
warehouseFk: user.value.warehouseFk,
});
const arrayData = useArrayData('FutureTickets', {
url: 'Tickets/getTicketsFuture',
userParams: userParams,
exprBuilder: exprBuilder,
});
const { store } = arrayData;
const params = reactive({
futureDated: Date.vnNew(),
originDated: Date.vnNew(),
warehouseFk: user.value.warehouseFk,
});
const applyColumnFilter = async (col) => {
try {
const paramKey = col.columnFilter?.filterParamKey || col.field;
params[paramKey] = col.columnFilter.filterValue;
console.log('paramKey', paramKey, 'params', params);
await arrayData.applyFilter({ params });
} catch (err) {
console.error('Error applying column filter', err);
}
};
const getInputEvents = (col) => {
return col.columnFilter.type === 'select'
? { 'update:modelValue': () => applyColumnFilter(col) }
: {
'keyup.enter': () => applyColumnFilter(col),
};
};
const ticketColumns = computed(() => [
Review

Revisamos el comportamiento de los filtros porque el valor desaparece y no filtra

Revisamos el comportamiento de los filtros porque el valor desaparece y no filtra
{
label: t('futureTickets.problems'),
name: 'problems',
align: 'left',
columnFilter: null,
},
{
label: t('futureTickets.ticketId'),
name: 'ticketId',
align: 'center',
sortable: true,
columnFilter: {
component: VnInput,
type: 'text',
filterValue: null,
filterParamKey: 'id',
event: getInputEvents,
attrs: {
dense: true,
},
},
},
{
label: t('futureTickets.shipped'),
name: 'shipped',
align: 'left',
sortable: true,
columnFilter: null,
},
{
label: t('futureTickets.ipt'),
name: 'ipt',
field: 'ipt',
align: 'left',
sortable: true,
columnFilter: null,
format: (val) => dashIfEmpty(val),
},
{
label: t('futureTickets.state'),
name: 'state',
align: 'left',
sortable: true,
columnFilter: null,
},
{
label: t('futureTickets.liters'),
name: 'liters',
field: 'liters',
align: 'left',
sortable: true,
columnFilter: null,
},
{
label: t('futureTickets.import'),
field: 'import',
name: 'import',
align: 'left',
sortable: true,
// columnFilter: {
// component: VnInput,
// type: 'text',
// filterValue: null,
// event: getInputEvents,
// filterParamKey: 'nickName',
// attrs: {
// dense: true,
// },
// },
},
{
label: t('futureTickets.availableLines'),
name: 'lines',
field: 'lines',
align: 'left',
sortable: true,
columnFilter: null,
format: (val) => dashIfEmpty(val),
},
{
label: t('futureTickets.futureId'),
name: 'futureId',
align: 'left',
sortable: true,
columnFilter: null,
},
{
label: t('futureTickets.futureShipped'),
name: 'futureShipped',
align: 'left',
sortable: true,
columnFilter: null,
format: (val) => dashIfEmpty(val),
},
{
label: t('futureTickets.futureIpt'),
name: 'futureIpt',
field: 'futureIpt',
align: 'left',
sortable: true,
columnFilter: null,
format: (val) => dashIfEmpty(val),
},
{
label: t('futureTickets.futureState'),
name: 'futureState',
align: 'left',
sortable: true,
columnFilter: null,
format: (val) => dashIfEmpty(val),
},
]);
const isLessThan50 = (totalWithVat) =>
parseInt(totalWithVat) > 0 && parseInt(totalWithVat) < 50;
const totalPriceColor = (totalWithVat) =>
isLessThan50(totalWithVat) ? 'warning' : 'transparent';
onMounted(async () => {
await arrayData.fetch({ append: false });
});
</script>
<template>
<FetchData
url="Tickets/getTicketsFuture"
:filter="{ fields: ['id', 'name'], order: 'name' }"
@on-fetch="(data) => (agencyModesOptions = data)"
/>
<VnSearchbar
data-key="WeeklyTickets"
:label="t('weeklyTickets.search')"
:info="t('weeklyTickets.searchInfo')"
/>
<VnSubToolbar>
<template #st-data>
<QBtn icon="keyboard_double_arrow_right" color="primary" />
</template>
</VnSubToolbar>
<QPage class="column items-center q-pa-md">
<QTable
:rows="store.data"
:columns="ticketColumns"
row-key="id"
selection="multiple"
v-model:selected="selectedTickets"
:pagination="{ rowsPerPage: 0 }"
:no-data-label="t('globals.noResults')"
style="max-width: 99%"
>
<template #header>
<QTr>
<QTh class="horizontal-separator" />
<QTh class="horizontal-separator" colspan="8" translate>
{{ t('futureTickets.origin') }}
</QTh>
<QTh class="horizontal-separator" colspan="4" translate>
{{ t('futureTickets.destination') }}
</QTh>
</QTr>
<QTr>
<QTh />
<QTh
v-for="(col, index) in ticketColumns"
:key="index"
:class="{ 'vertical-separator': col.name === 'futureId' }"
>
{{ col.label }}
</QTh>
</QTr>
</template>
<template #top-row="{ cols }">
<QTr>
<QTd />
<QTd
v-for="(col, index) in cols"
:key="index"
style="max-width: 100px"
>
<component
:is="col.columnFilter.component"
v-if="col.columnFilter"
v-model="col.columnFilter.filterValue"
v-bind="col.columnFilter.attrs"
v-on="col.columnFilter.event(col)"
dense
/>
</QTd>
</QTr>
</template>
<template #header-cell-availableLines="{ col }">
<QTh class="vertical-separator">
{{ col.label }}
</QTh>
</template>
<template #body-cell-problems="{ row }">
<QTd class="q-gutter-x-xs">
<QIcon
v-if="row.isTaxDataChecked === 0"
color="primary"
name="vn:no036"
size="xs"
jsegarra marked this conversation as resolved
Review

Añadir tooltip

Añadir tooltip
Review

Añadido.

Commit: 4e7c09fa44

Añadido. Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/4e7c09fa44fa60ff29bf3647711979e33bfb455e
>
<QTooltip>
{{ t('futureTickets.noVerified') }}
</QTooltip>
</QIcon>
<QIcon
v-if="row.hasTicketRequest"
color="primary"
name="vn:buyrequest"
size="xs"
>
<QTooltip>
{{ t('futureTickets.purchaseRequest') }}
</QTooltip>
jsegarra marked this conversation as resolved Outdated

No veo el selector/checkbox global

No veo el selector/checkbox global

Checkbox añadido.

Commit: 79c606fc70

Checkbox añadido. Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/79c606fc7059c51c911d96348a7a5de96000fcb9
</QIcon>
<QIcon
v-if="row.itemShortage"
color="primary"
name="vn:unavailable"
size="xs"
>
<QTooltip>
jsegarra marked this conversation as resolved
Review

Propuesta, añadir hide-bottom

Propuesta, añadir hide-bottom
Review

Si quieres lo mantenemos pero cuando se cierre el modal que no aparezca el texto de que hay una fila seleccionada, cuando no la hay

Si quieres lo mantenemos pero cuando se cierre el modal que no aparezca el texto de que hay una fila seleccionada, cuando no la hay
Review

Fixed.

Commit: 6cd8a478fa

Fixed. Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/6cd8a478fa39d39243e99efd191e386b666328e7
{{ t('futureTickets.noVisible') }}
</QTooltip>
</QIcon>
<QIcon
v-if="row.isFreezed"
jsegarra marked this conversation as resolved
Review

text-transform: uppercase
Y diria que tambien falta poner en texto ligthgray

text-transform: uppercase Y diria que tambien falta poner en texto ligthgray
Review

Cambios añadidos.

Commit: b6ec10994a

Cambios añadidos. Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/b6ec10994ae48a687198bf9d824bdcfa7bd7d699
color="primary"
name="vn:frozen"
size="xs"
>
<QTooltip>
{{ t('futureTickets.clientFrozen') }}
</QTooltip>
</QIcon>
<QIcon v-if="row.risk" color="primary" name="vn:risk" size="xs">
<QTooltip>
{{ t('futureTickets.risk') }}: {{ row.risk }}
</QTooltip>
</QIcon>
<QIcon
v-if="row.hasComponentLack"
color="primary"
name="vn:components"
size="xs"
>
<QTooltip>
{{ t('futureTickets.componentLack') }}
</QTooltip>
</QIcon>
<QIcon
v-if="row.hasRounding"
color="primary"
name="sync_problem"
size="xs"
>
<QTooltip>
{{ t('futureTickets.rounding') }}
</QTooltip>
</QIcon>
</QTd>
</template>
<template #body-cell-ticketId="{ row }">
<QTd>
<QBtn flat color="primary">
{{ row.id }}
<TicketDescriptorProxy :id="row.id" />
</QBtn>
</QTd>
</template>
<template #body-cell-shipped="{ row }">
<QTd>
<QBadge
text-color="black"
:color="getDateQBadgeColor(row.shipped)"
class="q-ma-none"
>
{{ toDateTimeFormat(row.shipped) }}
</QBadge>
</QTd>
</template>
<template #body-cell-state="{ row }">
<QTd>
<QBadge
text-color="black"
:color="row.classColor"
class="q-ma-none"
dense
>
{{ row.state }}
</QBadge>
</QTd>
</template>
<template #body-cell-import="{ row }">
<QTd>
<QBadge
text-color="black"
:color="totalPriceColor(row.totalWithVat)"
class="q-ma-none"
dense
>
{{ toCurrency(row.totalWithVat || 0) }}
</QBadge>
</QTd>
</template>
<template #body-cell-futureId="{ row }">
<QTd class="vertical-separator">
<QBtn flat color="primary" dense>
{{ row.futureId }}
<TicketDescriptorProxy :id="row.futureId" />
</QBtn>
</QTd>
</template>
<template #body-cell-futureShipped="{ row }">
<QTd>
<QBadge
text-color="black"
:color="getDateQBadgeColor(row.futureShipped)"
class="q-ma-none"
>
{{ toDateTimeFormat(row.futureShipped) }}
</QBadge>
</QTd>
</template>
<template #body-cell-futureState="{ row }">
<QTd>
<QBadge
text-color="black"
:color="row.futureClassColor"
class="q-ma-none"
dense
>
{{ row.futureState }}
</QBadge>
</QTd>
</template>
</QTable>
</QPage>
</template>
<style scoped lang="scss">
.vertical-separator {
border-left: 4px solid white !important;
}
.horizontal-separator {
border-bottom: 4px solid white !important;
}
</style>
<i18n>
es:
</i18n>

View File

@ -0,0 +1,22 @@
futureTickets:
problems: Problems
ticketId: ID
shipped: Date
ipt: IPT
state: State
liters: Liters
import: Import
availableLines: Available lines
futureId: ID
futureShipped: Date
futureIpt: IPT
futureState: State
noVerified: No verified data
noVisible: Not visible
purchaseRequest: Purchase request
clientFrozen: Client frozen
componentLack: Component lack
rounding: Rounding
risk: Risk
origin: Origin
destination: Destination

View File

@ -1,2 +1,24 @@
futureTickets:
problems: Problemas
ticketId: ID
shipped: Fecha
ipt: IPT
state: Estado
liters: Litros
import: Importe
availableLines: Líneas disponibles
futureId: ID
futureShipped: Fecha
futureIpt: IPT
futureState: Estado
noVerified: Sin datos comprobados
noVisible: No visible
purchaseRequest: Petición de compra
clientFrozen: Cliente congelado
risk: Riesgo
componentLack: Faltan componentes
rounding: Redondeo
origin: Origen
destination: Destino
Search ticket: Buscar ticket
You can search by ticket id or alias: Puedes buscar por id o alias del ticket

View File

@ -11,7 +11,7 @@ export default {
component: RouterView,
redirect: { name: 'TicketMain' },
menus: {
main: ['TicketList'],
main: ['TicketList', 'TicketFuture'],
card: ['TicketBoxing', 'TicketSms', 'TicketSale'],
},
children: [
@ -40,6 +40,15 @@ export default {
},
component: () => import('src/pages/Ticket/TicketCreate.vue'),
},
{
name: 'TicketFuture',
path: 'future',
meta: {
title: 'futureTickets',
icon: 'keyboard_double_arrow_right',
},
component: () => import('src/pages/Ticket/TicketFuture.vue'),
},
],
},
{