#6321 - Negative ticket #158

Open
jsegarra wants to merge 156 commits from 6321_negative_tickets into dev
3 changed files with 137 additions and 135 deletions
Showing only changes of commit f0333dfd01 - Show all commits

View File

@ -18,7 +18,7 @@ onMounted(() => {
const observer = new MutationObserver( const observer = new MutationObserver(
() => () =>
(hasContent.value = (hasContent.value =
actions.value.childNodes.length + data.value.childNodes.length) actions.value?.childNodes.length + data.value?.childNodes.length)
); );
if (actions.value) observer.observe(actions.value, opts); if (actions.value) observer.observe(actions.value, opts);
if (data.value) observer.observe(data.value, opts); if (data.value) observer.observe(data.value, opts);

View File

@ -1,8 +1,13 @@
<script setup> <script setup>
import { computed, onMounted, onUnmounted, ref, toRefs } from 'vue'; import { computed, nextTick, onMounted, onUnmounted, ref, toRefs } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { QBtn, QCheckbox } from 'quasar'; import { QBtn, QCheckbox } from 'quasar';
import axios from 'axios'; import axios from 'axios';
import HandleSplited from 'pages/Ticket/Negative/HandleSplited.vue';
import ChangeQuantityDialog from 'pages/Ticket/Negative/ChangeQuantityDialog.vue';
import ChangeStateDialog from 'pages/Ticket/Negative/ChangeStateDialog.vue';
import ItemProposal from 'src/pages/Item/components/ItemProposal.vue';
import { useVnConfirm } from 'composables/useVnConfirm';
import VnPaginate from 'src/components/ui/VnPaginate.vue'; import VnPaginate from 'src/components/ui/VnPaginate.vue';
import FetchData from 'src/components/FetchData.vue'; import FetchData from 'src/components/FetchData.vue';
@ -10,20 +15,29 @@ import VnSelect from 'components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import { toDate, toHour } from 'src/filters'; import { toDate, toHour } from 'src/filters';
import { useVnConfirm } from 'composables/useVnConfirm';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useDialogPluginComponent } from 'quasar';
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
import { useDialogPluginComponent } from 'quasar';
const { t } = useI18n(); const { t } = useI18n();
const URL_KEY = 'Tickets/ItemLack'; const URL_KEY = 'Tickets/ItemLack';
const editableStates = ref([]); const editableStates = ref([]);
const { notify } = useNotify(); const { notify } = useNotify();
const stateStore = useStateStore(); const stateStore = useStateStore();
const proposalDialogRef = ref();
const splitDialogRef = ref();
const changeStateDialogRef = ref();
const changeQuantityDialogRef = ref();
const showSplitDialog = ref(false);
const showProposalDialog = ref(false);
const showChangeQuantityDialog = ref(false);
const showChangeStateDialog = ref(false);
const componentIsRendered = ref(false);
const showFree = ref(true);
const resultSplit = ref([]);
const selectedRows = ref([]); const selectedRows = ref([]);
const originalRowDataCopy = ref(null); const originalRowDataCopy = ref(null);
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -38,7 +52,12 @@ const $props = defineProps({
}, },
}, },
}); });
onMounted(() => (stateStore.rightDrawer = false)); onMounted(() => {
stateStore.rightDrawer = false;
nextTick(() => {
componentIsRendered.value = true;
});
});
onUnmounted(() => (stateStore.rightDrawer = true)); onUnmounted(() => (stateStore.rightDrawer = true));
const copyOriginalRowsData = (rows) => { const copyOriginalRowsData = (rows) => {
@ -82,6 +101,11 @@ const entityId = computed(() => $props.id);
function isComponentVn(col) { function isComponentVn(col) {
return tableColumnComponents?.value[col.name]?.component === 'span' ?? false; return tableColumnComponents?.value[col.name]?.component === 'span' ?? false;
} }
// const onDetailDialogHide = (evt) => {
// if (evt?.type === 'refresh') ticketDetailRef.value.reload();
// };
const tableColumnComponents = computed(() => ({ const tableColumnComponents = computed(() => ({
status: { status: {
component: 'span', component: 'span',
@ -212,7 +236,7 @@ const columns = computed(() => [
]); ]);
const { dialogRef, onDialogHide } = useDialogPluginComponent(); const { dialogRef, onDialogHide } = useDialogPluginComponent();
const { filter } = toRefs($props); const { filter } = toRefs($props);
const emit = defineEmits([...useDialogPluginComponent.emits, 'selection']); const emit = defineEmits([...useDialogPluginComponent.emits, 'selection', 'close']);
function rowsHasSelected(selection) { function rowsHasSelected(selection) {
emit( emit(
'selection', 'selection',
@ -221,8 +245,23 @@ function rowsHasSelected(selection) {
); );
} }
const resultSplit = ref([]);
const itemLackForm = ref(); const itemLackForm = ref();
// const split = async ({ simple }, data = []) => {
// openConfirmationModal(
// t('negative.detail.split.confirmSplitSelected'),
// t('negative.detail.split.splitQuestion'),
// null,
// () => {
// showSplitDialog.value = true;
// resultSplit.value = [{}];
// // const body = simple ? data : selectedRows.value;
// // axios.post(`Tickets/split`, body).then((data) => {
// // resultSplit.value = data;
// // });
// }
// );
// };
const split = async ({ simple }, data = []) => { const split = async ({ simple }, data = []) => {
openConfirmationModal(t('Confirm split selected'), t('splitQuestion'), null, () => { openConfirmationModal(t('Confirm split selected'), t('splitQuestion'), null, () => {
const body = simple ? data : selectedRows.value; const body = simple ? data : selectedRows.value;
@ -268,7 +307,7 @@ function freeFirst({ alertLevel: a }, { alertLevel: b }) {
return 0; return 0;
} }
const handleRows = (rows) => { const handleRows = (rows) => {
if (filter.value.showFree) return rows.filter(({ alertLevel }) => alertLevel === 0); if (showFree.value) return rows.filter(({ alertLevel }) => alertLevel === 0);
return rows.sort(freeFirst); return rows.sort(freeFirst);
}; };
</script> </script>
@ -279,6 +318,65 @@ const handleRows = (rows) => {
@on-fetch="(data) => (editableStates = data)" @on-fetch="(data) => (editableStates = data)"
auto-load auto-load
/> />
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<QBtnGroup push style="column-gap: 1px"
><QBtn
:label="t('globals.cancel')"
@click="emit('close')"
color="primary"
flat
icon="close"
>
<QTooltip>{{ t('globals.cancel') }}</QTooltip>
</QBtn></QBtnGroup
>
</Teleport>
<Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown()">
<QBtnGroup push style="column-gap: 1px">
<QBtn
color="primary"
:label="t('Change state')"
:disable="selectedRows.length < 2"
@click="showChangeStateDialog = true"
>
<QTooltip bottom anchor="bottom right">
{{ t('Change state') }}
</QTooltip>
</QBtn>
<QBtn
color="primary"
:label="t('Change quantity')"
@click="showChangeQuantityDialog = true"
:disable="selectedRows.length < 2"
>
<QTooltip bottom anchor="bottom right">
{{ t('Change quantity') }}
</QTooltip>
</QBtn>
<QBtn
color="primary"
@click="split"
:disable="selectedRows.length < 1"
icon="call_split"
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.split') }}
</QTooltip>
</QBtn>
<QBtn
icon="vn:splitline"
color="primary"
:disable="selectedRows.length < 1"
@click="showProposalDialog = true"
>
<QTooltip bottom anchor="bottom right">
{{ t('Item proposal') }}
</QTooltip>
</QBtn>
</QBtnGroup>
<QCheckbox v-model="showFree" :label="t('negative.detail.showFree')" />
</Teleport>
<VnPaginate <VnPaginate
:data-key="URL_KEY" :data-key="URL_KEY"
:url="`${URL_KEY}/${entityId}/detail`" :url="`${URL_KEY}/${entityId}/detail`"
@ -380,4 +478,30 @@ const handleRows = (rows) => {
</QTable> </QTable>
</template> </template>
</VnPaginate> </VnPaginate>
<ChangeStateDialog
ref="changeStateDialogRef"
@hide="onDetailDialogHide"
v-model="showChangeStateDialog"
:selected-rows="selectedRows"
></ChangeStateDialog>
<ChangeQuantityDialog
ref="changeQuantityDialogRef"
@hide="onDetailDialogHide"
v-model="showChangeQuantityDialog"
:selected-rows="selectedRows"
>
</ChangeQuantityDialog>
<HandleSplited
ref="splitDialogRef"
@hide="onDialogHide"
v-model="showSplitDialog"
:tickets="resultSplit"
></HandleSplited>
<ItemProposal
ref="proposalDialogRef"
@hide="onDialogHide"
v-model="showProposalDialog"
:item="currentRow"
></ItemProposal>
</template> </template>

View File

@ -5,47 +5,31 @@ import { useStateStore } from 'stores/useStateStore';
import VnPaginate from 'components/ui/VnPaginate.vue'; import VnPaginate from 'components/ui/VnPaginate.vue';
import TicketLackFilter from 'pages/Ticket/Negative/TicketLackFilter.vue'; import TicketLackFilter from 'pages/Ticket/Negative/TicketLackFilter.vue';
import TicketLackDetail from 'pages/Ticket/Negative/TicketLackDetail.vue'; import TicketLackDetail from 'pages/Ticket/Negative/TicketLackDetail.vue';
import HandleSplited from 'pages/Ticket/Negative/HandleSplited.vue';
import ChangeQuantityDialog from 'pages/Ticket/Negative/ChangeQuantityDialog.vue';
import ChangeStateDialog from 'pages/Ticket/Negative/ChangeStateDialog.vue';
import ItemProposal from 'src/pages/Item/components/ItemProposal.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import { useVnConfirm } from 'composables/useVnConfirm';
import NegativeOriginDialog from 'pages/Ticket/Negative/NegativeOriginDialog.vue'; import NegativeOriginDialog from 'pages/Ticket/Negative/NegativeOriginDialog.vue';
import TotalNegativeOriginDialog from 'pages/Ticket/Negative/TotalNegativeOriginDialog.vue'; import TotalNegativeOriginDialog from 'pages/Ticket/Negative/TotalNegativeOriginDialog.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import axios from 'axios';
import { onBeforeMount } from 'vue'; import { onBeforeMount } from 'vue';
const DEFAULT_WAREHOUSE = 'Algemesi'; const DEFAULT_WAREHOUSE = 'Algemesi';
const stateStore = useStateStore(); const stateStore = useStateStore();
const { t } = useI18n(); const { t } = useI18n();
const selectedRows = ref([]); const selectedRows = ref([]);
const selectedRowsDetail = ref([]);
const resultSplit = ref([]);
const showNegativeOriginDialog = ref(false); const showNegativeOriginDialog = ref(false);
const showTotalNegativeOriginDialog = ref(false); const showTotalNegativeOriginDialog = ref(false);
const showProposalDialog = ref(false);
const showSplitDialog = ref(false);
const showChangeQuantityDialog = ref(false);
const showChangeStateDialog = ref(false);
const showFree = ref(true);
const showFilterPanel = ref(false); const showFilterPanel = ref(false);
const currentRow = ref(null); const currentRow = ref(null);
const negativeParams = reactive({ const negativeParams = reactive({
days: 2, days: 2,
}); });
const viewSummary = (row) => { const viewSummary = (row) => {
stateStore.rightDrawer = false;
currentRow.value = row; currentRow.value = row;
}; };
const originDialogRef = ref(); const originDialogRef = ref();
const totalNegativeDialogRef = ref(); const totalNegativeDialogRef = ref();
const proposalDialogRef = ref();
const splitDialogRef = ref();
const changeStateDialogRef = ref();
const changeQuantityDialogRef = ref();
const columns = computed(() => [ const columns = computed(() => [
{ {
name: 'minTimed', name: 'minTimed',
@ -118,26 +102,6 @@ const handleWarehouses = async (data) => {
await vnPaginateRef.value.fetch(); await vnPaginateRef.value.fetch();
showFilterPanel.value = true; showFilterPanel.value = true;
}; };
const onDetailDialogHide = (evt) => {
if (evt?.type === 'refresh') ticketDetailRef.value.reload();
};
const { openConfirmationModal } = useVnConfirm();
const split = async ({ simple }, data = []) => {
openConfirmationModal(
t('negative.detail.split.confirmSplitSelected'),
t('negative.detail.split.splitQuestion'),
null,
() => {
showSplitDialog.value = true;
resultSplit.value = [{}];
// const body = simple ? data : selectedRows.value;
// axios.post(`Tickets/split`, body).then((data) => {
// resultSplit.value = data;
// });
}
);
};
</script> </script>
<template> <template>
@ -163,17 +127,6 @@ const split = async ({ simple }, data = []) => {
<FetchData url="Warehouses" @on-fetch="handleWarehouses" auto-load /> <FetchData url="Warehouses" @on-fetch="handleWarehouses" auto-load />
<VnSubToolbar class="bg-vn-dark justify-end"> <VnSubToolbar class="bg-vn-dark justify-end">
<template #st-actions> <template #st-actions>
<QBtnGroup v-if="currentRow" push style="column-gap: 1px"
><QBtn
:label="t('globals.cancel')"
@click="currentRow = null"
color="primary"
flat
icon="close"
>
<QTooltip>{{ t('negative.totalNegative') }}</QTooltip>
</QBtn></QBtnGroup
>
<QBtnGroup push style="column-gap: 1px" v-if="!currentRow"> <QBtnGroup push style="column-gap: 1px" v-if="!currentRow">
<QBtn <QBtn
color="primary" color="primary"
@ -192,56 +145,6 @@ const split = async ({ simple }, data = []) => {
</QBtn> </QBtn>
</QBtnGroup> </QBtnGroup>
</template> </template>
<template #st-data>
<template v-if="currentRow">
<QBtnGroup push style="column-gap: 1px">
<QBtn
color="primary"
:label="t('Change state')"
:disable="selectedRowsDetail.length < 2"
@click="showChangeStateDialog = true"
>
<QTooltip bottom anchor="bottom right">
{{ t('Change state') }}
</QTooltip>
</QBtn>
<QBtn
color="primary"
:label="t('Change quantity')"
@click="showChangeQuantityDialog = true"
:disable="selectedRowsDetail.length < 2"
>
<QTooltip bottom anchor="bottom right">
{{ t('Change quantity') }}
</QTooltip>
</QBtn>
<QBtn
color="primary"
@click="split"
:disable="selectedRowsDetail.length < 1"
icon="call_split"
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.split') }}
</QTooltip>
</QBtn>
<QBtn
icon="vn:splitline"
color="primary"
@click="showProposalDialog = true"
:disable="selectedRowsDetail.length < 1"
>
<QTooltip bottom anchor="bottom right">
{{ t('Item proposal') }}
</QTooltip>
</QBtn>
</QBtnGroup>
<QCheckbox
v-model="showFree"
:label="t('negative.detail.showFree')"
/>
</template>
</template>
</VnSubToolbar> </VnSubToolbar>
<div v-show="!currentRow" class="list"> <div v-show="!currentRow" class="list">
<VnPaginate <VnPaginate
@ -322,35 +225,10 @@ const split = async ({ simple }, data = []) => {
<TicketLackDetail <TicketLackDetail
ref="ticketDetailRef" ref="ticketDetailRef"
:id="currentRow?.itemFk" :id="currentRow?.itemFk"
:filter="{ showFree }" @close="(evt) => (currentRow = null)"
@selection="(values) => (selectedRowsDetail = values)"
></TicketLackDetail> ></TicketLackDetail>
</div> </div>
<ChangeStateDialog
ref="changeStateDialogRef"
@hide="onDetailDialogHide"
v-model="showChangeStateDialog"
:selected-rows="selectedRowsDetail"
></ChangeStateDialog>
<ChangeQuantityDialog
ref="changeQuantityDialogRef"
@hide="onDetailDialogHide"
v-model="showChangeQuantityDialog"
:selected-rows="selectedRowsDetail"
>
</ChangeQuantityDialog>
<HandleSplited
ref="splitDialogRef"
@hide="onDialogHide"
v-model="showSplitDialog"
:tickets="resultSplit"
></HandleSplited>
<ItemProposal
ref="proposalDialogRef"
@hide="onDialogHide"
v-model="showProposalDialog"
:item="currentRow"
></ItemProposal>
<TotalNegativeOriginDialog <TotalNegativeOriginDialog
ref="totalNegativeDialogRef" ref="totalNegativeDialogRef"
v-model="showTotalNegativeOriginDialog" v-model="showTotalNegativeOriginDialog"