[update] remove unused components

This commit is contained in:
2023-10-11 23:43:44 +07:00
parent 6e979255ae
commit e7678c0e5e
237 changed files with 813 additions and 21083 deletions

View File

@@ -1,52 +1,4 @@
import {environment} from "../../environments/environment";
const ENV = {
url : environment.API_URL,
reportUrl : environment.API_REPORT_URL,
}
export const API = {
url : `${ENV.url}` ,
login : `${ENV.url}/auth/login` ,
users : `${ENV.url}/users` ,
userGroup : `${ENV.url}/userGroup` ,
customer : `${ENV.url}/customer` ,
seller : `${ENV.url}/seller` ,
quotation : `${ENV.url}/quotation` ,
quotationDetail : `${ENV.url}/quotationDetail` ,
quotationPayment : `${ENV.url}/quotationPayment` ,
products : `${ENV.url}/products` ,
masterProductBrand : `${ENV.url}/masterProductBrand` ,
masterProductCategory : `${ENV.url}/masterProductCategory` ,
masterProductUnit : `${ENV.url}/masterProductUnit` ,
masterProductMeasurement : `${ENV.url}/masterProductMeasurement` ,
masterArea : `${ENV.url}/masterArea` ,
masterStorageBox : `${ENV.url}/masterStorageBox` ,
attachments : `${ENV.url}/attachments` ,
settings : `${ENV.url}/settings` ,
packet : `${ENV.url}/packet` ,
promotion : `${ENV.url}/promotion` ,
quotationReport : `${ENV.reportUrl}/reports/quotation_report` ,
receiptReport : `${ENV.reportUrl}/reports/receipt_report` ,
installmentContractReport : `${ENV.reportUrl}/reports/installment_contract_report` ,
receiveInventory : `${ENV.reportUrl}/reports/receive_inventory` ,
receiveSendInventory : `${ENV.reportUrl}/reports/receive_send_inventory` ,
receivePickUp : `${ENV.reportUrl}/reports/pick_up` ,
reportOutstandingAccountsReceivable : `${ENV.reportUrl}/reports/outstanding_accounts_receivable` ,
paymentReport : `${ENV.reportUrl}/reports/payment_report` ,
paymentVoucher : `${ENV.reportUrl}/reports/payment_voucher` ,
}
export const STORAGE = {
products : `${ENV.url}/storage/products` ,
images : `${ENV.url}/storage/images` ,
}
export const GENDER = ['ชาย', 'หญิง', 'อื่นๆ'];
export const PREFIX = ['นาย', 'นาง', 'นางสาว', 'อื่นๆ'];
export const TYPE_CODE = ['A', 'C', 'H', 'W'];
export const CONDITIONS = ['new', 'like new', 'used'];

View File

@@ -26,141 +26,16 @@ const routes: Routes = [
path: 'dashboard',
loadChildren: () => import('./pages/dashboard/dashboard.module').then(m => m.DashboardModule)
},
{
path: 'users',
loadChildren: () => import('./pages/users/users.module').then(m => m.UsersModule)
},
{
path: 'manage',
children: [
{
path: 'kyc',
loadChildren: () => import('./pages/appraisal/1st-time/appraisal-1st-time.module').then(m => m.Appraisal1stTimeModule)
},
// {
// path: '2nd-time',
// loadChildren: () => import('./pages/appraisal/2nd-time/appraisal-2nd-time.module').then(m => m.Appraisal2ndTimeModule)
// },
// {
// path: '3rd-time',
// loadChildren: () => import('./pages/appraisal/3rd-time/appraisal-3rd-time.module').then(m => m.Appraisal3rdTimeModule)
// },
]
},
{
path: 'finance',
children: [
{
path: 'payment',
loadChildren: () => import('./pages/finance/payment/finance-payment.module').then(m => m.FinancePaymentModule)
},
{
path: 'refund',
loadChildren: () => import('./pages/page-blank/page-blank.module').then(m => m.PageBlankModule)
},
{
path: 'invoice',
loadChildren: () => import('./pages/finance/invoice/finance-invoice.module').then(m => m.FinanceInvoiceModule)
},
{
path: 'paying',
loadChildren: () => import('./pages/finance/paying/finance-paying.module').then(m => m.FinancePayingModule)
// loadChildren: () => import('./pages/appraisal/1st-time/appraisal-1st-time.module').then(m => m.Appraisal1stTimeModule)
loadChildren: () => import('./pages/manage/kyc/kyc.module').then(m => m.KycModule)
},
]
},
{
path: 'contract',
children: [
{
path: 'make',
loadChildren: () => import('./pages/contract/make/contract-make.module').then(m => m.ContractMakeModule)
},
{
path: 'approved',
loadChildren: () => import('./pages/contract/approved/contract-approved.module').then(m => m.ContractApprovedModule)
}
]
},
// {
// path: 'warehouse',
// children: [
// {
// path: 'received',
// loadChildren: () => import('./pages/warehouse/received/warehouse-received.module').then(m => m.WarehouseReceivedModule)
// },
// {
// path: 'inspection',
// loadChildren: () => import('./pages/warehouse/inspection/warehouse-inspection.module').then(m => m.WarehouseInspectionModule)
// },
// {
// path: 'disbursement',
// loadChildren: () => import('./pages/warehouse/disbursement/warehouse-disbursement.module').then(m => m.WarehouseDisbursementModule)
// },
// {
// path: 'area',
// loadChildren: () => import('./pages/setting/master-area/master-area.module').then(m => m.MasterAreaModule)
// },
// {
// path: 'storage-box',
// loadChildren: () => import('./pages/setting/master-storage-box/master-storage-box.module').then(m => m.MasterStorageBoxModule)
// }
// ]
// },
// {
// path: 'setting',
// children: [
// {
// path: 'products',
// loadChildren: () => import('./pages/setting/products/products.module').then(m => m.ProductsModule)
// },
// {
// path: 'deviation',
// loadChildren: () => import('./pages/setting/setting-deviation/setting-deviation.module').then(m => m.SettingDeviationModule)
// },
// {
// path: 'product-brand',
// loadChildren: () => import('./pages/setting/master-product-brand/master-product-brand.module').then(m => m.MasterProductBrandModule)
// },
// {
// path: 'product-category',
// loadChildren: () => import('./pages/setting/master-product-category/master-product-category.module').then(m => m.MasterProductCategoryModule)
// },
// {
// path: 'product-unit',
// loadChildren: () => import('./pages/setting/master-product-unit/master-product-unit.module').then(m => m.MasterProductUnitModule)
// },
// {
// path: 'product-measurement',
// loadChildren: () => import('./pages/setting/master-product-measurement/master-product-measurement.module').then(m => m.MasterProductMeasurementModule)
// },
// {
// path: 'installment',
// loadChildren: () => import('./pages/setting/setting-installment/setting-installment.module').then(m => m.SettingInstallmentModule)
// },
// {
// path: 'packet',
// loadChildren: () => import('./pages/setting/packet/packet.module').then(m => m.PacketModule)
// },
// {
// path: 'promotion',
// loadChildren: () => import('./pages/setting/promotion/promotion.module').then(m => m.PromotionModule)
// },
// {
// path: 'customer',
// loadChildren: () => import('./pages/setting/customer/customer.module').then(m => m.CustomerModule)
// },
// {
// path: 'seller',
// loadChildren: () => import('./pages/setting/seller/seller.module').then(m => m.SellerModule)
// },
// ]
// },
// {
// path: 'report',
// loadChildren: () => import('./pages/report/report.module').then(m => m.ReportModule)
// },
{
path: 'not-found',
loadChildren: () => import('./pages/errors/errors.module').then(m => m.ErrorsModule)

View File

@@ -1,61 +1,61 @@
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {AppService} from '../../app.service';
import {lastValueFrom} from "rxjs";
import {API, EAction, EText} from "../../@config/app";
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AppService } from '../../app.service';
import { lastValueFrom } from "rxjs";
import { EAction, EText } from "../../@config/app";
import { environment } from "../../../environments/environment";
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styles: []
selector: 'app-login',
templateUrl: './login.component.html',
styles: []
})
export class LoginComponent implements OnInit {
apiUrl: string = API.login;
dataForm: any = {};
isLoading = false;
// apiUrl: string = API.login;
dataForm: any = {};
isLoading = false;
constructor(
private router: Router,
private appService: AppService,
private route: ActivatedRoute
) {
}
ngOnInit() {
if (!environment.production) {
this.dataForm = {
username : 'admin',
password : 'password@1',
}
}
}
async onSubmit(form: any) {
if (!form.valid) return false;
const dataForm = {
username: this.dataForm.username,
password: this.dataForm.password,
userType: 'ADMIN'
};
try {
console.log(this.apiUrl)
const result = await lastValueFrom(this.appService.post(this.apiUrl, dataForm));
this.appService.setAuth(result.data);
this.appService.setToken(result.accessToken);
return this.router.navigate(['/pages']);
} catch (err) {
return this.appService.message(EAction.ERROR, EText.NO_DATA);
constructor(
private router: Router,
private appService: AppService,
private route: ActivatedRoute
) {
}
}
ngOnInit() {
if (!environment.production) {
this.dataForm = {
username: 'admin',
password: 'password@1',
}
}
}
async onSubmit(form: any) {
if (!form.valid) return false;
const dataForm = {
username: this.dataForm.username,
password: this.dataForm.password,
userType: 'ADMIN'
};
public isFieldValid(form: any, field: any) {
return field.errors && (field.dirty || field.touched || form.submitted);
}
try {
// console.log(this.apiUrl)
// const result = await lastValueFrom(this.appService.post(this.apiUrl, dataForm));
// this.appService.setAuth(result.data);
// this.appService.setToken(result.accessToken);
return this.router.navigate(['/pages']);
} catch (err) {
return this.appService.message(EAction.ERROR, EText.NO_DATA);
}
}
public isFieldValid(form: any, field: any) {
return field.errors && (field.dirty || field.touched || form.submitted);
}
}

View File

@@ -0,0 +1,75 @@
import { environment } from '../../../environments/environment';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Location } from '@angular/common'
import { ActivatedRoute, Router } from '@angular/router';
import { filter, tap } from 'rxjs/operators';
import { Directive } from '@angular/core';
@Directive()
export class BaseForm {
isHideForm: boolean = environment.hideForm;
baseFormBuilder: FormBuilder
form: FormGroup
state: string = 'add'
isEdit: boolean = false
id: number
uid: string
uid2: string
path: string
constructor(
public _router: Router,
public _activeRouter: ActivatedRoute,
public fb: FormBuilder,
public location: Location
) {
this.baseFormBuilder = this.fb
this.form = this.createForm()
this._activeRouter.params.pipe(
tap(x => {
if (x.hasOwnProperty('id')) {
x.id ? this.state = 'edit' : this.state = 'add'
x.id ? this.isEdit = true : this.isEdit = false
}
if (x.hasOwnProperty('uid')) {
x.uid ? this.state = 'edit' : this.state = 'add'
}
}),
tap(x => console.log(this.state)),
tap(x => {
this._activeRouter.url.pipe(
tap(x => {
if (x[0]?.path === 'approve') {
this.state = 'approve';
}
}),
tap(x => this.path = x[0]?.path),
// tap(x => console.log(x))
).subscribe();
}),
tap(x => x.id ? this.id = x.id : this.id = null),
tap(x => x.uid ? this.uid = x.uid : this.uid = null),
tap(x => x.uid2 ? this.uid2 = x.uid2 : this.uid2 = null)
).subscribe();
}
back() {
this.location.back()
}
createForm(): FormGroup {
return this.fb.group({})
}
}
export var sortByProperty = function (property) {
return function (x, y) {
return ((x[property] === y[property]) ? 0 : ((x[property] > y[property]) ? 1 : -1));
};
};
export var sortByPropertyplus = function (property) {
return function (y, x) {
return ((y[property] === x[property]) ? 0 : ((y[property] < x[property]) ? 1 : -1));
};
};

View File

@@ -0,0 +1,75 @@
import { Observable } from 'rxjs';
import { Directive, Output, ViewChild, EventEmitter } from '@angular/core';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { environment } from 'src/environments/environment';
import { map, startWith } from 'rxjs/operators';
export interface ResultPageEvent<T> {
results: T[];
current_page: number;
page_count: number;
page_size: number;
row_count: number;
first_row_on_page: number;
last_row_on_page: number;
}
export interface CustomeEventPage extends PageEvent {
queryStringPage?: string,
paginator?: MatPaginator
}
@Directive()
export class BaseList {
protected INT_PAGING:CustomeEventPage = {
length: 0,
pageIndex: 0,
pageSize: 5,
previousPageIndex: null,
queryStringPage: `0/5`,
}
isProduction = environment.production
@ViewChild(MatSort,{ static: true }) sort: MatSort;
@ViewChild(MatPaginator,{ static: true }) paginator: MatPaginator;
@Output() onPaginatorPageChange = new EventEmitter<PageEvent>()
protected updateMatTable(res: any){
if(res instanceof Array){
res = new MatTableDataSource(res)
res.paginator = this.paginator
res.sort = this.sort
return res
}
return res
}
protected updatePagingMatTable<T>(data: ResultPageEvent<T>){
// let matTable = new MatTableDataSource<T>(data.results)
// matTable.paginator = this.paginator
// matTable.sort = this.sort
// return matTable
this.paginator.length = data.row_count
return data.results
}
protected getEventPage(): Observable<PageEvent> {
return this.paginator.page.pipe(
startWith(this.INT_PAGING),
map( event => {
return {
...event,
paginator: this.paginator,
queryStringPage: `${event.pageIndex + 1}/${event.pageSize}`
}
})
)
}
}

View File

@@ -0,0 +1,93 @@
import { HttpClient, HttpEventType } from '@angular/common/http';
import { Optional } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
export interface IapiResponse<T>{
apiResponse:{
id:number,
desc:string,
},
data:Array<T>
}
export class BaseService {
protected host:string = `${environment.APIURL}`
protected prefix:string = `${this.host}/api`
protected fullUrl:string = ''
constructor(
endpoint:string,
protected http: HttpClient,
) {
this.fullUrl = this.prefix + endpoint
}
uploadDocument<HttpHeaderResponse>(target: FormData){
return this.http.post(this.fullUrl,target,{
reportProgress: true,
observe:'events'
}).pipe(
map((event: any) => {
switch(event.type){
case HttpEventType.UploadProgress:
const progress = Math.round(100 * event.loaded / event.total);
return { status: 'progress', message: `${progress}` };
case HttpEventType.Response:
return { status: 'success', message: event.body };
default:
return `Unhandled event: ${event.type}`;
}
}
),
catchError(err => {
return of({ status: 'error', message: `${err.message}` })
})
)
}
getAll<T>(): Observable<T[]>{
return this.http.get<T[]>(this.fullUrl)
}
add<T>(data: T): Observable<T> {
return this.http.post<T>(this.fullUrl,data)
}
get<T>(id: any): Observable<T> {
return this.http.get<T>(`${this.fullUrl}/${id}`)
}
update<T>(id: number,data: T): Observable<Response>{
return this.http.put<Response>(`${this.fullUrl}/${id}`,data)
}
update2<T>(data: T): Observable<Response>{
return this.http.put<Response>(this.fullUrl,data)
}
deleteData(id: number | string): Observable<Response> {
return this.http.delete<Response>(`${this.fullUrl}/${id}`)
}
query<T>(query: string): Observable<T> {
return this.http.get<T>(`${this.fullUrl}/${query}`)
}
queryString<T>(query: string): Observable<T>{
return this.http.get<T>(`${this.fullUrl}?${query}`)
}
addMany<T>(data: T): Observable<T> {
return this.http.post<T>(`${this.fullUrl}/s`,data)
}
updateMany<T>(data: T): Observable<Response> {
return this.http.put<Response>(`${this.fullUrl}/s`,data)
}
}

View File

@@ -0,0 +1,93 @@
import { HttpClient, HttpEventType } from '@angular/common/http';
import { Optional } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
export interface IapiResponse<T>{
apiResponse:{
id:number,
desc:string,
},
data:Array<T>
}
export class BaseStoreService {
protected host:string = `${environment.storeApi}`
protected prefix:string = `${this.host}`
protected fullUrl:string = ''
constructor(
endpoint:string,
protected http: HttpClient,
) {
this.fullUrl = this.prefix + endpoint
}
uploadDocument<HttpHeaderResponse>(target: FormData){
return this.http.post(this.fullUrl,target,{
reportProgress: true,
observe:'events'
}).pipe(
map((event) => {
switch(event.type){
case HttpEventType.UploadProgress:
const progress = Math.round(100 * event.loaded / event.total);
return { status: 'progress', message: `${progress}` };
case HttpEventType.Response:
return { status: 'success', message: event.body };
default:
return `Unhandled event: ${event.type}`;
}
}
),
catchError(err => {
return of({ status: 'error', message: `${err.message}` })
})
)
}
getAll<T>(): Observable<T[]>{
return this.http.get<T[]>(this.fullUrl)
}
add<T>(data: T): Observable<T> {
return this.http.post<T>(this.fullUrl,data)
}
get<T>(id: any): Observable<T> {
return this.http.get<T>(`${this.fullUrl}/${id}`)
}
update<T>(id: number,data: T): Observable<Response>{
return this.http.put<Response>(`${this.fullUrl}/${id}`,data)
}
update2<T>(data: T): Observable<Response>{
return this.http.put<Response>(this.fullUrl,data)
}
deleteData(id: number | string): Observable<Response> {
return this.http.delete<Response>(`${this.fullUrl}/${id}`)
}
query<T>(query: string): Observable<T> {
return this.http.get<T>(`${this.fullUrl}/${query}`)
}
queryString<T>(query: string): Observable<T>{
return this.http.get<T>(`${this.fullUrl}?${query}`)
}
addMany<T>(data: T): Observable<T> {
return this.http.post<T>(`${this.fullUrl}/s`,data)
}
updateMany<T>(data: T): Observable<Response> {
return this.http.put<Response>(`${this.fullUrl}/s`,data)
}
}

View File

@@ -0,0 +1,5 @@
export const configs: {
formatDate: string
} = {
formatDate: 'yyyy-MM-dd'
}

View File

@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenIntercepterInterceptor } from './intercepter/token-intercepter.interceptor';
@NgModule({
declarations: [],
imports: [
CommonModule,
HttpClientModule,
],
exports: [
CommonModule,
HttpClientModule,
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: TokenIntercepterInterceptor, multi: true },
]
})
export class CoreModule { }

44
src/app/core/enum/role.ts Normal file
View File

@@ -0,0 +1,44 @@
export enum OBJECT {
BUILDING = 'BUILDING',
ROOM_AND_FIELD = 'ROOM_AND_FIELD',
REQUEST_RESERVATION = 'REQUEST_RESERVATION',
LIST_RESERVATION = 'LIST_RESERVATION',
LIST_BLUEPRINT = 'LIST_BLUEPRINT',
LIST_BROKEN = 'LIST_BROKEN',
LIST_ROOM_CLOSE = 'LIST_ROOM_CLOSE',
EMPLOYMENT_CONTACT = 'EMPLOYMENT_CONTRACT',
MAINTENANCE_CONTRACT = 'MAINTENANCE_CONTRACT',
RENTAL_CONTRACT = 'RENTAL_CONTRACT',
LIST_MAINTENANCE_CONTRACT = 'LIST_MAINTENANCE_CONTRACT',
ASSET_LIST_CONTRACT = 'ASSET_LIST_CONTRACT',
LOG_CONTRACT = 'LOG_CONTRACT',
CREATE_PERMISSION = 'CREATE_PERMISSION',
SET_PERMISSION = 'SET_PERMISSION',
ASSET_RECEIVE = 'ASSET_RECEIVE',
INVENTORY_RECEIVE = 'INVENTORY_RECEIVE',
LIST_INVENTORY = 'LIST_INVENTORY',
REQUISITION = 'REQUISITION',
REQUISITION_PLACEMENT = 'REQUISITION_PLACEMENT',
APPROVE_REQUISITION = 'APPROVE_REQUISITION',
RETURN_ASSET = 'RETURN_ASSET',
STORE_ITEMS = 'STORE_ITEMS',
WAREHOUSE = 'WAREHOUSE',
STORE_ITEMS_CATEGORY = 'STORE_ITEMS_CATEGORY',
STORE_ITEMS_GROUP = 'STORE_ITEMS_GROUP',
STORE_ITEMS_TYPE = 'STORE_ITEMS_TYPE',
STORE_ITEMS_CLASS = 'STORE_ITEMS_CLASS',
UNITS = 'UNITS',
UNITS_GROUP = 'UNITS_GROUP',
REPAIR_LIST = 'REPAIR_LIST',
REPAIR_ORDER = 'REPAIR_ORDER',
REPAIR_RESULT = 'REPAIR_RESULT',
REPAIR_TYPE = 'REPAIR_TYPE',
REPAIR_DETAIL = 'REPAIR_DETAIL',
REPAIR_ROUTE = 'REPAIR_ROUTE',
REPAIR_URGENT = 'REPAIR_URGENT',
BUILDING_GROUP = 'BUILDING_GROUP',
ROOM_GROUP = 'ROOM_GROUP',
PURPOSE = 'PURPOSE',
SCHEDULE_TEACHING = 'SCHEDULE_TEACHING',
PERIOD_REQUEST = 'PERIOD_REQUEST',
}

View File

@@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot } from '@angular/router';
// import { AppService } from './app.service';
@Injectable()
export class AppGuard implements CanActivate, CanActivateChild {
constructor(private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.isLogin();
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.isLogin();
}
isLogin() {
return true;
// const user = this.app.auth();
// if (!user) {
// this.router.navigate(['/auth/login']);
// return false;
// }
// return true;
}
}

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { TokenIntercepterInterceptor } from './token-intercepter.interceptor';
describe('TokenIntercepterInterceptor', () => {
beforeEach(() => TestBed.configureTestingModule({
providers: [
TokenIntercepterInterceptor
]
}));
it('should be created', () => {
const interceptor: TokenIntercepterInterceptor = TestBed.inject(TokenIntercepterInterceptor);
expect(interceptor).toBeTruthy();
});
});

View File

@@ -0,0 +1,44 @@
import { OidcAuthService } from 'src/app/core/oidc/oidc.service';
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators';
import { Router } from '@angular/router';
import { NgProgress } from 'ngx-progressbar';
import { ApplicationSecurityService } from '../service/security/application-security.service';
@Injectable()
export class TokenIntercepterInterceptor implements HttpInterceptor {
constructor(
private odicSV: OidcAuthService,
private router: Router,
private progress: NgProgress,
private appTokenSV: ApplicationSecurityService
) {
}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
const isRegisterSubjectAPI = request.url.includes('rsu-reg-api')
const customReq = request.clone({
setHeaders:{
Authorization: request.url.includes('app_tokens') ? `${this.odicSV.getAuthorizationHeaderValue()}` : `Bearer ${this.appTokenSV.getToken()}`
}
});
this.progress.ref('progressBar').start()
return next.handle(customReq).pipe(
finalize(() => this.progress.ref('progressBar').complete()),
catchError(err => {
if (err.status == 401) {
this.router.navigate(['./'],{ replaceUrl: true })
}
return throwError(err)
})
);
}
}

View File

@@ -0,0 +1,16 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BaseService } from 'src/app/core/base/base-service';
@Injectable({
providedIn: 'root'
})
export class KycService extends BaseService{
constructor(
public http: HttpClient
) {
super('/common/kyc', http)
}
}

View File

@@ -10,7 +10,7 @@
</button>
</div>
<img class="logo-main" src="./assets/images/logo.png" />
<img class="logo-icon" src="./assets/images/logo-icon.png" />
<!-- <img class="logo-icon" src="./assets/images/logo-icon.png" /> -->
</section>
<nav class="main-menu-nav">

View File

@@ -3,7 +3,6 @@ import { ActivatedRoute, Router } from '@angular/router';
import { AppService } from '../../app.service';
import { MENU } from "../../@config/menus";
import { lastValueFrom } from "rxjs";
import { API } from "../../@config/app";
import { environment } from 'src/environments/environment';
@Component({
@@ -41,9 +40,9 @@ export class PagesLayoutsComponent implements OnInit {
this.auth = this.app.auth();
if (!this.permissionCheck) {
const users = await lastValueFrom(this.app.get(`${API.users}/getById/${this.auth.id}`));
this.permission = users.permission;
this.permissionCheck = true;
// const users = await lastValueFrom(this.app.get(`${API.users}/getById/${this.auth.id}`));
// this.permission = users.permission;
// this.permissionCheck = true;
}
}

View File

@@ -1,28 +0,0 @@
import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import {Appraisal1stTimeIndexComponent} from './index/appraisal-1st-time-index.component';
import {Appraisal1stTimeDoComponent} from "./do/appraisal-1st-time-do.component";
import { Appraisal1stTimeHistoryComponent } from "./history/appraisal-1st-time-history.component";
import { Appraisal1stTimePdfComponent } from "./pdf/appraisal-1st-time-pdf.component";
const routes: Routes = [
{path: '', component: Appraisal1stTimeIndexComponent},
{path: 'do/:action', component: Appraisal1stTimeDoComponent},
{path: 'do/:action/:id', component: Appraisal1stTimeDoComponent},
{path: 'history', component: Appraisal1stTimeHistoryComponent},
{path: 'history/pdf/:id', component: Appraisal1stTimePdfComponent},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
Appraisal1stTimeIndexComponent,
Appraisal1stTimeDoComponent,
Appraisal1stTimeHistoryComponent,
Appraisal1stTimePdfComponent,
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './appraisal-1st-time-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class Appraisal1stTimeModule {}

View File

@@ -1,391 +0,0 @@
<form class="main-form" #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<form #ngfCalculate="ngForm" (ngSubmit)="onCalculate(ngfCalculate)">
<div class="grid grid-cols-12 gap-4 md:gap-2 h-full">
<div class="col-span-6 md:col-span-12">
<div class="card card-form-panel card-form-panel-blue h-full">
<div class="card-header ">
<div class="card-title"> กรอกข้อมูลการจัดผ่อน <span class="color-red">(ราคาล่าสุด {{dataView.latestPrice | number : '1.2-2'}} บาท)</span></div>
</div>
<div class="card-body form-input-list">
<div style="height: 20px;"></div>
<div class="grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> เลือก Packet</label>
</div>
<div class="col-span-4 md:col-span-12">
<ng-select placeholder="เลือก Packet" name="packetId" #packetId="ngModel" [(ngModel)]="dataForm.packetId" (ngModelChange)="onChangePacket($event)" appendTo="body" required>
<ng-option *ngFor="let item of packets" [value]="item.id">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit" *ngIf="dataForm.packetId">
<i (click)="onPacketView()" class="bi bi-search color-main cursor-pointer"></i>
</div>
</div>
</div>
<div class="grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> วันที่เริ่มจัดผ่อน</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input
matInput
name="startDate"
#startDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.startDate"
[matDatepicker]="dpkName"
readonly
required
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit"></div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ราคา (Price)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="price" #price="ngModel" [(ngModel)]="dataForm.price" (ngModelChange)="onChange($event, 'price')" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำแม่ค้า</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="sellerDeposit" #sellerDeposit="ngModel" [(ngModel)]="dataForm.sellerDeposit" (ngModelChange)="onChange($event, 'sellerDeposit')" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำ CMFS</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="deposit" #deposit="ngModel" [(ngModel)]="dataForm.deposit" (ngModelChange)="onChange($event, 'deposit')" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> เงินต้นคงเหลือ (Total)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="principalBalanceTotal" #principalBalanceTotal="ngModel" [(ngModel)]="dataForm.principalBalanceTotal" required disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ต้องการผ่อน (Term)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput type="number" name="wantToInstallmentTerm" #wantToInstallmentTerm="ngModel" [(ngModel)]="dataForm.wantToInstallmentTerm" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">งวด</div>
</div>
</div>
<div class="action">
<button type="button" class="btn btn-back" (click)="onCalculateReset()">ล้างข้อมูล</button>
<button type="submit" class="btn btn-submit">คำนวน</button>
</div>
</div>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="card card-form-panel card-form-panel-blue h-full">
<div class="card-header ">
<div class="card-title"> รายละเอียดค่าใช้จ่ายในการโอนเงิน</div>
</div>
<div class="card-body form-input-list">
<div style="height: 20px;"></div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำ CMFS Deposit</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="cmfsDeposit" #cmfsDeposit="ngModel" [(ngModel)]="dataForm.cmfsDeposit" (ngModelChange)="onChange($event, 'cmfsDeposit')" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> หัก เงินมัดจำแม่ค้า </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="lessSellerDeposit" #lessSellerDeposit="ngModel" [(ngModel)]="dataForm.lessSellerDeposit" (ngModelChange)="onChange($event, 'lessSellerDeposit')">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Packing </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusPacking" #plusPacking="ngModel" [(ngModel)]="dataForm.plusPacking" (ngModelChange)="onChange($event, 'plusPacking')" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Luxury handbag </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusLuxuryHandbag" #plusLuxuryHandbag="ngModel" [(ngModel)]="dataForm.plusLuxuryHandbag" (ngModelChange)="onChange($event, 'plusLuxuryHandbag')" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Bank fee, Insurance , Storage</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusBankFee" #plusBankFee="ngModel" [(ngModel)]="dataForm.plusBankFee" (ngModelChange)="onChange($event, 'plusBankFee')" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ส่วนลด </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="discount" #discount="ngModel" [(ngModel)]="dataForm.discount" (ngModelChange)="onChange($event, 'discount')" >
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> สรุปยอดโอน </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="transferSummary" #transferSummary="ngModel" [(ngModel)]="dataForm.transferSummary" disabled >
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<div style="height: 20px;"></div>
<div class="card card-table mb-6">
<div class="card-body">
<div *ngIf="!dataForm.quotationDetail?.[0]" class="no-data color-red font-bold"> กรุณากรอกข้อมูลการจัดผ่อนเพื่อแสดงตารางผ่อนชำระ</div>
<div class="table-wrap" *ngIf="dataForm.quotationDetail?.[0]">
<table class="tables">
<thead>
<tr>
<th>งวดที่</th>
<th>กำหนดจ่ายวันที่ <br>Due date</th>
<th>เงินต้น <br>Principle</th>
<th>ดอกเบี้ย(บาท) <br>Interest Total</th>
<th>Bank fee, <br>Insurance ,Storage</th>
<th>รวมยอดจ่ายต่อเดือน <br>Total payment</th>
<th>เงินต้นคงเหลือ <br>Principle Total</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let item of dataForm.quotationDetail; let i = index">
<tr>
<td class="text-center">{{item.installment }}</td>
<td class="text-center">{{item.dueDate | date : 'dd/MM/YYYY'}}</td>
<td class="text-center">{{item.principle | number: '1.0-0'}}</td>
<td class="text-center">{{item.interestTotal | number: '1.0-0'}}</td>
<td class="text-center">{{item.fee | number: '1.0-0'}}</td>
<td class="text-center"><span class="b-color-green">{{item.totalPayment | number: '1.0-0'}}</span></td>
<td class="text-center"><span class="b-color-orange" *ngIf="item.principleTotal">{{item.principleTotal | number: '1.0-0'}}</span></td>
</tr>
</ng-container>
<tr>
<td colspan="2" class="text-right"><b>รวม</b></td>
<td class="text-center">{{dataForm.principleSum | number: '1.0-0'}}</td>
<td class="text-center">{{dataForm.interestTotalSum | number: '1.0-0'}}</td>
<td class="text-center">{{dataForm.feeSum | number: '1.0-0'}}</td>
<td class="text-center"><span class="b-color-green">{{dataForm.totalPaymentSum | number: '1.0-0'}}</span></td>
<td class="text-center"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลลูกค้า</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-3 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="prefix" #prefix="ngModel" [(ngModel)]="dataForm.customerPrefix" appendTo="body" >
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="customerFirstName" #customerFirstName="ngModel" [(ngModel)]="dataForm.customerFirstName" >
</mat-form-field>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="customerLastName" #customerLastName="ngModel" [(ngModel)]="dataForm.customerLastName">
</mat-form-field>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="customerPhone" #customerPhone="ngModel" [(ngModel)]="dataForm.customerPhone">
</mat-form-field>
</div>
<!-- <div class="col-span-3 md:col-span-12 ">-->
<!-- <mat-label>BOM</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="productNo" #productNo="ngModel" [(ngModel)]="dataForm.productNo" required>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<div class="col-span-3 md:col-span-12 ">
<mat-label>ประเภทรหัส</mat-label>
<ng-select placeholder="ประเภทรหัส" name="typeCode" #typeCode="ngModel" [(ngModel)]="dataForm.typeCode" appendTo="body" required>
<ng-option *ngFor="let item of typeCodeData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<!-- <div class="col-span-3 md:col-span-12 ">-->
<!-- <mat-label>เลขที่ใบเสนอราคา</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="quotationNo" #quotationNo="ngModel" [(ngModel)]="dataForm.quotationNo" required>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<!-- <div class="col-span-9 md:hidden"></div>-->
<div class="col-span-3 md:col-span-12 ">
<mat-label>ชื่อพนักงาน</mat-label>
<mat-form-field>
<input matInput name="userFullName" #userFullName="ngModel" [(ngModel)]="dataForm.userFullName" required disabled>
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">รูปสินค้าจากลูกค้า</div>
<div class="ml-4">
<input hidden type="file" accept="image/*" #productImages (change)="onAttachments($event, 'products')" />
<button type="button" class="btn btn-sm btn-success-o" (click)="productImages.click()">เพิ่มรูปภาพสินค้า</button>
</div>
</div>
</div>
<div class="card-body">
<div class="list-images">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<ng-container *ngFor="let item of attachments; let i = index">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i *ngIf="dataForm.coverImage !== item" (click)="dataForm.coverImage = item"
matTooltip="ใช้ทำเอกสาร" class="bi bi-star color-main cursor-pointer select-none"></i>
<i *ngIf="dataForm.coverImage === item" class="bi bi bi-star-fill color-main cursor-pointer select-none"></i>
<i (click)="onRemoveAttachments(i, item)" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img src="{{storage.products}}/{{item}}" alt="">
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div class="main-form-action text-right">
<button type="submit" class="btn btn-submit">บันทึก</button>
<button type="button" class="btn btn-back" (click)="onAction('back')">ยกเลิก</button>
</div>
</form>

View File

@@ -1,309 +0,0 @@
import {ChangeDetectorRef, Component, OnInit} from "@angular/core";
import {API, EAction, EText, PREFIX, STORAGE, TYPE_CODE} from "../../../../@config/app";
import {AppService} from "../../../../app.service";
import {lastValueFrom} from "rxjs";
import {BaseFormComponent} from "../../../../@common/base/base-form.component";
import {ActivatedRoute, Router} from "@angular/router";
import {IProduct} from "../../../../app.interface";
import {addMonths, differenceInDays} from "date-fns";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {PacketViewComponent} from "../../../@popup/packet-view/packet-view.component";
import {MatDialog} from "@angular/material/dialog";
@Component({
selector: "app-appraisal-1st-time-do",
templateUrl: "./appraisal-1st-time-do.component.html",
styleUrls: []
})
export class Appraisal1stTimeDoComponent extends BaseFormComponent implements OnInit {
override dataForm: any = {};
dataView: IProduct = {};
auth: any = {};
title = "";
api: any = API;
storage: any = STORAGE;
addItemNumber: number = 1;
attachments: any = [];
settings: any = [];
packets: any = [];
packetData: any = {};
promotionDetail: any = [];
IN01: any = {};
IN05: any = {};
prefixData = PREFIX;
typeCodeData = TYPE_CODE;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private packetDialog: MatDialog,
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
this.action = params["action"];
this.auth = this.appService.auth();
this.settings = await lastValueFrom(this.appService.get(`${this.api.settings}?showAll=true&status=true&orderBy=code&sort=asc&codeIn=IN01,IN02,IN03,IN04,IN05`));
this.packets = await lastValueFrom(this.appService.get(`${API.packet}?showAll=true&status=true`));
if (this.ids) await this.getData();
});
}
async onAction(action: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.BACK));
if (!sweetalert.isConfirmed) return;
if (action === "back") return this.router.navigate(["/pages/appraisal/1st-time"]);
return;
}
async getData() {
if (!this.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
try {
this.dataForm = {};
this.dataView = await lastValueFrom(this.appService.get(`${this.api.products}/getById/${this.ids}`));
this.attachments = this.dataView.images ? this.dataView.images?.split(",") : [];
this.dataForm.startDate = new Date();
this.dataForm.cmfsDeposit = 0;
this.dataForm.deposit = 0;
this.dataForm.plusPacking = 0;
this.dataForm.plusLuxuryHandbag = 0;
this.dataForm.plusBankFee = 0;
this.dataForm.settingCmfsDeposit = 0;
this.dataForm.settingInterestRate = 0;
this.dataForm.discount = 0;
this.dataForm.sellerDeposit = 0;
this.dataForm.lessSellerDeposit = 0;
// this.dataForm.productNo = this.dataView.code;
this.dataForm.productName = this.dataView.name;
this.dataForm.coverImage = this.dataView.coverImage;
this.dataForm.productId = this.dataView.id;
this.dataForm.productSize = this.dataView.size;
this.dataForm.productWeight = this.dataView.weight;
this.dataForm.productColor = this.dataView.color;
this.dataForm.productYear = this.dataView.year;
this.dataForm.productPrice = this.dataView.price;
this.dataForm.productLatestPrice = this.dataView.latestPrice;
this.dataForm.productBrandName = this.dataView.masterProductBrand?.name;
this.dataForm.productMeasurement = this.dataView.productMeasurement;
this.dataForm.userFullName = this.auth.name;
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onChangePacket(value: string) {
this.dataForm.plusPacking = 0;
this.dataForm.plusLuxuryHandbag = 0;
this.dataForm.plusBankFee = 0;
this.dataForm.settingCmfsDeposit = 0;
this.dataForm.settingInterestRate = 0;
if (!value) return;
this.packetData = await lastValueFrom(this.appService.get(`${API.packet}/getById/${value}`));
if (!this.packetData.packetDetail) return;
this.dataForm.plusPacking = this.packetData.packetDetail.find((f: { code: string; }) => f.code === "IN02").value;
this.dataForm.plusLuxuryHandbag = this.packetData.packetDetail.find((f: { code: string; }) => f.code === "IN03").value;
this.dataForm.plusBankFee = this.packetData.packetDetail.find((f: { code: string; }) => f.code === "IN04").value;
this.dataForm.settingCmfsDeposit = this.packetData.packetDetail.find((f: { code: string; }) => f.code === "IN01").value;
this.dataForm.settingInterestRate = this.packetData.packetDetail.find((f: { code: string; }) => f.code === "IN05").value;
this.promotionDetail = this.packetData?.promotion?.promotionDetail;
this.onChange(this.dataForm.price, 'price');
this.dataForm.quotationDetail = [];
}
onChange($event: any, key?: string) {
if (key) this.dataForm[key] = $event;
this.changeDetectorRef.detectChanges();
if (key === "price") {
const IN01 = Number(this.dataForm.settingCmfsDeposit) / 100;
this.dataForm.price = this.dataForm.price ? this.dataForm.price : 0;
this.dataForm.deposit = IN01 * this.dataForm.price;
this.dataForm.cmfsDeposit = IN01 * this.dataForm.price;
}
this.dataForm.sellerDeposit = this.dataForm.sellerDeposit ? this.dataForm.sellerDeposit : 0;
this.dataForm.deposit = this.dataForm.deposit ? this.dataForm.deposit : 0;
if (key === "sellerDeposit") {
this.dataForm.lessSellerDeposit = this.dataForm.sellerDeposit;
}
if (key === "deposit") {
this.dataForm.cmfsDeposit = this.dataForm.deposit;
}
if (key === "cmfsDeposit") {
this.dataForm.deposit = this.dataForm.cmfsDeposit;
}
this.dataForm.principalBalanceTotal = this.dataForm.price - this.dataForm.deposit;
this.dataForm.transferSummary = Number(this.dataForm.cmfsDeposit) +
Number(this.dataForm.plusPacking) +
Number(this.dataForm.plusLuxuryHandbag) +
Number(this.dataForm.plusBankFee) -
Number(this.dataForm.lessSellerDeposit) -
Number(this.dataForm.discount);
this.changeDetectorRef.detectChanges();
}
async onCalculate(form: any) {
if (!form.valid) return false;
this.dataForm.quotationDetail = [];
const principle = this.dataForm.principalBalanceTotal / this.dataForm.wantToInstallmentTerm;
let principleTotalBefore = Number(this.dataForm.principalBalanceTotal);
let startDate = this.dataForm.startDate;
const IN05 = Number(this.dataForm.settingInterestRate) / 100;
for (let i = 0; i < this.dataForm.wantToInstallmentTerm; i++) {
let item = {
installment: i + 1,
dueDate: addMonths(this.dataForm.startDate, i + 1),
principle: Number(principle),
interestTotal: 0,
interestRate: this.promotionDetail?.[i].value,
isInterest: this.promotionDetail?.[i].status,
fee: Number(this.dataForm.plusBankFee),
totalPayment: 0,
principleTotal: 0,
interestPerDays: 0
};
const interestPerDays = differenceInDays(item.dueDate, startDate) + 1;
item.interestTotal = principleTotalBefore * IN05 * interestPerDays / 365;
item.interestPerDays = interestPerDays;
if (item.isInterest) item.interestTotal = 0;
item.totalPayment = item.principle + item.interestTotal + item.fee;
item.principleTotal = principleTotalBefore - item.principle;
startDate = item.dueDate;
principleTotalBefore = item.principleTotal;
console.log(item)
this.dataForm.quotationDetail.push(item);
this.dataForm.principleSum = 0;
this.dataForm.interestTotalSum = 0;
this.dataForm.feeSum = 0;
this.dataForm.feeSum = 0;
this.dataForm.totalPaymentSum = 0;
this.dataForm.quotationDetail.map((item: any) => {
this.dataForm.principleSum += Number(item.principle);
this.dataForm.interestTotalSum += Number(item.interestTotal);
this.dataForm.feeSum += Number(item.fee);
this.dataForm.totalPaymentSum += Number(item.totalPayment);
});
this.dataForm.principleSum = Math.round(this.dataForm.principleSum);
}
console.log("quotationDetail", this.dataForm.quotationDetail);
return;
}
async onCalculateReset() {
return await this.getData();
}
async onSubmit(form: any) {
if (!form.valid) return false;
if (!this.dataForm.quotationDetail?.[0]) return this.appService.message(EAction.ERROR, "กรุณากรอกข้อมูลการจัดผ่อนเพื่อแสดงตารางผ่อนชำระ");
this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null;
if (this.action === EAction.CREATE) return await this.onCreate();
if (this.action === EAction.UPDATE) return await this.onUpdate();
return;
}
async onCreate() {
try {
await lastValueFrom(this.appService.post(this.api.quotation, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.CREATE);
await this.router.navigate(["/pages/appraisal/1st-time"]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onUpdate() {
try {
await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.UPDATE);
await this.router.navigate(["/pages/setting/products"]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachments($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${this.api.attachments}/products`, formData));
if (!this.attachments[0]) {
this.dataForm.coverImage = res.fileName;
}
this.attachments.push(res.fileName);
console.log(this.attachments, res);
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments(i: number, fileName: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.attachments?.splice(i, 1);
if (!this.attachments[0]) {
this.dataForm.coverImage = null;
}
this.changeDetectorRef.detectChanges();
}
async onPacketView() {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'รายละเอียด Packet';
dialogConfig.data.data = this.packetData;
const dialogRef = this.packetDialog.open(PacketViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
}

View File

@@ -1,123 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<div class="card-header-action">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
</div>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-3 md:col-span-6">
<mat-form-field>
<input
matInput
name="startDate"
#startDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataFilter.createdDate"
[matDatepicker]="dpkName"
readonly
(ngModelChange)="getData()"
/>
<!-- <mat-icon matSuffix (click)="clearDate($event)">clear</mat-icon>-->
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-9 md:col-span-12 ">
<div class="flex w-full ">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="tac">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 200px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item">
<i class="bi bi-filetype-pdf color-main" (click)="onAction(item.id)"></i>
</div>
<div class="item" *ngIf="item.status === 'pending'">
<i class="bi bi-trash3 color-red" (click)="onDelete(item.id)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSourceCount === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,91 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EText } from "../../../../@config/app";
import { Router } from "@angular/router";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-appraisal-1st-time-index",
templateUrl: "./appraisal-1st-time-history.component.html",
styleUrls: []
})
export class Appraisal1stTimeHistoryComponent extends BaseListComponent implements OnInit {
pageTitle = "ประวัติการสร้างใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = ["action","price", "quotationNo", "customerFirstName", "productName", "wantToInstallmentTerm", "createdDate", "status"];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
await this.getData();
}
onAction(id?: any) {
if (id) return this.router.navigate(["/pages/appraisal/1st-time/history/pdf", id]);
return this.router.navigate(["/pages/appraisal/1st-time/do", "create"]);
}
async getData($event?: any) {
try {
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,customerLastName,price";
const dataSource = await lastValueFrom(this.appService.get(this.setParams(this.apiUrl, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
const url = `${API.quotation}/export-history?${filter ? '&' + filter : '' }`;
window.open(url);
}
}

View File

@@ -1,122 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<div class="card-header-action">
<button type="button" class="btn btn-create" (click)="onAction()">
<i class="bi bi-plus"></i>
ประวัติการสร้างใบเสนอราคา
</button>
</div>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-3 md:col-span-6">
<ng-select name="categoryId" #categoryId="ngModel" [(ngModel)]="dataFilter.categoryId" (ngModelChange)="getData()" appendTo="body" required placeholder="เลือกหมวดหมู่">
<ng-option *ngFor="let item of masterProductCategory" [value]="item.id">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-6">
<ng-select placeholder="Choose Brand" name="brandId" #brandId="ngModel" [(ngModel)]="dataFilter.brandId" (ngModelChange)="getData()" appendTo="body" required>
<ng-option *ngFor="let item of masterProductBrand" [value]="item.id">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="code">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="tac">{{item.code}}</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 200px;">
<!-- <div class="flex items-center">-->
<!-- <div class="image-td"><img *ngIf="item.coverImage" src="{{storage.products}}/{{item.coverImage}}" alt=""></div>-->
<!-- <div class="">{{item.name }}</div>-->
<!-- </div>-->
{{item.name }}
</td>
</ng-container>
<ng-container matColumnDef="brandId">
<th mat-header-cell *matHeaderCellDef class="tal" mat-sort-header>Brand</th>
<td mat-cell *matCellDef="let item" class="">{{item?.masterProductBrand.name }}</td>
</ng-container>
<ng-container matColumnDef="size">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">Main</th>
<td mat-cell *matCellDef="let item" class="">{{item.size }}</td>
</ng-container>
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">น้ำหนัก</th>
<td mat-cell *matCellDef="let item" class="">{{item.weight }}</td>
</ng-container>
<ng-container matColumnDef="color">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">Color</th>
<td mat-cell *matCellDef="let item" class="">{{item.color }}</td>
</ng-container>
<ng-container matColumnDef="year">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">Year</th>
<td mat-cell *matCellDef="let item" class="">{{item.year }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>ราคา</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-orange"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="latestPrice">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>ราคาล่าสุด</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.latestPrice | number : '1.2-2' }}</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">สร้างใบเสนอราคา</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item">
<i class="bi bi-file-earmark-text icon-doc" (click)="onAction(item.id)"></i>
</div>
</div>
</td>
</ng-container>
</table>
</div>
<div *ngIf="dataSourceCount === 0" class="no-data"></div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,71 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API } from "../../../../@config/app";
import { Router } from "@angular/router";
@Component({
selector: "app-appraisal-1st-time-index",
templateUrl: "./appraisal-1st-time-index.component.html",
styleUrls: []
})
export class Appraisal1stTimeIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "สินค้า";
apiUrl: string = API.products;
api: any = API;
displayedColumns: string[] = ["action", "price", "latestPrice","code", "name", "brandId", "size",'weight', "color", "year" ];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.masterProductCategory = await lastValueFrom(this.appService.get(`${this.api.masterProductCategory}?showAll=true&status=true`));
this.masterProductBrand = await lastValueFrom(this.appService.get(`${this.api.masterProductBrand}?showAll=true&status=true`));
await this.getData();
}
onAction(id?: any) {
if (id) return this.router.navigate(["/pages/appraisal/1st-time/do", "create", id]);
return this.router.navigate(["/pages/appraisal/1st-time/history"]);
}
async getData($event?: any) {
try {
this.dataFilter.keywordColumn = "name,price,latestPrice";
const dataSource = await lastValueFrom(this.appService.get(this.setParams(this.apiUrl, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,105 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { lastValueFrom } from "rxjs";
import { AppService } from "../../../../app.service";
import { API, STORAGE } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { IQuotation } from "../../../../@common/interface/Quotation";
import { format, parseISO } from "date-fns";
@Component({
selector: "app-appraisal-1st-time-index",
templateUrl: "./appraisal-1st-time-pdf.component.html",
styleUrls: []
})
export class Appraisal1stTimePdfComponent extends BaseFormComponent implements OnInit {
pageTitle = "ใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotation : IQuotation = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
const startDate = quotation.startDate ? format(parseISO(quotation.startDate), "dd/MM/yyyy") : null;
const customerPrefix = quotation.customerPrefix ? quotation.customerPrefix : '';
const customerName = quotation.customerId ? `${quotation.customer?.prefix} ${quotation.customer?.firstName} ${quotation.customer?.lastName}` :
`${customerPrefix} ${quotation.customerFirstName} ${quotation.customerLastName}`;
const data = {
doc_no: quotation.quotationNo,
product_code: quotation.productNo,
type_code: quotation.typeCode,
customer_name: customerName,
phone_no: quotation.customerPhone,
installment_start_date: startDate,
picture: `${STORAGE.products}/${quotation.coverImage}`,
price: Number(quotation.price),
seller_deposit: Number(quotation.sellerDeposit),
cmfs_deposit: Number(quotation.cmfsDeposit),
total_balance: Number(quotation.principalBalanceTotal),
installment: Number(quotation.wantToInstallmentTerm),
packing: Number(quotation.plusPacking),
luxury_handbag_authentication: Number(quotation.plusLuxuryHandbag),
bankfee_insurance_storage: Number(quotation.plusBankFee),
transfer_amount: Number(quotation.transferSummary),
discount: Number(quotation.discount),
data: [],
total1: 0,
total2: 0,
total3: 0,
total4: 0
}
const quotationDetail: any = [];
quotation.quotationDetail?.map(item => {
const dueDate = item.dueDate ? format(parseISO(item.dueDate), "dd/MM/yyyy") : null;
const map = {
due_date: dueDate,
principle: Number(item.principle),
interest_total: Number(item.interestTotal),
bank_fee: Number(item.fee),
total_payment: Number(item.totalPayment),
principle_total: Number(item.principleTotal)
}
quotationDetail.push(map);
})
data.data = quotationDetail;
const pdf = await lastValueFrom(this.appService.post(`${this.api.quotationReport}/pdf`, data, { responseType: "arraybuffer" }));
const url = URL.createObjectURL(new Blob([pdf], { type: "application/pdf" }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,28 +0,0 @@
import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import {Appraisal2ndTimeIndexComponent} from './index/appraisal-2nd-time-index.component';
import {Appraisal2ndTimeDoComponent} from "./do/appraisal-2nd-time-do.component";
import { Appraisal2ndTimeHistoryComponent } from "./history/appraisal-2nd-time-history.component";
import { Appraisal2ndTimePdfComponent } from "./pdf/appraisal-2nd-time-pdf.component";
const routes: Routes = [
{path: '', component: Appraisal2ndTimeIndexComponent},
{path: 'list', component: Appraisal2ndTimeIndexComponent},
{path: 'list/:action', component: Appraisal2ndTimeIndexComponent},
{path: 'do/:action', component: Appraisal2ndTimeDoComponent},
{path: 'do/:action/:id', component: Appraisal2ndTimeDoComponent},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
Appraisal2ndTimeIndexComponent,
Appraisal2ndTimeDoComponent,
Appraisal2ndTimeHistoryComponent,
Appraisal2ndTimePdfComponent,
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './appraisal-2nd-time-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class Appraisal2ndTimeModule {}

View File

@@ -1,262 +0,0 @@
<form class="main-form" #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลลูกค้า</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<div class="col-span-4 md:col-span-12 ">
<mat-label>ค้นหาเลขบัตรประชาชน</mat-label>
<ng-select placeholder="ค้นหาเลขบัตรประชาชน" name="filterIdCard" #filterIdCard="ngModel" [(ngModel)]="dataFilter.idCard" (ngModelChange)="onChangeFilter($event)" appendTo="body" >
<ng-option *ngFor="let item of customer" [value]="item.idCard">{{item.idCard}} : {{item.prefix}} {{item.firstName}} {{item.lastName}}</ng-option>
</ng-select>
</div>
<div class="col-span-8 md:hidden"></div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="prefix" #prefix="ngModel" [(ngModel)]="dataForm.customer.prefix" appendTo="body" required>
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="firstName" #firstName="ngModel" [(ngModel)]="dataForm.customer.firstName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="lastName" #lastName="ngModel" [(ngModel)]="dataForm.customer.lastName" >
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<ng-select placeholder="เลือกเพศ" name="gender" #gender="ngModel" [(ngModel)]="dataForm.customer.gender" appendTo="body" >
<ng-option *ngFor="let item of genderData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="phone" #phone="ngModel" [(ngModel)]="dataForm.customer.phone" >
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="idCard" #idCard="ngModel" [(ngModel)]="dataForm.customer.idCard" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<div style="height: 20px;"></div>
<div class="flex items-center">
<div class="">
<input hidden type="file" accept="image/*" #idCardImages (change)="onAttachmentsIdCard($event, 'idcard')" />
<button type="button" class="btn btn-icon-upload color-main" (click)="idCardImages.click()">
<ng-container *ngIf="!dataForm.customer.idCardImage"> <i class="bi bi-plus-circle "></i> สำเนาบัตรประชาชน</ng-container>
<ng-container *ngIf="dataForm.customer.idCardImage"> <i class="bi bi-pencil" matTooltip="แก้ไขสำเนาบัตรประชาชน"></i> </ng-container>
</button>
</div>
<div style="padding-top: 4px;">
<ng-container *ngIf="dataForm.customer.idCardImage">
<div class="cursor-pointer" (click)="onAttachmentsView('images')"><i class="bi bi-search"></i> ดูสำเนาบัตรประชาชน</div></ng-container>
</div>
</div>
</div>
<div class="col-span-8 md:hidden"></div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ตามบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="address" #address="ngModel" [(ngModel)]="dataForm.customer.address" (ngModelChange)="onChangeAddress('address', $event)">
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ในการจัดส่ง</mat-label>
<label class="inline-flex items-center cursor-pointer select-none ml-2">
<input type="checkbox" name="isAddress" [(ngModel)]="dataForm.customer.isAddress" (ngModelChange)="onChangeAddress('isAddress', $event)">
<span style="padding-left: 2px;">ใช้ที่อยู่ตามบัตรประชาชน</span>
</label>
<mat-form-field>
<input matInput name="deliveryAddress" #deliveryAddress="ngModel" [(ngModel)]="dataForm.customer.deliveryAddress" [disabled]="dataForm.customer.isAddress">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>E-mail</mat-label>
<mat-form-field>
<input matInput name="email" #email="ngModel" [(ngModel)]="dataForm.customer.email">
</mat-form-field>
</div>
<div class="col-span-8 md:col-span-12 ">
<mat-label>อาชีพ</mat-label>
<mat-form-field>
<input matInput name="occupation" #occupation="ngModel" [(ngModel)]="dataForm.customer.occupation">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="line" #line="ngModel" [(ngModel)]="dataForm.customer.line">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="facebook" #facebook="ngModel" [(ngModel)]="dataForm.customer.facebook">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="ig" #ig="ngModel" [(ngModel)]="dataForm.customer.ig">
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="text-right mt-4 ">
<mat-checkbox name="depositChecked" #depositChecked="ngModel" [(ngModel)]="dataForm.depositChecked">ชำระเงินเพิ่ม</mat-checkbox>
</div>
<div class="card card-table mb-6">
<div class="card-body">
<div class="table-wrap" >
<table class="tables ">
<thead>
<tr>
<th>BOM</th>
<th>Brand</th>
<th>Model</th>
<th>ราคาสินค้า</th>
<th>จำนวนเงินมัดจำ</th>
<th>ค่ามัดจำเพิ่ม</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">
<mat-form-field>
<input matInput name="productNo" #productNo="ngModel" [(ngModel)]="dataForm.productNo" required>
</mat-form-field>
</td>
<td class="text-center">{{dataForm.productBrandName}}</td>
<td class="text-center">{{dataForm.productName }}</td>
<td class="text-center">{{dataForm.price | number : '1.2-2'}}</td>
<td class="text-center">
<div class="b-color-orange">{{dataForm.deposit | number : '1.2-2'}}</div>
</td>
<td>
<mat-form-field>
<input matInput name="paymentAmount" #paymentAmount="ngModel" [(ngModel)]="dataForm.paymentAmount" [required]="dataForm.depositChecked" [disabled]="!dataForm.depositChecked">
</mat-form-field>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">รูปสินค้าจากลูกค้า</div>
<div class="ml-4">
<input hidden type="file" accept="image/*" #productImages (change)="onAttachments($event, 'products')" />
<button type="button" class="btn btn-sm btn-success-o" (click)="productImages.click()">เพิ่มรูปภาพสินค้า</button>
</div>
</div>
</div>
<div class="card-body">
<div class="list-images">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<ng-container *ngFor="let item of attachments; let i = index">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i *ngIf="dataForm.coverImage !== item" (click)="dataForm.coverImage = item"
matTooltip="ใช้ทำเอกสาร" class="bi bi-star color-main cursor-pointer select-none"></i>
<i *ngIf="dataForm.coverImage === item" class="bi bi bi-star-fill color-main cursor-pointer select-none"></i>
<i (click)="onRemoveAttachments(i, item)" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img src="{{storage.products}}/{{item}}" alt="">
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">อุปกรณ์</div>
</div>
</div>
<div class="card-body">
<ng-container *ngFor="let item of equipmentData; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-1 md:col-span-2 text-right">
<div *ngIf="i === 0" style="height: 25px;"></div>
<input type="checkbox" name="isCheck-{{i}}" #isCheck="ngModel" [(ngModel)]="item.isCheck">
</div>
<div class="col-span-9 md:col-span-8 cursor-pointer select-none" (click)="item.isCheck = !item.isCheck">
<div *ngIf="i === 0" style="height: 25px;"></div>
{{item.name}}
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="isEquipmentOther()">
<ng-container *ngFor="let item of equipmentOtherData; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-1 md:col-span-2 text-right">
</div>
<div class="col-span-9 md:col-span-8 cursor-pointer select-none" >
<mat-form-field>
<input matInput name="equipmentOtherItem-{{i}}" #equipmentOtherItem="ngModel" [(ngModel)]="item.value" >
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-2 " >
<i (click)="onAddEquipmentOther()" class="bi bi-plus-circle color-green cursor-pointer select-none mr-2"></i>
<i (click)="onRemoveEquipmentOther(i)" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
</div>
</div>
</ng-container>
</ng-container>
<div style="height: 40px;"></div>
</div>
</div>
<div class="main-form-action text-right">
<button type="submit" class="btn btn-submit">บันทึก</button>
<button type="button" class="btn btn-back" (click)="onAction('back')">ยกเลิก</button>
</div>
</form>

View File

@@ -1,274 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { API, EAction, EText, GENDER, PREFIX, STORAGE } from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { ActivatedRoute, Router } from "@angular/router";
import { IProduct } from "../../../../app.interface";
import deepCopy from "../../../../@common/utils/DeepCopy";
import { AttachmentsViewComponent } from "../../../@popup/attachments-view/attachments-view.component";
import { MatDialog } from "@angular/material/dialog";
@Component({
selector: "app-appraisal-2nd-time-do",
templateUrl: "./appraisal-2nd-time-do.component.html",
styleUrls: []
})
export class Appraisal2ndTimeDoComponent extends BaseFormComponent implements OnInit {
override dataForm: any = {};
dataView: IProduct = {};
auth: any = {};
title = "";
api: any = API;
storage: any = STORAGE;
addItemNumber: number = 1;
attachments: any = [];
settings: any = [];
IN01: any = {};
IN05: any = {};
prefixData = PREFIX;
genderData = GENDER;
customer : any = [];
equipmentData : any = [];
equipmentOtherData : any = [{value : ''}];
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private attachmentsView: MatDialog,
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
this.action = params["action"];
this.auth = this.appService.auth();
this.dataForm.customer = {};
this.dataForm.sellsr = {};
this.defaultEquipmentData();
this.customer = await lastValueFrom(this.appService.get(`${API.customer}?showAll=true`));
if (this.ids) await this.getData();
});
}
async onAction(action: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.BACK));
if (!sweetalert.isConfirmed) return;
if (action === "back") return this.router.navigate(["/pages/appraisal/2nd-time/list", this.action]);
return;
}
async getData() {
if (!this.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
this.attachments = this.dataForm.images ? this.dataForm.images?.split(",") : [];
this.dataForm.paymentAmount = 0;
this.dataForm.customer = {};
this.dataForm.customer.prefix = this.dataForm.customerPrefix;
this.dataForm.customer.firstName = this.dataForm.customerFirstName;
this.dataForm.customer.lastName = this.dataForm.customerLastName;
this.dataForm.customer.phone = this.dataForm.customerPhone;
if (this.dataForm.customer.isAddress) this.dataForm.customer.deliveryAddress = this.dataForm.customer.address;
if (!this.dataForm.productNo) {
const currentDate = new Date();
let currentMonth: any = new Date().getMonth() + 1;
currentMonth = currentMonth.toString().padStart(2, '0');
let currentYear: any = currentDate.getFullYear() + 543;
currentYear = currentYear.toString().substring(2);
const RUNNING = this.dataForm.id.toString().padStart(6, '0');
this.dataForm.productNo = `${this.dataForm.typeCode}${currentYear}-${currentMonth}-${RUNNING}`;
}
const equipment : any[] = this.dataForm.equipment ? this.dataForm.equipment?.split(",") : [];
const equipmentOther : any[] = this.dataForm.equipmentOther ? this.dataForm.equipmentOther?.split(",") : [];
if (equipment.length) {
this.equipmentData.map((d: any) => {
if (equipment.includes(d.name)) d.isCheck = true;
})
}
if (equipmentOther.length) {
this.equipmentOtherData = [];
equipmentOther.map((d : any) => {
this.equipmentOtherData.push({ value : d});
})
}
this.changeDetectorRef.detectChanges();
} catch (err) {
console.log(err)
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onChangeFilter(value : any) {
if (!value) return await this.getData();
this.dataForm.customer = this.customer.filter((f : any) => f.idCard === value)?.[0];
}
onChangeAddress(key : string, value : any) {
if (key === 'isAddress') this.dataForm.customer.deliveryAddress = value ? this.dataForm.customer.address : '';
if (key === 'address') this.dataForm.customer.deliveryAddress = this.dataForm.customer.isAddress ? value : this.dataForm.customer.deliveryAddress;
}
async onSubmit(form: any) {
if (!form.valid) return false;
if (!this.dataForm.customer.idCardImage) {
return this.appService.message(EAction.ERROR, 'กรุณาอัพโหลดสำเนาบัตรประชาชน');
}
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE));
if (!sweetalert.isConfirmed) return;
const equipment : any[] = [];
this.equipmentData.map((d : any) => {
if (d.isCheck) equipment.push(d.name);
})
this.dataForm.equipment = equipment?.[0] ? equipment.join(",") : null;
this.dataForm.equipmentOther = null;
if (equipment.includes('อื่นๆ')) {
const equipmentOther : any[] = [];
this.equipmentOtherData.map((d : any) => {
equipmentOther.push(d.value);
})
this.dataForm.equipmentOther = equipmentOther?.[0] ? equipmentOther.join(",") : null;
}
this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null;
return await this.onUpdate();
}
async onUpdate() {
try {
await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.UPDATE);
await this.router.navigate(["/pages/appraisal/2nd-time/list", this.action]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachments($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${this.api.attachments}/products`, formData));
if (!this.attachments[0]) {
this.dataForm.coverImage = res.fileName;
}
this.attachments.push(res.fileName);
console.log(this.attachments, res);
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments(i: number, fileName: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.attachments?.splice(i, 1);
if (!this.attachments[0]) {
this.dataForm.coverImage = null;
}
this.changeDetectorRef.detectChanges();
}
async onAttachmentsIdCard($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData));
this.dataForm.customer.idCardImage = res.fileName;
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onAttachmentsView(type : any) {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'สำเนาบัตรประชาชน';
dialogConfig.data.type = type;
dialogConfig.data.images = this.dataForm.customer.idCardImage;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
defaultEquipmentData() {
this.equipmentData = [
{ name : 'ตัวเปล่า', isCheck : false},
{ name : 'ถุงกระดาษ', isCheck : false},
{ name : 'ถุงผ้า', isCheck : false},
{ name : 'ใบเสร็จ', isCheck : false},
{ name : 'บุ๊ค 1', isCheck : false},
{ name : 'บุ๊ค 2', isCheck : false},
{ name : 'ดอกคามิเลีย', isCheck : false},
{ name : 'ริบบิ้น', isCheck : false},
{ name : 'ถุงกันฝน', isCheck : false},
{ name : 'การ์ด', isCheck : false},
{ name : 'สายกระเป๋า', isCheck : false},
{ name : 'ใบเซอร์', isCheck : false},
{ name : 'พวงกุญแจแม่ และลูก', isCheck : false},
{ name : 'กล่อง', isCheck : false},
{ name : 'สายนาฬิกา', isCheck : false},
{ name : 'ใบรับประกัน', isCheck : false},
{ name : 'ใบตรวจ', isCheck : false},
{ name : 'อื่นๆ', isCheck : false},
]
}
isEquipmentOther() {
return this.equipmentData.find((f : any) => f.name === 'อื่นๆ' && f.isCheck === true)
}
onAddEquipmentOther() {
this.equipmentOtherData.push({value : ''});
}
onRemoveEquipmentOther(i : number) {
if (i === 0) return;
this.equipmentOtherData?.splice(i, 1);
this.changeDetectorRef.detectChanges();
}
}

View File

@@ -1,118 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-3 md:col-span-6">
<mat-form-field>
<input
matInput
name="startDate"
#startDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataFilter.createdDate"
[matDatepicker]="dpkName"
readonly
(ngModelChange)="getData()"
/>
<!-- <mat-icon matSuffix (click)="clearDate($event)">clear</mat-icon>-->
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-9 md:col-span-12 ">
<div class="flex w-full ">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="tac">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 200px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item">
<i class="bi bi-filetype-pdf color-main" (click)="onAction(item.id)"></i>
</div>
<div class="item" *ngIf="item.status === 'pending'">
<i class="bi bi-trash3 color-red" (click)="onDelete(item.id)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSourceCount === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,86 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EText } from "../../../../@config/app";
import { Router } from "@angular/router";
@Component({
selector: "app-appraisal-1st-time-index",
templateUrl: "./appraisal-2nd-time-history.component.html",
styleUrls: []
})
export class Appraisal2ndTimeHistoryComponent extends BaseListComponent implements OnInit {
pageTitle = "ประวัติการสร้างใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = ["action", "quotationNo", "customerFirstName", "productNo", "productName", "price", "wantToInstallmentTerm", "createdDate", "status"];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
await this.getData();
}
onAction(id?: any) {
if (id) return this.router.navigate(["/pages/appraisal/1st-time/history/pdf", id]);
return this.router.navigate(["/pages/appraisal/1st-time/do", "create"]);
}
async getData($event?: any) {
try {
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,customerLastName";
const dataSource = await lastValueFrom(this.appService.get(this.setParams(this.apiUrl, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
}

View File

@@ -1,186 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="tabs-btn">
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'wait'}" (click)="onTabs('wait')">รอประเมิน</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'evaluated'}" (click)="onTabs('evaluated')">ประเมินแล้ว</button>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="productBrandName">
<th mat-header-cell *matHeaderCellDef class="tal">Brand</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productBrandName }}</td>
</ng-container>
<ng-container matColumnDef="productSize">
<th mat-header-cell *matHeaderCellDef class="tal">Main</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productSize }}</td>
</ng-container>
<ng-container matColumnDef="productWeight">
<th mat-header-cell *matHeaderCellDef class="tal" >น้ำหนัก</th>
<td mat-cell *matCellDef="let item" class="">{{item.productWeight }}</td>
</ng-container>
<ng-container matColumnDef="productColor">
<th mat-header-cell *matHeaderCellDef class="tal">Color</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productColor }}</td>
</ng-container>
<ng-container matColumnDef="productYear">
<th mat-header-cell *matHeaderCellDef class="tal">Year</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productYear }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="deposit">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงินมัดจำ</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-orange"> {{item.deposit | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="sellerDeposit2ndTime">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>เงินมัดจำเพิ่ม</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-red" *ngIf="item.sellerDeposit2ndTime"> {{item.sellerDeposit2ndTime | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac" style="min-width: 100px;">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.type === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.type === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentType">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentType === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.paymentType === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentMethod">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>วิธีชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.paymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentAmountAll">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-green">{{item.paymentAmountAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item" *ngIf="item.status2ndTime === 'wait' " >
<i class="bi bi-pencil-square icon-edit" (click)="onAction(item.id)"></i>
</div>
<!-- <div class="item" *ngIf="item.status === 'paid' ">-->
<!-- <i class="bi bi-filetype-pdf color-main" (click)="onAction(item.id)"></i>-->
<!-- </div>-->
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSource?.length === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,121 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EStatusQuotation, EText } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-appraisal-2nd-time-index",
templateUrl: "./appraisal-2nd-time-index.component.html",
styleUrls: []
})
export class Appraisal2ndTimeIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "รับชำระเงิน/ออกใบเสร็จรับเงิน";
action = "pending";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = [];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
public activatedRoute: ActivatedRoute,
public changeDetectorRef: ChangeDetectorRef
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.action = params["action"];
this.dataFilter.step = 3;
this.dataFilter.status2ndTime = this.action;
if (!this.action) this.router.navigate(["/pages/appraisal/2nd-time/list", EStatusQuotation.WAIT]);
await this.getData();
});
}
async onTabs(action?: any) {
this.dataFilter = {};
return this.router.navigate(["/pages/appraisal/2nd-time/list", action]);
}
onAction(id?: any) {
if (id) return this.router.navigate([`/pages/appraisal/2nd-time/do/${this.action}`, id]);
return;
}
async getData($event?: any) {
try {
this.dataFilter.keywordColumn = "productNo,productName,quotationNo,price,deposit,sellerDeposit2ndTime";
this.dataSource = [];
let url = API.quotation;
if (this.action === EStatusQuotation.WAIT) {
url = API.quotation;
this.displayedColumns = ["action", "price", "deposit", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor", "productYear"];
}
if (this.action === EStatusQuotation.EVALUATED) {
url = API.quotation;
delete this.dataFilter.step;
this.displayedColumns = ["price", "deposit", "sellerDeposit2ndTime", "quotationNo", "customerFirstName", "productNo", "productName", "status"];
}
const dataSource = await lastValueFrom(this.appService.get(this.setParams(url, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
const url = `${API.quotation}/export-2nd-time?${filter ? '&' + filter : '' }`;
window.open(url);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,94 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { lastValueFrom } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API } from "../../../../@config/app";
import { Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
@Component({
selector: "app-appraisal-1st-time-index",
templateUrl: "./appraisal-2nd-time-pdf.component.html",
styleUrls: []
})
export class Appraisal2ndTimePdfComponent extends BaseListComponent implements OnInit {
pageTitle = "ใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
await this.getData();
}
onAction(id?: any) {
if (id) return this.router.navigate(["/pages/appraisal/1st-time/do", "update", id]);
return this.router.navigate(["/pages/appraisal/1st-time/do", "create"]);
}
async getData($event?: any) {
try {
const data = {
doc_no: "string",
product_code: "string",
customer_name: "string",
phone_no: "string",
installment_start_date: "string",
picture: "string",
price: 0,
seller_deposit: 0,
cmfs_deposit: 0,
total_balance: 0,
installment: 0,
packing: 0,
luxury_handbag_authentication: 0,
bankfee_insurance_storage: 0,
transfer_amount: 0,
data: [
{
due_date: "string",
principle: 0,
interest_total: 0,
bank_fee: 0,
total_payment: 0,
principle_total: 0
}
],
total1: 0,
total2: 0,
total3: 0,
total4: 0
}
this.dataView = await lastValueFrom(this.appService.post(`${this.api.quotationReport}/pdf`, data, { responseType: 'arraybuffer' }));
const url = URL.createObjectURL(new Blob([this.dataView], { type: 'application/pdf' }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,30 +0,0 @@
import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import {Appraisal3rdTimeIndexComponent} from './index/appraisal-3rd-time-index.component';
import {Appraisal3rdTimeDoComponent} from "./do/appraisal-3rd-time-do.component";
import { Appraisal3rdTimeHistoryComponent } from "./history/appraisal-3rd-time-history.component";
import { Appraisal3rdTimePdfComponent } from "./pdf/appraisal-3rd-time-pdf.component";
const routes: Routes = [
{path: '', component: Appraisal3rdTimeIndexComponent},
{path: 'list', component: Appraisal3rdTimeIndexComponent},
{path: 'list/:action', component: Appraisal3rdTimeIndexComponent},
{path: 'do/:action', component: Appraisal3rdTimeDoComponent},
{path: 'do/:action/:id', component: Appraisal3rdTimeDoComponent},
{path: 'history', component: Appraisal3rdTimeHistoryComponent},
{path: 'history/pdf/:id', component: Appraisal3rdTimePdfComponent},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
Appraisal3rdTimeIndexComponent,
Appraisal3rdTimeDoComponent,
Appraisal3rdTimeHistoryComponent,
Appraisal3rdTimePdfComponent,
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './appraisal-3rd-time-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class Appraisal3rdTimeModule {}

View File

@@ -1,401 +0,0 @@
<form class="main-form" #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลลูกค้า</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ค้นหาเลขบัตรประชาชน</mat-label>-->
<!-- <ng-select placeholder="ค้นหาเลขบัตรประชาชน" name="filterIdCard" #filterIdCard="ngModel" [(ngModel)]="dataFilter.idCard" (ngModelChange)="onChangeFilter($event)" appendTo="body" >-->
<!-- <ng-option *ngFor="let item of customer" [value]="item.idCard">{{item.idCard}} : {{item.prefix}} {{item.firstName}} {{item.lastName}}</ng-option>-->
<!-- </ng-select>-->
<!-- </div>-->
<!-- <div class="col-span-8 md:hidden"></div>-->
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="prefix" #prefix="ngModel" [(ngModel)]="dataForm.customer.prefix" appendTo="body" required>
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="firstName" #firstName="ngModel" [(ngModel)]="dataForm.customer.firstName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="lastName" #lastName="ngModel" [(ngModel)]="dataForm.customer.lastName" >
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<ng-select placeholder="เลือกเพศ" name="gender" #gender="ngModel" [(ngModel)]="dataForm.customer.gender" appendTo="body" >
<ng-option *ngFor="let item of genderData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="phone" #phone="ngModel" [(ngModel)]="dataForm.customer.phone" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="idCard" #idCard="ngModel" [(ngModel)]="dataForm.customer.idCard" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<div style="height: 20px;"></div>
<div class="flex items-center">
<div class="">
<input hidden type="file" accept="image/*" #idCardImages (change)="onAttachmentsIdCard($event, 'idcard')" />
<button type="button" class="btn btn-icon-upload color-main" (click)="idCardImages.click()">
<ng-container *ngIf="!dataForm.customer.idCardImage"> <i class="bi bi-plus-circle "></i> สำเนาบัตรประชาชน</ng-container>
<ng-container *ngIf="dataForm.customer.idCardImage"> <i class="bi bi-pencil" matTooltip="แก้ไขสำเนาบัตรประชาชน"></i> </ng-container>
</button>
</div>
<div style="padding-top: 4px;">
<ng-container *ngIf="dataForm.customer.idCardImage">
<div class="cursor-pointer" (click)="onAttachmentsView('images')"><i class="bi bi-search"></i> ดูสำเนาบัตรประชาชน</div>
</ng-container>
</div>
</div>
</div>
<div class="col-span-8 md:hidden"></div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ตามบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="address" #address="ngModel" [(ngModel)]="dataForm.customer.address" (ngModelChange)="onChangeAddress('address', $event)">
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ในการจัดส่ง</mat-label>
<label class="inline-flex items-center cursor-pointer select-none ml-2">
<input type="checkbox" name="isAddress" [(ngModel)]="dataForm.customer.isAddress" (ngModelChange)="onChangeAddress('isAddress', $event)">
<span style="padding-left: 2px;">ใช้ที่อยู่ตามบัตรประชาชน</span>
</label>
<mat-form-field>
<input matInput name="deliveryAddress" #deliveryAddress="ngModel" [(ngModel)]="dataForm.customer.deliveryAddress" [disabled]="dataForm.customer.isAddress">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>E-mail</mat-label>
<mat-form-field>
<input matInput name="email" #email="ngModel" [(ngModel)]="dataForm.customer.email">
</mat-form-field>
</div>
<div class="col-span-8 md:col-span-12 ">
<mat-label>อาชีพ</mat-label>
<mat-form-field>
<input matInput name="occupation" #occupation="ngModel" [(ngModel)]="dataForm.customer.occupation">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="line" #line="ngModel" [(ngModel)]="dataForm.customer.line">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="facebook" #facebook="ngModel" [(ngModel)]="dataForm.customer.facebook">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="ig" #ig="ngModel" [(ngModel)]="dataForm.customer.ig">
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลคนขาย</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-4 md:col-span-12 ">
<mat-label>ค้นหาเลขประจําตัวผู้เสียภาษี</mat-label>
<ng-select placeholder="ค้นหาเลขประจําตัวผู้เสียภาษี" name="filterSeller" #filterSeller="ngModel" [(ngModel)]="dataFilter.filterSeller" (ngModelChange)="onChangeFilter($event)" appendTo="body" >
<ng-option *ngFor="let item of seller" [value]="item.id"> {{item.idCard}} : {{item.prefix}} {{item.firstName}} {{item.lastName}}</ng-option>
</ng-select>
</div>
<div class="col-span-8 md:hidden"></div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="sellerprefix" #sellerprefix="ngModel" [(ngModel)]="dataForm.seller.prefix" appendTo="body" required>
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="sellerfirstName" #sellerfirstName="ngModel" [(ngModel)]="dataForm.seller.firstName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="sellerlastName" #sellerlastName="ngModel" [(ngModel)]="dataForm.seller.lastName" >
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<ng-select placeholder="เลือกเพศ" name="sellergender" #sellergender="ngModel" [(ngModel)]="dataForm.seller.gender" appendTo="body" >
<ng-option *ngFor="let item of genderData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="sellerPhone" #sellerPhone="ngModel" [(ngModel)]="dataForm.seller.phone" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="sellerFacebook" #sellerFacebook="ngModel" [(ngModel)]="dataForm.seller.facebook">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="sellerLine" #sellerLine="ngModel" [(ngModel)]="dataForm.seller.line">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID LINE ร้านค้า</mat-label>
<mat-form-field>
<input matInput name="sellerLineShop" #sellerLineShop="ngModel" [(ngModel)]="dataForm.seller.lineShop">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="sellerIg" #sellerIg="ngModel" [(ngModel)]="dataForm.seller.ig">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>S/N สินค้า</mat-label>
<mat-form-field>
<input matInput name="sellerSnProduct" #sellerSnProduct="ngModel" [(ngModel)]="dataForm.seller.snProduct">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>แหล่งที่มา</mat-label>
<ng-select placeholder="เลือกแหล่งที่มา" name="source" #source="ngModel" [(ngModel)]="dataForm.source" appendTo="body" >
<ng-option *ngFor="let item of sourceData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ค่าขนส่ง</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="shippingCost" #shippingCost="ngModel" [(ngModel)]="dataForm.shippingCost">-->
<!-- </mat-form-field>-->
<!-- </div>-->
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mt-6">
<div class="card-header ">
<div class="grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-6 md:col-span-12">
<div class="flex items-center w-full">
<div class="">รูปแบบการวัด</div>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
</div>
</div>
</div>
<div class="card-body">
<ng-container *ngFor="let item of dataForm.productMeasurement; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-7 md:col-span-11">
<label *ngIf="i === 0">รายการวัด</label>
<mat-form-field>
<input matInput name="productMeasurementName-{{i}}" #productMeasurementName="ngModel" [(ngModel)]="item.name" >
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-6">
<label *ngIf="i === 0">ขนาด</label>
<mat-form-field>
<input appNumberOnly matInput name="productMeasurementSize-{{i}}" #productMeasurementSize="ngModel" [(ngModel)]="item.size" >
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-5">
<label *ngIf="i === 0">หน่วยนับ</label>
<ng-select placeholder="เลือกหน่วยนับ" name="productMeasurementUnit-{{i}}" #productMeasurementUnit="ngModel" [(ngModel)]="item.unitId" appendTo="body" >
<ng-option *ngFor="let item of masterProductUnit" [value]="item.id">{{item.name}}</ng-option>
</ng-select>
</div>
</div>
</div>
</ng-container>
</div>
</div>
<div class="text-right mt-4 ">
<mat-checkbox name="depositChecked" #depositChecked="ngModel" [(ngModel)]="dataForm.depositChecked">ชำระเงินเพิ่ม</mat-checkbox>
</div>
<div class="card card-table mb-6">
<div class="card-body">
<div class="table-wrap">
<table class="tables ">
<thead>
<tr>
<th>BOM</th>
<th>Brand</th>
<th>Model</th>
<th>ราคาสินค้า</th>
<th>จำนวนเงินมัดจำ</th>
<th>ค่ามัดจำเพิ่ม</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">{{dataForm.productNo}}</td>
<td class="text-center">{{dataForm.productBrandName}}</td>
<td class="text-center">{{dataForm.productName }}</td>
<td class="text-center">{{dataForm.price | number : '1.2-2'}}</td>
<td class="text-center">
<div class="b-color-orange">{{dataForm.deposit | number : '1.2-2'}}</div>
</td>
<td>
<mat-form-field>
<input matInput name="paymentAmount" #paymentAmount="ngModel" [(ngModel)]="dataForm.paymentAmount" [required]="dataForm.depositChecked" [disabled]="!dataForm.depositChecked">
</mat-form-field>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">รูปสินค้าจากลูกค้า</div>
<div class="ml-4">
<input hidden type="file" accept="image/*" #productImages (change)="onAttachments($event, 'products')" />
<button type="button" class="btn btn-sm btn-success-o" (click)="productImages.click()">เพิ่มรูปภาพสินค้า</button>
</div>
</div>
</div>
<div class="card-body">
<div class="list-images">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<ng-container *ngFor="let item of attachments; let i = index">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i *ngIf="dataForm.coverImage !== item" (click)="dataForm.coverImage = item"
matTooltip="ใช้ทำเอกสาร" class="bi bi-star color-main cursor-pointer select-none"></i>
<i *ngIf="dataForm.coverImage === item" class="bi bi bi-star-fill color-main cursor-pointer select-none"></i>
<i (click)="onRemoveAttachments(i, item)" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img src="{{storage.products}}/{{item}}" alt="">
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">อุปกรณ์</div>
</div>
</div>
<div class="card-body">
<ng-container *ngFor="let item of equipmentData; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-1 md:col-span-2 text-right">
<div *ngIf="i === 0" style="height: 25px;"></div>
<input type="checkbox" name="isCheck-{{i}}" #isCheck="ngModel" [(ngModel)]="item.isCheck">
</div>
<div class="col-span-9 md:col-span-8 cursor-pointer select-none" (click)="item.isCheck = !item.isCheck">
<div *ngIf="i === 0" style="height: 25px;"></div>
{{item.name}}
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="isEquipmentOther()">
<ng-container *ngFor="let item of equipmentOtherData; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-1 md:col-span-2 text-right">
</div>
<div class="col-span-9 md:col-span-8 cursor-pointer select-none" >
<mat-form-field>
<input matInput name="equipmentOtherItem-{{i}}" #equipmentOtherItem="ngModel" [(ngModel)]="item.value" >
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-2 " >
<i (click)="onAddEquipmentOther()" class="bi bi-plus-circle color-green cursor-pointer select-none mr-2"></i>
<i (click)="onRemoveEquipmentOther(i)" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
</div>
</div>
</ng-container>
</ng-container>
<div style="height: 40px;"></div>
</div>
</div>
<div class="main-form-action text-right" *ngIf="dataForm.status3rdTime !== 'complete' ">
<button type="submit" class="btn btn-submit">บันทึก</button>
<button type="button" class="btn btn-back" (click)="onAction('back')">ยกเลิก</button>
</div>
</form>

View File

@@ -1,283 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import {API, EAction, EText, GENDER, PREFIX, SOURCES, STORAGE} from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { ActivatedRoute, Router } from "@angular/router";
import { IProduct } from "../../../../app.interface";
import deepCopy from "../../../../@common/utils/DeepCopy";
import { AttachmentsViewComponent } from "../../../@popup/attachments-view/attachments-view.component";
import { MatDialog } from "@angular/material/dialog";
@Component({
selector: "app-appraisal-3rd-time-do",
templateUrl: "./appraisal-3rd-time-do.component.html",
styleUrls: []
})
export class Appraisal3rdTimeDoComponent extends BaseFormComponent implements OnInit {
override dataForm: any = {};
dataView: IProduct = {};
auth: any = {};
title = "";
api: any = API;
storage: any = STORAGE;
attachments: any = [];
settings: any = [];
masterProductUnit: any = [];
deviation: any = 0;
prefixData = PREFIX;
genderData = GENDER;
sourceData = SOURCES;
customer : any = [];
seller : any = [];
equipmentData : any = [];
equipmentOtherData : any = [{value : ''}];
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private attachmentsView: MatDialog,
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
this.action = params["action"];
this.auth = this.appService.auth();
this.dataForm.customer = {};
this.dataForm.seller = {};
this.defaultEquipmentData();
this.settings = await lastValueFrom(this.appService.get(`${this.api.settings}/getByCode/DEVIATION`));
this.masterProductUnit = await lastValueFrom(this.appService.get(`${this.api.masterProductUnit}?showAll=true&status=true&orderBy=name&sort=asc`));
this.customer = await lastValueFrom(this.appService.get(`${API.customer}?showAll=true`));
this.seller = await lastValueFrom(this.appService.get(`${API.customer}?showAll=true`));
if (this.ids) await this.getData();
});
}
async onAction(action: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.BACK));
if (!sweetalert.isConfirmed) return;
if (action === "back") return this.router.navigate(["/pages/appraisal/3rd-time/list", this.action]);
return;
}
async getData() {
if (!this.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
this.attachments = this.dataForm.images ? this.dataForm.images?.split(",") : [];
this.dataForm.productMeasurement.map((item : any) => {
item.sizeOld = item.size;
item.size = this.dataForm.status3rdTime === 'wait' ? null : item.size;
})
this.dataForm.deposit = Number(this.dataForm.deposit) + Number(this.dataForm.sellerDeposit2ndTime)
if (this.dataForm.customer.isAddress) this.dataForm.customer.deliveryAddress = this.dataForm.customer.address;
if(!this.dataForm.sellerId) {
this.dataForm.seller = {};
this.dataForm.seller.name = this.dataForm.sellerName;
this.dataForm.seller.phone = this.dataForm.sellerPhone;
this.dataForm.seller.facebook = this.dataForm.sellerFacebook;
this.dataForm.seller.line = this.dataForm.sellerLine;
this.dataForm.seller.lineShop = this.dataForm.sellerLineShop;
this.dataForm.seller.ig = this.dataForm.sellerIg;
this.dataForm.seller.snProduct = this.dataForm.sellerSnProduct;
}
const equipment : any[] = this.dataForm.equipment ? this.dataForm.equipment?.split(",") : [];
const equipmentOther : any[] = this.dataForm.equipmentOther ? this.dataForm.equipmentOther?.split(",") : [];
if (equipment.length) {
this.equipmentData.map((d: any) => {
if (equipment.includes(d.name)) d.isCheck = true;
})
}
if (equipmentOther.length) {
this.equipmentOtherData = [];
equipmentOther.map((d : any) => {
this.equipmentOtherData.push({ value : d});
})
}
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onChangeFilter(value : any) {
if (!value) return await this.getData();
this.dataForm.seller = this.seller.filter((f : any) => f.id === value)?.[0];
}
onChangeAddress(key : string, value : any) {
if (key === 'isAddress') this.dataForm.customer.deliveryAddress = value ? this.dataForm.customer.address : '';
if (key === 'address') this.dataForm.customer.deliveryAddress = this.dataForm.customer.isAddress ? value : this.dataForm.customer.deliveryAddress;
}
async onSubmit(form: any) {
if (!form.valid) return false;
const error : any[] = [];
this.dataForm.productMeasurement.map((item : any) => {
if (!item.size) return;
const deviation = (Number(this.settings.value) / 100) * Number(item.sizeOld);
const deviationSize = Number(item.sizeOld) + deviation;
console.log(deviationSize);
if (Number(item.size) > deviationSize) {
const msg = `${item.name} ขนาดมากกว่าค่าเบี่ยงเบนการวัด (${deviationSize})`;
error.push(msg)
}
})
if (error.length > 0) {
const msg = error.join("<br>");
return this.appService.html(EAction.INFO, msg);
}
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE));
if (!sweetalert.isConfirmed) return;
const equipment : any[] = [];
this.equipmentData.map((d : any) => {
if (d.isCheck) equipment.push(d.name);
})
this.dataForm.equipment = equipment?.[0] ? equipment.join(",") : null;
this.dataForm.equipmentOther = null;
if (equipment.includes('อื่นๆ')) {
const equipmentOther : any[] = [];
this.equipmentOtherData.map((d : any) => {
equipmentOther.push(d.value);
})
this.dataForm.equipmentOther = equipmentOther?.[0] ? equipmentOther.join(",") : null;
}
this.dataForm.pageAction = '3rd-time';
this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null;
return await this.onUpdate();
}
async onUpdate() {
try {
await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.UPDATE);
await this.router.navigate(["/pages/appraisal/3rd-time/list", this.action]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachments($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${this.api.attachments}/products`, formData));
if (!this.attachments[0]) {
this.dataForm.coverImage = res.fileName;
}
this.attachments.push(res.fileName);
console.log(this.attachments, res);
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments(i: number, fileName: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.attachments?.splice(i, 1);
if (!this.attachments[0]) {
this.dataForm.coverImage = null;
}
this.changeDetectorRef.detectChanges();
}
async onAttachmentsIdCard($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData));
this.dataForm.customer.idCardImage = res.fileName;
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onAttachmentsView(type : any) {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'สำเนาบัตรประชาชน';
dialogConfig.data.type = type;
dialogConfig.data.images = this.dataForm.customer.idCardImage;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
defaultEquipmentData() {
this.equipmentData = [
{ name : 'ตัวเปล่า', isCheck : false},
{ name : 'ถุงกระดาษ', isCheck : false},
{ name : 'ถุงผ้า', isCheck : false},
{ name : 'ใบเสร็จ', isCheck : false},
{ name : 'บุ๊ค 1', isCheck : false},
{ name : 'บุ๊ค 2', isCheck : false},
{ name : 'ดอกคามิเลีย', isCheck : false},
{ name : 'ริบบิ้น', isCheck : false},
{ name : 'ถุงกันฝน', isCheck : false},
{ name : 'การ์ด', isCheck : false},
{ name : 'สายกระเป๋า', isCheck : false},
{ name : 'ใบเซอร์', isCheck : false},
{ name : 'พวงกุญแจแม่ และลูก', isCheck : false},
{ name : 'กล่อง', isCheck : false},
{ name : 'สายนาฬิกา', isCheck : false},
{ name : 'ใบรับประกัน', isCheck : false},
{ name : 'ใบตรวจ', isCheck : false},
{ name : 'อื่นๆ', isCheck : false},
]
}
isEquipmentOther() {
return this.equipmentData.find((f : any) => f.name === 'อื่นๆ' && f.isCheck === true)
}
onAddEquipmentOther() {
this.equipmentOtherData.push({value : ''});
}
onRemoveEquipmentOther(i : number) {
if (i === 0) return;
this.equipmentOtherData?.splice(i, 1);
this.changeDetectorRef.detectChanges();
}
}

View File

@@ -1,118 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-3 md:col-span-6">
<mat-form-field>
<input
matInput
name="startDate"
#startDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataFilter.createdDate"
[matDatepicker]="dpkName"
readonly
(ngModelChange)="getData()"
/>
<!-- <mat-icon matSuffix (click)="clearDate($event)">clear</mat-icon>-->
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-9 md:col-span-12 ">
<div class="flex w-full ">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="tac">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 200px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item">
<i class="bi bi-filetype-pdf color-main" (click)="onAction(item.id)"></i>
</div>
<div class="item" *ngIf="item.status === 'pending'">
<i class="bi bi-trash3 color-red" (click)="onDelete(item.id)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSourceCount === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,86 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EText } from "../../../../@config/app";
import { Router } from "@angular/router";
@Component({
selector: "app-appraisal-1st-time-index",
templateUrl: "./appraisal-3rd-time-history.component.html",
styleUrls: []
})
export class Appraisal3rdTimeHistoryComponent extends BaseListComponent implements OnInit {
pageTitle = "ประวัติการสร้างใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = ["action", "quotationNo", "customerFirstName", "productNo", "productName", "price", "wantToInstallmentTerm", "createdDate", "status"];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
await this.getData();
}
onAction(id?: any) {
if (id) return this.router.navigate(["/pages/appraisal/1st-time/history/pdf", id]);
return this.router.navigate(["/pages/appraisal/1st-time/do", "create"]);
}
async getData($event?: any) {
try {
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,customerLastName";
const dataSource = await lastValueFrom(this.appService.get(this.setParams(this.apiUrl, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
}

View File

@@ -1,187 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="tabs-btn">
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'wait'}" (click)="onTabs('wait')">รอประเมิน</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'evaluated'}" (click)="onTabs('evaluated')">ประเมินแล้ว</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'complete'}" (click)="onTabs('complete')">ข้อมูลครบถ้วน</button>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="productBrandName">
<th mat-header-cell *matHeaderCellDef class="tal">Brand</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productBrandName }}</td>
</ng-container>
<ng-container matColumnDef="productSize">
<th mat-header-cell *matHeaderCellDef class="tal">Main</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productSize }}</td>
</ng-container>
<ng-container matColumnDef="productWeight">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">น้ำหนัก</th>
<td mat-cell *matCellDef="let item" class="">{{item.productWeight }}</td>
</ng-container>
<ng-container matColumnDef="productColor">
<th mat-header-cell *matHeaderCellDef class="tal">Color</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productColor }}</td>
</ng-container>
<ng-container matColumnDef="productYear">
<th mat-header-cell *matHeaderCellDef class="tal">Year</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productYear }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="deposit">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนมัดจำ</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-orange"> {{item.deposit | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac" style="min-width: 100px;">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.type === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.type === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentType">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentType === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.paymentType === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentMethod">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>วิธีชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.paymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentAmountAll">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-green">{{item.paymentAmountAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="sellerDeposit3rdTime">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>เงินมัดจำเพิ่ม</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-red" *ngIf="item.sellerDeposit3rdTime">{{item.sellerDeposit3rdTime | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item" *ngIf="['wait','evaluated'].includes(item.status3rdTime)" >
<i class="bi bi-pencil-square icon-edit" (click)="onAction(item.id)"></i>
</div>
<div class="item" *ngIf="['complete'].includes(item.status3rdTime)" >
<i class="bi bi-eye color-green" (click)="onAction(item.id)"></i>
</div>
<!-- <div class="item" *ngIf="item.status === 'paid' ">-->
<!-- <i class="bi bi-filetype-pdf color-main" (click)="onAction(item.id)"></i>-->
<!-- </div>-->
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSource?.length === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,132 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EStatusQuotation, EText } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-appraisal-3rd-time-index",
templateUrl: "./appraisal-3rd-time-index.component.html",
styleUrls: []
})
export class Appraisal3rdTimeIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "รับชำระเงิน/ออกใบเสร็จรับเงิน";
action = "pending";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = [];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
public activatedRoute: ActivatedRoute,
public changeDetectorRef: ChangeDetectorRef
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.action = params["action"];
this.dataFilter.step = 4;
this.dataFilter.status3rdTime = this.action;
if (!this.action) this.router.navigate(["/pages/appraisal/3rd-time/list", EStatusQuotation.WAIT]);
await this.getData();
});
}
async onTabs(action?: any) {
this.dataFilter = {};
return this.router.navigate(["/pages/appraisal/3rd-time/list", action]);
}
onAction(id?: any) {
if (id) return this.router.navigate([`/pages/appraisal/3rd-time/do/${this.action}`, id]);
return;
}
async getData($event?: any) {
try {
this.dataFilter.keywordColumn = "productNo,productName,quotationNo,price,deposit,sellerDeposit3rdTime";
this.dataSource = [];
let url = API.quotation;
if (this.action === EStatusQuotation.WAIT) {
url = API.quotation;
this.displayedColumns = ["action", "price", "deposit", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor", "productYear"];
}
if (this.action === EStatusQuotation.EVALUATED) {
url = API.quotation;
delete this.dataFilter.step;
this.displayedColumns = ["action", "price", "deposit", "sellerDeposit3rdTime", "quotationNo", "customerFirstName", "productNo", "productName", "status"];
}
if (this.action === EStatusQuotation.COMPLETE) {
url = API.quotation;
delete this.dataFilter.step;
this.displayedColumns = ["action", "price", "deposit", "sellerDeposit3rdTime", "quotationNo", "customerFirstName", "productNo", "productName", "status"];
}
const dataSource = await lastValueFrom(this.appService.get(this.setParams(url, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
if (this.action === EStatusQuotation.WAIT) {
this.dataSource.map((item: any) => {
item.deposit = Number(item.deposit) + Number(item.sellerDeposit2ndTime)
})
}
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
const url = `${API.quotation}/export-3rd-time?${filter ? '&' + filter : '' }`;
window.open(url);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,94 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { lastValueFrom } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API } from "../../../../@config/app";
import { Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
@Component({
selector: "app-appraisal-1st-time-index",
templateUrl: "./appraisal-3rd-time-pdf.component.html",
styleUrls: []
})
export class Appraisal3rdTimePdfComponent extends BaseListComponent implements OnInit {
pageTitle = "ใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
await this.getData();
}
onAction(id?: any) {
if (id) return this.router.navigate(["/pages/appraisal/1st-time/do", "update", id]);
return this.router.navigate(["/pages/appraisal/1st-time/do", "create"]);
}
async getData($event?: any) {
try {
const data = {
doc_no: "string",
product_code: "string",
customer_name: "string",
phone_no: "string",
installment_start_date: "string",
picture: "string",
price: 0,
seller_deposit: 0,
cmfs_deposit: 0,
total_balance: 0,
installment: 0,
packing: 0,
luxury_handbag_authentication: 0,
bankfee_insurance_storage: 0,
transfer_amount: 0,
data: [
{
due_date: "string",
principle: 0,
interest_total: 0,
bank_fee: 0,
total_payment: 0,
principle_total: 0
}
],
total1: 0,
total2: 0,
total3: 0,
total4: 0
}
this.dataView = await lastValueFrom(this.appService.post(`${this.api.quotationReport}/pdf`, data, { responseType: 'arraybuffer' }));
const url = URL.createObjectURL(new Blob([this.dataView], { type: 'application/pdf' }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,28 +0,0 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { ContractApprovedIndexComponent } from "./index/contract-approved-index.component";
import { ContractApprovedDoComponent } from "./do/contract-approved-do.component";
import { ContractApprovedPdfComponent } from "./pdf/contract-approved-pdf.component";
const routes: Routes = [
{ path: "", component: ContractApprovedIndexComponent },
{ path: "list", component: ContractApprovedIndexComponent },
{ path: "list/:action", component: ContractApprovedIndexComponent },
{ path: "do/:action", component: ContractApprovedDoComponent },
{ path: "do/:action/:id", component: ContractApprovedDoComponent },
{ path: "pdf/:action/:id", component: ContractApprovedPdfComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
ContractApprovedIndexComponent,
ContractApprovedDoComponent,
ContractApprovedPdfComponent
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './contract-approved-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class ContractApprovedModule {}

View File

@@ -1,694 +0,0 @@
<ul class="progressbar">
<li [ngClass]="{ 'active' : isTabs === 1}" (click)="isTabs = 1">รายละเอียดหลัก</li>
<li [ngClass]="{ 'active' : isTabs === 2}" (click)="isTabs = 2">การจัดผ่อน</li>
<li [ngClass]="{ 'active' : isTabs === 3}" (click)="isTabs = 3">ข้อมูลรับชำระเงิน</li>
</ul>
<form class="main-form" #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<ng-container *ngIf="isTabs === 1">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> สัญญาเงินกู้ระหว่าง CM-FS. Co., Ltd. ("บริษัทฯ") กับ</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่สัญญา/BOM</mat-label>
<mat-form-field>
<input matInput name="productNo" #productNo="ngModel" [(ngModel)]="dataForm.productNo" disabled >
</mat-form-field>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ชื่อลูกค้า</mat-label>-->
<!-- <mat-form-field>-->
<!-- <div class="flex">-->
<!-- <input style="width: 75px; padding-right: 0 !important;" matInput name="customerPrefix" #customerPrefix="ngModel" [(ngModel)]="dataForm.customer.prefix" disabled>-->
<!-- <input style="padding-left: 0 !important;" matInput name="customerFirstName" #customerFirstName="ngModel" [(ngModel)]="dataForm.customer.firstName" disabled>-->
<!-- </div>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>นามสกุล</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="customerLastName" #customerLastName="ngModel" [(ngModel)]="dataForm.customer.lastName" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>เบอร์โทร</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="customerPhone" #customerPhone="ngModel" [(ngModel)]="dataForm.customer.phone" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>เลขบัตรประชาชน</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="customerIdCard" #customerIdCard="ngModel" [(ngModel)]="dataForm.customer.idCard" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<div class="col-span-4 md:col-span-12 ">
<mat-label>วันที่ทำสัญญา</mat-label>
<mat-form-field>
<input
matInput
name="contractDate"
#contractDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.contractDate"
[matDatepicker]="dpkName"
readonly
disabled
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="prefix" #prefix="ngModel" [(ngModel)]="dataForm.customer.prefix" appendTo="body" disabled>
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="firstName" #firstName="ngModel" [(ngModel)]="dataForm.customer.firstName" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="lastName" #lastName="ngModel" [(ngModel)]="dataForm.customer.lastName" disabled>
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<ng-select placeholder="" name="gender" #gender="ngModel" [(ngModel)]="dataForm.customer.gender" appendTo="body" disabled>
<ng-option *ngFor="let item of genderData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="phone" #phone="ngModel" [(ngModel)]="dataForm.customer.phone" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="idCard" #idCard="ngModel" [(ngModel)]="dataForm.customer.idCard" disabled>
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ตามบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="address" #address="ngModel" [(ngModel)]="dataForm.customer.address" disabled>
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ในการจัดส่ง</mat-label>
<label class="inline-flex items-center cursor-pointer select-none ml-2">
<input type="checkbox" name="isAddress" [(ngModel)]="dataForm.customer.isAddress" disabled>
<span style="padding-left: 2px;">ใช้ที่อยู่ตามบัตรประชาชน</span>
</label>
<mat-form-field>
<input matInput name="deliveryAddress" #deliveryAddress="ngModel" [(ngModel)]="dataForm.customer.deliveryAddress" [disabled]="dataForm.customer.isAddress" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>E-mail</mat-label>
<mat-form-field>
<input matInput name="email" #email="ngModel" [(ngModel)]="dataForm.customer.email" disabled>
</mat-form-field>
</div>
<div class="col-span-8 md:col-span-12 ">
<mat-label>อาชีพ</mat-label>
<mat-form-field>
<input matInput name="occupation" #occupation="ngModel" [(ngModel)]="dataForm.customer.occupation" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="line" #line="ngModel" [(ngModel)]="dataForm.customer.line" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="facebook" #facebook="ngModel" [(ngModel)]="dataForm.customer.facebook" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="ig" #ig="ngModel" [(ngModel)]="dataForm.customer.ig" disabled>
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลร้านค้า</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="sellerprefix" #sellerprefix="ngModel" [(ngModel)]="dataForm.seller.prefix" appendTo="body" disabled>
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="sellerfirstName" #sellerfirstName="ngModel" [(ngModel)]="dataForm.seller.firstName" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="sellerlastName" #sellerlastName="ngModel" [(ngModel)]="dataForm.seller.lastName" disabled>
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<ng-select placeholder="" name="sellergender" #sellergender="ngModel" [(ngModel)]="dataForm.seller.gender" appendTo="body" disabled>
<ng-option *ngFor="let item of genderData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="sellerPhone" #sellerPhone="ngModel" [(ngModel)]="dataForm.seller.phone" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="sellerFacebook" #sellerFacebook="ngModel" [(ngModel)]="dataForm.seller.facebook" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="sellerLine" #sellerLine="ngModel" [(ngModel)]="dataForm.seller.line" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID LINE ร้านค้า</mat-label>
<mat-form-field>
<input matInput name="sellerLineShop" #sellerLineShop="ngModel" [(ngModel)]="dataForm.seller.lineShop" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="sellerIg" #sellerIg="ngModel" [(ngModel)]="dataForm.seller.ig" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>S/N สินค้า</mat-label>
<mat-form-field>
<input matInput name="sellerSnProduct" #sellerSnProduct="ngModel" [(ngModel)]="dataForm.seller.snProduct" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>แหล่งที่มา</mat-label>
<mat-form-field>
<input matInput name="source" #source="ngModel" [(ngModel)]="dataForm.source" disabled>
</mat-form-field>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ค่าขนส่ง</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="shippingCost" #shippingCost="ngModel" [(ngModel)]="dataForm.shippingCost" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
</div>
</div>
</div>
<div class="card card-table card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลสินค้า</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mb-2">
<div class="col-span-3 md:col-span-12 ">
<mat-label>Condition</mat-label>
<ng-select placeholder="Condition" name="condition" #condition="ngModel" [(ngModel)]="dataForm.productCondition" disabled>
<ng-option *ngFor="let item of conditions" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>Year</mat-label>
<mat-form-field>
<input appNumberOnly matInput name="year" #year="ngModel" [(ngModel)]="dataForm.productYear" disabled>
</mat-form-field>
</div>
</div>
<div class="table-wrap">
<table class="tables ">
<thead>
<tr>
<th>BOM</th>
<th>Model</th>
<th>Brand</th>
<th>Main</th>
<th>น้ำหนัก</th>
<th>Color</th>
<th>Year</th>
<th>ราคาสินค้า</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">{{dataForm.productNo}}</td>
<td class="text-center">{{dataForm.productName }}</td>
<td class="text-center">{{dataForm.productBrandName}}</td>
<td class="text-center">{{dataForm.productSize }}</td>
<td class="text-center">{{dataForm.productWeight }}</td>
<td class="text-center">{{dataForm.productColor }}</td>
<td class="text-center">{{dataForm.productYear }}</td>
<td class="text-center"> <div class="b-color-orange">{{dataForm.price | number : '1.2-2'}}</div></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">รูปสินค้าจากลูกค้า</div>
</div>
</div>
<div class="card-body">
<div class="list-images">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<ng-container *ngFor="let item of attachments; let i = index">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i *ngIf="dataForm.coverImage !== item" class="bi bi-star color-main cursor-pointer select-none"></i>
<i *ngIf="dataForm.coverImage === item" class="bi bi bi-star-fill color-main cursor-pointer select-none"></i>
</div>
<img src="{{storage.products}}/{{item}}" alt="">
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">อุปกรณ์</div>
</div>
</div>
<div class="card-body">
<ng-container *ngFor="let item of equipment; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-9 md:col-span-8 " >{{item}}</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="equipment.includes('อื่นๆ')">
<ng-container *ngFor="let item of equipmentOther; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-9 md:col-span-8 " >{{item}}</div>
</div>
</div>
</ng-container>
</ng-container>
<div style="height: 20px;"></div>
</div>
</div>
</ng-container>
<ng-container *ngIf="isTabs === 2">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลการจัดผ่อน</div>
</div>
<div class="card-body form-input-list">
<div style="height: 20px;"></div>
<div class="grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> วันที่เริ่มจัดผ่อน</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input
matInput
name="startDate"
#startDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.startDate"
[matDatepicker]="dpkName"
readonly
disabled
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit"></div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ราคา (Price)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="price" #price="ngModel" [(ngModel)]="dataForm.price" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำแม่ค้า</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="sellerDeposit" #sellerDeposit="ngModel" [(ngModel)]="dataForm.sellerDeposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำ CMFS</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="deposit" #deposit="ngModel" [(ngModel)]="dataForm.deposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> เงินต้นคงเหลือ (Total)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="principalBalanceTotal" #principalBalanceTotal="ngModel" [(ngModel)]="dataForm.principalBalanceTotal" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ต้องการผ่อน (Term)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput type="number" name="wantToInstallmentTerm" #wantToInstallmentTerm="ngModel" [(ngModel)]="dataForm.wantToInstallmentTerm" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">งวด</div>
</div>
</div>
<div style="height: 20px;"></div>
</div>
</div>
</div>
<div class="col-span-6 md:col-span-12">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> รายละเอียดค่าใช้จ่ายในการโอนเงิน</div>
</div>
<div class="card-body form-input-list">
<div style="height: 20px;"></div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำ CMFS Deposit</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="cmfsDeposit" #cmfsDeposit="ngModel" [(ngModel)]="dataForm.cmfsDeposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> หัก เงินมัดจำแม่ค้า </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="lessSellerDeposit" #lessSellerDeposit="ngModel" [(ngModel)]="dataForm.lessSellerDeposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Packing </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusPacking" #plusPacking="ngModel" [(ngModel)]="dataForm.plusPacking" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Luxury handbag </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusLuxuryHandbag" #plusLuxuryHandbag="ngModel" [(ngModel)]="dataForm.plusLuxuryHandbag" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Bank fee, Insurance , Storage</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusBankFee" #plusBankFee="ngModel" [(ngModel)]="dataForm.plusBankFee" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ส่วนลด </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="discount" #discount="ngModel" [(ngModel)]="dataForm.discount" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> สรุปยอดโอน </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="transferSummary" #transferSummary="ngModel" [(ngModel)]="dataForm.transferSummary" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div style="height: 10px;"></div>
</div>
</div>
</div>
</div>
<div class="card card-table mb-6">
<div class="card-body">
<div class="table-wrap" *ngIf="dataForm.quotationDetail?.[0]">
<table class="tables">
<thead>
<tr>
<th>งวดที่</th>
<th>กำหนดจ่ายวันที่ <br>Due date</th>
<th>เงินต้น <br>Principle</th>
<th>ดอกเบี้ย(บาท) <br>Interest Total</th>
<th>Bank fee, <br>Insurance ,Storage</th>
<th>รวมยอดจ่ายต่อเดือน <br>Total payment</th>
<th>เงินต้นคงเหลือ <br>Principle Total</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let item of dataForm.quotationDetail; let i = index">
<tr>
<td class="text-center">{{item.installment }}</td>
<td class="text-center">{{item.dueDate | date : 'dd/MM/YYYY'}}</td>
<td class="text-center">{{item.principle | number : '1.0-0'}}</td>
<td class="text-center">{{item.interestTotal | number : '1.0-0'}}</td>
<td class="text-center">{{item.fee | number : '1.0-0'}}</td>
<td class="text-center"><span class="b-color-green">{{item.totalPayment | number : '1.0-0'}}</span></td>
<td class="text-center"><span class="b-color-orange" *ngIf="item.principleTotal">{{item.principleTotal | number : '1.0-0'}}</span></td>
</tr>
</ng-container>
<tr>
<td colspan="2" class="text-right"><b>รวม</b></td>
<td class="text-center">{{dataForm.principleSum | number : '1.0-0'}}</td>
<td class="text-center">{{dataForm.interestTotalSum | number : '1.0-0'}}</td>
<td class="text-center">{{dataForm.feeSum | number : '1.0-0'}}</td>
<td class="text-center"><span class="b-color-green">{{dataForm.totalPaymentSum | number : '1.0-0'}}</span></td>
<td class="text-center"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="isTabs === 3">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลธนาคารที่รับชำระเงิน</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-8 md:col-span-12 ">
<mat-label>ชื่อธนาคาร</mat-label>
<mat-form-field>
<input matInput name="productNo" #productNo="ngModel" [(ngModel)]="dataForm.contractBankName" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อบัญชี</mat-label>
<mat-form-field>
<input matInput name="contractAccountName" #contractAccountName="ngModel" [(ngModel)]="dataForm.contractAccountName" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่บัญชี</mat-label>
<mat-form-field>
<input matInput name="contractAccountNumber" #contractAccountNumber="ngModel" [(ngModel)]="dataForm.contractAccountNumber" disabled>
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> รายละเอียดท้ายสัญญา</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-12 md:col-span-12 ">
<mat-form-field>
<textarea matInput [(ngModel)]="dataForm.contractDetail" name="contractDetail" #contractDetail="ngModel" placeholder="" disabled></textarea>
</mat-form-field>
</div>
</div>
</div>
</div>
</ng-container>
<div class="main-form-action text-right">
<ng-container *ngIf="dataForm.statusContract === 'pending' ">
<button type="button" class="btn btn-red" (click)="onSubmitCancel(ngf)">ไม่อนุมัติ</button>
<button type="submit" class="btn btn-submit">อนุมัติ</button>
</ng-container>
<button type="button" class="btn btn-back" (click)="onAction('back')">ยกเลิก</button>
</div>
</form>

View File

@@ -1,187 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import {API, CONDITIONS, EAction, EText, GENDER, PREFIX, SOURCES, STORAGE} from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { ActivatedRoute, Router } from "@angular/router";
import { IProduct } from "../../../../app.interface";
import {sortByProperty} from "../../../../@common/utils/OrderBy";
import {C} from "@angular/cdk/keycodes";
@Component({
selector: "app-appraisal-3rd-time-do",
templateUrl: "./contract-approved-do.component.html",
styleUrls: []
})
export class ContractApprovedDoComponent extends BaseFormComponent implements OnInit {
override dataForm: any = {};
dataView: IProduct = {};
auth: any = {};
title = "";
api: any = API;
storage: any = STORAGE;
attachments: any = [];
equipment: any = [];
equipmentOther: any = [];
settings: any = [];
masterProductUnit: any = [];
deviation: any = 0;
isTabs: any = 1;
prefixData = PREFIX;
genderData = GENDER;
conditions = CONDITIONS;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
this.action = params["action"];
this.auth = this.appService.auth();
this.dataForm.customer = {};
this.dataForm.sellsr = {};
if (this.ids) await this.getData();
});
}
async onAction(action: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.BACK));
if (!sweetalert.isConfirmed) return;
if (action === "back") return this.router.navigate(["/pages/contract/approved/list", this.action]);
return;
}
async getData() {
if (!this.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
this.attachments = this.dataForm.images ? this.dataForm.images?.split(",") : [];
this.equipment = this.dataForm.equipment ? this.dataForm.equipment?.split(",") : [];
this.equipmentOther = this.dataForm.equipmentOther ? this.dataForm.equipmentOther?.split(",") : [];
this.dataForm.deposit = Number(this.dataForm.deposit) + Number(this.dataForm.sellerDeposit2ndTime) + Number(this.dataForm.sellerDeposit3rdTime);
if (!this.dataForm.customerId) {
this.dataForm.customer = {};
this.dataForm.customer.prefix = this.dataForm.customerPrefix;
this.dataForm.customer.firstName = this.dataForm.customerFirstName;
this.dataForm.customer.lastName = this.dataForm.customerLastName;
this.dataForm.customer.phone = this.dataForm.customerPhone;
}
sortByProperty(this.dataForm.quotationDetail, 'installment', 'ASC');
this.dataForm.principleSum = 0
this.dataForm.interestTotalSum = 0
this.dataForm.feeSum = 0
this.dataForm.feeSum = 0
this.dataForm.totalPaymentSum = 0
this.dataForm.quotationDetail.map((item : any) => {
this.dataForm.principleSum += Number(item.principle)
this.dataForm.interestTotalSum += Number(item.interestTotal)
this.dataForm.feeSum += Number(item.fee)
this.dataForm.totalPaymentSum += Number(item.totalPayment)
})
this.dataForm.principleSum = Math.round(this.dataForm.principleSum);
this.dataForm.contractBankName = 'ธนาคารทหารไทยธนชาต จำกัด (มหาชน)';
this.dataForm.contractAccountName = 'บริษัท ซีเอ็ม เอฟเอส จำกัด';
this.dataForm.contractAccountNumber = '263-2-17778-4';
this.dataForm.contractDetail = 'ชำระเงินงวดอย่างน้อย ทุกเดือนตามวันและยอดขั้นต่ำตามตาราง โดยที่ไม่เสียค่าปรับ ทั้งนี้หากเกินกำหนด ผู้กู้ต้องเสียค่าดอกเบี้ยผิดนัดเพิ่มเติมวันละ 1,000 บาท (ไม่รวมค่าทวงถาม) หากขาดส่งเกินกว่า 60 วัน นับแต่วันผ่อนล่าสุดจะถือว่าผิดสัญญา โดยหากผู้กู้ติดสัญญาไม่ว่ากรณีใดๆ ผู้กู้ยินดีที่จะนำสังหาริมทรัพย์ที่ผู้กู้นำเงินที่กู้ไปซื้อเป็นค่าตอบแทนในการชำระหนี้สินส่วนที่เหลือโดยทันที';
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onSubmitCancel(form: any) {
this.dataForm.isStatusContract = 'cancel';
await this.onSubmit(form)
}
async onSubmit(form: any) {
try {
// console.log(form);
// if (!form.valid) return false;
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE));
if (!sweetalert.isConfirmed) return;
if (this.dataForm.isStatusContract) {
this.dataForm.statusContract = 'cancel';
this.dataForm.contractCancelDate = new Date();
this.dataForm.contractCancelBy = this.auth.id;
}
if (!this.dataForm.isStatusContract) {
this.dataForm.statusContract = 'approved';
this.dataForm.contractApprovedDate = new Date();
this.dataForm.contractApprovedBy = this.auth.id;
this.dataForm.statusWarehouse = 'warehouse';
}
this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null;
return await this.onUpdate();
} catch (e) {
console.log(e);
}
}
async onUpdate() {
try {
await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.UPDATE);
await this.router.navigate(["/pages/contract/approved/list", this.action]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachments($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${this.api.attachments}/products`, formData));
if (!this.attachments[0]) {
this.dataForm.coverImage = res.fileName;
}
this.attachments.push(res.fileName);
console.log(this.attachments, res);
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments(i: number, fileName: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.attachments?.splice(i, 1);
if (!this.attachments[0]) {
this.dataForm.coverImage = null;
}
this.changeDetectorRef.detectChanges();
}
protected readonly SOURCES = SOURCES;
}

View File

@@ -1,205 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="tabs-btn">
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'pending'}" (click)="onTabs('pending')">รออนุมัติ</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'approved'}" (click)="onTabs('approved')">อนุมัติแล้ว</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'cancel'}" (click)="onTabs('cancel')">ไม่อนุมัติ</button>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="productBrandName">
<th mat-header-cell *matHeaderCellDef class="tal">Brand</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productBrandName }}</td>
</ng-container>
<ng-container matColumnDef="productSize">
<th mat-header-cell *matHeaderCellDef class="tal">Main</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productSize }}</td>
</ng-container>
<ng-container matColumnDef="productWeight">
<th mat-header-cell *matHeaderCellDef class="tal" >น้ำหนัก</th>
<td mat-cell *matCellDef="let item" class="">{{item.productWeight }}</td>
</ng-container>
<ng-container matColumnDef="productColor">
<th mat-header-cell *matHeaderCellDef class="tal">Color</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productColor }}</td>
</ng-container>
<ng-container matColumnDef="productYear">
<th mat-header-cell *matHeaderCellDef class="tal">Year</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productYear }}</td>
</ng-container>
<ng-container matColumnDef="userFullName">
<th mat-header-cell *matHeaderCellDef class="tal">ชื่อคนขาย</th>
<td mat-cell *matCellDef="let item" style="min-width: 200px;" >{{item.userFullName }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="deposit">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนมัดจำ</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-orange"> {{item.deposit | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="contractApprovedDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.contractApprovedDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="contractCancelDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่ไม่อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.contractCancelDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac" style="min-width: 100px;">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.type === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.type === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentType">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentType === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.paymentType === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentMethod">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>วิธีชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.paymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentAmountAll">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-green">{{item.paymentAmountAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="contractBy">
<th mat-header-cell *matHeaderCellDef class="tac">พนักงานทำรายการ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item?.userContractBy?.name}}</td>
</ng-container>
<ng-container matColumnDef="contractApprovedBy">
<th mat-header-cell *matHeaderCellDef class="tac">ผู้อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item?.userApprovedBy?.name }}</td>
</ng-container>
<ng-container matColumnDef="contractCancelBy">
<th mat-header-cell *matHeaderCellDef class="tac">ผู้ไม่อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item?.userCancelBy?.name }}</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item" *ngIf="item.statusContract === 'pending' " >
<i class="bi bi-pencil-square icon-edit" (click)="onAction('do', item.id)"></i>
</div>
<div class="item" *ngIf="['approved', 'cancel'].includes(item.statusContract) ">
<i class="bi bi-eye color-green" (click)="onAction('do', item.id)"></i>
</div>
<div class="item" *ngIf="['approved', 'cancel'].includes(item.statusContract) ">
<i class="bi bi-filetype-pdf color-main" (click)="onAction('pdf', item.id)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSource?.length === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,125 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EStatusContract, EStatusQuotation, EText } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-appraisal-3rd-time-index",
templateUrl: "./contract-approved-index.component.html",
styleUrls: []
})
export class ContractApprovedIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "สัญญา";
action = "pending";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = [];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
public activatedRoute: ActivatedRoute,
public changeDetectorRef: ChangeDetectorRef
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.action = params["action"];
if (!this.action) this.router.navigate(["/pages/contract/approved/list", EStatusQuotation.PENDING]);
await this.getData();
});
}
async onTabs(action?: any) {
this.dataFilter = {};
return this.router.navigate(["/pages/contract/approved/list", action]);
}
onAction(action : any, id?: any) {
if (action === 'do') return this.router.navigate([`/pages/contract/approved/do/${this.action}`, id]);
if (action === 'pdf') return this.router.navigate([`/pages/contract/approved/pdf/${this.action}`, id]);
return;
}
async getData($event?: any) {
try {
this.dataSource = [];
this.dataFilter.step = 5;
this.dataFilter.statusContract = this.action;
let url = API.quotation;
if (this.action === EStatusContract.PENDING) {
url = API.quotation;
this.displayedColumns = ["action", "price", "wantToInstallmentTerm", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor","contractBy", "createdDate"];
}
if (this.action === EStatusContract.APPROVED) {
url = API.quotation;
this.displayedColumns = ["action", "price", "wantToInstallmentTerm", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor","contractBy", "contractApprovedBy", "contractApprovedDate"];
}
if (this.action === EStatusContract.CANCEL) {
url = API.quotation;
this.displayedColumns = ["action", "price", "wantToInstallmentTerm", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor","contractBy", "contractCancelBy", "contractCancelDate"];
}
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,customerLastName,price,productName";
const dataSource = await lastValueFrom(this.appService.get(this.setParams(url, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
const url = `${API.quotation}/export-contract-approved?${filter ? '&' + filter : '' }`;
window.open(url);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,114 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { lastValueFrom } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, STORAGE } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { IQuotation } from "../../../../@common/interface/Quotation";
import { format, parseISO } from "date-fns";
@Component({
selector: "app-contract-make-pdf-index",
templateUrl: "./contract-approved-pdf.component.html",
styleUrls: []
})
export class ContractApprovedPdfComponent extends BaseFormComponent implements OnInit {
pageTitle = "สัญญา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotation : IQuotation = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
const startDate = quotation.startDate ? format(parseISO(quotation.startDate), "dd/MM/yyyy") : null;
const customerPrefix = quotation.customerPrefix ? quotation.customerPrefix : '';
const customerName = quotation.customerId ? `${quotation.customer?.prefix} ${quotation.customer?.firstName} ${quotation.customer?.lastName}` :
`${customerPrefix} ${quotation.customerFirstName} ${quotation.customerLastName}`;
const data = {
doc_no: quotation.quotationNo,
product_code: quotation.productNo,
customer_name: customerName,
first_name: quotation.customerFirstName,
last_name: quotation.customerLastName,
start_date: startDate,
phone_no: quotation.customerPhone,
picture: `${STORAGE.products}/${quotation.coverImage}`,
price: Number(quotation.price),
deposit: Number(quotation.deposit),
seller_deposit: Number(quotation.sellerDeposit),
cmfs_deposit: Number(quotation.cmfsDeposit),
total_balance: Number(quotation.principalBalanceTotal),
installment: Number(quotation.wantToInstallmentTerm),
packing: Number(quotation.plusPacking),
luxury_handbag_authentication: Number(quotation.plusLuxuryHandbag),
bankfee_insurance_storage: Number(quotation.plusBankFee),
transfer_amount: Number(quotation.transferSummary),
deduct_seller_deposit: Number(quotation.sellerDepositSum),
authenticity_verification: 0,
data: [],
total1: 0,
total2: 0,
total3: 0,
total4: 0
}
const quotationDetail: any = [];
quotation.quotationDetail?.map(item => {
const dueDate = item.dueDate ? format(parseISO(item.dueDate), "dd/MM/yyyy") : null;
const map = {
due_date: dueDate,
principle: Number(item.principle),
interest_total: Number(item.interestTotal),
bank_fee: Number(item.fee),
total_payment: Number(item.totalPayment),
principle_total: Number(item.principleTotal)
}
quotationDetail.push(map);
})
data.data = quotationDetail;
const pdf = await lastValueFrom(this.appService.post(`${this.api.installmentContractReport}/pdf`, data, { responseType: "arraybuffer" }));
const url = URL.createObjectURL(new Blob([pdf], { type: "application/pdf" }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,28 +0,0 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { ContractMakeIndexComponent } from "./index/contract-make-index.component";
import { ContractMakeDoComponent } from "./do/contract-make-do.component";
import { ContractMakePdfComponent } from "./pdf/contract-make-pdf.component";
const routes: Routes = [
{ path: "", component: ContractMakeIndexComponent },
{ path: "list", component: ContractMakeIndexComponent },
{ path: "list/:action", component: ContractMakeIndexComponent },
{ path: "do/:action", component: ContractMakeDoComponent },
{ path: "do/:action/:id", component: ContractMakeDoComponent },
{ path: "pdf/:action/:id", component: ContractMakePdfComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
ContractMakeIndexComponent,
ContractMakeDoComponent,
ContractMakePdfComponent
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './contract-make-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class ContractMakeModule {}

View File

@@ -1,867 +0,0 @@
<ul class="progressbar">
<li [ngClass]="{ 'active' : isTabs === 1}" (click)="isTabs = 1">รายละเอียดหลัก</li>
<li [ngClass]="{ 'active' : isTabs === 2}" (click)="isTabs = 2">การจัดผ่อน</li>
<li [ngClass]="{ 'active' : isTabs === 3}" (click)="isTabs = 3">ข้อมูลรับชำระเงิน</li>
</ul>
<form class="main-form" #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<ng-container *ngIf="isTabs === 1">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> สัญญาเงินกู้ระหว่าง CM-FS. Co., Ltd. ("บริษัทฯ") กับ</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่สัญญา/BOM</mat-label>
<mat-form-field>
<input matInput name="productNo" #productNo="ngModel" [(ngModel)]="dataForm.productNo" disabled>
</mat-form-field>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ชื่อลูกค้า</mat-label>-->
<!-- <mat-form-field>-->
<!-- <div class="flex">-->
<!-- <input style="width: 75px; padding-right: 0 !important;" matInput name="customerPrefix" #customerPrefix="ngModel" [(ngModel)]="dataForm.customer.prefix" disabled>-->
<!-- <input style="padding-left: 0 !important;" matInput name="customerFirstName" #customerFirstName="ngModel" [(ngModel)]="dataForm.customer.firstName" disabled>-->
<!-- </div>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>นามสกุล</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="customerLastName" #customerLastName="ngModel" [(ngModel)]="dataForm.customer.lastName" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>เบอร์โทร</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="customerPhone" #customerPhone="ngModel" [(ngModel)]="dataForm.customer.phone" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>เลขบัตรประชาชน</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="customerIdCard" #customerIdCard="ngModel" [(ngModel)]="dataForm.customer.idCard" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<div class="col-span-4 md:col-span-12 ">
<mat-label>วันที่ทำสัญญา</mat-label>
<mat-form-field>
<input
matInput
name="contractDate"
#contractDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.contractDate"
[matDatepicker]="dpkName"
readonly
required
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="prefix" #prefix="ngModel" [(ngModel)]="dataForm.customer.prefix" appendTo="body" disabled>
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="firstName" #firstName="ngModel" [(ngModel)]="dataForm.customer.firstName" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="lastName" #lastName="ngModel" [(ngModel)]="dataForm.customer.lastName" disabled>
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<ng-select placeholder="" name="gender" #gender="ngModel" [(ngModel)]="dataForm.customer.gender" appendTo="body" disabled>
<ng-option *ngFor="let item of genderData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="phone" #phone="ngModel" [(ngModel)]="dataForm.customer.phone" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="idCard" #idCard="ngModel" [(ngModel)]="dataForm.customer.idCard" disabled>
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ตามบัตรประชาชน</mat-label>
<mat-form-field>
<input matInput name="address" #address="ngModel" [(ngModel)]="dataForm.customer.address" disabled>
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<mat-label>ที่อยู่ในการจัดส่ง</mat-label>
<label class="inline-flex items-center cursor-pointer select-none ml-2">
<input type="checkbox" name="isAddress" [(ngModel)]="dataForm.customer.isAddress" disabled>
<span style="padding-left: 2px;">ใช้ที่อยู่ตามบัตรประชาชน</span>
</label>
<mat-form-field>
<input matInput name="deliveryAddress" #deliveryAddress="ngModel" [(ngModel)]="dataForm.customer.deliveryAddress" [disabled]="dataForm.customer.isAddress" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>E-mail</mat-label>
<mat-form-field>
<input matInput name="email" #email="ngModel" [(ngModel)]="dataForm.customer.email" disabled>
</mat-form-field>
</div>
<div class="col-span-8 md:col-span-12 ">
<mat-label>อาชีพ</mat-label>
<mat-form-field>
<input matInput name="occupation" #occupation="ngModel" [(ngModel)]="dataForm.customer.occupation" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="line" #line="ngModel" [(ngModel)]="dataForm.customer.line" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="facebook" #facebook="ngModel" [(ngModel)]="dataForm.customer.facebook" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="ig" #ig="ngModel" [(ngModel)]="dataForm.customer.ig" disabled>
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลร้านค้า</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ชื่อคนขาย/ร้านค้า</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="sellerName" #sellerName="ngModel" [(ngModel)]="dataForm.seller.name" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<ng-select placeholder="เลือกคำนำหน้า" name="sellerprefix" #sellerprefix="ngModel" [(ngModel)]="dataForm.seller.prefix" appendTo="body" disabled>
<ng-option *ngFor="let item of prefixData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="sellerfirstName" #sellerfirstName="ngModel" [(ngModel)]="dataForm.seller.firstName" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="sellerlastName" #sellerlastName="ngModel" [(ngModel)]="dataForm.seller.lastName" disabled>
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<ng-select placeholder="" name="sellergender" #sellergender="ngModel" [(ngModel)]="dataForm.seller.gender" appendTo="body" disabled>
<ng-option *ngFor="let item of genderData" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="sellerPhone" #sellerPhone="ngModel" [(ngModel)]="dataForm.seller.phone" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="sellerFacebook" #sellerFacebook="ngModel" [(ngModel)]="dataForm.seller.facebook" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="sellerLine" #sellerLine="ngModel" [(ngModel)]="dataForm.seller.line" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID LINE ร้านค้า</mat-label>
<mat-form-field>
<input matInput name="sellerLineShop" #sellerLineShop="ngModel" [(ngModel)]="dataForm.seller.lineShop" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="sellerIg" #sellerIg="ngModel" [(ngModel)]="dataForm.seller.ig" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>S/N สินค้า</mat-label>
<mat-form-field>
<input matInput name="sellerSnProduct" #sellerSnProduct="ngModel" [(ngModel)]="dataForm.seller.snProduct" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>แหล่งที่มา</mat-label>
<mat-form-field>
<input matInput name="source" #source="ngModel" [(ngModel)]="dataForm.source" disabled>
</mat-form-field>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ค่าขนส่ง</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="shippingCost" #shippingCost="ngModel" [(ngModel)]="dataForm.shippingCost" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
</div>
</div>
</div>
<div class="card card-table card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลสินค้า</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mb-2">
<div class="col-span-3 md:col-span-12 ">
<mat-label>Condition</mat-label>
<ng-select placeholder="Condition" name="condition" #condition="ngModel" [(ngModel)]="dataForm.productCondition" >
<ng-option *ngFor="let item of conditions" [value]="item">{{item}}</ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>Year</mat-label>
<mat-form-field>
<input appNumberOnly matInput name="year" #year="ngModel" [(ngModel)]="dataForm.productYear" >
</mat-form-field>
</div>
</div>
<div class="table-wrap">
<table class="tables ">
<thead>
<tr>
<th>BOM</th>
<th>Model</th>
<th>Brand</th>
<th>Main</th>
<th>น้ำหนัก</th>
<th>Color</th>
<th>Year</th>
<th>ราคาสินค้า</th>
<th>จำนวนเงินมัดจำ</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">{{dataForm.productNo}}</td>
<td class="text-center">{{dataForm.productName }}</td>
<td class="text-center">{{dataForm.productBrandName}}</td>
<td class="text-center">{{dataForm.productSize }}</td>
<td class="text-center">{{dataForm.productWeight }}</td>
<td class="text-center">{{dataForm.productColor }}</td>
<td class="text-center">{{dataForm.productYear }}</td>
<td class="text-center">{{dataForm.price | number : '1.2-2'}}</td>
<td class="text-center">
<div class="b-color-orange">{{dataForm.deposit | number : '1.2-2'}}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">รูปสินค้าจากลูกค้า</div>
<div class="ml-4">
<input hidden type="file" accept="image/*" #productImages (change)="onAttachments($event, 'products')" />
<button type="button" class="btn btn-sm btn-success-o" (click)="productImages.click()">เพิ่มรูปภาพสินค้า</button>
</div>
</div>
</div>
<div class="card-body">
<div class="list-images">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<ng-container *ngFor="let item of attachments; let i = index">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i *ngIf="dataForm.coverImage !== item" (click)="dataForm.coverImage = item"
matTooltip="ใช้ทำเอกสาร" class="bi bi-star color-main cursor-pointer select-none"></i>
<i *ngIf="dataForm.coverImage === item" class="bi bi bi-star-fill color-main cursor-pointer select-none"></i>
<i (click)="onRemoveAttachments(i, item)" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img src="{{storage.products}}/{{item}}" alt="">
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title flex items-center">
<div class="">อุปกรณ์</div>
</div>
</div>
<div class="card-body">
<ng-container *ngFor="let item of equipment; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-9 md:col-span-8 " >{{item}}</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="equipment.includes('อื่นๆ')">
<ng-container *ngFor="let item of equipmentOther; let i = index">
<div class="form-list">
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-9 md:col-span-8 " >{{item}}</div>
</div>
</div>
</ng-container>
</ng-container>
<div style="height: 20px;"></div>
</div>
</div>
</ng-container>
<ng-container *ngIf="isTabs === 2">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลการจัดผ่อน</div>
</div>
<div class="card-body form-input-list">
<div style="height: 20px;"></div>
<div class="grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> วันที่เริ่มจัดผ่อน</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input
matInput
name="startDate"
#startDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.startDate"
[matDatepicker]="dpkName"
readonly
disabled
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit"></div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ราคา (Price)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="price" #price="ngModel" [(ngModel)]="dataForm.price" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำแม่ค้า</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="sellerDeposit" #sellerDeposit="ngModel" [(ngModel)]="dataForm.sellerDeposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำ CMFS</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="deposit" #deposit="ngModel" [(ngModel)]="dataForm.deposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> เงินต้นคงเหลือ (Total)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="principalBalanceTotal" #principalBalanceTotal="ngModel" [(ngModel)]="dataForm.principalBalanceTotal" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ต้องการผ่อน (Term)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput type="number" name="wantToInstallmentTerm" #wantToInstallmentTerm="ngModel" [(ngModel)]="dataForm.wantToInstallmentTerm" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">งวด</div>
</div>
</div>
<div style="height: 20px;"></div>
</div>
</div>
</div>
<div class="col-span-6 md:col-span-12">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> รายละเอียดค่าใช้จ่ายในการโอนเงิน</div>
</div>
<div class="card-body form-input-list">
<div style="height: 20px;"></div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> มัดจำ CMFS Deposit</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="cmfsDeposit" #cmfsDeposit="ngModel" [(ngModel)]="dataForm.cmfsDeposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> หัก เงินมัดจำแม่ค้า </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="lessSellerDeposit" #lessSellerDeposit="ngModel" [(ngModel)]="dataForm.lessSellerDeposit" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Packing </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusPacking" #plusPacking="ngModel" [(ngModel)]="dataForm.plusPacking" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Luxury handbag </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusLuxuryHandbag" #plusLuxuryHandbag="ngModel" [(ngModel)]="dataForm.plusLuxuryHandbag" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> บวก Bank fee, Insurance , Storage</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="plusBankFee" #plusBankFee="ngModel" [(ngModel)]="dataForm.plusBankFee" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ส่วนลด </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="discount" #discount="ngModel" [(ngModel)]="dataForm.discount" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> สรุปยอดโอน </label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="transferSummary" #transferSummary="ngModel" [(ngModel)]="dataForm.transferSummary" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div style="height: 10px;"></div>
</div>
</div>
</div>
</div>
<div class="card card-table mb-6">
<div class="card-body">
<div class="table-wrap" *ngIf="dataForm.quotationDetail?.[0]">
<table class="tables">
<thead>
<tr>
<th>งวดที่</th>
<th>กำหนดจ่ายวันที่ <br>Due date</th>
<th>วันที่จ่าย <br>Payment date</th>
<th>เงินต้น <br>Principle</th>
<th>ดอกเบี้ย(บาท) <br>Interest Total</th>
<th>Bank fee, <br>Insurance ,Storage</th>
<th>ค่าชำระล่าช้า</th>
<th>รวมยอดจ่ายต่อเดือน <br>Total payment</th>
<th>เงินต้นคงเหลือ <br>Principle Total</th>
<th>ชำระเงิน</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let item of dataForm.quotationDetail; let i = index">
<tr>
<td class="text-center">{{item.installment }}</td>
<td class="text-center">{{item.dueDate | date : 'dd/MM/YYYY'}}</td>
<td class="text-center"><span *ngIf="item.status === 'paid'"> {{item.paymentDate | date : 'dd/MM/YYYY'}}</span></td>
<td class="text-center">{{item.principle | number : '1.0-0'}}</td>
<td class="text-center">{{item.interestTotal | number : '1.0-0'}}</td>
<td class="text-center">{{item.fee | number : '1.0-0'}}</td>
<td class="text-center">
<div class="b-color-red" *ngIf="item.interestLateTotal">
{{item.interestLateTotal | number : '1.2-2'}}
</div>
</td>
<td class="text-center">
<span class="b-color-green">
<ng-container *ngIf="item.totalPaymentAll"> {{ item.totalPaymentAll | number : '1.0-0'}}</ng-container>
<ng-container *ngIf="!item.totalPaymentAll"> {{ item.totalPayment | number : '1.0-0'}}</ng-container>
</span>
</td>
<td class="text-center"><span class="b-color-orange" *ngIf="item.principleTotal">{{item.principleTotal | number : '1.0-0'}}</span></td>
<td class="text-center">
<span *ngIf="item.status === 'paid'"> <i class="i bi-check-circle-fill color-green"></i></span>
</td>
</tr>
</ng-container>
<tr>
<td colspan="3" class="text-right"><b>รวม</b></td>
<td class="text-center">{{dataForm.principleSum | number : '1.0-0'}}</td>
<td class="text-center">{{dataForm.interestTotalSum | number : '1.0-0'}}</td>
<td class="text-center">{{dataForm.feeSum | number : '1.0-0'}}</td>
<td class="text-center">{{dataForm.interestLateTotalSum | number : '1.0-0'}}</td>
<td class="text-center"><span class="b-color-green">{{dataForm.totalPaymentSum | number : '1.0-0'}}</span></td>
<td class="text-center"></td>
<td class="text-center"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-table mb-6" *ngIf="quotationPayment?.[0]">
<div class="card-header"><b>ชำระเงินเพิ่มเติม</b></div>
<div class="card-body">
<div class="table-wrap">
<table class="tables">
<thead>
<tr>
<th width="60"></th>
<th width="150">วันที่จ่าย</th>
<th width="">วิธีชำระ</th>
<th>จำนวนเงิน</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let item of quotationPayment; let i = index">
<tr>
<td class="text-center">
<div class="item" *ngIf="item.status === 'paid' && item.paymentImages ">
<i class="bi bi-file-image-fill color-main" (click)="onAttachmentsView(item.paymentImages)"></i>
</div>
</td>
<td class="text-center">{{item.paymentDate | date : 'dd/MM/YYYY'}}</td>
<td class="text-center">
<div *ngIf="item.paymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.paymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
<td class="text-center"><span class="b-color-green">{{item.paymentAmountAll | number : '1.0-0'}}</span></td>
</tr>
</ng-container>
<tr>
<td colspan="3" class="text-right"><b>รวม</b></td>
<td class="text-center"><span class="b-color-green">{{dataForm.quotationPaymentSum | number : '1.0-0'}}</span></td>
</tr>
<tr>
<td colspan="3" class="text-right"><b>ยอดคงเหลือ</b></td>
<td class="text-center"><span class="b-color-green">{{dataForm.contractPriceSum | number : '1.0-0'}}</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-table " *ngIf="dataForm.statusPayment === 'paid'">
<div class="card-body">
<div class="no-data color-green font-bold"> ปิดยอดแล้ว</div>
</div>
</div>
<ng-container *ngIf="dataForm.statusPayment !== 'paid' ">
<div class="mt-4 mb-4">
<label class="inline-flex items-center cursor-pointer select-none ">
<input type="checkbox" name="isContractClosing" [(ngModel)]="dataForm.isContractClosing">
<span style="padding-left: 2px;">ปิดยอด</span>
</label>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6" *ngIf="dataForm.isContractClosing">
<div class="card-header ">
<div class="card-title"> ปิดยอดการผ่อนชำระ</div>
</div>
<div class="card-body form-input-list">
<div style="height: 20px;"></div>
<div class="grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> วันที่ปิดยอด</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input
matInput
name="contractClosingDate"
#contractClosingDate="ngModel"
(click)="dpkClosingDate.open()"
[(ngModel)]="dataForm.contractClosingDate"
[matDatepicker]="dpkClosingDate"
readonly
/>
<mat-datepicker-toggle [for]="dpkClosingDate" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkClosingDate></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit"></div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> เงินต้นคงเหลือ (Total)</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="contractPrice" #contractPrice="ngModel" [(ngModel)]="dataForm.contractPrice">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> ดอกเบี้ย</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="contractInterest" #contractInterest="ngModel" [(ngModel)]="dataForm.contractInterest">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div class=" grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-4 md:col-span-12 text-right md:text-left">
<label> สรุปยอดที่ต้องชำระ</label>
</div>
<div class="col-span-4 md:col-span-12">
<mat-form-field>
<input matInput appCurrencyInputMask name="contractPriceSum" #contractPriceSum="ngModel" [(ngModel)]="dataForm.contractPriceSum">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<div class="unit">บาท (THB)</div>
</div>
</div>
<div style="height: 20px;"></div>
</div>
</div>
</ng-container>
</ng-container>
<ng-container *ngIf="isTabs === 3">
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลธนาคารที่รับชำระเงิน</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-8 md:col-span-12 ">
<mat-label>ชื่อธนาคาร</mat-label>
<mat-form-field>
<input matInput name="productNo" #productNo="ngModel" [(ngModel)]="dataForm.contractBankName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อบัญชี</mat-label>
<mat-form-field>
<input matInput name="contractAccountName" #contractAccountName="ngModel" [(ngModel)]="dataForm.contractAccountName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่บัญชี</mat-label>
<mat-form-field>
<input matInput name="contractAccountNumber" #contractAccountNumber="ngModel" [(ngModel)]="dataForm.contractAccountNumber" required>
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> รายละเอียดท้ายสัญญา</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-12 md:col-span-12 ">
<mat-form-field>
<textarea matInput [(ngModel)]="dataForm.contractDetail" name="contractDetail" #contractDetail="ngModel" placeholder="" required></textarea>
</mat-form-field>
</div>
</div>
</div>
</div>
</ng-container>
<div class="main-form-action text-right">
<button type="submit" class="btn btn-submit">บันทึก</button>
<button type="button" class="btn btn-back" (click)="onAction('back')">ยกเลิก</button>
</div>
</form>

View File

@@ -1,222 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import {API, CONDITIONS, EAction, EText, GENDER, PREFIX, STORAGE} from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { ActivatedRoute, Router } from "@angular/router";
import { IProduct } from "../../../../app.interface";
import {orderByArray, sortByProperty} from "../../../../@common/utils/OrderBy";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {AttachmentsViewComponent} from "../../../@popup/attachments-view/attachments-view.component";
import {MatDialog} from "@angular/material/dialog";
@Component({
selector: "app-contract-make-do",
templateUrl: "./contract-make-do.component.html",
styleUrls: []
})
export class ContractMakeDoComponent extends BaseFormComponent implements OnInit {
override dataForm: any = {};
dataView: IProduct = {};
auth: any = {};
title = "";
api: any = API;
storage: any = STORAGE;
attachments: any = [];
equipment: any = [];
equipmentOther: any = [];
settings: any = [];
masterProductUnit: any = [];
quotationPayment: any = [];
deviation: any = 0;
isTabs: any = 1;
prefixData = PREFIX;
genderData = GENDER;
conditions = CONDITIONS;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
private attachmentsView: MatDialog,
public appService: AppService
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
this.action = params["action"];
this.auth = this.appService.auth();
this.dataForm.customer = {};
this.dataForm.seller = {};
if (this.ids) await this.getData();
});
}
async onAction(action: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.BACK));
if (!sweetalert.isConfirmed) return;
if (action === "back") return this.router.navigate(["/pages/contract/make/list", this.action]);
return;
}
async getData() {
if (!this.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
this.attachments = this.dataForm.images ? this.dataForm.images?.split(",") : [];
this.equipment = this.dataForm.equipment ? this.dataForm.equipment?.split(",") : [];
this.equipmentOther = this.dataForm.equipmentOther ? this.dataForm.equipmentOther?.split(",") : [];
this.dataForm.deposit = Number(this.dataForm.deposit) + Number(this.dataForm.sellerDeposit2ndTime) + Number(this.dataForm.sellerDeposit3rdTime);
this.dataForm.contractDate = new Date();
if (!this.dataForm.customerId) {
this.dataForm.customer = {};
this.dataForm.customer.prefix = this.dataForm.customerPrefix;
this.dataForm.customer.firstName = this.dataForm.customerFirstName;
this.dataForm.customer.lastName = this.dataForm.customerLastName;
this.dataForm.customer.phone = this.dataForm.customerPhone;
}
sortByProperty(this.dataForm.quotationDetail, 'installment', 'ASC');
this.dataForm.principleSum = 0
this.dataForm.interestTotalSum = 0
this.dataForm.interestLateTotalSum = 0
this.dataForm.feeSum = 0
this.dataForm.totalPaymentSum = 0
this.dataForm.contractPrincipleSum = 0
this.dataForm.contractInterestTotalSum = 0
this.dataForm.contractFeeSum = 0
this.dataForm.contractTotalPaymentSum = 0
this.dataForm.quotationDetail.map((item : any) => {
this.dataForm.principleSum += Number(item.principle)
this.dataForm.interestTotalSum += Number(item.interestTotal)
this.dataForm.interestLateTotalSum += Number(item.interestLateTotal)
this.dataForm.feeSum += Number(item.fee)
this.dataForm.totalPaymentSum += item.totalPaymentAll ? Number(item.totalPaymentAll) : Number(item.totalPayment)
if (item.status === 'pending') {
this.dataForm.contractPrincipleSum += Number(item.principle)
this.dataForm.contractInterestTotalSum += Number(item.interestTotal)
this.dataForm.contractFeeSum += Number(item.fee)
this.dataForm.contractTotalPaymentSum += item.totalPaymentAll ? Number(item.totalPaymentAll) : Number(item.totalPayment)
}
})
this.dataForm.principleSum = Math.round(this.dataForm.principleSum);
this.dataForm.contractTotalPaymentSum = Math.round(this.dataForm.contractTotalPaymentSum);
this.dataForm.contractClosingDate = new Date();
this.dataForm.contractPrice = this.dataForm.contractPrincipleSum;
this.dataForm.contractInterest = this.dataForm.contractInterestTotalSum;
this.dataForm.contractPriceSum = this.dataForm.contractTotalPaymentSum + this.dataForm.contractInterestTotalSum;
this.dataForm.contractBankName = 'ธนาคารทหารไทยธนชาต จำกัด (มหาชน)';
this.dataForm.contractAccountName = 'บริษัท ซีเอ็ม เอฟเอส จำกัด';
this.dataForm.contractAccountNumber = '263-2-17778-4';
this.dataForm.contractDetail = 'ชำระเงินงวดอย่างน้อย ทุกเดือนตามวันและยอดขั้นต่ำตามตาราง โดยที่ไม่เสียค่าปรับ ทั้งนี้หากเกินกำหนด ผู้กู้ต้องเสียค่าดอกเบี้ยผิดนัดเพิ่มเติมวันละ 1,000 บาท (ไม่รวมค่าทวงถาม) หากขาดส่งเกินกว่า 60 วัน นับแต่วันผ่อนล่าสุดจะถือว่าผิดสัญญา โดยหากผู้กู้ติดสัญญาไม่ว่ากรณีใดๆ ผู้กู้ยินดีที่จะนำสังหาริมทรัพย์ที่ผู้กู้นำเงินที่กู้ไปซื้อเป็นค่าตอบแทนในการชำระหนี้สินส่วนที่เหลือโดยทันที';
this.quotationPayment = await lastValueFrom(this.appService.get(`${API.quotationPayment}?showAll=true&status=paid&paymentType=receive&quotationId=${this.ids}`));
this.dataForm.quotationPaymentSum = 0;
this.quotationPayment.map((item : any) => {
this.dataForm.quotationPaymentSum += Number(item.paymentAmountAll)
});
if (this.dataForm.quotationPaymentSum) {
this.dataForm.contractPriceSum = this.dataForm.contractPriceSum - this.dataForm.quotationPaymentSum;
}
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onSubmit(form: any) {
if (!form.valid) return false;
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE));
if (!sweetalert.isConfirmed) return;
this.dataForm.pageAction = 'contractMake';
this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null;
this.dataForm.contractBy = this.auth.id;
this.dataForm.contractPrice = Number(this.dataForm.contractPrice);
this.dataForm.contractInterest = Number(this.dataForm.contractInterest);
this.dataForm.contractPriceSum = Number(this.dataForm.contractPriceSum);
return await this.onUpdate();
}
async onUpdate() {
try {
await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.UPDATE);
await this.router.navigate(["/pages/contract/make/list", this.action]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachments($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${this.api.attachments}/products`, formData));
if (!this.attachments[0]) {
this.dataForm.coverImage = res.fileName;
}
this.attachments.push(res.fileName);
console.log(this.attachments, res);
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments(i: number, fileName: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.attachments?.splice(i, 1);
if (!this.attachments[0]) {
this.dataForm.coverImage = null;
}
this.changeDetectorRef.detectChanges();
}
async onAttachmentsView(images : any) {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'ไฟล์แนบ';
dialogConfig.data.type = 'images';
dialogConfig.data.images = images;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
}

View File

@@ -1,202 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="tabs-btn">
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'wait'}" (click)="onTabs('wait')">รอทำสัญญา</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'pending'}" (click)="onTabs('pending')">รออนุมัติ</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'approved'}" (click)="onTabs('approved')">สัญญา</button>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="productBrandName">
<th mat-header-cell *matHeaderCellDef class="tal">Brand</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productBrandName }}</td>
</ng-container>
<ng-container matColumnDef="productSize">
<th mat-header-cell *matHeaderCellDef class="tal">Main</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productSize }}</td>
</ng-container>
<ng-container matColumnDef="productWeight">
<th mat-header-cell *matHeaderCellDef class="tal" >น้ำหนัก</th>
<td mat-cell *matCellDef="let item" class="">{{item.productWeight }}</td>
</ng-container>
<ng-container matColumnDef="productColor">
<th mat-header-cell *matHeaderCellDef class="tal">Color</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productColor }}</td>
</ng-container>
<ng-container matColumnDef="productYear">
<th mat-header-cell *matHeaderCellDef class="tal">Year</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productYear }}</td>
</ng-container>
<ng-container matColumnDef="userFullName">
<th mat-header-cell *matHeaderCellDef class="tal">ชื่อคนขาย</th>
<td mat-cell *matCellDef="let item" style="min-width: 200px;" >{{item.userFullName }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="deposit">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนมัดจำ</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-orange"> {{item.deposit | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="contractApprovedDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.contractApprovedDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac" style="min-width: 100px;">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.type === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.type === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentType">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentType === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.paymentType === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentMethod">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>วิธีชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.paymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentAmountAll">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-green">{{item.paymentAmountAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="sellerDeposit3rdTime">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>เงินมัดจำเพิ่ม</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-red" *ngIf="item.sellerDeposit3rdTime">{{item.sellerDeposit3rdTime | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="contractBy">
<th mat-header-cell *matHeaderCellDef class="tac">พนักงานทำรายการ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item?.userContractBy?.name}}</td>
</ng-container>
<ng-container matColumnDef="contractApprovedBy">
<th mat-header-cell *matHeaderCellDef class="tac">ผู้อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item?.userApprovedBy?.name }}</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item" *ngIf="['wait', 'approved'].includes(item.statusContract)" >
<i class="bi bi-pencil-square icon-edit" (click)="onAction('do', item.id)"></i>
</div>
<div class="item" *ngIf="['pending', 'approved'].includes(item.statusContract)">
<i class="bi bi-filetype-pdf color-red" (click)="onAction('pdf', item.id)"></i>
</div>
<div class="item" *ngIf="['pending', 'approved'].includes(item.statusContract)">
<i class="bi bi bi-arrow-clockwise color-green" (click)="onAction('refinance', item.id)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSource?.length === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,131 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EStatusContract, EStatusQuotation, EText } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-appraisal-3rd-time-index",
templateUrl: "./contract-make-index.component.html",
styleUrls: []
})
export class ContractMakeIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "สัญญา";
action = "pending";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = [];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
public activatedRoute: ActivatedRoute,
public changeDetectorRef: ChangeDetectorRef
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.action = params["action"];
if (!this.action) this.router.navigate(["/pages/contract/make/list", EStatusQuotation.WAIT]);
await this.getData();
});
}
async onTabs(action?: any) {
this.dataFilter = {};
return this.router.navigate(["/pages/contract/make/list", action]);
}
async onAction(action : any, id?: any) {
if (action === 'do') return this.router.navigate([`/pages/contract/make/do/${this.action}`, id]);
if (action === 'pdf') return this.router.navigate([`/pages/contract/make/pdf/${this.action}`, id]);
if (action === 'refinance') {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.REFINANCE));
if (!sweetalert.isConfirmed) return;
}
return;
}
async getData($event?: any) {
try {
this.dataSource = [];
this.dataFilter.step = 5;
this.dataFilter.statusContract = this.action;
let url = API.quotation;
if (this.action === EStatusContract.WAIT) {
url = API.quotation;
this.displayedColumns = ["action", "price", "wantToInstallmentTerm", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor", "productYear", "contractBy", "userFullName"];
}
if (this.action === EStatusContract.PENDING) {
url = API.quotation;
this.displayedColumns = ["action", "price", "wantToInstallmentTerm", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor", "contractBy", "createdDate"];
}
if (this.action === EStatusContract.APPROVED) {
url = API.quotation;
this.displayedColumns = ["action", "price", "wantToInstallmentTerm", "customerFirstName", "productNo", "productName", "productBrandName", "productSize", "productWeight", "productColor", "contractBy", "contractApprovedBy", "contractApprovedDate"];
}
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,price";
const dataSource = await lastValueFrom(this.appService.get(this.setParams(url, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
const url = `${API.quotation}/export-contract?${filter ? '&' + filter : '' }`;
window.open(url);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,111 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { lastValueFrom } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, STORAGE } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { IQuotation } from "../../../../@common/interface/Quotation";
import { format, parseISO } from "date-fns";
@Component({
selector: "app-contract-make-pdf-index",
templateUrl: "./contract-make-pdf.component.html",
styleUrls: []
})
export class ContractMakePdfComponent extends BaseFormComponent implements OnInit {
pageTitle = "สัญญา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotation : IQuotation = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
const startDate = quotation.startDate ? format(parseISO(quotation.startDate), "dd/MM/yyyy") : null;
const customerPrefix = quotation.customerPrefix ? quotation.customerPrefix : '';
const customerName = quotation.customerId ? `${quotation.customer?.prefix} ${quotation.customer?.firstName} ${quotation.customer?.lastName}` :
`${customerPrefix} ${quotation.customerFirstName} ${quotation.customerLastName}`;
const data = {
doc_no: quotation.quotationNo,
product_code: quotation.productNo,
type_code: quotation.typeCode,
customer_name: customerName,
first_name: quotation.customerFirstName,
last_name: quotation.customerLastName,
start_date: startDate,
phone_no: quotation.customerPhone,
picture: `${STORAGE.products}/${quotation.coverImage}`,
price: Number(quotation.price),
deposit: Number(quotation.deposit),
seller_deposit: Number(quotation.sellerDeposit),
cmfs_deposit: Number(quotation.cmfsDeposit),
total_balance: Number(quotation.principalBalanceTotal),
installment: Number(quotation.wantToInstallmentTerm),
packing: Number(quotation.plusPacking),
luxury_handbag_authentication: Number(quotation.plusLuxuryHandbag),
bankfee_insurance_storage: Number(quotation.plusBankFee),
transfer_amount: Number(quotation.transferSummary),
deduct_seller_deposit: Number(quotation.sellerDepositSum),
authenticity_verification: 0,
data: [],
total1: 0,
total2: 0,
total3: 0,
total4: 0
}
const quotationDetail: any = [];
quotation.quotationDetail?.map(item => {
const dueDate = item.dueDate ? format(parseISO(item.dueDate), "dd/MM/yyyy") : null;
const map = {
due_date: dueDate,
principle: Number(item.principle),
interest_total: Number(item.interestTotal),
bank_fee: Number(item.fee),
total_payment: Number(item.totalPayment),
principle_total: Number(item.principleTotal)
}
quotationDetail.push(map);
})
data.data = quotationDetail;
const pdf = await lastValueFrom(this.appService.post(`${this.api.installmentContractReport}/pdf`, data, { responseType: "arraybuffer" }));
const url = URL.createObjectURL(new Blob([pdf], { type: "application/pdf" }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -13,17 +13,16 @@ export class IndexComponent implements OnInit {
constructor(
public router: Router,
private route: ActivatedRoute,
private app: AppService
) {}
ngOnInit() {
this.auth = this.app.auth();
if (!this.auth) return;
// if (!this.auth) return;
if (this.auth.userType === 'ADMIN') {
return this.router.navigate(['/pages/manage/kyc']);
}
return;
// if (this.auth.userType === 'ADMIN') {
// return this.router.navigate(['/pages/manage/kyc']);
// }
return this.router.navigate(['/pages/manage/kyc']);
}
}

View File

@@ -1,217 +0,0 @@
<form class="main-form" #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่เอกสาร</mat-label>
<mat-form-field>
<input matInput name="quotationNo" #quotationNo="ngModel" [(ngModel)]="dataForm.quotationNo">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>วันที่ทำรายการ</mat-label>
<mat-form-field>
<input
matInput
name="sellerPaymentDate"
#sellerPaymentDate="ngModel"
(click)="dpkName3.open()"
[(ngModel)]="dataForm.sellerPaymentDate"
[matDatepicker]="dpkName3"
readonly
/>
<mat-datepicker-toggle [for]="dpkName3" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName3></mat-datepicker>
</mat-form-field>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลคนขาย</div>
</div>
<div class="card-body">
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<input matInput name="sellerprefix" #sellerprefix="ngModel" [(ngModel)]="dataForm.seller.prefix" disabled>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="sellerfirstName" #sellerfirstName="ngModel" [(ngModel)]="dataForm.seller.firstName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="sellerlastName" #sellerlastName="ngModel" [(ngModel)]="dataForm.seller.lastName" disabled>
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<input matInput name="sellergender" #sellergender="ngModel" [(ngModel)]="dataForm.seller.gender" disabled>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="sellerPhone" #sellerPhone="ngModel" [(ngModel)]="dataForm.seller.phone" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="sellerFacebook" #sellerFacebook="ngModel" [(ngModel)]="dataForm.seller.facebook" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="sellerLine" #sellerLine="ngModel" [(ngModel)]="dataForm.seller.line" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID LINE ร้านค้า</mat-label>
<mat-form-field>
<input matInput name="sellerLineShop" #sellerLineShop="ngModel" [(ngModel)]="dataForm.seller.lineShop" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="sellerIg" #sellerIg="ngModel" [(ngModel)]="dataForm.seller.ig">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>S/N สินค้า</mat-label>
<mat-form-field>
<input matInput name="sellerSnProduct" #sellerSnProduct="ngModel" [(ngModel)]="dataForm.seller.snProduct" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>แหล่งที่มา</mat-label>
<mat-form-field>
<input matInput name="source" #source="ngModel" [(ngModel)]="dataForm.source" disabled>
</mat-form-field>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ค่าขนส่ง</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="shippingCost" #shippingCost="ngModel" [(ngModel)]="dataForm.shippingCost" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
</div>
</div>
</div>
</div>
<div class="card card-table mb-6">
<div class="card-body">
<div class="table-wrap">
<table class="tables ">
<thead>
<tr>
<th>BOM</th>
<th>Model</th>
<th>Brand</th>
<th>Main</th>
<th>น้ำหนัก</th>
<th>Color</th>
<th>Year</th>
<th>ราคาสินค้า</th>
<th>มัดจำแม่ค้า</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">{{dataForm.productNo}}</td>
<td class="text-center">{{dataForm.productName }}</td>
<td class="text-center">{{dataForm.productBrandName}}</td>
<td class="text-center">{{dataForm.productSize }}</td>
<td class="text-center">{{dataForm.productWeight }}</td>
<td class="text-center">{{dataForm.productColor }}</td>
<td class="text-center">{{dataForm.productYear }}</td>
<td class="text-center">{{dataForm.price | number : '1.2-2'}}</td>
<td class="text-center">
<div class="b-color-orange">{{dataForm.sellerDeposit | number : '1.2-2'}}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลการชำระเงิน</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-4 md:col-span-12 ">
<mat-label>วิธีชำระ</mat-label>
<ng-select placeholder="เลือกวิธีชำระ" name="sellerPaymentMethod" #sellerPaymentMethod="ngModel" [(ngModel)]="dataForm.sellerPaymentMethod" appendTo="body" required>
<ng-option *ngFor="let item of paymentMethods" [value]="item.value">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ผู้รับเงิน</mat-label>
<mat-form-field>
<input matInput name="sellerPaymentPayee" #sellerPaymentPayee="ngModel" [(ngModel)]="dataForm.sellerPaymentPayee" required>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่บัญชี</mat-label>
<mat-form-field>
<input matInput name="sellerPaymentAccountNumber" #sellerPaymentAccountNumber="ngModel" [(ngModel)]="dataForm.sellerPaymentAccountNumber" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อธนาคาร</mat-label>
<mat-form-field>
<input matInput name="sellerPaymentAccountName" #sellerPaymentAccountName="ngModel" [(ngModel)]="dataForm.sellerPaymentAccountName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>จำนวนเงินสุทธิที่ต้องจ่าย</mat-label>
<mat-form-field>
<input class="!text-right" appCurrencyInputMask matInput name="sellerPaymentAmount" #sellerPaymentAmount="ngModel" [(ngModel)]="dataForm.sellerPaymentAmount" required>
</mat-form-field>
</div>
</div>
</div>
</div>
<div class="main-form-action text-right">
<button type="submit" class="btn btn-submit">บันทึก</button>
<button type="button" class="btn btn-back" (click)="onAction('back')">ยกเลิก</button>
</div>
</form>

View File

@@ -1,137 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { API, EAction, EText, STORAGE } from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { ActivatedRoute, Router } from "@angular/router";
import { IProduct } from "../../../../app.interface";
@Component({
selector: "app-finance-invoice-do",
templateUrl: "./finance-invoice-do.component.html",
styleUrls: []
})
export class FinanceInvoiceDoComponent extends BaseFormComponent implements OnInit {
override dataForm: any = {};
dataView: IProduct = {};
auth: any = {};
title = "";
api: any = API;
storage: any = STORAGE;
attachments: any = [];
settings: any = [];
masterProductUnit: any = [];
deviation: any = 0;
isTabs: any = 1;
paymentMethods = [
{value : 'transfer', name : 'โอนเงิน'},
{value : 'cash', name : 'เงินสด'},
]
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
this.action = params["action"];
this.auth = this.appService.auth();
this.dataForm.customer = {};
this.dataForm.seller = {};
if (this.ids) await this.getData();
});
}
async onAction(action: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.BACK));
if (!sweetalert.isConfirmed) return;
if (action === "back") return this.router.navigate(["/pages/finance/invoice/list", this.action]);
return;
}
async getData() {
if (!this.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
this.dataForm.sellerPaymentDate = new Date();
this.dataForm.sellerPaymentAmount = Number(this.dataForm.price) - Number(this.dataForm.sellerDeposit);
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onSubmit(form: any) {
if (!form.valid) return false;
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE));
if (!sweetalert.isConfirmed) return;
this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null;
this.dataForm.pageAction = 'financeInvoice';
return await this.onUpdate();
}
async onUpdate() {
try {
await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.UPDATE);
await this.router.navigate(["/pages/finance/invoice/list", this.action]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachments($event: any, type: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", type);
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${this.api.attachments}/products`, formData));
if (!this.attachments[0]) {
this.dataForm.coverImage = res.fileName;
}
this.attachments.push(res.fileName);
console.log(this.attachments, res);
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments(i: number, fileName: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.attachments?.splice(i, 1);
if (!this.attachments[0]) {
this.dataForm.coverImage = null;
}
this.changeDetectorRef.detectChanges();
}
}

View File

@@ -1,28 +0,0 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { FinanceInvoiceIndexComponent } from "./index/finance-invoice-index.component";
import { FinanceInvoiceDoComponent } from "./do/finance-invoice-do.component";
import { FinanceInvoicePdfComponent } from "./pdf/finance-invoice-pdf.component";
const routes: Routes = [
{ path: "", component: FinanceInvoiceIndexComponent },
{ path: "list", component: FinanceInvoiceIndexComponent },
{ path: "list/:action", component: FinanceInvoiceIndexComponent },
{ path: "do/:action", component: FinanceInvoiceDoComponent },
{ path: "do/:action/:id", component: FinanceInvoiceDoComponent },
{ path: "pdf/:action/:id", component: FinanceInvoicePdfComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
FinanceInvoiceIndexComponent,
FinanceInvoiceDoComponent,
FinanceInvoicePdfComponent
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './finance-invoice-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class FinanceInvoiceModule {}

View File

@@ -1,200 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="tabs-btn">
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'pending'}" (click)="onTabs('pending')">รอตั้งหนี้</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'invoice'}" (click)="onTabs('invoice')">ตั้งหนี้แล้ว</button>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="sellerName">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>ชื่อคนขาย</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item?.seller?.name}}</td>
</ng-container>
<ng-container matColumnDef="updatedDate">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>วันที่ทำรายการ</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.updatedDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="productBrandName">
<th mat-header-cell *matHeaderCellDef class="tal">Brand</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productBrandName }}</td>
</ng-container>
<ng-container matColumnDef="productSize">
<th mat-header-cell *matHeaderCellDef class="tal">Main</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productSize }}</td>
</ng-container>
<ng-container matColumnDef="productWeight">
<th mat-header-cell *matHeaderCellDef class="tal" >น้ำหนัก</th>
<td mat-cell *matCellDef="let item" class="">{{item.productWeight }}</td>
</ng-container>
<ng-container matColumnDef="productColor">
<th mat-header-cell *matHeaderCellDef class="tal">Color</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productColor }}</td>
</ng-container>
<ng-container matColumnDef="productYear">
<th mat-header-cell *matHeaderCellDef class="tal">Year</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productYear }}</td>
</ng-container>
<ng-container matColumnDef="userFullName">
<th mat-header-cell *matHeaderCellDef class="tal">ชื่อคนขาย</th>
<td mat-cell *matCellDef="let item" style="min-width: 200px;" >{{item.userFullName }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="sellerPaymentAmount">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.sellerPaymentAmount | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="deposit">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนมัดจำ</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-orange"> {{item.deposit | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="contractApprovedDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.contractApprovedDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac" style="min-width: 100px;">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.type === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.type === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentType">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentType === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.paymentType === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentMethod">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>วิธีชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.paymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentAmountAll">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-green">{{item.paymentAmountAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="sellerDeposit3rdTime">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>เงินมัดจำเพิ่ม</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-red" *ngIf="item.sellerDeposit3rdTime">{{item.sellerDeposit3rdTime | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item" *ngIf="item.isInvoice === 'pending' " >
<i class="bi bi-pencil-square icon-edit" (click)="onAction('do', item.id)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSource?.length === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,124 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EStatusContract, EStatusQuotation, EText } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-finance-invoice-index",
templateUrl: "./finance-invoice-index.component.html",
styleUrls: []
})
export class FinanceInvoiceIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "การแจ้งหนี้/ตั้งเจ้าหนี้";
action = "pending";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = [];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
public activatedRoute: ActivatedRoute,
public changeDetectorRef: ChangeDetectorRef
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.action = params["action"];
if (!this.action) this.router.navigate(["/pages/finance/invoice/list", 'pending']);
await this.getData();
});
}
async onTabs(action?: any) {
this.dataFilter = {};
return this.router.navigate(["/pages/finance/invoice/list", action]);
}
onAction(action : any, id?: any) {
if (action === 'do') return this.router.navigate([`/pages/finance/invoice/do/${this.action}`, id]);
if (action === 'pdf') return this.router.navigate([`/pages/finance/invoice/pdf/${this.action}`, id]);
return;
}
async getData($event?: any) {
try {
this.dataSource = [];
this.dataFilter.step = 5;
let url = API.quotation;
if (this.action === 'pending') {
this.dataFilter.isInvoice = 'pending';
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,customerLastName,price";
this.displayedColumns = ["action", "price", "sellerName", "productNo", "productName", "customerFirstName", "updatedDate"];
}
if (this.action === 'invoice') {
this.dataFilter.isInvoice = 'invoice';
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,customerLastName,sellerPaymentAmount";
this.displayedColumns = [ "sellerPaymentAmount", "sellerName", "productNo", "productName", "customerFirstName", "updatedDate"];
}
const dataSource = await lastValueFrom(this.appService.get(this.setParams(url, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
const url = `${API.quotation}/export-invoice?${filter ? '&' + filter : '' }`;
window.open(url);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,110 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { lastValueFrom } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, STORAGE } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { IQuotation } from "../../../../@common/interface/Quotation";
import { format, parseISO } from "date-fns";
@Component({
selector: "app-contract-make-pdf-index",
templateUrl: "./finance-invoice-pdf.component.html",
styleUrls: []
})
export class FinanceInvoicePdfComponent extends BaseFormComponent implements OnInit {
pageTitle = "สัญญา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotation : IQuotation = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
const startDate = quotation.startDate ? format(parseISO(quotation.startDate), "dd/MM/yyyy") : null;
const customerPrefix = quotation.customerPrefix ? quotation.customerPrefix : '';
const customerName = quotation.customerId ? `${quotation.customer?.prefix} ${quotation.customer?.firstName} ${quotation.customer?.lastName}` :
`${customerPrefix} ${quotation.customerFirstName} ${quotation.customerLastName}`;
const data = {
doc_no: quotation.quotationNo,
product_code: quotation.productNo,
customer_name: customerName,
first_name: quotation.customerFirstName,
last_name: quotation.customerLastName,
start_date: startDate,
phone_no: quotation.customerPhone,
picture: `${STORAGE.products}/${quotation.coverImage}`,
price: Number(quotation.price),
deposit: Number(quotation.deposit),
seller_deposit: Number(quotation.sellerDeposit),
cmfs_deposit: Number(quotation.cmfsDeposit),
total_balance: Number(quotation.principalBalanceTotal),
installment: Number(quotation.wantToInstallmentTerm),
packing: Number(quotation.plusPacking),
luxury_handbag_authentication: Number(quotation.plusLuxuryHandbag),
bankfee_insurance_storage: Number(quotation.plusBankFee),
transfer_amount: Number(quotation.transferSummary),
deduct_seller_deposit: Number(quotation.sellerDepositSum),
authenticity_verification: 0,
data: [],
total1: 0,
total2: 0,
total3: 0,
total4: 0
}
const quotationDetail: any = [];
quotation.quotationDetail?.map(item => {
const dueDate = item.dueDate ? format(parseISO(item.dueDate), "dd/MM/yyyy") : null;
const map = {
due_date: dueDate,
principle: Number(item.principle),
interest_total: Number(item.interestTotal),
bank_fee: Number(item.fee),
total_payment: Number(item.totalPayment),
principle_total: Number(item.principleTotal)
}
quotationDetail.push(map);
})
data.data = quotationDetail;
const pdf = await lastValueFrom(this.appService.post(`${this.api.installmentContractReport}/pdf`, data, { responseType: "arraybuffer" }));
const url = URL.createObjectURL(new Blob([pdf], { type: "application/pdf" }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,238 +0,0 @@
<form class="main-form" #ngf="ngForm" (ngSubmit)="onSubmit(ngf)">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่เอกสาร</mat-label>
<mat-form-field>
<input matInput name="quotationNo" #quotationNo="ngModel" [(ngModel)]="dataForm.quotationNo">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>วันที่ทำรายการ</mat-label>
<mat-form-field>
<input
matInput
name="sellerPaymentDate"
#sellerPaymentDate="ngModel"
(click)="dpkName3.open()"
[(ngModel)]="dataForm.sellerPaymentDate"
[matDatepicker]="dpkName3"
readonly
/>
<mat-datepicker-toggle [for]="dpkName3" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName3></mat-datepicker>
</mat-form-field>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลคนขาย</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-2 md:col-span-12 ">
<mat-label>คำนำหน้า</mat-label>
<input matInput name="sellerprefix" #sellerprefix="ngModel" [(ngModel)]="dataForm.seller.prefix" disabled>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput name="sellerfirstName" #sellerfirstName="ngModel" [(ngModel)]="dataForm.seller.firstName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput name="sellerlastName" #sellerlastName="ngModel" [(ngModel)]="dataForm.seller.lastName" disabled>
</mat-form-field>
</div>
<div class="col-span-2 md:col-span-12 ">
<mat-label>เพศ</mat-label>
<input matInput name="sellergender" #sellergender="ngModel" [(ngModel)]="dataForm.seller.gender" disabled>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="sellerPhone" #sellerPhone="ngModel" [(ngModel)]="dataForm.seller.phone" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>Facebook</mat-label>
<mat-form-field>
<input matInput name="sellerFacebook" #sellerFacebook="ngModel" [(ngModel)]="dataForm.seller.facebook" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID Line</mat-label>
<mat-form-field>
<input matInput name="sellerLine" #sellerLine="ngModel" [(ngModel)]="dataForm.seller.line" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ID LINE ร้านค้า</mat-label>
<mat-form-field>
<input matInput name="sellerLineShop" #sellerLineShop="ngModel" [(ngModel)]="dataForm.seller.lineShop" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>IG</mat-label>
<mat-form-field>
<input matInput name="sellerIg" #sellerIg="ngModel" [(ngModel)]="dataForm.seller.ig">
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>S/N สินค้า</mat-label>
<mat-form-field>
<input matInput name="sellerSnProduct" #sellerSnProduct="ngModel" [(ngModel)]="dataForm.seller.snProduct" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>แหล่งที่มา</mat-label>
<mat-form-field>
<input matInput name="source" #source="ngModel" [(ngModel)]="dataForm.source" disabled>
</mat-form-field>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>ค่าขนส่ง</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="shippingCost" #shippingCost="ngModel" [(ngModel)]="dataForm.shippingCost" disabled>-->
<!-- </mat-form-field>-->
<!-- </div>-->
</div>
</div>
</div>
<div class="card card-table mb-6">
<div class="card-body">
<div class="table-wrap">
<table class="tables ">
<thead>
<tr>
<th>BOM</th>
<th>Model</th>
<th>Brand</th>
<th>Main</th>
<th>น้ำหนัก</th>
<th>Color</th>
<th>Year</th>
<th>ราคาสินค้า</th>
<th>มัดจำแม่ค้า</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">{{dataForm.productNo}}</td>
<td class="text-center">{{dataForm.productName }}</td>
<td class="text-center">{{dataForm.productBrandName}}</td>
<td class="text-center">{{dataForm.productSize }}</td>
<td class="text-center">{{dataForm.productWeight }}</td>
<td class="text-center">{{dataForm.productColor }}</td>
<td class="text-center">{{dataForm.productYear }}</td>
<td class="text-center">{{dataForm.price | number : '1.2-2'}}</td>
<td class="text-center">
<div class="b-color-orange">{{dataForm.sellerDeposit | number : '1.2-2'}}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card card-form-panel card-form-panel-blue mb-6">
<div class="card-header ">
<div class="card-title"> ข้อมูลการชำระเงิน</div>
</div>
<div class="card-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 mt-4 mb-4">
<div class="col-span-4 md:col-span-12 ">
<mat-label>วิธีชำระ</mat-label>
<ng-select placeholder="เลือกวิธีชำระ" name="sellerPaymentMethod" #sellerPaymentMethod="ngModel" [(ngModel)]="dataForm.sellerPaymentMethod" appendTo="body" required>
<ng-option *ngFor="let item of paymentMethods" [value]="item.value">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ผู้รับเงิน</mat-label>
<mat-form-field>
<input matInput name="sellerPaymentPayee" #sellerPaymentPayee="ngModel" [(ngModel)]="dataForm.sellerPaymentPayee" required>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่บัญชี</mat-label>
<mat-form-field>
<input matInput name="sellerPaymentAccountNumber" #sellerPaymentAccountNumber="ngModel" [(ngModel)]="dataForm.sellerPaymentAccountNumber" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>ชื่อธนาคาร</mat-label>
<mat-form-field>
<input matInput name="sellerPaymentAccountName" #sellerPaymentAccountName="ngModel" [(ngModel)]="dataForm.sellerPaymentAccountName" required>
</mat-form-field>
</div>
<div class="col-span-4 md:hidden"></div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>จำนวนเงินสุทธิที่ต้องจ่าย</mat-label>
<mat-form-field>
<input class="!text-right" appCurrencyInputMask matInput name="sellerPaymentAmount" #sellerPaymentAmount="ngModel" [(ngModel)]="dataForm.sellerPaymentAmount" required>
</mat-form-field>
</div>
<div class="col-span-12">
<div class="mt-4">
<input hidden type="file" accept="image/*" #uploadFile (change)="onAttachments($event)"/>
<button type="button" class="btn btn-sm btn-success-o" (click)="uploadFile.click()">เพิ่มแนบไฟล์</button>
</div>
<div class="list-images" *ngIf="dataForm.sellerPaymentImages" style="min-height: auto !important;">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i (click)="onRemoveAttachments()" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img (click)="onAttachmentsView()" src="{{storage.images}}/{{dataForm.sellerPaymentImages}}" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="main-form-action text-right">
<button type="submit" class="btn btn-submit">บันทึก</button>
<button type="button" class="btn btn-back" (click)="onAction('back')">ยกเลิก</button>
</div>
</form>

View File

@@ -1,147 +0,0 @@
import {ChangeDetectorRef, Component, OnInit, ViewChild} from "@angular/core";
import {API, EAction, EText, GENDER, PREFIX, STORAGE} from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { ActivatedRoute, Router } from "@angular/router";
import { IProduct } from "../../../../app.interface";
import {MatDialog} from "@angular/material/dialog";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {AttachmentsViewComponent} from "../../../@popup/attachments-view/attachments-view.component";
@Component({
selector: "app-finance-paying-do",
templateUrl: "./finance-paying-do.component.html",
styleUrls: []
})
export class FinancePayingDoComponent extends BaseFormComponent implements OnInit {
override dataForm: any = {};
dataView: IProduct = {};
auth: any = {};
title = "";
api: any = API;
storage: any = STORAGE;
attachments: any = [];
settings: any = [];
masterProductUnit: any = [];
deviation: any = 0;
isTabs: any = 1;
paymentMethods = [
{value : 'transfer', name : 'โอนเงิน'},
{value : 'cash', name : 'เงินสด'},
]
@ViewChild('uploadFile') uploadFile: any;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
private attachmentsView: MatDialog,
public appService: AppService
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
this.action = params["action"];
this.auth = this.appService.auth();
this.dataForm.customer = {};
this.dataForm.seller = {};
if (this.ids) await this.getData();
});
}
async onAction(action: string) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.BACK));
if (!sweetalert.isConfirmed) return;
if (action === "back") return this.router.navigate(["/pages/finance/paying/list", this.action]);
return;
}
async getData() {
if (!this.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onSubmit(form: any) {
if (!form.valid) return false;
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.CREATE));
if (!sweetalert.isConfirmed) return;
this.dataForm.images = this.attachments?.[0] ? this.attachments.join(",") : null;
this.dataForm.pageAction = 'financePaying';
return await this.onUpdate();
}
async onUpdate() {
try {
await lastValueFrom(this.appService.post(`${this.api.quotation}/update/${this.ids}`, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.UPDATE);
await this.router.navigate(["/pages/finance/paying/list", this.action]);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachments($event: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", 'images');
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData));
this.dataForm.sellerPaymentImages = res.fileName;
this.uploadFile.nativeElement.value = null;
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments() {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.dataForm.paymentImages = null;
this.changeDetectorRef.detectChanges();
}
async onAttachmentsView() {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'ไฟล์แนบ';
dialogConfig.data.type = 'images';
dialogConfig.data.images = this.dataForm.sellerPaymentImages;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
protected readonly GENDER = GENDER;
protected readonly PREFIX = PREFIX;
}

View File

@@ -1,28 +0,0 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { FinancePayingIndexComponent } from "./index/finance-paying-index.component";
import { FinancePayingDoComponent } from "./do/finance-paying-do.component";
import { FinancePayingPdfComponent } from "./pdf/finance-paying-pdf.component";
const routes: Routes = [
{ path: "", component: FinancePayingIndexComponent },
{ path: "list", component: FinancePayingIndexComponent },
{ path: "list/:action", component: FinancePayingIndexComponent },
{ path: "do/:action", component: FinancePayingDoComponent },
{ path: "do/:action/:id", component: FinancePayingDoComponent },
{ path: "pdf/:action/:id", component: FinancePayingPdfComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
FinancePayingIndexComponent,
FinancePayingDoComponent,
FinancePayingPdfComponent
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './finance-paying-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class FinancePayingModule {}

View File

@@ -1,209 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword" (ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="tabs-btn">
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'pending'}" (click)="onTabs('pending')">รอจ่าย</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'paid'}" (click)="onTabs('paid')">จ่ายแล้ว</button>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสนอราคา</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container *ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="sellerName">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>ชื่อคนขาย</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item?.seller?.name}}</td>
</ng-container>
<ng-container matColumnDef="sellerPaymentPayee">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>ชื่อผู้รับเงิน</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item?.sellerPaymentPayee}}</td>
</ng-container>
<ng-container matColumnDef="sellerPaymentDate">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>วันที่ทำรายการ</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.sellerPaymentDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="productBrandName">
<th mat-header-cell *matHeaderCellDef class="tal">Brand</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productBrandName }}</td>
</ng-container>
<ng-container matColumnDef="productSize">
<th mat-header-cell *matHeaderCellDef class="tal">Main</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productSize }}</td>
</ng-container>
<ng-container matColumnDef="productWeight">
<th mat-header-cell *matHeaderCellDef class="tal" >น้ำหนัก</th>
<td mat-cell *matCellDef="let item" class="">{{item.productWeight }}</td>
</ng-container>
<ng-container matColumnDef="productColor">
<th mat-header-cell *matHeaderCellDef class="tal">Color</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productColor }}</td>
</ng-container>
<ng-container matColumnDef="productYear">
<th mat-header-cell *matHeaderCellDef class="tal">Year</th>
<td mat-cell *matCellDef="let item" class="" >{{item.productYear }}</td>
</ng-container>
<ng-container matColumnDef="userFullName">
<th mat-header-cell *matHeaderCellDef class="tal">ชื่อคนขาย</th>
<td mat-cell *matCellDef="let item" style="min-width: 200px;" >{{item.userFullName }}</td>
</ng-container>
<ng-container matColumnDef="sellerPaymentAmount">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.sellerPaymentAmount | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="deposit">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนมัดจำ</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-orange"> {{item.deposit | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่บันทึก</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="contractApprovedDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่อนุมัติ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.contractApprovedDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac" style="min-width: 100px;">
<div *ngIf="item.status === 'paid' " class="status status-active">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status status-disabled">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.type === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.type === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentType">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentType === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.paymentType === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
</td>
</ng-container>
<ng-container matColumnDef="sellerPaymentMethod">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>วิธีชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.sellerPaymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.sellerPaymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentAmountAll">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-green">{{item.paymentAmountAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="sellerDeposit3rdTime">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>เงินมัดจำเพิ่ม</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-red" *ngIf="item.sellerDeposit3rdTime">{{item.sellerDeposit3rdTime | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item" *ngIf="item.isPaying === 'pending' " >
<i class="bi bi-pencil-square icon-edit" (click)="onAction('do', item.id)"></i>
</div>
<div class="item" *ngIf="item.isPaying === 'paying' ">
<i class="bi bi-filetype-pdf color-red" (click)="onAction('pdf', item.id)"></i>
</div>
<div class="item" *ngIf="item.isPaying === 'paying' && item.sellerPaymentImages ">
<i class="bi bi-file-image-fill color-main" (click)="onAttachmentsView(item.sellerPaymentImages)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSource?.length === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,133 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { debounceTime, distinctUntilChanged, lastValueFrom, Subject } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, EAction, EStatusContract, EStatusQuotation, EText } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {AttachmentsViewComponent} from "../../../@popup/attachments-view/attachments-view.component";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-finance-paying-index",
templateUrl: "./finance-paying-index.component.html",
styleUrls: []
})
export class FinancePayingIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "การแจ้งหนี้/ตั้งเจ้าหนี้";
action = "pending";
apiUrl: string = API.quotation;
api: any = API;
displayedColumns: string[] = [];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
public activatedRoute: ActivatedRoute,
private attachmentsView: MatDialog,
public changeDetectorRef: ChangeDetectorRef
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.action = params["action"];
if (!this.action) this.router.navigate(["/pages/finance/paying/list", 'pending']);
await this.getData();
});
}
async onTabs(action?: any) {
this.dataFilter = {};
return this.router.navigate(["/pages/finance/paying/list", action]);
}
onAction(action : any, id?: any) {
if (action === 'do') return this.router.navigate([`/pages/finance/paying/do/${this.action}`, id]);
if (action === 'pdf') return this.router.navigate([`/pages/finance/paying/pdf/${this.action}`, id]);
return;
}
async getData($event?: any) {
try {
this.dataSource = [];
this.dataFilter.step = 5;
this.dataFilter.keywordColumn = "sellerPaymentAmount,sellerPaymentPayee,productNo";
let url = API.quotation;
if (this.action === 'pending') {
this.dataFilter.isPaying = 'pending';
this.displayedColumns = ["action", "sellerPaymentAmount", "sellerPaymentPayee","sellerName", "productNo", "productName", "customerFirstName", "sellerPaymentMethod"];
}
if (this.action === 'paid') {
this.dataFilter.isPaying = 'paying';
this.displayedColumns = [ "action", "sellerPaymentAmount", "sellerPaymentPayee","sellerName", "productNo", "productName", "customerFirstName", "sellerPaymentMethod"];
}
const dataSource = await lastValueFrom(this.appService.get(this.setParams(url, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachmentsView(images : any) {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'ไฟล์แนบ';
dialogConfig.data.type = 'images';
dialogConfig.data.images = images;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
const url = `${API.quotation}/export-paying?${filter ? '&' + filter : '' }`;
window.open(url);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,85 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { lastValueFrom } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API, STORAGE } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { IQuotation } from "../../../../@common/interface/Quotation";
import { format, parseISO } from "date-fns";
@Component({
selector: "app-contract-make-pdf-index",
templateUrl: "./finance-paying-pdf.component.html",
styleUrls: []
})
export class FinancePayingPdfComponent extends BaseFormComponent implements OnInit {
pageTitle = "สัญญา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotation : IQuotation = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
const sellerPaymentDate = quotation.sellerPaymentDate ? format(parseISO(quotation.sellerPaymentDate), "dd/MM/yyyy") : null;
const data : any = {
payment_no: quotation.quotationNo,
payment_date:sellerPaymentDate,
customer_name: quotation?.sellerPaymentPayee,
bank: quotation?.sellerPaymentAccountName,
account_number: quotation?.sellerPaymentAccountNumber,
data: [
{
item_code: quotation.productNo,
item_name_th: quotation.productName,
item_amount: Number(quotation.sellerPaymentAmount)
}
],
total_amount: Number(quotation.sellerPaymentAmount),
payee: quotation.sellerPaymentPayee,
payer: quotation.userFullName,
}
console.log(quotation)
const pdf = await lastValueFrom(this.appService.post(`${this.api.paymentVoucher}/pdf`, data, { responseType: "arraybuffer" }));
const url = URL.createObjectURL(new Blob([pdf], { type: "application/pdf" }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,34 +0,0 @@
import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import {FinancePaymentCreateComponent} from "./popup-create/finance-payment-create.component";
import { FinancePaymentIndexComponent } from "./index/finance-payment-index.component";
import { FinancePaymentPdfComponent } from "./pdf/finance-payment-pdf.component";
import { FinancePaymentUpdateComponent } from "./popup-update/finance-payment-update.component";
import {FinancePaymentPdfInvoiceComponent} from "./pdf-invoice/finance-payment-pdf-invoice.component";
import {FinancePaymentInstallmentComponent} from "./popup-installment/finance-payment-installment.component";
import {FinancePaymentPdfInstallmentComponent} from "./pdf-installment/finance-payment-pdf-installment.component";
const routes: Routes = [
{path: '', component: FinancePaymentIndexComponent},
{path: ':action', component: FinancePaymentIndexComponent},
{path: ':action/pdf/:id', component: FinancePaymentPdfComponent},
{path: ':action/pdf-invoice/:id', component: FinancePaymentPdfInvoiceComponent},
{path: ':action/pdf-invoice-installment/:id', component: FinancePaymentPdfInstallmentComponent},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RoutingModule {
}
export const RoutingComponents = [
FinancePaymentIndexComponent,
FinancePaymentCreateComponent,
FinancePaymentUpdateComponent,
FinancePaymentInstallmentComponent,
FinancePaymentPdfComponent,
FinancePaymentPdfInstallmentComponent,
FinancePaymentPdfInvoiceComponent,
];

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import {RoutingComponents, RoutingModule} from './finance-payment-routing.module';
import {AppSharedModule} from "../../../app.shared";
import { NgOptimizedImage } from "@angular/common";
@NgModule({
declarations: [
...RoutingComponents,
],
imports: [
AppSharedModule,
RoutingModule,
NgOptimizedImage
]
})
export class FinancePaymentModule {}

View File

@@ -1,286 +0,0 @@
<div class="card card-table">
<div class="card-filter text-right">
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
<div class="col-span-5 md:col-span-12 md:order-2">
<mat-form-field>
<i matTextPrefix class="bi bi-search"></i>
<input matInput name="keyword" #keyword="ngModel" [(ngModel)]="dataFilter.keyword"
(ngModelChange)="onFilter($event)">
</mat-form-field>
</div>
<div class="col-span-7 md:col-span-12 md:order-1">
<div class="card-header-action">
<button type="button" class="btn btn-export" (click)="onExport()">Export</button>
<button type="button" class="btn btn-create" (click)="onPopupNew()">
<i class="bi bi-plus"></i>
รับชำระเงิน
</button>
</div>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 ">
<div class="col-span-6 md:col-span-12">
<div class="tabs-btn">
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'pending'}" (click)="onTabs('pending')">
รอชำระ
</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'due'}" (click)="onTabs('due')">
ครบกำหนด
</button>
<button type="button" class="btn" [ngClass]="{ 'active' : action === 'paid'}" (click)="onTabs('paid')">
ชำระแล้ว
</button>
</div>
</div>
<div class="col-span-6 md:col-span-12 ">
<div class="flex w-full justify-end md:justify-start">
<div class="">จำนวนทั้งหมด {{totalItem}} รายการ</div>
<div class="pl-2 pr-2">|</div>
<div class="">ค้นหาจำนวน {{totalOfElement}} รายการ</div>
</div>
</div>
</div>
<div class="card-filter-section grid grid-cols-12 gap-4 items-center md:gap-2 "
*ngIf="this.selection.selected.length > 0 && ['pending', 'due'].includes(action)">
<div class="col-span-6 md:col-span-12 text-left ">
<button type="button" class="btn btn-red-o mr-2" (click)="onInvoice()"><i class="bi bi-filetype-pdf"></i>
ส่งใบแจ้งหนี้
</button>
</div>
</div>
<mat-progress-bar *ngIf="isLoading" mode="indeterminate"></mat-progress-bar>
</div>
<div class="card-body">
<div class="table-wrap">
<table class="table table-main" mat-table [dataSource]="dataSource" matSort (matSortChange)="onSort($event)">
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<ng-container matColumnDef="invoice">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="quotationNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่เอกสาร</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.quotationNo}}</td>
</ng-container>
<ng-container matColumnDef="paymentNo">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>เลขที่ใบเสร็จ</th>
<td mat-cell *matCellDef="let item" width="150" class="">
{{item.paymentNo}}
</td>
</ng-container>
<ng-container matColumnDef="quotationNoDetail">
<th mat-header-cell *matHeaderCellDef class="">เลขที่เอกสาร</th>
<td mat-cell *matCellDef="let item" width="150" class="">
{{item?.quotation?.quotationNo}}
</td>
</ng-container>
<ng-container matColumnDef="customerFirstName">
<th mat-header-cell *matHeaderCellDef class="" mat-sort-header>ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container
*ngIf="item.customerId"> {{item.customer?.prefix}}{{item.customer?.firstName}} {{item.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.customerId && item.isQuotationNo">{{item.customerFirstName}} {{item.customerLastName}}</ng-container>
<ng-container *ngIf="item.isQuotationNo">{{item.customerName}} </ng-container>
</td>
</ng-container>
<ng-container matColumnDef="customerFirstNameDetail">
<th mat-header-cell *matHeaderCellDef class="">ชื่อลูกค้า</th>
<td mat-cell *matCellDef="let item" width="150" class="">
<ng-container
*ngIf="item.quotation?.customerId"> {{item.quotation?.customer?.prefix}}{{item.quotation?.customer?.firstName}} {{item.quotation?.customer?.lastName}}</ng-container>
<ng-container *ngIf="!item.quotation?.customerId">{{item.quotation?.customerFirstName}} {{item.quotation?.customerLastName}}</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="productNo">
<th mat-header-cell *matHeaderCellDef class="tac" mat-sort-header>BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productNoDetail">
<th mat-header-cell *matHeaderCellDef class="tac">BOM</th>
<td mat-cell *matCellDef="let item" width="150" class="">{{item?.quotation?.productNo}}</td>
</ng-container>
<ng-container matColumnDef="productName">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item.productName }}</td>
</ng-container>
<ng-container matColumnDef="productNameDetail">
<th mat-header-cell *matHeaderCellDef class="tal">Model</th>
<td mat-cell *matCellDef="let item" class="" style="min-width: 220px;">{{item?.quotation?.productName }}</td>
</ng-container>
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.price | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="totalPaymentAll">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">จำนวนเงินที่ชำระ</th>
<td mat-cell *matCellDef="let item" class="">
<div class="b-color-green"> {{item.totalPaymentAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="lateFines">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">ค่าปรับ</th>
<td mat-cell *matCellDef="let item" class="">
<div *ngIf="item.lateFines" class="b-color-red"> {{item.lateFines | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="interestLateTotal">
<th mat-header-cell *matHeaderCellDef class="tal" width="150">ค่าชำระล่าช้า</th>
<td mat-cell *matCellDef="let item" class="">
<div *ngIf="item.interestLateTotal" class="b-color-red"> {{item.interestLateTotal | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="deposit">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>จำนวนเงินที่ชำระ</th>
<td mat-cell *matCellDef="let item" class="">
<ng-container *ngIf="item.step === 2">
<div class="b-color-orange" *ngIf="item.transferSummary"> {{item.transferSummary | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="item.step === 3">
<div class="b-color-orange" *ngIf="item.sellerDeposit2ndTime"> {{item.sellerDeposit2ndTime | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="item.step === 4">
<div class="b-color-orange" *ngIf="item.sellerDeposit3rdTime"> {{item.sellerDeposit3rdTime | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="item.step === 5">
<ng-container *ngIf="item.type !== 'close' ">
<div class="b-color-orange" *ngIf="item.priceDisbursement"> {{item.priceDisbursement | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="item.type === 'close' ">
<div class="b-color-orange" *ngIf="item.contractPriceSum"> {{item.contractPriceSum | number : '1.2-2'}}</div>
</ng-container>
</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="wantToInstallmentTerm">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ระยะเวลาผ่อน</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.wantToInstallmentTerm }} งวด</td>
</ng-container>
<ng-container matColumnDef="createdDate">
<th mat-header-cell *matHeaderCellDef class="tac">วันที่ชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">{{item.createdDate | date : 'dd/MM/YYYY'}}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef class="tac">สถานะ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.status === 'paid' " class="status-text status-paid">ชำระแล้ว</div>
<div *ngIf="item.status === 'pending'" class="status-text status-pending">รอชำระ</div>
</td>
</ng-container>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.type === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.type === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
<div *ngIf="item.type === 'pickup'" class="status-text status-installment">เบิกสินค้า</div>
<div *ngIf="item.type === 'receive'" class="status-text status-installment">รับชำระเงิน</div>
<div *ngIf="item.type === 'close'" class="status-text status-installment">ปิดยอด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentType">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>ประเภทการชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentType === 'deposit' " class="status-text status-deposit">ค่ามัดจำ</div>
<div *ngIf="item.paymentType === 'installment'" class="status-text status-installment">ผ่อนสินค้า</div>
<div *ngIf="item.paymentType === 'pickup'" class="status-text status-pickup">เบิกสินค้า</div>
<div *ngIf="item.paymentType === 'receive'" class="status-text status-pickup">รับชำระเงิน</div>
<div *ngIf="item.paymentType === 'close'" class="status-text status-pickup">ปิดยอด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentMethod">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>วิธีชำระ</th>
<td mat-cell *matCellDef="let item" class="tac">
<div *ngIf="item.paymentMethod === 'transfer' " class="status-text status-transfer">โอนเงิน</div>
<div *ngIf="item.paymentMethod === 'cash'" class="status-text status-cash">เงินสด</div>
</td>
</ng-container>
<ng-container matColumnDef="paymentAmountAll">
<th mat-header-cell *matHeaderCellDef class="tac" width="150" mat-sort-header>จำนวนเงิน</th>
<td mat-cell *matCellDef="let item" class="tac">
<div class="b-color-green">{{item.paymentAmountAll | number : '1.2-2'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="dueDate">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>กำหนดชำระ</th>
<td mat-cell *matCellDef="let item" class="">
<div class=""> {{item.dueDate | date : 'dd/MM/YYYY'}}</div>
</td>
</ng-container>
<ng-container matColumnDef="installment">
<th mat-header-cell *matHeaderCellDef class="tal" width="150" mat-sort-header>งวด</th>
<td mat-cell *matCellDef="let item" class="">
<div class=""> {{item.installment }}/{{item?.quotation?.wantToInstallmentTerm }}</div>
</td>
</ng-container>
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef width="80">Action</th>
<td mat-cell *matCellDef="let item">
<div class="action flex justify-center">
<div class="item" *ngIf="item.status === 'pending' ">
<i class="bi bi-pencil-square icon-edit" (click)="onPopup(item.id)"></i>
</div>
<div class="item" *ngIf="item.status === 'pending' ">
<i class="bi bi-filetype-pdf color-red" (click)="onAction(item)"></i>
</div>
<div class="item" *ngIf="item.status === 'paid' && item.paymentImages ">
<i class="bi bi-file-image-fill color-main" (click)="onAttachmentsView(item.paymentImages)"></i>
</div>
<div class="item" *ngIf="item.status === 'paid' ">
<i class="bi bi-filetype-pdf color-red" (click)="onAction(item)"></i>
</div>
</div>
</td>
</ng-container>
</table>
<div *ngIf="dataSource?.length === 0" class="no-data"></div>
</div>
<mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons (page)="getData($event)"></mat-paginator>
</div>
</div>

View File

@@ -1,223 +0,0 @@
import {ChangeDetectorRef, Component, OnInit} from "@angular/core";
import {BaseListComponent} from "../../../../@common/base/base-list.component";
import {debounceTime, distinctUntilChanged, lastValueFrom, Subject} from "rxjs";
import {MatDialog} from "@angular/material/dialog";
import {AppService} from "../../../../app.service";
import {API, EAction, EStatusQuotation, EText} from "../../../../@config/app";
import {ActivatedRoute, Router} from "@angular/router";
import {FinancePaymentUpdateComponent} from "../popup-update/finance-payment-update.component";
import {FinancePaymentCreateComponent} from "../popup-create/finance-payment-create.component";
import {SelectionModel} from "@angular/cdk/collections";
import {FinancePaymentInstallmentComponent} from "../popup-installment/finance-payment-installment.component";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {AttachmentsViewComponent} from "../../../@popup/attachments-view/attachments-view.component";
import generateParamsValue from "../../../../@common/utils/GenerateParamsValue";
@Component({
selector: "app-finance-payment-index",
templateUrl: "./finance-payment-index.component.html",
styleUrls: []
})
export class FinancePaymentIndexComponent extends BaseListComponent implements OnInit {
pageTitle = "รับชำระเงิน/ออกใบเสร็จรับเงิน";
action = "pending";
apiUrl: string = API.quotation;
api: any = API;
selection = new SelectionModel<any>(true, []);
displayedColumns: string[] = [];
masterProductCategory: any = [];
masterProductBrand: any = [];
filterKeyword: Subject<string> = new Subject<string>();
isLoading = false;
constructor(
private dialog: MatDialog,
private router: Router,
public appService: AppService,
public activatedRoute: ActivatedRoute,
public changeDetectorRef: ChangeDetectorRef,
private attachmentsView: MatDialog,
) {
super();
this.filterKeyword.pipe(debounceTime(1000), distinctUntilChanged()).subscribe(model => {
this.getData();
});
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.action = params["action"];
this.dataFilter.status = this.action;
if (!this.action) this.router.navigate(["/pages/finance/payment", EStatusQuotation.PENDING]);
await this.getData();
});
}
async onTabs(action?: any) {
this.dataFilter = {};
this.selection.clear();
return this.router.navigate(["/pages/finance/payment", action]);
}
onAction(item?: any) {
if (item.id && this.action === EStatusQuotation.PENDING) return this.router.navigate([`/pages/finance/payment/${this.action}/pdf-invoice`, item.id]);
if (item.id && this.action === EStatusQuotation.DUE) return this.router.navigate([`/pages/finance/payment/${this.action}/pdf-invoice-installment`, item.id]);
if (item.id) return this.router.navigate([`/pages/finance/payment/${this.action}/pdf`, item.id]);
return;
}
async getData($event?: any) {
try {
this.dataSource = [];
let url = '';
if (this.action === EStatusQuotation.PENDING) {
url = API.quotation;
this.dataFilter.keywordColumn = "quotationNo,productNo,customerFirstName,customerLastName,price,transferSummary,sellerDeposit2ndTime,sellerDeposit3rdTime,priceDisbursement,contractPriceSum";
this.displayedColumns = ["invoice", "action", "price", "deposit", "quotationNo", "customerFirstName", "productNo", "productName", "type"];
}
if (this.action === EStatusQuotation.DUE) {
url = API.quotationDetail;
this.dataFilter.status = 'pending';
this.dataFilter.keywordColumn = "totalPaymentAll,interestLateTotal";
this.displayedColumns = ["invoice", "action", "totalPaymentAll", "interestLateTotal", "quotationNoDetail", "customerFirstNameDetail", "productNoDetail", "productNameDetail", "dueDate", "installment"];
}
if (this.action === EStatusQuotation.PAID) {
url = API.quotationPayment;
this.dataFilter.keywordColumn = "paymentNo,quotationNo,productNo,customerFirstName,customerLastName,paymentAmountAll";
delete this.dataFilter.status;
this.displayedColumns = ["action", "paymentAmountAll", "createdDate", "paymentNo", "customerFirstName", "productNo", "productName", "paymentMethod", "paymentType"];
}
const dataSource = await lastValueFrom(this.appService.get(this.setParams(url, $event)));
this.dataSource = this.setDataSource<any>(dataSource);
} catch (e) {
this.dataSource = [];
}
}
onFilter($event?: any) {
this.filterKeyword.next($event);
}
clearDate($event?: any) {
$event.stopPropagation();
this.dataFilter.createdDate = null;
}
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.length;
return numSelected === numRows;
}
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.forEach((row : any) => this.selection.select(row));
}
async onSort($event: any) {
this.dataFilter.orderBy = $event.active;
this.dataFilter.sort = $event.direction;
await this.getData();
console.log($event);
}
async onPopup(ids?: any) {
this.dialogConfig.data.ids = ids;
let dialogRef = null;
if (this.action === EStatusQuotation.PENDING) {
if (ids) dialogRef = this.dialog.open(FinancePaymentUpdateComponent, this.dialogConfig);
}
if (this.action === EStatusQuotation.DUE) dialogRef = this.dialog.open(FinancePaymentInstallmentComponent, this.dialogConfig);
if (dialogRef) {
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
if (afterClosed === EAction.GET) await this.getData(this.getCurrentPage());
}
}
async onPopupNew() {
const dialogRef = this.dialog.open(FinancePaymentCreateComponent, this.dialogConfig);
if (dialogRef) {
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
if (afterClosed === EAction.GET) await this.getData(this.getCurrentPage());
}
}
async onDelete(ids: any) {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
try {
await lastValueFrom(this.appService.delete(this.apiUrl, ids));
await this.appService.message(EAction.SUCCESS, EText.DELETE);
await this.getData(this.getCurrentPage());
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onInvoice() {
const selected = this.selection.selected;
const data : any = [];
selected.map((item) => {
data.push(item.id)
})
this.isLoading = true;
try {
if (this.action === EStatusQuotation.PENDING) await lastValueFrom(this.appService.post(`${API.quotation}/sendInvoice`, data));
if (this.action === EStatusQuotation.DUE) await lastValueFrom(this.appService.post(`${API.quotationDetail}/sendInvoice`, data));
this.isLoading = false;
this.selection.clear();
await this.appService.message(EAction.SUCCESS, EText.MAIL);
} catch (err) {
this.isLoading = false;
this.appService.message(EAction.ERROR, EText.ERROR);
}
}
async onAttachmentsView(images : any) {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'ไฟล์แนบ';
dialogConfig.data.type = 'images';
dialogConfig.data.images = images;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
onExport() {
const filter = generateParamsValue(this.dataFilter);
let url = '';
if (this.action === EStatusQuotation.PENDING) {
url = `${API.quotation}/export-payment?${filter ? '&' + filter : '' }`;
}
if (this.action === EStatusQuotation.DUE) {
url = `${API.quotationDetail}/export-payment?${filter ? '&' + filter : '' }`;
}
if (this.action === EStatusQuotation.PAID) {
url = `${API.quotationPayment}/export-payment?${filter ? '&' + filter : '' }`;
}
window.open(url);
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,101 +0,0 @@
import {ChangeDetectorRef, Component, OnInit} from "@angular/core";
import {lastValueFrom} from "rxjs";
import {AppService} from "../../../../app.service";
import {API} from "../../../../@config/app";
import {ActivatedRoute, Router} from "@angular/router";
import {DomSanitizer} from "@angular/platform-browser";
import {BaseFormComponent} from "../../../../@common/base/base-form.component";
import {IQuotation} from "../../../../@common/interface/Quotation";
@Component({
selector: "app-finance-payment-pdf",
templateUrl: "./finance-payment-pdf-installment.component.html",
styleUrls: []
})
export class FinancePaymentPdfInstallmentComponent extends BaseFormComponent implements OnInit {
pageTitle = "ใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
paymentMethods : any = {
transfer : "โอนเงิน",
cash : "เงินสด",
}
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotationDetail: any = await lastValueFrom(this.appService.get(`${this.api.quotationDetail}/getById/${this.ids}`));
// const startDate = quotation.startDate ? format(parseISO(quotation.startDate), "dd/MM/yyyy") : null;
const customerPrefix = quotationDetail?.quotation?.customerPrefix ? quotationDetail?.quotation?.customerPrefix : '';
const customerName = quotationDetail?.quotation?.customerId ? `${quotationDetail?.quotation?.customer?.prefix} ${quotationDetail?.quotation?.customer?.firstName} ${quotationDetail?.quotation?.customer?.lastName}` :
`${customerPrefix} ${quotationDetail?.quotation?.customerFirstName} ${quotationDetail?.quotation?.customerLastName}`;
const phone = quotationDetail?.quotation?.customerId ? quotationDetail?.quotation?.customer?.phone : quotationDetail?.quotation?.customerPhone;
const address = quotationDetail?.quotation?.customerId ? quotationDetail?.quotation?.customer?.address : quotationDetail?.quotation?.customerAddress;
let paymentAmountAll: any = 0;
paymentAmountAll = quotationDetail?.totalPayment;
const data: any = {
payment_no: quotationDetail?.quotation?.quotationNo,
due_date: quotationDetail?.quotation?.startDate,
due_dates: "",
customer_name: customerName,
phone: phone ? phone : '',
address: address ? address : '',
data: [
{
item_code: quotationDetail?.quotation.productNo,
item_name_th: quotationDetail?.quotation.productName,
item_amount: Number(paymentAmountAll)
}
],
total_amount: Number(paymentAmountAll),
payee: quotationDetail?.quotation?.userFullName
}
console.log(data)
const pdf = await lastValueFrom(this.appService.post(`${this.api.paymentReport}/pdf`, data, {responseType: "arraybuffer"}));
const url = URL.createObjectURL(new Blob([pdf], {type: "application/pdf"}));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,103 +0,0 @@
import {ChangeDetectorRef, Component, OnInit} from "@angular/core";
import {lastValueFrom} from "rxjs";
import {AppService} from "../../../../app.service";
import {API} from "../../../../@config/app";
import {ActivatedRoute, Router} from "@angular/router";
import {DomSanitizer} from "@angular/platform-browser";
import {BaseFormComponent} from "../../../../@common/base/base-form.component";
import {IQuotation} from "../../../../@common/interface/Quotation";
@Component({
selector: "app-finance-payment-pdf",
templateUrl: "./finance-payment-pdf-invoice.component.html",
styleUrls: []
})
export class FinancePaymentPdfInvoiceComponent extends BaseFormComponent implements OnInit {
pageTitle = "ใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
paymentMethods : any = {
transfer : "โอนเงิน",
cash : "เงินสด",
}
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotation: IQuotation = await lastValueFrom(this.appService.get(`${this.api.quotation}/getById/${this.ids}`));
// const startDate = quotation.startDate ? format(parseISO(quotation.startDate), "dd/MM/yyyy") : null;
const customerPrefix = quotation.customerPrefix ? quotation.customerPrefix : '';
const customerName = quotation?.customerId ? `${quotation.customer?.prefix} ${quotation.customer?.firstName} ${quotation.customer?.lastName}` :
`${customerPrefix} ${quotation.customerFirstName} ${quotation.customerLastName}`;
const phone = quotation?.customerId ? quotation.customer?.phone : quotation.customerPhone;
const address = quotation?.customerId ? quotation.customer?.address : quotation.customerAddress;
let paymentAmountAll: any = 0;
if (quotation.step === 2) paymentAmountAll = quotation.transferSummary;
if (quotation.step === 3) paymentAmountAll = quotation.sellerDeposit2ndTime;
if (quotation.step === 4) paymentAmountAll = quotation.sellerDeposit3rdTime;
if (quotation.step === 5) paymentAmountAll = quotation.priceDisbursement;
const data: any = {
payment_no: quotation.quotationNo,
due_date: quotation.startDate,
due_dates: "",
customer_name: customerName,
phone: phone ? phone : '',
address: address ? address : '',
data: [
{
item_code: quotation.productNo,
item_name_th: quotation.productName,
item_amount: Number(paymentAmountAll)
}
],
total_amount: Number(paymentAmountAll),
payee: quotation?.userFullName
}
console.log(data)
const pdf = await lastValueFrom(this.appService.post(`${this.api.paymentReport}/pdf`, data, {responseType: "arraybuffer"}));
const url = URL.createObjectURL(new Blob([pdf], {type: "application/pdf"}));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,3 +0,0 @@
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>

View File

@@ -1,101 +0,0 @@
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
import { BaseListComponent } from "../../../../@common/base/base-list.component";
import { lastValueFrom } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { AppService } from "../../../../app.service";
import { API } from "../../../../@config/app";
import { ActivatedRoute, Router } from "@angular/router";
import { DomSanitizer } from "@angular/platform-browser";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { IQuotation, IQuotationPayment } from "../../../../@common/interface/Quotation";
import { format, parseISO } from "date-fns";
@Component({
selector: "app-finance-payment-pdf",
templateUrl: "./finance-payment-pdf.component.html",
styleUrls: []
})
export class FinancePaymentPdfComponent extends BaseFormComponent implements OnInit {
pageTitle = "ใบเสนอราคา";
apiUrl: string = API.quotation;
api: any = API;
dataView: any;
pdfView: any;
paymentMethods : any = {
transfer : "โอนเงิน",
cash : "เงินสด",
}
constructor(
public activatedRoute: ActivatedRoute,
public router: Router,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private sanitizer: DomSanitizer
) {
super();
}
async ngOnInit() {
this.activatedRoute.params.subscribe(async params => {
this.ids = params["id"];
await this.getData();
});
}
async getData() {
try {
const quotationPayment : any = await lastValueFrom(this.appService.get(`${this.api.quotationPayment}/getById/${this.ids}`));
// const startDate = quotationPayment.startDate ? format(parseISO(quotation.startDate), "dd/MM/yyyy") : null;
const customerPrefix = quotationPayment.customerPrefix ? quotationPayment.customerPrefix : '';
let customerName = quotationPayment?.quotation?.customerId ? `${quotationPayment.quotation.customer?.prefix} ${quotationPayment.quotation.customer?.firstName} ${quotationPayment.quotation.customer?.lastName}` :
`${customerPrefix} ${quotationPayment.customerFirstName} ${quotationPayment.customerLastName}`;
if (quotationPayment.isQuotationNo) customerName = quotationPayment.customerName;
const phone = quotationPayment?.quotation?.customerId ? quotationPayment?.quotation?.customer?.phone : quotationPayment?.quotation?.customerPhone;
const address = quotationPayment?.quotation?.customerId ? quotationPayment?.quotation?.customer?.address : quotationPayment?.quotation?.customerAddress;
const data: any = {
receipt_no: quotationPayment.paymentNo,
print_date: quotationPayment.createdDate,
print_dates: "",
print_times: "",
customer_name: customerName,
phone: phone ? phone : '',
address: address ? address : '',
data: [
{
item_code: quotationPayment.productNo,
item_name_th: quotationPayment.productName,
item_amount: Number(quotationPayment.paymentAmountAll)
}
],
total_amount: Number(quotationPayment.paymentAmountAll),
pay_by: quotationPayment.paymentMethod ? this.paymentMethods[quotationPayment.paymentMethod] : null,
payee: quotationPayment.quotation?.userFullName
};
const pdf = await lastValueFrom(this.appService.post(`${this.api.receiptReport}/pdf`, data, { responseType: "arraybuffer" }));
const url = URL.createObjectURL(new Blob([pdf], { type: "application/pdf" }));
this.pdfView = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} catch (e) {
console.log(e);
}
}
}

View File

@@ -1,154 +0,0 @@
<form class="dialog-main form-dialog " #ngf="ngForm" (ngSubmit)="onSubmit(ngf)" autocomplete="off">
<div class="dialog-main">
<div class="dialog-header">
<h2>{{title}}</h2>
</div>
<div class="dialog-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<div class="col-span-3 md:col-span-12 ">
<mat-label>เลขที่สัญญา</mat-label>
<ng-select placeholder="เลขที่สัญญา" name="productNo" #productNo="ngModel" [(ngModel)]="dataFilter.productNo" (change)="onChangeFilter($event)" appendTo="body" [required]="!dataForm.isQuotationNo" >
<ng-option *ngFor="let item of quotations" [value]="item.productNo">{{item.productNo}} </ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>วันที่ชำระ</mat-label>
<mat-form-field>
<input
matInput
name="paymentDate"
#paymentDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.paymentDate"
[matDatepicker]="dpkName"
readonly
required
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-6 md:hidden "></div>
<div class="col-span-12 md:col-span-12 ">
<label class="inline-flex items-center cursor-pointer select-none ">
<input type="checkbox" name="isQuotationNo" [(ngModel)]="dataForm.isQuotationNo" >
<span style="padding-left: 2px;">ไม่มีเลขที่สัญญา</span>
</label>
</div>
<ng-container *ngIf="dataForm.isQuotationNo">
<div class="col-span-3 md:col-span-12">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput [(ngModel)]="dataForm.customerName" name="customerName" #customerName="ngModel" required>
<mat-error *ngIf="isFieldValid(ngf, customerName)"> กรุณากรอกข้อมูล</mat-error>
</mat-form-field>
</div>
<div class="col-span-9 md:hidden "></div>
<div class="col-span-6 md:col-span-12">
<mat-label>รายละเอียด</mat-label>
<mat-form-field>
<textarea matInput [(ngModel)]="dataForm.desc" name="desc" #desc="ngModel"></textarea>
<mat-error *ngIf="isFieldValid(ngf, desc)"> กรุณากรอกข้อมูล</mat-error>
</mat-form-field>
</div>
<div class="col-span-6 md:hidden "></div>
</ng-container>
<ng-container *ngIf=" dataForm.quotationNo ">
<div class="col-span-3 md:col-span-12">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput [(ngModel)]="dataForm.customerFirstName" name="customerFirstName" #customerFirstName="ngModel" required>
</mat-form-field>
</div>
<div class="col-span-3 md:col-span-12">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput [(ngModel)]="dataForm.customerLastName" name="customerLastName" #customerLastName="ngModel" >
</mat-form-field>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="customerPhone" #customerPhone="ngModel" [(ngModel)]="dataForm.customerPhone" >
</mat-form-field>
</div>
<div class="col-span-3 md:hidden "></div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>รหัสรายการ</mat-label>
<mat-form-field>
<input matInput name="productNo" #productNo="ngModel" [(ngModel)]="dataForm.productNo" required>
</mat-form-field>
</div>
<div class="col-span-6 md:col-span-12 ">
<mat-label>ชื่อรายการ</mat-label>
<mat-form-field>
<input matInput name="productName" #productName="ngModel" [(ngModel)]="dataForm.productName" required>
</mat-form-field>
</div>
<div class="col-span-3 md:hidden "></div>
</ng-container>
<div class="col-span-3 md:col-span-12 ">
<mat-label>วิธีชำระ</mat-label>
<ng-select placeholder="เลือกวิธีชำระ" name="paymentMethod" #paymentMethod="ngModel" [(ngModel)]="dataForm.paymentMethod" appendTo="body" required>
<ng-option *ngFor="let item of paymentMethods" [value]="item.value">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>จำนวนเงินที่ต้องการชำระ</mat-label>
<mat-form-field>
<input matInput name="paymentAmount" #paymentAmount="ngModel" [(ngModel)]="dataForm.paymentAmount" required>
</mat-form-field>
</div>
<div class="col-span-12">
<div class="mt-4">
<input hidden type="file" accept="image/*" #uploadFile (change)="onAttachments($event)"/>
<button type="button" class="btn btn-sm btn-success-o" (click)="uploadFile.click()">เพิ่มแนบไฟล์</button>
</div>
<div class="list-images" *ngIf="dataForm.paymentImages" style="min-height: auto !important;">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i (click)="onRemoveAttachments()" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img (click)="onAttachmentsView()" src="{{storage.images}}/{{dataForm.paymentImages}}" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="dialog-footer">
<button type="submit" class="btn btn-submit" >บันทึก</button>
<button type="button" mat-dialog-close class="btn btn-dialog-close">ยกเลิก</button>
</div>
</div>
</form>

View File

@@ -1,128 +0,0 @@
import {ChangeDetectorRef, Component, Inject, OnInit, ViewChild} from "@angular/core";
import { API, EAction, EText, STORAGE } from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import { BaseFormComponent } from "../../../../@common/base/base-form.component";
import { ActivatedRoute, Router } from "@angular/router";
import { IProduct } from "../../../../app.interface";
import { addMonths } from "date-fns";
import { BasePopupComponent } from "../../../../@common/base/base-popup.component";
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
import { IDialogConfigData } from "../../../../@common/interface/Dialog";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {AttachmentsViewComponent} from "../../../@popup/attachments-view/attachments-view.component";
@Component({
selector: "app-finance-payment-do",
templateUrl: "./finance-payment-create.component.html",
styleUrls: []
})
export class FinancePaymentCreateComponent extends BasePopupComponent implements OnInit {
title = 'รับชำระเงิน/ออกใบเสร็จ';
apiUrl: string = API.quotationPayment;
paymentTypes = [
{value : 'deposit', name : 'ค่ามัดจำ'},
{value : 'installment', name : 'ผ่อนสินค้า'},
];
paymentMethods = [
{value : 'transfer', name : 'โอนเงิน'},
{value : 'cash', name : 'เงินสด'},
]
quotations : any = [];
dataFilter : any = {};
storage: any = STORAGE;
@ViewChild('uploadFile') uploadFile: any;
constructor(
public dialogRef: MatDialogRef<FinancePaymentCreateComponent>,
@Inject(MAT_DIALOG_DATA) public dialog : IDialogConfigData,
public changeDetectorRef: ChangeDetectorRef,
public appService: AppService,
private attachmentsView: MatDialog,
) {
super();
}
async ngOnInit() {
this.quotations = await lastValueFrom(this.appService.get(`${API.quotation}?showAll=true&statusContract=approved`));
this.dataForm.paymentDate = new Date();
this.dataForm.typeCode = this.quotations.typeCode;
}
async onChangeFilter(ev : any) {
this.dataForm = {};
if (!ev) return;
const data = this.quotations.find((f : any) => f.productNo === ev);
this.dataForm = data ? data : {};
this.dataForm.paymentDate = new Date();
}
async onSubmit(form : any) {
if (!form.valid) return false;
return await this.onCreate();
}
async onCreate() {
try {
this.dataForm.quotationId = this.dataForm.id;
this.dataForm.paymentType = 'receive';
this.dataForm.paymentAmountAll = Number(this.dataForm.paymentAmount);
this.dataForm.type = 'receive';
delete this.dataForm.id;
delete this.dataForm.seller;
delete this.dataForm.customer;
this.dataForm.pageAction = 'PopupCreate';
await lastValueFrom(this.appService.post(this.apiUrl, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.CREATE);
await this.dialogRef.close(EAction.GET);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
this.dialogRef.close(EAction.GET);
}
}
async onAttachments($event: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", 'images');
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData));
this.dataForm.paymentImages = res.fileName;
this.uploadFile.nativeElement.value = null;
console.log(this.uploadFile)
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments() {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.dataForm.paymentImages = null;
this.changeDetectorRef.detectChanges();
}
async onAttachmentsView() {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'ไฟล์แนบ';
dialogConfig.data.type = 'images';
dialogConfig.data.images = this.dataForm.paymentImages;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
}

View File

@@ -1,148 +0,0 @@
<form class="dialog-main form-dialog " #ngf="ngForm" (ngSubmit)="onSubmit(ngf)" autocomplete="off">
<div class="dialog-main">
<div class="dialog-header">
<h2>{{title}}</h2>
</div>
<div class="dialog-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<div class="col-span-4 md:col-span-12">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput [(ngModel)]="dataForm.customerFirstName" name="customerFirstName" #customerFirstName="ngModel" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput [(ngModel)]="dataForm.customerLastName" name="customerLastName" #customerLastName="ngModel" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="customerPhone" #customerPhone="ngModel" [(ngModel)]="dataForm.customerPhone" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เลขที่ใบเสร็จ</mat-label>
<mat-form-field>
<input matInput name="quotationNo" #quotationNo="ngModel" [(ngModel)]="dataForm.quotationNo" disabled>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>วันที่ชำระ</mat-label>
<mat-form-field>
<input
matInput
name="paymentDate"
#paymentDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.paymentDate"
[matDatepicker]="dpkName"
readonly
required
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<div class="table-wrap" >
<table class="tables table-sty-2">
<thead>
<tr>
<th>BOM</th>
<th>Model</th>
<th>Brand</th>
<th>งวดที่</th>
<th>กำหนดจ่ายวันที่ <br>Due date</th>
<th>เงินต้น <br>Principle</th>
<th>ดอกเบี้ย(บาท) <br>Interest Total</th>
<th>Bank fee, <br>Insurance ,Storage</th>
<th>ค่าชำระล่าช้า</th>
<th>รวมยอดจ่ายต่อเดือน <br>Total payment</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">{{dataForm?.quotation?.productNo}}</td>
<td class="text-center">{{dataForm?.quotation?.productName }}</td>
<td class="text-center">{{dataForm?.quotation?.productBrandName}}</td>
<td class="text-center"> {{dataForm.installment }}/{{dataForm?.quotation?.wantToInstallmentTerm}} </td>
<td class="text-center">{{dataForm.dueDate | date : 'dd/MM/YYYY'}}</td>
<td class="text-center">{{dataForm.principle | number : '1.2-2'}}</td>
<td class="text-center">{{dataForm.interestTotal | number : '1.2-2'}}</td>
<td class="text-center">{{dataForm.fee | number : '1.2-2'}}</td>
<td class="text-center">
<div class="b-color-red" *ngIf="dataForm.interestLateTotal">
{{dataForm.interestLateTotal | number : '1.2-2'}}
</div>
</td>
<td class="text-center">
<div class="b-color-orange" *ngIf="dataForm.totalPaymentAll"> {{dataForm.totalPaymentAll | number : '1.2-2'}}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>วิธีชำระ</mat-label>
<ng-select placeholder="เลือกวิธีชำระ" name="paymentMethod" #paymentMethod="ngModel" [(ngModel)]="dataForm.paymentMethod" required>
<ng-option *ngFor="let item of paymentMethods" [value]="item.value">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>จำนวนเงินที่ต้องชำระทั้งสิ้น</mat-label>
<mat-form-field>
<input matInput appCurrencyInputMask name="paymentAmountAll" #paymentAmountAll="ngModel" [(ngModel)]="dataForm.paymentAmountAll" required>
</mat-form-field>
</div>
<div class="col-span-12">
<div class="mt-4">
<input hidden type="file" accept="image/*" #uploadFile (change)="onAttachments($event)"/>
<button type="button" class="btn btn-sm btn-success-o" (click)="uploadFile.click()">เพิ่มแนบไฟล์</button>
</div>
<div class="list-images" *ngIf="dataForm.paymentImages" style="min-height: auto !important;">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i (click)="onRemoveAttachments()" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img (click)="onAttachmentsView()" src="{{storage.images}}/{{dataForm.paymentImages}}" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="dialog-footer">
<button type="submit" class="btn btn-submit" >บันทึก</button>
<button type="button" mat-dialog-close class="btn btn-dialog-close">ยกเลิก</button>
</div>
</div>
</form>

View File

@@ -1,128 +0,0 @@
import {ChangeDetectorRef, Component, Inject, OnInit, ViewChild} from "@angular/core";
import {API, EAction, EText, STORAGE} from "../../../../@config/app";
import {AppService} from "../../../../app.service";
import {lastValueFrom} from "rxjs";
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
import {IDialogConfigData} from "../../../../@common/interface/Dialog";
import {BasePopupComponent} from "../../../../@common/base/base-popup.component";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {AttachmentsViewComponent} from "../../../@popup/attachments-view/attachments-view.component";
@Component({
selector: "app-finance-payment-do",
templateUrl: "./finance-payment-installment.component.html",
styleUrls: []
})
export class FinancePaymentInstallmentComponent extends BasePopupComponent implements OnInit {
title = "รับชำระเงิน/ออกใบเสร็จ";
apiUrl: string = API.quotationDetail;
storage: any = STORAGE;
paymentTypes = [
{value: "deposit", name: "ค่ามัดจำ"},
{value: "installment", name: "ผ่อนสินค้า"}
];
paymentMethods = [
{value: "transfer", name: "โอนเงิน"},
{value: "cash", name: "เงินสด"}
];
@ViewChild('uploadFile') uploadFile: any;
constructor(
public dialogRef: MatDialogRef<FinancePaymentInstallmentComponent>,
@Inject(MAT_DIALOG_DATA) public dialog: IDialogConfigData,
public changeDetectorRef: ChangeDetectorRef,
private attachmentsView: MatDialog,
public appService: AppService
) {
super();
}
async ngOnInit() {
await this.getData();
}
async getData() {
if (!this.dialog.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
this.ids = this.dialog.ids;
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.apiUrl}/getById/${this.ids}`));
this.dataForm.paymentDate = new Date();
this.dataForm.paymentType = 'installment';
this.dataForm.quotationDetailId = this.dataForm.id;
this.dataForm.quotationNo = this.dataForm?.quotation?.quotationNo;
this.dataForm.productNo = this.dataForm?.quotation?.productNo;
this.dataForm.productName = this.dataForm?.quotation?.productName;
this.dataForm.customerFirstName = this.dataForm?.quotation?.customerFirstName;
this.dataForm.customerLastName = this.dataForm?.quotation?.customerLastName;
this.dataForm.customerPhone = this.dataForm?.quotation?.customerPhone;
this.dataForm.paymentAmountAll = this.dataForm.totalPaymentAll;
this.dataForm.typeCode = this.dataForm?.quotation?.typeCode;
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
this.dialogRef.close();
}
}
async onSubmit(form: any) {
if (!form.valid) return false;
return await this.onCreate();
}
async onCreate() {
try {
await lastValueFrom(this.appService.post(API.quotationPayment, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.CREATE);
await this.dialogRef.close(EAction.GET);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
this.dialogRef.close(EAction.GET);
}
}
async onAttachments($event: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", 'images');
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData));
this.dataForm.paymentImages = res.fileName;
this.uploadFile.nativeElement.value = null;
console.log(this.uploadFile)
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments() {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.dataForm.paymentImages = null;
this.changeDetectorRef.detectChanges();
}
async onAttachmentsView() {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'ไฟล์แนบ';
dialogConfig.data.type = 'images';
dialogConfig.data.images = this.dataForm.paymentImages;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
protected readonly STORAGE = STORAGE;
}

View File

@@ -1,173 +0,0 @@
<form class="dialog-main form-dialog " #ngf="ngForm" (ngSubmit)="onSubmit(ngf)" autocomplete="off">
<div class="dialog-main">
<div class="dialog-header">
<h2>{{title}}</h2>
</div>
<div class="dialog-body">
<div class="grid grid-cols-12 gap-4 md:gap-2 ">
<div class="col-span-4 md:col-span-12">
<mat-label>ชื่อลูกค้า</mat-label>
<mat-form-field>
<input matInput [(ngModel)]="dataForm.customerFirstName" name="customerFirstName" #customerFirstName="ngModel" required>
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12">
<mat-label>นามสกุล</mat-label>
<mat-form-field>
<input matInput [(ngModel)]="dataForm.customerLastName" name="customerLastName" #customerLastName="ngModel" >
</mat-form-field>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>เบอร์โทร</mat-label>
<mat-form-field>
<input matInput name="customerPhone" #customerPhone="ngModel" [(ngModel)]="dataForm.customerPhone" >
</mat-form-field>
</div>
<!-- <div class="col-span-4 md:col-span-12 ">-->
<!-- <mat-label>เลขที่ใบเสร็จ</mat-label>-->
<!-- <mat-form-field>-->
<!-- <input matInput name="quotationNo" #quotationNo="ngModel" [(ngModel)]="dataForm.quotationNo" >-->
<!-- </mat-form-field>-->
<!-- </div>-->
<div class="col-span-4 md:col-span-12 ">
<mat-label>วันที่ชำระ</mat-label>
<mat-form-field>
<input
matInput
name="paymentDate"
#paymentDate="ngModel"
(click)="dpkName.open()"
[(ngModel)]="dataForm.paymentDate"
[matDatepicker]="dpkName"
readonly
required
/>
<mat-datepicker-toggle [for]="dpkName" matSuffix></mat-datepicker-toggle>
<mat-datepicker #dpkName></mat-datepicker>
</mat-form-field>
</div>
<div class="col-span-12 md:col-span-12 ">
<div class="table-wrap" >
<table class="tables table-sty-2">
<thead>
<tr>
<th>เลขที่เอกสาร</th>
<th>BOM</th>
<th>Model</th>
<th>Brand</th>
<th>ประเภทการชำระ</th>
<th>ระยะเวลาผ่อน</th>
<th>จำนวนเงิน</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center">{{dataForm.quotationNo }}</td>
<td class="text-center">{{dataForm.productNo}}</td>
<td class="text-center">{{dataForm.productName }}</td>
<td class="text-center">{{dataForm.productBrandName}}</td>
<td class="text-center">
<div *ngIf="dataForm.type === 'deposit' " class="status status-active">ค่ามัดจำ</div>
<div *ngIf="dataForm.type === 'installment'" class="status status-disabled">ผ่อนสินค้า</div>
<div *ngIf="dataForm.type === 'pickup'" class="status-text status-installment">เบิกสินค้า</div>
<div *ngIf="dataForm.type === 'close'" class="status-text status-installment">ปิดยอด</div>
</td>
<td class="text-center">{{dataForm.wantToInstallmentTerm}} งวด</td>
<td class="text-center">
<ng-container *ngIf="dataForm.step === 2">
<div class="b-color-orange" *ngIf="dataForm.transferSummary"> {{dataForm.transferSummary | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="dataForm.step === 3">
<div class="b-color-orange" *ngIf="dataForm.sellerDeposit2ndTime"> {{dataForm.sellerDeposit2ndTime | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="dataForm.step === 4">
<div class="b-color-orange" *ngIf="dataForm.sellerDeposit3rdTime"> {{dataForm.sellerDeposit3rdTime | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="dataForm.step === 5">
<ng-container *ngIf="dataForm.type !== 'close' ">
<div class="b-color-orange" *ngIf="dataForm.priceDisbursement"> {{dataForm.priceDisbursement | number : '1.2-2'}}</div>
</ng-container>
<ng-container *ngIf="dataForm.type === 'close' ">
<div class="b-color-orange" *ngIf="dataForm.contractPriceSum"> {{dataForm.contractPriceSum | number : '1.2-2'}}</div>
</ng-container>
</ng-container>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<ng-container *ngIf=" dataForm.type !== 'close' ">
<div class="col-span-2 md:col-span-12 ">
<div style="height: 15px;"></div>
<mat-checkbox name="checked" #checked="ngModel" [(ngModel)]="dataForm.checked">ชำระเงินเพิ่ม</mat-checkbox>
</div>
<div class="col-span-4 md:col-span-12 ">
<mat-label>จำนวนเงินที่ชำระ</mat-label>
<mat-form-field>
<input matInput appCurrencyInputMask name="paymentAmount" #paymentAmount="ngModel" [(ngModel)]="dataForm.paymentAmount"
(ngModelChange)="onChange($event, 'paymentAmount')" appendTo="body" required [disabled]="!dataForm.checked">
</mat-form-field>
</div>
<div class="col-span-6 md:hidden"></div>
</ng-container>
<div class="col-span-3 md:col-span-12 ">
<mat-label>วิธีชำระ</mat-label>
<ng-select placeholder="เลือกวิธีชำระ" name="paymentMethod" #paymentMethod="ngModel" [(ngModel)]="dataForm.paymentMethod" required>
<ng-option *ngFor="let item of paymentMethods" [value]="item.value">{{item.name}}</ng-option>
</ng-select>
</div>
<div class="col-span-3 md:col-span-12 ">
<mat-label>จำนวนเงินที่ต้องชำระทั้งสิ้น</mat-label>
<mat-form-field>
<input matInput appCurrencyInputMask name="paymentAmountAll" #paymentAmountAll="ngModel" [(ngModel)]="dataForm.paymentAmountAll" required>
</mat-form-field>
</div>
<div class="col-span-12">
<div class="mt-4">
<input hidden type="file" accept="image/*" #uploadFile (change)="onAttachments($event)"/>
<button type="button" class="btn btn-sm btn-success-o" (click)="uploadFile.click()">เพิ่มแนบไฟล์</button>
</div>
<div class="list-images" *ngIf="dataForm.paymentImages" style="min-height: auto !important;">
<div class=" grid grid-cols-12 gap-2 md:gap-2 items-center">
<div class="col-span-2 md:col-span-4">
<div class="flex justify-center items-center list-images-item">
<div class="list-images-action">
<i (click)="onRemoveAttachments()" class="bi bi-x-circle color-red cursor-pointer select-none"></i>
</div>
<img (click)="onAttachmentsView()" src="{{storage.images}}/{{dataForm.paymentImages}}" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="dialog-footer">
<button type="submit" class="btn btn-submit" >บันทึก</button>
<button type="button" mat-dialog-close class="btn btn-dialog-close">ยกเลิก</button>
</div>
</div>
</form>

View File

@@ -1,145 +0,0 @@
import {ChangeDetectorRef, Component, ElementRef, Inject, OnInit, ViewChild} from "@angular/core";
import {API, EAction, EText, STORAGE} from "../../../../@config/app";
import { AppService } from "../../../../app.service";
import { lastValueFrom } from "rxjs";
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
import { IDialogConfigData } from "../../../../@common/interface/Dialog";
import { BasePopupComponent } from "../../../../@common/base/base-popup.component";
import { data } from "autoprefixer";
import deepCopy from "../../../../@common/utils/DeepCopy";
import {AttachmentsViewComponent} from "../../../@popup/attachments-view/attachments-view.component";
@Component({
selector: "app-finance-payment-do",
templateUrl: "./finance-payment-update.component.html",
styleUrls: []
})
export class FinancePaymentUpdateComponent extends BasePopupComponent implements OnInit {
title = "รับชำระเงิน/ออกใบเสร็จ";
apiUrl: string = API.quotation;
paymentTypes = [
{ value: "deposit", name: "ค่ามัดจำ" },
{ value: "installment", name: "ผ่อนสินค้า" }
];
paymentMethods = [
{ value: "transfer", name: "โอนเงิน" },
{ value: "cash", name: "เงินสด" }
];
storage: any = STORAGE;
@ViewChild('uploadFile') uploadFile: any;
constructor(
public dialogRef: MatDialogRef<FinancePaymentUpdateComponent>,
@Inject(MAT_DIALOG_DATA) public dialog: IDialogConfigData,
public changeDetectorRef: ChangeDetectorRef,
private attachmentsView: MatDialog,
public appService: AppService
) {
super();
}
async ngOnInit() {
await this.getData();
}
async getData() {
if (!this.dialog.ids) this.appService.message(EAction.INFO, EText.NO_DATA);
this.ids = this.dialog.ids;
try {
this.dataForm = await lastValueFrom(this.appService.get(`${this.apiUrl}/getById/${this.ids}`));
this.dataForm.paymentAmountAll = this.dataForm.deposit;
this.dataForm.paymentDate = this.dataForm.startDate;
this.dataForm.paymentType = this.dataForm.type;
this.dataForm.quotationId = this.ids;
if (this.dataForm.step === 2) this.dataForm.paymentAmountAll = this.dataForm.transferSummary;
if (this.dataForm.step === 3) this.dataForm.paymentAmountAll = this.dataForm.sellerDeposit2ndTime;
if (this.dataForm.step === 4) this.dataForm.paymentAmountAll = this.dataForm.sellerDeposit3rdTime;
if (this.dataForm.step === 5) {
if (this.dataForm.type !== 'close') this.dataForm.paymentAmountAll = this.dataForm.priceDisbursement;
if (this.dataForm.type === 'close') this.dataForm.paymentAmountAll = this.dataForm.contractPriceSum;
}
this.changeDetectorRef.detectChanges();
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
this.dialogRef.close();
}
}
onChange($event: any, key?: string) {
if (key) this.dataForm[key] = $event;
if (key === "paymentAmount" ) {
const paymentAmount = this.dataForm.paymentAmount ? this.dataForm.paymentAmount : 0;
let deposit = 0
if (this.dataForm.step === 2) deposit = this.dataForm.transferSummary;
if (this.dataForm.step === 3) deposit = this.dataForm.sellerDeposit2ndTime;
if (this.dataForm.step === 4) deposit = this.dataForm.sellerDeposit3rdTime;
this.dataForm.paymentAmountAll = Number(paymentAmount) + Number(deposit);
}
this.changeDetectorRef.detectChanges();
}
async onSubmit(form: any) {
if (!form.valid) return false;
return await this.onCreate();
}
async onCreate() {
try {
await lastValueFrom(this.appService.post(API.quotationPayment, this.dataForm));
await this.appService.message(EAction.SUCCESS, EText.CREATE);
await this.dialogRef.close(EAction.GET);
} catch (err) {
this.appService.message(EAction.ERROR, EText.ERROR);
this.dialogRef.close(EAction.GET);
}
}
async onAttachments($event: any) {
const file = $event.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append("ref", 'images');
formData.append("file", file);
try {
const res = await lastValueFrom(this.appService.post(`${API.attachments}/images`, formData));
this.dataForm.paymentImages = res.fileName;
this.uploadFile.nativeElement.value = null;
console.log(this.uploadFile)
this.changeDetectorRef.detectChanges();
} catch (e) {
this.appService.message(EText.ERROR);
}
}
async onRemoveAttachments() {
const sweetalert = await lastValueFrom(this.appService.confirm(EAction.DELETE));
if (!sweetalert.isConfirmed) return;
// await lastValueFrom(this.appService.delete(`${this.api.attachments}/deleteByName`, fileName));
this.dataForm.paymentImages = null;
this.changeDetectorRef.detectChanges();
}
async onAttachmentsView() {
const dialogConfig = deepCopy(this.dialogConfig);
dialogConfig.data.action = EAction.POPUP;
dialogConfig.data.title = 'ไฟล์แนบ';
dialogConfig.data.type = 'images';
dialogConfig.data.images = this.dataForm.paymentImages;
const dialogRef = this.attachmentsView.open(AttachmentsViewComponent, dialogConfig);
const afterClosed = await lastValueFrom(dialogRef.afterClosed());
}
}

View File

@@ -0,0 +1 @@
<app-list [kycList]="kyc$ | async"></app-list>

View File

@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { KycContainer } from './kyc.container';
describe('KycContainer', () => {
let component: KycContainer;
let fixture: ComponentFixture<KycContainer>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ KycContainer ]
})
.compileComponents();
fixture = TestBed.createComponent(KycContainer);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,17 @@
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { KycService } from 'src/app/core/service/manage/kyc.service';
@Component({
selector: 'app-kyc',
templateUrl: './kyc.container.html',
styleUrls: ['./kyc.container.scss']
})
export class KycContainer {
kyc$ = new Observable();
constructor(
private kycService: KycService
) {
this.kyc$ = this.kycService.getAll();
}
}

View File

@@ -0,0 +1,35 @@
import { NgOptimizedImage } from "@angular/common";
import { RouterModule, Routes } from "@angular/router";
import { AppSharedModule } from "src/app/app.shared";
import { KycRouter } from "./router/router";
import { KycContainer } from "./container/kyc/kyc.container";
import { NgModule } from "@angular/core";
import { ListComponent } from "./presenter/list/list.component";
const routes: Routes = [
{
path: '',
component: KycRouter,
children: [
{
path: '',
component: KycContainer
}
]
}
]
@NgModule({
declarations: [
KycRouter,
KycContainer,
ListComponent
],
imports: [
AppSharedModule,
NgOptimizedImage,
RouterModule.forChild(routes)
]
})
export class KycModule { }

Some files were not shown because too many files have changed in this diff Show More