refactor: show all product and add column status and edit format remark
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 7s

This commit is contained in:
Thanaphon Frappet 2025-04-17 15:02:22 +07:00
parent 145784ee40
commit 550ed55de0
7 changed files with 92 additions and 16 deletions

View file

@ -159,6 +159,7 @@ export default {
period: 'Period', period: 'Period',
documentStatus: 'Document Status', documentStatus: 'Document Status',
advanceSearch: 'Advance Search', advanceSearch: 'Advance Search',
totalPeople: '{meg} people',
}, },
menu: { menu: {

View file

@ -159,6 +159,7 @@ export default {
period: 'ช่วงเวลา', period: 'ช่วงเวลา',
documentStatus: 'สถานะเอกสาร', documentStatus: 'สถานะเอกสาร',
advanceSearch: 'ค้นหาขั้นสูง', advanceSearch: 'ค้นหาขั้นสูง',
totalPeople: '{meg} คน',
}, },
menu: { menu: {

View file

@ -227,6 +227,12 @@ export const productColumn = [
label: 'taskOrder.productList', label: 'taskOrder.productList',
field: 'productList', field: 'productList',
}, },
{
name: 'status',
align: 'center',
label: 'general.status',
field: 'status',
},
{ {
name: 'amountOfEmployee', name: 'amountOfEmployee',
align: 'center', align: 'center',

View file

@ -11,6 +11,8 @@ import { baseUrl, formatNumberDecimal, commaInput } from 'src/stores/utils';
import { precisionRound } from 'src/utils/arithmetic'; import { precisionRound } from 'src/utils/arithmetic';
import { useConfigStore } from 'stores/config'; import { useConfigStore } from 'stores/config';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import BadgeComponent from 'src/components/BadgeComponent.vue';
import { TaskStatus } from 'src/stores/task-order/types';
const currentBtnOpen = ref<boolean[]>([]); const currentBtnOpen = ref<boolean[]>([]);
const configStore = useConfigStore(); const configStore = useConfigStore();
@ -30,7 +32,10 @@ const props = defineProps<{
readonly?: boolean; readonly?: boolean;
agentPrice?: boolean; agentPrice?: boolean;
taskList: { taskList: {
product: RequestWork['productService']['product']; product: RequestWork['productService']['product'] & {
taskStatus?: TaskStatus;
totalNotStatusComplete?: number;
};
list: RequestWork[]; list: RequestWork[];
}[]; }[];
creditNote?: boolean; creditNote?: boolean;
@ -111,6 +116,26 @@ function calcPrice(
return precisionRound(priceNoVat * amount + rawVatTotal); return precisionRound(priceNoVat * amount + rawVatTotal);
} }
function taskOrderStatus(value: TaskStatus) {
if ([TaskStatus.Pending].includes(value)) {
return '--blue-6-hsl';
}
if ([TaskStatus.InProgress, TaskStatus.Validate].includes(value)) {
return '--orange-5-hsl';
}
if (
[
TaskStatus.Canceled,
TaskStatus.Restart,
TaskStatus.Redo,
TaskStatus.Failed,
].includes(value)
) {
return '--red-5-hsl';
}
return '--green-8-hsl';
}
</script> </script>
<template> <template>
<q-expansion-item <q-expansion-item
@ -144,7 +169,8 @@ function calcPrice(
(v) => (v) =>
v.name !== 'discount' && v.name !== 'discount' &&
v.name !== 'priceBeforeVat' && v.name !== 'priceBeforeVat' &&
v.name !== 'vat', v.name !== 'vat' &&
v.name !== 'status',
) )
: productColumn : productColumn
" "
@ -173,7 +199,10 @@ function calcPrice(
<template <template
v-slot:body="props: { v-slot:body="props: {
row: { row: {
product: RequestWork['productService']['product']; product: RequestWork['productService']['product'] & {
taskStatus?: TaskStatus;
totalNotStatusComplete?: number;
};
list: RequestWork[]; list: RequestWork[];
}; };
} & Omit<Parameters<QTableSlots['body']>[0], 'row'>" } & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
@ -203,6 +232,14 @@ function calcPrice(
</q-avatar> </q-avatar>
{{ props.row.product.name }} {{ props.row.product.name }}
</q-td> </q-td>
<q-td class="text-left" v-if="!creditNote">
<BadgeComponent
hide-icon
:hsla-color="taskOrderStatus(props.row.product.taskStatus)"
:title="`${$t(`taskOrder.status.${props.row.product.taskStatus}`)} ${!!props.row.product.totalNotStatusComplete ? $t('general.totalPeople', { meg: props.row.product.totalNotStatusComplete }) : ''}`"
/>
</q-td>
<q-td> <q-td>
{{ props.row.list.length }} {{ props.row.list.length }}
</q-td> </q-td>

View file

@ -280,7 +280,10 @@ let taskListGroup = computed(() => {
const cacheData = currentFormData.value.taskList.reduce< const cacheData = currentFormData.value.taskList.reduce<
{ {
product: RequestWork['productService']['product']; product: RequestWork['productService']['product'] & {
taskStatus?: TaskStatus;
totalNotStatusComplete?: number;
};
list: (RequestWork & { list: (RequestWork & {
_template?: { _template?: {
id: string; id: string;
@ -289,15 +292,15 @@ let taskListGroup = computed(() => {
step: number; step: number;
responsibleInstitution: (string | { group: string })[]; responsibleInstitution: (string | { group: string })[];
} | null; } | null;
taskStatus?: TaskStatus;
failedComment?: string;
failedType?: string;
})[]; })[];
}[] }[]
>((acc, curr) => { >((acc, curr) => {
if ( const isNotComplete =
fullTaskOrder.value?.taskOrderStatus === TaskOrderStatus.Complete && fullTaskOrder.value?.taskOrderStatus === TaskOrderStatus.Complete &&
curr.taskStatus !== TaskStatus.Complete curr.taskStatus !== TaskStatus.Complete;
) {
return acc;
}
const task = curr.requestWorkStep; const task = curr.requestWorkStep;
const step = curr.step; const step = curr.step;
@ -308,9 +311,18 @@ let taskListGroup = computed(() => {
let exist = acc.find( let exist = acc.find(
(item) => task.requestWork.productService.productId == item.product.id, (item) => task.requestWork.productService.productId == item.product.id,
); );
const record = Object.assign(task.requestWork, {
_template: getTemplateData(task.requestWork, step), const record = Object.assign(
}); {
...task.requestWork,
taskStatus: curr.taskStatus,
failedComment: curr.failedComment || '',
failedType: curr.failedType || '',
},
{
_template: getTemplateData(task.requestWork, step),
},
);
const template = getTemplateData(task.requestWork, step); const template = getTemplateData(task.requestWork, step);
@ -323,10 +335,18 @@ let taskListGroup = computed(() => {
} }
if (exist) { if (exist) {
exist.list.push(task.requestWork); exist.list.push(record);
if (isNotComplete) {
exist.product.totalNotStatusComplete =
(exist.product.totalNotStatusComplete || undefined) + 1;
}
} else { } else {
acc.push({ acc.push({
product: task.requestWork.productService.product, product: {
...task.requestWork.productService.product,
taskStatus: curr.taskStatus || TaskStatus.Pending,
totalNotStatusComplete: isNotComplete ? 1 : undefined,
},
list: [record], list: [record],
}); });
} }
@ -985,6 +1005,7 @@ watch(
" "
/> />
<!-- TODO: blind remark, urgent --> <!-- TODO: blind remark, urgent -->
{{ console.log(taskListGroup) }}
<RemarkExpansion <RemarkExpansion
v-if=" v-if="
view === TaskOrderStatus.Pending || view === TaskOrderStatus.Pending ||

View file

@ -164,6 +164,8 @@ export interface TaskOrderPayload {
requestWorkId: string; requestWorkId: string;
requestWorkStep?: Task; requestWorkStep?: Task;
taskStatus?: TaskStatus; taskStatus?: TaskStatus;
failedType?: string;
failedComment?: string;
}[]; }[];
taskProduct?: { taskProduct?: {
productId: string; productId: string;

View file

@ -1,5 +1,7 @@
import { RequestWork } from 'src/stores/request-list'; import { RequestWork } from 'src/stores/request-list';
import { TaskStatus } from 'src/stores/task-order/types';
import { formatNumberDecimal } from 'src/stores/utils'; import { formatNumberDecimal } from 'src/stores/utils';
import { i18n } from 'src/boot/i18n';
const templates = { const templates = {
'quotation-labor': { 'quotation-labor': {
@ -46,7 +48,12 @@ const templates = {
converter: (context?: { converter: (context?: {
items?: { items?: {
product: RequestWork['productService']['product']; product: RequestWork['productService']['product'];
list: RequestWork[]; list: (RequestWork & {
taskStatus?: TaskStatus;
failedComment?: string;
failedType?: string;
codeRequest?: string;
})[];
}[]; }[];
itemsDiscount?: { itemsDiscount?: {
productId: string; productId: string;
@ -67,8 +74,9 @@ const templates = {
const branch = v.request.quotation.customerBranch; const branch = v.request.quotation.customerBranch;
return ( return (
`${i + 1}. ` + `${i + 1}. ` +
` ${v.request.code}_${branch.customer.customerType === 'PERS' ? `นายจ้าง ${branch.namePrefix}. ${branch.firstNameEN} ${branch.lastNameEN} `.toUpperCase() : branch.registerName}_` +
`${employee.namePrefix}. ${employee.firstNameEN} ${employee.lastNameEN} `.toUpperCase() + `${employee.namePrefix}. ${employee.firstNameEN} ${employee.lastNameEN} `.toUpperCase() +
`(${branch.customer.customerType === 'PERS' ? `นายจ้าง ${branch.namePrefix}. ${branch.firstNameEN} ${branch.lastNameEN} `.toUpperCase() : branch.registerName})` `${!!v.failedType && v.failedType !== 'other' ? `${i18n.global.t(`taskOrder.${v.failedType}`)}` : !!v.failedComment ? v.failedComment : ''}`
); );
}); });
return [ return [