diff --git a/package.json b/package.json
index 9638bb29..be62c38a 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,6 @@
"apexcharts": "^4.5.0",
"axios": "^1.8.4",
"cropperjs": "^1.6.2",
- "dayjs": "^1.11.13",
"highlight.js": "^11.11.1",
"keycloak-js": "^25.0.6",
"markdown-it": "^14.1.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7cb78cc6..47c2eb49 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -29,9 +29,6 @@ importers:
cropperjs:
specifier: ^1.6.2
version: 1.6.2
- dayjs:
- specifier: ^1.11.13
- version: 1.11.13
highlight.js:
specifier: ^11.11.1
version: 11.11.1
@@ -1476,9 +1473,6 @@ packages:
date-fns@3.6.0:
resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==}
- dayjs@1.11.13:
- resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
-
de-indent@1.0.2:
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
@@ -5278,8 +5272,6 @@ snapshots:
date-fns@3.6.0: {}
- dayjs@1.11.13: {}
-
de-indent@1.0.2: {}
debug@2.6.9:
diff --git a/public/images/customer-CORP-avartar-female.png b/public/images/customer-CORP-avartar-female.png
index 4cbb894f..446ef866 100644
Binary files a/public/images/customer-CORP-avartar-female.png and b/public/images/customer-CORP-avartar-female.png differ
diff --git a/public/images/customer-CORP-avartar-male.png b/public/images/customer-CORP-avartar-male.png
index ae177f60..6ad95d7d 100644
Binary files a/public/images/customer-CORP-avartar-male.png and b/public/images/customer-CORP-avartar-male.png differ
diff --git a/public/images/customer-PERS-avartar-female.png b/public/images/customer-PERS-avartar-female.png
index c3ba574e..ca0a2bf1 100644
Binary files a/public/images/customer-PERS-avartar-female.png and b/public/images/customer-PERS-avartar-female.png differ
diff --git a/public/images/customer-PERS-avartar-male.png b/public/images/customer-PERS-avartar-male.png
index ce0ab20c..e9fd15fe 100644
Binary files a/public/images/customer-PERS-avartar-male.png and b/public/images/customer-PERS-avartar-male.png differ
diff --git a/public/images/employee-avatar-female.png b/public/images/employee-avatar-female.png
index ce9370f1..66ace3a0 100644
Binary files a/public/images/employee-avatar-female.png and b/public/images/employee-avatar-female.png differ
diff --git a/public/images/employee-avatar-male.png b/public/images/employee-avatar-male.png
index aaf5fb1f..a8daa8ff 100644
Binary files a/public/images/employee-avatar-male.png and b/public/images/employee-avatar-male.png differ
diff --git a/public/img-group.png b/public/img-group.png
deleted file mode 100644
index 0493168b..00000000
Binary files a/public/img-group.png and /dev/null differ
diff --git a/public/no-img-female.png b/public/no-img-female.png
index 95f959ff..4e177dca 100644
Binary files a/public/no-img-female.png and b/public/no-img-female.png differ
diff --git a/public/no-img-man.png b/public/no-img-man.png
index f0ccba15..861f356a 100644
Binary files a/public/no-img-man.png and b/public/no-img-man.png differ
diff --git a/public/option/option.json b/public/option/option.json
index 963c4ad2..c5ea33cd 100644
--- a/public/option/option.json
+++ b/public/option/option.json
@@ -183,15 +183,15 @@
"prefix": [
{
- "label": "MR",
+ "label": "Mr",
"value": "mr"
},
{
- "label": "MRS",
+ "label": "Mrs",
"value": "mrs"
},
{
- "label": "MISS",
+ "label": "Miss",
"value": "miss"
}
],
diff --git a/quasar.config.ts b/quasar.config.ts
index 38bb94c1..cc0715ad 100644
--- a/quasar.config.ts
+++ b/quasar.config.ts
@@ -31,7 +31,7 @@ export default defineConfig((ctx) => {
devServer: {
host: '0.0.0.0',
open: false,
- port: 5174,
+ port: 5173,
},
framework: {
config: {},
diff --git a/src/components/01_branch-management/BranchCard.vue b/src/components/01_branch-management/BranchCard.vue
index c10d63fc..83c268ba 100644
--- a/src/components/01_branch-management/BranchCard.vue
+++ b/src/components/01_branch-management/BranchCard.vue
@@ -89,7 +89,15 @@ defineProps<{
-
+
+
+ (virtual = v === 'Virtual')"
+ :rules="[(val) => val && val.length > 0]"
+ :error-message="$t('form.error.required')"
+ >
+
+
+
+ {{ $t('general.noData') }}
+
+
+
+
diff --git a/src/components/02_personnel-management/FormByType.vue b/src/components/02_personnel-management/FormByType.vue
index d1709858..1537dc07 100644
--- a/src/components/02_personnel-management/FormByType.vue
+++ b/src/components/02_personnel-management/FormByType.vue
@@ -29,18 +29,19 @@ const discountCondition = defineModel
(
const sourceNationality = defineModel(
'sourceNationality',
);
-const importNationality = defineModel(
+const importNationality = defineModel(
'importNationality',
);
const trainingPlace = defineModel('trainingPlace');
const checkpoint = defineModel('checkpoint');
-const userFile = defineModel('userFile');
-const userFileList =
- defineModel<{ name: string; url: string }[]>('userFileList');
+const agencyFile = defineModel('agencyFile');
+const agencyFileList =
+ defineModel<{ name: string; url: string }[]>('agencyFileList');
const remark = defineModel('remark');
const agencyStatus = defineModel('agencyStatus');
const attachmentRef = ref();
+const checkpointENOption = ref([]);
defineProps<{
dense?: boolean;
@@ -70,12 +71,18 @@ function deleteFile(name: string) {
userStore.deleteAttachment(userId.value, payload);
const result = await userStore.fetchAttachment(userId.value);
if (result) {
- userFileList.value = result;
+ agencyFileList.value = result;
}
},
cancel: () => {},
});
}
+
+onMounted(async () => {
+ const resultOption = await fetch('/option/option.json');
+ const rawOption = await resultOption.json();
+ checkpointENOption.value = rawOption.eng.border;
+});
@@ -133,12 +140,11 @@ function deleteFile(name: string) {
/>
(typeof v === 'string' ? (sourceNationality = v) : '')
"
/>
-
(typeof v === 'string' ? (importNationality = v) : '')
+ "
+ />
+ (typeof v === 'string' ? (trainingPlace = v) : '')
+ "
/>
-
(typeof v === 'string' ? (checkpoint = v) : '')
"
/>
-
(typeof v === 'string' ? (trainingPlace = v) : '')
+ (v) => (typeof v === 'string' ? (checkpoint = v) : '')
"
/>
@@ -237,7 +253,7 @@ function deleteFile(name: string) {
value: AgencyStatus.Blacklist,
},
]"
- class="col-md-4 col-12"
+ class="col-md-6 col-12"
:readonly
:label="$t('personnel.form.agencyStatus')"
clearable
@@ -259,78 +275,76 @@ function deleteFile(name: string) {
"
@clear="remark = ''"
/>
-
-
-
-
-
-
-
-
-
- {{ file.file.name }}
-
-
+
+
-
-
-
+
+
+
+
+ {{ file.file.name }}
+
+
+
+
+
-
-
- openNewTab(item.url)"
- >
-
-
-
- {{ item.name }}
+
+
+ openNewTab(item.url)"
+ >
+
+
-
-
-
-
-
+
+
+
+
diff --git a/src/components/02_personnel-management/FormPerson.vue b/src/components/02_personnel-management/FormPerson.vue
index cb0463af..0204bb47 100644
--- a/src/components/02_personnel-management/FormPerson.vue
+++ b/src/components/02_personnel-management/FormPerson.vue
@@ -1,8 +1,10 @@
@@ -96,19 +171,41 @@ watch(
for="input-citizen-id"
/>
-
+ :dense="dense"
+ :readonly="readonly"
+ :options="prefixNameOptions"
+ :for="`${prefixId}-select-prefix-name`"
+ :label="$t('personnel.form.prefixName')"
+ @filter="prefixNameFilter"
+ :model-value="readonly ? prefixName || '-' : prefixName"
+ @update:model-value="
+ (v) => (typeof v === 'string' ? (prefixName = v) : '')
+ "
+ @clear="prefixName = ''"
+ :rules="[(val: string) => !!val || $t('form.error.required')]"
+ >
+
+
+
+ {{ $t('general.noData') }}
+
+
+
+
-
+ :dense="dense"
+ :readonly="readonly"
+ :options="prefixNameOptionsEn"
+ :for="`${prefixId}-select-prefix-name-en`"
+ label="Prefix"
+ @filter="prefixNameFilter"
+ :model-value="readonly ? prefixName || '-' : prefixName"
+ @update:model-value="
+ (v) => (typeof v === 'string' ? (prefixName = v) : '')
+ "
+ @clear="prefixName = ''"
+ :rules="[(val: string) => !!val || $t('form.error.required')]"
+ >
+
+
+
+ {{ $t('general.noData') }}
+
+
+
+
(typeof v === 'string' ? (email = v) : '')"
@@ -275,16 +405,39 @@ watch(
-
+ @filter="genderFilter"
+ :model-value="readonly ? gender || '-' : gender"
+ @update:model-value="(v) => (typeof v === 'string' ? (gender = v) : '')"
+ @clear="gender = ''"
+ >
+
+
+
+ {{ $t('general.noData') }}
+
+
+
+
-
-
+
+
+
+ {{ $t('general.noData') }}
+
+
+
+
+
-
- (typeof v === 'string' ? (contactName = v) : '')
- "
- />
-
- (typeof v === 'string' ? (contactTel = v) : '')
- "
+ @filter="nationalityFilter"
>
-
-
+
+
+
+ {{ $t('general.noData') }}
+
+
-
+
diff --git a/src/components/03_customer-management/DialogEmployee.vue b/src/components/03_customer-management/DialogEmployee.vue
deleted file mode 100644
index db428f83..00000000
--- a/src/components/03_customer-management/DialogEmployee.vue
+++ /dev/null
@@ -1,1656 +0,0 @@
-
-
-
-
-
{
- employeeFormState.imageDialog = true;
- employeeFormState.isImageEdit = false;
- }
- "
- @edit="
- () => {
- if (currentFromDataEmployee.id) {
- fetchImageList(
- currentFromDataEmployee.id,
- currentFromDataEmployee.selectedImage || '',
- 'employee',
- );
- }
- employeeFormState.imageDialog =
- employeeFormState.isImageEdit = true;
- }
- "
- @update:toggle-status="
- () => {
- currentFromDataEmployee.status =
- currentFromDataEmployee.status === 'CREATED'
- ? 'INACTIVE'
- : 'CREATED';
- }
- "
- />
-
-
-
-
-
- {
- if (!v) return;
- if (!currentFromDataEmployee.id) return;
- await employeeStore.addImageList(
- v,
- currentFromDataEmployee.id,
- Date.now().toString(),
- );
- await fetchImageList(
- currentFromDataEmployee.id,
- currentFromDataEmployee.selectedImage || '',
- 'employee',
- );
- }
- "
- @remove-image="
- async (v) => {
- if (!v) return;
- if (!currentFromDataEmployee.id) return;
- const name = v.split('/').pop() || '';
- await employeeStore.deleteImageByName(currentFromDataEmployee.id, name);
- await fetchImageList(
- currentFromDataEmployee.id,
- currentFromDataEmployee.selectedImage || '',
- 'employee',
- );
- }
- "
- @submit="
- async (v) => {
- if (employeeFormState.dialogModal && !currentFromDataEmployee.id) {
- employeeFormState.profileUrl = v;
- employeeFormState.imageDialog = false;
- } else {
- refreshImageState = true;
- employeeFormState.dialogType = 'edit';
- currentFromDataEmployee.selectedImage = v;
- employeeFormState.imageList
- ? (employeeFormState.imageList.selectedImage = v)
- : '';
- employeeFormState.profileUrl = `${baseUrl}/employee/${currentFromDataEmployee.id && currentFromDataEmployee.id}/image/${v}`;
- employeeFormStore.resetFormDataEmployee();
- await employeeFormStore.submitPersonal(onCreateImageList);
- employeeFormState.imageDialog = false;
- refreshImageState = false;
- employeeFormState.isEmployeeEdit = false;
- employeeFormState.dialogType = 'info';
- await fetchListEmployee();
- }
- }
- "
- >
-
-
- {{ $t('general.image') }}
- {{
- $i18n.locale === 'eng'
- ? `${currentFromDataEmployee.firstNameEN || currentFromDataEmployee.firstName} ${currentFromDataEmployee.lastNameEN || currentFromDataEmployee.lastName}`
- : `${currentFromDataEmployee.firstName} ${currentFromDataEmployee.lastName}`
- }}
-
-
-
-
-
-
-
diff --git a/src/components/03_customer-management/DrawerEmployee.vue b/src/components/03_customer-management/DrawerEmployee.vue
deleted file mode 100644
index 1c1d39bf..00000000
--- a/src/components/03_customer-management/DrawerEmployee.vue
+++ /dev/null
@@ -1,1772 +0,0 @@
-
-
-
-
-
-
-
{
- employeeFormState.isImageEdit = false;
- employeeFormStore.resetFormDataEmployee();
- employeeFormState.isEmployeeEdit = false;
- employeeFormState.dialogType = 'info';
- employeeFormState.currentIndexPassport = -1;
- }
- "
- @view="
- () => {
- employeeFormState.imageDialog = true;
- employeeFormState.isImageEdit = false;
- }
- "
- @edit="
- employeeFormState.imageDialog = employeeFormState.isImageEdit = true
- "
- @update:toggle-status="
- (v) => {
- if (currentFromDataEmployee.id !== undefined)
- $emit('changeStatus', v);
- }
- "
- :active="currentFromDataEmployee.status !== 'INACTIVE'"
- use-toggle
- color="white"
- icon="mdi-account-outline"
- :bg-color="
- employeeFormState.profileUrl
- ? 'white'
- : 'linear-gradient(135deg, rgba(43,137,223,1) 0%, rgba(230,51,81,1) 100%)'
- "
- v-model:current-tab="employeeFormState.currentTab"
- v-model:toggle-status="currentFromDataEmployee.status"
- fallback-cover="/images/employee-banner.png"
- :title="
- employeeFormState.currentEmployee
- ? setPrefixName(
- {
- namePrefix: employeeFormState.currentEmployee.namePrefix,
- firstName:
- employeeFormState.currentEmployee.firstName ||
- employeeFormState.currentEmployee.firstNameEN,
- lastName:
- employeeFormState.currentEmployee.lastName ||
- employeeFormState.currentEmployee.lastNameEN,
- firstNameEN: employeeFormState.currentEmployee.firstNameEN,
- lastNameEN: employeeFormState.currentEmployee.lastNameEN,
- },
- { locale },
- )
- : '-'
- "
- :caption="currentFromDataEmployee.code"
- :img="
- `${baseUrl}/employee/${currentFromDataEmployee.id}/image/${currentFromDataEmployee.selectedImage}`.concat(
- refreshImageState ? `?ts=${Date.now()}` : '',
- ) || null
- "
- :fallbackImg="`/images/employee-avatar-${currentFromDataEmployee.gender === 'male' ? 'male' : 'female'}.png`"
- :tabs-list="[
- {
- name: 'personalInfo',
- label: $t('customerEmployee.form.group.personalInfo'),
- },
- {
- name: 'passport',
- label: $t('customerEmployee.fileType.passport'),
- },
- {
- name: 'visa',
- label: $t('customerEmployee.form.group.visa'),
- },
- {
- name: 'healthCheck',
- label: $t('customerEmployee.form.group.healthCheck'),
- },
- {
- name: 'workHistory',
- label: $t('customerEmployee.form.group.workHistory'),
- },
- { name: 'other', label: $t('customerEmployee.form.group.other') },
- ]"
- :toggle-title="$t('status.title')"
- />
-
-
-
-
-
- {
- if (!v) return;
- if (!currentFromDataEmployee.id) return;
- await employeeStore.addImageList(
- v,
- currentFromDataEmployee.id,
- Date.now().toString(),
- );
- await fetchImageList(
- currentFromDataEmployee.id,
- currentFromDataEmployee.selectedImage || '',
- 'employee',
- );
- }
- "
- @remove-image="
- async (v) => {
- if (!v) return;
- if (!currentFromDataEmployee.id) return;
- const name = v.split('/').pop() || '';
- await employeeStore.deleteImageByName(currentFromDataEmployee.id, name);
- await fetchImageList(
- currentFromDataEmployee.id,
- currentFromDataEmployee.selectedImage || '',
- 'employee',
- );
- }
- "
- @submit="
- async (v) => {
- if (employeeFormState.dialogModal && !currentFromDataEmployee.id) {
- employeeFormState.profileUrl = v;
- employeeFormState.imageDialog = false;
- } else {
- refreshImageState = true;
- employeeFormState.dialogType = 'edit';
- currentFromDataEmployee.selectedImage = v;
- employeeFormState.imageList
- ? (employeeFormState.imageList.selectedImage = v)
- : '';
- employeeFormState.profileUrl = `${baseUrl}/employee/${currentFromDataEmployee.id && currentFromDataEmployee.id}/image/${v}`;
- employeeFormStore.resetFormDataEmployee();
- await employeeFormStore.submitPersonal(onCreateImageList);
- employeeFormState.imageDialog = false;
- refreshImageState = false;
- employeeFormState.isEmployeeEdit = false;
- employeeFormState.dialogType = 'info';
- await fetchListEmployee();
- }
- }
- "
- >
-
-
- {{ $t('general.image') }}
- {{
- $i18n.locale === 'eng'
- ? `${currentFromDataEmployee.firstNameEN || currentFromDataEmployee.firstName} ${currentFromDataEmployee.lastNameEN || currentFromDataEmployee.lastName}`
- : `${currentFromDataEmployee.firstName} ${currentFromDataEmployee.lastName}`
- }}
-
-
-
-
-
-
-
diff --git a/src/components/03_customer-management/FormEmployeeHealthCheck.vue b/src/components/03_customer-management/FormEmployeeHealthCheck.vue
index f8690dbe..b08e7a70 100644
--- a/src/components/03_customer-management/FormEmployeeHealthCheck.vue
+++ b/src/components/03_customer-management/FormEmployeeHealthCheck.vue
@@ -268,7 +268,6 @@ const insuranceCompanyFilter = selectFilterOptionRefMod(
('issuePlace');
const issueCountry = defineModel('issueCountry');
const issueDate = defineModel('issueDate');
const type = defineModel('type');
-const expireDate = defineModel('expireDate');
-const birthDate = defineModel('birthDate');
+const expireDate = defineModel('expireDate');
+const birthDate = defineModel('birthDate');
const workerStatus = defineModel('workerStatus');
const nationality = defineModel('nationality');
const gender = defineModel('gender');
@@ -34,8 +32,6 @@ const firstName = defineModel('firstName');
const namePrefix = defineModel('namePrefix');
const passportNumber = defineModel('passportNumber');
-const file = defineModel('file');
-
const passportValidator = /[a-zA-Z]{1}[a-zA-Z0-9]{1}[0-9]{5,7}$/;
const genderOptions = ref[]>([]);
@@ -181,30 +177,6 @@ watch(
},
);
-function browse() {
- inputFile?.click();
-}
-
-const inputFile = (() => {
- const _element = document.createElement('input');
- _element.type = 'file';
- _element.accept = 'image/jpeg,image/png';
- _element.addEventListener('change', change);
- return _element;
-})();
-
-async function change(e: Event) {
- const _element = e.target as HTMLInputElement | null;
- const _file = _element?.files?.[0];
-
- if (_file) {
- const newFileName = `passport-${dateFormat(new Date().toISOString())}-${_file.name}`;
- const renamedFile = new File([_file], newFileName, { type: _file.type });
-
- file.value = renamedFile;
- }
-}
-
watch(
() => namePrefix.value,
(v) => {
@@ -249,14 +221,20 @@ watch(
-
-
browse()"
- :disable="readonly"
- >
+
+
('arrivalAt');
const arrivalTMNo = defineModel('arrivalTmNo');
const arrivalTM = defineModel('arrivalTm');
const mrz = defineModel('mrz');
-const entryCount = defineModel('entryCount');
+const entryCount = defineModel('entryCount');
const issuePlace = defineModel('issuePlace');
const issueCountry = defineModel('issueCountry');
const issueDate = defineModel('visaIssueDate');
-const type = defineModel('type');
-const expireDate = defineModel('expireDate');
+const type = defineModel('visaType');
+const expireDate = defineModel('expireDate');
const remark = defineModel('remark');
const workerType = defineModel('workerType');
-const number = defineModel('number');
-const reportDate = defineModel('reportDate');
+const number = defineModel('visaNumber');
-//
-// const calculatedVisaDate = computed(() => {
-// if (!issueDate.value) return undefined;
-// return calculate90DayNext(issueDate.value);
-// });
+const calculatedVisaDate = computed(() => {
+ if (!issueDate.value) return undefined;
+ return calculate90DayNext(issueDate.value);
+});
defineProps<{
title?: string;
@@ -80,12 +78,6 @@ onMounted(async () => {
await fetchProvince();
});
-const visaIssueCountryOptions = ref[]>([]);
-let visaIssueCountryFilter: (
- value: string,
- update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
-) => void;
-
const visaTypeOptions = ref[]>([]);
let visaTypeFilter: (
value: string,
@@ -105,12 +97,6 @@ onMounted(() => {
'label',
);
- visaIssueCountryFilter = selectFilterOptionRefMod(
- ref(optionStore.globalOption?.nationality),
- visaIssueCountryOptions,
- 'label',
- );
-
workerTypeFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption?.workerType),
workerTypeOptions,
@@ -121,14 +107,8 @@ onMounted(() => {
watch(
() => optionStore.globalOption,
() => {
- visaIssueCountryFilter = selectFilterOptionRefMod(
- ref(optionStore.globalOption?.nationality),
- visaIssueCountryOptions,
- 'label',
- );
-
visaTypeFilter = selectFilterOptionRefMod(
- optionStore.globalOption.visaType,
+ optionStore.globalOption.nationality,
visaTypeOptions,
'label',
);
@@ -140,10 +120,6 @@ watch(
);
},
);
-//
-// watch([() => issueDate.value], () => {
-// reportDate.value = calculate90DayNext(issueDate.value);
-// });
@@ -157,7 +133,7 @@ watch(
name="mdi-passport"
style="background-color: var(--surface-3)"
/>
- {{ $t(title) }}
+ {{ title }}
@@ -448,11 +422,11 @@ watch(
class="col-md-4 col-6"
:dense="dense"
:readonly="readonly"
- :options="visaIssueCountryOptions"
+ :options="visaTypeOptions"
:hide-dropdown-icon="readonly"
:for="`${prefixId}-select-issue-country`"
:label="$t('customerEmployee.form.issueCountry')"
- @filter="visaIssueCountryFilter"
+ @filter="visaTypeFilter"
:model-value="readonly ? issueCountry || '-' : issueCountry"
@update:model-value="
(v) => (typeof v === 'string' ? (issueCountry = v) : '')
diff --git a/src/components/03_customer-management/TableEmpoloyee.vue b/src/components/03_customer-management/TableEmpoloyee.vue
index 000c701a..e5e49b51 100644
--- a/src/components/03_customer-management/TableEmpoloyee.vue
+++ b/src/components/03_customer-management/TableEmpoloyee.vue
@@ -22,8 +22,6 @@ const prop = withDefaults(
inTable?: boolean;
addButton?: boolean;
prefixId?: string;
- hideAction?: boolean;
- hideDelete?: boolean;
}>(),
{
gridView: false,
@@ -141,9 +139,8 @@ defineEmits<{
();
const { t } = useI18n();
const userStore = useUserStore();
const optionStore = useOptionStore();
-const workflowStore = useWorkflowTemplate();
const userInTable = defineModel('userInTable', {
default: [],
@@ -56,9 +51,7 @@ let objectOptions = [
const options = ref(objectOptions);
const role = ref([]);
const userList = ref([]);
-const groupList = ref([]);
const responsiblePersonSearch = ref('');
-const responsibleMenu = ref(false);
async function getUserList(opts?: { query: string }) {
const resUser = await userStore.fetchList({
@@ -67,10 +60,10 @@ async function getUserList(opts?: { query: string }) {
if (resUser) userList.value = resUser.result;
}
-async function getGroupList() {
- const resGroup = await workflowStore.getGroupList();
- if (resGroup) groupList.value = resGroup;
-}
+// async function getUserById(responsiblePersonId: string) {
+// const resUser = await userStore.fetchById(responsiblePersonId);
+// if (resUser) userInTable.value.push(resUser);
+// }
function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
const currStep = flowData.value.step[stepIndex];
@@ -85,7 +78,6 @@ function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
userInTable.value[stepIndex] = {
name: flowData.value.step[stepIndex].name,
responsiblePerson: [],
- responsibleGroup: [],
};
}
@@ -109,33 +101,6 @@ function selectResponsiblePerson(stepIndex: number, responsiblePerson: User) {
}
}
-function selectResponsibleGroup(stepIndex: number, responsibleGroup: string) {
- const currStep = flowData.value.step[stepIndex];
- const existGroupIndex = currStep.responsibleGroup?.findIndex(
- (p) => p === responsibleGroup,
- );
-
- if (existGroupIndex === -1) {
- currStep.responsibleGroup?.push(responsibleGroup);
-
- if (!userInTable.value[stepIndex]) {
- userInTable.value[stepIndex] = {
- name: flowData.value.step[stepIndex].name,
- responsiblePerson: [],
- responsibleGroup: [],
- };
- }
-
- userInTable.value[stepIndex]?.responsibleGroup.push(responsibleGroup);
- } else {
- currStep.responsibleGroup?.splice(Number(existGroupIndex), 1);
- userInTable.value[stepIndex]?.responsibleGroup.splice(
- Number(existGroupIndex),
- 1,
- );
- }
-}
-
function selectItem(
val: Record,
responsibleInstitution?: string[],
@@ -177,7 +142,6 @@ watch(
onMounted(async () => {
role.value = getRole() || [];
await getUserList();
- await getGroupList();
await userStore.fetchHqOption();
});
@@ -202,7 +166,6 @@ onMounted(async () => {
:class="{ 'q-ml-lg': $q.screen.gt.xs, 'q-mt-sm': $q.screen.lt.sm }"
>
{
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
- {{
- `${optionStore.mapOption(person.namePrefix || '')} ${
- $i18n.locale === 'eng'
- ? person.firstNameEN
- : person.firstName
- } ${
- $i18n.locale === 'eng'
- ? person.lastNameEN
- : person.lastName
- }`
- }}
-
-
- {{ person.code }}
-
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ `${optionStore.mapOption(person.namePrefix || '')} ${
+ $i18n.locale === 'eng'
+ ? person.firstNameEN
+ : person.firstName
+ } ${
+ $i18n.locale === 'eng'
+ ? person.lastNameEN
+ : person.lastName
+ }`
+ }}
+
+
+ {{ person.code }}
+
+
-
-
-
- {{ $t('general.group') }}
-
-
-
-
-
- {{ group }}
-
-
-
-
-
-
(responsibleMenu = true)"
- @before-hide="() => (responsibleMenu = false)"
- >
+
+
+
{
{{ $t('general.noData') }}
{
{{ $t('personnel.MESSENGER') }}
{
-
-
- {{ $t('general.group') }}
-
-
- {{ $t('general.noData') }}
-
-
-
-
-
-
-
-
- {{ group.name }}
-
-
-
-
+
{
:deep(.q-dialog.fullscreen.no-pointer-events.q-dialog--modal) {
visibility: hidden;
}
-
-.transition-rotate {
- transition: transform 0.3s ease;
-}
-.rotated {
- transform: rotate(180deg);
-}
diff --git a/src/components/04_product-service/PriceDataComponent.vue b/src/components/04_product-service/PriceDataComponent.vue
index d005c043..59043144 100644
--- a/src/components/04_product-service/PriceDataComponent.vue
+++ b/src/components/04_product-service/PriceDataComponent.vue
@@ -167,28 +167,26 @@ withDefaults(
@@ -276,8 +271,6 @@ withDefaults(
flat
outlined
dense
- :readonly
- :hide-dropdown-icon="readonly"
v-model="vatIncluded"
>
diff --git a/src/components/04_product-service/WorkManagementComponent.vue b/src/components/04_product-service/WorkManagementComponent.vue
index 86e79951..e79872d9 100644
--- a/src/components/04_product-service/WorkManagementComponent.vue
+++ b/src/components/04_product-service/WorkManagementComponent.vue
@@ -98,8 +98,7 @@ watch(
(c, o) => {
const list = c.map((v: { name: string }) => v.name);
const oldList = o.map((v: { name: string }) => v.name);
- const index = workName.value ? oldList.indexOf(workName.value) : -1;
- if (index === -1) return;
+ const index = oldList.indexOf(workName.value || '');
if (
list[index] !== oldList[index] &&
@@ -705,8 +704,8 @@ watch(
}
:deep(
- .q-item__section.column.q-item__section--side.justify-center.q-item__section--avatar.q-focusable.relative-position.cursor-pointer
-) {
+ .q-item__section.column.q-item__section--side.justify-center.q-item__section--avatar.q-focusable.relative-position.cursor-pointer
+ ) {
justify-content: start !important;
padding-right: 8px !important;
padding-top: 16px;
@@ -736,8 +735,8 @@ watch(
}
:deep(
- i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-item__toggle-icon--rotated
-) {
+ i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-item__toggle-icon--rotated
+ ) {
color: var(--brand-1);
}
diff --git a/src/components/04_product-service/WorkNameManagement.vue b/src/components/04_product-service/WorkNameManagement.vue
index 81854b9e..2bde41ce 100644
--- a/src/components/04_product-service/WorkNameManagement.vue
+++ b/src/components/04_product-service/WorkNameManagement.vue
@@ -1,6 +1,7 @@
@@ -88,12 +68,7 @@ function deleteAttachment(name: string) {
class="col-md-4 col-12"
:label="$t('agencies.name')"
v-model="name"
- :rules="[
- (val) => !!val || $t('form.error.required'),
- (val) =>
- /^[A-Za-z0-9ก-๙\s&.,'-]+$/.test(val) ||
- $t('form.error.branchNameField'),
- ]"
+ :rules="[(val: string) => !!val || $t('form.error.required')]"
/>
(typeof v === 'string' ? (contactTel = v) : '')
@@ -182,78 +148,6 @@ function deleteAttachment(name: string) {
/>
-
-
-
-
-
-
-
-
- {{ file.file.name }}
-
-
-
-
-
-
-
-
- openNewTab(item.url)"
- >
-
-
-
- {{ item.name }}
-
-
-
-
-
-
-
diff --git a/src/components/08_request-list/DataDisplay.vue b/src/components/08_request-list/DataDisplay.vue
index f36acb4f..30a8e52b 100644
--- a/src/components/08_request-list/DataDisplay.vue
+++ b/src/components/08_request-list/DataDisplay.vue
@@ -27,38 +27,26 @@ withDefaults(
class="app-text-muted q-pr-sm"
:width="iconSize || '2rem'"
/>
-
-
+
+
{{ label }}
-
+
{{ value }}
{{ value }}
-
+
{{ item }}
,
diff --git a/src/components/11_credit-note/FormCredit.vue b/src/components/11_credit-note/FormCredit.vue
index 5e4ee55b..b6e2bf1f 100644
--- a/src/components/11_credit-note/FormCredit.vue
+++ b/src/components/11_credit-note/FormCredit.vue
@@ -8,10 +8,6 @@ defineProps<{
const quotationId = defineModel('quotationId', {
required: true,
});
-const isDebitNote = defineModel('isDebitNote', {
- required: false,
- default: false,
-});
@@ -41,7 +37,6 @@ const isDebitNote = defineModel('isDebitNote', {
cancelIncludeDebitNote: true,
hasCancel: true,
}"
- @selected="(v) => (isDebitNote = v.isDebitNote)"
/>
diff --git a/src/components/DialogForm.vue b/src/components/DialogForm.vue
index fb29a4ca..84319bcf 100644
--- a/src/components/DialogForm.vue
+++ b/src/components/DialogForm.vue
@@ -42,15 +42,6 @@ defineProps<{
const modal = defineModel('modal', { default: false });
const currentTab = defineModel('currentTab');
-
-async function onValidationError(ref: any) {
- const el = ref.$el as Element;
- el.scrollIntoView({
- behavior: 'smooth',
- block: 'center',
- inline: 'nearest',
- });
-}
('drawerOpen', {
const myForm = ref();
function reset() {
- if (props.beforeClose) {
- drawerOpen.value = props.beforeClose
- ? props.beforeClose()
- : !drawerOpen.value;
- }
if (myForm.value) {
myForm.value.resetValidation();
}
}
-
-async function onValidationError(ref: any) {
- const el = ref.$el as Element;
- el.scrollIntoView({
- behavior: 'smooth',
- block: 'center',
- inline: 'nearest',
- });
-}
(drawerOpen = beforeClose ? beforeClose() : v)"
:width="$q.screen.gt.xs ? windowSize * 0.85 : windowSize"
v-model="drawerOpen"
behavior="mobile"
@@ -79,7 +66,6 @@ async function onValidationError(ref: any) {
greedy
@submit.prevent
@validation-success="submit"
- @validation-error="onValidationError"
>
-import { Icon } from '@iconify/vue/dist/iconify.js';
-
defineProps<{
hideIcon?: boolean;
- icon?: string;
}>();
@@ -13,13 +10,10 @@ defineProps<{
v-if="!hideIcon"
id="btn-add"
padding="sm"
- :icon="icon ? undefined : 'mdi-plus'"
+ icon="mdi-plus"
direction="up"
class="color-btn"
>
-
-
-
-
-
+ />
diff --git a/src/components/GlobalDialog.vue b/src/components/GlobalDialog.vue
index f9df77d4..059f7755 100644
--- a/src/components/GlobalDialog.vue
+++ b/src/components/GlobalDialog.vue
@@ -46,7 +46,6 @@ defineProps<{
color="grey"
icon="mdi-close"
v-close-popup
- @click="cancel"
/>
diff --git a/src/components/PaginationPageSize.vue b/src/components/PaginationPageSize.vue
index e8ece111..4eb86e0c 100644
--- a/src/components/PaginationPageSize.vue
+++ b/src/components/PaginationPageSize.vue
@@ -1,12 +1,5 @@
@@ -17,12 +10,7 @@ withDefaults(
:key="v"
clickable
v-close-popup
- @click="
- () => {
- pageSize = v;
- fetchData();
- }
- "
+ @click="pageSize = v"
>
{{ v }}
diff --git a/src/components/ProfileBanner.vue b/src/components/ProfileBanner.vue
index 2d4b3975..9c72041c 100644
--- a/src/components/ProfileBanner.vue
+++ b/src/components/ProfileBanner.vue
@@ -229,7 +229,6 @@ const smallBanner = ref(false);
$emit('update:currentTab', v)"
>
import { BranchWithChildren } from 'stores/branch/types';
import KebabAction from './shared/KebabAction.vue';
+import { isRoleInclude } from 'stores/utils';
const nodes = defineModel<(any | BranchWithChildren)[]>('nodes', {
default: [],
@@ -16,7 +17,6 @@ withDefaults(
labelKey?: string;
childrenKey: string;
action?: boolean;
- hideCreate?: boolean;
}>(),
{
color: 'transparent',
@@ -96,9 +96,7 @@ defineEmits<{
expandedTree[expandedTree.length - 1] === node.id,
}"
>
- {{
- $i18n.locale === 'eng' ? node.nameEN || node.name : node.name
- }}
+ {{ node.name }}
{{ node.code }}
@@ -122,7 +120,11 @@ defineEmits<{
/>
-import { ref } from 'vue';
import MainButton from './MainButton.vue';
-const emit = defineEmits<{
+defineEmits<{
(e: 'click', v: MouseEvent): void;
- (e: 'fileSelected', v: File[]): void;
}>();
defineProps<{
iconOnly?: boolean;
@@ -12,29 +10,15 @@ defineProps<{
outlined?: boolean;
disabled?: boolean;
dark?: boolean;
- importFile?: boolean;
label?: string;
icon?: string;
}>();
-
-const inputRef = ref(null);
-
-function triggerFileInput() {
- inputRef.value?.click();
-}
-
-function handleFileChange(event: Event) {
- const files = (event.target as HTMLInputElement).files;
- if (files && files.length > 0) {
- emit('fileSelected', Array.from(files));
- }
-}
(importFile ? triggerFileInput() : $emit('click', e))"
+ @click="(e) => $emit('click', e)"
v-bind="{ ...$props, ...$attrs }"
:icon="icon || 'mdi-import'"
color="var(--info-bg)"
@@ -42,13 +26,4 @@ function handleFileChange(event: Event) {
>
{{ label || $t('general.import') }}
-
- handleFileChange(e)"
- hidden
- accept=".xls, .xlsx , .csv"
- multiple
- />
diff --git a/src/components/button/MainButton.vue b/src/components/button/MainButton.vue
index 08233063..836abe32 100644
--- a/src/components/button/MainButton.vue
+++ b/src/components/button/MainButton.vue
@@ -5,7 +5,6 @@ defineEmits<{
(e: 'click', v: MouseEvent): void;
}>();
defineProps<{
- id?: string;
icon?: string;
color: string;
iconOnly?: boolean;
@@ -19,7 +18,6 @@ defineProps<{
-
-
-
- {{ $t('personnel.form.addressForeign') }}
-
@@ -499,24 +449,7 @@ watchEffect(async () => {
(v) => (typeof v === 'string' ? (street = v) : '')
"
/>
-
{
-
{
-
-
{
(zipCode = v.toString())"
- :rules="
- !addressForeign
- ? []
- : [(val) => (val && val.length > 0) || $t('form.error.required')]
+ addrOptions.subDistrictOps
+ ?.filter((x) => x.id === subDistrictId)
+ .map((x) => x.zipCode)[0] ?? ''
"
/>
{
(v) => (typeof v === 'string' ? (streetEN = v) : '')
"
/>
-
{
-
-
{
-
-
{
(zipCode = v.toString())"
- :rules="
- !addressForeign
- ? []
- : [(val) => (val && val.length > 0) || $t('form.error.required')]
+ addrOptions.subDistrictOps
+ ?.filter((x) => x.id === subDistrictId)
+ .map((x) => x.zipCode)[0] ?? ''
"
/>
-import { ref, watch } from 'vue';
-import { dateFormatJS } from 'src/utils/datetime';
-import SelectInput from './SelectInput.vue';
-import VueDatePicker from '@vuepic/vue-datepicker';
-import dayjs from 'dayjs';
-
-defineProps<{
- active?: boolean;
-}>();
-
-const date = defineModel();
-
-const dateRange = ref('');
-const isDateSelect = ref(false);
-
-function mapDateRange(val: string) {
- const today = dayjs();
- let start: dayjs.Dayjs, end: dayjs.Dayjs;
-
- switch (val) {
- case 'toDay':
- start = today.startOf('day');
- end = today.endOf('day');
- break;
- case 'yesterday':
- start = today.subtract(1, 'day').startOf('day');
- end = today.subtract(1, 'day').endOf('day');
- break;
- case 'thisWeek':
- start = today.startOf('week');
- end = today.endOf('week');
- break;
- case 'lastWeek':
- start = today.subtract(1, 'week').startOf('week');
- end = today.subtract(1, 'week').endOf('week');
- break;
- case 'thisMonth':
- start = today.startOf('month');
- end = today.endOf('month');
- break;
- case 'lastMonth':
- start = today.subtract(1, 'month').startOf('month');
- end = today.subtract(1, 'month').endOf('month');
- break;
- case 'thisYear':
- start = today.startOf('year');
- end = today.endOf('year');
- break;
- case 'lastYear':
- start = today.subtract(1, 'year').startOf('year');
- end = today.subtract(1, 'year').endOf('year');
- break;
- case 'last7Days':
- start = today.subtract(6, 'day').startOf('day');
- end = today.endOf('day');
- break;
- case 'last30Days':
- start = today.subtract(29, 'day').startOf('day');
- end = today.endOf('day');
- break;
- case 'last90Days':
- start = today.subtract(89, 'day').startOf('day');
- end = today.endOf('day');
- break;
- case 'customDateRange':
- start = today.startOf('day');
- end = today.endOf('day');
- break;
- default:
- return;
- }
-
- return [start.toDate().toISOString(), end.toDate().toISOString()];
-}
-
-watch(
- () => dateRange.value,
- () => {
- if (!dateRange.value) return;
- date.value = mapDateRange(dateRange.value);
- },
-);
-
-watch(
- () => date.value,
- () => {
- if (date.value && date.value.length === 0) dateRange.value = '';
- },
-);
-
-
-
-
-
-
-
- {{ $t('general.advanceSearch') }}
-
-
(date = [])"
- />
-
- (isDateSelect = true)"
- @closed="() => (isDateSelect = false)"
- >
-
-
-
-
-
-
- {{
- date
- ? dateFormatJS({ date: date[0] }) +
- ' - ' +
- dateFormatJS({ date: date[1] })
- : ''
- }}
-
-
-
-
-
-
-
-
-
-
- {{ $t('general.advanceSearch') }}
-
-
-
diff --git a/src/components/shared/AvatarGroup.vue b/src/components/shared/AvatarGroup.vue
index ed8f63ef..a3f3d85e 100644
--- a/src/components/shared/AvatarGroup.vue
+++ b/src/components/shared/AvatarGroup.vue
@@ -25,11 +25,7 @@ withDefaults(
alt="Image"
/>
-
+
{{ person.name }}
diff --git a/src/components/shared/KebabAction.vue b/src/components/shared/KebabAction.vue
index 7bea6b36..4dd095db 100644
--- a/src/components/shared/KebabAction.vue
+++ b/src/components/shared/KebabAction.vue
@@ -16,7 +16,6 @@ const props = withDefaults(
useUpload?: boolean;
useCancel?: boolean;
useRejectCancel?: boolean;
- useCopy?: boolean;
disableCancel?: boolean;
disableDelete?: boolean;
}>(),
@@ -32,7 +31,6 @@ defineEmits<{
(e: 'link'): void;
(e: 'upload'): void;
(e: 'delete'): void;
- (e: 'copy'): void;
(e: 'cancel'): void;
(e: 'rejectCancel'): void;
(e: 'changeStatus'): void;
@@ -174,27 +172,6 @@ watch(
-
$emit('copy')"
- >
-
-
- {{ $t('general.copy') }}
-
-
-
();
defineEmits<{
@@ -78,10 +76,8 @@ defineEmits<{
/>
string | true)[];
}>(),
@@ -72,7 +70,6 @@ watch(
{
- multiple ? (model = []) : (model = '');
- }
- "
>
diff --git a/src/components/shared/select-muliple/SelectOffice.vue b/src/components/shared/select-muliple/SelectOffice.vue
index 22a0a327..24437cd1 100644
--- a/src/components/shared/select-muliple/SelectOffice.vue
+++ b/src/components/shared/select-muliple/SelectOffice.vue
@@ -72,11 +72,7 @@ onMounted(async () => {
:option="selectOptions"
:hide-selected="false"
:fill-input="false"
- :rules="[
- (v: string) => {
- return !!v?.length || $t('form.error.required');
- },
- ]"
+ :rules="[(v: string) => !!v || $t('form.error.required')]"
@filter="filter"
>
diff --git a/src/components/shared/select/SelectBranch.vue b/src/components/shared/select/SelectBranch.vue
index 6fa6aa8c..b18a1e51 100644
--- a/src/components/shared/select/SelectBranch.vue
+++ b/src/components/shared/select/SelectBranch.vue
@@ -75,9 +75,9 @@ function setDefaultValue() {
-import { ref, onMounted } from 'vue';
-
-import { createSelect, SelectProps } from './select';
-import SelectInput from '../SelectInput.vue';
-
-import { BusinessType } from 'src/stores/business-type/types';
-
-import useStore from 'src/stores/business-type';
-
-type SelectOption = BusinessType;
-
-const value = defineModel('value', {
- required: true,
-});
-const valueOption = defineModel('valueOption', {
- required: false,
-});
-
-const selectOptions = ref([]);
-
-const { fetchList: getList, fetchById: getById } = useStore();
-
-defineEmits<{
- (e: 'create'): void;
-}>();
-
-type ExclusiveProps = {
- lang?: string;
- codeOnly?: boolean;
- selectFirstValue?: boolean;
- branchVirtual?: boolean;
- checkRole?: string[];
-};
-
-const props = defineProps & ExclusiveProps>();
-
-const { getOptions, setFirstValue, getSelectedOption, filter } =
- createSelect(
- {
- value,
- valueOption,
- selectOptions,
- getList: async (query) => {
- const ret = await getList({
- query,
- ...props.params,
- pageSize: 99999,
- });
- if (ret) return ret.result;
- },
- getByValue: async (id) => {
- const ret = await getById(id);
- if (ret) return ret;
- },
- },
- { valueField: 'id' },
- );
-
-onMounted(async () => {
- await getOptions();
-
- if (props.autoSelectOnSingle && selectOptions.value.length === 1) {
- setFirstValue();
- }
-
- if (props.selectFirstValue) {
- setDefaultValue();
- } else await getSelectedOption();
-});
-
-function setDefaultValue() {
- setFirstValue();
-}
-
-
-
-
- {{ (lang ?? $i18n.locale) !== 'eng' ? opt.name : opt.nameEN }}
-
-
-
-
-
-
-
-
- {{ $t('general.add', { text: $t('businessType.title') }) }}
-
-
- {{ creatableDisabledText }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t('general.add', { text: $t('businessType.title') }) }}
-
-
- {{ creatableDisabledText }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t('general.add', { text: $t('menu.manage.businessType') }) }}
-
-
- {{ creatableDisabledText }}
-
-
-
-
-
-
-
-
-
-
-
- {{ (lang ?? $i18n.locale) !== 'eng' ? opt.name : opt.nameEN }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/shared/select/SelectCustomer.vue b/src/components/shared/select/SelectCustomer.vue
index 2e62eba8..f6fbf9cd 100644
--- a/src/components/shared/select/SelectCustomer.vue
+++ b/src/components/shared/select/SelectCustomer.vue
@@ -30,7 +30,6 @@ defineEmits<{
type ExclusiveProps = {
simple?: boolean;
simpleBranchNo?: boolean;
- selectFirstValue?: boolean;
};
const props = defineProps & ExclusiveProps>();
@@ -65,14 +64,8 @@ onMounted(async () => {
setFirstValue();
}
- if (props.selectFirstValue) {
- setDefaultValue();
- } else await getSelectedOption();
+ await getSelectedOption();
});
-
-function setDefaultValue() {
- setFirstValue();
-}
-
+
+
+
@@ -180,11 +175,3 @@ function setDefaultValue() {
-
-
diff --git a/src/components/shared/select/SelectInstitution.vue b/src/components/shared/select/SelectInstitution.vue
index 4b4ea912..bf5877c0 100644
--- a/src/components/shared/select/SelectInstitution.vue
+++ b/src/components/shared/select/SelectInstitution.vue
@@ -43,7 +43,6 @@ const { getOptions, setFirstValue, getSelectedOption, filter } =
const ret = await getList({
query: query === '' ? undefined : query,
...props.params,
- activeOnly: true,
});
if (ret) return ret.result;
},
diff --git a/src/components/shared/select/SelectQuotation.vue b/src/components/shared/select/SelectQuotation.vue
index 344e500b..ae9f7863 100644
--- a/src/components/shared/select/SelectQuotation.vue
+++ b/src/components/shared/select/SelectQuotation.vue
@@ -25,7 +25,6 @@ const { getQuotationList: getList, getQuotation: getById } = useStore();
defineEmits<{
(e: 'create'): void;
- (e: 'selected', value: SelectOption): void;
}>();
type ExclusiveProps = {
@@ -118,14 +117,6 @@ function setDefaultValue() {
(v: string) => !props.required || !!v || $t('form.error.required'),
]"
@filter="filter"
- @update:model-value="
- (v) => {
- $emit(
- 'selected',
- selectOptions.find((opt) => opt.id === v),
- );
- }
- "
>
& ExclusiveProps>();
@@ -72,7 +71,6 @@ function setDefaultValue() {
diff --git a/src/components/shared/select/select.ts b/src/components/shared/select/select.ts
index 11ec46d4..08fd88b2 100644
--- a/src/components/shared/select/select.ts
+++ b/src/components/shared/select/select.ts
@@ -35,13 +35,7 @@ export const createSelect = >(
let previousSearch = '';
watch(value, (v) => {
- if (!v) return;
-
- if (cache && cache.find((opt) => opt[valueField] === v)) {
- valueOption.value = cache.find((opt) => opt[valueField] === v);
- return;
- }
-
+ if (!v || (cache && cache.find((opt) => opt[valueField] === v))) return;
getSelectedOption();
});
@@ -69,26 +63,15 @@ export const createSelect = >(
const currentValue = value.value;
if (!currentValue) return;
-
+ if (selectOptions.value.find((v) => v[valueField] === currentValue)) return;
if (valueOption.value && valueOption.value[valueField] === currentValue) {
- selectOptions.value.unshift(valueOption.value);
- selectOptions.value = selectOptions.value.filter((curr, idx, arr) => {
- return (
- arr.findIndex((item) => item[valueField] === curr[valueField]) === idx
- );
- });
- return;
+ return selectOptions.value.unshift(valueOption.value);
}
const ret = await getByValue(currentValue);
if (ret) {
selectOptions.value.unshift(ret);
- selectOptions.value = selectOptions.value.filter((curr, idx, arr) => {
- return (
- arr.findIndex((item) => item[valueField] === curr[valueField]) === idx
- );
- });
valueOption.value = ret;
}
}
diff --git a/src/components/shared/table/TableProductAndService.vue b/src/components/shared/table/TableProductAndService.vue
index d8e0c683..e1801167 100644
--- a/src/components/shared/table/TableProductAndService.vue
+++ b/src/components/shared/table/TableProductAndService.vue
@@ -251,10 +251,7 @@ function selectedIndex(item: any) {
>
-
- {{ props.row.detail.replace(/<\/?[^>]+(>|$)/g, '') || '-' }}
-
-
+
{{
typeof col.field === 'string'
? props.row[col.field as keyof (Product | Service)]
diff --git a/src/components/shared/table/TableWorker.vue b/src/components/shared/table/TableWorker.vue
index e8cfa214..8594b0e7 100644
--- a/src/components/shared/table/TableWorker.vue
+++ b/src/components/shared/table/TableWorker.vue
@@ -145,7 +145,6 @@ function selectedIndex(item: Employee) {
handleUpdate()"
size="sm"
@@ -201,7 +200,6 @@ function selectedIndex(item: Employee) {
v-model="props.selected"
size="sm"
:id="`select-worker-${props.row.firstName}`"
- :for="`select-worker-${props.row.firstName}`"
/>
diff --git a/src/components/upload-file/FormCitizen.vue b/src/components/upload-file/FormCitizen.vue
index 06c97e6d..5d35209e 100644
--- a/src/components/upload-file/FormCitizen.vue
+++ b/src/components/upload-file/FormCitizen.vue
@@ -188,7 +188,6 @@ function formatCode(input: string | undefined, type: 'code' | 'number') {
:label="$t('customer.form.citizenId')"
for="input-citizen-id"
v-model="citizenId"
- :rules="[(val: string) => !!val || $t('form.error.required')]"
/>
{
@click="$emit('click')"
>
-
-
-
+
{{
uploading.loaded
@@ -80,7 +79,7 @@ onMounted(() => {
/>
{{ idle ? `Pending` : progress !== 1 ? `Uploading...` : 'Completed' }}
-
+
Promise<{
+ ) => void | Promise<{
status: boolean;
group: string;
meta: { name: string; value: string }[];
@@ -123,7 +123,7 @@ async function change(e: Event) {
...obj.value,
{
_meta: structuredClone(toRaw(selectedMenu.value)._meta || {}),
- group: selectedMenu.value?.group,
+ group: selectedMenu.value?.value,
file: renamedFile,
},
];
@@ -168,8 +168,8 @@ async function change(e: Event) {
type: map['doc_type'],
number: map['doc_number'],
gender: map['sex'],
- firstName: map['last_name'],
- lastName: map['first_name'],
+ firstName: map['first_name'],
+ lastName: map['last_name'],
issueDate: map['issue_date'],
expireDate: map['expire_date'],
issuePlace: map['nationality'],
@@ -327,7 +327,7 @@ defineEmits<{
:rows="
obj
.filter((v) => {
- if (!autoSave && v.group !== selectedMenu?.group) {
+ if (!autoSave && v.group !== selectedMenu?.value) {
return false;
}
return true;
diff --git a/src/css/quasar.variables.scss b/src/css/quasar.variables.scss
index eb2b877b..7bd226ac 100644
--- a/src/css/quasar.variables.scss
+++ b/src/css/quasar.variables.scss
@@ -198,10 +198,3 @@ i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-i
.q-focus-helper {
visibility: hidden;
}
-
-.clear-btn {
- opacity: 0.6;
- &:hover {
- opacity: 1;
- }
-}
diff --git a/src/i18n/eng.ts b/src/i18n/eng.ts
index 3379ba60..241621bb 100644
--- a/src/i18n/eng.ts
+++ b/src/i18n/eng.ts
@@ -4,7 +4,7 @@ export default {
save: 'Save',
open: 'Open',
close: 'Close',
- edit: 'Edit{text}',
+ edit: 'Edit',
cancel: 'Cancel',
back: 'Back',
undo: 'Undo',
@@ -31,7 +31,6 @@ export default {
displayField: 'Display Fields',
order: 'Order',
name: '{msg} Name',
- nameEN: 'Name (English)',
fullName: 'Full Name',
detail: '{msg} Detail',
remark: '{msg} Remark',
@@ -61,7 +60,7 @@ export default {
branchStatus: 'Branch Status',
success: 'Success',
taxNo: 'Legal Person',
- contactName: 'Contact Person',
+ contactName: 'Contact Name',
image: 'Image of ',
apply: 'Apply',
licenseNumber: 'License number',
@@ -155,13 +154,6 @@ export default {
draw: 'Draw',
newUpload: 'New Upload',
nativeLanguage: '{msg} Native Language',
- copy: 'Copy',
- paste: 'Paste',
- period: 'Period',
- documentStatus: 'Document Status',
- advanceSearch: 'Advance Search',
- totalPeople: '{meg} people',
- price: 'Price {price} Baht',
},
menu: {
@@ -204,14 +196,12 @@ export default {
title: 'Manage',
branch: 'Branch',
personnel: 'Personnel',
- group: 'Group',
productService: 'Product and Service',
workflow: 'Workflow',
property: 'Property',
customer: 'Customer',
mainData: 'Main Data',
agencies: 'Agencies',
- businessType: 'Business Type',
},
sales: {
@@ -258,8 +248,7 @@ export default {
manual: {
title: 'Manual',
- usage: 'Usage',
- troubleshooting: 'Troubleshooting',
+ usage: 'การใช้งาน',
},
},
@@ -341,7 +330,7 @@ export default {
requireLength: 'Please enter {msg} character',
branchNameField: "Only letters, numbers, or the characters . , - ' &.",
branchNameENField:
- "Only English letters, numbers, or the characters . , - ' &. ( )",
+ "Only English letters, numbers, or the characters . , - ' &.",
passportFormat: 'Please enter the passport number in the correct format.',
},
warning: {
@@ -388,7 +377,7 @@ export default {
branchLabel: 'Branch',
branchHQLabel: 'Headoffice',
taxNo: 'Legal Person',
- contactName: 'Contact Person',
+ contactName: 'Contact Name',
},
page: {
captionManage: 'Manage',
@@ -409,8 +398,8 @@ export default {
code: 'Headoffice Code',
codeBranch: 'Branch Code',
taxNo: 'Tax Identification Number',
- contactName: 'Contact Person',
- contactTelephone: 'Contact Number',
+ contactName: 'Contact Name',
+ contactTelephone: 'Contact Telephone',
branchName: 'Branch Name',
branchNameEN: 'Branch Name (EN)',
servicePointName: 'Service Point Name',
@@ -460,7 +449,7 @@ export default {
regisNo: 'Registration Number',
startDate: 'Start Date',
retireDate: 'Retire Date',
- responsibleArea: 'Responsible Area',
+ responsibleArea: 'Responsibel Area',
discount: 'Discount Condition',
sourceNationality: 'Source Nationality',
importNationality: 'Import Nationality',
@@ -475,9 +464,6 @@ export default {
normal: 'Normal',
canceled: 'Canceled',
blacklist: 'Black list',
- contactName: 'Contact Person',
- contactTel: 'Contact Number',
- addressForeign: 'Use foreign address',
},
},
customer: {
@@ -491,9 +477,10 @@ export default {
powerOfAttorney: 'Power of Attorney',
others: 'Others',
},
+
employer: 'Employer',
employerLegalEntity: 'Legal Entity',
- employerNaturalPerson: 'Natural Person',
+ employerNaturalPerson: 'Natrual Person',
employerType: 'Employer Type',
employee: 'Employee',
form: {
@@ -503,22 +490,24 @@ export default {
},
prefix: {
- mr: 'MR.',
- mrs: 'MRS.',
- miss: 'MISS.',
+ mr: 'Mr.',
+ mrs: 'Mrs.',
+ miss: 'Miss.',
},
- taxpayyerNo: 'Taxpayer Identification Number',
citizenId: 'Citizen ID',
religion: 'Religion',
issueDate: 'Issue Date',
passportExpiryDate: 'Passport Expiry Date',
+
ownerName: 'Customer Name',
firstName: 'First Name ',
lastName: 'Last Name ',
firstNameEN: 'First Name in English',
lastNameEN: 'Last Name in English',
+
cardNumber: 'ID Card Number',
+
prefixName: 'Prefix',
legalPersonNo: 'Legal Entity Registration Number',
registerName: 'Company Name',
@@ -526,6 +515,7 @@ export default {
registerDate: 'Registered On',
registerCompanyName: 'Registered Name',
authorizedCapital: 'Authorized Capital',
+
workplace: 'Workplace',
workplaceEN: 'Workplace (EN)',
address: 'Address',
@@ -533,6 +523,7 @@ export default {
branchCode: 'Branch Code',
customerCode: 'Employer Code',
legalPersonCode: 'Legal Entity Code',
+
codeAbbrev: 'Company Abbreviation',
codeNumber: 'Company Number',
registeredBranch: 'Registered Branch',
@@ -570,7 +561,7 @@ export default {
jobPosition: 'Job Position',
address: 'Address',
workPlace: 'Workplace',
- contactName: 'Contact Person',
+ contactName: 'Contact Name',
contactPhone: 'Contact Phone',
totalEmployee: 'Total Employee',
officeTel: 'Headoffice Telephone',
@@ -624,7 +615,7 @@ export default {
placeOfBirth: 'Place of Birth',
countryOfbirth: 'Country of Birth',
issueCountry: 'Issue Country',
- entryCount: 'Number of Days in the Country',
+ entryCount: 'Entry Count',
employerSelect: {
branchName: 'Branch Name',
customerName: 'Employer Name',
@@ -774,13 +765,10 @@ export default {
},
quotation: {
- ownOnly: 'View Own Quotation Only',
quotationDate: 'Quotation Date',
seller: 'Seller',
paymentChannels: 'Payment Channels',
channelsThat: 'Channels That',
- refNo: 'Reference Number',
- bankAccount: 'Bank Account',
bankAccountNumber: 'Bank Account Number',
bankAccountName: 'Bank Account Name',
inTheNameOf: 'In The Name Of',
@@ -811,7 +799,7 @@ export default {
employee: 'Employee',
employeeName: 'Full Name',
workName: 'Work Name',
- contactName: 'Contact Person',
+ contactName: 'Contact Name',
documentReceivePoint: 'Document Drop-Off Point"',
dueDate: 'Quotation Due Date',
specialCondition: 'Special Conditions',
@@ -929,10 +917,9 @@ export default {
code: 'Agencies Code',
group: 'Agencies Group',
name: 'Agencies Name',
- contactName: 'Contact Person',
- contactTel: 'Contact Number',
+ contactName: 'Contact Name',
+ contactTel: 'Contact Telephone',
bankInfo: 'Bank Information',
- attachment: 'Attachment',
},
requestList: {
@@ -954,9 +941,8 @@ export default {
localEmployee: 'Local Employee',
nonLocalEmployee: 'Non Local Employee',
noWorkflowTemplate: 'A workflow template has not been selected.',
- salesRepresentative: 'Sales Representative',
- dataOffice: 'Employment Office District',
+ salesRepresentative: 'Sales Representative',
ref: 'Reference',
action: {
title: 'Action',
@@ -1020,7 +1006,7 @@ export default {
issueBranch: 'Issue Branch',
issueDate: 'Issue Date',
madeBy: 'Made By',
- contactName: 'Contact Person',
+ contactName: 'Contact Name',
workOrderCode: 'Work Order Code',
workOrderName: 'Work Order Name',
telephone: 'Telephone',
@@ -1079,10 +1065,6 @@ export default {
confirmDebitNoteAccept: 'Confirm acceptance of the debit note.',
},
message: {
- copy: 'Copy',
- warningPaste:
- 'Do you want to replace the data with the newly copied information?',
- warningCopyEmpty: 'You have not copied any data yet',
quotationAccept: 'Once accepted, no further modifications can be made',
beingUse: '"{msg}" is being used.',
incompleteDataEntry: 'Incomplete data entry on {tap} page',
@@ -1127,7 +1109,7 @@ export default {
oneOrMoreBranchMissing:
'One or more branch cannot be delete and is missing.',
cantMakeHQAndBranchSameTime:
- 'Cannot make this as headquarters and branch at the same time.',
+ 'Cannot make this as headquaters and branch at the same time.',
unknowHowToVerify: 'Unknown how to verify identity.',
noPermission:
'You do not have permission to access or perform with this resource.',
@@ -1234,9 +1216,6 @@ export default {
taskListNotPending: 'One or more task is not pending.',
reqNotMet: 'Not Match',
systemError: 'A system error occurred.',
- taskOrderInvalid: 'Please select the product and the organization.',
-
- flowAccountProductIdNotFound: 'Product not found in flow account',
},
},
@@ -1506,26 +1485,4 @@ export default {
type: 'Type',
},
},
-
- dateRange: {
- today: 'Today',
- yesterday: 'Yesterday',
- thisWeek: 'This Week',
- lastWeek: 'Last Week',
- thisMonth: 'This Month',
- lastMonth: 'Last Month',
- thisYear: 'This Year',
- lastYear: 'Last Year',
- last7Days: 'Last 7 Days',
- last30Days: 'Last 30 Days',
- last90Days: 'Last 90 Days',
- customDateRange: 'Custom Date Range',
- },
-
- businessType: {
- title: 'Business Type',
- caption: 'Manage Business Type',
- name: 'Business Type Name',
- nameEn: 'Business Type Name (English)',
- },
};
diff --git a/src/i18n/tha.ts b/src/i18n/tha.ts
index 921e25fd..19915334 100644
--- a/src/i18n/tha.ts
+++ b/src/i18n/tha.ts
@@ -4,7 +4,7 @@ export default {
save: 'บันทึก',
open: 'เปิด',
close: 'ปิด',
- edit: 'แก้ไข{text}',
+ edit: 'แก้ไข',
cancel: 'ยกเลิก',
back: 'ย้อนกลับ',
undo: 'ย้อนกลับ',
@@ -31,7 +31,6 @@ export default {
displayField: 'ฟิลด์แสดงผล',
order: 'ลำดับ',
name: 'ชื่อ{msg}',
- nameEN: 'ชื่อ (ภาษาอังกฤษ)',
fullName: 'ชื่อ-สกุล',
detail: 'รายละเอียด{msg}',
remark: 'หมายเหตุ{msg}',
@@ -155,13 +154,6 @@ export default {
draw: 'วาด',
newUpload: 'อัปโหลดใหม่',
nativeLanguage: '{msg} ภาษาต้นทาง',
- copy: 'คัดลอก',
- paste: 'วาง',
- period: 'ช่วงเวลา',
- documentStatus: 'สถานะเอกสาร',
- advanceSearch: 'ค้นหาขั้นสูง',
- totalPeople: '{meg} คน',
- price: 'ราคา {price} บาท',
},
menu: {
@@ -204,14 +196,12 @@ export default {
title: 'จัดการ',
branch: 'สาขา',
personnel: 'บุคลากร',
- group: 'กลุ่ม',
productService: 'สินค้าและบริการ',
workflow: 'ขั้นตอนการทำงาน',
property: 'คุณสมบัติ',
customer: 'ลูกค้า',
mainData: 'ข้อมูลหลัก',
agencies: 'หน่วยงาน',
- businessType: 'ประเภทกิจการ',
},
sales: {
@@ -259,7 +249,6 @@ export default {
manual: {
title: 'คู่มือ',
usage: 'การใช้งาน',
- troubleshooting: 'การแก้ปัญหา',
},
},
@@ -338,7 +327,7 @@ export default {
letterAndNumOnly: 'โปรดใช้เฉพาะ _ ตัวอักษรภาษาอังกฤษและตัวเลขเท่านั้น',
numOnly: 'โปรดใช้เฉพาะตัวเลขเท่านั้น',
requireLength: 'กรุณากรอกให้ครบ {msg} หลัก',
- branchNameField: "โปรดใช้ตัวอักษร ตัวเลข หรือ . , - ' ( ) & เท่านั้น",
+ branchNameField: "โปรดใช้ตัวอักษร ตัวเลข หรือ . , - ' & เท่านั้น",
branchNameENField:
"โปรดใช้ตัวอักษรภาษาอังกฤษ ตัวเลข หรือ . , - ' & เท่านั้น",
passportFormat: 'กรุณากรอกหมายเลขพาสปอร์ตให้ถูกต้องตามรูปแบบ',
@@ -467,13 +456,10 @@ export default {
citizenId: 'เลขที่บัตรประชาชน',
citizenIssue: 'วันที่ออกบัตร',
citizenExpire: 'วันที่หมดอายุ',
- agencyStatus: 'สถานะเอเจนซี่',
+ agencyStatus: 'สถานะการเป็นเอเจนซี่',
normal: 'ปกติ',
canceled: 'ยกเลิก',
blacklist: 'แบล็คลิสต์',
- contactName: 'ชื่อผู้ติดต่อ',
- contactTel: 'เบอร์โทรศัพท์ผู้ติดต่อ',
- addressForeign: 'ใช้ที่อยู่ต่างประเทศ',
},
},
customer: {
@@ -500,16 +486,15 @@ export default {
},
prefix: {
- mr: 'นาย',
- mrs: 'นาง',
- miss: 'นางสาว',
+ mr: 'Mr.',
+ mrs: 'Mrs.',
+ miss: 'Miss.',
},
citizenId: 'บัตรประจำตัวประชาชน',
religion: 'ศาสนา',
issueDate: 'วันที่ออกหนังสือ',
passportExpiryDate: 'วันหiมดอายุหนังสือเดินทาง',
- taxpayyerNo: 'เลขที่ประจำตัวผู้เสียภาษี',
ownerName: 'ชื่อนายจ้าง',
firstName: 'ชื่อ ',
@@ -593,7 +578,7 @@ export default {
family: 'ข้อมูลครอบครัว',
},
workerStatus: 'สถานะคนงาน',
- previousPassportNumber: 'หมายเลขหนังสือเดินทางเล่มเก่า',
+ previousPassportNumber: 'หมายเลขอันเก่าหนังสือเดินทาง',
employerBranch: 'สาขานายจ้าง',
employeeCode: 'รหัสลูกจ้าง',
nrcNo: 'เลขบัตรประจำตัวคนซึ่งไม่มีสัญชาติไทย (N.R.C No.)',
@@ -626,7 +611,7 @@ export default {
placeOfBirth: 'สถานที่เกิด',
countryOfbirth: 'ประเทศที่เกิด',
issueCountry: 'ประเทศที่ออก',
- entryCount: 'จำนวนวันที่เข้าประเทศ',
+ entryCount: 'จำนวนที่เข้าประเทศ',
employerSelect: {
branchName: 'ชื่อสาขา',
customerName: 'ชื่อนายจ้าง',
@@ -654,7 +639,7 @@ export default {
permitIssuedAt: 'สถานที่ออกใบอนุญาต',
permitIssueDate: 'วันที่ออกใบอนุญาตทำงาน',
permitExpireDate: 'วันที่หมดอายุใบอนุญาตทำงาน',
- identityNo: 'เลขประจำตัวคนต่างด้าว (13 หลัก)',
+ identityNo: 'เลขประจำตัวคนต่างด้าว (13หลัก)',
},
formFamily: {
citizenId:
@@ -772,13 +757,10 @@ export default {
},
quotation: {
- ownOnly: 'เห็นเฉพาะใบเสนอราคาของตัวเอง',
quotationDate: 'วันที่ใบเสนอราคา',
seller: 'ผู้ขาย',
paymentChannels: 'ช่องทางชำระเงิน',
channelsThat: 'ช่องทางที่',
- refNo: 'เลขที่อ้างอิง',
- bankAccount: 'บัญชีธนาคาร',
bankAccountNumber: 'เลขบัญชีธนาคาร',
bankAccountName: 'ชื่อบัญชี',
inTheNameOf: 'ในนาม',
@@ -803,7 +785,7 @@ export default {
branch: 'สาขาที่ออกใบเสนอราคา',
branchVirtual: 'จุดรับบริการที่ออกใบเสนอราคา',
customer: 'ลูกค้า',
- newCustomer: 'แรงงานใหม่',
+ newCustomer: 'ลูกค้าใหม่',
employeeList: 'รายชื่อแรงงาน',
employee: 'แรงงาน',
employeeName: 'ชื่อ-นามสกุล แรงงาน',
@@ -929,7 +911,6 @@ export default {
contactName: 'ชื่อผู้ติดต่อ',
contactTel: 'เบอร์โทรผู้ติดต่อ',
bankInfo: 'ข้อมูลธนาคาร',
- attachment: 'เอกสารเพิ่มเติม',
},
requestList: {
@@ -951,7 +932,6 @@ export default {
nonLocalEmployee: 'พนักงานนอกพื้นที่',
noWorkflowTemplate: 'คุณไม่ได้เลือกแม่แบบขั้นตอนการทำงาน',
salesRepresentative: 'พนักงานขาย',
- dataOffice: 'สำนักงานเขตจัดหางาน',
ref: 'อ้างอิง',
action: {
title: 'จัดการ',
@@ -1070,9 +1050,6 @@ export default {
confirmDebitNoteAccept: 'ยืนยันการตอบรับใบเพิ่มหนี้',
},
message: {
- copy: 'คัดลอก',
- warningPaste: 'คุณต้องการที่จะเเทนที่ข้อมูลที่คัดลอกมาใหม่ใช่หรือไม่',
- warningCopyEmpty: 'คุณยังไม่ได้คัดลอกข้อมูล',
quotationAccept: 'เมื่อตอบรับเเล้วจะไม่สามารถแก้ไขได้อีก',
beingUse: '"{msg}" มีการใช้งานอยู่',
incompleteDataEntry: 'กรอกข้อมูลไม่ครบในหน้า {tap}',
@@ -1220,8 +1197,6 @@ export default {
'มีงานหนึ่งงานหรือมากกว่าที่ไม่อยู่ในสถานะรอดำเนินการ',
reqNotMet: 'ไม่ตรงกัน',
systemError: 'ระบบเกิดข้อผิดพลาด',
- taskOrderInvalid: 'โปรดเลือก สินค้าเเละสาขา',
- flowAccountProductIdNotFound: 'ไม่พบสินค้าใน flow account',
},
},
@@ -1493,26 +1468,4 @@ export default {
type: 'ประเภท',
},
},
-
- dateRange: {
- today: 'วันนี้',
- yesterday: 'เมื่อวานนี้',
- thisWeek: 'สัปดาห์นี้',
- lastWeek: 'สัปดาห์ที่แล้ว',
- thisMonth: 'เดือนนี้',
- lastMonth: 'เดือนที่แล้ว',
- thisYear: 'ปีนี้',
- lastYear: 'ปีที่แล้ว',
- last7Days: '7 วันที่ผ่านมา',
- last30Days: '30 วันที่ผ่านมา',
- last90Days: '90 วันที่ผ่านมา',
- customDateRange: 'กำหนดช่วงวันที่เอง',
- },
-
- businessType: {
- title: 'ประเภทกิจการ',
- caption: 'จัดการประเภทกิจการ',
- name: 'ชื่อประเภทกิจการ',
- nameEn: 'ชื่อประเภทกิจการ (ภาษาอังกฤษ)',
- },
};
diff --git a/src/layouts/DrawerComponent.vue b/src/layouts/DrawerComponent.vue
index d7a70d33..c1b01436 100644
--- a/src/layouts/DrawerComponent.vue
+++ b/src/layouts/DrawerComponent.vue
@@ -7,7 +7,7 @@ import useMyBranch from 'stores/my-branch';
import { getUserId, getRole } from 'src/services/keycloak';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
-import { canAccess } from 'src/stores/utils';
+import { isRoleInclude } from 'src/stores/utils';
type Menu = {
label: string;
@@ -71,50 +71,82 @@ function initMenu() {
{
label: 'branch',
route: '/branch-management',
- hidden: !canAccess('branch'),
+ hidden: !isRoleInclude([
+ 'system',
+ 'head_of_admin',
+ 'admin',
+ 'branch_manager',
+ 'head_of_accountant',
+ ]),
},
{
label: 'personnel',
route: '/personnel-management',
- hidden: !canAccess('personnel'),
- },
- {
- label: 'group',
- route: '/group-management',
- hidden: !canAccess('personnel'),
+ hidden: !isRoleInclude([
+ 'owner',
+ 'system',
+ 'head_of_admin',
+ 'admin',
+ 'branch_manager',
+ ]),
},
{
label: 'workflow',
route: '/workflow',
- hidden: !canAccess('workflow'),
+ hidden: !isRoleInclude(['system', 'head_of_admin', 'admin']),
},
{
label: 'property',
route: '/property',
- hidden: !canAccess('workflow'),
- },
- {
- label: 'businessType',
- route: '/business-type',
+ hidden: !isRoleInclude(['system', 'head_of_admin', 'admin']),
},
{
label: 'productService',
route: '/product-service',
+ hidden: !isRoleInclude([
+ 'system',
+ 'head_of_admin',
+ 'admin',
+ 'branch_manager',
+ 'head_of_accountant',
+ 'head_of_sale',
+ 'sale',
+ ]),
},
{
label: 'customer',
route: '/customer-management',
- hidden: !canAccess('customer'),
+ hidden: !isRoleInclude([
+ 'system',
+ 'head_of_admin',
+ 'admin',
+ 'branch_manager',
+ 'head_of_accountant',
+ 'accountant',
+ 'head_of_sale',
+ 'sale',
+ ]),
},
{
label: 'agencies',
route: '/agencies-management',
+ hidden: !isRoleInclude(['system', 'head_of_admin', 'admin']),
},
],
},
{
label: 'menu.sales',
icon: 'mdi-store-settings-outline',
+ hidden: !isRoleInclude([
+ 'system',
+ 'head_of_admin',
+ 'admin',
+ 'branch_manager',
+ 'head_of_accountant',
+ 'accountant',
+ 'head_of_sale',
+ 'sale',
+ ]),
children: [
{ label: 'quotation', route: '/quotation' },
{ label: 'invoice', route: '/invoice' },
@@ -137,6 +169,16 @@ function initMenu() {
label: 'menu.account',
icon: 'mdi-bank-outline',
disabled: false,
+ hidden: !isRoleInclude([
+ 'system',
+ 'head_of_admin',
+ 'admin',
+ 'branch_manager',
+ 'head_of_accountant',
+ 'accountant',
+ 'head_of_sale',
+ 'sale',
+ ]),
children: [
{ label: 'receipt', route: '/receipt' },
{ label: 'creditNote', route: '/credit-note' },
@@ -158,13 +200,10 @@ function initMenu() {
{
label: 'menu.overall',
icon: 'mdi-monitor-dashboard',
+ hidden: !isRoleInclude(['system', 'head_of_admin', 'admin', 'executive']),
children: [
{ label: 'report', route: '/report' },
- {
- label: 'dashboard',
- route: '/dash-board',
- hidden: !canAccess('dashBoard'),
- },
+ { label: 'dashboard', route: '/dash-board' },
],
},
@@ -176,10 +215,6 @@ function initMenu() {
label: 'usage',
route: '/manual',
},
- {
- label: 'troubleshooting',
- route: '/troubleshooting',
- },
],
},
];
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index 29e106bc..c09effed 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -2,7 +2,7 @@
import { ref, onMounted, computed, reactive } from 'vue';
import { storeToRefs } from 'pinia';
import { useQuasar } from 'quasar';
-import { getUserId, getUsername, getName, logout, getRole } from 'src/services/keycloak';
+import { getUserId, getUsername, logout, getRole } from 'src/services/keycloak';
import { Icon } from '@iconify/vue';
import { useI18n } from 'vue-i18n';
import moment from 'moment';
@@ -39,7 +39,7 @@ const configStore = useConfigStore();
const { data: notificationData } = storeToRefs(notificationStore);
const { visible } = storeToRefs(loaderStore);
-const { t, locale } = useI18n({ useScope: 'global' });
+const { t } = useI18n({ useScope: 'global' });
const userStore = useUserStore();
const canvasModal = ref(false);
@@ -52,14 +52,8 @@ const unread = computed(
);
const userImage = ref();
const userGender = ref('');
-const userName = ref({ th: '', en: '' });
const canvasRef = ref();
-const displayName = computed(() => {
- if (!userName.value.th && !userName.value.en) return getName() || 'Guest';
- return locale.value === 'eng' ? userName.value.en : userName.value.th;
-});
-
const language: {
value: Lang;
label: string;
@@ -167,14 +161,9 @@ onMounted(async () => {
if (user === 'admin') return;
if (uid) {
const res = await userStore.fetchById(uid);
- if (res) {
- if (res.gender) {
- userGender.value = res.gender;
- userImage.value = `${baseUrl}/user/${uid}/profile-image/${res.selectedImage}`;
- }
- // เก็บชื่อทั้งสองภาษา
- userName.value.th = `${res.firstName || ''} ${res.lastName || ''}`.trim();
- userName.value.en = `${res.firstNameEN || ''} ${res.lastNameEN || ''}`.trim();
+ if (res && res.gender) {
+ userGender.value = res.gender;
+ userImage.value = `${baseUrl}/user/${uid}/profile-image/${res.selectedImage}`;
}
}
});
@@ -495,7 +484,6 @@ onMounted(async () => {
{
style="margin-top: 58px"
>
- {{ userName || getName() }}
+ {{ getName() }}
{{ 'Guest' }}
- {{ userName || getName() }}
+ {{ getName() }}
{{ 'Guest' }}
diff --git a/src/pages/00_manual/MainPage.vue b/src/pages/00_manual/MainPage.vue
index 33a19ebe..adcb668f 100644
--- a/src/pages/00_manual/MainPage.vue
+++ b/src/pages/00_manual/MainPage.vue
@@ -1,7 +1,7 @@
@@ -56,7 +34,7 @@ watch(
>
diff --git a/src/pages/03_customer-management/components/employer/EmployerFormBranch.vue b/src/pages/03_customer-management/components/employer/EmployerFormBranch.vue
index 14f7aa98..1b70b651 100644
--- a/src/pages/03_customer-management/components/employer/EmployerFormBranch.vue
+++ b/src/pages/03_customer-management/components/employer/EmployerFormBranch.vue
@@ -7,8 +7,6 @@ import { CustomerCreate } from 'stores/customer/types';
import EmployerFormAbout from './EmployerFormAbout.vue';
import EmployerFormAuthorized from './EmployerFormAuthorized.vue';
import { waitAll } from 'src/stores/utils';
-import FormEmployeePassport from 'src/components/03_customer-management/FormEmployeePassport.vue';
-import FormEmployeeVisa from 'src/components/03_customer-management/FormEmployeeVisa.vue';
import {
FormCitizen,
CorpFormBusinessRegistration,
@@ -53,7 +51,6 @@ withDefaults(
actionDisabled?: boolean;
customerType?: 'CORP' | 'PERS';
hideAction?: boolean;
- hideDelete?: boolean;
}>(),
{
hideAction: false,
@@ -84,7 +81,7 @@ withDefaults(
/>
(businessTypeDialog = true)"
- />
-
+
+
+
+ {{ $t('general.noData') }}
+
+
+
+
+ (businessTypeDialog = true)"
- />
+ >
+
+
+
+ {{ $t('general.noData') }}
+
+
+
+
-
-
diff --git a/src/pages/03_customer-management/components/employer/EmployerFormContact.vue b/src/pages/03_customer-management/components/employer/EmployerFormContact.vue
index 7f56742c..4a58439c 100644
--- a/src/pages/03_customer-management/components/employer/EmployerFormContact.vue
+++ b/src/pages/03_customer-management/components/employer/EmployerFormContact.vue
@@ -9,6 +9,8 @@ const contactName = defineModel
('contactName');
const email = defineModel('email');
const contactTel = defineModel('contactTel');
const officeTel = defineModel('officeTel');
+const agent = defineModel('agent');
+
const agentUserId = defineModel('agentUserId');
@@ -107,6 +109,7 @@ const agentUserId = defineModel('agentUserId');
/>
+
{
const customerStore = useCustomerStore();
- const onCreateImageList = ref<{
- selectedImage: string;
- list: { url: string; imgFile: File | null; name: string }[];
- }>({ selectedImage: '', list: [] });
const { t } = useI18n();
const flowStore = useFlowStore();
@@ -34,13 +30,11 @@ export const useCustomerForm = defineStore('form-customer', () => {
const registerAbleBranchOption = ref<{ id: string; name: string }[]>();
- const currentBranchRootId = ref('');
-
const tabFieldRequired = ref<{
[key: string]: (keyof CustomerBranchCreate)[];
}>({
main: [],
- business: ['businessTypeId', 'jobPosition'],
+ business: ['businessType', 'jobPosition'],
address: [
'address',
'addressEN',
@@ -88,7 +82,6 @@ export const useCustomerForm = defineStore('form-customer', () => {
formDataOcr: Record;
isImageEdit: boolean;
currentCustomerId?: string;
- imageList: { list: string[]; selectedImage: string };
}>({
dialogType: 'info',
dialogOpen: false,
@@ -105,7 +98,6 @@ export const useCustomerForm = defineStore('form-customer', () => {
treeFile: [],
formDataOcr: {},
isImageEdit: false,
- imageList: { list: [], selectedImage: '' },
});
watch(
@@ -168,7 +160,6 @@ export const useCustomerForm = defineStore('form-customer', () => {
state.value.editCustomerCode = data.code;
state.value.customerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`;
state.value.defaultCustomerImageUrl = `${baseUrl}/customer/${id}/image/${data.selectedImage}`;
- currentBranchRootId.value = data.branch[0].id || '';
resetFormData.registeredBranchId = data.registeredBranchId;
resetFormData.status = data.status;
@@ -190,7 +181,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
payDate: v.payDate,
jobDescription: v.jobDescription,
jobPosition: v.jobPosition,
- businessTypeId: v.businessTypeId,
+ businessType: v.businessType,
employmentOffice: v.employmentOffice,
employmentOfficeEN: v.employmentOfficeEN,
telephoneNo: v.telephoneNo,
@@ -227,6 +218,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
contactTel: v.contactTel,
officeTel: v.officeTel,
agentUserId: v.agentUserId || undefined,
+ customerName: v.customerName,
authorizedName: v.authorizedName,
authorizedNameEN: v.authorizedNameEN,
@@ -264,6 +256,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
async function addCurrentCustomerBranch() {
if (currentFormData.value.customerBranch?.some((v) => !v.id)) return;
currentFormData.value.customerBranch?.push({
+ id: '',
customerId: '',
branchCode:
currentFormData.value.customerBranch.length !== 0
@@ -297,8 +290,8 @@ export const useCustomerForm = defineStore('form-customer', () => {
birthDate:
currentFormData.value.customerBranch?.at(0)?.birthDate || undefined,
- businessTypeId:
- currentFormData.value.customerBranch?.at(0)?.businessTypeId || '',
+ businessType:
+ currentFormData.value.customerBranch?.at(0)?.businessType || '',
jobPosition:
currentFormData.value.customerBranch?.at(0)?.jobPosition || '',
jobDescription:
@@ -335,6 +328,8 @@ export const useCustomerForm = defineStore('form-customer', () => {
currentFormData.value.customerBranch?.at(0)?.agentUserId || undefined,
status: 'CREATED',
+ customerName:
+ currentFormData.value.customerBranch?.at(0)?.customerName || '',
registerName:
currentFormData.value.customerBranch?.at(0)?.registerName || '',
registerNameEN:
@@ -503,14 +498,11 @@ export const useCustomerForm = defineStore('form-customer', () => {
}
return {
- onCreateImageList,
tabFieldRequired,
registerAbleBranchOption,
state,
resetFormData,
currentFormData,
- currentBranchRootId,
-
isFormDataDifferent,
resetForm,
assignFormData,
@@ -549,7 +541,7 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
gender: '',
birthDate: undefined,
- businessTypeId: '',
+ businessType: '',
jobPosition: '',
jobDescription: '',
payDate: '',
@@ -579,6 +571,7 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
agentUserId: undefined,
status: 'CREATED',
+ customerName: '',
registerName: '',
registerNameEN: '',
registerDate: undefined,
@@ -630,7 +623,7 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
payDateEN: _data.payDateEN,
jobDescription: _data.jobDescription,
jobPosition: _data.jobPosition,
- businessTypeId: _data.businessTypeId,
+ businessType: _data.businessType,
employmentOffice: _data.employmentOffice,
employmentOfficeEN: _data.employmentOfficeEN,
telephoneNo: _data.telephoneNo,
@@ -664,6 +657,7 @@ export const useCustomerBranchForm = defineStore('form-customer-branch', () => {
officeTel: _data.officeTel,
agentUserId: _data.agentUserId || undefined,
codeCustomer: _data.codeCustomer,
+ customerName: _data.customerName,
homeCode: _data.homeCode,
authorizedName: _data.authorizedName,
authorizedNameEN: _data.authorizedNameEN,
@@ -790,7 +784,6 @@ export const useEmployeeForm = defineStore('form-employee', () => {
}
| undefined;
ocr: boolean;
- imageList: { list: string[]; selectedImage: string };
}>({
currentBranchId: '',
isImageEdit: false,
@@ -815,10 +808,9 @@ export const useEmployeeForm = defineStore('form-employee', () => {
infoEmployeePersonCard: [],
formDataEmployeeOwner: undefined,
ocr: false,
- imageList: { list: [], selectedImage: '' },
});
- const defaultFormData: EmployeeCreate & { image?: File } = {
+ const defaultFormData: EmployeeCreate = {
id: '',
code: '',
customerBranchId: '',
@@ -900,7 +892,6 @@ export const useEmployeeForm = defineStore('form-employee', () => {
expireDate: new Date(),
remark: undefined,
workerType: '',
- reportDate: null,
number: '',
},
],
@@ -946,7 +937,7 @@ export const useEmployeeForm = defineStore('form-employee', () => {
};
let resetEmployeeData = structuredClone(defaultFormData);
- const currentFromDataEmployee = ref(
+ const currentFromDataEmployee = ref(
structuredClone(defaultFormData),
);
@@ -968,14 +959,12 @@ export const useEmployeeForm = defineStore('form-employee', () => {
state.value.currentIndexVisa = -1;
state.value.currentIndexCheckup = -1;
state.value.currentIndexWorkHistory = -1;
- state.value.imageList = { list: [], selectedImage: '' };
- // state.value.currentTab = 'personalInfo';
+ state.value.currentTab = 'personalInfo';
if (clean) {
state.value.formDataEmployeeOwner = undefined;
resetEmployeeData = structuredClone(defaultFormData);
state.value.statusSavePersonal = false;
state.value.profileUrl = '';
- state.value.currentBranchId = '';
} else {
resetEmployeeData.selectedImage =
currentFromDataEmployee.value.selectedImage;
@@ -996,16 +985,12 @@ export const useEmployeeForm = defineStore('form-employee', () => {
state.value.currentIndexPassport
].id === undefined
) {
- const { id, employeeId, updatedAt, createdAt, file, ...payload } =
- currentFromDataEmployee.value.employeePassport?.[
- state.value.currentIndexPassport
- ];
-
const res = await employeeStore.postMeta({
parentId: currentFromDataEmployee.value.id || '',
group: 'passport',
- meta: payload,
- file: file,
+ meta: currentFromDataEmployee.value.employeePassport?.[
+ state.value.currentIndexPassport
+ ],
});
if (res) {
@@ -1019,7 +1004,7 @@ export const useEmployeeForm = defineStore('form-employee', () => {
state.value.currentIndexPassport
].id !== undefined
) {
- const { id, employeeId, updatedAt, createdAt, file, ...payload } =
+ const { id, employeeId, updatedAt, createdAt, ...payload } =
currentFromDataEmployee.value.employeePassport?.[
state.value.currentIndexPassport
];
@@ -1032,7 +1017,6 @@ export const useEmployeeForm = defineStore('form-employee', () => {
state.value.currentIndexPassport
].id || '',
meta: payload,
- file: file || undefined,
});
}
@@ -1260,7 +1244,7 @@ export const useEmployeeForm = defineStore('form-employee', () => {
await assignFormDataEmployee(currentFromDataEmployee.value.id);
}
- async function submitPersonal(imgList?: {
+ async function submitPersonal(imgList: {
selectedImage: string;
list: { url: string; imgFile: File | null; name: string }[];
}) {
@@ -1281,7 +1265,6 @@ export const useEmployeeForm = defineStore('form-employee', () => {
currentFromDataEmployee.value.lastNameEN.trim();
if (state.value.dialogType === 'create') {
- delete currentFromDataEmployee.value.image;
const res = await employeeStore.create(
{
...currentFromDataEmployee.value,
@@ -1310,7 +1293,7 @@ export const useEmployeeForm = defineStore('form-employee', () => {
state.value.currentEmployee?.status === 'CREATED'
? 'ACTIVE'
: state.value.currentEmployee?.status,
- customerBranchId: state.value.currentBranchId || '',
+ customerBranchId: state.value.formDataEmployeeOwner?.id || '',
employeeWork: [],
employeeCheckup: [],
employeeOtherInfo: undefined,
@@ -1398,10 +1381,12 @@ export const useEmployeeForm = defineStore('form-employee', () => {
statusSave: true,
})),
),
- employeeOtherInfo: structuredClone({
- ...(payload.employeeOtherInfo ?? {}),
- statusSave: true,
- }),
+ employeeOtherInfo: structuredClone(
+ {
+ ...payload.employeeOtherInfo,
+ statusSave: !!payload.employeeOtherInfo?.id ? true : false,
+ } || {},
+ ),
employeeWork: structuredClone(
payload.employeeWork?.length === 0
? state.value.dialogModal
@@ -1550,7 +1535,6 @@ export const useEmployeeForm = defineStore('form-employee', () => {
expireDate: new Date(),
remark: undefined,
workerType: '',
- reportDate: null,
number: '',
});
@@ -1675,7 +1659,6 @@ export const useEmployeeForm = defineStore('form-employee', () => {
state,
currentFromDataEmployee,
resetEmployeeData,
-
addPassport,
addVisa,
addCheckup,
diff --git a/src/pages/04_flow-managment/FlowDialog.vue b/src/pages/04_flow-managment/FlowDialog.vue
index 42c429ba..77d8bd12 100644
--- a/src/pages/04_flow-managment/FlowDialog.vue
+++ b/src/pages/04_flow-managment/FlowDialog.vue
@@ -43,7 +43,6 @@ withDefaults(
defineProps<{
readonly?: boolean;
isEdit?: boolean;
- hideAction?: boolean;
}>(),
{ readonly: false, isEdit: false },
);
@@ -61,7 +60,6 @@ async function addStep() {
flowData.value.step.push({
responsibleInstitution: [],
responsiblePersonId: [],
- responsibleGroup: [],
value: [],
detail: '',
name: '',
@@ -168,7 +166,6 @@ function triggerPropertiesDialog(step: WorkFlowPayloadStep) {
id="flow-form-dialog"
>
import { onMounted, reactive, ref, watch } from 'vue';
-import { QTableProps } from 'quasar';
+import { QSelect, QTableProps } from 'quasar';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
@@ -11,7 +11,7 @@ import {
} from 'src/stores/workflow-template/types';
import { useWorkflowTemplate } from 'src/stores/workflow-template';
import { useNavigator } from 'src/stores/navigator';
-import { dialog, canAccess } from 'src/stores/utils';
+import { dialog } from 'src/stores/utils';
import FloatingActionButton from 'components/FloatingActionButton.vue';
import StatCardComponent from 'src/components/StatCardComponent.vue';
@@ -22,7 +22,6 @@ import NoData from 'src/components/NoData.vue';
import KebabAction from 'src/components/shared/KebabAction.vue';
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import { useQuasar } from 'quasar';
-import AdvanceSearch from 'src/components/shared/AdvanceSearch.vue';
const { t } = useI18n();
const workflowStore = useWorkflowTemplate();
@@ -46,7 +45,6 @@ const pageState = reactive({
addModal: false,
viewDrawer: false,
isDrawerEdit: true,
- searchDate: [],
});
const fieldSelected = ref<('order' | 'name' | 'step')[]>([
@@ -70,6 +68,7 @@ const fieldSelectedOption = ref<{ label: string; value: string }[]>([
},
]);
+const refFilter = ref>();
const currWorkflowData = ref();
const formDataWorkflow = ref({
status: 'CREATED',
@@ -103,7 +102,6 @@ const columns = [
function triggerDialog(type: 'add' | 'edit' | 'view') {
if (type === 'add') {
registeredBranchId.value = '';
- userInTable.value = [];
formDataWorkflow.value = {
status: 'CREATED',
name: '',
@@ -208,7 +206,7 @@ async function submit() {
...formDataWorkflow.value,
});
} else {
- await workflowStore.createWorkflowTemplate({
+ await workflowStore.creatWorkflowTemplate({
registeredBranchId: registeredBranchId.value,
...formDataWorkflow.value,
});
@@ -224,11 +222,7 @@ function assignFormData(workflowData: WorkflowTemplate) {
status: workflowData.status,
name: workflowData.name,
step: workflowData.step.map((s, i) => {
- userInTable.value[i] = {
- name: s.name,
- responsiblePerson: [],
- responsibleGroup: [],
- };
+ userInTable.value[i] = { name: s.name, responsiblePerson: [] };
s.responsiblePerson.forEach((p) => {
userInTable.value[i].responsiblePerson.push({
id: p.user.id,
@@ -242,16 +236,12 @@ function assignFormData(workflowData: WorkflowTemplate) {
code: p.user.code,
});
});
- s.responsibleGroup.forEach((g) => {
- userInTable.value[i].responsibleGroup.push(g);
- });
return {
id: s.id,
name: s.name,
detail: s.detail,
messengerByArea: s.messengerByArea || false,
value: s.value.length > 0 ? JSON.parse(JSON.stringify(s.value)) : [],
- responsibleGroup: s.responsibleGroup.map((g) => g),
responsiblePersonId: s.responsiblePerson.map((p) => p.userId),
responsibleInstitution: JSON.parse(
JSON.stringify(s.responsibleInstitution),
@@ -292,8 +282,6 @@ async function fetchWorkflowList(mobileFetch?: boolean) {
: statusFilter.value === 'statusACTIVE'
? 'ACTIVE'
: 'INACTIVE',
- startDate: pageState.searchDate[0],
- endDate: pageState.searchDate[1],
});
if (res) {
workflowData.value =
@@ -323,18 +311,14 @@ watch(
fetchWorkflowList();
},
);
-watch(
- [() => pageState.inputSearch, workflowPageSize, () => pageState.searchDate],
- () => {
- workflowData.value = [];
- workflowPage.value = 1;
- fetchWorkflowList();
- },
-);
+watch([() => pageState.inputSearch, workflowPageSize], () => {
+ workflowData.value = [];
+ workflowPage.value = 1;
+ fetchWorkflowList();
+});
-
-
-
-
- {{ $t('general.status') }}
-
-
+
+
+
-
+
{
@@ -849,7 +813,6 @@ watch(
@drawer-undo="undo"
@close="resetForm"
@submit="submit"
- :hide-action="!canAccess('workflow', 'edit')"
:readonly="!pageState.isDrawerEdit"
:isEdit="pageState.isDrawerEdit"
v-model="pageState.addModal"
diff --git a/src/pages/04_product-service/MainPage.vue b/src/pages/04_product-service/MainPage.vue
index 17cd4040..462e7476 100644
--- a/src/pages/04_product-service/MainPage.vue
+++ b/src/pages/04_product-service/MainPage.vue
@@ -3,7 +3,7 @@ import { nextTick, ref, watch, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import { onMounted } from 'vue';
import { storeToRefs } from 'pinia';
-import { useQuasar, type QTableProps } from 'quasar';
+import { QSelect, useQuasar, type QTableProps } from 'quasar';
import DialogProperties from 'src/components/dialog/DialogProperties.vue';
import ProductCardComponent from 'components/04_product-service/ProductCardComponent.vue';
@@ -33,7 +33,6 @@ import {
SaveButton,
UndoButton,
ToggleButton,
- ImportButton,
} from 'components/button';
import TableProduct from 'src/components/04_product-service/TableProduct.vue';
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
@@ -41,7 +40,7 @@ import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import useFlowStore from 'stores/flow';
import { dateFormat } from 'src/utils/datetime';
-import { formatNumberDecimal, isRoleInclude, canAccess } from 'stores/utils';
+import { formatNumberDecimal, isRoleInclude } from 'stores/utils';
const { getWorkflowTemplate } = useWorkflowTemplate();
import { Status } from 'stores/types';
@@ -60,7 +59,6 @@ import {
ServiceById,
WorkItems,
Attributes,
- WorkCreate,
} from 'stores/product-service/types';
import { computed } from 'vue';
import {
@@ -69,8 +67,6 @@ import {
} from 'src/stores/workflow-template/types';
import { useWorkflowTemplate } from 'src/stores/workflow-template';
import { deepEquals } from 'src/utils/arr';
-import { toRaw } from 'vue';
-import AdvanceSearch from 'src/components/shared/AdvanceSearch.vue';
const flowStore = useFlowStore();
const navigatorStore = useNavigator();
@@ -100,15 +96,10 @@ const {
createWork,
editWork,
deleteWork,
-
- importProduct,
-
- productExport,
} = productServiceStore;
const { workNameItems } = storeToRefs(productServiceStore);
const allStat = ref<{ mode: string; count: number }[]>([]);
-
const stat = ref<
{
icon: string;
@@ -145,29 +136,33 @@ const { t } = useI18n();
const baseUrl = ref(import.meta.env.VITE_API_BASE_URL);
const priceDisplay = computed(() => ({
- // price: !isRoleInclude(['sale_agent']),
- price: true,
+ price: !isRoleInclude(['sale_agent']),
agentPrice: isRoleInclude([
- 'system',
- 'head_of_admin',
'admin',
- 'executive',
- 'accountant',
+ 'head_of_admin',
'head_of_sale',
+ 'system',
+ 'owner',
+ 'accountant',
+ 'sale_agent',
]),
serviceCharge: isRoleInclude([
- 'system',
- 'head_of_admin',
'admin',
- 'executive',
+ 'head_of_admin',
+ 'system',
+ 'owner',
'accountant',
]),
}));
-const actionDisplay = computed(() => canAccess('product', 'edit'));
+const actionDisplay = computed(() =>
+ isRoleInclude(['admin', 'head_of_admin', 'system', 'owner', 'accountant']),
+);
const splitterModel = computed(() =>
$q.screen.lt.md ? (productMode.value !== 'group' ? 0 : 100) : 25,
);
+const refFilterGroup = ref>();
+const refFilterProductService = ref>();
const holdDialog = ref(false);
const imageDialog = ref(false);
const currentNode = ref();
@@ -525,7 +520,6 @@ const currentStatusGroupType = ref('CREATED');
const currentIdGroupType = ref('');
const currentStatus = ref('All');
-const searchDate = ref([]);
// img
const isImageEdit = ref(false);
@@ -621,8 +615,6 @@ async function fetchListGroups(mobileFetch?: boolean) {
: currentStatus.value === 'ACTIVE'
? 'ACTIVE'
: 'INACTIVE',
- startDate: searchDate.value[0],
- endDate: searchDate.value[1],
});
if (res) {
@@ -683,8 +675,6 @@ async function fetchListOfProduct(mobileFetch?: boolean) {
? 'ACTIVE'
: undefined,
productGroupId: currentIdGroup.value,
- startDate: searchDate.value[0],
- endDate: searchDate.value[1],
});
if (res) {
@@ -730,8 +720,6 @@ async function fetchListOfService(mobileFetch?: boolean) {
? 'ACTIVE'
: undefined,
productGroupId: currentIdGroup.value,
- startDate: searchDate.value[0],
- endDate: searchDate.value[1],
});
if (res) {
@@ -1171,7 +1159,6 @@ function clearFormService() {
profileSubmit.value = false;
imageProduct.value = undefined;
profileFileImg.value = null;
- serviceTab.value = 1;
}
function sameFormService() {
@@ -1398,7 +1385,6 @@ function submitAddWorkProduct() {
if (!s.hasOwnProperty('productsId')) {
s.productsId = [];
}
- if (s.productsId.length === 0) return;
s.productsId.push(i.id);
},
);
@@ -1451,11 +1437,17 @@ function confirmDeleteWork(id: string, noDialog?: boolean) {
}
}
-function triggerConfirmCloseWorkName() {
+function triggerConfirmCloseWork() {
dialogWarningClose(t, {
message: t('dialog.message.warningClose'),
action: () => {
manageWorkNameDialog.value = false;
+ if (workNameItems.value[workNameItems.value.length - 1].name === '') {
+ confirmDeleteWork(
+ workNameItems.value[workNameItems.value.length - 1].id,
+ true,
+ );
+ }
},
cancel: () => {},
});
@@ -1598,7 +1590,6 @@ async function enterNext(type: 'service' | 'product') {
inputSearchProductAndService.value = '';
currentStatus.value = 'All';
filterStat.value = [];
- searchDate.value = [];
if (
expandedTree.value.length > 1 &&
@@ -1754,7 +1745,7 @@ watch(currentStatus, async () => {
flowStore.rotate();
});
-watch([inputSearch, () => searchDate.value], async () => {
+watch(inputSearch, async () => {
if (productMode.value === 'group') {
productGroup.value = [];
currentPageGroup.value = 1;
@@ -1763,7 +1754,7 @@ watch([inputSearch, () => searchDate.value], async () => {
}
});
-watch([inputSearchProductAndService, () => searchDate.value], async () => {
+watch(inputSearchProductAndService, async () => {
product.value = [];
service.value = [];
currentPageServiceAndProduct.value = 1;
@@ -1840,84 +1831,6 @@ function handleSubmitSameWorkflow() {
);
}
-async function copy(id: string) {
- {
- const res = await fetchListServiceById(id);
- if (res) {
- formService.value = {
- code: res.code.slice(0, -3),
- name: res.name,
- detail: res.detail,
- attributes: res.attributes,
- work: res.work.map((v) => ({
- id: v.id,
- name: v.name,
- attributes: v.attributes,
- product: v.productOnWork.map((productOnWorkItem) => ({
- id: productOnWorkItem.product.id,
- installmentNo: productOnWorkItem.installmentNo,
- stepCount: productOnWorkItem.stepCount,
- })),
- })),
- status: res.status,
- productGroupId: res.productGroupId,
- selectedImage: res.selectedImage,
- installments: res.installments,
- };
-
- workItems.value = res.work.map((item) => {
- return {
- id: item.id,
- name: item.name,
- attributes: item.attributes,
- product: item.productOnWork.map((productOnWorkItem) => {
- return {
- ...productOnWorkItem.product,
- nameEn: productOnWorkItem.product.name,
- installmentNo: productOnWorkItem.installmentNo,
- };
- }),
- };
- });
- }
- }
-
- dialogService.value = true;
-}
-
-function addWorkName(data: { name: string; order: number }) {
- workNameItems.value.push({ id: '', name: data.name, isEdit: true });
-}
-
-async function submitWorkName(
- workId: string,
- data: Partial,
-) {
- if (workNameItems.value.length === 0) return;
-
- if (!workId) await createWork({ ...data, order: 1 });
- else await editWork(workId, data);
-}
-
-async function triggerExport() {
- productExport({
- pageSize: 100_000,
- productGroupId: currentIdGroup.value,
- query: !!inputSearchProductAndService.value
- ? inputSearchProductAndService.value
- : undefined,
- status:
- currentStatus.value === 'INACTIVE'
- ? 'INACTIVE'
- : currentStatus.value === 'ACTIVE'
- ? 'ACTIVE'
- : undefined,
-
- startDate: searchDate.value[0] ? new Date(searchDate.value[0]) : undefined,
- endDate: searchDate.value[1] ? new Date(searchDate.value[1]) : undefined,
- });
-}
-
watch(
() => formService.value.attributes.workflowId,
async (a, b) => {
@@ -2035,34 +1948,19 @@ watch(
-
-
-
-
- {{ $t('general.status') }}
-
-
+
+
+
-
+
@@ -2217,43 +2115,26 @@ watch(
-
-
-
-
- {{ $t('general.status') }}
-
-
+
+
+
-
+
+
+
+
- {{
- props.row.detail.replace(/<\/?[^>]+(>|$)/g, '') ||
- '-'
- }}
+ {{ props.row.detail || '-' }}
@@ -2747,72 +2618,26 @@ watch(
-
-
-
-
- {{ $t('general.status') }}
-
-
+
+
+
-
+
-
-
- {
- importProduct(
- currentIdGroup,
- file,
- async () => await fetchListOfProduct(),
- );
- }
- "
- />
-
-
-
+
+
{
- copy(props.row.id);
- }
- "
@view="
async () => {
if (props.row.type === 'product') {
@@ -3455,15 +3275,7 @@ watch(
{{ $t('general.recordPerPage') }}
@@ -3595,7 +3407,7 @@ watch(
-
@@ -4730,7 +4535,7 @@ watch(
? workNameRef.isWorkNameEdit()
: false;
if (isWorkNameEdit) {
- triggerConfirmCloseWorkName();
+ triggerConfirmCloseWork();
return true;
}
return false;
@@ -4742,16 +4547,15 @@ watch(
ref="workNameRef"
v-model:name-list="workNameItems"
@delete="confirmDeleteWork"
- @edit="submitWorkName"
- @add="addWorkName"
+ @edit="editWork"
+ @add="createWork"
/>
-
+
-
-
-
-
- {{ $t('general.status') }}
-
-
+
+
+
-
+
undo()"
@close="() => resetForm()"
@submit="() => submit()"
- :hide-action="!canAccess('workflow', 'edit')"
:readonly="!pageState.isDrawerEdit"
:isEdit="pageState.isDrawerEdit"
v-model="pageState.addModal"
diff --git a/src/pages/04_property-managment/PropertyDialog.vue b/src/pages/04_property-managment/PropertyDialog.vue
index 66161d57..333f0ec7 100644
--- a/src/pages/04_property-managment/PropertyDialog.vue
+++ b/src/pages/04_property-managment/PropertyDialog.vue
@@ -30,7 +30,6 @@ withDefaults(
defineProps<{
readonly?: boolean;
isEdit?: boolean;
- hideAction?: boolean;
}>(),
{ readonly: false, isEdit: false },
);
@@ -152,7 +151,7 @@ defineEmits<{
style="position: absolute; z-index: 999; top: 0; right: 0"
>
-import { onMounted, onUnmounted, reactive, ref, watch, computed } from 'vue';
+import { onMounted, reactive, ref, watch, computed } from 'vue';
import { storeToRefs } from 'pinia';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
@@ -7,15 +7,14 @@ import { useI18n } from 'vue-i18n';
// NOTE: Import stores
import useCustomerStore from 'stores/customer';
import { useQuotationStore } from 'src/stores/quotations';
-import { dialog, isRoleInclude, notify, setPrefixName } from 'stores/utils';
+import { dialog, isRoleInclude, notify } from 'stores/utils';
import { useNavigator } from 'src/stores/navigator';
import useFlowStore from 'src/stores/flow';
import useMyBranch from 'stores/my-branch';
import { useQuotationForm } from './form';
import { hslaColors } from './constants';
import { pageTabs, columnQuotation } from './constants';
-import { toCamelCase, canAccess } from 'stores/utils';
-import { getUserId } from 'src/services/keycloak';
+import { toCamelCase } from 'stores/utils';
// NOTE Import Types
import { CustomerBranchCreate, CustomerType } from 'stores/customer/types';
@@ -50,7 +49,6 @@ import { Quotation } from 'src/stores/quotations/types';
import TableQuotation from 'src/components/05_quotation/TableQuotation.vue';
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
import { DialogContainer, DialogHeader } from 'src/components/dialog';
-import AdvanceSearch from 'src/components/shared/AdvanceSearch.vue';
const { t, locale } = useI18n();
const $q = useQuasar();
@@ -60,6 +58,7 @@ const flowStore = useFlowStore();
const userBranch = useMyBranch();
const navigatorStore = useNavigator();
const customerStore = useCustomerStore();
+
const {
fetchListOfOptionBranch,
customerFormUndo,
@@ -75,7 +74,6 @@ const {
const {
state: customerFormState,
currentFormData: customerFormData,
- currentBranchRootId,
registerAbleBranchOption,
tabFieldRequired,
} = storeToRefs(customerFormStore);
@@ -89,8 +87,6 @@ const fieldSelectedOption = computed(() => {
value: v.name,
}));
});
-
-const keyAddDialog = ref(0);
const special = ref(false);
const branchId = ref('');
const agentPrice = ref(false);
@@ -107,14 +103,12 @@ const pageState = reactive({
fieldSelected: [''],
gridView: false,
total: 0,
- sellerId: '',
currentTab: 'Issued',
addModal: false,
quotationModal: false,
employeeModal: false,
receiptModal: false,
- searchDate: [],
});
pageState.fieldSelected = [...columnQuotation.map((v) => v.name)];
@@ -275,10 +269,6 @@ const customerNameInfo = computed(() => {
return name || '-';
});
-function handleWindowFocus() {
- fetchQuotationList();
-}
-
onMounted(async () => {
pageState.gridView = $q.screen.lt.md ? true : false;
navigatorStore.current.title = 'quotation.title';
@@ -305,7 +295,6 @@ onMounted(async () => {
pageSize: quotationPageSize.value,
status: 'Issued',
urgentFirst: true,
- sellerId: pageState.sellerId || undefined,
});
if (ret) {
@@ -316,12 +305,6 @@ onMounted(async () => {
}
flowStore.rotate();
-
- window.addEventListener('focus', handleWindowFocus);
-});
-
-onUnmounted(() => {
- window.removeEventListener('focus', handleWindowFocus);
});
async function fetchQuotationList(mobileFetch?: boolean) {
@@ -344,9 +327,6 @@ async function fetchQuotationList(mobileFetch?: boolean) {
: 'Issued',
query: pageState.inputSearch,
urgentFirst: true,
- startDate: pageState.searchDate[0],
- endDate: pageState.searchDate[1],
- sellerId: pageState.sellerId || undefined,
});
if (ret) {
@@ -370,12 +350,7 @@ async function fetchQuotationList(mobileFetch?: boolean) {
}
watch(
- [
- () => pageState.currentTab,
- () => pageState.inputSearch,
- () => pageState.searchDate,
- quotationPageSize,
- ],
+ [() => pageState.currentTab, () => pageState.inputSearch, quotationPageSize],
() => {
quotationPage.value = 1;
quotationData.value = [];
@@ -422,11 +397,6 @@ async function storeDataLocal(id: string) {
window.open(url, '_blank');
}
-
-async function filterBySellerId() {
- pageState.sellerId = pageState.sellerId ? '' : getUserId();
- await fetchQuotationList();
-}
@@ -434,7 +404,6 @@ async function filterBySellerId() {
hide-icon
style="z-index: 999"
@click.stop="triggerAddQuotationDialog"
- v-if="canAccess('quotation', 'create')"
/>
@@ -548,21 +517,6 @@ async function filterBySellerId() {
-
-
-
-
-
-
- {{ $t('quotation.ownOnly') }}
-
-
-
-
@@ -680,20 +634,12 @@ async function filterBySellerId() {
class="col surface-2 flex items-center justify-center"
>
storeDataLocal(id)"
@view="
@@ -750,8 +694,7 @@ async function filterBySellerId() {
@@ -1018,7 +954,6 @@ async function filterBySellerId() {
() => {
customerFormState.dialogModal = false;
onCreateImageList = { selectedImage: '', list: [] };
- keyAddDialog++;
}
"
>
@@ -1073,16 +1008,7 @@ async function filterBySellerId() {
"
:title="
customerFormData.customerType === 'PERS'
- ? setPrefixName(
- {
- namePrefix: customerFormData.customerBranch[0]?.namePrefix,
- firstName: customerFormData.customerBranch[0]?.firstName,
- lastName: customerFormData.customerBranch[0]?.lastName,
- firstNameEN: customerFormData.customerBranch[0]?.firstNameEN,
- lastNameEN: customerFormData.customerBranch[0]?.lastNameEN,
- },
- { locale },
- )
+ ? `${customerFormData.customerBranch[0]?.firstName} ${customerFormData.customerBranch[0]?.lastName}`
: customerFormData.customerBranch[0]?.registerName
"
:caption="
@@ -1191,13 +1117,13 @@ async function filterBySellerId() {
id="form-basic-info-customer"
:onCreate="customerFormState.dialogType === 'create'"
@edit="
- ((customerFormState.dialogType = 'edit'),
- (customerFormState.readonly = false))
+ (customerFormState.dialogType = 'edit'),
+ (customerFormState.readonly = false)
"
@cancel="() => customerFormUndo(false)"
@delete="
customerFormState.editCustomerId &&
- deleteCustomerById(customerFormState.editCustomerId)
+ deleteCustomerById(customerFormState.editCustomerId)
"
:customer-type="customerFormData.customerType"
v-model:registered-branch-id="customerFormData.registeredBranchId"
@@ -1210,7 +1136,7 @@ async function filterBySellerId() {
customerFormData.customerBranch[0].legalPersonNo
"
v-model:business-type="
- customerFormData.customerBranch[0].businessTypeId
+ customerFormData.customerBranch[0].businessType
"
v-model:job-position="
customerFormData.customerBranch[0].jobPosition
@@ -1291,6 +1217,7 @@ async function filterBySellerId() {
res = await customerStore.createBranch({
...customerFormData.customerBranch[idx],
customerId: customerFormState.editCustomerId || '',
+ id: undefined,
});
}
if (res) {
diff --git a/src/pages/05_quotation/PaymentForm.vue b/src/pages/05_quotation/PaymentForm.vue
index cf3d7c63..5bf0e43e 100644
--- a/src/pages/05_quotation/PaymentForm.vue
+++ b/src/pages/05_quotation/PaymentForm.vue
@@ -1,9 +1,15 @@
-
-
-
-
-
-
-
-
- {{ $t('quotation.receiptDialog.paymentWait') }}
-
-
-
-
-
- {{ data.workName }}
-
-
- {{ data.code }}
-
-
- ฿ {{ formatNumberDecimal(data.finalPrice, 2) || '0.00' }}
+
+
+
+
+
+
+
+
+
+ {{ $t('quotation.receiptDialog.paymentWait') }}
+
+
+
+
+
+ {{ data.workName }}
-
-
-
-
-
-
-
-
- {{ $t('general.total') }}
-
- ฿
- {{ formatNumberDecimal(data.totalPrice, 2) || '0.00' }}
-
-
-
- {{ $t('quotation.discountList') }}
-
- ฿
- {{ formatNumberDecimal(data.totalDiscount, 2) || '0.00' }}
-
-
-
- {{ $t('general.totalAfterDiscount') }}
-
- ฿
- {{
- formatNumberDecimal(data.totalPrice - data.totalDiscount, 2) ||
- '0.00'
- }}
-
-
-
- {{ $t('general.totalVatExcluded') }}
-
- ฿ {{ formatNumberDecimal(data.vatExcluded, 2) || '0.00' }}
-
-
-
- {{
- $t('general.vat', {
- msg: `${config && Math.round(config.vat * 100)}%`,
- })
- }}
-
- ฿ {{ formatNumberDecimal(data.vat, 2) || '0.00' }}
-
-
-
- {{ $t('general.totalVatIncluded') }}
-
- ฿
- {{
- formatNumberDecimal(
- data.totalPrice - data.totalDiscount + data.vat,
- 2,
- ) || '0.00'
- }}
-
-
-
- {{ $t('general.discountAfterVat') }}
-
- ฿ {{ formatNumberDecimal(data.discount, 2) || '0.00' }}
-
-
-
-
-
-
- {{ $t('quotation.totalPriceBaht') }}:
-
- {{ formatNumberDecimal(data.finalPrice, 2) || '0.00' }}
-
-
-
-
-
-
-
+
-
-
-
+
+ {{ $t('general.total') }}
+
+ ฿
+ {{ formatNumberDecimal(data.totalPrice, 2) || '0.00' }}
+
+
+
+ {{ $t('quotation.discountList') }}
+
+ ฿
+ {{ formatNumberDecimal(data.totalDiscount, 2) || '0.00' }}
+
+
+
+ {{ $t('general.totalAfterDiscount') }}
+
+ ฿
+ {{
+ formatNumberDecimal(
+ data.totalPrice - data.totalDiscount,
+ 2,
+ ) || '0.00'
+ }}
+
+
+
+ {{ $t('general.totalVatExcluded') }}
+
+ ฿ {{ formatNumberDecimal(data.vatExcluded, 2) || '0.00' }}
+
+
+
+ {{
+ $t('general.vat', {
+ msg: `${config && Math.round(config.vat * 100)}%`,
+ })
+ }}
+
+ ฿ {{ formatNumberDecimal(data.vat, 2) || '0.00' }}
+
+
+
+ {{ $t('general.totalVatIncluded') }}
+
+ ฿
+ {{
+ formatNumberDecimal(
+ data.totalPrice - data.totalDiscount + data.vat,
+ 2,
+ ) || '0.00'
+ }}
+
+
+
+ {{ $t('general.discountAfterVat') }}
+
+ ฿ {{ formatNumberDecimal(data.discount, 2) || '0.00' }}
+
+
+
+
+
+
+ {{ $t('quotation.totalPriceBaht') }}:
+
+ {{ formatNumberDecimal(data.finalPrice, 2) || '0.00' }}
+
+
+
+
+
+
+
-
-
+
+
diff --git a/src/pages/05_quotation/QuotationForm.vue b/src/pages/05_quotation/QuotationForm.vue
index cd24e5cd..3322cf0d 100644
--- a/src/pages/05_quotation/QuotationForm.vue
+++ b/src/pages/05_quotation/QuotationForm.vue
@@ -2,15 +2,12 @@
import { useI18n } from 'vue-i18n';
import { storeToRefs } from 'pinia';
import { QSelect, useQuasar } from 'quasar';
-import { getUserId } from 'src/services/keycloak';
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
import {
baseUrl,
dialogCheckData,
dialogWarningClose,
formatNumberDecimal,
- canAccess,
- isRoleInclude,
} from 'stores/utils';
import { ProductTree, quotationProductTree } from './utils';
@@ -79,8 +76,7 @@ import { api } from 'src/boot/axios';
import { RouterLink, useRoute } from 'vue-router';
import { initLang, initTheme, Lang } from 'src/utils/ui';
import { convertTemplate } from 'src/utils/string-template';
-
-import { CustomerBranch } from 'src/stores/customer';
+import { getRole } from 'src/services/keycloak';
type Node = {
[key: string]: any;
@@ -96,8 +92,6 @@ type ProductGroupId = string;
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
-const customerBranchOption = ref();
-
const employeeStore = useEmployeeStore();
const route = useRoute();
const useReceiptStore = useReceipt();
@@ -161,7 +155,50 @@ const selectedWorker = ref<
}[];
})[]
>([]);
-const selectedWorkerItem = ref([]);
+const selectedWorkerItem = computed(() => {
+ return [
+ ...selectedWorker.value.map((e) => ({
+ foreignRefNo: e.employeePassport
+ ? e.employeePassport[0]?.number || '-'
+ : '-',
+ employeeName:
+ locale.value === Lang.English
+ ? `${e.firstNameEN} ${e.lastNameEN}`
+ : e.firstName
+ ? `${e.firstName} ${e.lastName}`
+ : `${e.firstNameEN} ${e.lastNameEN}`,
+ birthDate: dateFormatJS({ date: e.dateOfBirth }),
+ gender: e.gender,
+ age: calculateAge(e.dateOfBirth),
+ nationality: optionStore.mapOption(e.nationality),
+ documentExpireDate:
+ e.employeePassport !== undefined &&
+ e.employeePassport[0]?.expireDate !== undefined
+ ? dateFormatJS({ date: e.employeePassport[0]?.expireDate })
+ : '-',
+ imgUrl: e.selectedImage
+ ? `${API_BASE_URL}/employee/${e.id}/image/${e.selectedImage}`
+ : '',
+ status: e.status,
+ })),
+
+ ...newWorkerList.value.map((v: any) => ({
+ foreignRefNo: v.passportNo,
+ employeeName:
+ locale.value === Lang.English
+ ? `${v.firstNameEN} ${v.lastNameEN}`
+ : `${v.firstName} ${v.lastName}`,
+ birthDate: dateFormatJS({ date: v.dateOfBirth }),
+ gender: v.gender,
+ age: calculateAge(v.dateOfBirth),
+ nationality: optionStore.mapOption(v.nationality),
+ documentExpireDate: '-',
+ imgUrl: '',
+ status: 'CREATED',
+ })),
+ ];
+});
+const workerList = ref([]);
const firstCodePayment = ref('');
const selectedProductGroup = ref('');
const selectedInstallmentNo = ref([]);
@@ -177,6 +214,17 @@ const attachmentData = ref<
url?: string;
}[]
>([]);
+const hideBtnApproveInvoice = computed(() => {
+ const role = getRole();
+ const allowedRoles = [
+ 'system',
+ 'head_of_admin',
+ 'admin',
+ 'head_of_accountant',
+ 'accountant',
+ ];
+ return !role || !role.some((r) => allowedRoles.includes(r));
+});
const getToolbarConfig = computed(() => {
const toolbar = [['left', 'center', 'justify'], ['toggle'], ['clip']];
@@ -196,7 +244,7 @@ function getPrice(
) {
if (filterHook) list = list.filter(filterHook);
- const value = list.reduce(
+ return list.reduce(
(a, c) => {
if (
selectedInstallmentNo.value.length > 0 &&
@@ -206,25 +254,32 @@ function getPrice(
return a;
}
+ const originalPrice = c.pricePerUnit;
+ const finalPriceWithVat = precisionRound(
+ originalPrice * (1 + (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);
+
const calcVat =
c.product[agentPrice.value ? 'agentPriceCalcVat' : 'calcVat'];
- const vatFactor = calcVat ? (config.value?.vat ?? 0.07) : 0;
- const pricePerUnit =
- precisionRound(c.pricePerUnit * (1 + vatFactor)) / (1 + vatFactor);
-
- const price =
- (pricePerUnit * c.amount * (1 + vatFactor) - c.discount) /
- (1 + vatFactor);
- const vat = price * vatFactor;
-
- a.totalPrice = precisionRound(a.totalPrice + price + c.discount);
- a.totalDiscount = precisionRound(a.totalDiscount + c.discount);
- a.vat = precisionRound(a.vat + vat);
+ a.totalPrice = precisionRound(a.totalPrice + price);
+ a.totalDiscount = precisionRound(a.totalDiscount + Number(c.discount));
+ a.vat = calcVat ? precisionRound(a.vat + vat) : a.vat;
a.vatExcluded = calcVat
? a.vatExcluded
: precisionRound(a.vatExcluded + price);
- a.finalPrice = precisionRound(a.totalPrice - a.totalDiscount + a.vat);
+ a.finalPrice = precisionRound(
+ a.totalPrice -
+ a.totalDiscount +
+ a.vat -
+ Number(quotationFormData.value.discount || 0),
+ );
return a;
},
@@ -236,8 +291,6 @@ function getPrice(
finalPrice: 0,
},
);
-
- return value;
}
const summaryPrice = computed(() => getPrice(productServiceList.value));
@@ -516,7 +569,7 @@ async function convertDataToFormSubmit() {
),
);
- selectedWorkerItem.value.forEach((v, i) => {
+ selectedWorker.value.forEach((v, i) => {
if (v.attachment !== undefined) {
v.attachment.forEach((value) => {
fileItemNewWorker.value.push({
@@ -533,7 +586,7 @@ async function convertDataToFormSubmit() {
quotationFormData.value.worker = JSON.parse(
JSON.stringify([
- ...selectedWorkerItem.value.map((v) => {
+ ...selectedWorker.value.map((v) => {
{
return v.id;
}
@@ -573,7 +626,6 @@ async function convertDataToFormSubmit() {
discount: quotationFormData.value.discount,
remark: quotationFormData.value.remark || '',
agentPrice: agentPrice.value,
- sellerId: quotationFormData.value.sellerId,
};
newWorkerList.value = [];
@@ -676,13 +728,19 @@ function handleUpdateProductTable(
// handleChangePayType(quotationFormData.value.payCondition);
// calc price
const calc = (c: QuotationPayload['productServiceList'][number]) => {
- const calcVat =
- c.product[agentPrice.value ? 'agentPriceCalcVat' : 'calcVat'];
- const vatFactor = calcVat ? (config.value?.vat ?? 0.07) : 0;
- const pricePerUnit =
- precisionRound(c.pricePerUnit * (1 + vatFactor)) / (1 + vatFactor);
- const price = pricePerUnit * c.amount * (1 + vatFactor) - c.discount;
- return precisionRound(price);
+ const originalPrice = c.pricePerUnit || 0;
+ const finalPriceWithVat = precisionRound(
+ originalPrice * (1 + (config.value?.vat || 0.07)),
+ );
+ const finalPriceNoVat =
+ finalPriceWithVat / (1 + (config.value?.vat || 0.07));
+
+ const price = finalPriceNoVat * c.amount;
+ const vat = c.product.calcVat
+ ? (finalPriceNoVat * c.amount - (c.discount || 0)) *
+ (config.value?.vat || 0.07)
+ : 0;
+ return precisionRound(price + vat);
};
// installment
@@ -735,16 +793,21 @@ function toggleDeleteProduct(index: number) {
// cal curr amount
if (currPaySplit && currTempPaySplit) {
- const calcVat =
- currProduct.product[agentPrice.value ? 'agentPriceCalcVat' : 'calcVat'];
- const vatFactor = calcVat ? (config.value?.vat ?? 0.07) : 0;
+ const price = agentPrice.value
+ ? currProduct.product.agentPrice
+ : currProduct.product.price;
+ const pricePerUnit = currProduct.product.vatIncluded
+ ? price / (1 + (config.value?.vat || 0.07))
+ : price;
+ const vat =
+ (pricePerUnit * currProduct.amount - currProduct.discount) *
+ (config.value?.vat || 0.07);
+ const finalPrice =
+ pricePerUnit * currProduct.amount +
+ vat -
+ Number(currProduct.discount || 0);
- const price = precisionRound(
- currProduct.pricePerUnit * currProduct.amount * (1 + vatFactor) -
- currProduct.discount,
- );
-
- currTempPaySplit.amount = currPaySplit.amount - price;
+ currTempPaySplit.amount = currPaySplit.amount - finalPrice;
currPaySplit.amount = currTempPaySplit.amount;
}
@@ -766,40 +829,7 @@ function toggleDeleteProduct(index: number) {
}
async function assignWorkerToSelectedWorker() {
- selectedWorkerItem.value = quotationFormData.value.worker.map((e) => {
- return {
- id: e.id,
- foreignRefNo: e.employeePassport
- ? e.employeePassport[0]?.number || '-'
- : '-',
- employeeName:
- locale.value === Lang.English
- ? `${e.firstNameEN} ${e.lastNameEN}`
- : `${e.firstName || e.firstNameEN} ${e.lastName || e.lastNameEN}`,
- birthDate: dateFormatJS({ date: e.dateOfBirth }),
- gender: e.gender,
- age: calculateAge(e.dateOfBirth),
- nationality: optionStore.mapOption(e.nationality),
- documentExpireDate:
- e.employeePassport !== undefined &&
- e.employeePassport[0]?.expireDate !== undefined
- ? dateFormatJS({ date: e.employeePassport[0]?.expireDate })
- : '-',
- imgUrl: e.selectedImage
- ? `${API_BASE_URL}/employee/${e.id}/image/${e.selectedImage}`
- : '',
- employeePassport: e.employeePassport,
- status: e.status,
- workerNew: false,
- lastNameEN: e.lastNameEN,
- lastName: e.lastName,
- middleNameEN: e.middleNameEN,
- middleName: e.middleName,
- firstNameEN: e.firstNameEN,
- firstName: e.firstName,
- namePrefix: e.namePrefix,
- };
- });
+ selectedWorker.value = quotationFormData.value.worker;
}
function convertToTable(nodes: Node[]) {
@@ -832,7 +862,8 @@ function convertToTable(nodes: Node[]) {
tempTableProduct.value = JSON.parse(JSON.stringify(list));
if (nodes.length > 0) {
- quotationFormData.value.paySplit = Array.from(
+ quotationFormData.value.paySplit = Array.apply(
+ null,
new Array(quotationFormData.value.paySplitCount),
).map((_, i) => ({
no: i + 1,
@@ -858,21 +889,21 @@ function convertToTable(nodes: Node[]) {
function convertEmployeeToTable(selected: Employee[]) {
productServiceList.value.forEach((v) => {
- if (selectedWorkerItem.value.length === 0 && v.amount === 1) v.amount -= 1;
+ if (selectedWorker.value.length === 0 && v.amount === 1) v.amount -= 1;
v.amount = Math.max(
- v.amount + selected.length - selectedWorkerItem.value.length,
+ v.amount + selected.length - selectedWorker.value.length,
1,
);
const oldWorkerId: string[] = [];
const newWorkerIndex: number[] = [];
- selectedWorkerItem.value.forEach((item, i) => {
+ selectedWorker.value.forEach((item, i) => {
if (v.workerIndex.includes(i)) oldWorkerId.push(item.id);
});
selected.forEach((item, i) => {
- if (selectedWorkerItem.value.find((n) => item.id === n.id)) return;
+ if (selectedWorker.value.find((n) => item.id === n.id)) return;
newWorkerIndex.push(i);
});
@@ -885,7 +916,7 @@ function convertEmployeeToTable(selected: Employee[]) {
pageState.employeeModal = false;
quotationFormData.value.workerMax = Math.max(
quotationFormData.value.workerMax || 1,
- selectedWorkerItem.value.length,
+ selectedWorker.value.length,
);
}
@@ -958,71 +989,6 @@ function viewProductFile(data: ProductRelation) {
pageState.imageDialogUrl = base64 ? base64[1] : '';
}
-function combineWorker(newWorker: any, oldWorker: any) {
- selectedWorkerItem.value = [
- ...oldWorker.map((e) => ({
- id: e.id,
- foreignRefNo: e.employeePassport
- ? e.employeePassport[0]?.number || '-'
- : '-',
- employeeName:
- locale.value === Lang.English
- ? `${e.firstNameEN} ${e.lastNameEN}`
- : `${e.firstName || e.firstNameEN} ${e.lastName || e.lastNameEN}`,
- birthDate: dateFormatJS({ date: e.dateOfBirth }),
- gender: e.gender,
- age: calculateAge(e.dateOfBirth),
- nationality: optionStore.mapOption(e.nationality),
- documentExpireDate:
- e.employeePassport !== undefined &&
- e.employeePassport[0]?.expireDate !== undefined
- ? dateFormatJS({ date: e.employeePassport[0]?.expireDate })
- : '-',
- imgUrl: e.selectedImage
- ? `${API_BASE_URL}/employee/${e.id}/image/${e.selectedImage}`
- : '',
-
- employeePassport: e.employeePassport,
- status: e.status,
- workerNew: false,
- lastNameEN: e.lastNameEN,
- lastName: e.lastName,
- middleNameEN: e.middleNameEN,
- middleName: e.middleName,
- firstNameEN: e.firstNameEN,
- firstName: e.firstName,
- namePrefix: e.namePrefix,
- })),
-
- ...newWorker.map((v: any) => ({
- id: v.id,
- foreignRefNo: v.passportNo || '-',
- employeeName:
- locale.value === Lang.English
- ? `${v.firstNameEN} ${v.lastNameEN}`
- : `${v.firstName || v.firstNameEN} ${v.lastName || v.lastNameEN}`,
- birthDate: dateFormatJS({ date: v.dateOfBirth }),
- gender: v.gender,
- age: calculateAge(v.dateOfBirth),
- nationality: optionStore.mapOption(v.nationality),
- documentExpireDate: '-',
- imgUrl: '',
- status: 'CREATED',
-
- lastNameEN: v.lastNameEN,
- lastName: v.lastName,
- middleNameEN: v.middleNameEN,
- middleName: v.middleName,
- firstNameEN: v.firstNameEN,
- firstName: v.firstName,
- namePrefix: v.namePrefix,
-
- dateOfBirth: v.dateOfBirth,
- workerNew: true,
- })),
- ];
-}
-
const sessionData = ref>();
onMounted(async () => {
@@ -1059,7 +1025,6 @@ onMounted(async () => {
quotationFormData.value.customerBranchId = parsed.customerBranchId;
currentQuotationId.value = parsed.quotationId;
agentPrice.value = parsed.agentPrice;
- quotationFormData.value.sellerId = getUserId();
await fetchQuotation();
await assignWorkerToSelectedWorker();
sessionData.value = parsed;
@@ -1094,7 +1059,12 @@ watch(
() => quotationFormData.value.customerBranchId,
async (v) => {
if (!v) return;
- selectedWorkerItem.value = [];
+
+ const retEmp = await customerStore.fetchBranchEmployee(v, {
+ passport: true,
+ });
+
+ if (retEmp) workerList.value = retEmp.data.result;
},
);
@@ -1110,15 +1080,6 @@ watch(
const productServiceNodes = ref([]);
-watch(customerBranchOption, () => {
- if (!customerBranchOption.value) return;
-
- quotationFormData.value.contactName =
- customerBranchOption.value.contactName || '';
- quotationFormData.value.contactTel =
- customerBranchOption.value.contactTel || '';
-});
-
watch(
() => productServiceList.value,
() => {
@@ -1126,13 +1087,6 @@ watch(
},
);
-watch(customerBranchOption, () => {
- if (!customerBranchOption.value) return;
-
- quotationFormData.value.contactName = customerBranchOption.value.contactName;
- quotationFormData.value.contactTel = customerBranchOption.value.contactTel;
-});
-
// async function searchEmployee(text: string) {
// let query: string | undefined = text;
// let pageSize = 50;
@@ -1154,19 +1108,7 @@ watch(customerBranchOption, () => {
// }
function storeDataLocal() {
- const tempProductService = productService.value.map((v) => {
- return {
- ...v,
- vat: v.product[agentPrice ? 'agentPriceCalcVat' : 'calcVat']
- ? precisionRound(
- ((v.pricePerUnit * (1 + (config?.value.vat || 0.07)) * v.amount -
- v.discount) /
- (1 + (config?.value.vat || 0.07))) *
- 0.07,
- )
- : 0,
- };
- });
+ quotationFormData.value.productServiceList = productService.value;
localStorage.setItem(
'quotation-preview',
@@ -1175,7 +1117,7 @@ function storeDataLocal() {
codeInvoice: code.value,
codePayment: firstCodePayment.value,
...quotationFormData.value,
- productServiceList: tempProductService,
+ productServiceList: productService.value,
},
meta: {
source: {
@@ -1195,7 +1137,7 @@ function storeDataLocal() {
workName: quotationFormData.value.workName,
dueDate: quotationFormData.value.dueDate,
},
- selectedWorker: selectedWorkerItem.value,
+ selectedWorker: selectedWorker.value,
createdBy: quotationFormState.value.createdBy('tha'),
agentPrice: agentPrice.value,
},
@@ -1280,10 +1222,10 @@ async function getWorkerFromCriteria(
if (!ret) return false; // error, do not close dialog
const deduplicate = ret.result.filter(
- (a) => !selectedWorkerItem.value.find((b) => a.id === b.id),
+ (a) => !selectedWorker.value.find((b) => a.id === b.id),
);
- convertEmployeeToTable([...deduplicate, ...selectedWorkerItem.value]);
+ convertEmployeeToTable([...deduplicate, ...selectedWorker.value]);
return true;
}
@@ -1573,13 +1515,11 @@ function covertToNode() {
:quotation-status="
quotationFormState.source?.quotationStatus === 'Expired'
"
- :created-at="quotationFormState.createdAt"
v-model:urgent="quotationFormData.urgent"
v-model:work-name="quotationFormData.workName"
v-model:contactor="quotationFormData.contactName"
v-model:telephone="quotationFormData.contactTel"
v-model:due-date="quotationFormData.dueDate"
- v-model:seller-id="quotationFormData.sellerId"
>
@@ -1635,7 +1574,7 @@ function covertToNode() {
}}
-
@@ -1812,9 +1751,7 @@ function covertToNode() {
:readonly="
{
quotation: quotationFormState.mode !== 'edit',
- invoice:
- isRoleInclude(['sale', 'head_of_sale']) ||
- !canAccess('quotation', 'edit'),
+ invoice: false,
accepted: true,
}[view]
"
@@ -1925,10 +1862,10 @@ function covertToNode() {
installments: quotationFormData.paySplit,
},
'quotation-labor': {
- name: selectedWorkerItem.map(
+ name: selectedWorker.map(
(v, i) =>
`${i + 1}. ` +
- `${v.employeePassport.length !== 0 ? v.employeePassport[0].number + '_' : ''}${v.namePrefix}.${v.firstNameEN ? `${v.firstNameEN} ${v.lastNameEN}` : `${v.firstName} ${v.lastName}`} `.toUpperCase(),
+ `${v.namePrefix}. ${v.firstNameEN} ${v.lastNameEN}`.toUpperCase(),
),
},
})
@@ -2018,11 +1955,6 @@ function covertToNode() {
view !== View.Receipt &&
view !== View.Complete
"
- :branch-id="quotationFull.registeredBranchId"
- :readonly="
- isRoleInclude(['sale', 'head_of_sale']) ||
- !canAccess('quotation', 'edit')
- "
:data="quotationFormState.source"
v-model:first-code-payment="firstCodePayment"
@fetch-status="
@@ -2161,14 +2093,7 @@ function covertToNode() {
:style="`background-color:hsla(var(--info-bg) / 0.07)`"
>
-
+
@@ -2378,15 +2304,9 @@ function covertToNode() {
-
+
{
- combineWorker(v.newWorker, v.worker);
+ selectedWorker = v.worker;
}
"
/>
@@ -2517,7 +2437,7 @@ function covertToNode() {
{
@@ -275,7 +275,6 @@ watch(
{{
formatNumberDecimal(
- summaryPrice.totalPrice -
- summaryPrice.totalDiscount -
- summaryPrice.vatExcluded,
+ summaryPrice.totalPrice - summaryPrice.totalDiscount,
2,
)
}}
@@ -488,11 +482,7 @@ watch(
{{ $t('quotation.totalPriceBaht') }}
-
+
{{
payType === 'SplitCustom' && view === View.Invoice
? formatNumberDecimal(Math.max(installmentAmount || 0, 0), 2) || 0
diff --git a/src/pages/05_quotation/QuotationFormMetadata.vue b/src/pages/05_quotation/QuotationFormMetadata.vue
index 161b0420..071bc84b 100644
--- a/src/pages/05_quotation/QuotationFormMetadata.vue
+++ b/src/pages/05_quotation/QuotationFormMetadata.vue
@@ -1,6 +1,5 @@
@@ -97,11 +95,5 @@ const sellerId = defineModel('sellerId', { required: true });
dense
outlined
/>
-
diff --git a/src/pages/05_quotation/QuotationFormProductSelect.vue b/src/pages/05_quotation/QuotationFormProductSelect.vue
index b2e92761..eb6ffef8 100644
--- a/src/pages/05_quotation/QuotationFormProductSelect.vue
+++ b/src/pages/05_quotation/QuotationFormProductSelect.vue
@@ -51,8 +51,6 @@ const emit = defineEmits<{
const selectedProductGroup = defineModel('selectedProductGroup', {
default: '',
});
-
-const selectedProductGroupOption = ref();
const model = defineModel();
const inputSearch = defineModel('inputSearch');
const productGroup = defineModel('productGroup', {
@@ -68,21 +66,21 @@ const serviceList = defineModel>>(
);
const priceDisplay = computed(() => ({
- // price: !isRoleInclude(['sale_agent']),
- price: true,
+ price: !isRoleInclude(['sale_agent']),
agentPrice: isRoleInclude([
- 'system',
- 'head_of_admin',
'admin',
- 'executive',
- 'accountant',
+ 'head_of_admin',
'head_of_sale',
+ 'system',
+ 'owner',
+ 'accountant',
+ 'sale_agent',
]),
serviceCharge: isRoleInclude([
- 'system',
- 'head_of_admin',
'admin',
- 'executive',
+ 'head_of_admin',
+ 'system',
+ 'owner',
'accountant',
]),
}));
@@ -571,18 +569,14 @@ watch(
{{
productGroup.find(
(g) => g.id === selectedProductGroup,
- )?.name ||
- selectedProductGroupOption?.name ||
- '-'
+ )?.name || '-'
}}
{{
productGroup.find(
(g) => g.id === selectedProductGroup,
- )?.code ||
- selectedProductGroupOption?.code ||
- '-'
+ )?.code || '-'
}}
@@ -868,13 +862,13 @@ watch(
{{ $t('productService.group.title') }}
+
import { useI18n } from 'vue-i18n';
import { reactive, ref, watch, onMounted } from 'vue';
-import { baseUrl, notify, setPrefixName } from 'src/stores/utils';
+import { baseUrl, notify } from 'src/stores/utils';
// NOTE: Import stores
import { dialog } from 'stores/utils';
@@ -21,7 +21,6 @@ import useOcrStore from 'stores/ocr';
// NOTE: Import Components
import {
- AddButton,
SaveButton,
EditButton,
UndoButton,
@@ -54,9 +53,6 @@ import { SideMenu } from 'src/components';
import BasicInformation from 'components/03_customer-management/employee/BasicInformation.vue';
import { AddressForm } from 'src/components/form';
import ExpirationDate from 'src/components/03_customer-management/ExpirationDate.vue';
-import FormEmployeeHealthCheck from 'src/components/03_customer-management/FormEmployeeHealthCheck.vue';
-import FormEmployeeWorkHistory from 'src/components/03_customer-management/FormEmployeeWorkHistory.vue';
-import FormEmployeeOther from 'src/components/03_customer-management/FormEmployeeOther.vue';
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
@@ -113,7 +109,7 @@ const props = withDefaults(
defineProps<{
customerBranchId?: string;
disabledWorkerId?: string[];
- preselectWorker?: (Employee & { workerNew: boolean })[];
+ preselectWorker?: Employee[];
}>(),
{},
);
@@ -133,7 +129,7 @@ const optionStore = useOptionStore();
const employeeStore = useEmployeeStore();
const open = defineModel('open', { default: false });
-const newWorkerList = ref<
+const newWorkerList = defineModel<
(EmployeeWorker & {
attachment?: {
name?: string;
@@ -143,7 +139,7 @@ const newWorkerList = ref<
_meta?: Record;
}[];
})[]
->([]);
+>('newWorkerList', { default: [] });
const workerSelected = ref([]);
const workerList = ref([]);
const importWorkerCriteria = ref<{
@@ -208,13 +204,7 @@ function getEmployeeImageUrl(item: Employee) {
function init() {
if (props.preselectWorker) {
- workerSelected.value = JSON.parse(
- JSON.stringify(props.preselectWorker.filter((v) => !v.workerNew)),
- );
-
- newWorkerList.value = JSON.parse(
- JSON.stringify(props.preselectWorker.filter((v) => v.workerNew)),
- );
+ workerSelected.value = JSON.parse(JSON.stringify(props.preselectWorker));
}
getWorkerList();
}
@@ -306,42 +296,6 @@ watch(
function setCurrentBranchId() {
employeeFormState.value.currentBranchId = props.customerBranchId;
}
-
-watch(
- () => employeeFormState.value.currentCustomerBranch,
- (e) => {
- if (!e) return;
- if (employeeFormState.value.formDataEmployeeSameAddr) {
- currentFromDataEmployee.value.address = e.address;
- currentFromDataEmployee.value.addressEN = e.addressEN;
- currentFromDataEmployee.value.provinceId = e.provinceId;
- currentFromDataEmployee.value.districtId = e.districtId;
- currentFromDataEmployee.value.subDistrictId = e.subDistrictId;
- }
- currentFromDataEmployee.value.customerBranchId = e.id;
- },
-);
-
-watch(
- () => employeeFormState.value.formDataEmployeeSameAddr,
- (isSame) => {
- if (!employeeFormState.value.currentCustomerBranch) return;
- if (isSame) {
- currentFromDataEmployee.value.address =
- employeeFormState.value.currentCustomerBranch.address;
- currentFromDataEmployee.value.addressEN =
- employeeFormState.value.currentCustomerBranch.addressEN;
- currentFromDataEmployee.value.provinceId =
- employeeFormState.value.currentCustomerBranch.provinceId;
- currentFromDataEmployee.value.districtId =
- employeeFormState.value.currentCustomerBranch.districtId;
- currentFromDataEmployee.value.subDistrictId =
- employeeFormState.value.currentCustomerBranch.subDistrictId;
- }
- currentFromDataEmployee.value.customerBranchId =
- employeeFormState.value.currentCustomerBranch.id;
- },
-);
@@ -614,14 +568,11 @@ watch(
solid
id="btn-success"
@click="
- () => {
- $emit('success', {
- worker: workerSelected,
- newWorker: newWorkerList,
- });
-
- open = false;
- }
+ emits('success', {
+ worker: workerSelected,
+ newWorker: newWorkerList,
+ }),
+ (open = false)
"
>
{{ $t('general.select', { msg: $t('quotation.employeeList') }) }}
@@ -643,11 +594,9 @@ watch(
if (employeeFormState.currentTab === 'personalInfo') {
const currentEmployeeId =
await employeeFormStore.submitPersonal(onCreateImageList);
- newWorkerList.push(
- quotationForm.injectNewEmployee({
- data: { ...currentFromDataEmployee, id: currentEmployeeId },
- }),
- );
+ quotationForm.injectNewEmployee({
+ data: { ...currentFromDataEmployee, id: currentEmployeeId },
+ });
employeeFormState.isEmployeeEdit = false;
employeeFormState.dialogType = 'info';
}
@@ -678,7 +627,6 @@ watch(
:show="
() => {
employeeFormStore.resetFormDataEmployee(true);
- setCurrentBranchId();
}
"
:before-close="
@@ -752,20 +700,6 @@ watch(
"
:toggleTitle="$t('status.title')"
hideFade
- :title="
- currentFromDataEmployee
- ? setPrefixName(
- {
- namePrefix: currentFromDataEmployee.namePrefix,
- firstName: currentFromDataEmployee.firstName,
- lastName: currentFromDataEmployee.lastName,
- firstNameEN: currentFromDataEmployee.firstNameEN,
- lastNameEN: currentFromDataEmployee.lastNameEN,
- },
- { locale },
- )
- : '-'
- "
@view="
() => {
employeeFormState.imageDialog = true;
@@ -1051,7 +985,6 @@ watch(
@@ -1699,7 +1628,6 @@ watch(
v-model:remark="value.remark"
v-model:worker-type="value.workerType"
v-model:number="value.number"
- v-model:report-date="value.reportDate"
>
{{ $t('general.expirationDate') }} :
@@ -2010,8 +1938,8 @@ watch(
}
:deep(
- i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-item__toggle-icon--rotated
-) {
+ i.q-icon.mdi.mdi-chevron-down-circle.q-expansion-item__toggle-icon.q-expansion-item__toggle-icon--rotated
+ ) {
color: var(--brand-1);
}
@@ -2028,9 +1956,9 @@ watch(
}
:deep(
- .q-item.q-item-type.row.no-wrap.q-item--dense.q-item--clickable.q-link.cursor-pointer.q-focusable.q-hoverable.surface-1
- .q-focus-helper
-) {
+ .q-item.q-item-type.row.no-wrap.q-item--dense.q-item--clickable.q-link.cursor-pointer.q-focusable.q-hoverable.surface-1
+ .q-focus-helper
+ ) {
visibility: hidden;
}
diff --git a/src/pages/05_quotation/form.ts b/src/pages/05_quotation/form.ts
index 5b16785a..45801a5a 100644
--- a/src/pages/05_quotation/form.ts
+++ b/src/pages/05_quotation/form.ts
@@ -8,7 +8,6 @@ import {
QuotationPayload,
QuotationFull,
EmployeeWorker,
- PayCondition,
} from 'src/stores/quotations/types';
import { Employee } from 'src/stores/employee/types';
@@ -30,7 +29,7 @@ export const DEFAULT_DATA: QuotationPayload = {
payBillDate: new Date(),
paySplit: [],
paySplitCount: 0,
- payCondition: PayCondition.Full,
+ payCondition: 'Full',
dueDate: new Date(Date.now() + 86400000),
discount: 0,
contactTel: '',
@@ -41,7 +40,6 @@ export const DEFAULT_DATA: QuotationPayload = {
status: 'CREATED',
remark: '#[quotation-labor]
#[quotation-payment]',
agentPrice: false,
- sellerId: '',
};
const DEFAULT_DATA_INVOICE: InvoicePayload = {
@@ -69,7 +67,6 @@ export const useQuotationForm = defineStore('form-quotation', () => {
file?: File;
_meta?: Record;
}[];
- workerNew: boolean;
})[]
>([]);
@@ -221,7 +218,7 @@ export const useQuotationForm = defineStore('form-quotation', () => {
},
callback?: () => void,
) {
- const temp = {
+ newWorkerList.value.push({
//passportNo: obj.data.passportNo,
//documentExpireDate: obj.data.documentExpireDate,
id: obj.data.id,
@@ -236,12 +233,9 @@ export const useQuotationForm = defineStore('form-quotation', () => {
gender: obj.data.gender,
dateOfBirth: obj.data.dateOfBirth,
attachment: obj.data.attachment,
- workerNew: true,
- };
+ });
callback?.();
-
- return temp;
}
function dialogDelete(callback: () => void) {
diff --git a/src/pages/05_quotation/preview/ViewForm.vue b/src/pages/05_quotation/preview/ViewForm.vue
index 3a7fd081..0a12408f 100644
--- a/src/pages/05_quotation/preview/ViewForm.vue
+++ b/src/pages/05_quotation/preview/ViewForm.vue
@@ -1,6 +1,6 @@
-
-
-
-
- {{ $t('general.status') }}
-
-
+
+
+
-
+
@@ -1046,18 +954,13 @@ watch(
}
"
@change-status="triggerChangeStatus"
- @delete-attachment="deleteAttachment"
:readonly="!pageState.isDrawerEdit"
:isEdit="pageState.isDrawerEdit"
- :hide-action="!canAccess('agencies', 'edit')"
v-model="pageState.addModal"
v-model:drawer-model="pageState.viewDrawer"
v-model:data="formData"
v-model:form-bank-book="formData.bank"
- v-model:image-list-on-create="imageListOnCreate"
- v-model:deletes-status-qr-code-bank-imag="deletesStatusQrCodeBankImag"
- v-model:attachment="attachment"
- :attachment-list="attachmentList"
+ v-model:on-create-image-list="onCreateImageList"
/>
diff --git a/src/pages/08_request-list/MessengerExpansion.vue b/src/pages/08_request-list/MessengerExpansion.vue
index 456aefe4..24434d89 100644
--- a/src/pages/08_request-list/MessengerExpansion.vue
+++ b/src/pages/08_request-list/MessengerExpansion.vue
@@ -13,8 +13,6 @@ const props = defineProps<{
readonly?: boolean;
step: Step;
responsibleAreaDistrictId?: string;
- defaultMessenger?: string;
- prefix?: string;
}>();
const emit = defineEmits<{
@@ -58,7 +56,6 @@ const formData = ref(defaultForm);
function triggerUndo() {
assignToForm();
state.isEdit = false;
- refForm.value?.resetValidation();
}
async function triggerSubmit() {
@@ -87,13 +84,8 @@ function assignToForm() {
customerDutyCost: attributesForm.value.customerDutyCost ?? 30,
companyDuty: attributesForm.value.companyDuty ?? false,
companyDutyCost: attributesForm.value.companyDutyCost ?? 30,
- responsibleUserLocal: attributesForm.value.responsibleUserLocal
- ? attributesForm.value.responsibleUserLocal
- : props.responsibleAreaDistrictId
- ? false
- : true,
- responsibleUserId:
- attributesForm.value.responsibleUserId || props.defaultMessenger,
+ responsibleUserLocal: attributesForm.value.responsibleUserLocal ?? true,
+ responsibleUserId: attributesForm.value.responsibleUserId ?? '',
individualDuty: attributesForm.value.individualDuty ?? false,
individualDutyCost: attributesForm.value.individualDutyCost ?? 10,
}),
@@ -117,21 +109,21 @@ function assignToForm() {
refForm?.submit(e)"
/>
diff --git a/src/pages/08_request-list/ProductExpansion.vue b/src/pages/08_request-list/ProductExpansion.vue
index ed5f5784..d2214d03 100644
--- a/src/pages/08_request-list/ProductExpansion.vue
+++ b/src/pages/08_request-list/ProductExpansion.vue
@@ -83,8 +83,6 @@ function changeableStatus(currentStatus?: RequestWorkStatus) {
(),
{
id: '',
@@ -129,7 +128,7 @@ defineEmits<{
-import { reactive, ref, watch } from 'vue';
-import { RequestData } from 'src/stores/request-list';
-import { DialogContainer, DialogHeader } from 'src/components/dialog';
-import {
- BackButton,
- CancelButton,
- MainButton,
- SaveButton,
-} from 'src/components/button';
-import FormResponsibleUser from './FormResponsibleUser.vue';
-import FormGroupHead from './FormGroupHead.vue';
-import TableRequestList from './TableRequestList.vue';
-import { column } from './constants';
-import useAddressStore from 'src/stores/address';
-
-defineProps<{
- requestList: RequestData[];
- noLink?: boolean;
-}>();
-
-defineEmits<{
- (
- e: 'submit',
- data: {
- form: { responsibleUserLocal: boolean; responsibleUserId: string };
- selected: RequestData[];
- },
- ): void;
-}>();
-
-enum Step {
- RequestList = 1,
- Configure = 2,
-}
-
-const open = defineModel({ default: false });
-const step = ref(Step.RequestList);
-const selected = ref([]);
-const listSameArea = ref([]);
-const form = reactive({
- responsibleUserLocal: false,
- responsibleUserId: '',
-});
-
-function reset() {
- step.value = Step.RequestList;
- selected.value = [];
- form.responsibleUserLocal = false;
- form.responsibleUserId = '';
-}
-
-function prev() {
- step.value = Step.RequestList;
-}
-
-watch(
- () => selected.value,
- async () => {
- if (selected.value.length === 1) {
- const districtId = selected.value[0].quotation.customerBranch.districtId;
- const ret = await useAddressStore().listSameOfficeArea(districtId);
- if (ret) listSameArea.value = ret;
- }
- },
-);
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ label }}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t('general.next') }}
-
-
-
-
-
-
-
-
diff --git a/src/pages/08_request-list/RequestListView.vue b/src/pages/08_request-list/RequestListView.vue
index afb649b8..a908e4d5 100644
--- a/src/pages/08_request-list/RequestListView.vue
+++ b/src/pages/08_request-list/RequestListView.vue
@@ -26,7 +26,6 @@ import {
getEmployeeName,
getCustomerName,
dialogWarningClose,
- canAccess,
} from 'src/stores/utils';
import { dateFormatJS } from 'src/utils/datetime';
import { useRequestList } from 'src/stores/request-list';
@@ -55,7 +54,6 @@ import { Invoice } from 'src/stores/payment/types';
import { CreatedBy } from 'src/stores/types';
import { getUserId } from 'src/services/keycloak';
import { QuotationFull } from 'src/stores/quotations/types';
-import useUserStore from 'src/stores/user';
const { locale, t } = useI18n();
@@ -64,9 +62,7 @@ const route = useRoute();
const optionStore = useOptionStore();
const requestListStore = useRequestList();
const flowTemplateStore = useWorkflowTemplate();
-const userStore = useUserStore();
-const currentUserGroup = ref([]);
const workList = ref([]);
const statusFile = ref({
customer: {},
@@ -162,10 +158,6 @@ onMounted(async () => {
initTheme();
initLang();
- const result = await userStore.fetchUserGroup();
-
- currentUserGroup.value = result.map((v) => v.name);
-
// get data
await getData();
});
@@ -291,38 +283,26 @@ async function triggerViewFile(opt: {
if (!opt.download) window.open(url, '_blank');
}
-const responsibleList = computed(() => {
- const temp = workList.value?.reduce<
- Record
- >((acc, curr: RequestWork) => {
- curr.productService.service?.workflow?.step.forEach((v) => {
- const key = v.order.toString();
- const responsibleGroup = (
- v.responsibleGroup as unknown as { group: string }[]
- ).map((v) => v.group);
+const responsiblePersonList = computed(() => {
+ const temp = workList.value?.reduce>(
+ (acc, curr: RequestWork) => {
+ curr.productService.service?.workflow?.step.forEach((v) => {
+ const key = v.order.toString();
- if (!acc[key]) {
- acc[key] = {
- user: v.responsiblePerson.map((v) => v.user),
- group: responsibleGroup,
- };
- }
+ if (!acc[key]) acc[key] = v.responsiblePerson.map((v) => v.user);
- const current = acc[key];
+ const current = acc[key];
- v.responsiblePerson.forEach((lhs) => {
- if (current.user.find((rhs) => rhs.id === lhs.userId)) return;
- current.user.push(lhs.user);
+ v.responsiblePerson.forEach((lhs) => {
+ if (current.find((rhs) => rhs.id === lhs.userId)) return;
+ current.push(lhs.user);
+ });
});
- responsibleGroup.forEach((lhs) => {
- if (current.group.find((rhs) => rhs === lhs)) return;
- current.group.push(lhs);
- });
- });
-
- return acc;
- }, {});
+ return acc;
+ },
+ {},
+ );
return temp || {};
});
@@ -458,26 +438,6 @@ async function submitRejectCancel() {
pageState.rejectCancelDialog = false;
}
}
-
-function toCustomer(customer: RequestData['quotation']['customerBranch']) {
- if (!canAccess('customer', 'view')) return;
- const url = new URL(
- `/customer-management?tab=customer&id=${customer.customerId}`,
- window.location.origin,
- );
-
- window.open(url.toString(), '_blank');
-}
-
-function toEmployee(employee: RequestData['employee']) {
- if (!canAccess('customer', 'view')) return;
- const url = new URL(
- `/customer-management?tab=employee&id=${employee.id}`,
- window.location.origin,
- );
-
- window.open(url.toString(), '_blank');
-}
@@ -518,11 +478,11 @@ function toEmployee(employee: RequestData['employee']) {
{{ $t('flow.responsiblePerson') }}
({
name:
$i18n.locale === 'eng'
@@ -534,12 +494,8 @@ function toEmployee(employee: RequestData['employee']) {
: `/no-img-female.png`
: `${baseUrl}/user/${v.id}/profile-image/${v.selectedImage}`,
}),
- ),
- ...responsibleList[pageState.currentStep].group.map((g) => ({
- name: `${$t('general.group')} ${g}`,
- imgUrl: '/img-group.png',
- })),
- ]"
+ )
+ "
/>
-
@@ -745,7 +701,6 @@ function toEmployee(employee: RequestData['employee']) {
}"
>
-
+
{
triggerChangeStatusFile({
@@ -928,12 +870,8 @@ function toEmployee(employee: RequestData['employee']) {
/>
(),
{
row: () => [],
@@ -41,19 +36,9 @@ defineEmits<{
(e: 'rejectCancel', data: RequestData): void;
}>();
-const selected = defineModel('selected');
-
-function responsiblePerson(quotation: QuotationFull) {
+function responsiblePerson(quotation: QuotationFull): CreatedBy[] | undefined {
const productServiceList = quotation.productServiceList;
const tempPerson: CreatedBy[] = [];
- const tempGroup: {
- group: string;
- id: string;
- workflowTemplateStepId: string;
- }[] = [];
-
- const userIds = new Set();
- const groupKeys = new Set();
for (const v of productServiceList) {
const tempStep = v.service?.workflow?.step;
@@ -61,30 +46,10 @@ function responsiblePerson(quotation: QuotationFull) {
if (tempStep) {
tempStep.forEach((lhs) => {
for (const rhs of lhs.responsiblePerson) {
- if (!userIds.has(rhs.user.id)) {
- userIds.add(rhs.user.id);
- tempPerson.push(rhs.user);
- }
+ tempPerson.push(rhs.user);
}
});
-
- tempStep.forEach((lhs) => {
- const newGroup = lhs.responsibleGroup as unknown as {
- group: string;
- id: string;
- workflowTemplateStepId: string;
- }[];
-
- for (const rhs of newGroup) {
- const key = `${rhs.group}-${rhs.id}-${rhs.workflowTemplateStepId}`;
- if (!groupKeys.has(key)) {
- groupKeys.add(key);
- tempGroup.push(rhs);
- }
- }
- });
-
- return { user: tempPerson, group: tempGroup };
+ return tempPerson;
}
}
@@ -127,41 +92,10 @@ function getEmployeeName(
return (
{
['eng']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstNameEN} ${employee?.lastNameEN}`,
- ['tha']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstName || employee?.firstNameEN} ${employee?.lastName || employee?.lastNameEN}`,
+ ['tha']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstName} ${employee?.lastName}`,
}[opts?.locale || 'eng'] || '-'
);
}
-
-function toCustomer(customer: RequestData['quotation']['customerBranch']) {
- if (props.noLink) return;
- const url = new URL(
- `/customer-management?tab=customer&id=${customer.customerId}`,
- window.location.origin,
- );
-
- window.open(url.toString(), '_blank');
-}
-
-function toEmployee(employee: RequestData['employee']) {
- if (props.noLink) return;
- const url = new URL(
- `/customer-management?tab=employee&id=${employee.id}`,
- window.location.origin,
- );
-
- window.open(url.toString(), '_blank');
-}
-
-function handleCheckAll() {
- const filteredRows = props.rows.filter((row) =>
- props.listSameArea?.includes(row.quotation.customerBranch.districtId),
- );
- if (selected.value.length === filteredRows.length) {
- selected.value = [];
- } else {
- selected.value = filteredRows;
- }
-}
-
-
-
-
{{ col.label && $t(col.label) }}
@@ -217,32 +125,9 @@ function handleCheckAll() {
} & Omit[0], 'row'>"
>
-
-
-
{{ props.rowIndex + 1 }}
@@ -253,53 +138,21 @@ function handleCheckAll() {
-
- {{
- getCustomerName(props.row, {
- noCode: true,
- locale: $i18n.locale,
- }) || '-'
- }}
-
+ {{
+ getCustomerName(props.row, {
+ noCode: true,
+ locale: $i18n.locale,
+ }) || '-'
+ }}
-
- {{ getEmployeeName(props.row, { locale: $i18n.locale }) || '-' }}
-
+ {{ getEmployeeName(props.row, { locale: $i18n.locale }) || '-' }}
-
-
- {{
- props.row.employee.employeePassport.length !== 0
- ? props.row.employee.employeePassport[0].number
- : '-'
- }}
-
-
- {{
- $i18n.locale === 'eng'
- ? props.row.dataOffice.nameEN
- : props.row.dataOffice.name
- }}
-
-
- {{ dateFormatJS({ date: props.row.createdAt }) }}
-
-
{{ props.row.quotation.code || '-' }}
-
-
+ />
0"
+ :data="
+ responsiblePerson(props.row.quotation)?.map((v) => {
+ return {
+ name:
+ $i18n.locale === 'eng'
+ ? `${v.firstNameEN} ${v.lastNameEN}`
+ : `${v.firstName} ${v.lastName}`,
+ imgUrl: !v.selectedImage
+ ? v.gender === 'male'
+ ? `/no-img-man.png`
+ : `/no-img-female.png`
+ : `${baseUrl}/user/${v.id}/profile-image/${v.selectedImage}`,
+ };
+ })
"
- :data="[
- ...responsiblePerson(props.row.quotation).user.map((v) => ({
- name:
- $i18n.locale === 'eng'
- ? `${v.firstNameEN} ${v.lastNameEN}`
- : `${v.firstName} ${v.lastName}`,
- imgUrl: !v.selectedImage
- ? v.gender === 'male'
- ? `/no-img-man.png`
- : `/no-img-female.png`
- : `${baseUrl}/user/${v.id}/profile-image/${v.selectedImage}`,
- })),
- ...responsiblePerson(props.row.quotation).group.map((g) => ({
- name: `${$t('general.group')} ${g.group}`,
- imgUrl: '/img-group.png',
- })),
- ]"
/>
-
@@ -581,15 +406,4 @@ function handleCheckAll() {
background: var(--red-8);
}
}
-
-.link {
- color: hsl(var(--info-bg));
- text-decoration: underline;
- cursor: pointer;
-}
-
-.disabled-row {
- opacity: 0.3;
- filter: grayscale(1);
-}
diff --git a/src/pages/08_request-list/constants.ts b/src/pages/08_request-list/constants.ts
index c71aac2e..2534aea5 100644
--- a/src/pages/08_request-list/constants.ts
+++ b/src/pages/08_request-list/constants.ts
@@ -28,24 +28,6 @@ export const column = [
label: 'customer.employee',
field: 'employee',
},
- {
- name: 'employeePassport',
- align: 'center',
- label: 'customerEmployee.form.passportNo',
- field: 'employeePassport',
- },
- {
- name: 'dataOffice',
- align: 'center',
- label: 'requestList.dataOffice',
- field: 'dataOffice',
- },
- {
- name: 'createdAt',
- align: 'center',
- label: 'general.createdAt',
- field: 'createdAt',
- },
{
name: 'quotationCode',
diff --git a/src/pages/09_task-order/MainPage.vue b/src/pages/09_task-order/MainPage.vue
index 2a9f22bd..a842b431 100644
--- a/src/pages/09_task-order/MainPage.vue
+++ b/src/pages/09_task-order/MainPage.vue
@@ -1,11 +1,10 @@
- {{
- pageState.isMessenger
- ? pageState.total
- : stats[pageState.currentTab as TaskOrderStatus]
- }}
+ {{ Object.values(stats).reduce((s, v) => s + v, 0) }}
-
-
-
-
diff --git a/src/pages/09_task-order/SelectReadyRequestWork.vue b/src/pages/09_task-order/SelectReadyRequestWork.vue
index 5276a1a5..34d9dd22 100644
--- a/src/pages/09_task-order/SelectReadyRequestWork.vue
+++ b/src/pages/09_task-order/SelectReadyRequestWork.vue
@@ -4,7 +4,6 @@ import {
useRequestList,
RequestWork,
RequestWorkStatus,
- RequestDataStatus,
} from 'src/stores/request-list';
import DialogHeader from 'src/components/dialog/DialogHeader.vue';
import CancelButton from 'src/components/button/CancelButton.vue';
@@ -193,8 +192,7 @@ function submit() {
s.workStatus ===
(props.creditNote
? RequestWorkStatus.Canceled
- : RequestWorkStatus.InProgress) ||
- v.request.requestDataStatus === RequestDataStatus.Canceled,
+ : RequestWorkStatus.InProgress),
);
if (curr) {
const task: Task = {
@@ -295,7 +293,6 @@ function assignTempGroup() {
class="bordered-b"
>