Merge branch 'develop'

This commit is contained in:
Methapon2001 2025-01-23 10:24:36 +07:00
commit 35fbedd74f
8 changed files with 131 additions and 56 deletions

View file

@ -57,11 +57,18 @@ const currentBtnOpen = ref<{ title: string; opened: boolean[] }[]>([
]); ]);
function calcPrice(c: (typeof rows.value)[number]) { function calcPrice(c: (typeof rows.value)[number]) {
const price = c.pricePerUnit * c.amount; const originalPrice = c.pricePerUnit;
const finalPriceWithVat = precisionRound(
originalPrice +
(c.product.vatIncluded || c.vat !== 0
? 0
: originalPrice * (config.value?.vat || 0.07)),
);
const finalPriceNoVat = finalPriceWithVat / (1 + (config.value?.vat || 0.07));
const price = finalPriceNoVat * c.amount;
const vat = c.product.calcVat const vat = c.product.calcVat
? (c.pricePerUnit * (c.discount ? c.amount : 1) - c.discount) * ? (finalPriceNoVat * c.amount - c.discount) * (config.value?.vat || 0.07)
(config.value?.vat || 0.07) *
(!c.discount ? c.amount : 1)
: 0; : 0;
return precisionRound(price + vat); return precisionRound(price + vat);
} }

View file

@ -69,7 +69,7 @@ defineEmits<{
<q-td v-if="visibleColumns.includes('workName')"> <q-td v-if="visibleColumns.includes('workName')">
<div class="column"> <div class="column">
<div class="col-6">{{ props.row.workName }}</div> <div class="col-6">{{ props.row.workName || '-' }}</div>
<div class="col-6 app-text-muted">{{ props.row.code }}</div> <div class="col-6 app-text-muted">{{ props.row.code }}</div>
</div> </div>
</q-td> </q-td>
@ -83,7 +83,7 @@ defineEmits<{
</q-td> </q-td>
<q-td v-if="visibleColumns.includes('contactName')"> <q-td v-if="visibleColumns.includes('contactName')">
{{ props.row.contactName }} {{ props.row.contactName || '-' }}
</q-td> </q-td>
<q-td v-if="visibleColumns.includes('actor')"> <q-td v-if="visibleColumns.includes('actor')">

View file

@ -80,7 +80,7 @@ const pageState = reactive({
hideStat: false, hideStat: false,
inputSearch: '', inputSearch: '',
fieldSelected: [''], fieldSelected: [''],
gridView: true, gridView: false,
total: 0, total: 0,
currentTab: 'Issued', currentTab: 'Issued',

View file

@ -242,18 +242,26 @@ function getPrice(
return a; return a;
} }
const price = c.pricePerUnit * c.amount; const originalPrice = c.pricePerUnit;
const finalPriceWithVat = precisionRound(
originalPrice +
(c.product.vatIncluded
? 0
: originalPrice * (config.value?.vat || 0.07)),
);
const finalPriceNoVat =
finalPriceWithVat / (1 + (config.value?.vat || 0.07));
const price = finalPriceNoVat * c.amount;
const vat = const vat =
(c.pricePerUnit * (c.discount ? c.amount : 1) - c.discount) * (finalPriceNoVat * c.amount - c.discount) * (config.value?.vat || 0.07);
(config.value?.vat || 0.07) *
(!c.discount ? c.amount : 1);
a.totalPrice = precisionRound(a.totalPrice + price); a.totalPrice = precisionRound(a.totalPrice + price);
a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount)); a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount));
a.vat = c.product.calcVat ? precisionRound(a.vat + vat) : a.vat; a.vat = c.product.calcVat ? precisionRound(a.vat + vat) : a.vat;
a.vatExcluded = c.product.calcVat a.vatExcluded = c.product.calcVat
? a.vatExcluded ? a.vatExcluded
: precisionRound(a.vat + vat); : precisionRound(a.vatExcluded + vat);
a.finalPrice = precisionRound( a.finalPrice = precisionRound(
a.totalPrice - a.totalPrice -
a.totalDiscount + a.totalDiscount +
@ -704,12 +712,12 @@ function handleUpdateProductTable(
const pricePerUnit = c.pricePerUnit || 0; const pricePerUnit = c.pricePerUnit || 0;
const discount = c.discount || 0; const discount = c.discount || 0;
return precisionRound( return (
pricePerUnit * c.amount - pricePerUnit * c.amount -
discount + discount +
(c.product.calcVat (c.product.calcVat
? (pricePerUnit * c.amount - discount) * (config.value?.vat || 0.07) ? (pricePerUnit * c.amount - discount) * (config.value?.vat || 0.07)
: 0), : 0)
); );
}; };
@ -767,17 +775,15 @@ function toggleDeleteProduct(index: number) {
? currProduct.product.agentPrice ? currProduct.product.agentPrice
: currProduct.product.price; : currProduct.product.price;
const pricePerUnit = currProduct.product.vatIncluded const pricePerUnit = currProduct.product.vatIncluded
? precisionRound(price / (1 + (config.value?.vat || 0.07))) ? price / (1 + (config.value?.vat || 0.07))
: price; : price;
const vat = precisionRound( const vat =
(pricePerUnit * currProduct.amount - currProduct.discount) * (pricePerUnit * currProduct.amount - currProduct.discount) *
(config.value?.vat || 0.07), (config.value?.vat || 0.07);
); const finalPrice =
const finalPrice = precisionRound(
pricePerUnit * currProduct.amount + pricePerUnit * currProduct.amount +
vat - vat -
Number(currProduct.discount || 0), Number(currProduct.discount || 0);
);
currTempPaySplit.amount = currPaySplit.amount - finalPrice; currTempPaySplit.amount = currPaySplit.amount - finalPrice;
currPaySplit.amount = currTempPaySplit.amount; currPaySplit.amount = currTempPaySplit.amount;

View file

@ -228,23 +228,33 @@ onMounted(async () => {
productList.value = productList.value =
(data?.value?.productServiceList ?? data.value?.productServiceList).map( (data?.value?.productServiceList ?? data.value?.productServiceList).map(
(v) => ({ (v) => {
id: v.product.id, const originalPrice = v.pricePerUnit;
code: v.product.code, const finalPriceWithVat = precisionRound(
detail: v.product.name, originalPrice +
amount: v.amount || 0, (v.product.vatIncluded || v.vat !== 0
priceUnit: v.pricePerUnit || 0, ? 0
discount: v.discount || 0, : originalPrice * (config.value?.vat || 0.07)),
vat: v.vat || 0, );
value: precisionRound( const finalPriceNoVat =
(v.pricePerUnit || 0) * v.amount - finalPriceWithVat / (1 + (config.value?.vat || 0.07));
(v.discount || 0) +
(v.product.calcVat const price = finalPriceNoVat * v.amount;
? ((v.pricePerUnit || 0) * v.amount - (v.discount || 0)) * const vat =
(config.value?.vat || 0.07) (finalPriceNoVat * v.amount - v.discount) *
: 0), (config.value?.vat || 0.07);
),
}), return {
id: v.product.id,
code: v.product.code,
detail: v.product.name,
amount: v.amount || 0,
priceUnit: v.pricePerUnit || 0,
discount: v.discount || 0,
vat: v.vat || 0,
value: precisionRound(price + (v.product.calcVat ? vat : 0)),
};
},
) || []; ) || [];
} }
@ -253,18 +263,26 @@ onMounted(async () => {
[] []
).reduce( ).reduce(
(a, c) => { (a, c) => {
const price = precisionRound((c.pricePerUnit || 0) * c.amount); const originalPrice = c.pricePerUnit;
const vat = precisionRound( const finalPriceWithVat = precisionRound(
((c.pricePerUnit || 0) * c.amount - (c.discount || 0)) * originalPrice +
(config.value?.vat || 0.07), (c.product.vatIncluded || c.vat !== 0
? 0
: originalPrice * (config.value?.vat || 0.07)),
); );
const finalPriceNoVat =
finalPriceWithVat / (1 + (config.value?.vat || 0.07));
const price = finalPriceNoVat * c.amount;
const vat =
(finalPriceNoVat * c.amount - c.discount) * (config.value?.vat || 0.07);
a.totalPrice = precisionRound(a.totalPrice + price); a.totalPrice = precisionRound(a.totalPrice + price);
a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount)); a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount));
a.vat = c.product.calcVat ? precisionRound(a.vat + vat) : a.vat; a.vat = c.product.calcVat ? precisionRound(a.vat + vat) : a.vat;
a.vatExcluded = c.product.calcVat a.vatExcluded = c.product.calcVat
? a.vatExcluded ? a.vatExcluded
: precisionRound(a.vat + vat); : precisionRound(a.vatExcluded + vat);
a.finalPrice = precisionRound( a.finalPrice = precisionRound(
a.totalPrice - a.totalPrice -
a.totalDiscount + a.totalDiscount +

View file

@ -116,6 +116,10 @@ function openReceiveDialog(scan?: boolean) {
pageState.receiveDialog = true; pageState.receiveDialog = true;
} }
async function deleteTaskOrder() {
console.log('delete');
}
onMounted(async () => { onMounted(async () => {
navigatorStore.current.title = 'taskOrder.title'; navigatorStore.current.title = 'taskOrder.title';
navigatorStore.current.path = [{ text: 'taskOrder.caption', i18n: true }]; navigatorStore.current.path = [{ text: 'taskOrder.caption', i18n: true }];
@ -441,6 +445,8 @@ watch(
: triggerTaskOrder({ statusDialog: 'info', id: v.id }); : triggerTaskOrder({ statusDialog: 'info', id: v.id });
} }
" "
@edit="console.log('edit')"
@delete="deleteTaskOrder"
/> />
</article> </article>

View file

@ -105,6 +105,8 @@ function openList(index: number, data: TaskOrder) {
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'view', data: TaskOrder): void; (e: 'view', data: TaskOrder): void;
(e: 'edit', data: TaskOrder): void;
(e: 'delete', data: TaskOrder): void;
(e: 'clickSubRow', index: number, data: TaskOrder): void; (e: 'clickSubRow', index: number, data: TaskOrder): void;
}>(); }>();
</script> </script>
@ -205,14 +207,16 @@ const emit = defineEmits<{
flat flat
@click.stop="$emit('view', props.row)" @click.stop="$emit('view', props.row)"
/> />
<KebabAction <KebabAction
v-if="false" v-if="
!receive && props.row.taskOrderStatus === TaskOrderStatus.Pending
"
:idName="`btn-kebab-${props.row.taskName}`" :idName="`btn-kebab-${props.row.taskName}`"
status="'ACTIVE'" status="'ACTIVE'"
hide-toggle hide-toggle
:hide-edit="true"
@view="$emit('view', props.row)" @view="$emit('view', props.row)"
@edit="$emit('edit', props.row)"
@delete="$emit('delete', props.row)"
/> />
</q-td> </q-td>
<q-td v-else> <q-td v-else>
@ -254,8 +258,10 @@ const emit = defineEmits<{
<QuotationCard <QuotationCard
:status="$t(taskOrderStatus(props.row.taskOrderStatus, 'status'))" :status="$t(taskOrderStatus(props.row.taskOrderStatus, 'status'))"
:badge-color="taskOrderStatus(props.row.taskOrderStatus, 'color')" :badge-color="taskOrderStatus(props.row.taskOrderStatus, 'color')"
hide-action hide-preview
hidePreview :hide-action="
receive || props.row.taskOrderStatus !== TaskOrderStatus.Pending
"
:code="props.row.code" :code="props.row.code"
:title="props.row.taskName" :title="props.row.taskName"
:custom-data="[ :custom-data="[
@ -296,6 +302,8 @@ const emit = defineEmits<{
}, },
]" ]"
@view="$emit('view', props.row)" @view="$emit('view', props.row)"
@edit="$emit('edit', props.row)"
@delete="$emit('delete', props.row)"
/> />
</div> </div>
</template> </template>

View file

@ -15,7 +15,12 @@ import AdditionalFileExpansion from '../expansion/AdditionalFileExpansion.vue';
import RemarkExpansion from '../expansion/RemarkExpansion.vue'; import RemarkExpansion from '../expansion/RemarkExpansion.vue';
import InfoMessengerExpansion from '../expansion/receive/InfoMessengerExpansion.vue'; import InfoMessengerExpansion from '../expansion/receive/InfoMessengerExpansion.vue';
import TableEmployee from '../TableEmployee.vue'; import TableEmployee from '../TableEmployee.vue';
import { SaveButton, MainButton, EditButton } from 'src/components/button'; import {
SaveButton,
MainButton,
EditButton,
UndoButton,
} from 'src/components/button';
import FormGroupHead from 'src/pages/08_request-list/FormGroupHead.vue'; import FormGroupHead from 'src/pages/08_request-list/FormGroupHead.vue';
import FailRemarkDialog from '../receive_view/FailRemarkDialog.vue'; import FailRemarkDialog from '../receive_view/FailRemarkDialog.vue';
@ -412,6 +417,26 @@ function openProductDialog() {
pageState.productDialog = true; pageState.productDialog = true;
} }
async function closeTab() {
if (state.value.mode === 'edit' && !!currentFormData.value.id) {
taskOrderFormStore.resetForm();
await taskOrderFormStore.assignFormData(currentFormData.value.id, 'edit');
} else {
dialogWarningClose(t, {
message: t('dialog.message.close'),
action: () => {
window.close();
},
cancel: () => {},
});
}
}
function undo() {
if (!currentFormData.value) return;
taskOrderFormStore.assignFormData(currentFormData.value?.id || '', 'info');
}
onMounted(async () => { onMounted(async () => {
initTheme(); initTheme();
initLang(); initLang();
@ -1124,13 +1149,18 @@ watch([currentFormData.value.taskStatus], () => {
{{ $t('general.view', { msg: $t('general.example') }) }} {{ $t('general.view', { msg: $t('general.example') }) }}
</MainButton> </MainButton>
<div class="row" style="gap: var(--size-2)"> <div class="row" style="gap: var(--size-2)">
<template v-if="state.mode === 'create'"> <template
<!-- <UndoButton outlined @click="undo()" v-if="state.mode === 'edit'" /> v-if="
fullTaskOrder?.taskOrderStatus === TaskOrderStatus.Pending ||
state.mode === 'create'
"
>
<UndoButton outlined @click="undo()" v-if="state.mode === 'edit'" />
<CancelButton <CancelButton
@click="closeTab()" @click="closeTab()"
v-if="state.mode === 'info'" v-if="state.mode === 'info'"
outlined outlined
/> --> />
<SaveButton <SaveButton
v-if="state.mode && ['create', 'edit'].includes(state.mode)" v-if="state.mode && ['create', 'edit'].includes(state.mode)"
@click="() => formDocument.submit()" @click="() => formDocument.submit()"