print and report
This commit is contained in:
@@ -45,37 +45,6 @@ export class MainDashboardComponent implements OnInit {
|
||||
private dashboardStateService: DashboardStateService
|
||||
){}
|
||||
|
||||
readonly kpiCards = [
|
||||
{
|
||||
label: 'รายรับรวม',
|
||||
value: '฿1.28M',
|
||||
trend: '+12.4%',
|
||||
context: 'เทียบกับเดือนก่อน',
|
||||
accent: 'mint'
|
||||
},
|
||||
{
|
||||
label: 'รายจ่ายรวม',
|
||||
value: '฿732K',
|
||||
trend: '-4.1%',
|
||||
context: 'จัดการได้ดีขึ้น',
|
||||
accent: 'lavender'
|
||||
},
|
||||
{
|
||||
label: 'ยอดค้างชำระ',
|
||||
value: '฿184K',
|
||||
trend: '-2 ใบแจ้งหนี้',
|
||||
context: 'รอติดตาม',
|
||||
accent: 'amber'
|
||||
},
|
||||
{
|
||||
label: 'อัตรากำไร',
|
||||
value: '37.8%',
|
||||
trend: '+1.9 จุด',
|
||||
context: 'ระยะ 30 วัน',
|
||||
accent: 'teal'
|
||||
}
|
||||
];
|
||||
|
||||
// readonly revenueTrend = [
|
||||
// { label: 'ม.ค.', value: 52 },
|
||||
// { label: 'ก.พ.', value: 61 },
|
||||
@@ -98,71 +67,8 @@ export class MainDashboardComponent implements OnInit {
|
||||
isNumber(val: any): boolean {
|
||||
return typeof val === 'number';
|
||||
}
|
||||
readonly periodSummaries = [
|
||||
{
|
||||
label: 'รายปี',
|
||||
note: 'ปี 2567',
|
||||
income: '฿9.6M',
|
||||
expense: '฿5.1M',
|
||||
net: '+฿4.5M',
|
||||
trend: '+18%',
|
||||
badge: 'year'
|
||||
},
|
||||
{
|
||||
label: 'รายเดือน',
|
||||
note: 'มิถุนายน 2567',
|
||||
income: '฿1.28M',
|
||||
expense: '฿732K',
|
||||
net: '+฿548K',
|
||||
trend: '+6%',
|
||||
badge: 'month'
|
||||
},
|
||||
{
|
||||
label: 'รายสัปดาห์',
|
||||
note: 'สัปดาห์ที่ 24',
|
||||
income: '฿312K',
|
||||
expense: '฿188K',
|
||||
net: '+฿124K',
|
||||
trend: '+2%',
|
||||
badge: 'week'
|
||||
}
|
||||
];
|
||||
|
||||
readonly alerts = [
|
||||
{
|
||||
title: 'ใบแจ้งหนี้ #INV-083 จะครบกำหนด',
|
||||
detail: 'ลูกค้า Metro Engineering',
|
||||
tag: 'ภายใน 3 วัน'
|
||||
},
|
||||
{
|
||||
title: 'มีเอกสารที่ต้องอนุมัติ 2 รายการ',
|
||||
detail: 'เบิกค่าใช้จ่ายฝ่ายการตลาด',
|
||||
tag: 'รออนุมัติ'
|
||||
},
|
||||
{
|
||||
title: 'พบรายการใช้จ่ายผิดปกติ',
|
||||
detail: 'ค่าใช้จ่ายเดินทางสูงกว่าค่าเฉลี่ย 28%',
|
||||
tag: 'ตรวจสอบ'
|
||||
}
|
||||
];
|
||||
|
||||
readonly tasks = [
|
||||
{
|
||||
title: 'กระทบยอดธนาคาร เดือน มิ.ย.',
|
||||
due: 'วันนี้ 16:00',
|
||||
priority: 'สูง'
|
||||
},
|
||||
{
|
||||
title: 'เตรียมรายงาน VAT',
|
||||
due: 'พรุ่งนี้ 10:30',
|
||||
priority: 'กลาง'
|
||||
},
|
||||
{
|
||||
title: 'ออกใบเสนอราคา โครงการใหม่',
|
||||
due: 'ศุกร์ 14:00',
|
||||
priority: 'ต่ำ'
|
||||
}
|
||||
];
|
||||
|
||||
// readonly ledgerEntries = [
|
||||
// {
|
||||
@@ -199,14 +105,6 @@ isNumber(val: any): boolean {
|
||||
// }
|
||||
// ];
|
||||
|
||||
readonly expenseBreakdown = [
|
||||
{ label: 'ฝ่ายบริหาร', value: 32, color: '#0ea5e9' },
|
||||
{ label: 'การตลาด', value: 18, color: '#f97316' },
|
||||
{ label: 'ต้นทุนโครงการ', value: 27, color: '#10b981' },
|
||||
{ label: 'บุคลากร', value: 15, color: '#a855f7' },
|
||||
{ label: 'อื่นๆ', value: 8, color: '#e11d48' }
|
||||
];
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setupFormControl();
|
||||
|
||||
@@ -209,80 +209,127 @@
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
/* --- UPDATED PIE CHART SECTION (Donut Style) --- */
|
||||
|
||||
.pie-panel__content {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3rem; /* ระยะห่างระหว่างกราฟกับ Legend */
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.chart-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pie-chart {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
/* Flex เพื่อจัดรูตรงกลาง */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pie-chart {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
box-shadow: inset 0 0 20px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.pie-chart__center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
border-radius: 50%;
|
||||
width: 75%; /* ความหนาของขอบ */
|
||||
height: 75%;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.1);
|
||||
box-shadow: inset 0 2px 10px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.pie-chart__center p {
|
||||
.chart-shadow {
|
||||
position: absolute;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
border-radius: 50%;
|
||||
background: rgba(0,0,0,0.03);
|
||||
filter: blur(20px);
|
||||
z-index: 1;
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
.label-muted {
|
||||
margin: 0;
|
||||
color: #94a3b8;
|
||||
font-size: 0.85rem;
|
||||
font-size: 0.8rem;
|
||||
color: #9ca3af;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.pie-chart__center strong {
|
||||
color: #0f172a;
|
||||
.total-amount {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: #1f2937;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Legend Styles */
|
||||
.pie-legend {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.8rem;
|
||||
gap: 1.5rem; /* ระยะห่างแต่ละ item */
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.pie-legend li {
|
||||
.pie-legend__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 4px;
|
||||
margin-top: 6px; /* ดันลงมาให้ตรงกับ Text บรรทัดแรก */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.legend-label {
|
||||
.legend-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
color: #374151;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.item-percent {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.legend-value {
|
||||
margin: 0;
|
||||
color: #94a3b8;
|
||||
.item-value {
|
||||
font-size: 0.85rem;
|
||||
color: #6b7280;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* --- END UPDATED PIE CHART SECTION --- */
|
||||
|
||||
|
||||
.preview-modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
@@ -422,6 +469,7 @@
|
||||
|
||||
.pie-panel__content {
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +1,59 @@
|
||||
<section class="report">
|
||||
<header class="report__header">
|
||||
<div class="report">
|
||||
<div class="report__header">
|
||||
<div>
|
||||
<p class="eyebrow">สรุปรายงาน</p>
|
||||
<h1>รายงานรายรับรายจ่าย</h1>
|
||||
<p class="muted">ช่วงวันที่ {{ reportRange.start }} - {{ reportRange.end }}</p>
|
||||
</div>
|
||||
<div class="report__actions">
|
||||
<button class="btn btn--ghost">ส่งออกเป็น Excel</button>
|
||||
<!-- <button class="btn btn--ghost">ส่งออกเป็น Excel</button> -->
|
||||
<button class="btn btn--primary" (click)="openPreview()">ปริ้นรายงาน</button>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<section class="summary-grid">
|
||||
<article class="summary-card" *ngFor="let card of summaryCards">
|
||||
<p class="summary-card__label">{{ card.label }}</p>
|
||||
<h2>{{ card.value }}</h2>
|
||||
<p class="summary-card__detail">{{ card.detail }}</p>
|
||||
<span class="summary-card__tone" [ngClass]="'tone-' + card.tone"></span>
|
||||
</article>
|
||||
</section>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
|
||||
<section class="report__content">
|
||||
<article class="panel">
|
||||
<div class="p-6 rounded-2xl bg-green-50 border border-green-100 shadow-sm hover:shadow-md transition duration-200">
|
||||
<p class="text-sm font-medium text-green-800 opacity-70">รายรับรวม</p>
|
||||
<h2 class="text-3xl font-bold text-gray-800 mt-2">{{ myActSumData.summary.totalIncome | number:'1.2-2' }}</h2>
|
||||
<div class="mt-2 flex items-center text-sm font-medium text-green-600">
|
||||
<!-- <span>+12.4% MoM</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 rounded-2xl bg-yellow-50 border border-yellow-100 shadow-sm hover:shadow-md transition duration-200">
|
||||
<p class="text-sm font-medium text-yellow-800 opacity-70">รายจ่ายรวม</p>
|
||||
<h2 class="text-3xl font-bold text-gray-800 mt-2">{{ myActSumData.summary.totalExpense | number:'1.2-2' }}</h2>
|
||||
<div class="mt-2 flex items-center text-sm font-medium text-yellow-600">
|
||||
<!-- <span>-4.1% MoM</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 rounded-2xl bg-purple-50 border border-purple-100 shadow-sm hover:shadow-md transition duration-200">
|
||||
<p class="text-sm font-medium text-purple-800 opacity-70">กำไรสุทธิ</p>
|
||||
<h2 class="text-3xl font-bold text-gray-800 mt-2">{{ myActSumData.summary.netProfit | number:'1.2-2' }}</h2>
|
||||
<div class="mt-2 flex items-center text-sm font-medium text-purple-600">
|
||||
<span>Margin {{ myActSumData.summary.profitRate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 rounded-2xl bg-gray-50 border border-gray-100 shadow-sm hover:shadow-md transition duration-200">
|
||||
<p class="text-sm font-medium text-gray-600 opacity-70">บันทึกรายการ</p>
|
||||
<h2 class="text-3xl font-bold text-gray-800 mt-2">{{myActData.length}} รายการ</h2>
|
||||
<div class="mt-2 flex items-center text-xs font-medium text-gray-500">
|
||||
<!-- <span>32 รายรับ · 54 รายจ่าย</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="report__content">
|
||||
<div class="panel">
|
||||
<div class="panel__header">
|
||||
<div>
|
||||
<h2>สมุดรายวัน</h2>
|
||||
<p>บันทึกรายรับรายจ่ายทั้งหมดในช่วงเวลา</p>
|
||||
</div>
|
||||
<button class="btn btn--compact btn--ghost">กรองข้อมูล</button>
|
||||
</div>
|
||||
<div class="table">
|
||||
<div class="table__head">
|
||||
@@ -37,106 +63,123 @@
|
||||
<span>หมวดหมู่</span>
|
||||
<span class="amount-col">ยอดเงิน</span>
|
||||
</div>
|
||||
<div class="table__row" *ngFor="let record of formattedRecords">
|
||||
<span>{{ record.date }}</span>
|
||||
<span class="mono">{{ record.doc }}</span>
|
||||
@for (idx of myActData; track idx.actseq) {
|
||||
<div class="table__row">
|
||||
<span>{{ idx.actacpdtm | date:'dd/MM/yyyy' }}</span>
|
||||
<span class="mono">RCPT{{ idx.actseq }}</span>
|
||||
<span>
|
||||
<strong>{{ record.topic }}</strong>
|
||||
<small class="muted">{{ record.type === 'income' ? 'รายรับ' : 'รายจ่าย' }}</small>
|
||||
<strong>{{ idx.actcatnam }}</strong>
|
||||
<small class="muted">{{ idx.acttyp === 'i' ? 'รับ' : 'จ่าย' }}</small>
|
||||
</span>
|
||||
<span>{{ record.category }}</span>
|
||||
<span class="amount-col" [ngClass]="record.tone">{{ record.displayAmount }}</span>
|
||||
<span>{{ idx.actcatnam }}</span>
|
||||
<span class="amount-col" [ngClass]="idx.acttyp === 'i' ? 'income' : 'expense' ">{{ idx.actqty | number:'1.2-2' }}</span>
|
||||
</div>
|
||||
} @empty {
|
||||
<div class="p-4 text-center text-gray-400">ไม่มีข้อมูลรายการ</div>
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<article class="panel pie-panel">
|
||||
<div class="panel__header">
|
||||
<div>
|
||||
<h2>สัดส่วนค่าใช้จ่าย</h2>
|
||||
<p>เปรียบเทียบหมวดหลักของรายจ่ายเดือนนี้</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pie-panel__content">
|
||||
<div class="pie-chart" [style.background]="expenseGradient">
|
||||
<div class="pie-chart__center">
|
||||
<p>รวมรายจ่าย</p>
|
||||
<strong>฿732K</strong>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pie-legend">
|
||||
<li *ngFor="let part of expenseBreakdown">
|
||||
<span class="swatch" [style.background]="part.color"></span>
|
||||
<div>
|
||||
<p class="legend-label">{{ part.label }}</p>
|
||||
<p class="legend-value">{{ part.value }}%</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="preview-modal" *ngIf="printPreviewOpen">
|
||||
<div class="preview-modal__backdrop" (click)="closePreview()"></div>
|
||||
<div class="preview-modal__content">
|
||||
<header class="preview-modal__header">
|
||||
<div>
|
||||
<p class="eyebrow">Print Preview</p>
|
||||
<h2>รายงานรายรับรายจ่าย</h2>
|
||||
<p class="muted">ช่วงวันที่ {{ reportRange.start }} - {{ reportRange.end }}</p>
|
||||
</div>
|
||||
<div class="preview-modal__actions">
|
||||
<button class="btn btn--ghost" (click)="closePreview()">ปิด</button>
|
||||
<button class="btn btn--primary">พิมพ์</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="preview-sheet">
|
||||
<div class="preview-sheet__header">
|
||||
<div>
|
||||
<h3>Accounting Summary</h3>
|
||||
<p>Prepared on {{ reportRange.end }}</p>
|
||||
</div>
|
||||
<div class="preview-totals">
|
||||
<div *ngFor="let total of previewTotals">
|
||||
<p>{{ total.label }}</p>
|
||||
<strong>{{ total.value }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-pie">
|
||||
<div class="mini-pie" [style.background]="expenseGradient"></div>
|
||||
<ul>
|
||||
<li *ngFor="let part of expenseBreakdown">
|
||||
<span class="swatch" [style.background]="part.color"></span>
|
||||
<span>{{ part.label }} · {{ part.value }}%</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<table class="preview-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>วันที่</th>
|
||||
<th>เลขที่</th>
|
||||
<th>หัวข้อ</th>
|
||||
<th>หมวดหมู่</th>
|
||||
<th>ยอดเงิน</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let record of formattedRecords">
|
||||
<td>{{ record.date }}</td>
|
||||
<td>{{ record.doc }}</td>
|
||||
<td>{{ record.topic }}</td>
|
||||
<td>{{ record.category }}</td>
|
||||
<td [ngClass]="record.tone">{{ record.displayAmount }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="panel pie-panel">
|
||||
<div class="panel__header">
|
||||
<div>
|
||||
<h2>สัดส่วนค่าใช้จ่าย</h2>
|
||||
<p>เปรียบเทียบหมวดหลักของรายจ่ายเดือนนี้</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="pie-panel__content">
|
||||
<div class="chart-wrapper">
|
||||
<div class="pie-chart" [style.background]="ActSumDataGradient">
|
||||
<div class="pie-chart__center">
|
||||
<p class="label-muted">รวมรายจ่าย</p>
|
||||
<strong class="total-amount">{{ myActSumData.summary.totalExpense | number:'1.0-0' }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-shadow"></div>
|
||||
</div>
|
||||
|
||||
<ul class="pie-legend">
|
||||
@for (part of myActSumData.pie.expense; track part.label) {
|
||||
<li class="pie-legend__item">
|
||||
<span class="swatch" [style.background]="part.color"></span>
|
||||
<div class="legend-text">
|
||||
<p class="item-label">{{ part.label }}</p>
|
||||
<p class="item-percent">{{ part.percent }}%</p>
|
||||
<p class="item-value">{{ part.value | number:'1.0-0' }} บาท</p>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PRINT PREVIEW MODAL -->
|
||||
@if(printPreviewOpen){
|
||||
<div class="preview-modal">
|
||||
<div class="preview-modal__backdrop" (click)="closePreview()"></div>
|
||||
<div class="preview-modal__content">
|
||||
<div class="preview-modal__header">
|
||||
<div>
|
||||
<p class="eyebrow">Print Preview</p>
|
||||
<h2>รายงานรายรับรายจ่าย</h2>
|
||||
</div>
|
||||
<div class="preview-modal__actions">
|
||||
<button class="btn btn--ghost" (click)="closePreview()">ปิด</button>
|
||||
<!-- ACTION ADDED HERE -->
|
||||
<button class="btn btn--primary" (click)="printReport()">พิมพ์</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-sheet">
|
||||
<div class="preview-sheet__header">
|
||||
<div>
|
||||
<h3>Accounting Summary</h3>
|
||||
<p>Prepared on {{ reportRange.end }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="preview-pie">
|
||||
<div class="mini-pie" [style.background]="ActSumDataGradient"></div>
|
||||
<ul>
|
||||
@for (part of myActSumData.pie.expense; track part.label) {
|
||||
<li>
|
||||
<span class="swatch" [style.background]="part.color"></span>
|
||||
<span>{{ part.label }} · {{ part.percent }}%</span>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<table class="preview-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>วันที่</th>
|
||||
<th>เลขที่</th>
|
||||
<th>หัวข้อ</th>
|
||||
<th>หมวดหมู่</th>
|
||||
<th>ยอดเงิน</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (idx of myActData; track idx.actseq) {
|
||||
<tr>
|
||||
<td>{{ idx.actacpdtm | date:'dd/MM/yyyy'}}</td>
|
||||
<td>RCPT{{ idx.actseq }}</td>
|
||||
<td>{{ idx.actcatnam }}</td>
|
||||
<td>{{ idx.actcatnam }}</td>
|
||||
<td [ngClass]="idx.acttyp === 'i' ? 'income' : 'expense' ">{{ idx.actqty | number:'1.2-2' }}</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- The rest of the dashboard HTML is excluded for brevity/focus on the core report logic -->
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { GeneralService } from './../../services/generalservice';
|
||||
import { QuickRatio, IStateDrop, IActSumData } from './../../interfaces/dashboard.interface';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { IActData } from '../../interfaces/dashboard.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-main-report',
|
||||
@@ -6,7 +10,36 @@ import { Component } from '@angular/core';
|
||||
standalone: false,
|
||||
styleUrls: ['./main-report.component.css']
|
||||
})
|
||||
export class MainReportComponent {
|
||||
export class MainReportComponent implements OnInit{
|
||||
|
||||
|
||||
myActData: IActData[] = [];
|
||||
quickRatios: QuickRatio[] = [];
|
||||
// myDropAct: IStateDrop[] = [];
|
||||
myDropAct: IStateDrop = { income: [], expense: [] };
|
||||
myActSumData: IActSumData = {
|
||||
summary: {
|
||||
totalIncome: '',
|
||||
totalExpense: '',
|
||||
netProfit: 0,
|
||||
profitRate: '',
|
||||
adjustedProfitRate: '',
|
||||
period: ''
|
||||
},
|
||||
pie: {
|
||||
income: [],
|
||||
expense: []
|
||||
}
|
||||
};
|
||||
|
||||
ActSumDataGradient: any
|
||||
|
||||
|
||||
constructor(
|
||||
private generalService: GeneralService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router
|
||||
){}
|
||||
readonly reportRange = {
|
||||
start: '1 มิถุนายน 2567',
|
||||
end: '30 มิถุนายน 2567'
|
||||
@@ -102,6 +135,60 @@ export class MainReportComponent {
|
||||
|
||||
printPreviewOpen = false;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.OnSearchSum({}, false);
|
||||
this.OnSearchAct({});
|
||||
}
|
||||
|
||||
|
||||
OnSearchAct(value: any): void {
|
||||
const uri = '/api/web/accountingSearch';
|
||||
let request = {
|
||||
token: value
|
||||
}
|
||||
this.generalService.postRequest(uri, request).subscribe({
|
||||
next: (result: any) => {
|
||||
if (result.code === '200') {
|
||||
this.generalService.trowApi(result);
|
||||
this.myActData = result.data;
|
||||
}else{
|
||||
this.generalService.trowApi(result);
|
||||
}
|
||||
},
|
||||
error: (error: any) => {
|
||||
this.generalService.trowApi(error);
|
||||
},
|
||||
complete: () => {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
OnSearchSum(value: any, setupFirst: boolean): void {
|
||||
const uri = '/api/web/accountingSum';
|
||||
let request = {
|
||||
token: value
|
||||
}
|
||||
this.generalService.postRequest(uri, request).subscribe({
|
||||
next: (result: any) => {
|
||||
if (result.code === '200') {
|
||||
this.generalService.trowApi(result);
|
||||
this.myActSumData = result.data
|
||||
this.ActSumDataGradient = this.buildExpenseGradient();
|
||||
}else{
|
||||
this.generalService.trowApi(result);
|
||||
}
|
||||
},
|
||||
error: (error: any) => {
|
||||
this.generalService.trowApi(error);
|
||||
},
|
||||
complete: () => {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get expenseGradient(): string {
|
||||
let current = 0;
|
||||
const segments = this.expenseBreakdown
|
||||
@@ -115,6 +202,24 @@ export class MainReportComponent {
|
||||
return `conic-gradient(${segments})`;
|
||||
}
|
||||
|
||||
|
||||
private buildExpenseGradient(): string {
|
||||
if (!this.myActSumData?.pie?.expense?.length) return '';
|
||||
|
||||
let current = 0;
|
||||
const segments = this.myActSumData.pie.expense
|
||||
.map(part => {
|
||||
const start = current;
|
||||
const percent = parseFloat(part.percent); // แปลงจาก string → number
|
||||
const end = current + percent;
|
||||
current = end;
|
||||
return `${part.color} ${start}% ${end}%`;
|
||||
})
|
||||
.join(', ');
|
||||
|
||||
return `conic-gradient(${segments})`;
|
||||
}
|
||||
|
||||
get formattedRecords() {
|
||||
return this.ledgerRecords.map(record => ({
|
||||
...record,
|
||||
@@ -123,6 +228,10 @@ export class MainReportComponent {
|
||||
}));
|
||||
}
|
||||
|
||||
printReport(): void {
|
||||
window.print();
|
||||
}
|
||||
|
||||
openPreview(): void {
|
||||
this.printPreviewOpen = true;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ export interface QuickRatio {
|
||||
value: string | number;
|
||||
colorClass: string; // ตัวเก็บชื่อ class สี
|
||||
}
|
||||
|
||||
// export
|
||||
// ข้อมูลสินค้าหลัก
|
||||
// export interface IProduct {
|
||||
// id: string;
|
||||
|
||||
Reference in New Issue
Block a user