.
This commit is contained in:
@@ -28,6 +28,7 @@ import { CachingInterceptor } from './services/caching.interceptor';
|
|||||||
import { MainProject } from './component/main-project/main-project';
|
import { MainProject } from './component/main-project/main-project';
|
||||||
import { MainProjectContent } from './content/main-project-content/main-project-content';
|
import { MainProjectContent } from './content/main-project-content/main-project-content';
|
||||||
import { MainProjectAdd } from './component/main-project-add/main-project-add';
|
import { MainProjectAdd } from './component/main-project-add/main-project-add';
|
||||||
|
import { BudgetAprovalContent } from './content/budget-aproval-content/budget-aproval-content';
|
||||||
// import { BudgetAproval } from './component/budget-aproval/budget-aproval';
|
// import { BudgetAproval } from './component/budget-aproval/budget-aproval';
|
||||||
// import { AccDateFormatPipe } from './pipe/dtmtodatetime.pipe';
|
// import { AccDateFormatPipe } from './pipe/dtmtodatetime.pipe';
|
||||||
// import { DtmtodatetimePipe } from './dtmtodatetime.pipe';
|
// import { DtmtodatetimePipe } from './dtmtodatetime.pipe';
|
||||||
@@ -39,7 +40,8 @@ import { MainProjectAdd } from './component/main-project-add/main-project-add';
|
|||||||
SidebarContentComponent,
|
SidebarContentComponent,
|
||||||
SidebarComponent,
|
SidebarComponent,
|
||||||
LicensePrivacyTermsComponent,
|
LicensePrivacyTermsComponent,
|
||||||
TokenTimerComponent
|
TokenTimerComponent,
|
||||||
|
// BudgetAprovalContent
|
||||||
// MainProjectAdd,
|
// MainProjectAdd,
|
||||||
// MainProject,
|
// MainProject,
|
||||||
// MainProjectContent,
|
// MainProjectContent,
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.animate-fade-in-down { animation: fadeInDown 0.3s ease-out; }
|
||||||
|
.animate-fade-in { animation: fadeIn 0.2s ease-out; }
|
||||||
|
|
||||||
|
@keyframes fadeInDown {
|
||||||
|
from { opacity: 0; transform: translateY(-10px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
input[type=number]::-webkit-inner-spin-button,
|
||||||
|
input[type=number]::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,307 +1,339 @@
|
|||||||
<div class="p-6 space-y-10">
|
|
||||||
|
|
||||||
<!-- Header -->
|
<div class="w-full p-6 space-y-8 bg-gray-50 min-h-screen font-sans text-gray-800">
|
||||||
<div class="flex justify-between items-center mb-4 ">
|
|
||||||
<h2 class="text-xl font-semibold">
|
|
||||||
รายการงบประมาณของโครงการ: ระบบจัดการน้ำดื่ม
|
|
||||||
<!-- {{ project?.name }} -->
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="text-gray-600 text-sm">
|
<!-- 1. Header Section -->
|
||||||
แสดงข้อมูล {{ budgetItems.length }} รายการ
|
<div class="flex flex-col md:flex-row md:justify-between md:items-end gap-4 border-b border-gray-200 pb-4">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-2xl font-bold text-gray-800 flex items-center gap-3">
|
||||||
|
<!-- <span class="bg-red-100 text-red-800 p-2 rounded-lg text-xl">💸</span> -->
|
||||||
|
<span>จัดสรรงบประมาณ</span>
|
||||||
|
</h2>
|
||||||
|
<p class="text-gray-500 mt-1 ml-1 text-sm">โครงการ: <span class="font-medium text-red-900">{{projectTitle}}</span></p>
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-gray-500 bg-white px-4 py-2 rounded-full shadow-sm border border-gray-100">
|
||||||
|
รายการทั้งหมด: <span class="font-bold text-red-800">{{ myTrnMst.length }}</span> รายการ
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 2. Add/Edit Budget Form (Collapsible) -->
|
||||||
<!-- Add New Budget Item -->
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden transition-all duration-300">
|
||||||
<!-- <form [formGroup]="addItemForm" class="bg-gray-50 border rounded-xl p-4 mb-6">
|
<!-- Toggle Header -->
|
||||||
|
<div
|
||||||
<h3 class="font-semibold mb-3 text-gray-700">เพิ่มรายการงบประมาณ</h3>
|
class="flex justify-between items-center p-4 bg-gray-50 cursor-pointer hover:bg-gray-100 transition select-none border-b border-gray-100"
|
||||||
|
(click)="toggleFormCollapse()"
|
||||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
||||||
|
|
||||||
หมวดงบ
|
|
||||||
<div>
|
|
||||||
<label class="text-sm text-gray-600">หมวดงบประมาณ</label>
|
|
||||||
<select
|
|
||||||
formControlName="category"
|
|
||||||
class="w-full px-4 py-2 border rounded-xl bg-white mt-1
|
|
||||||
focus:ring-2 focus:ring-blue-200 focus:border-blue-300" >
|
|
||||||
<option value="">-- เลือกหมวดงบ --</option>
|
|
||||||
|
|
||||||
@for (item of budgetCategoriesDrop.expense; track item.dtlcod) {
|
|
||||||
<option [value]="item.dtlcod">{{ item.dtlnam }}</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
|
|
||||||
error
|
|
||||||
<div
|
|
||||||
*ngIf="addItemForm.controls['category'].invalid && addItemForm.controls['category'].touched"
|
|
||||||
class="text-red-500 text-xs mt-1"
|
|
||||||
>
|
|
||||||
กรุณาเลือกหมวดงบ
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
รายการ
|
|
||||||
<div>
|
|
||||||
<label class="text-sm text-gray-600">ชื่อรายการ</label>
|
|
||||||
<select
|
|
||||||
formControlName="name"
|
|
||||||
class="w-full px-4 py-2 border rounded-xl bg-white mt-1
|
|
||||||
focus:ring-2 focus:ring-blue-200 focus:border-blue-300"
|
|
||||||
>
|
|
||||||
<option value="">-- เลือกรายการ --</option>
|
|
||||||
|
|
||||||
<option *ngFor="let it of masterItems" [value]="it.name">
|
|
||||||
{{ it.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<div
|
|
||||||
*ngIf="addItemForm.controls['name'].invalid && addItemForm.controls['name'].touched"
|
|
||||||
class="text-red-500 text-xs mt-1"
|
|
||||||
>
|
|
||||||
กรุณาเลือกรายการ
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
จำนวน
|
|
||||||
<div>
|
|
||||||
<label class="text-sm text-gray-600">จำนวน</label>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
formControlName="qty"
|
|
||||||
class="w-full px-4 py-2 border rounded-xl bg-white mt-1
|
|
||||||
focus:ring-2 focus:ring-blue-200 focus:border-blue-300"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
*ngIf="addItemForm.controls['qty'].invalid && addItemForm.controls['qty'].touched"
|
|
||||||
class="text-red-500 text-xs mt-1"
|
|
||||||
>
|
|
||||||
จำนวนต้องมากกว่า 0
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
ราคา
|
|
||||||
<div>
|
|
||||||
<label class="text-sm text-gray-600">ราคา</label>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
formControlName="price"
|
|
||||||
class="w-full px-4 py-2 border rounded-xl bg-white mt-1
|
|
||||||
focus:ring-2 focus:ring-blue-200 focus:border-blue-300"/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
*ngIf="addItemForm.controls['price'].invalid && addItemForm.controls['price'].touched"
|
|
||||||
class="text-red-500 text-xs mt-1"
|
|
||||||
>
|
|
||||||
ราคาต้องมากกว่า 0
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Add button
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
(click)="addBudgetItem()"
|
|
||||||
class="mt-4 bg-green-600 hover:bg-green-700 text-white px-5 py-2 rounded-xl shadow"
|
|
||||||
>
|
>
|
||||||
➕ เพิ่มเข้าตาราง
|
<div class="flex items-center gap-2 font-bold text-gray-700">
|
||||||
</button>
|
<!-- <span class="bg-red-600 text-white w-6 h-6 flex items-center justify-center rounded-full text-xs shadow-sm">
|
||||||
|
{{ isEditMode ? '✎' : '✚' }}
|
||||||
</form> -->
|
</span> -->
|
||||||
|
{{ isEditMode ? 'แก้ไขรายการ' : 'เพิ่มรายการงบประมาณ' }}
|
||||||
<div class="bg-white rounded-lg shadow-md border border-gray-200 ">
|
</div>
|
||||||
<!-- หัวพับได้ -->
|
<button class="text-gray-400 transition-transform duration-300" [ngClass]="{'rotate-180': isFormExpanded}">
|
||||||
<div class="flex justify-between items-center p-4 border-b bg-gray-50 rounded-t-lg" (click)="toggleFormCollapse()">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<h3 class="text-base font-semibold text-gray-700">เพิ่มรายการงบประมาณสำหรับโครงการ</h3>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||||
<button class="text-gray-400 hover:text-gray-600 focus:outline-none">
|
</svg>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"
|
</button>
|
||||||
[ngClass]="{'rotate-180': !isFormExpanded}">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- เนื้อหาพับได้ -->
|
|
||||||
@if(!isFormExpanded){
|
<!-- Form Content -->
|
||||||
<div class="p-4 space-y-4">
|
@if(isFormExpanded){
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div class="p-6 bg-white animate-fade-in-down">
|
||||||
<div>
|
<form [formGroup]="budgetForm">
|
||||||
<label for="borrower_id" class="block text-sm font-medium text-gray-700 mb-1">หมวดงบประมาณ</label>
|
<div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-start">
|
||||||
<select name="" id="" class="w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500 shadow-sm">
|
|
||||||
<option value="">-- เลือกหมวดงบ --</option>
|
<!-- Dropdown หมวดงบ -->
|
||||||
@for (item of budgetCategoriesDrop.expense; track item.dtlcod) {
|
<div class="md:col-span-5 space-y-1">
|
||||||
<option [value]="item.dtlcod">{{ item.dtlnam }}</option>
|
<label class="block text-xs font-bold text-gray-500 uppercase">
|
||||||
}
|
หมวดงบประมาณ <span class="text-red-500">*</span>
|
||||||
</select>
|
</label>
|
||||||
|
<select formControlName="bdgcod"
|
||||||
|
class="w-full p-3 border border-gray-200 rounded-lg focus:ring-2 focus:ring-red-500 focus:border-transparent bg-gray-50 transition cursor-pointer"
|
||||||
|
[class.border-red-500]="budgetForm.get('bdgcod')?.invalid && budgetForm.get('bdgcod')?.touched">
|
||||||
|
<option value="">-- กรุณาเลือก --</option>
|
||||||
|
@for (item of myDropBdg; track item.bdgcod) {
|
||||||
|
<option [value]="item.bdgcod">{{ item.bdgnam }}</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<!-- Error Message -->
|
||||||
|
@if (budgetForm.get('bdgcod')?.invalid && budgetForm.get('bdgcod')?.touched) {
|
||||||
|
<div class="text-red-500 text-xs flex items-center gap-1">
|
||||||
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||||
|
กรุณาเลือกหมวดงบ
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Input จำนวนเงิน -->
|
||||||
|
<div class="md:col-span-5 space-y-1">
|
||||||
|
<label class="block text-xs font-bold text-gray-500 uppercase">
|
||||||
|
จำนวนเงิน <span class="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="relative">
|
||||||
|
<input type="number" formControlName="amount" placeholder="0.00"
|
||||||
|
class="w-full p-3 pr-12 border border-gray-200 rounded-lg focus:ring-2 focus:ring-red-500 focus:border-transparent bg-gray-50 text-right font-mono text-gray-800 transition"
|
||||||
|
[class.border-red-500]="budgetForm.get('amount')?.invalid && budgetForm.get('amount')?.touched">
|
||||||
|
<span class="absolute right-4 top-3 text-gray-400 text-sm font-medium pointer-events-none">THB</span>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Error Message -->
|
||||||
|
@if (budgetForm.get('amount')?.invalid && budgetForm.get('amount')?.touched) {
|
||||||
|
<div class="text-red-500 text-xs flex items-center gap-1">
|
||||||
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||||
|
ระบุจำนวนเงินที่ถูกต้อง
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<!-- Action Buttons -->
|
||||||
<label for="first_name" class="block text-sm font-medium text-gray-700 mb-1">จำนวนเงิน</label>
|
<div class="md:col-span-2 flex gap-2 pt-6">
|
||||||
<input type="text" id="first_name" name="first_name" type="number" class="w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500 shadow-sm" placeholder="">
|
<button type="button" (click)="onSaveSubmit()"
|
||||||
</div>
|
class="flex-1 bg-red-800 hover:bg-red-900 text-white font-bold py-3 px-4 rounded-lg shadow-md hover:shadow-lg transition active:scale-95 flex justify-center items-center gap-2">
|
||||||
</div>
|
<span>{{ isEditMode ? 'บันทึกแก้ไข' : 'เพิ่ม' }}</span>
|
||||||
|
|
||||||
<div class="flex justify-end pt-4 space-x-2">
|
|
||||||
|
|
||||||
<!-- <button class="flex items-center px-4 py-2 text-sm font-medium text-white bg-gray-500 rounded-md shadow-sm hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
||||||
</svg>
|
|
||||||
รีเซ็ต
|
|
||||||
</button> -->
|
|
||||||
|
|
||||||
<!-- <button class="flex items-center px-4 py-2 text-sm font-medium text-white bg-blue-500 rounded-md shadow-sm hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
||||||
</svg>
|
|
||||||
ค้นหา
|
|
||||||
</button> -->
|
|
||||||
|
|
||||||
<!-- <button class="flex items-center px-4 py-2 text-sm font-medium text-white bg-green-500 rounded-md shadow-sm hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0011.414 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3 3v-6" />
|
|
||||||
</svg>
|
|
||||||
ส่งออก Excel
|
|
||||||
</button> -->
|
|
||||||
<button class="flex items-center px-4 py-2 text-sm font-medium text-white bg-green-500 rounded-md shadow-sm hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0011.414 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3 3v-6" />
|
|
||||||
</svg>
|
|
||||||
เพิ่มเข้าสู่ตาราง
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@if(isEditMode) {
|
||||||
|
<button type="button" (click)="cancelEdit()"
|
||||||
|
class="bg-gray-200 hover:bg-gray-300 text-gray-600 font-bold py-3 px-4 rounded-lg transition active:scale-95">
|
||||||
|
ยกเลิก
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Table -->
|
|
||||||
<!-- <div class="overflow-x-auto bg-white shadow rounded-xl border">
|
|
||||||
<table class="min-w-full border-collapse text-sm">
|
|
||||||
|
|
||||||
<thead class="bg-gray-100 border-b">
|
|
||||||
<tr class="text-gray-700">
|
|
||||||
<th class="py-3 px-4">ลำดับ</th>
|
|
||||||
<th class="py-3 px-4">สถานะ</th>
|
|
||||||
<th class="py-3 px-4">รหัส</th>
|
|
||||||
<th class="py-3 px-4">ชื่อรายการ</th>
|
|
||||||
<th class="py-3 px-4 text-center">จำนวน</th>
|
|
||||||
<th class="py-3 px-4 text-right">ราคา/หน่วย</th>
|
|
||||||
<th class="py-3 px-4 text-right">ยอดชำระ</th>
|
|
||||||
<th class="py-3 px-4 text-center">ดำเนินการ</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
<tr
|
|
||||||
*ngFor="let item of budgetItems; let i = index"
|
|
||||||
class="border-b hover:bg-gray-50 transition"
|
|
||||||
>
|
|
||||||
<td class="py-3 px-4">{{ i + 1 }}</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-center">
|
|
||||||
<span class="text-green-500 text-xl">●</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 font-medium">{{ item.code }}</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 font-semibold">{{ item.name }}</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-center">
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
class="w-20 px-3 py-2 border rounded-lg text-center"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-right">
|
|
||||||
{{ item.price | number:'1.0-2' }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-right font-semibold">
|
|
||||||
{{ item.qty * item.price | number:'1.0-2' }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-3 px-4 text-center space-x-2">
|
|
||||||
<button
|
|
||||||
class="bg-red-500 hover:bg-red-600 text-white px-3 py-2 rounded-lg shadow"
|
|
||||||
>
|
|
||||||
🗑
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="bg-gray-600 hover:bg-gray-700 text-white px-3 py-2 rounded-lg shadow"
|
|
||||||
>
|
|
||||||
👁
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div> -->
|
|
||||||
<div class="overflow-x-auto bg-white border border-gray-200 rounded-2xl shadow-sm">
|
|
||||||
<table class="min-w-full text-left border-collapse">
|
|
||||||
<thead class="bg-gray-100 border-b border-gray-200 text-gray-700 text-sm">
|
|
||||||
<tr>
|
|
||||||
<th class="py-3 px-4 font-semibold">ลำดับ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold">ชื่องบประมาณ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold text-center">จำนวนเงิน</th>
|
|
||||||
<th class="py-3 px-4 font-semibold text-right pr-11">ดำเนินการ</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="let p of projects; let i = index"
|
|
||||||
class="border-b border-gray-100 hover:bg-blue-50/20 transition">
|
|
||||||
<td class="py-4 px-4 text-gray-700">{{ i + 1 }}</td>
|
|
||||||
<td class="py-4 px-4 font-medium text-gray-700"> {{ p.code }}</td>
|
|
||||||
|
|
||||||
<td class="py-4 px-4 text-center">
|
|
||||||
<input type="number" class="w-40 px-3 py-2 border border-gray-300 rounded-lg text-center hover:shadow-2xl">
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-4 px-4 text-right space-x-2 whitespace-nowrap pr-8">
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="bg-red-500 hover:bg-red-600 text-white px-3 py-2 rounded-lg shadow"
|
|
||||||
>
|
|
||||||
🗑
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="bg-gray-600 hover:bg-gray-700 text-white px-3 py-2 rounded-lg shadow"
|
|
||||||
>
|
|
||||||
🖊
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<!-- endtable -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Summary -->
|
|
||||||
<div class="text-right mt-4 text-lg font-semibold">
|
|
||||||
ยอดรวมทั้งหมด:
|
|
||||||
<span class="text-blue-600">
|
|
||||||
{{ getTotalAmount() | number:'1.0-2' }} บาท
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 3. Budget Table -->
|
||||||
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="min-w-full text-left border-collapse">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-red-900 text-white text-sm uppercase tracking-wider">
|
||||||
|
<th class="py-4 px-6 font-semibold w-16 text-center">#</th>
|
||||||
|
<th class="py-4 px-6 font-semibold">รายการ / หมวดงบ</th>
|
||||||
|
<th class="py-4 px-6 font-semibold text-right w-48">จำนวนเงิน (บาท)</th>
|
||||||
|
<th class="py-4 px-6 font-semibold text-center w-32">จัดการ</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-100 text-sm">
|
||||||
|
@for (idx of myTrnMst; track idx.trnseq; let i = $index) {
|
||||||
|
<tr class="hover:bg-red-50/40 transition group">
|
||||||
|
<td class="py-4 px-6 text-center text-gray-500 font-mono">{{ i + 1 }}</td>
|
||||||
|
|
||||||
|
<td class="py-4 px-6">
|
||||||
|
<div class="font-bold text-gray-800">{{ idx.trnbdgnam }}</div>
|
||||||
|
<div class="text-xs text-gray-400 font-mono mt-0.5">{{ idx.trnbdgcod }}</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-4 px-6 text-right font-mono font-medium text-gray-700">
|
||||||
|
{{ idx.trnexpbdg | number:'1.2-2' }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-4 px-6 text-center">
|
||||||
|
<div class="flex justify-center items-center gap-2">
|
||||||
|
<button (click)="editItem(i)" class="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition" title="แก้ไข">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button (click)="removeItem(i)" class="p-2 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition" title="ลบ">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
} @empty {
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" class="py-12 text-center text-gray-400 bg-gray-50/30">
|
||||||
|
<div class="text-4xl mb-2 opacity-50">📭</div>
|
||||||
|
<p>ยังไม่มีรายการงบประมาณ</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<!-- Footer Total & Action Buttons -->
|
||||||
|
<tfoot class="bg-gray-50 border-t-2 border-red-200">
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="py-4 px-6 text-right font-bold text-gray-600 uppercase text-xs tracking-wider">รวมยอดสุทธิ</td>
|
||||||
|
<td class="py-4 px-6 text-right">
|
||||||
|
<span class="text-xl font-extrabold text-red-900">{{ getTotalAmount() | number:'1.2-2' }}</span>
|
||||||
|
<span class="text-xs text-gray-500 ml-1 font-medium">THB</span>
|
||||||
|
</td>
|
||||||
|
<td class="py-4 px-6 text-center">
|
||||||
|
<div class="flex items-center justify-center gap-3">
|
||||||
|
<!-- 🟢 ปุ่มย้อนกลับ (Icon Arrow) -->
|
||||||
|
<button (click)="goBack()" class="p-2.5 bg-white border border-gray-200 rounded-lg text-gray-500 hover:text-red-700 hover:border-red-200 hover:bg-red-50 hover:shadow-sm transition active:scale-95 group" title="ย้อนกลับ">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 group-hover:-translate-x-1 transition-transform duration-200" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 🟢 ปุ่มยืนยันบันทึกทั้งหมด -->
|
||||||
|
<button (click)="openConfirmModal()"
|
||||||
|
class="bg-green-600 hover:bg-green-700 text-white text-xs font-bold py-2.5 px-5 rounded-lg shadow transition active:scale-95 flex items-center gap-2">
|
||||||
|
<span>✓</span> บันทึก
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 🟢 Modal Confirmation (Save / Cancel) -->
|
||||||
|
@if(showConfirmModal) {
|
||||||
|
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-fade-in">
|
||||||
|
<div class="bg-white rounded-2xl shadow-2xl w-96 overflow-hidden transform transition-all scale-100">
|
||||||
|
|
||||||
|
<!-- 🟢 Dynamic Header Color -->
|
||||||
|
<div class="p-4 text-white flex justify-between items-center"
|
||||||
|
[ngClass]="myTrnMst.length === 0 ? 'bg-red-600' : 'bg-red-900'">
|
||||||
|
<h3 class="font-bold text-lg flex items-center gap-2">
|
||||||
|
<span>{{ myTrnMst.length === 0 ? '⚠️' : '💾' }}</span>
|
||||||
|
{{ myTrnMst.length === 0 ? 'ยืนยันการยกเลิก' : 'ยืนยันการบันทึก' }}
|
||||||
|
</h3>
|
||||||
|
<button (click)="closeConfirmModal()" class="text-white/70 hover:text-white">✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-6 text-center space-y-4">
|
||||||
|
<!-- 🟢 Dynamic Icon -->
|
||||||
|
<div class="w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-2"
|
||||||
|
[ngClass]="myTrnMst.length === 0 ? 'bg-red-50 text-red-600' : 'bg-red-50 text-red-600'">
|
||||||
|
<span class="text-3xl">{{ myTrnMst.length === 0 ? '🗑️' : '📝' }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 🟢 Dynamic Message -->
|
||||||
|
<p class="text-gray-600">
|
||||||
|
@if(myTrnMst.length === 0) {
|
||||||
|
คุณต้องการ <b>ยกเลิกการจัดสรรงบประมาณ</b> <br>ของโครงการนี้ใช่หรือไม่?
|
||||||
|
} @else {
|
||||||
|
คุณต้องการ <b>บันทึกข้อมูลการจัดสรรงบประมาณ</b> <br>ของโครงการนี้ใช่หรือไม่?
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Summary Info -->
|
||||||
|
<div class="bg-gray-50 p-3 rounded-lg border border-gray-100 text-sm">
|
||||||
|
<div class="flex justify-between mb-1">
|
||||||
|
<span class="text-gray-500">จำนวนรายการ:</span>
|
||||||
|
<span class="font-bold text-gray-800">{{ myTrnMst.length }} รายการ</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-gray-500">ยอดรวม:</span>
|
||||||
|
<span class="font-bold text-red-800">{{ getTotalAmount() | number:'1.2-2' }} บาท</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 🟢 List of Items (บอกรายการ) -->
|
||||||
|
<div class="text-xs text-gray-500 mt-2 text-left max-h-32 overflow-y-auto border-t border-gray-200 pt-2">
|
||||||
|
<div class="font-semibold mb-1">รายการ:</div>
|
||||||
|
@if(myTrnMst.length > 0) {
|
||||||
|
<ul class="list-disc pl-4 space-y-1">
|
||||||
|
@for(item of myTrnMst; track $index) {
|
||||||
|
<li>{{ item.trnbdgnam }} ({{ item.trnexpbdg | number }})</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
} @else {
|
||||||
|
<p class="text-red-500 italic">- ไม่พบรายการคงเหลือ (ลบทั้งหมด) -</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal Footer -->
|
||||||
|
<div class="p-4 bg-gray-50 flex gap-3 border-t border-gray-100">
|
||||||
|
<button (click)="closeConfirmModal()" class="flex-1 py-2.5 px-4 bg-white border border-gray-300 text-gray-700 font-bold rounded-xl hover:bg-gray-50 transition">
|
||||||
|
ยกเลิก
|
||||||
|
</button>
|
||||||
|
<!-- 🟢 Dynamic Button Color -->
|
||||||
|
<button (click)="confirmSave()"
|
||||||
|
class="flex-1 py-2.5 px-4 text-white font-bold rounded-xl shadow-md hover:shadow-lg transition"
|
||||||
|
[ngClass]="myTrnMst.length === 0 ? 'bg-red-600 hover:bg-red-700' : 'bg-red-800 hover:bg-red-900'">
|
||||||
|
{{ myTrnMst.length === 0 ? 'ยืนยันการยกเลิก' : 'ยืนยัน' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<!-- 🟢 Modal Confirmation
|
||||||
|
@if(showConfirmModal) {
|
||||||
|
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-fade-in">
|
||||||
|
<div class="bg-white rounded-2xl shadow-2xl w-96 overflow-hidden transform transition-all scale-100">
|
||||||
|
|
||||||
|
Modal Header
|
||||||
|
<div class="bg-red-900 p-4 text-white flex justify-between items-center">
|
||||||
|
<h3 class="font-bold text-lg flex items-center gap-2">
|
||||||
|
<span>💾</span> ยืนยันการบันทึก
|
||||||
|
</h3>
|
||||||
|
<button (click)="closeConfirmModal()" class="text-white/70 hover:text-white">✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Modal Body
|
||||||
|
<div class="p-6 text-center space-y-4">
|
||||||
|
<div class="w-16 h-16 bg-red-50 rounded-full flex items-center justify-center mx-auto mb-2">
|
||||||
|
<span class="text-3xl">📝</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-gray-600">คุณต้องการบันทึกข้อมูลการจัดสรรงบประมาณใช่หรือไม่?</p>
|
||||||
|
|
||||||
|
<div class="bg-gray-50 p-3 rounded-lg border border-gray-100 text-sm">
|
||||||
|
<div class="flex justify-between mb-1">
|
||||||
|
<span class="text-gray-500">จำนวนรายการ:</span>
|
||||||
|
<span class="font-bold text-gray-800">{{ myTrnMst.length }} รายการ</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<span class="text-gray-500">ยอดรวม:</span>
|
||||||
|
<span class="font-bold text-red-800">{{ getTotalAmount() | number:'1.2-2' }} บาท</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Modal Footer
|
||||||
|
<div class="p-4 bg-gray-50 flex gap-3 border-t border-gray-100">
|
||||||
|
<button (click)="closeConfirmModal()" class="flex-1 py-2.5 px-4 bg-white border border-gray-300 text-gray-700 font-bold rounded-xl hover:bg-gray-50 transition">
|
||||||
|
ยกเลิก
|
||||||
|
</button>
|
||||||
|
<button (click)="confirmSave()" class="flex-1 py-2.5 px-4 bg-red-800 text-white font-bold rounded-xl hover:bg-red-900 shadow-md hover:shadow-lg transition">
|
||||||
|
ยืนยัน
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
} -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 🔴 Modal Confirmation (Delete) -->
|
||||||
|
@if(showDeleteModal) {
|
||||||
|
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-fade-in">
|
||||||
|
<div class="bg-white rounded-2xl shadow-2xl w-96 overflow-hidden transform transition-all scale-100">
|
||||||
|
|
||||||
|
<div class="bg-red-600 p-4 text-white flex justify-between items-center">
|
||||||
|
<h3 class="font-bold text-lg flex items-center gap-2">
|
||||||
|
<span>🗑️</span> ยืนยันการลบ
|
||||||
|
</h3>
|
||||||
|
<button (click)="closeDeleteModal()" class="text-white/70 hover:text-white">✕</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-6 text-center space-y-4">
|
||||||
|
<div class="w-16 h-16 bg-red-50 rounded-full flex items-center justify-center mx-auto mb-2">
|
||||||
|
<span class="text-3xl">⚠️</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-gray-600">คุณต้องการลบรายการนี้ใช่หรือไม่?</p>
|
||||||
|
<p class="text-sm text-gray-500">การกระทำนี้ไม่สามารถย้อนกลับได้ (ในหน้าจอนี้)</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4 bg-gray-50 flex gap-3 border-t border-gray-100">
|
||||||
|
<button (click)="closeDeleteModal()" class="flex-1 py-2.5 px-4 bg-white border border-gray-300 text-gray-700 font-bold rounded-xl hover:bg-gray-50 transition">
|
||||||
|
ยกเลิก
|
||||||
|
</button>
|
||||||
|
<button (click)="confirmDelete()" class="flex-1 py-2.5 px-4 bg-red-600 text-white font-bold rounded-xl hover:bg-red-700 shadow-md hover:shadow-lg transition">
|
||||||
|
ลบรายการ
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
import { TransactionStateService } from './../../services/state/transaction-state.service';
|
||||||
|
import { ITrnmst, IDropBdg } from './../../interfaces/main.interface';
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
||||||
import { GeneralService } from '../../services/generalservice';
|
import { GeneralService } from '../../services/generalservice';
|
||||||
import { IDropAct, IStateDrop, IStateResultResponse, IActData, IActSumData } from '../../interfaces/dashboard.interface'
|
|
||||||
import { DashboardStateService } from '../../services/state/dashboard-state.service';
|
import { DashboardStateService } from '../../services/state/dashboard-state.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { ToastrService } from 'ngx-toastr';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-budget-aproval',
|
selector: 'app-budget-aproval',
|
||||||
@@ -12,109 +15,239 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
templateUrl: './budget-aproval.html',
|
templateUrl: './budget-aproval.html',
|
||||||
styleUrl: './budget-aproval.css',
|
styleUrl: './budget-aproval.css',
|
||||||
})
|
})
|
||||||
export class BudgetAproval {
|
export class BudgetAproval implements OnInit {
|
||||||
projectCode: any;
|
@Output() ExpenseEventSubmit = new EventEmitter<any>();
|
||||||
project: any;
|
|
||||||
addItemForm!: FormGroup;
|
|
||||||
isFormExpanded: boolean = false;
|
|
||||||
|
|
||||||
budgetItems = [
|
budgetForm!: FormGroup;
|
||||||
{ code: 'ITEM001', name: 'เอกซ์เรย์', qty: 1, price: 1000 },
|
isFormExpanded = true;
|
||||||
{ code: 'ITEM002', name: 'กรอกคำสั่งซื้อ', qty: 1, price: 1500 },
|
isEditMode = false;
|
||||||
{ code: 'ITEM003', name: 'ตรวจพื้นฐาน', qty: 1, price: 1000 },
|
editingIndex: number = -1;
|
||||||
];
|
showConfirmModal = false;
|
||||||
|
myTrnMst: ITrnmst[]=[];
|
||||||
|
myDropBdg: IDropBdg[]=[];
|
||||||
|
param:string = '';
|
||||||
|
// State สำหรับการลบ
|
||||||
|
showDeleteModal = false;
|
||||||
|
deleteIndex: number = -1;
|
||||||
|
|
||||||
projects = [
|
// budgetCategoriesDrop = [
|
||||||
{ code: 'เงินรายได้', name: 'ระบบจัดการน้ำดื่ม', owner: 'นาย A', budget: 20000, status: 'WAIT', acp: 0, bdgnam: 'ยังไมจัดสรร' },
|
// { dtlcod: 'EXP01', dtlnam: 'ค่าวัสดุอุปกรณ์ (EXP01)' },
|
||||||
{ code: 'งบดำเนินงาน', name: 'ปรับปรุงอาคาร B', owner: 'นางสาว B', budget: 45000, status: 'WAIT', acp: 0, bdgnam: 'ยังไมจัดสรร'},
|
// { dtlcod: 'EXP02', dtlnam: 'ค่าจ้างเหมาแรงงาน (EXP02)' },
|
||||||
{ code: 'ค่ากิจกรรมพัฒนาคุณภาพผู้เรียน', name: 'ซื้อคอมพิวเตอร์', owner: 'นาย C', budget: 30000, status: 'APPROVED', acp: 20000, bdgnam: 'งบดำเนินงาน' }
|
// { dtlcod: 'EXP03', dtlnam: 'ค่าครุภัณฑ์ (EXP03)' }
|
||||||
];
|
// ];
|
||||||
|
|
||||||
budgetCategoriesDrop = {
|
// budgetItems: IBudgetItem[] = [];
|
||||||
expense: [
|
|
||||||
{ dtlcod: 'BDG001', dtlnam: 'เงินรายได้' },
|
|
||||||
{ dtlcod: 'BDG002', dtlnam: 'งบดำเนินงาน ปวส.' },
|
|
||||||
{ dtlcod: 'BDG003', dtlnam: 'โครงการส่งเสริมพัฒนาทักษะวิชาชีพทักษะพื้นฐาน' },
|
|
||||||
{ dtlcod: 'BDG004', dtlnam: 'ค่ากิจกรรมพัฒนาคุณภาพผู้เรียน' },
|
|
||||||
{ dtlcod: 'BDG005', dtlnam: 'อุดหนุนส่งเสริมและพัฒนาผู้เรียนองค์การวิชาชีพแห่งประเทศไทย (อวท.)' },
|
|
||||||
{ dtlcod: 'BDG006', dtlnam: 'งบดำเนินงาน ระยะสั้น' },
|
|
||||||
{ dtlcod: 'BDG007', dtlnam: 'โครงการบูรณาการการพัฒนาทักษะทางวิชาชีพกับการเสริมสร้างคุณลักษณะอันพึงประสงค์ (FIX IT)' },
|
|
||||||
{ dtlcod: 'BDG008', dtlnam: 'โครงการพัฒนาทักษะและสมรรถนะวิชาชีพกำลังคน (Up-skill, Re-skill)' },
|
|
||||||
{ dtlcod: 'BDG009', dtlnam: 'งบดำเนินงาน ปวช.' },
|
|
||||||
{ dtlcod: 'BDG010', dtlnam: 'โครงการขยายและยกระดับการจัดอาชีวศึกษาระบบทวิภาคีคุณภาพสูง' },
|
|
||||||
{ dtlcod: 'BDG011', dtlnam: 'ปวช.(สอจ)' },
|
|
||||||
{ dtlcod: 'BDG012', dtlnam: 'ค่าจัดการเรียนการสอน' },
|
|
||||||
{ dtlcod: 'BDG013', dtlnam: 'งบดำเนินงาน 170000' },
|
|
||||||
{ dtlcod: 'BDG014', dtlnam: 'โครงการพัฒนาทักษะและศักยภาพภาพการจัดการเรียนการสอนอาชีวศึกษา' },
|
|
||||||
{ dtlcod: 'BDG015', dtlnam: 'ศึกษาธิการ' },
|
|
||||||
{ dtlcod: 'BDG016', dtlnam: 'Up-skill' },
|
|
||||||
{ dtlcod: 'BDG017', dtlnam: 'ติดตามผู้สำเร็จ' },
|
|
||||||
{ dtlcod: 'BDG018', dtlnam: 'ทวิภาคี' },
|
|
||||||
{ dtlcod: 'BDG019', dtlnam: 'พันธุกรรม' },
|
|
||||||
{ dtlcod: 'BDG020', dtlnam: 'ปวส(สาธารณูประโภค)' },
|
|
||||||
{ dtlcod: 'BDG021', dtlnam: 'ปวส(ค่าสาธารณูปโภค)' },
|
|
||||||
{ dtlcod: 'BDG022', dtlnam: 'งบดำเนินงาน (ค่าสาธารณูปโภค)' },
|
|
||||||
{ dtlcod: 'BDG023', dtlnam: 'ค่าหนังสือเรียน' },
|
|
||||||
{ dtlcod: 'BDG024', dtlnam: 'โครงการอาชีวะต้านยาเสพติด' },
|
|
||||||
{ dtlcod: 'BDG025', dtlnam: 'ค่าตอบแทนพนักงานราชการ' },
|
|
||||||
{ dtlcod: 'BDG026', dtlnam: 'ค่าอุปกรณ์การเรียน' },
|
|
||||||
{ dtlcod: 'BDG027', dtlnam: 'โครงการยกระดับและพัฒนาขีดความสามารถด้านภาษาและทักษะดิจิทัลเพื่อพัฒนากำลังคนให้มีสมรรถนะสูง' },
|
|
||||||
{ dtlcod: 'BDG028', dtlnam: 'โครงการอนุรักษ์พันธุกรรมพืชอันเนื่องมาจากพระราชดำริ' },
|
|
||||||
{ dtlcod: 'BDG029', dtlnam: 'ปวช.(สอจ.)' },
|
|
||||||
{ dtlcod: 'BDG030', dtlnam: 'โครงการพัฒนาศักยภาพผู้เรียนอาชีวศึกษาในการเป็นผู้ประกอบการ (บ่มเพาะ)' },
|
|
||||||
{ dtlcod: 'BDG031', dtlnam: 'โครงการพัฒนาและยกระดับการติดตามผู้สำเร็จการศึกษาอาชีวศึกษา' },
|
|
||||||
{ dtlcod: 'BDG032', dtlnam: 'โครงการเสริมสร้างคุณธรรม จริยธรรมและธรรมาภิบาลในสถานศึกษา' },
|
|
||||||
{ dtlcod: 'BDG033', dtlnam: 'โครงการจัดการอาชีวศึกษาเพื่อสนองพระราชดำริ' },
|
|
||||||
{ dtlcod: 'BDG034', dtlnam: 'เงินรายได้ ป.ตรี' },
|
|
||||||
{ dtlcod: 'BDG035', dtlnam: 'งบดำเนินงาน 235200' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private location: Location,
|
||||||
|
private toastr: ToastrService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private transactionStateService: TransactionStateService
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.setupForm();
|
this.param = this.route.snapshot.paramMap.get('seq') ?? '';
|
||||||
}
|
this.setupFormControl();
|
||||||
|
this.transactionStateService.getTransactionState().subscribe(data => {
|
||||||
setupForm() {
|
this.myTrnMst = data || []
|
||||||
this.addItemForm = new FormGroup({
|
});
|
||||||
category: new FormControl('', [Validators.required]),
|
this.transactionStateService.getBudgetDrop().subscribe(data => {
|
||||||
name: new FormControl('', [Validators.required]),
|
this.myDropBdg = data ?? []
|
||||||
qty: new FormControl(1, [Validators.required, Validators.min(1)]),
|
});
|
||||||
price: new FormControl(0, [Validators.required, Validators.min(1)])
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleFormCollapse(): void {
|
|
||||||
this.isFormExpanded = !this.isFormExpanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
addBudgetItem() {
|
|
||||||
if (this.addItemForm.invalid) {
|
|
||||||
this.addItemForm.markAllAsTouched();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const formValue = this.addItemForm.value;
|
setupFormControl() {
|
||||||
|
this.budgetForm = new FormGroup({
|
||||||
|
bdgcod: new FormControl('', [Validators.required]),
|
||||||
|
amount: new FormControl('', [Validators.required, Validators.min(1)])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.budgetItems.push({
|
toggleFormCollapse() {
|
||||||
code: 'NEW' + (this.budgetItems.length + 1).toString().padStart(3, '0'),
|
this.isFormExpanded = !this.isFormExpanded;
|
||||||
name: formValue.name,
|
}
|
||||||
qty: formValue.qty,
|
|
||||||
price: formValue.price,
|
|
||||||
// category: formValue.category
|
|
||||||
});
|
|
||||||
|
|
||||||
// reset form
|
|
||||||
this.addItemForm.reset({
|
|
||||||
category: '',
|
|
||||||
name: '',
|
|
||||||
qty: 1,
|
|
||||||
price: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getTotalAmount() {
|
|
||||||
return this.budgetItems.reduce((sum, item) => sum + item.qty * item.price, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// onSaveSubmit() {
|
||||||
|
// if (this.budgetForm.invalid) {
|
||||||
|
// this.budgetForm.markAllAsTouched();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const formValue = this.budgetForm.value;
|
||||||
|
// const selectedCode = formValue.bdgcod;
|
||||||
|
|
||||||
|
// // Validation: เช็คว่าหมวดงบซ้ำหรือไม่
|
||||||
|
// const duplicateIndex = this.myTrnMst.findIndex(idx => idx.trnbdgcod === selectedCode);
|
||||||
|
|
||||||
|
// if (duplicateIndex !== -1) {
|
||||||
|
// // กรณีเพิ่มใหม่ (เจอซ้ำ = ห้าม) หรือ กรณีแก้ไข (เจอซ้ำกับแถวอื่นที่ไม่ใช่ตัวเอง = ห้าม)
|
||||||
|
// if (!this.isEditMode || (this.isEditMode && duplicateIndex !== this.editingIndex)) {
|
||||||
|
// this.toastr.error(`หมวดงบประมาณนี้ มีอยู่ในตารางแล้ว`, 'ไม่สามารถเพิ่มซ้ำได้', {
|
||||||
|
// positionClass: 'toast-top-right',
|
||||||
|
// timeOut: 3500,
|
||||||
|
// progressBar: true,
|
||||||
|
// progressAnimation: 'decreasing',
|
||||||
|
// toastClass:
|
||||||
|
// 'ngx-toastr error-toast bg-white bg-opacity-90 text-red-700 shadow-lg'
|
||||||
|
// })
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const category = this.myDropBdg.find(c => c.bdgcod === selectedCode);
|
||||||
|
|
||||||
|
// const newItem: ITrnmst = {
|
||||||
|
// trnbdgcod: formValue.bdgcod,
|
||||||
|
// trnbdgnam: category ? category.bdgcod : formValue.bdgcod,
|
||||||
|
// trnexpbdg: Number(formValue.amount)
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if (this.isEditMode && this.editingIndex > -1) {
|
||||||
|
// this.myTrnMst[this.editingIndex] = newItem;
|
||||||
|
// this.cancelEdit();
|
||||||
|
// } else {
|
||||||
|
// this.myTrnMst.push(newItem);
|
||||||
|
// this.budgetForm.reset();
|
||||||
|
// this.budgetForm.get('bdgcod')?.setValue('');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
onSaveSubmit() {
|
||||||
|
if (this.budgetForm.invalid) {
|
||||||
|
this.budgetForm.markAllAsTouched();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formValue = this.budgetForm.value;
|
||||||
|
const selectedCode = formValue.bdgcod;
|
||||||
|
|
||||||
|
// 1. Validation: เช็คว่าหมวดงบซ้ำหรือไม่
|
||||||
|
const duplicateIndex = this.myTrnMst.findIndex(idx => idx.trnbdgcod === selectedCode);
|
||||||
|
|
||||||
|
if (duplicateIndex !== -1) {
|
||||||
|
// ถ้าไม่ใช่โหมดแก้ไข หรือ แก้ไขแต่ไปซ้ำกับคนอื่น
|
||||||
|
if (!this.isEditMode || (this.isEditMode && duplicateIndex !== this.editingIndex)) {
|
||||||
|
this.toastr.error(`หมวดงบประมาณนี้ (${selectedCode}) มีอยู่ในตารางแล้ว`, 'ไม่สามารถเพิ่มซ้ำได้', {
|
||||||
|
timeOut: 3500,
|
||||||
|
progressBar: true
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 2. ค้นหาชื่อหมวดงบ (Name) จาก Dropdown โดยใช้ Code ที่เลือก
|
||||||
|
const category = this.myDropBdg.find(c => c.bdgcod === selectedCode);
|
||||||
|
|
||||||
|
// ✅ 3. สร้าง Object ใหม่ โดยใส่ชื่อ (trnbdgnam) ที่ค้นหาได้ลงไป
|
||||||
|
const newItem: ITrnmst = {
|
||||||
|
trnbdgcod: selectedCode,
|
||||||
|
// ถ้าเจอชื่อให้ใส่ชื่อ ถ้าไม่เจอให้ใส่รหัสแทน (กันเหนียว)
|
||||||
|
trnbdgnam: category ? category.bdgnam : selectedCode,
|
||||||
|
trnexpbdg: Number(formValue.amount),
|
||||||
|
trnprjnam: this.projectTitle // คงชื่อโครงการเดิมไว้
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.isEditMode && this.editingIndex > -1) {
|
||||||
|
// กรณีแก้ไข: Merge ข้อมูลใหม่ทับของเดิม (เพื่อรักษา field อื่นๆ เช่น trnseq ไว้ถ้ามี)
|
||||||
|
this.myTrnMst[this.editingIndex] = {
|
||||||
|
...this.myTrnMst[this.editingIndex],
|
||||||
|
...newItem
|
||||||
|
};
|
||||||
|
this.cancelEdit();
|
||||||
|
} else {
|
||||||
|
// กรณีเพิ่มใหม่
|
||||||
|
this.myTrnMst.push(newItem);
|
||||||
|
this.budgetForm.reset();
|
||||||
|
this.budgetForm.get('bdgcod')?.setValue('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editItem(index: number) {
|
||||||
|
const item = this.myTrnMst[index];
|
||||||
|
this.isEditMode = true;
|
||||||
|
this.editingIndex = index;
|
||||||
|
this.isFormExpanded = true;
|
||||||
|
this.budgetForm.patchValue({
|
||||||
|
bdgcod: item.trnbdgcod,
|
||||||
|
amount: item.trnexpbdg
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelEdit() {
|
||||||
|
this.isEditMode = false;
|
||||||
|
this.editingIndex = -1;
|
||||||
|
this.budgetForm.reset();
|
||||||
|
this.budgetForm.get('bdgcod')?.setValue('');
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItem(index: number) {
|
||||||
|
// // if(confirm('ต้องการลบรายการนี้หรือไม่?')) {
|
||||||
|
// this.myTrnMst.splice(index, 1);
|
||||||
|
// if (this.isEditMode && this.editingIndex === index) {
|
||||||
|
// this.cancelEdit();
|
||||||
|
// }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
this.deleteIndex = index;
|
||||||
|
this.showDeleteModal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmDelete() {
|
||||||
|
if (this.deleteIndex > -1) {
|
||||||
|
this.myTrnMst.splice(this.deleteIndex, 1);
|
||||||
|
|
||||||
|
// ถ้าลบตัวที่กำลังแก้อยู่ ให้เคลียร์ฟอร์ม
|
||||||
|
if (this.isEditMode && this.editingIndex === this.deleteIndex) {
|
||||||
|
this.cancelEdit();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toastr.success('ลบรายการเรียบร้อย', 'สำเร็จ');
|
||||||
|
}
|
||||||
|
this.closeDeleteModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
closeDeleteModal() {
|
||||||
|
this.showDeleteModal = false;
|
||||||
|
this.deleteIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTotalAmount() {
|
||||||
|
return this.myTrnMst.reduce((sum, item) => sum + Number(item.trnexpbdg || 0), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
openConfirmModal() {
|
||||||
|
this.showConfirmModal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeConfirmModal() {
|
||||||
|
this.showConfirmModal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmSave() {
|
||||||
|
const expenseList = this.myTrnMst.map(item => ({
|
||||||
|
bdgcod: item.trnbdgcod,
|
||||||
|
amount: Number(item.trnexpbdg)
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
prjseq: this.param,
|
||||||
|
expenseList: expenseList
|
||||||
|
};
|
||||||
|
|
||||||
|
this.expenseEventSubmit(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
expenseEventSubmit(event: any){
|
||||||
|
this.ExpenseEventSubmit.emit(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
goBack() {
|
||||||
|
this.location.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectTitle(): string {
|
||||||
|
return this.myTrnMst?.[0]?.trnprjnam ?? '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,39 +22,39 @@
|
|||||||
|
|
||||||
<main class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-6">
|
<main class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-6">
|
||||||
<div class="md:col-span-2 ">
|
<div class="md:col-span-2 ">
|
||||||
<div class="bg-white p-6 rounded-xl shadow-lg h-88">
|
<div class="bg-white p-6 rounded-xl shadow-lg">
|
||||||
<h2 class="text-lg font-medium text-gray-700 mb-4">เมนู</h2>
|
<h2 class="text-lg font-medium text-gray-700 mb-4">เมนู</h2>
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
<!-- <button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m4 2h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m4 2h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-gray-700">การเบิกงวดงบ</span>
|
<span class="text-gray-700">การเบิกงวดงบ</span>
|
||||||
</button>
|
</button> -->
|
||||||
|
|
||||||
<button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
<!-- <button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-gray-700">สัญญา / ข้อตกลง</span>
|
<span class="text-gray-700">สัญญา / ข้อตกลง</span>
|
||||||
</button>
|
</button> -->
|
||||||
|
|
||||||
<button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
<!-- <button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
||||||
<!-- <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.102a9 9 0 11-12.728 0m12.728 0a9 9 0 00-12.728 0M3 12a9 9 0 1118 0" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.102a9 9 0 11-12.728 0m12.728 0a9 9 0 00-12.728 0M3 12a9 9 0 1118 0" />
|
||||||
</svg> -->
|
</svg>
|
||||||
<img src="stamp_0.png" alt="" class="h-6 w-6 text-gray-500 opacity-50">
|
<img src="stamp_0.png" alt="" class="h-6 w-6 text-gray-500 opacity-50">
|
||||||
<span class="text-gray-700">การอนุมัติโครงการ</span>
|
<span class="text-gray-700">การอนุมัติโครงการ</span>
|
||||||
</button>
|
</button> -->
|
||||||
|
|
||||||
<button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
<!-- <button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-gray-700">เอกสารฟอร์มวิทยาลัย</span>
|
<span class="text-gray-700">เอกสารฟอร์มวิทยาลัย</span>
|
||||||
</button>
|
</button> -->
|
||||||
|
|
||||||
<button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer">
|
<button class="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition duration-150 cursor-pointer" (click)="navigate('main/manager')">
|
||||||
<!-- <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<!-- <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 3.055A9.992 9.992 0 0112 21c-3.142 0-6.186-1.042-8.625-2.999M21 12a9.992 9.992 0 00-3-6.945M3 12a9.992 9.992 0 013-6.945M12 15a3 3 0 100-6 3 3 0 000 6z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 3.055A9.992 9.992 0 0112 21c-3.142 0-6.186-1.042-8.625-2.999M21 12a9.992 9.992 0 00-3-6.945M3 12a9.992 9.992 0 013-6.945M12 15a3 3 0 100-6 3 3 0 000 6z" />
|
||||||
</svg> -->
|
</svg> -->
|
||||||
|
|||||||
@@ -1,131 +1,126 @@
|
|||||||
<div class="w-full p-6">
|
|
||||||
|
|
||||||
<!-- Summary Cards -->
|
<div class="w-full p-6">
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-6 mb-8">
|
|
||||||
<!--
|
|
||||||
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
|
|
||||||
<div class="text-gray-500 text-sm">งบทั้งหมด</div>
|
|
||||||
<div class="text-3xl font-bold text-gray-800 mt-1">
|
|
||||||
{{ totalBudget | number:'1.0-2' }} บาท
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
|
<!-- Summary Cards -->
|
||||||
<div class="text-gray-500 text-sm">งบที่อนุมัติแล้ว</div>
|
<div class="grid grid-cols-1 sm:grid-cols-3 gap-6 mb-8">
|
||||||
<div class="text-3xl font-bold text-green-600 mt-1">
|
<!--
|
||||||
{{ approvedBudget | number:'1.0-2' }} บาท
|
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
|
||||||
</div>
|
<div class="text-gray-500 text-sm">งบทั้งหมด</div>
|
||||||
</div>
|
<div class="text-3xl font-bold text-gray-800 mt-1">
|
||||||
|
{{ totalBudget | number:'1.0-2' }} บาท
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
|
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
|
||||||
<div class="text-gray-500 text-sm">งบคงเหลือ</div>
|
<div class="text-gray-500 text-sm">งบที่อนุมัติแล้ว</div>
|
||||||
<div
|
<div class="text-3xl font-bold text-green-600 mt-1">
|
||||||
class="text-3xl font-bold mt-1"
|
{{ approvedBudget | number:'1.0-2' }} บาท
|
||||||
[ngClass]="remainingBudget >= 0 ? 'text-blue-600' : 'text-red-600'"
|
</div>
|
||||||
>
|
</div>
|
||||||
{{ remainingBudget | number:'1.0-2' }} บาท
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
</div>
|
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
|
||||||
|
<div class="text-gray-500 text-sm">งบคงเหลือ</div>
|
||||||
<!-- Add Button -->
|
<div
|
||||||
<div class="mb-4">
|
class="text-3xl font-bold mt-1"
|
||||||
<button
|
[ngClass]="remainingBudget >= 0 ? 'text-blue-600' : 'text-red-600'"
|
||||||
class=" rounded-3xl bg-green-600 hover:bg-green-700 text-white px-5 py-2.5 text-sm font-medium shadow-sm flex items-center gap-2 transition"
|
|
||||||
>
|
|
||||||
➕ เพิ่มโครงการใหม่
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Table -->
|
|
||||||
<div class="overflow-x-auto bg-white border border-gray-200 rounded-2xl shadow-sm">
|
|
||||||
<table class="min-w-full text-left border-collapse">
|
|
||||||
<thead class="bg-red-900 border-b border-gray-200 text-white text-sm">
|
|
||||||
<tr>
|
|
||||||
<th class="py-3 px-4 font-semibold">ลำดับ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold">รหัสโครงการ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold">ชื่อโครงการ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold">ผู้รับผิดชอบ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold">งบที่ขออนุมัติ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold">หมวดงบ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold">จำนวนที่อนุมัติ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold text-center">สถานะ</th>
|
|
||||||
<th class="py-3 px-4 font-semibold text-center">ดำเนินการ</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="let p of projects; let i = index"class="border-b border-gray-100 hover:bg-blue-50/20 transition">
|
|
||||||
<td class="py-4 px-4 text-gray-700">{{ i + 1 }}</td>
|
|
||||||
<td class="py-4 px-4 font-medium text-gray-700"> {{ p.code }}</td>
|
|
||||||
<td class="py-4 px-4 text-gray-800 font-semibold leading-tight">{{ p.name }}</td>
|
|
||||||
<td class="py-4 px-4 text-gray-700">{{ p.owner }}</td>
|
|
||||||
<td class="py-4 px-4 text-blue-700 font-bold whitespace-nowrap"> {{ p.budget | number:'1.0-0' }} บาท</td>
|
|
||||||
|
|
||||||
<td class="py-4 px-4 w-64">
|
|
||||||
<!-- <select class="w-full px-4 py-2.5 border border-gray-300 rounded-xl bg-white
|
|
||||||
focus:outline-none focus:ring-2 focus:ring-blue-200 focus:border-blue-300
|
|
||||||
text-sm transition">
|
|
||||||
<option value="">ไม่เลือก</option>
|
|
||||||
@for (item of budgetCategoriesDrop.expense; track item.dtlcod) {
|
|
||||||
<option [value]="item.dtlcod">
|
|
||||||
{{ item.dtlnam }}
|
|
||||||
</option>
|
|
||||||
}
|
|
||||||
</select> -->
|
|
||||||
{{ p.bdgnam }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-4 px-4 w-40">
|
|
||||||
<!-- <input type="number" class="w-full px-4 py-2.5 border border-gray-300 rounded-xl bg-white focus:outline-none focus:ring-2 focus:ring-blue-200 focus:border-blue-300 text-sm transition"/> -->
|
|
||||||
{{ p.acp }} บาท
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-4 px-4 text-center">
|
|
||||||
<span
|
|
||||||
class="px-3 py-1.5 rounded-full text-xs font-semibold inline-flex items-center gap-1
|
|
||||||
shadow-sm border"
|
|
||||||
[ngClass]="{
|
|
||||||
'bg-yellow-50 text-yellow-700 border-yellow-200': p.status === 'WAIT',
|
|
||||||
'bg-green-50 text-green-700 border-green-200': p.status === 'APPROVED',
|
|
||||||
'bg-red-50 text-red-700 border-red-200': p.status === 'REJECTED'
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<ng-container *ngIf="p.status === 'APPROVED'">อนุมัติแล้ว</ng-container>
|
{{ remainingBudget | number:'1.0-2' }} บาท
|
||||||
<ng-container *ngIf="p.status === 'WAIT'">รออนุมัติ</ng-container>
|
</div>
|
||||||
<ng-container *ngIf="p.status === 'REJECTED'">ไม่อนุมัติ</ng-container>
|
</div> -->
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="py-4 px-4 text-center space-x-2 whitespace-nowrap">
|
</div>
|
||||||
|
|
||||||
<button
|
<!-- Add Button -->
|
||||||
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-xl text-sm
|
<!-- <div class="mb-4">
|
||||||
shadow-sm font-medium transition"
|
<button
|
||||||
(click)="openBudgetDetail(p)">
|
class=" rounded-3xl bg-green-600 hover:bg-green-700 text-white px-5 py-2.5 text-sm font-medium shadow-sm flex items-center gap-2 transition"
|
||||||
จัดสรรงบประมาณ
|
>
|
||||||
</button>
|
➕ เพิ่มโครงการใหม่
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
</td>
|
<!-- Table -->
|
||||||
</tr>
|
<div class="overflow-x-auto bg-white border border-gray-200 rounded-2xl shadow-sm">
|
||||||
</tbody>
|
<table class="min-w-full text-left border-collapse">
|
||||||
</table>
|
<thead class="bg-red-900 border-b border-gray-200 text-white text-sm">
|
||||||
<!-- endtable -->
|
<tr>
|
||||||
</div>
|
<th class="py-3 px-4 font-semibold">ลำดับ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold">รหัสโครงการ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold">ชื่อโครงการ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold">ผู้รับผิดชอบ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold">งบที่ขออนุมัติ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold">หมวดงบ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold">จำนวนที่อนุมัติ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold text-center">สถานะ</th>
|
||||||
|
<th class="py-3 px-4 font-semibold text-center">ดำเนินการ</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
@for(idx of myPrjMst; track idx.prjseq; let i = $index){
|
||||||
|
<tr class="border-b border-gray-100 hover:bg-blue-50/20 transition">
|
||||||
|
<td class="py-4 px-4 text-gray-700">{{ i + 1 }}</td>
|
||||||
|
<td class="py-4 px-4 font-medium text-gray-700"> {{ idx.prjseq }}</td>
|
||||||
|
<td class="py-4 px-4 text-gray-800 font-semibold leading-tight">{{ idx.prjnam }}</td>
|
||||||
|
<td class="py-4 px-4 text-gray-700">{{ idx.prjusrnam }}</td>
|
||||||
|
<td class="py-4 px-4 text-blue-700 font-bold whitespace-nowrap"> {{ idx.prjwntbdg | number:'1.0-0' }} บาท</td>
|
||||||
|
|
||||||
|
@if(idx.prjbdgnam){
|
||||||
|
<td class="py-4 px-4 text-gray-800 font-semibold leading-tight">{{ idx.prjbdgnam }}</td>
|
||||||
|
}@else {
|
||||||
|
<td class="py-4 px-4 text-gray-400 font-semibold leading-tight italic">ไม่จัดสรร</td>
|
||||||
|
}
|
||||||
|
|
||||||
|
<td class="py-4 px-4 w-40">
|
||||||
|
<!-- <input type="number" class="w-full px-4 py-2.5 border border-gray-300 rounded-xl bg-white focus:outline-none focus:ring-2 focus:ring-blue-200 focus:border-blue-300 text-sm transition"/> -->
|
||||||
|
{{ idx.prjacpbdg }} บาท
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-4 px-4 text-center">
|
||||||
|
<span
|
||||||
|
class="px-3 py-1.5 rounded-full text-xs font-semibold inline-flex items-center gap-1
|
||||||
|
shadow-sm border"
|
||||||
|
[ngClass]="{
|
||||||
|
'bg-yellow-50 text-yellow-700 border-yellow-200': idx.prjcomstt === 'UAC',
|
||||||
|
'bg-green-50 text-green-700 border-green-200': idx.prjcomstt === 'BAP',
|
||||||
|
'bg-red-50 text-red-700 border-red-200': idx.prjcomstt === 'CN'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<ng-container *ngIf="idx.prjcomstt === 'BAP'">อนุมัติแล้ว</ng-container>
|
||||||
|
<ng-container *ngIf="idx.prjcomstt === 'UAC'">รออนุมัติ</ng-container>
|
||||||
|
<ng-container *ngIf="idx.prjcomstt === 'CN'">ไม่อนุมัติ</ng-container>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="py-4 px-4 text-center space-x-2 whitespace-nowrap">
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="bg-red-900 hover:bg-red-950 text-white px-4 py-2 rounded-xl text-sm
|
||||||
|
shadow-sm font-medium transition"
|
||||||
|
(click)="openBudgetDetail(idx)">
|
||||||
|
จัดสรรงบประมาณ
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
<!-- Pagination
|
</td>
|
||||||
<div class="flex justify-end items-center gap-3 mt-5">
|
</tr>
|
||||||
<button class="px-4 py-2 border border-gray-300 rounded-xl bg-white hover:bg-gray-100">
|
}
|
||||||
1
|
</tbody>
|
||||||
</button>
|
</table>
|
||||||
<button class="px-4 py-2 border border-gray-300 rounded-xl bg-white hover:bg-gray-100">
|
<!-- endtable -->
|
||||||
2
|
</div>
|
||||||
</button>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
<!-- Pagination
|
||||||
|
<div class="flex justify-end items-center gap-3 mt-5">
|
||||||
|
<button class="px-4 py-2 border border-gray-300 rounded-xl bg-white hover:bg-gray-100">
|
||||||
|
1
|
||||||
|
</button>
|
||||||
|
<button class="px-4 py-2 border border-gray-300 rounded-xl bg-white hover:bg-gray-100">
|
||||||
|
2
|
||||||
|
</button>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
||||||
import { GeneralService } from '../../services/generalservice';
|
import { GeneralService } from '../../services/generalservice';
|
||||||
import { IDropAct, IStateDrop, IStateResultResponse, IActData, IActSumData } from '../../interfaces/dashboard.interface'
|
import { IPrjMst } from '../../interfaces/main.interface'
|
||||||
import { DashboardStateService } from '../../services/state/dashboard-state.service';
|
import { ProjectStateService } from '../../services/state/project-state.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -15,6 +15,8 @@ export class MainManagerComponent implements OnInit {
|
|||||||
|
|
||||||
mode: string = 'i';
|
mode: string = 'i';
|
||||||
|
|
||||||
|
myPrjMst:IPrjMst[] = [];
|
||||||
|
|
||||||
totalBudget = 200000; // งบทั้งหมด
|
totalBudget = 200000; // งบทั้งหมด
|
||||||
approvedBudget = 65000; // งบที่อนุมัติแล้ว
|
approvedBudget = 65000; // งบที่อนุมัติแล้ว
|
||||||
|
|
||||||
@@ -24,98 +26,22 @@ export class MainManagerComponent implements OnInit {
|
|||||||
return this.totalBudget - this.approvedBudget;
|
return this.totalBudget - this.approvedBudget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
projects = [
|
|
||||||
{ code: 'PRJ001', name: 'ระบบจัดการน้ำดื่ม', owner: 'นาย A', budget: 20000, status: 'WAIT', acp: 0, bdgnam: 'ยังไมจัดสรร' },
|
|
||||||
{ code: 'PRJ002', name: 'ปรับปรุงอาคาร B', owner: 'นางสาว B', budget: 45000, status: 'WAIT', acp: 0, bdgnam: 'ยังไมจัดสรร'},
|
|
||||||
{ code: 'PRJ003', name: 'ซื้อคอมพิวเตอร์', owner: 'นาย C', budget: 30000, status: 'APPROVED', acp: 20000, bdgnam: 'งบดำเนินงาน' }
|
|
||||||
];
|
|
||||||
|
|
||||||
approveProject(p: any) {
|
approveProject(p: any) {
|
||||||
p.status = 'APPROVED';
|
p.status = 'BAP';
|
||||||
this.approvedBudget += p.budget;
|
this.approvedBudget += p.budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
rejectProject(p: any) {
|
rejectProject(p: any) {
|
||||||
p.status = 'REJECTED';
|
p.status = 'CN';
|
||||||
}
|
}
|
||||||
|
|
||||||
openBudgetDetail(project: any) {
|
openBudgetDetail(idx: IPrjMst) {
|
||||||
this.router.navigate(['/main/manager/budget', project.code]);
|
this.router.navigate(['/main/budget/approve', idx.prjseq]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
budgetCategoriesDrop = {
|
|
||||||
expense: [
|
|
||||||
{ dtlcod: 'BDG001', dtlnam: 'เงินรายได้' },
|
|
||||||
{ dtlcod: 'BDG002', dtlnam: 'งบดำเนินงาน ปวส.' },
|
|
||||||
{ dtlcod: 'BDG003', dtlnam: 'โครงการส่งเสริมพัฒนาทักษะวิชาชีพทักษะพื้นฐาน' },
|
|
||||||
{ dtlcod: 'BDG004', dtlnam: 'ค่ากิจกรรมพัฒนาคุณภาพผู้เรียน' },
|
|
||||||
{ dtlcod: 'BDG005', dtlnam: 'อุดหนุนส่งเสริมและพัฒนาผู้เรียนองค์การวิชาชีพแห่งประเทศไทย (อวท.)' },
|
|
||||||
{ dtlcod: 'BDG006', dtlnam: 'งบดำเนินงาน ระยะสั้น' },
|
|
||||||
{ dtlcod: 'BDG007', dtlnam: 'โครงการบูรณาการการพัฒนาทักษะทางวิชาชีพกับการเสริมสร้างคุณลักษณะอันพึงประสงค์ (FIX IT)' },
|
|
||||||
{ dtlcod: 'BDG008', dtlnam: 'โครงการพัฒนาทักษะและสมรรถนะวิชาชีพกำลังคน (Up-skill, Re-skill)' },
|
|
||||||
{ dtlcod: 'BDG009', dtlnam: 'งบดำเนินงาน ปวช.' },
|
|
||||||
{ dtlcod: 'BDG010', dtlnam: 'โครงการขยายและยกระดับการจัดอาชีวศึกษาระบบทวิภาคีคุณภาพสูง' },
|
|
||||||
{ dtlcod: 'BDG011', dtlnam: 'ปวช.(สอจ)' },
|
|
||||||
{ dtlcod: 'BDG012', dtlnam: 'ค่าจัดการเรียนการสอน' },
|
|
||||||
{ dtlcod: 'BDG013', dtlnam: 'งบดำเนินงาน 170000' },
|
|
||||||
{ dtlcod: 'BDG014', dtlnam: 'โครงการพัฒนาทักษะและศักยภาพภาพการจัดการเรียนการสอนอาชีวศึกษา' },
|
|
||||||
{ dtlcod: 'BDG015', dtlnam: 'ศึกษาธิการ' },
|
|
||||||
{ dtlcod: 'BDG016', dtlnam: 'Up-skill' },
|
|
||||||
{ dtlcod: 'BDG017', dtlnam: 'ติดตามผู้สำเร็จ' },
|
|
||||||
{ dtlcod: 'BDG018', dtlnam: 'ทวิภาคี' },
|
|
||||||
{ dtlcod: 'BDG019', dtlnam: 'พันธุกรรม' },
|
|
||||||
{ dtlcod: 'BDG020', dtlnam: 'ปวส(สาธารณูประโภค)' },
|
|
||||||
{ dtlcod: 'BDG021', dtlnam: 'ปวส(ค่าสาธารณูปโภค)' },
|
|
||||||
{ dtlcod: 'BDG022', dtlnam: 'งบดำเนินงาน (ค่าสาธารณูปโภค)' },
|
|
||||||
{ dtlcod: 'BDG023', dtlnam: 'ค่าหนังสือเรียน' },
|
|
||||||
{ dtlcod: 'BDG024', dtlnam: 'โครงการอาชีวะต้านยาเสพติด' },
|
|
||||||
{ dtlcod: 'BDG025', dtlnam: 'ค่าตอบแทนพนักงานราชการ' },
|
|
||||||
{ dtlcod: 'BDG026', dtlnam: 'ค่าอุปกรณ์การเรียน' },
|
|
||||||
{ dtlcod: 'BDG027', dtlnam: 'โครงการยกระดับและพัฒนาขีดความสามารถด้านภาษาและทักษะดิจิทัลเพื่อพัฒนากำลังคนให้มีสมรรถนะสูง' },
|
|
||||||
{ dtlcod: 'BDG028', dtlnam: 'โครงการอนุรักษ์พันธุกรรมพืชอันเนื่องมาจากพระราชดำริ' },
|
|
||||||
{ dtlcod: 'BDG029', dtlnam: 'ปวช.(สอจ.)' },
|
|
||||||
{ dtlcod: 'BDG030', dtlnam: 'โครงการพัฒนาศักยภาพผู้เรียนอาชีวศึกษาในการเป็นผู้ประกอบการ (บ่มเพาะ)' },
|
|
||||||
{ dtlcod: 'BDG031', dtlnam: 'โครงการพัฒนาและยกระดับการติดตามผู้สำเร็จการศึกษาอาชีวศึกษา' },
|
|
||||||
{ dtlcod: 'BDG032', dtlnam: 'โครงการเสริมสร้างคุณธรรม จริยธรรมและธรรมาภิบาลในสถานศึกษา' },
|
|
||||||
{ dtlcod: 'BDG033', dtlnam: 'โครงการจัดการอาชีวศึกษาเพื่อสนองพระราชดำริ' },
|
|
||||||
{ dtlcod: 'BDG034', dtlnam: 'เงินรายได้ ป.ตรี' },
|
|
||||||
{ dtlcod: 'BDG035', dtlnam: 'งบดำเนินงาน 235200' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
// isModalOpen: boolean = false;
|
|
||||||
// isSubmitting: boolean = false;
|
|
||||||
// arrearsForm!: FormGroup;
|
|
||||||
// saveFrm!: FormGroup;
|
|
||||||
// myActData: IActData[] = [];
|
|
||||||
// // myDropAct: IStateDrop[] = [];
|
|
||||||
// myDropAct: IStateDrop = { income: [], expense: [] };
|
|
||||||
// myActSumData: IActSumData = {
|
|
||||||
// summary: {
|
|
||||||
// totalIncome: '',
|
|
||||||
// totalExpense: '',
|
|
||||||
// netProfit: '',
|
|
||||||
// profitRate: '',
|
|
||||||
// adjustedProfitRate: '',
|
|
||||||
// period: ''
|
|
||||||
// },
|
|
||||||
// pie: {
|
|
||||||
// income: [],
|
|
||||||
// expense: []
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// ActSumDataGradient: any
|
|
||||||
|
|
||||||
|
|
||||||
// readonly ownerName = 'Nuttakit';
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private dashboardStateService: DashboardStateService
|
private projectStateService: ProjectStateService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|
||||||
@@ -123,40 +49,14 @@ export class MainManagerComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.setupFormControl();
|
this.setupFormControl();
|
||||||
// this.dashboardStateService.getStateResult().subscribe(data => {
|
this.projectStateService.getStateResult().subscribe(data => {
|
||||||
// if (data) {
|
if(data){
|
||||||
// this.myDropAct = data;
|
this.myPrjMst = data
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// // ผลลับท์ ของ รายการ
|
|
||||||
// this.dashboardStateService.getStateAccountResult().subscribe(data => {
|
|
||||||
// if (data) {
|
|
||||||
// this.myActData = data;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// // ผลลัพการ คำนวณ ของ ปัญชี ต่างๆ
|
|
||||||
// this.dashboardStateService.getStateSumResult().subscribe(data => {
|
|
||||||
// if (data) {
|
|
||||||
// this.myActSumData = data;
|
|
||||||
// this.ActSumDataGradient = this.buildExpenseGradient()
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
setupFormControl(){
|
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({
|
|
||||||
// actacpdtm: new FormControl('',[Validators.required, Validators.maxLength(12)]),
|
|
||||||
// actqty: new FormControl('',[Validators.required]),
|
|
||||||
// actcat: new FormControl('',[Validators.required, Validators.maxLength(1)]),
|
|
||||||
// actcmt: new FormControl('',[Validators.maxLength(200)])
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSaveSubmit(){
|
onSaveSubmit(){
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<app-budget-aproval (ExpenseEventSubmit)="OnBudgetExp($event)"></app-budget-aproval>
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import { IDropBdg, ITrnmst } from './../../interfaces/main.interface';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { GeneralService } from '../../services/generalservice';
|
||||||
|
import { TransactionStateService } from '../../services/state/transaction-state.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-budget-aproval-content',
|
||||||
|
standalone: false,
|
||||||
|
templateUrl: './budget-aproval-content.html',
|
||||||
|
styleUrl: './budget-aproval-content.css',
|
||||||
|
})
|
||||||
|
export class BudgetAprovalContent implements OnInit {
|
||||||
|
|
||||||
|
myTrnmst: ITrnmst[]=[];
|
||||||
|
myDropBdg: IDropBdg[]=[];
|
||||||
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private generalService: GeneralService,
|
||||||
|
private transactionStateService: TransactionStateService
|
||||||
|
){}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
let param = this.route.snapshot.paramMap.get('seq');
|
||||||
|
this.OnSearchTrn(param);
|
||||||
|
this.OnBudgetSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
OnSearchTrn(value: any): void {
|
||||||
|
const uri = '/api/ttc/transactionsearch';
|
||||||
|
let request = {
|
||||||
|
trnprjseq: value
|
||||||
|
}
|
||||||
|
this.generalService.postRequest(uri, request).subscribe({
|
||||||
|
next: (result: any) => {
|
||||||
|
if (result.code === '200') {
|
||||||
|
this.generalService.trowApi(result);
|
||||||
|
this.myTrnmst = result.data;
|
||||||
|
this.transactionStateService.setTransactionState(this.myTrnmst);
|
||||||
|
}else{
|
||||||
|
this.generalService.trowApi(result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
this.generalService.trowApi(error);
|
||||||
|
},
|
||||||
|
complete: () => {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
OnBudgetExp(value: any): void {
|
||||||
|
const uri = '/api/ttc/budgetexpense';
|
||||||
|
let request = value;
|
||||||
|
this.generalService.postRequest(uri, request).subscribe({
|
||||||
|
next: (result: any) => {
|
||||||
|
if (result.code === '200') {
|
||||||
|
this.generalService.trowApi(result);
|
||||||
|
}else{
|
||||||
|
this.generalService.trowApi(result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
this.generalService.trowApi(error);
|
||||||
|
},
|
||||||
|
complete: () => {
|
||||||
|
this.router.navigate(['/main/manager'])
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OnBudgetSearch(): void {
|
||||||
|
const uri = '/api/ttc/budgetsearch';
|
||||||
|
let request = {}
|
||||||
|
this.generalService.postRequest(uri, request).subscribe({
|
||||||
|
next: (result: any) => {
|
||||||
|
if (result.code === '200') {
|
||||||
|
// this.generalService.trowApi(result);
|
||||||
|
this.myDropBdg = result.data;
|
||||||
|
this.transactionStateService.setBudgetDrop(this.myDropBdg);
|
||||||
|
}else{
|
||||||
|
// this.generalService.trowApi(result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (error: any) => {
|
||||||
|
// this.generalService.trowApi(error);
|
||||||
|
},
|
||||||
|
complete: () => {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,8 @@ import { Component, OnInit, ViewChild } from '@angular/core';
|
|||||||
import { ChartConfiguration, ChartOptions } from 'chart.js';
|
import { ChartConfiguration, ChartOptions } from 'chart.js';
|
||||||
import { BaseChartDirective } from 'ng2-charts';
|
import { BaseChartDirective } from 'ng2-charts';
|
||||||
import { GeneralService } from '../../services/generalservice';
|
import { GeneralService } from '../../services/generalservice';
|
||||||
import { IDropAct, IStateDrop, IActData, IActSumData } from '../../interfaces/dashboard.interface';
|
import { IPrjMst } from '../../interfaces/main.interface';
|
||||||
|
import { ProjectStateService } from '../../services/state/project-state.service';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -14,46 +15,41 @@ import { IDropAct, IStateDrop, IActData, IActSumData } from '../../interfaces/da
|
|||||||
})
|
})
|
||||||
export class MainManagerContentComponent implements OnInit {
|
export class MainManagerContentComponent implements OnInit {
|
||||||
// @ViewChild(BaseChartDirective) chart?: BaseChartDirective;
|
// @ViewChild(BaseChartDirective) chart?: BaseChartDirective;
|
||||||
myDropAct!: IStateDrop;
|
myPrjMst: IPrjMst[]=[];
|
||||||
myActData: IActData[] = [];
|
// myActData: IActData[] = [];
|
||||||
myActSumData: IActSumData = {
|
// myActSumData: IActSumData = {
|
||||||
summary: {
|
// summary: {
|
||||||
totalIncome: '',
|
// totalIncome: '',
|
||||||
totalExpense: '',
|
// totalExpense: '',
|
||||||
netProfit: '',
|
// netProfit: '',
|
||||||
profitRate: '',
|
// profitRate: '',
|
||||||
adjustedProfitRate: '',
|
// adjustedProfitRate: '',
|
||||||
period: ''
|
// period: ''
|
||||||
},
|
// },
|
||||||
pie: {
|
// pie: {
|
||||||
income: [],
|
// income: [],
|
||||||
expense: []
|
// expense: []
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private generalService: GeneralService,
|
private generalService: GeneralService,
|
||||||
private dashboardStateService: DashboardStateService
|
private projectStateService: ProjectStateService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
let token = localStorage.getItem('access_token')
|
this.OnSearchPrj({}, true);
|
||||||
// this.OnSearchAct(token, true);
|
|
||||||
// this.OnSetupDashboard(token, true);
|
|
||||||
// this.OnSearchSum(token, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OnSearchAct(value: any, setupFirst: boolean): void {
|
OnSearchPrj(value: any, setupFirst: boolean): void {
|
||||||
const uri = '/api/web/accountingSearch';
|
const uri = '/api/ttc/projectsearch';
|
||||||
let request = {
|
let request = {}
|
||||||
token: value
|
|
||||||
}
|
|
||||||
this.generalService.postRequest(uri, request).subscribe({
|
this.generalService.postRequest(uri, request).subscribe({
|
||||||
next: (result: any) => {
|
next: (result: any) => {
|
||||||
if (result.code === '200') {
|
if (result.code === '200') {
|
||||||
this.generalService.trowApi(result);
|
this.generalService.trowApi(result);
|
||||||
this.myActData = result.data;
|
this.myPrjMst = result.data;
|
||||||
this.dashboardStateService.setStateAccountResult(this.myActData);
|
this.projectStateService.setProjectState(this.myPrjMst);
|
||||||
}else{
|
}else{
|
||||||
this.generalService.trowApi(result);
|
this.generalService.trowApi(result);
|
||||||
}
|
}
|
||||||
@@ -69,94 +65,51 @@ export class MainManagerContentComponent implements OnInit {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
OnSetupDashboard(value: any, setupFirst: boolean): void {
|
// OnSetupDashboard(value: any, setupFirst: boolean): void {
|
||||||
const uri = '/api/web/accountingSetup';
|
// const uri = '/api/web/accountingSetup';
|
||||||
let request = {
|
// let request = {
|
||||||
token: value
|
// token: value
|
||||||
}
|
// }
|
||||||
this.generalService.postRequest(uri, request).subscribe({
|
// this.generalService.postRequest(uri, request).subscribe({
|
||||||
next: (result: any) => {
|
|
||||||
if (result.code === '200') {
|
|
||||||
this.generalService.trowApi(result);
|
|
||||||
this.myDropAct = result.data
|
|
||||||
this.dashboardStateService.setStateResult(this.myDropAct)
|
|
||||||
}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.dashboardStateService.setStateSumResult(this.myActSumData);
|
|
||||||
}else{
|
|
||||||
this.generalService.trowApi(result);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: (error: any) => {
|
|
||||||
this.generalService.trowApi(error);
|
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetchChartData(): void {
|
|
||||||
// // NOTE: Using a placeholder endpoint as the actual one was not provided.
|
|
||||||
// const uri = '/api/dashboard/summary-last-6-months';
|
|
||||||
|
|
||||||
// this.generalService.getRequest(uri).subscribe({
|
|
||||||
// next: (result: any) => {
|
// next: (result: any) => {
|
||||||
// if (result.code === '200' && result.data) {
|
// if (result.code === '200') {
|
||||||
// this.processChartData(result.data);
|
// this.generalService.trowApi(result);
|
||||||
// } else {
|
// this.myDropAct = result.data
|
||||||
// console.warn('Could not fetch chart data:', result.message_th);
|
// this.dashboardStateService.setStateResult(this.myDropAct)
|
||||||
// // Optionally, display placeholder data or an error message
|
// }else{
|
||||||
// this.setupPlaceholderData();
|
// this.generalService.trowApi(result);
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// error: (error: any) => {
|
// error: (error: any) => {
|
||||||
// console.error('Error fetching chart data:', error);
|
// this.generalService.trowApi(error);
|
||||||
// // Display placeholder data on error to show the graph structure
|
// },
|
||||||
// this.setupPlaceholderData();
|
// complete: () => {
|
||||||
|
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// processChartData(data: any[]): void {
|
// OnSearchSum(value: any, setupFirst: boolean): void {
|
||||||
// const labels = data.map(item => item.month);
|
// const uri = '/api/web/accountingSum';
|
||||||
// const revenues = data.map(item => item.revenue);
|
// 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.dashboardStateService.setStateSumResult(this.myActSumData);
|
||||||
|
// }else{
|
||||||
|
// this.generalService.trowApi(result);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// error: (error: any) => {
|
||||||
|
// this.generalService.trowApi(error);
|
||||||
|
// },
|
||||||
|
// complete: () => {
|
||||||
|
|
||||||
// this.lineChartData.labels = labels;
|
// }
|
||||||
// this.lineChartData.datasets[0].data = revenues;
|
// });
|
||||||
|
|
||||||
// this.chart?.update();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// setupPlaceholderData(): void {
|
|
||||||
// // This function is called if the API fails, to show a sample graph.
|
|
||||||
// const labels = ['January', 'February', 'March', 'April', 'May', 'June'];
|
|
||||||
// const revenues = [1200, 1900, 3000, 5000, 2300, 3200]; // Sample data
|
|
||||||
|
|
||||||
// this.lineChartData.labels = labels;
|
|
||||||
// this.lineChartData.datasets[0].data = revenues;
|
|
||||||
|
|
||||||
// this.chart?.update();
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { MainReportComponent } from '../../component/main-report/main-report.com
|
|||||||
import { BudgetAproval } from '../../component/budget-aproval/budget-aproval';
|
import { BudgetAproval } from '../../component/budget-aproval/budget-aproval';
|
||||||
import { MainLandingComponent } from '../../component/main-landing/main-landing.component';
|
import { MainLandingComponent } from '../../component/main-landing/main-landing.component';
|
||||||
import { MainProjectContent } from '../../content/main-project-content/main-project-content';
|
import { MainProjectContent } from '../../content/main-project-content/main-project-content';
|
||||||
|
import { BudgetAprovalContent } from '../../content/budget-aproval-content/budget-aproval-content';
|
||||||
// import { MainReportComponent } from '../../component/main-report/main-report.component';
|
// import { MainReportComponent } from '../../component/main-report/main-report.component';
|
||||||
|
|
||||||
|
|
||||||
@@ -17,13 +18,14 @@ const routes: Routes = [
|
|||||||
{ path: 'manager', component: MainManagerContentComponent },
|
{ path: 'manager', component: MainManagerContentComponent },
|
||||||
{ path: 'project', component: MainProjectContent },
|
{ path: 'project', component: MainProjectContent },
|
||||||
{ path: 'project/:mode', component: MainProjectContent },
|
{ path: 'project/:mode', component: MainProjectContent },
|
||||||
{
|
{ path: 'budget/approve/:seq', component: BudgetAprovalContent},
|
||||||
path: 'manager',
|
// {
|
||||||
children: [
|
// path: 'manager',
|
||||||
{ path: '', component: MainManagerContentComponent }, // รายการโครงการ
|
// children: [
|
||||||
{ path: 'budget/:code', component: BudgetAproval }, // จัดการงบประมาณ
|
// { path: '', component: MainManagerContentComponent }, // รายการโครงการ
|
||||||
]
|
// { path: 'budget/:code', component: BudgetAproval }, // จัดการงบประมาณ
|
||||||
},
|
// ]
|
||||||
|
// },
|
||||||
// children: [
|
// children: [
|
||||||
// {
|
// {
|
||||||
// path: 'dashboard',
|
// path: 'dashboard',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
|
|
||||||
import { MainControlRoutingModule } from './main-control-routing.module';
|
import { MainControlRoutingModule } from './main-control-routing.module';
|
||||||
|
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { MainDashboardComponent } from '../../component/main-dashboard/main-dashboard.component';
|
import { MainDashboardComponent } from '../../component/main-dashboard/main-dashboard.component';
|
||||||
import { MainDashboardContentComponent } from '../../content/main-dashboard-content/main-dashboard-content.component';
|
import { MainDashboardContentComponent } from '../../content/main-dashboard-content/main-dashboard-content.component';
|
||||||
@@ -17,6 +17,7 @@ import { MainLandingComponent } from '../../component/main-landing/main-landing.
|
|||||||
import { MainProjectContent } from '../../content/main-project-content/main-project-content';
|
import { MainProjectContent } from '../../content/main-project-content/main-project-content';
|
||||||
import { MainProject } from '../../component/main-project/main-project';
|
import { MainProject } from '../../component/main-project/main-project';
|
||||||
import { MainProjectAdd } from '../../component/main-project-add/main-project-add';
|
import { MainProjectAdd } from '../../component/main-project-add/main-project-add';
|
||||||
|
import { BudgetAprovalContent } from '../../content/budget-aproval-content/budget-aproval-content';
|
||||||
|
|
||||||
// import { MainReportComponent } from '../../component/main-report/main-report.component';
|
// import { MainReportComponent } from '../../component/main-report/main-report.component';
|
||||||
|
|
||||||
@@ -34,13 +35,15 @@ import { MainProjectAdd } from '../../component/main-project-add/main-project-ad
|
|||||||
MainProjectContent,
|
MainProjectContent,
|
||||||
MainProject,
|
MainProject,
|
||||||
MainProjectAdd,
|
MainProjectAdd,
|
||||||
|
BudgetAprovalContent,
|
||||||
AccDateFormatPipe
|
AccDateFormatPipe
|
||||||
// MainReportComponent
|
// MainReportComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MainControlRoutingModule,
|
MainControlRoutingModule,
|
||||||
ReactiveFormsModule
|
ReactiveFormsModule,
|
||||||
|
FormsModule
|
||||||
// BrowserAnimationsModule
|
// BrowserAnimationsModule
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ export interface IStateDrop {
|
|||||||
income: IDropAct[];
|
income: IDropAct[];
|
||||||
expense: IDropAct[];
|
expense: IDropAct[];
|
||||||
}
|
}
|
||||||
|
export interface IBudgetItem {
|
||||||
|
id?: number; // เอาไว้เช็คตอน Edit
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
amount: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IDropAct {
|
export interface IDropAct {
|
||||||
dtlnam?: string,
|
dtlnam?: string,
|
||||||
@@ -22,6 +28,18 @@ export interface IStateResultResponse {
|
|||||||
data: IStateDrop;
|
data: IStateDrop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPrjData {
|
||||||
|
prjseq?: number;
|
||||||
|
prjnam?: string;
|
||||||
|
prjusrnam?: string;
|
||||||
|
prjwntbdg?: string;
|
||||||
|
prjbdgnam?: string;
|
||||||
|
prjbdgcod?: string;
|
||||||
|
prjacpbdg?: string;
|
||||||
|
prjcomstt?: string;
|
||||||
|
prjacpdtm?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IStateResultResponse {
|
export interface IStateResultResponse {
|
||||||
data: IStateDrop;
|
data: IStateDrop;
|
||||||
}
|
}
|
||||||
|
|||||||
26
ng-ttc-frontend/src/app/interfaces/main.interface.ts
Normal file
26
ng-ttc-frontend/src/app/interfaces/main.interface.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
export interface IPrjMst {
|
||||||
|
prjseq?: number;
|
||||||
|
prjnam?: string;
|
||||||
|
prjusrnam?: string;
|
||||||
|
prjwntbdg?: string;
|
||||||
|
prjbdgnam?: string;
|
||||||
|
prjbdgcod?: string;
|
||||||
|
prjacpbdg?: string;
|
||||||
|
prjcomstt?: string;
|
||||||
|
prjacpdtm?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ITrnmst {
|
||||||
|
trnseq?: number;
|
||||||
|
trnprjnam?: string;
|
||||||
|
trnbdgnam?: string;
|
||||||
|
trnbdgcod?: string;
|
||||||
|
trncomstt?: string;
|
||||||
|
trnexpbdg: number;
|
||||||
|
trnacpdtm?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDropBdg {
|
||||||
|
bdgnam?: string;
|
||||||
|
bdgcod?: number;
|
||||||
|
}
|
||||||
@@ -1,32 +1,32 @@
|
|||||||
import { Injectable } from '@angular/core';
|
// import { Injectable } from '@angular/core';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
// import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { IBudgetExpenseResponse, IBudgetAddResponse } from '../../interfaces/dashboard.interface';
|
// import { IBudgetExpenseResponse, IBudgetAddResponse } from '../../interfaces/dashboard.interface';
|
||||||
|
|
||||||
@Injectable({
|
// @Injectable({
|
||||||
providedIn: 'root'
|
// providedIn: 'root'
|
||||||
})
|
// })
|
||||||
export class BudgetStateService {
|
// export class BudgetStateService {
|
||||||
private budgetExpenseState = new BehaviorSubject<IBudgetExpenseResponse | null>(null);
|
// private budgetExpenseState = new BehaviorSubject<IBudgetExpenseResponse | null>(null);
|
||||||
private budgetAddState = new BehaviorSubject<IBudgetAddResponse | null>(null);
|
// private budgetAddState = new BehaviorSubject<IBudgetAddResponse | null>(null);
|
||||||
|
|
||||||
getBudgetExpenseState(): Observable<IBudgetExpenseResponse | null> {
|
// getBudgetExpenseState(): Observable<IBudgetExpenseResponse | null> {
|
||||||
return this.budgetExpenseState.asObservable();
|
// return this.budgetExpenseState.asObservable();
|
||||||
}
|
// }
|
||||||
|
|
||||||
setBudgetExpenseState(budgetExpense: IBudgetExpenseResponse): void {
|
// setBudgetExpenseState(budgetExpense: IBudgetExpenseResponse): void {
|
||||||
this.budgetExpenseState.next(budgetExpense);
|
// this.budgetExpenseState.next(budgetExpense);
|
||||||
}
|
// }
|
||||||
|
|
||||||
getBudgetAddState(): Observable<IBudgetAddResponse | null> {
|
// getBudgetAddState(): Observable<IBudgetAddResponse | null> {
|
||||||
return this.budgetAddState.asObservable();
|
// return this.budgetAddState.asObservable();
|
||||||
}
|
// }
|
||||||
|
|
||||||
setBudgetAddState(budgetAdd: IBudgetAddResponse): void {
|
// setBudgetAddState(budgetAdd: IBudgetAddResponse): void {
|
||||||
this.budgetAddState.next(budgetAdd);
|
// this.budgetAddState.next(budgetAdd);
|
||||||
}
|
// }
|
||||||
|
|
||||||
clearState(): void {
|
// clearState(): void {
|
||||||
this.budgetExpenseState.next(null);
|
// this.budgetExpenseState.next(null);
|
||||||
this.budgetAddState.next(null);
|
// this.budgetAddState.next(null);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { IProjectSearchResponse, ITransactionSearchResponse } from '../../interfaces/dashboard.interface';
|
import { IPrjMst } from '../../interfaces/main.interface';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class ProjectStateService {
|
export class ProjectStateService {
|
||||||
private projectState = new BehaviorSubject<IProjectSearchResponse | null>(null);
|
// ประกาศ BehaviorSubject ด้วย Interface
|
||||||
private transactionState = new BehaviorSubject<ITransactionSearchResponse | null>(null);
|
private projectState = new BehaviorSubject<IPrjMst[] | null>(null);
|
||||||
|
|
||||||
getProjectState(): Observable<IProjectSearchResponse | null> {
|
// ส่ง Observable ไปให้ components subscribe
|
||||||
|
getStateResult(): Observable<IPrjMst[] | null> {
|
||||||
return this.projectState.asObservable();
|
return this.projectState.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
setProjectState(project: IProjectSearchResponse): void {
|
// เซ็ท state
|
||||||
this.projectState.next(project);
|
setProjectState(projects: IPrjMst[]): void {
|
||||||
}
|
this.projectState.next(projects);
|
||||||
|
|
||||||
getTransactionState(): Observable<ITransactionSearchResponse | null> {
|
|
||||||
return this.transactionState.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
setTransactionState(transaction: ITransactionSearchResponse): void {
|
|
||||||
this.transactionState.next(transaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// เคลียร์ state
|
||||||
clearState(): void {
|
clearState(): void {
|
||||||
this.projectState.next(null);
|
this.projectState.next(null);
|
||||||
this.transactionState.next(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import { Injectable } from '@angular/core';
|
// import { Injectable } from '@angular/core';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
// import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { IReportResponse } from '../../interfaces/dashboard.interface';
|
// import { IReportResponse } from '../../interfaces/dashboard.interface';
|
||||||
|
|
||||||
@Injectable({
|
// @Injectable({
|
||||||
providedIn: 'root'
|
// providedIn: 'root'
|
||||||
})
|
// })
|
||||||
export class ReportStateService {
|
// export class ReportStateService {
|
||||||
private reportState = new BehaviorSubject<IReportResponse | null>(null);
|
// private reportState = new BehaviorSubject<IReportResponse | null>(null);
|
||||||
|
|
||||||
getReportState(): Observable<IReportResponse | null> {
|
// getReportState(): Observable<IReportResponse | null> {
|
||||||
return this.reportState.asObservable();
|
// return this.reportState.asObservable();
|
||||||
}
|
// }
|
||||||
|
|
||||||
setReportState(report: IReportResponse): void {
|
// setReportState(report: IReportResponse): void {
|
||||||
this.reportState.next(report);
|
// this.reportState.next(report);
|
||||||
}
|
// }
|
||||||
|
|
||||||
clearState(): void {
|
// clearState(): void {
|
||||||
this.reportState.next(null);
|
// this.reportState.next(null);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
|
import { ITrnmst, IDropBdg } from '../../interfaces/main.interface';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class TransactionStateService {
|
||||||
|
// ประกาศ BehaviorSubject ด้วย Interface
|
||||||
|
private transactionState = new BehaviorSubject<ITrnmst[] | null>(null);
|
||||||
|
private budgetState = new BehaviorSubject<IDropBdg[] | null>(null);
|
||||||
|
|
||||||
|
// ส่ง Observable ไปให้ components subscribe
|
||||||
|
getTransactionState(): Observable<ITrnmst[] | null> {
|
||||||
|
return this.transactionState.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// เซ็ท state
|
||||||
|
setTransactionState(transactions: ITrnmst[]): void {
|
||||||
|
this.transactionState.next(transactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
// เคลียร์ state
|
||||||
|
clearState(): void {
|
||||||
|
this.transactionState.next(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setBudgetDrop(budget: IDropBdg[]): void {
|
||||||
|
this.budgetState.next(budget);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBudgetDrop(): Observable<IDropBdg[] | null> {
|
||||||
|
return this.budgetState.asObservable();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user