Commit 7aa10f5a by DESKTOP-E0VCCBD\zedan

update ระบบยืมคืน

parent 4ee746ce
...@@ -17,8 +17,12 @@ import { EquipmentModel, EquipmentStockModel } from "../../models/equipments.mod ...@@ -17,8 +17,12 @@ import { EquipmentModel, EquipmentStockModel } from "../../models/equipments.mod
import { ProjectEquipmentModel } from "../../models/project-equipments"; import { ProjectEquipmentModel } from "../../models/project-equipments";
import { ProjectMemberModel } from '../../models/project-members'; import { ProjectMemberModel } from '../../models/project-members';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { FileUploader } from 'ng2-file-upload';
import { ProjectModel } from '../../models/project.model'; import { ProjectModel } from '../../models/project.model';
import { ChangeDetectorRef } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({ @Component({
selector: 'app-emp-borrow-return-status', selector: 'app-emp-borrow-return-status',
...@@ -46,7 +50,6 @@ export class EmpBorrowReturnStatusComponent { ...@@ -46,7 +50,6 @@ export class EmpBorrowReturnStatusComponent {
projectList:ProjectModel; projectList:ProjectModel;
allSelected = false; allSelected = false;
someSelected = false; someSelected = false;
uploaderProfile: FileUploader | undefined;
uploadErrorMsg: string = ""; uploadErrorMsg: string = "";
itemsList: ProjectEquipmentModel[] = []; itemsList: ProjectEquipmentModel[] = [];
filterList: ProjectEquipmentModel[] = []; filterList: ProjectEquipmentModel[] = [];
...@@ -76,9 +79,11 @@ export class EmpBorrowReturnStatusComponent { ...@@ -76,9 +79,11 @@ export class EmpBorrowReturnStatusComponent {
isEdit = false; isEdit = false;
empList: ProjectMemberModel[] = [] empList: ProjectMemberModel[] = []
hisList: BorrowTransactionsModel [] = []; hisList: BorrowTransactionsModel [] = [];
selectedStatus: string = 'all'; selectedStatus: string = '!requested,!rejected';
isProcessing = false;
constructor( constructor(
private http: HttpClient, private http: HttpClient,
private cdr: ChangeDetectorRef,
private eqService: EquipmentService, private eqService: EquipmentService,
public translate: TranslateService, public translate: TranslateService,
private tokenService: TokenService, private tokenService: TokenService,
...@@ -101,13 +106,28 @@ export class EmpBorrowReturnStatusComponent { ...@@ -101,13 +106,28 @@ export class EmpBorrowReturnStatusComponent {
} }
loadReturnList(): void { loadReturnList(): void {
this.borrowTransactionsService.getLists().subscribe(result => { this.borrowTransactionsService.getLists().subscribe({
this.hisList = result; next: (result) => {
// เรียงลำดับจากวันที่ล่าสุด // เก็บข้อมูลทั้งหมด
this.hisList.sort((a, b) => this.hisList = result;
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
); // เรียงลำดับจากวันที่ล่าสุด
this.applyFilter(); this.hisList.sort((a, b) =>
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
);
// กรองเฉพาะรายการที่ต้องคืน (is_returnable === true)
this.hisList = this.hisList.filter(item =>
item.project_equipment?.equipment?.is_returnable === true
);
// ใช้ applyFilter เพื่อกรองตามเงื่อนไขอื่นๆ
this.applyFilter();
},
error: (err) => {
console.error('Error loading return list:', err);
// สามารถเพิ่มการแจ้งเตือนผู้ใช้ที่นี่
}
}); });
} }
...@@ -119,10 +139,30 @@ export class EmpBorrowReturnStatusComponent { ...@@ -119,10 +139,30 @@ export class EmpBorrowReturnStatusComponent {
applyFilter(): void { applyFilter(): void {
let filtered = [...this.hisList]; let filtered = [...this.hisList];
// กรองตามสถานะ // แยกค่าสถานะเป็น Array
if (this.selectedStatus !== 'all') { const statusConditions = this.selectedStatus.split(',');
filtered = filtered.filter(item => item.status === this.selectedStatus);
} // กรองตามเงื่อนไขสถานะ
filtered = filtered.filter(item => {
if (!item.status) return false;
// ตรวจสอบแต่ละเงื่อนไข
for (const condition of statusConditions) {
if (condition.startsWith('!')) {
// กรณีเงื่อนไขแบบยกเว้น (!status)
const excludedStatus = condition.substring(1);
if (item.status === excludedStatus) {
return false;
}
} else {
// กรณีเงื่อนไขแบบบังคับ (status)
if (item.status !== condition) {
return false;
}
}
}
return true;
});
// กรองตามคำค้นหา // กรองตามคำค้นหา
if (this.searchTerm) { if (this.searchTerm) {
...@@ -135,7 +175,6 @@ export class EmpBorrowReturnStatusComponent { ...@@ -135,7 +175,6 @@ export class EmpBorrowReturnStatusComponent {
} }
this.filteredList = filtered; this.filteredList = filtered;
} }
...@@ -180,7 +219,7 @@ export class EmpBorrowReturnStatusComponent { ...@@ -180,7 +219,7 @@ export class EmpBorrowReturnStatusComponent {
getStatusText(status: string): string { getStatusText(status: string): string {
switch(status) { switch(status) {
case 'requested': return 'รออนุมัติ'; case 'requested': return 'รออนุมัติ';
case 'approved': return 'อนุมัติแล้ว'; case 'approved': return 'รอคืนอุปกรณ์';
case 'rejected': return 'ไม่อนุมัติ'; case 'rejected': return 'ไม่อนุมัติ';
case 'returned': return 'คืนแล้ว'; case 'returned': return 'คืนแล้ว';
case 'repairing': return 'กำลังซ่อม'; case 'repairing': return 'กำลังซ่อม';
......
<app-page-header <app-page-header
[title]="'อนุมัตการยืมอุปกรณ์'" [title]="'อนุมัตการยืมอุปกรณ์'"
[activeTitle]="'ผู้ดูแลระบบ'" [activeTitle]="'ผู้ดูแลระบบ'"
[title1]="'อนุมัตการยืมอุปกรณ์'" [title1]="'อนุมัตการยืมอุปกรณ์'"
></app-page-header> ></app-page-header>
<div class="grid grid-cols-12 gap-x-6"> <div class="grid grid-cols-12 gap-x-6">
...@@ -12,47 +12,47 @@ ...@@ -12,47 +12,47 @@
{{ "รายการทั้งหมด" | translate }} {{ "รายการทั้งหมด" | translate }}
<span <span
class="badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle" class="badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle"
>{{ hisList.length }}</span >{{ filteredList.length }}</span
> >
</div> </div>
<!-- แท็บสถานะ --> <!-- แท็บสถานะ -->
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<!-- สถานะทั้งหมด --> <!-- สถานะทั้งหมด -->
<div> <div>
<button <button
class="px-4 py-2 rounded-full border text-sm font-medium bg-blue-100 text-blue-800 border-blue-200" class="px-4 py-2 rounded-full border text-sm font-medium bg-blue-100 text-blue-800 border-blue-200"
(click)="filterByStatus('all')" (click)="selectedStatus = '!returned'; applyFilter()"
> >
ทั้งหมด ทั้งหมด
</button> </button>
</div> </div>
<!-- สถานะรออนุมัติ --> <!-- สถานะรออนุมัติ -->
<div> <div>
<button <button
class="px-4 py-2 rounded-full border text-sm font-medium bg-warning/10 text-warning border-warning/20" class="px-4 py-2 rounded-full border text-sm font-medium bg-warning/10 text-warning border-warning/20"
(click)="filterByStatus('requested')" (click)="selectedStatus = 'requested'; applyFilter()"
> >
รออนุมัติ รออนุมัติ
</button> </button>
</div> </div>
<!-- สถานะอนุมัติแล้ว --> <!-- สถานะอนุมัติแล้ว -->
<div> <div>
<button <button
class="px-4 py-2 rounded-full border text-sm font-medium bg-success/10 text-success border-success/20" class="px-4 py-2 rounded-full border text-sm font-medium bg-success/10 text-success border-success/20"
(click)="filterByStatus('approved')" (click)="selectedStatus = 'approved'; applyFilter()"
> >
อนุมัติแล้ว อนุมัติแล้ว
</button> </button>
</div> </div>
<div> <div>
<button <button
class="px-4 py-2 rounded-full border text-sm font-medium bg-danger/10 text-danger border-danger/20" class="px-4 py-2 rounded-full border text-sm font-medium bg-danger/10 text-danger border-danger/20"
(click)="filterByStatus('rejected')" (click)="selectedStatus = 'rejected'; applyFilter()"
> >
ไม่อนุมันติ ไม่อนุมัติ
</button> </button>
</div>
</div> </div>
</div>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<div> <div>
<input <input
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
type="text" type="text"
placeholder="{{ 'ค้นหารายการ...' | translate }}" placeholder="{{ 'ค้นหารายการ...' | translate }}"
aria-label=".form-control-sm example" aria-label=".form-control-sm example"
(input)="applyFilter()"
/> />
</div> </div>
</div> </div>
...@@ -71,11 +72,11 @@ ...@@ -71,11 +72,11 @@
<table class="table whitespace-nowrap table-bordered min-w-full"> <table class="table whitespace-nowrap table-bordered min-w-full">
<thead class="bg-light"> <thead class="bg-light">
<tr> <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> <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>
...@@ -84,8 +85,9 @@ ...@@ -84,8 +85,9 @@
<tbody> <tbody>
@for(product of filteredList;track product.peId){ @for(product of filteredList;track product.peId){
<tr class="product-list"> <tr class="product-list">
<td>{{ product.project_equipment?.project?.project_name }}</td>
<td> <td>
{{ product.project_equipment?.equipment?.equipmentName}} {{ product.project_equipment?.equipment?.equipmentName }}
</td> </td>
<td> <td>
<div class="flex items-center"> <div class="flex items-center">
...@@ -95,28 +97,34 @@ ...@@ -95,28 +97,34 @@
</div> </div>
</td> </td>
<td>{{ product.quantity_borrowed }}</td> <td>{{ product.quantity_borrowed }}</td>
<td>{{ product.created_at | date:'dd/MM/yyyy HH:mm' }}</td> <td>{{ product.created_at | date : "dd/MM/yyyy HH:mm" }}</td>
<td>{{ product.returned_date | date:'dd/MM/yyyy HH:mm' }}</td>
<td> <td>
<span class="badge" [ngClass]="{ <span
'bg-success/10 text-success': product.status === 'approved', class="badge"
'bg-warning/10 text-warning': product.status === 'requested', [ngClass]="{
'bg-danger/10 text-danger': product.status === 'rejected', 'bg-success/10 text-success':
'bg-info/10 text-info': product.status === 'returned' 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) }} {{ getStatusText(product.status) }}
</span> </span>
</td> </td>
<td>{{ product.approved_by_member?.getFullname() || '-' }}</td> <td>{{ product.approved_by_member?.getFullname() || "-" }}</td>
<td> <td>
<button *ngIf="product.status === 'requested'" <button
*ngIf="product.status === 'requested'"
aria-label="button" aria-label="button"
(click)="approve(product)" (click)="approve(product)"
class="ti-btn ti-btn-sm ti-btn-success me-1" class="ti-btn ti-btn-sm ti-btn-success me-1"
> >
<i class="ri-check-line"></i> <i class="ri-check-line"></i>
</button> </button>
<button *ngIf="product.status === 'requested'" <button
*ngIf="product.status === 'requested'"
aria-label="button" aria-label="button"
(click)="reject(product)" (click)="reject(product)"
class="ti-btn ti-btn-sm ti-btn-danger" class="ti-btn ti-btn-sm ti-btn-danger"
......
...@@ -68,7 +68,7 @@ export class EmpBorrowStatusComponent { ...@@ -68,7 +68,7 @@ export class EmpBorrowStatusComponent {
isEdit = false; isEdit = false;
empList: ProjectMemberModel[] = [] empList: ProjectMemberModel[] = []
hisList: BorrowTransactionsModel [] = []; hisList: BorrowTransactionsModel [] = [];
selectedStatus: string = 'all'; selectedStatus: string = '!returned';
constructor( constructor(
private http: HttpClient, private http: HttpClient,
private eqService: EquipmentService, private eqService: EquipmentService,
...@@ -86,13 +86,23 @@ export class EmpBorrowStatusComponent { ...@@ -86,13 +86,23 @@ export class EmpBorrowStatusComponent {
} }
loadBorrowHistory(): void { loadBorrowHistory(): void {
this.borrowTransactionsService.getLists().subscribe(result => { this.borrowTransactionsService.getLists().subscribe({
this.hisList = result; next: (result) => {
// เรียงลำดับจากวันที่ล่าสุด // เก็บข้อมูลทั้งหมด
this.hisList.sort((a, b) => this.hisList = result;
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
); // เรียงลำดับจากวันที่ล่าสุด
this.applyFilter(); this.hisList.sort((a, b) =>
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
);
// ใช้ applyFilter เพื่อกรองตามเงื่อนไขอื่นๆ
this.applyFilter();
},
error: (err) => {
console.error('Error loading return list:', err);
// สามารถเพิ่มการแจ้งเตือนผู้ใช้ที่นี่
}
}); });
} }
...@@ -194,10 +204,30 @@ export class EmpBorrowStatusComponent { ...@@ -194,10 +204,30 @@ export class EmpBorrowStatusComponent {
applyFilter(): void { applyFilter(): void {
let filtered = [...this.hisList]; let filtered = [...this.hisList];
// กรองตามสถานะ // แยกค่าสถานะเป็น Array
if (this.selectedStatus !== 'all') { const statusConditions = this.selectedStatus.split(',');
filtered = filtered.filter(item => item.status === this.selectedStatus);
} // กรองตามเงื่อนไขสถานะ
filtered = filtered.filter(item => {
if (!item.status) return false;
// ตรวจสอบแต่ละเงื่อนไข
for (const condition of statusConditions) {
if (condition.startsWith('!')) {
// กรณีเงื่อนไขแบบยกเว้น (!status)
const excludedStatus = condition.substring(1);
if (item.status === excludedStatus) {
return false;
}
} else {
// กรณีเงื่อนไขแบบบังคับ (status)
if (item.status !== condition) {
return false;
}
}
}
return true;
});
// กรองตามคำค้นหา // กรองตามคำค้นหา
if (this.searchTerm) { if (this.searchTerm) {
...@@ -210,8 +240,6 @@ export class EmpBorrowStatusComponent { ...@@ -210,8 +240,6 @@ export class EmpBorrowStatusComponent {
} }
this.filteredList = filtered; this.filteredList = filtered;
} }
} }
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