refactor: handle mode view
This commit is contained in:
parent
be69f66742
commit
83a7e7ee47
3 changed files with 104 additions and 57 deletions
|
|
@ -7,6 +7,7 @@ import { dateFormatJS, calculateAge } from 'src/utils/datetime';
|
||||||
import { initLang, initTheme, Lang } from 'src/utils/ui';
|
import { initLang, initTheme, Lang } from 'src/utils/ui';
|
||||||
import { useQuotationStore } from 'src/stores/quotations';
|
import { useQuotationStore } from 'src/stores/quotations';
|
||||||
import { useQuotationForm } from 'src/pages/05_quotation/form';
|
import { useQuotationForm } from 'src/pages/05_quotation/form';
|
||||||
|
import { useDebitNoteForm } from './form';
|
||||||
import { useReceipt, usePayment } from 'stores/payment';
|
import { useReceipt, usePayment } from 'stores/payment';
|
||||||
import useProductServiceStore from 'stores/product-service';
|
import useProductServiceStore from 'stores/product-service';
|
||||||
import {
|
import {
|
||||||
|
|
@ -63,6 +64,7 @@ import { precisionRound } from 'src/utils/arithmetic';
|
||||||
import QuotationFormProductSelect from '../05_quotation/QuotationFormProductSelect.vue';
|
import QuotationFormProductSelect from '../05_quotation/QuotationFormProductSelect.vue';
|
||||||
import { getName } from 'src/services/keycloak';
|
import { getName } from 'src/services/keycloak';
|
||||||
|
|
||||||
|
const debitNoteForm = useDebitNoteForm();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const debitNote = useDebitNote();
|
const debitNote = useDebitNote();
|
||||||
|
|
@ -76,6 +78,7 @@ const $q = useQuasar();
|
||||||
const paymentStore = usePayment();
|
const paymentStore = usePayment();
|
||||||
const { data: config } = storeToRefs(configStore);
|
const { data: config } = storeToRefs(configStore);
|
||||||
const { newWorkerList } = storeToRefs(quotationForm);
|
const { newWorkerList } = storeToRefs(quotationForm);
|
||||||
|
const { currentFormData } = storeToRefs(debitNoteForm);
|
||||||
const { t, locale } = useI18n();
|
const { t, locale } = useI18n();
|
||||||
const requestStore = useRequestList();
|
const requestStore = useRequestList();
|
||||||
|
|
||||||
|
|
@ -104,6 +107,7 @@ const quotationData = ref<DebitNote['debitNoteQuotation']>();
|
||||||
const view = ref<QuotationStatus>(QuotationStatus.Issued);
|
const view = ref<QuotationStatus>(QuotationStatus.Issued);
|
||||||
const fileList = ref<FileList>();
|
const fileList = ref<FileList>();
|
||||||
const receiptList = ref<Receipt[]>([]);
|
const receiptList = ref<Receipt[]>([]);
|
||||||
|
let previousValue: DebitNotePayload | undefined = undefined;
|
||||||
|
|
||||||
const rowsRequestList = ref<RequestData[]>([]);
|
const rowsRequestList = ref<RequestData[]>([]);
|
||||||
|
|
||||||
|
|
@ -111,20 +115,7 @@ const productServiceList = ref<
|
||||||
Required<QuotationPayload['productServiceList'][number]>[]
|
Required<QuotationPayload['productServiceList'][number]>[]
|
||||||
>([]);
|
>([]);
|
||||||
const productServiceNodes = ref<ProductTree>([]);
|
const productServiceNodes = ref<ProductTree>([]);
|
||||||
const currentFormData = ref<DebitNotePayload>({
|
|
||||||
productServiceList: [],
|
|
||||||
debitNoteQuotationId: '',
|
|
||||||
worker: [],
|
|
||||||
payBillDate: new Date(),
|
|
||||||
paySplitCount: 0,
|
|
||||||
payCondition: PayCondition.Full,
|
|
||||||
dueDate: new Date(Date.now() + 86400000),
|
|
||||||
discount: 0,
|
|
||||||
status: 'CREATED',
|
|
||||||
remark: '#[quotation-labor]<br/><br/>#[quotation-payment]',
|
|
||||||
quotationId: '',
|
|
||||||
agentPrice: false,
|
|
||||||
});
|
|
||||||
const tempPaySplitCount = ref(0);
|
const tempPaySplitCount = ref(0);
|
||||||
const tempPaySplit = ref<
|
const tempPaySplit = ref<
|
||||||
{ no: number; amount: number; name?: string; invoice?: boolean }[]
|
{ no: number; amount: number; name?: string; invoice?: boolean }[]
|
||||||
|
|
@ -335,6 +326,46 @@ async function assignToProductServiceList() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function undo() {
|
||||||
|
if (!previousValue) return;
|
||||||
|
|
||||||
|
currentFormData.value = structuredClone(previousValue);
|
||||||
|
assignProductServiceList();
|
||||||
|
assignSelectedWorker();
|
||||||
|
pageState.mode = 'info';
|
||||||
|
}
|
||||||
|
|
||||||
|
function assignProductServiceList() {
|
||||||
|
if (!debitNoteData.value) return;
|
||||||
|
productServiceList.value = debitNoteData.value.productServiceList.map(
|
||||||
|
(v, i) => ({
|
||||||
|
id: v.id!,
|
||||||
|
installmentNo: v.installmentNo || 0,
|
||||||
|
workerIndex: v.worker
|
||||||
|
.map((a) =>
|
||||||
|
debitNoteData.value!.worker.findIndex(
|
||||||
|
(b) => b.employeeId === a.employeeId,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.filter(
|
||||||
|
(index): index is number => index !== -1 && index !== undefined,
|
||||||
|
),
|
||||||
|
vat: v.vat || 0,
|
||||||
|
pricePerUnit: v.pricePerUnit || 0,
|
||||||
|
discount: v.discount || 0,
|
||||||
|
amount: v.amount || 0,
|
||||||
|
product: v.product,
|
||||||
|
work: v.work || null,
|
||||||
|
service: v.service || null,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function assignSelectedWorker() {
|
||||||
|
if (debitNoteData.value)
|
||||||
|
selectedWorker.value = debitNoteData.value.worker.map((v) => v.employee);
|
||||||
|
}
|
||||||
|
|
||||||
async function assignFormData(id: string) {
|
async function assignFormData(id: string) {
|
||||||
const data = await debitNote.getDebitNote(id);
|
const data = await debitNote.getDebitNote(id);
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
@ -344,7 +375,7 @@ async function assignFormData(id: string) {
|
||||||
selectedProductGroup.value =
|
selectedProductGroup.value =
|
||||||
data.productServiceList[0]?.product.productGroup?.id || '';
|
data.productServiceList[0]?.product.productGroup?.id || '';
|
||||||
|
|
||||||
currentFormData.value = {
|
(previousValue = {
|
||||||
id: data.id || undefined,
|
id: data.id || undefined,
|
||||||
debitNoteQuotationId: data.debitNoteQuotationId || undefined,
|
debitNoteQuotationId: data.debitNoteQuotationId || undefined,
|
||||||
productServiceList: structuredClone(
|
productServiceList: structuredClone(
|
||||||
|
|
@ -369,24 +400,11 @@ async function assignFormData(id: string) {
|
||||||
agentPrice: data.agentPrice,
|
agentPrice: data.agentPrice,
|
||||||
quotationId: data.debitNoteQuotationId,
|
quotationId: data.debitNoteQuotationId,
|
||||||
remark: data.remark || undefined,
|
remark: data.remark || undefined,
|
||||||
};
|
}),
|
||||||
|
(currentFormData.value = structuredClone(previousValue));
|
||||||
|
|
||||||
productServiceList.value = data.productServiceList.map((v, i) => ({
|
assignProductServiceList();
|
||||||
id: v.id!,
|
assignSelectedWorker();
|
||||||
installmentNo: v.installmentNo || 0,
|
|
||||||
workerIndex: v.worker.map((a) =>
|
|
||||||
data.worker.findIndex((b) => b.employeeId === a.employeeId),
|
|
||||||
) || [0],
|
|
||||||
vat: v.vat || 0,
|
|
||||||
pricePerUnit: v.pricePerUnit || 0,
|
|
||||||
discount: v.discount || 0,
|
|
||||||
amount: v.amount || 0,
|
|
||||||
product: v.product,
|
|
||||||
work: v.work || null,
|
|
||||||
service: v.service || null,
|
|
||||||
}));
|
|
||||||
|
|
||||||
selectedWorker.value = data.worker.map((v) => v.employee);
|
|
||||||
await getQuotation(data.debitNoteQuotation?.id);
|
await getQuotation(data.debitNoteQuotation?.id);
|
||||||
await assignToProductServiceList();
|
await assignToProductServiceList();
|
||||||
await fetchRequest();
|
await fetchRequest();
|
||||||
|
|
@ -431,7 +449,10 @@ async function initStatus() {
|
||||||
title: 'title',
|
title: 'title',
|
||||||
status: debitNoteData.value?.id !== undefined ? 'done' : 'doing',
|
status: debitNoteData.value?.id !== undefined ? 'done' : 'doing',
|
||||||
active: () => view.value === QuotationStatus.Issued,
|
active: () => view.value === QuotationStatus.Issued,
|
||||||
handler: () => (view.value = QuotationStatus.Issued),
|
handler: () => {
|
||||||
|
pageState.mode = 'info';
|
||||||
|
view.value = QuotationStatus.Issued;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'accepted',
|
title: 'accepted',
|
||||||
|
|
@ -440,7 +461,10 @@ async function initStatus() {
|
||||||
? getStatus(debitNoteData.value.quotationStatus, 1, -1)
|
? getStatus(debitNoteData.value.quotationStatus, 1, -1)
|
||||||
: 'waiting',
|
: 'waiting',
|
||||||
active: () => view.value === QuotationStatus.Accepted,
|
active: () => view.value === QuotationStatus.Accepted,
|
||||||
handler: () => (view.value = QuotationStatus.Accepted),
|
handler: () => {
|
||||||
|
pageState.mode = 'info';
|
||||||
|
view.value = QuotationStatus.Accepted;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'payment',
|
title: 'payment',
|
||||||
|
|
@ -459,6 +483,7 @@ async function initStatus() {
|
||||||
status: getStatus(debitNoteData.value?.quotationStatus, 2, 2),
|
status: getStatus(debitNoteData.value?.quotationStatus, 2, 2),
|
||||||
active: () => view.value === QuotationStatus.PaymentSuccess,
|
active: () => view.value === QuotationStatus.PaymentSuccess,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
|
pageState.mode = 'info';
|
||||||
view.value = QuotationStatus.PaymentSuccess;
|
view.value = QuotationStatus.PaymentSuccess;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -468,6 +493,7 @@ async function initStatus() {
|
||||||
status: getStatus(debitNoteData.value?.quotationStatus, 3, 2),
|
status: getStatus(debitNoteData.value?.quotationStatus, 3, 2),
|
||||||
active: () => view.value === QuotationStatus.ProcessComplete,
|
active: () => view.value === QuotationStatus.ProcessComplete,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
|
pageState.mode = 'info';
|
||||||
view.value = QuotationStatus.ProcessComplete;
|
view.value = QuotationStatus.ProcessComplete;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -906,6 +932,12 @@ onMounted(async () => {
|
||||||
}[route.query['tab']] || QuotationStatus.Issued;
|
}[route.query['tab']] || QuotationStatus.Issued;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
pageState.mode === 'edit' &&
|
||||||
|
debitNoteData.value?.quotationStatus !== QuotationStatus.Issued
|
||||||
|
) {
|
||||||
|
pageState.mode = 'info';
|
||||||
|
}
|
||||||
await useConfigStore().getConfig();
|
await useConfigStore().getConfig();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1236,10 +1268,13 @@ async function submitAccepted() {
|
||||||
</MainButton>
|
</MainButton>
|
||||||
|
|
||||||
<div class="row q-gutter-x-sm">
|
<div class="row q-gutter-x-sm">
|
||||||
<UndoButton outlined @click="pageState.mode = 'info'" v-if="false" />
|
<UndoButton
|
||||||
{{ pageState.mode }}
|
outlined
|
||||||
|
v-if="pageState.mode === 'edit'"
|
||||||
|
@click="undo()"
|
||||||
|
/>
|
||||||
<SaveButton
|
<SaveButton
|
||||||
v-if="!readonly"
|
v-if="pageState.mode !== 'info'"
|
||||||
:disabled="
|
:disabled="
|
||||||
selectedWorkerItem.length === 0 && productService.length === 0
|
selectedWorkerItem.length === 0 && productService.length === 0
|
||||||
"
|
"
|
||||||
|
|
@ -1247,24 +1282,36 @@ async function submitAccepted() {
|
||||||
solid
|
solid
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SaveButton
|
<template v-if="debitNoteData">
|
||||||
v-if="false"
|
<EditButton
|
||||||
@click="submit"
|
v-if="
|
||||||
:label="$t('debitNote.label.submit')"
|
pageState.mode === 'info' &&
|
||||||
icon="mdi-account-multiple-check-outline"
|
view === QuotationStatus.Issued &&
|
||||||
solid
|
debitNoteData.quotationStatus === QuotationStatus.Issued
|
||||||
/>
|
"
|
||||||
|
class="no-print"
|
||||||
|
solid
|
||||||
|
@click="pageState.mode = 'edit'"
|
||||||
|
/>
|
||||||
|
|
||||||
<EditButton
|
<MainButton
|
||||||
v-if="
|
v-if="
|
||||||
readonly &&
|
view === QuotationStatus.Accepted &&
|
||||||
pageState.mode === 'info' &&
|
debitNoteData.quotationStatus === QuotationStatus.Issued
|
||||||
QuotationStatus.Issued === view
|
"
|
||||||
"
|
solid
|
||||||
class="no-print"
|
icon="mdi-account-multiple-check-outline"
|
||||||
solid
|
color="207 96% 32%"
|
||||||
@click="pageState.mode = 'edit'"
|
id="btn-submit-accepted"
|
||||||
/>
|
@click="
|
||||||
|
() => {
|
||||||
|
submitAccepted();
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ $t('quotation.customerAcceptance') }}
|
||||||
|
</MainButton>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ const toggleWorker = defineModel<boolean>('toggleWorker');
|
||||||
</div>
|
</div>
|
||||||
<nav class="q-ml-auto">
|
<nav class="q-ml-auto">
|
||||||
<AddButton
|
<AddButton
|
||||||
v-if="!hideBtnAddWorker"
|
v-if="!readonly"
|
||||||
icon-only
|
icon-only
|
||||||
@click.stop="$emit('addWorker')"
|
@click.stop="$emit('addWorker')"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,9 @@ const DEFAULT_DATA: DebitNotePayload = {
|
||||||
debitNoteQuotationId: '',
|
debitNoteQuotationId: '',
|
||||||
worker: [],
|
worker: [],
|
||||||
payBillDate: new Date(),
|
payBillDate: new Date(),
|
||||||
paySplit: [],
|
|
||||||
paySplitCount: 0,
|
paySplitCount: 0,
|
||||||
payCondition: PayCondition.Full,
|
payCondition: PayCondition.Full,
|
||||||
dueDate: new Date(),
|
dueDate: new Date(Date.now() + 86400000),
|
||||||
discount: 0,
|
discount: 0,
|
||||||
status: 'CREATED',
|
status: 'CREATED',
|
||||||
remark: '#[quotation-labor]<br/><br/>#[quotation-payment]',
|
remark: '#[quotation-labor]<br/><br/>#[quotation-payment]',
|
||||||
|
|
@ -58,6 +57,7 @@ export const useDebitNoteForm = defineStore('form-debit-note', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
currentFormData,
|
||||||
isFormDataDifferent,
|
isFormDataDifferent,
|
||||||
resetForm,
|
resetForm,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue