jws-frontend/src/pages/05_quotation/MainPage.vue
2024-09-30 11:42:40 +07:00

1196 lines
37 KiB
Vue

<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue';
import { storeToRefs } from 'pinia';
import {
productTreeDecoration,
pageTabs,
fieldSelectedOption,
} from './constants';
import useProductServiceStore from 'src/stores/product-service';
import {
ProductGroup,
ProductList,
Service,
} from 'src/stores/product-service/types';
import {
EditButton,
DeleteButton,
SaveButton,
UndoButton,
} from 'components/button';
import {
UploadFileGroup,
FormTm6,
noticeJobEmployment,
} from 'components/upload-file';
import BasicInformation from 'components/03_customer-management/employee/BasicInformation.vue';
import FormReferDocument from 'src/components/05_quotation/FormReferDocument.vue';
import FormPerson from 'components/02_personnel-management/FormPerson.vue';
import { DialogContainer, DialogHeader } from 'components/dialog';
import ProfileBanner from 'components/ProfileBanner.vue';
import { AddressForm } from 'components/form';
import {
EmployerFormBasicInfo,
EmployerFormBusiness,
EmployerFormContact,
EmployerFormAbout,
} from 'src/pages/03_customer-management/components';
import { CustomerBranchCreate } from 'stores/customer/types';
import DialogForm from 'components/DialogForm.vue';
import useFlowStore from 'src/stores/flow';
import { Employee } from 'src/stores/employee/types';
import QuotationForm from './QuotationForm.vue';
import TreeView from 'src/components/shared/TreeView.vue';
import MainButton from 'src/components/button/MainButton.vue';
import { AddButton } from 'src/components/button';
import StatCardComponent from 'src/components/StatCardComponent.vue';
import CreateButton from 'src/components/AddButton.vue';
import PaginationComponent from 'src/components/PaginationComponent.vue';
import QuotationCard from 'src/components/05_quotation/QuotationCard.vue';
import FormAbout from 'src/components/05_quotation/FormAbout.vue';
import SelectZone from 'src/components/shared/SelectZone.vue';
import PersonCard from 'src/components/shared/PersonCard.vue';
import { useRouter } from 'vue-router';
import ProductServiceForm from './ProductServiceForm.vue';
const flowStore = useFlowStore();
import {
useCustomerForm,
useEmployeeForm,
} from 'src/pages/03_customer-management/form';
import useCustomerStore from 'stores/customer';
const tabFieldRequired = ref<{ [key: string]: (keyof CustomerBranchCreate)[] }>(
{
main: [],
business: ['businessType', 'jobPosition'],
address: [
'homeCode',
'address',
'addressEN',
'provinceId',
'districtId',
'subDistrictId',
],
contact: [],
},
);
const customerFormStore = useCustomerForm();
const employeeFormStore = useEmployeeForm();
const customerStore = useCustomerStore();
const { state: customerFormState, currentFormData: customerFormData } =
storeToRefs(customerFormStore);
const { state: employeeFormState, currentFromDataEmployee } =
storeToRefs(employeeFormStore);
const test1 = ref(true);
const test2 = ref(true);
const dialog = ref(true);
const nodes = ref([
{
title: 'กลุ่มสินค้าและบริการที่ 1',
subtitle: 'TG01000000001',
selected: false,
children: [
{
title: 'งานที่ 1',
subtitle: 'TG01000000001',
selected: false,
children: [
{
title: 'สินค้า 1',
subtitle: 'TG01000000001',
selected: false,
},
{
title: 'สินค้า 2',
subtitle: 'TG01000000001',
selected: false,
},
{
title: 'สินค้า 3',
subtitle: 'TG01000000001',
selected: false,
},
{
title: 'สินค้า 4',
subtitle: 'TG01000000001',
selected: false,
},
{
title: 'สินค้า 5',
subtitle: 'TG01000000001',
selected: false,
},
{
title: 'สินค้า 6',
subtitle: 'TG01000000001',
selected: false,
},
],
},
],
},
]);
const productServiceStore = useProductServiceStore();
const router = useRouter();
type ProductGroupId = string;
const productGroup = ref<ProductGroup[]>([]);
const productList = ref<Partial<Record<ProductGroupId, ProductList[]>>>({});
const serviceList = ref<Partial<Record<ProductGroupId, Service[]>>>({});
type Id = string;
const product = ref<Record<Id, ProductList>>({});
const service = ref<Record<Id, Service>>({});
const selectedGroup = ref<ProductGroup | null>(null);
const selectedGroupSub = ref<'product' | 'service' | null>(null);
const selectedProductServiceId = ref('');
const selectedEmployee = ref<Employee[]>([]);
const pageState = reactive({
hideStat: false,
inputSearch: '',
statusFilter: 'all',
fieldSelected: [],
gridView: false,
currentTab: 'all',
addModal: false,
quotationModal: false,
employeeModal: false,
productServiceModal: false,
currentMaxPage: 1,
currentPage: 1,
pageSize: 30,
});
const statData = ref<
{
icon: string;
count: number;
label: string;
color:
| 'pink'
| 'purple'
| 'green'
| 'orange'
| 'cyan'
| 'yellow'
| 'red'
| 'magenta'
| 'blue'
| 'lime'
| 'light-purple';
}[]
>([
{
icon: 'mdi-cash',
count: 0,
label: 'quotation.type.fullAmountCash',
color: 'red',
},
{
icon: 'mdi-hand-coin-outline',
count: 0,
label: 'quotation.type.installmentsCash',
color: 'blue',
},
{
icon: 'mdi-receipt-text-outline',
count: 0,
label: 'quotation.type.fullAmountBill',
color: 'lime',
},
{
icon: 'mdi-receipt-text-send-outline',
count: 0,
label: 'quotation.type.installmentsBill',
color: 'light-purple',
},
]);
function triggerAddQuotationDialog() {
pageState.addModal = true;
// TODO: form and state controll
}
function triggerQuotationDialog() {
window.open('/quotation/add-quotation', '_blank');
// TODO: form and state controll
}
function triggerSelectEmployeeDialog() {
pageState.employeeModal = true;
// TODO: form and state controll
}
function triggerProductServiceDialog() {
pageState.productServiceModal = true;
// TODO: form and state controll
}
async function getAllProduct(
groupId: string,
opts?: { force?: false; page?: number; pageSize?: number },
) {
selectedGroupSub.value = 'product';
if (!opts?.force && productList.value[groupId] !== undefined) return;
const ret = await productServiceStore.fetchListProduct({
page: opts?.page ?? 1,
pageSize: opts?.pageSize ?? 9999,
productGroupId: groupId,
});
if (ret) productList.value[groupId] = ret.result;
}
async function getAllService(
groupId: string,
opts?: { force?: false; page?: number; pageSize?: number },
) {
selectedGroupSub.value = 'service';
if (!opts?.force && serviceList.value[groupId] !== undefined) return;
const ret = await productServiceStore.fetchListService({
page: opts?.page ?? 1,
pageSize: opts?.pageSize ?? 9999,
productGroupId: groupId,
fullDetail: true,
});
if (ret) serviceList.value[groupId] = ret.result;
}
async function getProduct(id: string, force = false) {
selectedGroupSub.value = 'product';
selectedProductServiceId.value = id;
if (!force && product.value[id] !== undefined) return;
const ret = await productServiceStore.fetchListProductById(id);
if (ret) product.value[id] = ret;
}
async function getService(id: string, force = false) {
selectedGroupSub.value = 'service';
selectedProductServiceId.value = id;
if (!force && service.value[id] !== undefined) return;
const ret = await productServiceStore.fetchListServiceById(id);
if (ret) service.value[id] = ret;
}
function convertToTree() {
// TODO: convert product or service into selectable tree
// NOTE: this is meant to be used inside getService() and getProduct() before return and after return
}
onMounted(async () => {
const ret = await productServiceStore.fetchListProductService({
page: 1,
pageSize: 9999,
});
if (ret) productGroup.value = ret.result;
});
</script>
<template>
<div class="column full-height no-wrap">
<!-- SEC: stat -->
<section class="text-body-2 q-mb-xs flex items-center">
{{ $t('general.dataSum') }}
<q-badge
rounded
class="q-ml-sm"
style="
background-color: hsla(var(--info-bg) / 0.15);
color: hsl(var(--info-bg));
"
>
{{ '0' }}
</q-badge>
<q-btn
class="q-ml-sm"
icon="mdi-pin-outline"
color="primary"
size="sm"
flat
dense
rounded
@click="pageState.hideStat = !pageState.hideStat"
:style="pageState.hideStat ? 'rotate: 90deg' : ''"
style="transition: 0.1s ease-in-out"
/>
<q-btn
class="q-ml-sm"
label="add"
color="primary"
size="sm"
flat
dense
@click="triggerSelectEmployeeDialog"
:style="pageState.hideStat ? 'rotate: 90deg' : ''"
style="transition: 0.1s ease-in-out"
/>
<q-btn
class="q-ml-sm"
label="quo"
color="primary"
size="sm"
flat
dense
@click="triggerQuotationDialog"
:style="pageState.hideStat ? 'rotate: 90deg' : ''"
style="transition: 0.1s ease-in-out"
/>
<q-btn
class="q-ml-sm"
label="proserv"
color="primary"
size="sm"
flat
dense
@click="triggerProductServiceDialog"
:style="pageState.hideStat ? 'rotate: 90deg' : ''"
style="transition: 0.1s ease-in-out"
/>
</section>
<transition name="slide">
<div v-if="!pageState.hideStat" class="scroll q-mb-md">
<div style="display: inline-block">
<StatCardComponent
labelI18n
:branch="
pageState.currentTab === 'all'
? statData
: statData.filter((i) =>
i.label.split('.').pop()?.includes(pageState.currentTab),
)
"
:dark="$q.dark.isActive"
/>
</div>
</div>
</transition>
<!-- SEC: header content -->
<header class="col surface-1 rounded">
<div class="column full-height">
<section
class="row surface-3 justify-between full-width items-center bordered-b"
style="z-index: 1"
>
<div class="row q-py-sm q-px-md justify-between full-width">
<q-input
for="input-search"
outlined
dense
:label="$t('general.search')"
class="q-mr-md col-12 col-md-3"
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
v-model="pageState.inputSearch"
debounce="200"
>
<template #prepend>
<q-icon name="mdi-magnify" />
</template>
</q-input>
<div
class="row col-12 col-md-5"
:class="{ 'q-pt-xs': $q.screen.lt.md }"
style="white-space: nowrap"
>
<q-select
v-model="pageState.statusFilter"
outlined
dense
option-value="value"
option-label="label"
class="col"
:class="{ 'offset-md-5': pageState.gridView }"
map-options
emit-value
:for="'field-select-status'"
:hide-dropdown-icon="$q.screen.lt.sm"
:options="[
{ label: $t('general.all'), value: 'all' },
{ label: $t('general.active'), value: 'active' },
{ label: $t('general.inactive'), value: 'inactive' },
]"
></q-select>
<q-select
v-if="!pageState.gridView"
id="select-field"
for="select-field"
class="col q-ml-sm"
:options="
fieldSelectedOption.map((v) => ({
...v,
label: $t(v.label),
}))
"
:display-value="$t('general.displayField')"
:hide-dropdown-icon="$q.screen.lt.sm"
v-model="pageState.fieldSelected"
option-label="label"
option-value="value"
map-options
emit-value
outlined
multiple
dense
/>
<q-btn-toggle
id="btn-mode"
v-model="pageState.gridView"
dense
class="no-shadow bordered rounded surface-1 q-ml-sm"
:toggle-color="$q.dark.isActive ? 'grey-9' : 'grey-2'"
size="xs"
:options="[
{ value: true, slot: 'folder' },
{ value: false, slot: 'list' },
]"
>
<template v-slot:folder>
<q-icon
name="mdi-view-grid-outline"
size="16px"
class="q-px-sm q-py-xs rounded"
:style="{
color: $q.dark.isActive
? pageState.gridView
? '#C9D3DB '
: '#787B7C'
: pageState.gridView
? '#787B7C'
: '#C9D3DB',
}"
/>
</template>
<template v-slot:list>
<q-icon
name="mdi-format-list-bulleted"
class="q-px-sm q-py-xs rounded"
size="16px"
:style="{
color: $q.dark.isActive
? pageState.gridView === false
? '#C9D3DB'
: '#787B7C'
: pageState.gridView === false
? '#787B7C'
: '#C9D3DB',
}"
/>
</template>
</q-btn-toggle>
</div>
</div>
</section>
<nav class="surface-2 bordered-b q-px-md full-width">
<q-tabs
inline-label
mobile-arrows
dense
v-model="pageState.currentTab"
align="left"
class="full-width"
active-color="info"
>
<q-tab
v-for="tab in pageTabs"
:name="tab"
:key="tab"
@click="
async () => {
pageState.currentPage = 1;
pageState.currentTab = tab;
pageState.inputSearch = '';
pageState.statusFilter = 'all';
flowStore.rotate();
}
"
>
<div
class="row text-capitalize"
:class="
pageState.currentTab === tab ? 'text-bold' : 'app-text-muted'
"
>
{{ $t(`quotation.type.${tab}`) }}
</div>
</q-tab>
</q-tabs>
</nav>
<!-- SEC: body content -->
<body
v-if="true"
class="col surface-2 flex items-center justify-center"
>
<CreateButton
@click="triggerAddQuotationDialog"
label="general.add"
:i18n-args="{ text: $t('quotation.title') }"
/>
</body>
<body v-else class="col q-pa-md surface-2 scroll">
<div class="row q-col-gutter-md">
<div v-for="n in 5" :key="n" class="col-md-4 col-12">
<QuotationCard
:type="
pageState.currentTab !== 'all'
? pageState.currentTab
: 'fullAmountCash'
"
code="QT240120S0002"
title="ชื่อใบเสนอราคา"
date="20/01/2024 16:00:01"
:amount="2"
customer-name="เลด้า สวนลุม"
reporter="สตีเฟ่น สมัคร"
:total-price="1500"
@view="console.log('view')"
@edit="console.log('edit')"
@link="console.log('link')"
@upload="console.log('upload')"
@delete="console.log('delete')"
@change-status="console.log('change')"
/>
</div>
</div>
</body>
<!-- SEC: footer content -->
<footer
class="row justify-between items-center q-px-md q-py-sm surface-2"
v-if="pageState.currentMaxPage > 0"
>
<div class="col-4">
<div class="row items-center no-wrap">
<div class="app-text-muted q-mr-sm" v-if="$q.screen.gt.sm">
{{ $t('general.recordPerPage') }}
</div>
<div>
<q-btn-dropdown
dense
unelevated
:label="pageState.pageSize"
class="bordered q-pl-md"
>
<q-list>
<q-item
v-for="v in [10, 30, 50, 100, 500, 1000]"
:key="v"
clickable
v-close-popup
@click="
async () => {
pageState.pageSize = v;
}
"
>
<q-item-section>
<q-item-label>{{ v }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
</div>
</div>
<div class="col-4 row justify-center app-text-muted">
{{
$t('general.recordsPage', {
resultcurrentPage: 0,
total: 0,
})
}}
</div>
<nav class="col-4 row justify-end">
<PaginationComponent
v-model:current-page="pageState.currentPage"
v-model:max-page="pageState.currentMaxPage"
/>
<!-- :fetch-data="async () => await fetchUserList()" -->
</nav>
</footer>
</div>
</header>
</div>
<!-- SEC: Dialog -->
<!-- add quotation -->
<DialogForm
:title="$t('general.add', { text: $t('quotation.title') })"
v-model:modal="pageState.addModal"
:submit-label="$t('general.add', { text: $t('quotation.title') })"
submit-icon="mdi-check"
height="auto"
width="60vw"
>
<header class="q-mx-lg q-mt-lg">
<ProfileBanner
img="/images/quotation-bg-avatar.png"
fallback-cover="/images/quotation-banner.png"
bg-color="var(--surface-1)"
:title="$t('general.itemNo', { msg: $t('quotation.title') })"
hideActive
readonly
noImageAction
hideFade
/>
</header>
<section class="col surface-1 q-ma-lg rounded bordered row scroll">
<div
class="col-12 q-px-md q-py-lg"
id="customer-form-content"
style="height: 100%; max-height: 100%; overflow-y: auto"
>
<FormAbout prefixId="zxc" @add-customer="console.log('asdasd')" />
</div>
</section>
</DialogForm>
<!-- add employee -->
<DialogForm
:title="$t('general.select', { msg: $t('quotation.employeeList') })"
v-model:modal="pageState.employeeModal"
:submit-label="$t('general.select', { msg: $t('quotation.employee') })"
submit-icon="mdi-check"
height="75vh"
>
<section class="col row scroll">
<SelectZone
v-model:selected-item="selectedEmployee"
:items="[
{
name: 'มิเคล่า สุวรรณดี',
gender: 'female',
telephoneNo: '0621249602',
code: 'CORP000000-1-01-240001',
birthDate: '16 ปี 11 เดือน 5 วัน',
},
{
name: 'มิลิเซนต์ สุวรรณดี',
gender: 'female',
telephoneNo: '0621249666',
code: 'CORP000000-1-01-240002',
birthDate: '19 ปี 2 เดือน 2 วัน',
},
{
name: 'ไรคาร์ด พวงศรี',
gender: 'male',
telephoneNo: '0621249777',
code: 'CORP000000-1-01-240003',
birthDate: '39 ปี 5 เดือน 2 วัน',
},
]"
>
<template #top><AddButton icon-only /></template>
<template #data="{ item }">
<PersonCard
noAction
prefixId="asda"
class="full-width"
:data="{
name: item.name,
code: item.code,
female: item.gender === 'female',
male: item.gender === 'male',
img: 'images/employee-avatar.png',
detail: [
{ icon: 'mdi-phone-outline', value: item.telephoneNo },
{ icon: 'mdi-clock-outline', value: item.birthDate },
],
}"
></PersonCard>
</template>
</SelectZone>
</section>
</DialogForm>
<DialogContainer v-model="test1" :on-open="() => {}">
<template #header>
<DialogHeader
:title="
customerFormState.dialogType === 'create'
? $t(`general.add`, {
text: `${$t('customer.employer')} `,
})
: `${$t('customer.employer')} `
"
>
<template #title-after>
<span
:style="`color: hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`"
>
:
{{
customerFormData.customerType === 'CORP'
? $t('customer.employerLegalEntity')
: $t('customer.employerNaturalPerson')
}}
</span>
</template>
</DialogHeader>
</template>
<div class="q-px-lg q-pt-lg surface-2">
<ProfileBanner
v-if="customerFormData.customerBranch !== undefined"
active
hide-fade
:fallback-cover="`/images/customer-${customerFormData.customerType}-banner-bg.jpg`"
:img="
customerFormState.customerImageUrl ||
`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.customerType === 'PERS' ? customerFormData.customerBranch[0]?.gender : 'male'}.png`
"
:fallbackImg="`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.customerType === 'PERS' ? customerFormData.customerBranch[0]?.gender : 'male'}.png`"
:color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`"
:bg-color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/0.1)`"
:icon="
customerFormData.customerType === 'PERS'
? 'mdi-account-plus-outline'
: 'mdi-office-building-outline'
"
:title="
customerFormData.customerType === 'PERS'
? `${customerFormData.customerBranch[0]?.firstName} ${customerFormData.customerBranch[0]?.lastName}`
: customerFormData.customerBranch[0]?.registerName
"
:caption="
customerFormData.customerType === 'PERS'
? `${customerFormData.customerBranch[0]?.firstNameEN} ${customerFormData.customerBranch[0]?.lastNameEN}`
: customerFormData.customerBranch[0]?.registerNameEN
"
@view="
() => {
customerFormState.imageDialog = true;
customerFormState.isImageEdit = false;
}
"
@edit="
customerFormState.imageDialog = customerFormState.isImageEdit = true
"
/>
</div>
<q-form
style="flex: 1; width: 100%; overflow-y: auto"
class="surface-2 q-pa-lg"
id="customer-form"
greedy
@submit.prevent="
async () => {
console.log('test');
}
"
>
<div class="col surface-1 full-height rounded bordered scroll row">
<div
class="col-12 q-py-md q-pr-md q-pl-sm"
id="customer-form-content"
style="height: 100%; max-height: 100%; overflow-y: auto"
>
<div
class="surface-1 rounded q-pt-sm row"
style="position: absolute; z-index: 999; right: 4%"
>
<UndoButton
v-if="
employeeFormState.isEmployeeEdit &&
employeeFormState.dialogType !== 'create'
"
id="btn-info-basic-undo"
icon-only
@click="
() => {
employeeFormStore.resetFormDataEmployee();
employeeFormState.isEmployeeEdit = false;
employeeFormState.dialogType = 'info';
}
"
type="button"
/>
<SaveButton
v-if="employeeFormState.isEmployeeEdit"
id="btn-info-basic-save"
icon-only
type="submit"
/>
<EditButton
v-if="!employeeFormState.isEmployeeEdit"
id="btn-info-basic-edit"
icon-only
@click="
() => {
employeeFormState.isEmployeeEdit = true;
employeeFormState.dialogType = 'edit';
}
"
type="button"
/>
<DeleteButton
v-if="!employeeFormState.isEmployeeEdit"
id="btn-info-basic-delete"
icon-only
/>
</div>
<div
class="row full-width q-col-gutter-sm"
id="form-branch-customer-branch"
>
<!-- v-if="customerFormData.customerBranch" -->
<!-- v-if="!!customerFormState.editCustomerId" -->
<div class="col-12 text-weight-bold text-body1 row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-briefcase-outline"
style="background-color: var(--surface-3)"
/>
<span>{{ $t('customer.form.group.branch') }}</span>
</div>
<EmployerFormAbout :index="(0).toString()" customerType="CORP" />
<div class="col-12 text-weight-bold text-body1 row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-briefcase-outline"
style="background-color: var(--surface-3)"
/>
<span>{{ $t('customerBranch.tab.business') }}</span>
</div>
<EmployerFormBusiness prefixId="dialog" dense outlined />
<AddressForm
prefix-id="employer"
hide-title
dense
outlined
use-employment
:title="$t('form.address')"
:addressTitle="$t('form.address')"
:addressTitleEN="$t('form.address', { suffix: '(EN)' })"
/>
</div>
</div>
</div>
</q-form>
</DialogContainer>
<DialogForm
hideFooter
:title="$t('form.title.create', { name: $t('customer.employee') })"
v-model:modal="test2"
:undo="() => {}"
:submit="async () => {}"
:show="() => {}"
>
<div class="q-px-lg q-pt-lg surface-2">
<ProfileBanner
active
useToggle
color="white"
icon="mdi-account-plus-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"
fallbackCover="/images/employee-banner.png"
:img="employeeFormState.profileUrl || `/images/employee-avatar.png`"
:toggleTitle="$t('status.title')"
hideFade
@view="
() => {
employeeFormState.imageDialog = true;
employeeFormState.isImageEdit = false;
}
"
@edit="
employeeFormState.imageDialog = employeeFormState.isImageEdit = true
"
@update:toggle-status="
() => {
currentFromDataEmployee.status =
currentFromDataEmployee.status === 'CREATED'
? 'INACTIVE'
: 'CREATED';
}
"
/>
</div>
<div
style="flex: 1; width: 100%; overflow-y: auto"
class="surface-2 q-pa-lg"
id="drawer-employee-form"
>
<div class="col surface-1 full-height rounded bordered scroll row">
<div
class="col-12 full-width col-md-10 q-py-md q-pr-md q-pl-sm q-col-gutter-sm"
id="employee-form-content"
style="height: 100%; max-height: 100; overflow-y: auto"
>
<template v-if="employeeFormState.currentTab === 'personalInfo'">
<div
class="surface-1 rounded q-pt-sm row"
style="position: absolute; z-index: 999; right: 4%"
>
<UndoButton
v-if="
employeeFormState.isEmployeeEdit &&
employeeFormState.dialogType !== 'create'
"
id="btn-info-basic-undo"
icon-only
@click="
() => {
employeeFormStore.resetFormDataEmployee();
employeeFormState.isEmployeeEdit = false;
employeeFormState.dialogType = 'info';
}
"
type="button"
/>
<SaveButton
v-if="employeeFormState.isEmployeeEdit"
id="btn-info-basic-save"
icon-only
type="submit"
/>
<EditButton
v-if="!employeeFormState.isEmployeeEdit"
id="btn-info-basic-edit"
icon-only
@click="
() => {
employeeFormState.isEmployeeEdit = true;
employeeFormState.dialogType = 'edit';
}
"
type="button"
/>
<DeleteButton
v-if="!employeeFormState.isEmployeeEdit"
id="btn-info-basic-delete"
icon-only
/>
</div>
<FormReferDocument
title="form.field.basicInformation"
prefixId="dialog"
dense
/>
<FormPerson
id="form-personal"
prefix-id="form-employee"
dense
outlined
employee
separator
hideNameEn
title="personnel.form.personalInformation"
class="q-mb-xl"
/>
<UploadFileGroup
v-model:current-id="currentFromDataEmployee.id"
v-model="currentFromDataEmployee.file"
hide-action
:group-list="uploadFileListEmployee"
:menu="uploadFileListEmployee"
:columns="columnsAttachment"
:ocr="
async (group, file) => {
const res = await ocrStore.sendOcr({
file: file,
category: group,
});
if (res) {
const tempValue = {
status: true,
group,
meta: res.fields,
};
return tempValue;
}
return { status: false, group, meta: [] };
}
"
:auto-save="currentFromDataEmployee.id !== ''"
:download="
(obj) => {
employeeStore.getFile({
parentId: currentFromDataEmployee.id || '',
group: obj.group,
fileId: obj._meta.id,
});
}
"
:delete-item="
async (obj) => {
const res = await employeeStore.delMeta({
parentId: currentFromDataEmployee.id || '',
group: obj.group,
metaId: obj._meta.id,
});
if (res) {
return true;
}
return false;
}
"
:save="
async (
group: 'passport' | 'visa',
_meta: any,
file: File | undefined,
) => {
if (file !== undefined && currentFromDataEmployee.id) {
const res = await employeeStore.postMeta({
parentId: currentFromDataEmployee.id || '',
group,
meta: _meta,
file,
});
if (res) {
return true;
}
} else {
const { id, employeeId, createdAt, updatedAt, ...payload } =
_meta;
const res = await employeeStore.putMeta({
parentId: currentFromDataEmployee.id || '',
group,
metaId: _meta.id,
meta: payload,
file,
});
if (res) {
return true;
}
}
return false;
}
"
:get-file-list="
async (group: 'passport' | 'visa') => {
if (!!currentFromDataEmployee.id) {
const resMeta = await employeeStore.getMetaList({
parentId: currentFromDataEmployee.id,
group,
});
const tempValue = resMeta.map(async (i: any) => {
return {
_meta: { ...i },
name: i.id || '',
group: group,
url: await employeeStore.getFile({
parentId: currentFromDataEmployee.id || '',
group,
fileId: i.id,
}),
file: undefined,
};
});
return await waitAll(tempValue);
}
return [];
}
"
>
<template #form="{ mode, meta, isEdit }">
<FormCitizen
v-if="mode === 'citizen' && meta"
orc
ra
:readonly="!isEdit"
v-model:citizen-id="meta.citizenId"
v-model:birth-date="meta.birthDate"
v-model:first-name="meta.firstName"
v-model:first-name-en="meta.firstNameEN"
v-model:last-name="meta.lastName"
v-model:last-name-en="meta.lastNameEN"
v-model:address="meta.address"
/>
<FormEmployeePassport
v-if="mode === 'passport' && meta"
prefix-id="drawer-info-employee"
id="form-passport"
dense
outlined
separator
ocr
:title="$t('customerEmployee.form.group.passport')"
:readonly="!isEdit"
v-model:passport-type="meta.type"
v-model:passport-number="meta.number"
v-model:passport-issue-date="meta.issueDate"
v-model:passport-expiry-date="meta.expireDate"
v-model:passport-issuing-place="meta.issuePlace"
v-model:passport-issuing-country="meta.issueCountry"
/>
<FormEmployeeVisa
v-if="mode === 'visa' && meta"
prefix-id="drawer-info-employee"
id="form-visa"
ocr
dense
outlined
title="customerEmployee.form.group.visa"
:readonly="!isEdit"
v-model:visa-type="meta.type"
v-model:visa-number="meta.number"
v-model:visa-issue-date="meta.issueDate"
v-model:visa-expiry-date="meta.expireDate"
v-model:visa-issuing-place="meta.issuePlace"
/>
<noticeJobEmployment v-if="mode === 'noticeJobEmployment'" />
</template>
</UploadFileGroup>
</template>
</div>
</div>
</div>
</DialogForm>
<ProductServiceForm
v-model="pageState.productServiceModal"
></ProductServiceForm>
</template>
<style scoped></style>