feat: #6321 Split tickets
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Javier Segarra 2024-05-24 13:52:51 +02:00
parent 1eedb6f79b
commit 36d166ab44
4 changed files with 129 additions and 97 deletions

View File

@ -1,15 +1,16 @@
<script setup> <script setup>
import { ref } from 'vue'; import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import { useDialogPluginComponent } from 'quasar'; import { useDialogPluginComponent } from 'quasar';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnPaginate from 'src/components/ui/VnPaginate.vue';
const editableStates = ref([]);
const { t } = useI18n(); const { t } = useI18n();
const showChangeStateDialog = ref(false); const showChangeStateDialog = ref(false);
const newState = ref(null); const newState = ref(null);
const resultSplit = ref([]);
const { dialogRef, onDialogHide } = useDialogPluginComponent(); const { dialogRef, onDialogHide } = useDialogPluginComponent();
const $props = defineProps({ const $props = defineProps({
tickets: { tickets: {
@ -17,6 +18,11 @@ const $props = defineProps({
default: () => [], default: () => [],
}, },
}); });
const ticketsSelected = ref([]);
onMounted(() => {
ticketsSelected.value = [...new Set($props.tickets.map(({ ticketFk }) => ticketFk))];
});
const updateState = async () => { const updateState = async () => {
try { try {
showChangeStateDialog.value = true; showChangeStateDialog.value = true;
@ -33,15 +39,47 @@ const updateState = async () => {
dialogRef.value.hide({ type: 'refresh', refresh: true }); dialogRef.value.hide({ type: 'refresh', refresh: true });
} }
}; };
const step = ref(1);
const labelStepperBtn = (step) => {
switch (step) {
case 1:
return 'Split';
case 2:
return 'Finish';
default:
return 'Continue';
}
};
const clickStepperBtn = () => {
switch (stepperRef.value.modelValue) {
case 1:
split();
default:
stepperRef.value.next();
break;
}
};
const statusStepperBtn = () => {
switch (stepperRef.value.modelValue) {
case 1:
return ticketsSelected.value.length < 1;
default:
return true;
}
};
const split = async (data = ticketsSelected.value) => {
await axios.post(`Tickets/split`, data);
resultSplit.value = data;
};
const stepperRef = ref(null);
</script> </script>
<template> <template>
<QDialog ref="dialogRef" @hide="onDialogHide" v-model="showChangeStateDialog"> <QDialog ref="dialogRef" @hide="onDialogHide" v-model="showChangeStateDialog">
<FetchData
url="States/editableStates"
@on-fetch="(data) => (editableStates = data)"
auto-load
/>
<QCard class="q-pa-sm"> <QCard class="q-pa-sm">
<QCardSection class="row items-center q-pb-none"> <QCardSection class="row items-center q-pb-none">
<QAvatar <QAvatar
@ -52,22 +90,74 @@ const updateState = async () => {
v-if="icon" v-if="icon"
/> />
<span class="text-h6 text-grey">{{ <span class="text-h6 text-grey">{{
t('negative.detail.modal.changeState.title') t('negative.detail.split.title')
}}</span> }}</span>
<QSpace /> <QSpace />
<QBtn icon="close" flat round dense v-close-popup /> <QBtn icon="close" flat round dense v-close-popup />
</QCardSection> </QCardSection>
<QCardSection class="row items-center justify-center column items-stretch"> <QCardSection class="row items-center justify-center column items-stretch">
<span>{{ t('negative.detail.modal.changeState.title') }}</span> {{ tickets }}
<VnSelect <QStepper v-model="step" ref="stepperRef" color="primary" animated>
:label="t('negative.detail.modal.changeState.placeholder')" <QStep :name="1" title="Confirm tickets to split" icon="settings">
v-model="newState" {{ ticketsSelected }}
:options="editableStates" <div>
option-label="name" <QCheckbox
option-value="code" class="q-pa-md"
v-for="(ticket, index) in tickets"
:key="index"
v-model="ticketsSelected"
:label="` Ticket: ${ticket.ticketFk}`"
:val="ticket.ticketFk"
>
</QCheckbox>
</div>
</QStep>
<QStep
:name="2"
title="Handle tickets splitted"
icon="settings"
:done="step > 2"
><VnPaginate data-key="splitLack" :data="tickets">
<template #body="{ rows }">
<QTable :rows="rows" :columns="columns">
<template #header="props">
<QTr :props="props">
<QTh
v-for="col in props.cols"
:key="col.name"
:props="props"
>
{{ t(col.label) }}
</QTh>
</QTr>
</template>
<template #body="props">
<QTr :props="props"></QTr
></template> </QTable
></template> </VnPaginate
></QStep>
<template #navigation>
<QStepperNavigation>
<QBtn
@click="clickStepperBtn"
color="primary"
:label="labelStepperBtn(step)"
:disabled="statusStepperBtn()"
/> />
<QBtn
v-if="step > 1"
flat
color="primary"
@click="stepperRef.previous()"
label="Back"
class="q-ml-sm"
/>
</QStepperNavigation>
</template>
</QStepper>
</QCardSection> </QCardSection>
<QCardActions align="right"> <QCardActions align="right">
<QBtn :label="t('globals.next')" color="primary" flat v-close-popup />
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup /> <QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
<QBtn <QBtn
:label="t('globals.confirm')" :label="t('globals.confirm')"

View File

@ -71,10 +71,11 @@ const getInputEvents = (colField, props) => ({
const saveChange = async (field, { rowIndex, row }) => { const saveChange = async (field, { rowIndex, row }) => {
try { try {
switch (field) { switch (field) {
case 'split': // case 'split':
await split({ simple: true }, [row]); // showSplitDialog.value =true
// // await split({ simple: true }, [row]);
break; // break;
case 'code': case 'code':
await axios.post(`Tickets/state`, { await axios.post(`Tickets/state`, {
ticketFk: row.ticketFk, ticketFk: row.ticketFk,
@ -262,18 +263,22 @@ const itemLackForm = ref();
// ); // );
// }; // };
const split = async ({ simple }, data = []) => { // const split = async ({ simple }, data = []) => {
openConfirmationModal(t('Confirm split selected'), t('splitQuestion'), null, () => { // openConfirmationModal(
const body = simple ? data : selectedRows.value; // t('negative.modalSplit.title'),
axios.post(`Tickets/split`, body).then((data) => { // t('splitQuestion'),
resultSplit.value = data; // () => {
}); // const body = simple ? data : selectedRows.value;
}); // axios.post(`Tickets/split`, body).then((data) => {
}; // resultSplit.value = data;
// });
// }
// );
// };
const reload = async () => { const reload = async () => {
itemLackForm.value.fetch(); itemLackForm.value.fetch();
}; };
defineExpose({ split, reload }); defineExpose({ reload });
function getIcon(key, prop) { function getIcon(key, prop) {
const ticket = resultSplit.value.find((val) => val.ticketFk === key); const ticket = resultSplit.value.find((val) => val.ticketFk === key);
@ -355,7 +360,7 @@ const handleRows = (rows) => {
</QBtn> </QBtn>
<QBtn <QBtn
color="primary" color="primary"
@click="split" @click="showSplitDialog = true"
:disable="selectedRows.length < 1" :disable="selectedRows.length < 1"
icon="call_split" icon="call_split"
> >
@ -496,9 +501,8 @@ const handleRows = (rows) => {
ref="splitDialogRef" ref="splitDialogRef"
@hide="onDialogHide" @hide="onDialogHide"
v-model="showSplitDialog" v-model="showSplitDialog"
:tickets="resultSplit" :tickets="selectedRows"
></HandleSplited> ></HandleSplited>
{{ item }}
<ItemProposal <ItemProposal
ref="proposalDialogRef" ref="proposalDialogRef"
@hide="onDialogHide" @hide="onDialogHide"

View File

@ -1,65 +0,0 @@
<script setup>
import { toRefs, ref } from 'vue';
import TicketLackDetail from './TicketLackDetail.vue';
import { useSession } from 'src/composables/useSession';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const $props = defineProps({
ticket: {
type: Object,
required: false,
default: () => {},
},
id: {
type: Number,
default: 0,
},
});
const { ticket } = toRefs($props);
const session = useSession();
const token = session.getTokenMultimedia();
const ticketRef = ref(null);
const hasRowsSelected = ref(false);
async function splitSelected() {
ticketRef.value.split({ all: true });
}
</script>
<template>
<QCard class="q-pa-sm">
<QCardSection class="row items-center q-pb-none">
<QImg
:src="`/api/Images/catalog/50x50/${ticket.itemFk}/download?access_token=${token}`"
spinner-color="primary"
:ratio="1"
height="50px"
width="50px"
class="image remove-bg"
/>
<span class="text-h6 text-grey">{{ ticket.longName }}</span>
<QSpace />
<QBtn
round
color="primary"
@click="splitSelected()"
:disabled="!hasRowsSelected"
>
<QIcon name="call_split"></QIcon>
<QTooltip>
{{ t('global.split') }}
</QTooltip>
</QBtn>
<QBtn icon="close" flat round dense v-close-popup />
</QCardSection>
<QCardSection class="row items-center">
<TicketLackDetail
ref="ticketRef"
:id="ticket.itemFk"
@selection="(rows) => (hasRowsSelected = rows.length > 0)"
/> </QCardSection
></QCard>
</template>
<i18n> </i18n>

View File

@ -25,6 +25,9 @@ negative:
modalOrigin: modalOrigin:
title: 'Update negatives' title: 'Update negatives'
question: 'Select a state to update' question: 'Select a state to update'
modalSplit:
title: Confirm split selected
question: 'Select a state to update'
detail: detail:
itemFk: 'Article' itemFk: 'Article'
ticketFk: 'Id_Ticket' ticketFk: 'Id_Ticket'
@ -50,5 +53,5 @@ negative:
title: Update tickets quantity title: Update tickets quantity
placeholder: New quantity placeholder: New quantity
split: split:
splitQuestion: Are you sure you want to split all tickets? title: Are you sure you want to split all tickets?
confirmSplitSelected: Confirm split selected confirmSplitSelected: Confirm split selected