refactor: workerIndex
This commit is contained in:
parent
85b108a9b2
commit
7760f0f15a
4 changed files with 88 additions and 12 deletions
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { QTableProps } from 'quasar';
|
||||
import ThaiBahtText from 'thai-baht-text';
|
||||
import { toWords } from 'number-to-words';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
|
|
@ -9,14 +8,12 @@ import WorkerItem from './WorkerItem.vue';
|
|||
import DeleteButton from '../button/DeleteButton.vue';
|
||||
import { commaInput } from 'stores/utils';
|
||||
import { precisionRound } from 'src/utils/arithmetic';
|
||||
import TableComponents from 'components/TableComponents.vue';
|
||||
import { QuotationPayload } from 'stores/quotations/types';
|
||||
import { formatNumberDecimal } from 'stores/utils';
|
||||
import { useConfigStore } from 'stores/config';
|
||||
import { Product, Service, Work } from 'src/stores/product-service/types';
|
||||
import { read } from 'fs';
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
readonly?: boolean;
|
||||
agentPrice: boolean;
|
||||
employeeRows?: {
|
||||
|
|
@ -250,10 +247,22 @@ function groupByServiceId() {
|
|||
groupList.value = groupedItems;
|
||||
}
|
||||
|
||||
function handleCheck(
|
||||
index: number,
|
||||
data: QuotationPayload['productServiceList'][number],
|
||||
) {
|
||||
const target = data.workerIndex.indexOf(index);
|
||||
if (target > -1) {
|
||||
data.workerIndex.splice(target, 1);
|
||||
} else {
|
||||
data.workerIndex.push(index);
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => rows.value,
|
||||
() => {
|
||||
groupByServiceId();
|
||||
if (rows.value.length > 0) groupByServiceId();
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -263,6 +272,19 @@ watch(
|
|||
summaryPrice.value = summary.value;
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.employeeRows,
|
||||
(a, b) => {
|
||||
if (a === undefined || b === undefined) return;
|
||||
if (a.length < b.length) {
|
||||
rows.value.forEach((p) => {
|
||||
const maxValue = Math.max(...p.workerIndex);
|
||||
p.workerIndex = p.workerIndex.filter((i) => i !== maxValue);
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<div class="column">
|
||||
|
|
@ -278,7 +300,7 @@ watch(
|
|||
style="background: var(--orange-5); color: var(--surface-1)"
|
||||
size="sm"
|
||||
>
|
||||
{{ i + 1 }}
|
||||
<q-icon size="xs" name="mdi-server-outline" />
|
||||
</q-avatar>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
|
|
@ -419,9 +441,12 @@ watch(
|
|||
>
|
||||
<q-td colspan="100%" style="padding: 16px">
|
||||
<WorkerItem
|
||||
@check="(wokerIndex) => handleCheck(wokerIndex, props.row)"
|
||||
checkable
|
||||
fallback-img="/images/employee-avatar.png"
|
||||
inTable
|
||||
hideQuantity
|
||||
:check-list="props.row.workerIndex"
|
||||
:rows="employeeRows"
|
||||
/>
|
||||
</q-td>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" setup>
|
||||
import { QTableProps } from 'quasar';
|
||||
import TableComponents from 'src/components/TableComponents.vue';
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
defineEmits<{
|
||||
(e: 'delete', index: number): void;
|
||||
(e: 'check', index: number): void;
|
||||
}>();
|
||||
|
||||
withDefaults(
|
||||
|
|
@ -12,6 +14,7 @@ withDefaults(
|
|||
employeeAmount?: number;
|
||||
fallbackImg?: string;
|
||||
hideQuantity?: boolean;
|
||||
checkable?: boolean;
|
||||
inTable?: boolean;
|
||||
rows: {
|
||||
foreignRefNo: string;
|
||||
|
|
@ -31,6 +34,8 @@ withDefaults(
|
|||
},
|
||||
);
|
||||
|
||||
const checkList = defineModel<number[]>('checkList', { default: [] });
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'order',
|
||||
|
|
@ -87,13 +92,26 @@ const columns = [
|
|||
<TableComponents
|
||||
flat
|
||||
bordered
|
||||
button-delete
|
||||
:button-delete="!checkable"
|
||||
img-column="employeeName"
|
||||
:readonly="readonly"
|
||||
:inTable
|
||||
:columns
|
||||
:columns="
|
||||
checkable
|
||||
? [
|
||||
{
|
||||
name: 'check',
|
||||
align: 'center',
|
||||
label: '',
|
||||
field: 'check',
|
||||
},
|
||||
...columns.filter((c) => c.name !== 'action'),
|
||||
]
|
||||
: columns
|
||||
"
|
||||
:rows
|
||||
hidePagination
|
||||
:customColumn="['check']"
|
||||
@delete="(i) => $emit('delete', i)"
|
||||
>
|
||||
<template v-slot:img-column="{ props }">
|
||||
|
|
@ -121,6 +139,20 @@ const columns = [
|
|||
</div>
|
||||
</q-avatar>
|
||||
</template>
|
||||
|
||||
<template v-slot:body-cell-check="{ props }">
|
||||
<q-td class="text-center">
|
||||
<q-checkbox
|
||||
size="xs"
|
||||
@click.stop="
|
||||
() => {
|
||||
$emit('check', props.rowIndex);
|
||||
}
|
||||
"
|
||||
:model-value="checkList.includes(props.rowIndex)"
|
||||
></q-checkbox>
|
||||
</q-td>
|
||||
</template>
|
||||
</TableComponents>
|
||||
|
||||
<div v-if="!hideQuantity" class="row q-pt-md items-center">
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ function mapNode() {
|
|||
detail: p.product.detail,
|
||||
remark: p.product.remark,
|
||||
value: {
|
||||
workerIndex: [],
|
||||
vat: 0,
|
||||
pricePerUnit,
|
||||
discount: 0,
|
||||
|
|
@ -258,6 +259,7 @@ function mapNode() {
|
|||
subtitle: p.product.code || ' ',
|
||||
checked: true,
|
||||
value: {
|
||||
workerIndex: [],
|
||||
vat: 0,
|
||||
pricePerUnit,
|
||||
discount: 0,
|
||||
|
|
@ -282,6 +284,7 @@ function mapNode() {
|
|||
title: v.name,
|
||||
subtitle: v.code,
|
||||
value: {
|
||||
workerIndex: [],
|
||||
vat: 0,
|
||||
pricePerUnit,
|
||||
discount: 0,
|
||||
|
|
|
|||
|
|
@ -52,7 +52,13 @@ import ToggleButton from 'components/button/ToggleButton.vue';
|
|||
import FormAbout from 'components/05_quotation/FormAbout.vue';
|
||||
import SelectZone from 'components/shared/SelectZone.vue';
|
||||
import PersonCard from 'components/shared/PersonCard.vue';
|
||||
import { AddButton, SaveButton, EditButton } from 'components/button';
|
||||
import {
|
||||
AddButton,
|
||||
SaveButton,
|
||||
EditButton,
|
||||
UndoButton,
|
||||
DeleteButton,
|
||||
} from 'components/button';
|
||||
import ProductServiceForm from './ProductServiceForm.vue';
|
||||
import QuotationFormInfo from './QuotationFormInfo.vue';
|
||||
import ProfileBanner from 'components/ProfileBanner.vue';
|
||||
|
|
@ -250,7 +256,7 @@ async function assignToProductServiceList() {
|
|||
}),
|
||||
);
|
||||
selectedProductGroup.value =
|
||||
quotationFormData.value.productServiceList[0].product.productGroup?.id ||
|
||||
quotationFormData.value.productServiceList[0]?.product.productGroup?.id ||
|
||||
'';
|
||||
}
|
||||
}
|
||||
|
|
@ -424,6 +430,9 @@ function convertToTable(nodes: Node[]) {
|
|||
|
||||
list.forEach((v) => {
|
||||
v.amount = Math.max(selectedWorker.value.length, 1);
|
||||
for (let i = 0; i < selectedWorker.value.length; i++) {
|
||||
v.workerIndex.push(i);
|
||||
}
|
||||
});
|
||||
|
||||
productServiceList.value = list;
|
||||
|
|
@ -437,6 +446,14 @@ function convertEmployeeToTable() {
|
|||
v.amount + preSelectedWorker.value.length - selectedWorker.value.length,
|
||||
1,
|
||||
);
|
||||
|
||||
for (
|
||||
let i = 0;
|
||||
i < preSelectedWorker.value.length - selectedWorker.value.length;
|
||||
i++
|
||||
) {
|
||||
v.workerIndex.push(selectedWorker.value.length + i);
|
||||
}
|
||||
return v;
|
||||
});
|
||||
refSelectZoneEmployee.value?.assignSelect(
|
||||
|
|
@ -715,7 +732,6 @@ watch(
|
|||
productGroup.find((g) => g.id === selectedProductGroup)
|
||||
?.name || '-'
|
||||
}}
|
||||
<q-icon name="mdi-chevron-right" class="q-pl-sm" size="xs" />
|
||||
</span>
|
||||
|
||||
<ProductItem
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue