2025-11-11 10:52:30 +07:00
|
|
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
|
|
|
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
|
|
|
|
import { GeneralService } from '../../services/generalservice';
|
2025-11-21 15:01:21 +07:00
|
|
|
import { IDropAct, IStateDrop, IStateResultResponse, IActData, IActSumData, QuickRatio} from '../../interfaces/dashboard.interface'
|
2025-11-13 14:53:37 +07:00
|
|
|
import { DashboardStateService } from '../../services/state/dashboard-state.service';
|
2025-11-11 10:52:30 +07:00
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
|
selector: 'app-main-dashboard',
|
|
|
|
|
standalone: false,
|
|
|
|
|
templateUrl: './main-dashboard.component.html',
|
|
|
|
|
styleUrl: './main-dashboard.component.css'
|
|
|
|
|
})
|
|
|
|
|
export class MainDashboardComponent implements OnInit {
|
2025-11-21 15:01:21 +07:00
|
|
|
@Output() saveEventSubmit = new EventEmitter<any>();
|
2025-11-11 10:52:30 +07:00
|
|
|
mode: string = 'i';
|
|
|
|
|
isModalOpen: boolean = false;
|
|
|
|
|
isSubmitting: boolean = false;
|
|
|
|
|
arrearsForm!: FormGroup;
|
|
|
|
|
saveFrm!: FormGroup;
|
2025-11-13 18:00:51 +07:00
|
|
|
myActData: IActData[] = [];
|
2025-11-21 15:01:21 +07:00
|
|
|
quickRatios: QuickRatio[] = [];
|
2025-11-13 15:37:50 +07:00
|
|
|
// myDropAct: IStateDrop[] = [];
|
|
|
|
|
myDropAct: IStateDrop = { income: [], expense: [] };
|
2025-11-14 10:10:55 +07:00
|
|
|
myActSumData: IActSumData = {
|
|
|
|
|
summary: {
|
|
|
|
|
totalIncome: '',
|
|
|
|
|
totalExpense: '',
|
2025-11-21 15:01:21 +07:00
|
|
|
netProfit: 0,
|
2025-11-14 10:10:55 +07:00
|
|
|
profitRate: '',
|
|
|
|
|
adjustedProfitRate: '',
|
|
|
|
|
period: ''
|
|
|
|
|
},
|
|
|
|
|
pie: {
|
|
|
|
|
income: [],
|
|
|
|
|
expense: []
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-21 15:01:21 +07:00
|
|
|
|
2025-11-14 10:10:55 +07:00
|
|
|
ActSumDataGradient: any
|
2025-11-13 15:37:50 +07:00
|
|
|
|
2025-11-11 10:52:30 +07:00
|
|
|
|
2025-11-21 15:01:21 +07:00
|
|
|
ownerName = localStorage.getItem('username') || 'ชนกนันต์';
|
2025-11-11 10:52:30 +07:00
|
|
|
|
2025-11-13 14:53:37 +07:00
|
|
|
constructor(
|
|
|
|
|
private dashboardStateService: DashboardStateService
|
|
|
|
|
){}
|
|
|
|
|
|
2025-11-14 10:10:55 +07:00
|
|
|
// readonly revenueTrend = [
|
|
|
|
|
// { label: 'ม.ค.', value: 52 },
|
|
|
|
|
// { label: 'ก.พ.', value: 61 },
|
|
|
|
|
// { label: 'มี.ค.', value: 73 },
|
|
|
|
|
// { label: 'เม.ย.', value: 68 },
|
|
|
|
|
// { label: 'พ.ค.', value: 82 },
|
|
|
|
|
// { label: 'มิ.ย.', value: 77 }
|
|
|
|
|
// ];
|
2025-11-11 10:52:30 +07:00
|
|
|
|
2025-11-21 15:01:21 +07:00
|
|
|
// readonly quickRatios = [
|
|
|
|
|
// { label: 'กระแสเงินสด', value: '+฿312K', status: 'positive' },
|
|
|
|
|
// { label: 'วงเงินคงเหลือ', value: '฿890K', status: 'neutral' },
|
|
|
|
|
// { label: 'ค่าใช้จ่ายเดือนนี้', value: '฿412K', status: 'warning' }
|
|
|
|
|
// ];
|
|
|
|
|
// ฟังก์ชันนี้ควรเรียกหลังจากได้รับข้อมูล myActSumData แล้ว (เช่นใน subscribe หรือ ngOnChanges)
|
2025-11-11 10:52:30 +07:00
|
|
|
|
2025-11-21 15:01:21 +07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// เพิ่มใน Class Component
|
|
|
|
|
isNumber(val: any): boolean {
|
|
|
|
|
return typeof val === 'number';
|
|
|
|
|
}
|
2025-11-11 10:52:30 +07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-11-13 19:00:31 +07:00
|
|
|
// readonly ledgerEntries = [
|
|
|
|
|
// {
|
|
|
|
|
// type: 'i',
|
|
|
|
|
// title: 'ค่าบริการที่ปรึกษา',
|
|
|
|
|
// category: 'บริการ',
|
|
|
|
|
// amount: '+฿85,000',
|
|
|
|
|
// date: 'วันนี้ · 10:15',
|
|
|
|
|
// note: 'โครงการ Warehouse Automation'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// type: 'e',
|
|
|
|
|
// title: 'ค่าเช่าออฟฟิศ',
|
|
|
|
|
// category: 'ค่าใช้จ่ายคงที่',
|
|
|
|
|
// amount: '-฿48,000',
|
|
|
|
|
// date: 'วันนี้ · 09:00',
|
|
|
|
|
// note: 'สำนักงานพระราม 9'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// type: 'i',
|
|
|
|
|
// title: 'รับเงินมัดจำ',
|
|
|
|
|
// category: 'สัญญาใหม่',
|
|
|
|
|
// amount: '+฿120,000',
|
|
|
|
|
// date: 'เมื่อวาน',
|
|
|
|
|
// note: 'ลูกค้า Urbane CoWorking'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// type: 'e',
|
|
|
|
|
// title: 'ค่าวัตถุดิบ',
|
|
|
|
|
// category: 'ต้นทุนโครงการ',
|
|
|
|
|
// amount: '-฿27,500',
|
|
|
|
|
// date: '12 มิ.ย.',
|
|
|
|
|
// note: 'สั่งผ่าน Blue Supply'
|
|
|
|
|
// }
|
|
|
|
|
// ];
|
2025-11-11 10:52:30 +07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
ngOnInit(): void {
|
|
|
|
|
this.setupFormControl();
|
2025-11-13 14:53:37 +07:00
|
|
|
this.dashboardStateService.getStateResult().subscribe(data => {
|
2025-11-13 15:37:50 +07:00
|
|
|
if (data) {
|
|
|
|
|
this.myDropAct = data;
|
2025-11-13 14:53:37 +07:00
|
|
|
}
|
2025-11-13 15:37:50 +07:00
|
|
|
});
|
2025-11-14 10:10:55 +07:00
|
|
|
// ผลลับท์ ของ รายการ
|
2025-11-13 18:00:51 +07:00
|
|
|
this.dashboardStateService.getStateAccountResult().subscribe(data => {
|
|
|
|
|
if (data) {
|
|
|
|
|
this.myActData = data;
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-11-14 10:10:55 +07:00
|
|
|
// ผลลัพการ คำนวณ ของ ปัญชี ต่างๆ
|
|
|
|
|
this.dashboardStateService.getStateSumResult().subscribe(data => {
|
|
|
|
|
if (data) {
|
|
|
|
|
this.myActSumData = data;
|
|
|
|
|
this.ActSumDataGradient = this.buildExpenseGradient()
|
2025-11-21 15:01:21 +07:00
|
|
|
this.updateQuickRatios();
|
2025-11-14 10:10:55 +07:00
|
|
|
}
|
|
|
|
|
});
|
2025-11-21 15:01:21 +07:00
|
|
|
|
2025-11-11 10:52:30 +07:00
|
|
|
}
|
|
|
|
|
setupFormControl(){
|
|
|
|
|
this.arrearsForm = new FormGroup({
|
|
|
|
|
// email: new FormControl('',[Validators.required, Validators.email, Validators.maxLength(100)]),
|
|
|
|
|
amount: new FormControl('',[Validators.required, Validators.maxLength(20)]),
|
|
|
|
|
expdtm: new FormControl('',[Validators.required, Validators.maxLength(12)]),
|
|
|
|
|
note: new FormControl('',[Validators.maxLength(200)]),
|
|
|
|
|
reason: new FormControl('',[Validators.required, Validators.maxLength(200)])
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.saveFrm = new FormGroup({
|
2025-11-21 15:01:21 +07:00
|
|
|
actacpdtm: new FormControl('',[Validators.required]),
|
2025-11-11 10:52:30 +07:00
|
|
|
actqty: new FormControl('',[Validators.required]),
|
|
|
|
|
actcat: new FormControl('',[Validators.required, Validators.maxLength(1)]),
|
|
|
|
|
actcmt: new FormControl('',[Validators.maxLength(200)])
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-21 15:01:21 +07:00
|
|
|
updateQuickRatios() {
|
|
|
|
|
const summary = this.myActSumData.summary;
|
|
|
|
|
|
|
|
|
|
// แปลงค่า netProfit เป็นตัวเลขเพื่อเช็คเงื่อนไข (รองรับทั้ง string และ number)
|
|
|
|
|
const netProfitVal = parseFloat(String(summary.netProfit));
|
|
|
|
|
const profitRateVal = parseFloat(summary.profitRate.replace('%', '')); // ลบ % ออกก่อนเช็ค
|
|
|
|
|
|
|
|
|
|
this.quickRatios = [
|
|
|
|
|
{
|
|
|
|
|
label: 'รายรับรวม',
|
|
|
|
|
value: summary.totalIncome,
|
|
|
|
|
colorClass: 'text-green-600' // รายรับสีเขียวเสมอ (หรือจะใช้สีดำ text-gray-700 ก็ได้)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'รายจ่ายรวม',
|
|
|
|
|
value: summary.totalExpense,
|
|
|
|
|
colorClass: 'text-red-500' // รายจ่ายสีแดงอ่อน หรือสีปกติ
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'คงเหลือสุทธิ', // หรือ กำไรสุทธิ
|
|
|
|
|
value: netProfitVal, // ส่งเป็นตัวเลขไปให้ Pipe format
|
|
|
|
|
// ถ้า >= 0 สีน้ำเงิน, ถ้าติดลบ สีแดง
|
|
|
|
|
colorClass: netProfitVal >= 0 ? 'text-blue-600' : 'text-red-600 font-bold'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'อัตรากำไร',
|
|
|
|
|
value: summary.profitRate,
|
|
|
|
|
// เช็ค % ถ้าติดลบให้แดง
|
|
|
|
|
colorClass: profitRateVal >= 0 ? 'text-blue-600' : 'text-red-600'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'ระยะเวลา',
|
|
|
|
|
value: summary.period,
|
|
|
|
|
colorClass: 'text-gray-500'
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 10:52:30 +07:00
|
|
|
onSaveSubmit(){
|
2025-11-21 15:01:21 +07:00
|
|
|
const rawDate = this.saveFrm.get('actacpdtm')?.value; // ค่าดิบ: "2025-11-21T14:23"
|
|
|
|
|
let arysave = {
|
|
|
|
|
actacpdtm: rawDate ? rawDate.replace(/[-T:]/g, '') : '',
|
|
|
|
|
actqty: this.saveFrm.get('actqty')?.value,
|
|
|
|
|
actcat: this.saveFrm.get('actcat')?.value,
|
|
|
|
|
actcmt: this.saveFrm.get('actcmt')?.value,
|
|
|
|
|
acttyp: this.mode
|
|
|
|
|
}
|
|
|
|
|
this.SaveEventSubmit(arysave);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 10:52:30 +07:00
|
|
|
|
2025-11-21 15:01:21 +07:00
|
|
|
SaveEventSubmit(event: any){
|
|
|
|
|
this.saveEventSubmit.emit(event);
|
2025-11-11 10:52:30 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onArrearsSubmit(){
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private buildExpenseGradient(): string {
|
2025-11-14 10:10:55 +07:00
|
|
|
if (!this.myActSumData?.pie?.expense?.length) return '';
|
|
|
|
|
|
2025-11-11 10:52:30 +07:00
|
|
|
let current = 0;
|
2025-11-14 10:10:55 +07:00
|
|
|
const segments = this.myActSumData.pie.expense
|
2025-11-11 10:52:30 +07:00
|
|
|
.map(part => {
|
|
|
|
|
const start = current;
|
2025-11-14 10:10:55 +07:00
|
|
|
const percent = parseFloat(part.percent); // แปลงจาก string → number
|
|
|
|
|
const end = current + percent;
|
2025-11-11 10:52:30 +07:00
|
|
|
current = end;
|
|
|
|
|
return `${part.color} ${start}% ${end}%`;
|
|
|
|
|
})
|
|
|
|
|
.join(', ');
|
2025-11-14 10:10:55 +07:00
|
|
|
|
2025-11-11 10:52:30 +07:00
|
|
|
return `conic-gradient(${segments})`;
|
|
|
|
|
}
|
|
|
|
|
}
|