import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core'; import { ToastrService } from 'ngx-toastr'; import { BranchModel, MyBranchModel } from 'src/app/shared/model/branch.model'; import { Bu1Model, MyBu1Model } from 'src/app/shared/model/bu1.model'; import { EmpGroupModel, MyEmpGroupModel } from 'src/app/shared/model/emp-group.model'; import { EmpTypeModel, MyEmpTypeModel } from 'src/app/shared/model/employee-type.model'; import { EmployeeModel, MyEmployeeModel } from 'src/app/shared/model/employee.model'; import { JobCodeModel, MyJobCodeModel } from 'src/app/shared/model/job-code.model'; import { MyPLModel, PLModel } from 'src/app/shared/model/pl.model'; import { MyPositionModel, PositionModel } from 'src/app/shared/model/position.model'; import { Bu1Service } from 'src/app/shared/services/bu1.service'; import { EmpGroupService } from 'src/app/shared/services/emp-group.service'; import { EmpTypeService } from 'src/app/shared/services/employee-type.service'; import { EmployeeService } from 'src/app/shared/services/employee.service'; import { FileService } from 'src/app/shared/services/file.service'; import { PLService } from 'src/app/shared/services/pl.service'; import { PositionService } from 'src/app/shared/services/position.service'; import { BranchService } from 'src/app/shared/services/่branch.service'; import { JobCodeService } from 'src/app/shared/services/job-code.service'; export interface DataEmployee { loading: boolean select: EmployeeModel | any dataList: { check: boolean data: EmployeeModel }[] } export interface DataModal { search: string, currentPage: number, page: number[] } @Component({ selector: 'app-sub-employee-registration', templateUrl: './sub-employee-registration.component.html', styleUrls: ['./sub-employee-registration.component.scss'] }) export class SubEmployeeRegistrationComponent { employee: DataEmployee = { loading: false, select: new MyEmployeeModel({}), dataList: [] } currentPage = 1 page = Array.from({ length: 1 }, (_, i) => i + 1); search = "" modalType: 'add' | 'update' | 'delete' | 'deleteGroup' = 'add' modal: DataModal = { search: "", currentPage: 1, page: Array.from({ length: 1 }, (_, i) => i + 1) } numDataListChecked = 0 isDataListChecked = false isDataListCheckedAll = false selectedFile: File | null = null; selectedFileName: string = 'กรุณาเลือกไฟล์'; empGroup: { loading: boolean, dataList: EmpGroupModel[] } = { loading: false, dataList: [] } bu1: { loading: boolean, dataList: Bu1Model[] } = { loading: false, dataList: [] } position: { loading: boolean, dataList: PositionModel[] } = { loading: false, dataList: [] } jobcode: { loading: boolean, dataList: JobCodeModel[] } = { loading: false, dataList: [] } branch: { loading: boolean, dataList: BranchModel[] } = { loading: false, dataList: [] } empType: { loading: boolean, dataList: EmpTypeModel[] } = { loading: false, dataList: [] } pl: { loading: boolean, dataList: PLModel[] } = { loading: false, dataList: [] } constructor(private toastr: ToastrService, private employeeService: EmployeeService, private cdr: ChangeDetectorRef, private empGroupService: EmpGroupService, private bu1Service: Bu1Service, private positionService: PositionService, private jobcodeService: JobCodeService, private branchService: BranchService, private empTypeService: EmpTypeService, private fileService: FileService, private pLService: PLService) { } ngOnInit(): void { this.getEmployeeList() this.getEmpGroupList() this.getBu1List() this.getPositionList() this.getJobcodeList() this.getBranchList() this.getEmpTypeList() this.getPlList() } onFileSelected(event: any) { this.selectedFile = event.target.files.length > 0 ? event.target.files[0] : null; this.selectedFileName = this.selectedFile?.name || "กรุณาเลือกไฟล์" } uploadFile() { if (!this.selectedFile) { alert('กรุณาเลือกไฟล์ก่อนอัปโหลด') return } const formData = new FormData(); formData.append('file', this.selectedFile); this.employee.loading = true this.fileService.uploadExcel(formData, 'memployee').subscribe({ next: response => { if (response.success) { this.showAlert(response.message, 'success') this.getEmployeeList() } else { this.showAlert(response.message, 'error') this.employee.loading = false this.cdr.detectChanges(); } }, error: error => { this.showAlert(error.message, 'error') this.employee.loading = false this.cdr.detectChanges(); } }) } downloadFile() { const fileName = 'IMPORT_MEMPLOYEE.xlsx' this.fileService.downloadTemplate(fileName).subscribe({ next: response => { const url = window.URL.createObjectURL(response); const a = document.createElement("a"); a.href = url; a.download = fileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); }, error: error => { this.showAlert(error.message, 'error') } }) } getPlList() { this.pl.loading = false this.pLService.getList().subscribe({ next: response => { this.pl.dataList = response.map((x: any) => new MyPLModel(x)) this.pl.loading = false this.searchChange() this.cdr.detectChanges() }, error: error => { this.pl.loading = false this.cdr.detectChanges() } }) } plListFilter() { return this.pl.dataList.filter(x => x.plId.toLowerCase().includes(this.search.toLowerCase()) || x.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.edesc.toLowerCase().includes(this.search.toLowerCase())) } getEmpTypeList() { this.empType.loading = false this.empTypeService.getList().subscribe({ next: response => { this.empType.dataList = response.map((x: any) => new MyEmpTypeModel(x)) this.empType.loading = false this.searchChange() this.cdr.detectChanges() }, error: error => { this.empType.loading = false this.cdr.detectChanges() } }) } empTypeListFilter() { return this.empType.dataList.filter(x => x.codeId.toLowerCase().includes(this.search.toLowerCase()) || x.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.edesc.toLowerCase().includes(this.search.toLowerCase())) } getBranchList() { this.branch.loading = false this.branchService.getList().subscribe({ next: response => { this.branch.dataList = response.map((x: any) => new MyBranchModel(x)) this.branch.loading = false this.searchChange() this.cdr.detectChanges() }, error: error => { this.branch.loading = false this.cdr.detectChanges() } }) } branchListFilter() { return this.branch.dataList.filter(x => x.branchId.toLowerCase().includes(this.search.toLowerCase()) || x.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.edesc.toLowerCase().includes(this.search.toLowerCase())) } getJobcodeList() { this.jobcode.loading = false this.jobcodeService.getList().subscribe({ next: response => { this.jobcode.dataList = response.map((x: any) => new MyJobCodeModel(x)) this.jobcode.loading = false this.searchChange() this.cdr.detectChanges() }, error: error => { this.jobcode.loading = false this.cdr.detectChanges() } }) } jobcodeListFilter() { return this.jobcode.dataList.filter(x => x.jobcodeId.toLowerCase().includes(this.search.toLowerCase()) || x.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.edesc.toLowerCase().includes(this.search.toLowerCase())) } getPositionList() { this.position.loading = false this.positionService.getList().subscribe({ next: response => { this.position.dataList = response.map((x: any) => new MyPositionModel(x)) this.position.loading = false this.searchChange() this.cdr.detectChanges() }, error: error => { this.position.loading = false this.cdr.detectChanges() } }) } positionListFilter() { return this.position.dataList.filter(x => x.positionId.toLowerCase().includes(this.search.toLowerCase()) || x.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.edesc.toLowerCase().includes(this.search.toLowerCase())) } getBu1List() { this.bu1.loading = false this.bu1Service.getList().subscribe({ next: response => { this.bu1.dataList = response.map((x: any) => new MyBu1Model(x)) this.bu1.loading = false this.searchChange() this.cdr.detectChanges() }, error: error => { this.bu1.loading = false this.cdr.detectChanges() } }) } bu1ListFilter() { return this.bu1.dataList.filter(x => x.bu1id.toLowerCase().includes(this.search.toLowerCase()) || x.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.edesc.toLowerCase().includes(this.search.toLowerCase())) } getEmpGroupList() { this.empGroup.loading = false this.empGroupService.getList().subscribe({ next: response => { this.empGroup.dataList = response.map((x: any) => new MyEmpGroupModel(x)) this.empGroup.loading = false this.searchChange() this.cdr.detectChanges() }, error: error => { this.empGroup.loading = false this.cdr.detectChanges() } }) } empGroupListFilter() { return this.empGroup.dataList.filter(x => x.groupId.toLowerCase().includes(this.search.toLowerCase()) || x.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.edesc.toLowerCase().includes(this.search.toLowerCase())) } getEmployeeList() { this.employee.loading = true this.employeeService.getList().subscribe({ next: response => { this.employee.dataList = response.map((x: any) => ({ check: false, data: new MyEmployeeModel(x) })) this.employee.loading = false this.isDataListCheckedAll = false this.dataListCheckAll() this.searchChange() this.cdr.detectChanges() }, error: error => { this.employee.loading = false this.cdr.detectChanges() } }) } updateEmployeeList(type: 'add' | 'update' | 'delete' | 'deleteGroup') { let body = this.employee.select switch (type) { case 'delete': { body = [this.employee.select] break; } case 'deleteGroup': { body = this.employee.dataList.filter(x => x.check).map(x => new MyEmployeeModel(x.data)) type = 'delete' break; } } this.employee.loading = true this.employeeService[type](body).subscribe({ next: response => { if (response.success) { this.showAlert(response.message, 'success') this.getEmployeeList() } else { this.showAlert(response.message, 'error') this.employee.loading = false this.cdr.detectChanges() } }, error: error => { this.showAlert(error.message, 'error') this.employee.loading = false this.cdr.detectChanges() } }) } searchChange() { this.currentPage = 1 this.page = Array.from({ length: Math.ceil(this.employeeFilter().length / 10) }, (_, i) => i + 1); this.dataListCheck() } employeeFilter() { return this.employee.dataList.filter(x => x.data.employeeId.toLowerCase().includes(this.search.toLowerCase()) || x.data.fname.toLowerCase().includes(this.search.toLowerCase()) || x.data.lname.toLowerCase().includes(this.search.toLowerCase()) || x.data.position.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.data.jobCode.tdesc.toLowerCase().includes(this.search.toLowerCase())) } selectEmployee(data?: EmployeeModel) { this.employee.select = { ...new MyEmployeeModel(data || {}), dateIso: this.toISODate(data?.firstHireDate) } } changeDate(target: { [key: string]: any }, field: string, dateIso: string) { target[field] = this.toYYYYMMDD(dateIso) } toISODate(dateInput?: string | null): string { if (!dateInput) return ""; const parsedDate = new Date(dateInput); return isNaN(parsedDate.getTime()) ? new Date().toISOString() : parsedDate.toISOString(); } toYYYYMMDD(dateInput?: string | null): string { if (!dateInput) return ""; const parsedDate = new Date(dateInput); const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: '2-digit', day: '2-digit', }; const formattedDate = parsedDate.toLocaleDateString('en-GB', options); const [day, month, year] = formattedDate.split('/'); return `${year}-${month}-${day}`; } searchModalChange(dataList: any[]) { this.modal.currentPage = 1 this.modal.page = Array.from({ length: Math.ceil(dataList.length / 10) }, (_, i) => i + 1); } selectDataModal(target: { [key: string]: any }, field: string, data: any) { target[field] = JSON.parse(JSON.stringify(data)) } showAlert(text: string, type: 'success' | 'error') { this.toastr[type](text, 'แจ้งเตือน', { timeOut: 3000, positionClass: 'toast-top-right', }) } dataListCheckAll() { const selectAll = this.isDataListCheckedAll; this.employee.dataList.filter(x => x.data.employeeId.toLowerCase().includes(this.search.toLowerCase()) || x.data.fname.toLowerCase().includes(this.search.toLowerCase()) || x.data.lname.toLowerCase().includes(this.search.toLowerCase()) || x.data.position.tdesc.toLowerCase().includes(this.search.toLowerCase()) || x.data.jobCode.tdesc.toLowerCase().includes(this.search.toLowerCase())).forEach(x => x.check = selectAll); this.dataListCheck(); } dataListCheck() { const dataCheck = this.employeeFilter(); this.isDataListCheckedAll = dataCheck.length ? dataCheck.every(x => x.check) : false; this.numDataListChecked = this.employee.dataList.filter(x => x.check).length; this.isDataListChecked = Boolean(this.numDataListChecked) } checkEmployeeModel() { let disable = false if (!this.employee.select.employeeId || !this.employee.select.fname || !this.employee.select.lname || !this.employee.select.empGroup.groupId || !this.employee.select.firstHireDate || !this.employee.select.bu1.bu1id || !this.employee.select.position.positionId || !this.employee.select.jobCode.jobcodeId || !this.employee.select.branch.branchId || !this.employee.select.empType.codeId || !this.employee.select.personalLevel.plId ) { disable = true } return disable } }