Commit 4ee746ce by DESKTOP-E0VCCBD\zedan

update

parent 0d0c4672
......@@ -46,10 +46,8 @@ export class AdminProjectEquirementComponent {
uploadErrorMsg: string = "";
itemsList: ProjectEquipmentModel[] = []
filterList: ProjectEquipmentModel[] = []
itemsListAll: EquipmentModel[] = []
filterListAll: EquipmentModel[] = []
selectModel: ProjectEquipmentModel = new ProjectEquipmentModel()
selectStock?: EquipmentStockModel
selectedItems = new Map<string, boolean>();
......
......@@ -44,10 +44,8 @@ export class EmpBorrowManageComponent {
uploadErrorMsg: string = "";
itemsList: ProjectEquipmentModel[] = []
filterList: ProjectEquipmentModel[] = []
itemsListAll: EquipmentModel[] = []
filterListAll: EquipmentModel[] = []
selectModel: ProjectEquipmentModel = new ProjectEquipmentModel()
selectStock?: EquipmentStockModel
selectedItems = new Map<string, boolean>();
......
<p>
emp-borrow-status works!
</p>
<app-page-header
[title]="'อนุมัตการยืมอุปกรณ์'"
[activeTitle]="'ผู้ดูแลระบบ'"
[title1]="'อนุมัตการยืมอุปกรณ์'"
></app-page-header>
<div class="grid grid-cols-12 gap-x-6">
<div class="xl:col-span-12 col-span-12">
<div class="box mt-6">
<div class="box-header justify-between">
<div class="box-title">
{{ "รายการทั้งหมด" | translate }}
<span
class="badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle"
>{{ hisList.length }}</span
>
</div>
<!-- แท็บสถานะ -->
<div class="flex flex-wrap gap-2">
<!-- สถานะทั้งหมด -->
<div>
<button
class="px-4 py-2 rounded-full border text-sm font-medium bg-blue-100 text-blue-800 border-blue-200"
(click)="filterByStatus('all')"
>
ทั้งหมด
</button>
</div>
<!-- สถานะรออนุมัติ -->
<div>
<button
class="px-4 py-2 rounded-full border text-sm font-medium bg-warning/10 text-warning border-warning/20"
(click)="filterByStatus('requested')"
>
รออนุมัติ
</button>
</div>
<!-- สถานะอนุมัติแล้ว -->
<div>
<button
class="px-4 py-2 rounded-full border text-sm font-medium bg-success/10 text-success border-success/20"
(click)="filterByStatus('approved')"
>
อนุมัติแล้ว
</button>
</div>
<div>
<button
class="px-4 py-2 rounded-full border text-sm font-medium bg-danger/10 text-danger border-danger/20"
(click)="filterByStatus('rejected')"
>
ไม่อนุมันติ
</button>
</div>
</div>
<div class="flex flex-wrap gap-2">
<div>
<input
[(ngModel)]="searchTerm"
class="form-control form-control"
type="text"
placeholder="{{ 'ค้นหารายการ...' | translate }}"
aria-label=".form-control-sm example"
/>
</div>
</div>
</div>
<div class="box-body">
<div class="table-responsive">
<table class="table whitespace-nowrap table-bordered min-w-full">
<thead class="bg-light">
<tr>
<th scope="col" class="text-start">อุปกรณ์ที่ยืม</th>
<th scope="col" class="text-start">พนักงาน</th>
<th scope="col" class="text-start">จำนวน</th>
<th scope="col" class="text-start">วันที่ยืม</th>
<th scope="col" class="text-start">วันที่คืน</th>
<th scope="col" class="text-start">สถานะ</th>
<th scope="col" class="text-start">ผู้อนุมัติ</th>
<th scope="col" class="text-start">การดำเนินการ</th>
</tr>
</thead>
<tbody>
@for(product of filteredList;track product.peId){
<tr class="product-list">
<td>
{{ product.project_equipment?.equipment?.equipmentName}}
</td>
<td>
<div class="flex items-center">
<div class="font-semibold">
{{ product.member?.getFullname() }}
</div>
</div>
</td>
<td>{{ product.quantity_borrowed }}</td>
<td>{{ product.created_at | date:'dd/MM/yyyy HH:mm' }}</td>
<td>{{ product.returned_date | date:'dd/MM/yyyy HH:mm' }}</td>
<td>
<span class="badge" [ngClass]="{
'bg-success/10 text-success': product.status === 'approved',
'bg-warning/10 text-warning': product.status === 'requested',
'bg-danger/10 text-danger': product.status === 'rejected',
'bg-info/10 text-info': product.status === 'returned'
}">
{{ getStatusText(product.status) }}
</span>
</td>
<td>{{ product.approved_by_member?.getFullname() || '-' }}</td>
<td>
<button *ngIf="product.status === 'requested'"
aria-label="button"
(click)="approve(product)"
class="ti-btn ti-btn-sm ti-btn-success me-1"
>
<i class="ri-check-line"></i>
</button>
<button *ngIf="product.status === 'requested'"
aria-label="button"
(click)="reject(product)"
class="ti-btn ti-btn-sm ti-btn-danger"
>
<i class="ri-close-line"></i>
</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { BorrowTransactionsService } from './../../services/borrow-transactions.service';
import { CommonModule } from "@angular/common";
import { Component, ElementRef, ViewChild } from '@angular/core';
import { NgSelectModule } from "@ng-select/ng-select";
import { TranslateModule, TranslateService } from "@ngx-translate/core";
import { FormsModule } from "@angular/forms";
import swal from 'sweetalert';
import { SharedModule } from "../../../shared/shared.module";
import { TokenService } from "../../../shared/services/token.service";
import { BorrowTransactionsModel } from '../../models/borrow-transactions';
import { EquipmentService } from '../../services/equirement.service';
import { ProjectEquipmentService } from '../../services/project-equipments.service';
import { ProjectMemberService } from '../../services/project-members.service';
import { ProjectMemberModel } from '../../models/project-members';
import { HttpClient } from '@angular/common/http';
import { ProjectEquipmentModel } from '../../models/project-equipments';
import { EquipmentModel, EquipmentStockModel } from '../../models/equipments.model';
import { FileUploader } from 'ng2-file-upload';
@Component({
selector: 'app-emp-borrow-status',
standalone: true,
imports: [
CommonModule,
SharedModule,
TranslateModule,
NgSelectModule,
FormsModule
],
templateUrl: './emp-borrow-status.component.html',
styleUrls: ['./emp-borrow-status.component.scss']
})
export class EmpBorrowStatusComponent implements OnInit {
export class EmpBorrowStatusComponent {
@ViewChild('closeModal') public childModal?: ElementRef;
@ViewChild('closeModalStock') public closeModalStock?: ElementRef;
@ViewChild('modalDetail') public modalDetail?: ElementRef;
returnList: BorrowTransactionsModel[] = [];
selectedBorrowItem: BorrowTransactionsModel;
allSelected = false;
someSelected = false;
uploaderProfile: FileUploader | undefined;
uploadErrorMsg: string = "";
itemsList: ProjectEquipmentModel[] = [];
filterList: ProjectEquipmentModel[] = [];
itemsListAll: EquipmentModel[] = [];
filterListAll: EquipmentModel[] = [];
selectModel: ProjectEquipmentModel = new ProjectEquipmentModel()
selectStock: EquipmentStockModel
selectedItems = new Map<string, boolean>();
borrowSelect: BorrowTransactionsModel = new BorrowTransactionsModel()
filteredList: any[] = [];
pageIndex = 0;
get searchTerm(): string {
return this._searchTerm;
}
set searchTerm(val: string) {
this.pageIndex = 0;
this.allSelected = false
this._searchTerm = val;
if (val != '') {
this.filterList = this.filter(val);
} else {
this.updatePagedItems()
}
}
projectId = ""
_searchTerm = "";
isEdit = false;
empList: ProjectMemberModel[] = []
hisList: BorrowTransactionsModel [] = [];
selectedStatus: string = 'all';
constructor(
private http: HttpClient,
private eqService: EquipmentService,
public translate: TranslateService,
private tokenService: TokenService,
private projectEquipmentService: ProjectEquipmentService,
private borrowTransactionsService: BorrowTransactionsService,
private projectMemberService: ProjectMemberService) {
this.projectId = this.tokenService.getSelectCompany().projectId!;
}
ngOnInit(): void {
this.loadBorrowHistory();
}
loadBorrowHistory(): void {
this.borrowTransactionsService.getLists().subscribe(result => {
this.hisList = result;
// เรียงลำดับจากวันที่ล่าสุด
this.hisList.sort((a, b) =>
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
);
this.applyFilter();
});
}
getStatusText(status: string): string {
switch(status) {
case 'requested': return 'รออนุมัติ';
case 'approved': return 'อนุมัติแล้ว';
case 'rejected': return 'ไม่อนุมัติ';
case 'returned': return 'คืนแล้ว';
case 'repairing': return 'กำลังซ่อม';
default: return status;
}
}
approve(item : BorrowTransactionsModel){
// console.log(this.selectStock)
swal({
title: "Are you sure?",
text: "คุณต้องการบันทึกหรือไม่",
icon: "warning",
dangerMode: false,
buttons: ["Cancel", "Confirm"],
})
.then((willDelete: any) => {
if (willDelete) {
let body = {
"quantity_borrowed": item.quantity_borrowed,
"memberId" : item.memberId,
"status": "approved",
"approved_by": this.tokenService.getUser().member.memberId
}
this.borrowTransactionsService.update(item.borrowId , body).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.ngOnInit()
}, (error: any) => {
swal("Fail!!", error.error.detail, "info");
})
}
});
constructor() { }
ngOnInit() {
}
reject(item: BorrowTransactionsModel) {
swal({
title: "ยืนยันการไม่อนุมัติ",
text: "คุณต้องการไม่อนุมัติการยืมนี้หรือไม่?",
icon: "warning",
dangerMode: true,
buttons: ["ยกเลิก", "ไม่อนุมัติ"],
}).then((willReject) => {
if (willReject) {
let body = {
"quantity_borrowed": item.quantity_borrowed,
"memberId" : item.memberId,
"status": "rejected",
"approved_by": this.tokenService.getUser().member.memberId
}
this.borrowTransactionsService.update(item.borrowId, body).subscribe
(result => {
swal("ไม่อนุมัติสำเร็จ", "การยืมอุปกรณ์ถูกปฏิเสธแล้ว", "success");
this.loadBorrowHistory();
},
(error) => {
swal("เกิดข้อผิดพลาด", error.error.detail, "error");
}
);
}
});
}
filter(v: string) {
this.pageIndex = 0;
return this.itemsList?.filter(
(x) =>
x.equipment.equipmentName.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.equipment.description?.toLowerCase().indexOf(v.toLowerCase()) !== -1
);
}
updatePagedItems() {
const startIndex = this.pageIndex * 10;
const endIndex = startIndex + 10;
// this.filterList = this.itemsList.slice(startIndex, endIndex);
this.filterList = this.itemsList
}
updatePagedItemsAll() {
const startIndex = this.pageIndex * 10;
const endIndex = startIndex + 10;
// this.filterList = this.itemsList.slice(startIndex, endIndex);
this.filterListAll = this.itemsListAll
}
filterByStatus(status: string): void {
this.selectedStatus = status;
this.applyFilter();
}
applyFilter(): void {
let filtered = [...this.hisList];
// กรองตามสถานะ
if (this.selectedStatus !== 'all') {
filtered = filtered.filter(item => item.status === this.selectedStatus);
}
// กรองตามคำค้นหา
if (this.searchTerm) {
const term = this.searchTerm.toLowerCase();
filtered = filtered.filter(item =>
(item.project_equipment?.equipment?.equipmentName?.toLowerCase().includes(term)) ||
(item.member?.getFullname()?.toLowerCase().includes(term)) ||
(item.quantity_borrowed?.toString().includes(term))
);
}
this.filteredList = filtered;
}
}
......@@ -5,8 +5,10 @@ import { EquipmentModel } from "./equipments.model";
import { ProjectEquipmentModel } from "./project-equipments";
export class BorrowTransactionsModel extends BaseModel {
peId: string;
quantity_borrowed: number;
eqName:string;
status: string;
returned_date: string;
memberId: string;
......@@ -16,9 +18,11 @@ export class BorrowTransactionsModel extends BaseModel {
member: UserProfileModel;
project_equipment: ProjectEquipmentModel;
approved_by_member: UserProfileModel;
rejected_reason:string;
constructor(data?: Partial<BorrowTransactionsModel>, translateService?: TranslateService) {
super(data, translateService);
this.eqName = data?.eqName ?? '';
this.borrowId = data?.borrowId ?? '';
this.peId = data?.peId ?? '';
this.quantity_borrowed = data?.quantity_borrowed ?? 0;
......@@ -26,6 +30,7 @@ export class BorrowTransactionsModel extends BaseModel {
this.returned_date = data?.returned_date ?? ''
this.memberId = data?.memberId ?? ''
this.approved_by = data?.approved_by ?? ''
this.rejected_reason = data?.rejected_reason ?? ''
this.member = data?.member ? new UserProfileModel(data.member) : new UserProfileModel();
this.approved_by_member = data?.approved_by_member ? new UserProfileModel(data.approved_by_member) : new UserProfileModel();
this.project_equipment = data?.project_equipment ? new ProjectEquipmentModel(data.project_equipment) : new ProjectEquipmentModel();
......
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class EquipmentRepairService {
constructor() { }
}
// equipment-repair.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class EquipmentRepairService {
apiBaseUrl = "/equipments";
constructor(
private http: HttpClient
) { }
create(repairData: any) {
return this.http.post<EquipmentRepairModel>(this.apiBaseUrl, repairData);
}
update(id: number, repairData: any) {
return this.http.put(`${this.apiBaseUrl}/${id}`, repairData);
}
getList() {
return this.http.get<EquipmentRepairModel[]>(this.apiBaseUrl);
}
}
<!-- Start::Header -->
<header class="app-header">
<nav class="main-header !h-[3.75rem]" aria-label="Global">
<div class="main-header-container ps-[0.725rem] pe-[1rem] ">
<div class="main-header-container ps-[0.725rem] pe-[1rem]main-header-container ps-[0.725rem] pe-[1rem] bg-neutral-600 text-white ">
<div class="header-content-left">
<!-- Start::header-element -->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment