#7553 modified TicketExpedition & changes in ticket section #571

Merged
jon merged 79 commits from 7553_FixTicketExpedition into dev 2024-09-25 05:51:16 +00:00
9 changed files with 149 additions and 233 deletions
Showing only changes of commit 2ab7d48b0c - Show all commits

1
salix-front-mindshore Submodule

@ -0,0 +1 @@
Subproject commit 7432396ceafb7fe46b8ed8ac28fa7753df57efd2

View File

@ -1,41 +1,37 @@
<script setup>
import { onMounted, ref, computed, onUnmounted, reactive, watch } from 'vue';
import { onMounted, ref, computed, onUnmounted, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import FetchData from 'components/FetchData.vue';
import VnInput from 'src/components/common/VnInput.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import TicketEditManaProxy from './TicketEditMana.vue';
import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import ExpeditionNewTicket from './ExpeditionNewTicket.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency, toPercentage } from 'src/filters';
import { useArrayData } from 'composables/useArrayData';
import { useVnConfirm } from 'composables/useVnConfirm';
import useNotify from 'src/composables/useNotify.js';
import { toDateTimeFormat } from 'src/filters/date';
import axios from 'axios';
import VnTable from 'src/components/VnTable/VnTable.vue';
const route = useRoute();
const stateStore = useStateStore();
const { t } = useI18n();
const { notify } = useNotify();
const { openConfirmationModal } = useVnConfirm();
const editPriceProxyRef = ref(null);
const newTicketDialogRef = ref(null);
const logsTableDialogRef = ref(null);
const tableRef = ref();
const expeditionsLogsData = ref([]);
const selectedExpeditions = ref([]);
const allColumnNames = ref([]);
const visibleColumns = ref([]);
const newTicketWithRoute = ref(false);
const itemsOptions = ref([]);
const selectedRows = ref([]);
const hasSelectedRows = computed(() => selectedRows.value.length > 0);
const exprBuilder = (param, value) => {
switch (param) {
@ -56,8 +52,6 @@ const expeditionsArrayData = useArrayData('ticketExpeditions', {
filter: expeditionsFilter.value,
exprBuilder: exprBuilder,
});
const expeditionsStore = expeditionsArrayData.store;
const ticketExpeditions = computed(() => expeditionsStore.data);
const ticketArrayData = useArrayData('ticketData');
const ticketStore = ticketArrayData.store;
@ -75,127 +69,95 @@ watch(
{ immediate: true }
);
const params = reactive({});
const applyColumnFilter = async (col) => {
try {
const paramKey = col.columnFilter?.filterParamKey || col.field;
params[paramKey] = col.columnFilter.filterValue;
await expeditionsArrayData.addFilter({ filter: expeditionsFilter.value, 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 columns = computed(() => [
{
align: 'left',
label: t('expedition.id'),
name: 'id',
field: 'id',
align: 'left',
sortable: true,
chip: {
condition: () => true,
},
isId: true,
columnFilter: {
component: VnInput,
type: 'text',
filterParamKey: 'expeditionFk',
filterValue: null,
event: getInputEvents,
attrs: {
dense: true,
},
inWhere: true,
},
},
{
label: t('expedition.item'),
name: 'item',
name: 'packagingItemFk',
align: 'left',
cardVisible: true,
columnFilter: {
component: VnInput,
type: 'text',
filterParamKey: 'packageItemName',
filterValue: null,
event: getInputEvents,
attrs: {
dense: true,
},
inWhere: true,
},
},
{
label: t('expedition.name'),
name: 'name',
field: 'packageItemName',
name: 'packageItemName',
align: 'left',
isTitle: true,
columnFilter: {
component: VnSelect,
type: 'select',
filterValue: null,
event: getInputEvents,
attrs: {
options: itemsOptions.value,
'option-value': 'id',
'option-label': 'name',
dense: true,
},
inWhere: true,
// component: 'select',
// attrs: {
// url: 'Items',
// useLike: false,
// fields: ['id', 'name'],
// optionLabel: 'name',
// optionValue: 'id',
// },
},
},
{
label: t('expedition.packageType'),
name: 'packageType',
field: 'freightItemName',
name: 'freightItemName',
align: 'left',
columnFilter: {
component: VnInput,
type: 'text',
// filterParamKey: 'expeditionFk',
filterValue: null,
event: getInputEvents,
attrs: {
dense: true,
},
inWhere: true,
},
},
{
label: t('expedition.counter'),
name: 'counter',
field: 'counter',
align: 'left',
columnFilter: null,
columnFilter: {
inWhere: true,
},
},
{
label: t('expedition.externalId'),
name: 'externalId',
field: 'externalId',
align: 'left',
columnFilter: null,
cardVisible: true,
columnFilter: {
inWhere: true,
},
},
{
label: t('expedition.created'),
name: 'created',
field: 'created',
align: 'left',
columnFilter: null,
format: (value) => toDateTimeFormat(value),
cardVisible: true,
format: (row) => toDateTimeFormat(row.created),
},
{
label: t('expedition.state'),
name: 'state',
field: 'state',
align: 'left',
columnFilter: null,
cardVisible: true,
columnFilter: { inWhere: true },
},
{
label: '',
name: 'history',
align: 'left',
columnFilter: null,
align: 'right',
name: 'tableActions',
actions: [
{
title: t('expedition.historyAction'),
icon: 'history',
isPrimary: true,
action: (row) => showLog(row),
},
],
},
]);
@ -204,23 +166,35 @@ const logTableColumns = computed(() => [
label: t('expedition.state'),
name: 'state',
field: 'state',
align: 'left',
align: 'center',
sortable: true,
},
{
label: t('expedition.name'),
name: 'name',
align: 'name',
field: 'name',
align: 'center',
columnFilter: null,
},
{
label: t('expedition.created'),
name: 'created',
field: 'created',
align: 'left',
align: 'center',
columnFilter: null,
format: (value) => toDateTimeFormat(value),
},
{
label: t('expedition.isScanned'),
name: 'isScanned',
field: 'isScanned',
align: 'center',
columnFilter: null,
format: (value) => {
if (value === true) return t('expedition.yes');
else return t('expedition.no');
},
},
]);
const showNewTicketDialog = (withRoute = false) => {
@ -255,10 +229,20 @@ const getExpeditionState = async (expedition) => {
order: ['created DESC'],
};
const { data } = await axios.get(`ExpeditionStates/filter`, {
const { data: expeditionStates } = await axios.get(`ExpeditionStates/filter`, {
params: { filter: JSON.stringify(filter) },
});
expeditionsLogsData.value = data;
const { data: scannedStates } = await axios.get(`ExpeditionStates`, {
params: { filter: JSON.stringify(filter), fields: ['id', 'isScanned'] },
});
expeditionsLogsData.value = expeditionStates.map((state) => {
const scannedState = scannedStates.find((s) => s.id === state.id);
return {
...state,
isScanned: scannedState ? scannedState.isScanned : false,
};
});
} catch (error) {
console.error(error);
}
@ -268,19 +252,12 @@ onMounted(async () => {
stateStore.rightDrawer = true;
const filteredColumns = columns.value.filter((col) => col.name !== 'history');
allColumnNames.value = filteredColumns.map((col) => col.name);
// await expeditionsArrayData.fetch({ append: false });
});
onUnmounted(() => (stateStore.rightDrawer = false));
</script>
<template>
<FetchData
url="Items"
auto-load
:filter="{ fields: ['id', 'name'], order: 'name ASC' }"
@on-fetch="(data) => (itemsOptions = data)"
/>
<VnSubToolbar>
<template #st-data>
<TableVisibleColumns
@ -296,7 +273,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
ref="btnDropdownRef"
color="primary"
:label="t('expedition.move')"
:disable="!selectedExpeditions.length"
:disable="!hasSelectedRows"
>
<template #label>
<QTooltip>{{ t('Select lines to see the options') }}</QTooltip>
@ -329,7 +306,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
</QList>
</QBtnDropdown>
<QBtn
:disable="!selectedExpeditions.length"
:disable="!hasSelectedRows"
icon="delete"
color="primary"
@click="
@ -344,110 +321,27 @@ onUnmounted(() => (stateStore.rightDrawer = false));
</template>
</VnSubToolbar>
<QTable
:rows="ticketExpeditions"
<VnTable
ref="tableRef"
data-key="TicketExpedition"
url="Expeditions/filter"
:columns="columns"
row-key="id"
:pagination="{ rowsPerPage: 0 }"
class="full-width q-mt-md"
selection="multiple"
v-model:selected="selectedExpeditions"
:visible-columns="visibleColumns"
:no-data-label="t('globals.noResults')"
:filter="expeditionsFilter"
v-model:selected="selectedRows"
:table="{
'row-key': 'id',
selection: 'multiple',
}"
default-mode="table"
auto-load
>
<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 #body-cell-item="{ row }">
<QTd auto-width @click.stop>
<QBtn flat color="primary">{{ row.packagingItemFk }}</QBtn>
<template #column-packagingItemFk="{ row }">
<span class="link" @click.stop>
{{ row.packagingItemFk }}
<ItemDescriptorProxy :id="row.packagingItemFk" />
</QTd>
</span>
</template>
<template #body-cell-available="{ row }">
<QTd @click.stop>
<QBadge :color="row.available < 0 ? 'alert' : 'transparent'" dense>
{{ row.available }}
</QBadge>
</QTd>
</template>
<template #body-cell-price="{ row }">
<QTd>
<template v-if="isTicketEditable && row.id">
<QBtn flat color="primary" dense @click="onOpenEditPricePopover(row)">
{{ toCurrency(row.price) }}
</QBtn>
<TicketEditManaProxy
ref="editPriceProxyRef"
:mana="mana"
:new-price="getNewPrice"
@save="updatePrice(row)"
>
<VnInput
v-model.number="edit.price"
:label="t('ticketSale.price')"
type="number"
/>
</TicketEditManaProxy>
</template>
<span v-else>{{ toCurrency(row.price) }}</span>
</QTd>
</template>
<template #body-cell-discount="{ row }">
<QTd>
<template v-if="!isLocked && row.id">
<QBtn
flat
color="primary"
dense
@click="onOpenEditDiscountPopover(row)"
>
{{ toPercentage(row.discount / 100) }}
</QBtn>
<TicketEditManaProxy
:mana="mana"
:new-price="getNewPrice"
@save="changeDiscount(row)"
>
<VnInput
v-model.number="edit.discount"
:label="t('ticketSale.discount')"
type="number"
/>
</TicketEditManaProxy>
</template>
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
</QTd>
</template>
<template #body-cell-history="{ row }">
<QTd>
<QBtn
@click.stop="showLog(row)"
color="primary"
icon="history"
size="md"
flat
>
<QTooltip class="text-no-wrap">
{{ t('expedition.historyAction') }}
</QTooltip>
</QBtn>
</QTd>
</template>
</QTable>
</VnTable>
<QDialog ref="newTicketDialogRef" transition-show="scale" transition-hide="scale">
<ExpeditionNewTicket
:ticket="ticketData"
@ -461,12 +355,14 @@ onUnmounted(() => (stateStore.rightDrawer = false));
data-key="TicketExpeditionLog"
:rows="expeditionsLogsData"
:columns="logTableColumns"
class="q-pa-sm"
class="q-pa-md full-width"
>
<template #body-cell-name="{ row }">
<QTd auto-width>
<QBtn flat dense color="primary">{{ row.name }}</QBtn>
<WorkerDescriptorProxy :id="row.workerFk" />
<QTd style="text-align: center">
<span class="link" @click.stop>
<QBtn flat dense>{{ row.name }}</QBtn>
<WorkerDescriptorProxy :id="row.workerFk" />
</span>
</QTd>
</template>
</QTable>

View File

@ -186,18 +186,22 @@ const openCreateModal = () => createTicketRequestDialogRef.value.show();
</template>
<template #body-cell-requester="{ row }">
<QTd @click.stop>
<QBtn flat color="primary">
{{ row.requester?.user?.nickname }}
<WorkerDescriptorProxy :id="row.requesterFk" />
</QBtn>
<span class="link">
<QBtn flat>
{{ row.requester?.user?.nickname }}
<WorkerDescriptorProxy :id="row.requesterFk" />
</QBtn>
</span>
</QTd>
</template>
<template #body-cell-atender="{ row }">
<QTd @click.stop>
<QBtn flat color="primary">
{{ row.atender?.user?.nickname }}
<WorkerDescriptorProxy :id="row.attenderFk" />
</QBtn>
<span class="link">
<QBtn flat>
{{ row.atender?.user?.nickname }}
<WorkerDescriptorProxy :id="row.attenderFk" />
</QBtn>
</span>
</QTd>
</template>
<template #body-cell-quantity="{ row }">
jon marked this conversation as resolved Outdated

Los campos de cantidad y precio tienen el mismo tamaño que descripción?
Propongo recortar el tamaño y asi ganar ancho en campos como el que he dicho
Igual pasa con la columna de borrar

Los campos de cantidad y precio tienen el mismo tamaño que descripción? Propongo recortar el tamaño y asi ganar ancho en campos como el que he dicho Igual pasa con la columna de borrar
@ -220,10 +224,12 @@ const openCreateModal = () => createTicketRequestDialogRef.value.show();
</template>
<template #body-cell-saleFk="{ row }">
<QTd @click.stop>
<QBtn v-if="row.saleFk" flat color="primary">
{{ row.sale.itemFk }}
<ItemDescriptorProxy :id="row.sale.itemFk" />
</QBtn>
<span class="link">
<QBtn v-if="row.saleFk" flat>
{{ row.sale.itemFk }}
<ItemDescriptorProxy :id="row.sale.itemFk" />
</QBtn>
</span>
</QTd>
</template>
<template #body-cell-actions="{ row }">

View File

@ -11,7 +11,6 @@ import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import TicketEditManaProxy from './TicketEditMana.vue';
import VnImg from 'src/components/ui/VnImg.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import TicketSaleMoreActions from './TicketSaleMoreActions.vue';
import TicketTransfer from './TicketTransfer.vue';
@ -620,10 +619,12 @@ onUnmounted(() => (stateStore.rightDrawer = false));
<template #body-cell-itemFk="{ row }">
jon marked this conversation as resolved Outdated

Podemos hacer que la columna articulo sea mas ancho para que quepan mas registros por filas?
Por ejemplo hay campos numéricos que tienen mucho ancho

Podemos hacer que la columna articulo sea mas ancho para que quepan mas registros por filas? Por ejemplo hay campos numéricos que tienen mucho ancho
<QTd @click.stop>
<div v-if="row.id">
<QBtn flat color="primary" dense>
{{ row.itemFk }}
</QBtn>
<ItemDescriptorProxy :id="row.itemFk" />
<span class="link">
<QBtn flat dense>
{{ row.itemFk }}
</QBtn>
<ItemDescriptorProxy :id="row.itemFk" />
</span>
</div>
<VnSelect
v-else

View File

@ -406,10 +406,12 @@ const qCheckBoxController = (sale, action) => {
<template #body-cell-item="{ row }">
<QTd @click.stop>
<div>
<QBtn flat color="primary">
{{ row.itemFk }}
</QBtn>
<ItemDescriptorProxy :id="row.itemFk" />
<span class="link">
jon marked this conversation as resolved Outdated

Podemos recortar la columna de acciones en favor de tener FetchedTags en una linea?

Podemos recortar la columna de acciones en favor de tener FetchedTags en una linea?
<QBtn flat>
{{ row.itemFk }}
</QBtn>
<ItemDescriptorProxy :id="row.itemFk" />
</span>
</div>
</QTd>
</template>

View File

@ -95,10 +95,12 @@ const openCreateModal = () => createTrackingDialogRef.value.show();
>
<template #body-cell-worker="{ row }">
<QTd @click.stop>
<QBtn flat color="primary">
{{ row.user?.name }}
<WorkerDescriptorProxy :id="row.user?.worker?.id" />
</QBtn>
<span class="link">
<QBtn flat>
Review

Aqui habia un cambio con respecto al orden de los filtros. Seguro que jorge sabe donde se hace porque lo hizo para InvoiceInSummary

Aqui habia un cambio con respecto al orden de los filtros. Seguro que jorge sabe donde se hace porque lo hizo para InvoiceInSummary
{{ row.user?.name }}
<WorkerDescriptorProxy :id="row.user?.worker?.id" />
</QBtn>
</span>
</QTd>
</template>
</QTable>

View File

@ -134,10 +134,12 @@ onUnmounted(() => (stateStore.rightDrawer = false));
>
<template #body-cell-item="{ row }">
<QTd>
<QBtn flat color="primary">
{{ row.itemFk }}
<ItemDescriptorProxy :id="row.itemFk" />
</QBtn>
<span class="link">
<QBtn flat>
{{ row.itemFk }}
<ItemDescriptorProxy :id="row.itemFk" />
</QBtn>
</span>
</QTd>
</template>
<template #body-cell-description="{ row }">

View File

@ -112,6 +112,9 @@ expedition:
removeExpeditionSubtitle: Are you sure you want to delete this expedition?
worker: Worker
move: Move
isScanned: Is scanned
yes: Yes
no: No
basicData:
next: Next
back: Back

View File

@ -201,6 +201,9 @@ expedition:
removeExpeditionSubtitle: ¿Está seguro de eliminar esta expedición?
worker: Trabajador
move: Mover
isScanned: Escaneado
yes:
no: No
package:
package: Embalaje
quantity: Cantidad