diff --git a/accounting-ng-nuttakit/src/app/component/main-dashboard/main-dashboard.component.ts b/accounting-ng-nuttakit/src/app/component/main-dashboard/main-dashboard.component.ts index c7aaa5c..4955944 100644 --- a/accounting-ng-nuttakit/src/app/component/main-dashboard/main-dashboard.component.ts +++ b/accounting-ng-nuttakit/src/app/component/main-dashboard/main-dashboard.component.ts @@ -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(); diff --git a/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.css b/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.css index 9a96ffa..fe43d1a 100644 --- a/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.css +++ b/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.css @@ -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; } } diff --git a/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.html b/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.html index 99bb809..af8d54e 100644 --- a/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.html +++ b/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.html @@ -1,33 +1,59 @@ -
-
+
+

สรุปรายงาน

รายงานรายรับรายจ่าย

ช่วงวันที่ {{ reportRange.start }} - {{ reportRange.end }}

- +
-
+ -
-
-

{{ card.label }}

-

{{ card.value }}

-

{{ card.detail }}

- -
-
+
-
-
+
+

รายรับรวม

+

{{ myActSumData.summary.totalIncome | number:'1.2-2' }}

+
+ +
+
+ +
+

รายจ่ายรวม

+

{{ myActSumData.summary.totalExpense | number:'1.2-2' }}

+
+ +
+
+ +
+

กำไรสุทธิ

+

{{ myActSumData.summary.netProfit | number:'1.2-2' }}

+
+ Margin {{ myActSumData.summary.profitRate }} +
+
+ +
+

บันทึกรายการ

+

{{myActData.length}} รายการ

+
+ +
+
+ +
+ +
+

สมุดรายวัน

บันทึกรายรับรายจ่ายทั้งหมดในช่วงเวลา

-
@@ -37,106 +63,123 @@ หมวดหมู่ ยอดเงิน
-
- {{ record.date }} - {{ record.doc }} + @for (idx of myActData; track idx.actseq) { +
+ {{ idx.actacpdtm | date:'dd/MM/yyyy' }} + RCPT{{ idx.actseq }} - {{ record.topic }} - {{ record.type === 'income' ? 'รายรับ' : 'รายจ่าย' }} + {{ idx.actcatnam }} + {{ idx.acttyp === 'i' ? 'รับ' : 'จ่าย' }} - {{ record.category }} - {{ record.displayAmount }} + {{ idx.actcatnam }} + {{ idx.actqty | number:'1.2-2' }}
+ } @empty { +
ไม่มีข้อมูลรายการ
+ }
- +
-
-
-
-

สัดส่วนค่าใช้จ่าย

-

เปรียบเทียบหมวดหลักของรายจ่ายเดือนนี้

-
-
-
-
-
-

รวมรายจ่าย

- ฿732K -
-
-
    -
  • - -
    -

    {{ part.label }}

    -

    {{ part.value }}%

    -
    -
  • -
-
-
-
- - -
-
-
-
-
-

Print Preview

-

รายงานรายรับรายจ่าย

-

ช่วงวันที่ {{ reportRange.start }} - {{ reportRange.end }}

-
-
- - -
-
- -
-
-
-

Accounting Summary

-

Prepared on {{ reportRange.end }}

-
-
-
-

{{ total.label }}

- {{ total.value }} -
-
-
- -
-
-
    -
  • - - {{ part.label }} · {{ part.value }}% -
  • -
-
- - - - - - - - - - - - - - - - - - - - -
วันที่เลขที่หัวข้อหมวดหมู่ยอดเงิน
{{ record.date }}{{ record.doc }}{{ record.topic }}{{ record.category }}{{ record.displayAmount }}
+
+
+
+

สัดส่วนค่าใช้จ่าย

+

เปรียบเทียบหมวดหลักของรายจ่ายเดือนนี้

-
+ +
+
+
+
+

รวมรายจ่าย

+ {{ myActSumData.summary.totalExpense | number:'1.0-0' }} +
+
+
+
+ + + +
+ + + + + +@if(printPreviewOpen){ +
+
+
+
+
+

Print Preview

+

รายงานรายรับรายจ่าย

+
+
+ + + +
+
+ +
+
+
+

Accounting Summary

+

Prepared on {{ reportRange.end }}

+
+ +
+ +
+
+
    + @for (part of myActSumData.pie.expense; track part.label) { +
  • + + {{ part.label }} · {{ part.percent }}% +
  • + } +
+
+ + + + + + + + + + + + + @for (idx of myActData; track idx.actseq) { + + + + + + + + } + +
วันที่เลขที่หัวข้อหมวดหมู่ยอดเงิน
{{ idx.actacpdtm | date:'dd/MM/yyyy'}}RCPT{{ idx.actseq }}{{ idx.actcatnam }}{{ idx.actcatnam }}{{ idx.actqty | number:'1.2-2' }}
+
+
+
+} + + diff --git a/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.ts b/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.ts index 1ca16fc..9d88020 100644 --- a/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.ts +++ b/accounting-ng-nuttakit/src/app/component/main-report/main-report.component.ts @@ -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; } diff --git a/accounting-ng-nuttakit/src/app/interfaces/dashboard.interface.ts b/accounting-ng-nuttakit/src/app/interfaces/dashboard.interface.ts index b778428..91328a2 100644 --- a/accounting-ng-nuttakit/src/app/interfaces/dashboard.interface.ts +++ b/accounting-ng-nuttakit/src/app/interfaces/dashboard.interface.ts @@ -59,6 +59,8 @@ export interface QuickRatio { value: string | number; colorClass: string; // ตัวเก็บชื่อ class สี } + +// export // ข้อมูลสินค้าหลัก // export interface IProduct { // id: string;