[init] init version
This commit is contained in:
11
src/app/pages/@comingsoon/comingsoon.component.html
Normal file
11
src/app/pages/@comingsoon/comingsoon.component.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="panel-header">
|
||||
PAGE
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="card">
|
||||
<div class="card-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
15
src/app/pages/@comingsoon/comingsoon.component.ts
Normal file
15
src/app/pages/@comingsoon/comingsoon.component.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-comingsoon',
|
||||
templateUrl: './comingsoon.component.html',
|
||||
styles: []
|
||||
})
|
||||
export class ComingsoonComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
144
src/app/pages/@layouts/layouts.component.html
Normal file
144
src/app/pages/@layouts/layouts.component.html
Normal file
@@ -0,0 +1,144 @@
|
||||
<div class="layouts" [class.active-sidebar]="isToggleSidebar">
|
||||
<div class="main-sidebar">
|
||||
<div class="main-sidebar-container">
|
||||
<div class="main-menu">
|
||||
|
||||
<section class="main-menu-heading">
|
||||
<div class="sm:hidden btn-toggle ">
|
||||
<button type="button" class="btn-icon" (click)="toggleSidebar()">
|
||||
<i class="bi bi-justify"></i>
|
||||
</button>
|
||||
</div>
|
||||
<img class="logo-main" src="./assets/images/logo.png" />
|
||||
<img class="logo-icon" src="./assets/images/logo-icon.png" />
|
||||
</section>
|
||||
|
||||
<nav class="main-menu-nav">
|
||||
<ng-template #menuTemplate let-menus>
|
||||
<div *ngFor="let item of menus; let i = index">
|
||||
<ng-container *ngIf="roleCheck(item.permission)">
|
||||
<ng-container [ngSwitch]="item.type">
|
||||
<ng-container *ngSwitchCase="'heading'">
|
||||
<div class="menu-heading">{{ item.name }}</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="'link'">
|
||||
<a class="menu-item" [routerLink]="[item.link]">
|
||||
<div routerLinkActive="active" matRipple
|
||||
class="menu-item-wrap flex items-center">
|
||||
<div class="menu-item-icon"><i
|
||||
class="{{ item.icon || 'icon-sm bi bi-circle-fill' }}"></i>
|
||||
</div>
|
||||
<div class="menu-item-text">{{ item.name }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngSwitchCase="'collapsable'">
|
||||
<a class="menu-item menu-main-item" (click)="item.collapsed = !item.collapsed">
|
||||
<div matRipple class="menu-item-wrap flex items-center">
|
||||
<div class="menu-item-icon"><i
|
||||
class="{{ item.icon || 'icon-sm bi bi-circle-fill' }}"></i>
|
||||
</div>
|
||||
<div class="menu-item-text">{{ item.name }}</div>
|
||||
<div class="menu-item-action ml-auto">
|
||||
<i *ngIf="item.collapsed" class="bi bi-chevron-down"></i>
|
||||
<i *ngIf="!item.collapsed" class="bi bi-chevron-up"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div *ngIf="item.children && item.collapsed" class="menu-item-children">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="menuTemplate; context:{ $implicit: item.children }"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-container *ngTemplateOutlet="menuTemplate; context:{ $implicit: menus }"></ng-container>
|
||||
|
||||
<a class="menu-item menu-main-item" (click)="logout()">
|
||||
<div matRipple class="menu-item-wrap flex items-center">
|
||||
<div class="menu-item-icon"><i class="bi bi-power"></i></div>
|
||||
<div class="menu-item-text">ออกจากระบบ</div>
|
||||
</div>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-content ">
|
||||
|
||||
<header class="main-content-header flex items-center">
|
||||
<div class="sm:block hidden btn-toggle">
|
||||
<button type="button" class="btn-icon" (click)="toggleSidebar()">
|
||||
<i class="bi bi-justify"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="sm:hidden font-bold flex flex-col">
|
||||
<span class="text-sm">CATHAY INTERNATIONAL</span>
|
||||
<span class="text-xs">Shopping Center</span>
|
||||
</div>
|
||||
<div class="title-mobile">
|
||||
<div class="text"></div>
|
||||
<div class="img">
|
||||
<img src="./assets/images/logo.png" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto flex items-center ">
|
||||
<div class="top-bar-user flex items-center" [matMenuTriggerFor]="menu">
|
||||
<div class="top-bar-user-icon">
|
||||
<i class="bi bi-person-circle"></i>
|
||||
</div>
|
||||
<div class="top-bar-user-text md:hidden">
|
||||
<div class="name">{{auth?.name || '-'}}</div>
|
||||
<div class="role"> {{auth?.email || '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
<div class="main-content-toolbar flex items-center">
|
||||
<div *ngFor="let item of breadcrumb; let i = index">
|
||||
<ng-container *ngIf="i === 0"> {{item.name}}</ng-container>
|
||||
<ng-container *ngIf="i > 0 && i +1 !== breadcrumb.length">
|
||||
<span>></span>
|
||||
<a [routerLink]="[item.link]"> {{item.name}} </a>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="i +1 === breadcrumb.length">
|
||||
<span>></span>
|
||||
<a> {{item.name}} </a>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-content-container">
|
||||
<div id="main-top"></div>
|
||||
|
||||
<router-outlet (deactivate)="onDeactivate()"></router-outlet>
|
||||
</div>
|
||||
<div class="main-overlay">
|
||||
<div class="overlay-wrap" (click)="closeSidebar()"></div>
|
||||
<button type="button" class="btn-icon close-icon" (click)="closeSidebar()"><i
|
||||
class="bi bi-x-lg"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<mat-menu #menu="matMenu">
|
||||
<!-- <a mat-menu-item [routerLink]="['/pages', 'account','change-password' ]" style="color: #83A5B9">-->
|
||||
<!-- <i class="bi bi-key"></i>-->
|
||||
<!-- เปลี่ยนรหัสผ่าน-->
|
||||
<!-- </a>-->
|
||||
<a mat-menu-item (click)="logout()">
|
||||
<i class="bi bi-power"></i>
|
||||
ออกจากระบบ
|
||||
</a>
|
||||
</mat-menu>
|
||||
127
src/app/pages/@layouts/layouts.component.ts
Normal file
127
src/app/pages/@layouts/layouts.component.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
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({
|
||||
selector: 'app-pages-layouts',
|
||||
templateUrl: './layouts.component.html',
|
||||
styles: [],
|
||||
})
|
||||
export class PagesLayoutsComponent implements OnInit {
|
||||
|
||||
menus = MENU;
|
||||
isToggleSidebar = false;
|
||||
innerWidth: any;
|
||||
auth: any = {};
|
||||
isCollapsed: any = [];
|
||||
breadcrumb: any = [];
|
||||
permissionCheck = false;
|
||||
permission: any = [];
|
||||
|
||||
constructor(
|
||||
private app: AppService,
|
||||
private router: Router,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
public changeDetectorRef: ChangeDetectorRef,
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.onCollapsed();
|
||||
this.getBreadcrumb();
|
||||
await this.initAuth();
|
||||
this.changeDetectorRef.markForCheck()
|
||||
}
|
||||
async initAuth() {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
roleCheck(perm: string){
|
||||
if(!environment.production) return true
|
||||
return this.permission.includes(perm)
|
||||
}
|
||||
|
||||
getBreadcrumb() {
|
||||
this.breadcrumb = [];
|
||||
let router: any = this.router.url;
|
||||
router = router.split('/');
|
||||
this.mapBreadcrumb(router, this.menus)
|
||||
this.changeDetectorRef.markForCheck()
|
||||
|
||||
}
|
||||
|
||||
mapBreadcrumb(router: any, items: any) {
|
||||
items.map((item: any) => {
|
||||
this.addItemBreadcrumb(router, item);
|
||||
if (item.children) this.mapBreadcrumb(router, item.children);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
addItemBreadcrumb(router: any, item: any) {
|
||||
|
||||
const data = {
|
||||
name: item.name,
|
||||
link: item.link,
|
||||
}
|
||||
if (router[2]) {
|
||||
if (item.link === router[2]) this.breadcrumb.push(data);
|
||||
}
|
||||
if (router[3]) {
|
||||
if (item.link === `${router[2]}/${router[3]}`) this.breadcrumb.push(data);
|
||||
}
|
||||
if (router[4]) {
|
||||
if (item.link === `${router[2]}/${router[3]}/${router[4]}`) this.breadcrumb.push(data);
|
||||
}
|
||||
if (router[5]) {
|
||||
if (item.link === `${router[2]}/${router[3]}/${router[4]}/${router[5]}`) this.breadcrumb.push(data);
|
||||
}
|
||||
if (router[6]) {
|
||||
if (item.link === `${router[2]}/${router[3]}/${router[4]}/${router[5]}/${router[6]}`) this.breadcrumb.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
onCollapsed() {
|
||||
let router: any = this.router.url;
|
||||
router = router.split('/');
|
||||
this.menus.forEach((item: any, i: number) => {
|
||||
// item.collapsed = false;
|
||||
if (item.type === 'collapsable') {
|
||||
if (router.includes(item.link)) {
|
||||
item.collapsed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.app.logout();
|
||||
return this.router.navigate(['/auth']);
|
||||
}
|
||||
|
||||
|
||||
toggleSidebar() {
|
||||
this.isToggleSidebar = !this.isToggleSidebar;
|
||||
}
|
||||
|
||||
closeSidebar() {
|
||||
this.isToggleSidebar = false;
|
||||
}
|
||||
|
||||
onDeactivate() {
|
||||
this.ngOnInit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<div class="dialog-main">
|
||||
<div class="dialog-header">
|
||||
<h2>{{title}}</h2>
|
||||
</div>
|
||||
<div class="dialog-body">
|
||||
|
||||
<ng-container *ngIf="viewType === 'images' ">
|
||||
<div class="tac">
|
||||
<img src="{{viewPath}}/{{dialog.images}}" style="max-width: 100%" alt="">
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="viewType === 'vdo' ">
|
||||
<div class="video">
|
||||
<video controls #videoPlayer>
|
||||
<source src="{{viewPath}}/{{dialog.images}}" type="video/mp4" />
|
||||
Browser not supported
|
||||
</video>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
<div class="dialog-footer">
|
||||
|
||||
<button type="button" (click)="onClose()" class="btn btn-dialog-close">ปิด</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,63 @@
|
||||
import { ChangeDetectorRef, Component, Inject, OnInit } from "@angular/core";
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
|
||||
import { BasePopupComponent } from "../../../@common/base/base-popup.component";
|
||||
import { API, EAction, STORAGE } from "../../../@config/app";
|
||||
import { AppService } from "../../../app.service";
|
||||
import { Router } from "@angular/router";
|
||||
import { NgIf } from "@angular/common";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "app-attachments-view",
|
||||
templateUrl: "./attachments-view.component.html",
|
||||
styleUrls: [],
|
||||
imports: [
|
||||
NgIf
|
||||
],
|
||||
standalone: true
|
||||
})
|
||||
export class AttachmentsViewComponent extends BasePopupComponent implements OnInit {
|
||||
|
||||
title = "รายละเอียด";
|
||||
api = API;
|
||||
dataFile: any;
|
||||
storage: any = STORAGE;
|
||||
viewType = 'images';
|
||||
viewPath = STORAGE.images;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<AttachmentsViewComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public dialog: any,
|
||||
public changeDetectorRef: ChangeDetectorRef,
|
||||
public appService: AppService,
|
||||
public router: Router
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
if (this.dialog.title) this.title = this.dialog.title;
|
||||
this.onAttachmentsType(this.dialog.images);
|
||||
if (this.dialog.storage === 'products') this.viewPath = STORAGE.products;
|
||||
|
||||
|
||||
}
|
||||
|
||||
onAttachmentsType(image?: any) {
|
||||
if (!image) return;
|
||||
const ext = image.substring(image.lastIndexOf('.'), image.length);
|
||||
|
||||
if (['.png','.jpg', '.JPEG'].includes(ext)) this.viewType = 'images' ;
|
||||
if (['.mp4'].includes(ext)) this.viewType = 'vdo' ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
async onClose() {
|
||||
this.dialogRef.close(EAction.GET);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
97
src/app/pages/@popup/packet-view/packet-view.component.html
Normal file
97
src/app/pages/@popup/packet-view/packet-view.component.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<div class="dialog-main">
|
||||
<div class="dialog-header">
|
||||
<h2>{{title}}</h2>
|
||||
</div>
|
||||
<div class="dialog-body">
|
||||
|
||||
<div class="card card-form-panel mt-2">
|
||||
<div class="card-header ">
|
||||
<div class="">ข้อมูล Packet</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ng-container *ngFor="let item of packetDetail; 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-2 md:col-span-4">
|
||||
<label *ngIf="i === 0">รหัส</label>
|
||||
<mat-form-field>
|
||||
<input matInput name="code-{{i}}" #code="ngModel" [(ngModel)]="item.code" required disabled>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-span-6 md:col-span-8">
|
||||
<label *ngIf="i === 0">รายการจัดผ่อน</label>
|
||||
<mat-form-field>
|
||||
<input appNumberOnly matInput name="name-{{i}}" #name="ngModel" [(ngModel)]="item.name" disabled>
|
||||
</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="value-{{i}}" #value="ngModel" [(ngModel)]="item.value" disabled>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-span-2 md:col-span-6">
|
||||
<label *ngIf="i === 0">หน่วยนับ</label>
|
||||
<ng-select placeholder="เลือกหน่วยนับ" name="unitId-{{i}}" #unit="ngModel" [(ngModel)]="item.unit" appendTo="body" disabled>
|
||||
<ng-option *ngFor="let item of settingInstallmentUnit" [value]="item">{{item}}</ng-option>
|
||||
</ng-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card card-form-panel mt-6">
|
||||
<div class="card-header ">
|
||||
<div class="">โปรโมชั่น</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div style="height: 10px;"></div>
|
||||
<div class="grid grid-cols-12 gap-4 md:gap-2 items-center mb-1">
|
||||
<div class="col-span-4 md:col-span-12">
|
||||
<ng-select placeholder="" name="promotionId" #promotionId="ngModel" [(ngModel)]="dataView.promotionId" appendTo="body" disabled>
|
||||
<ng-option *ngFor="let item of promotionData" [value]="item.id">{{item.name}}</ng-option>
|
||||
</ng-select>
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngIf="promotionDetail">
|
||||
<ng-container *ngFor="let item of promotionDetail; let i = index">
|
||||
<ng-container *ngIf="item.status">
|
||||
|
||||
<div class="form-list">
|
||||
<div class="form-list-item grid grid-cols-12 gap-4 md:gap-2 items-center">
|
||||
<div class="col-span-8 md:col-span-10 ">
|
||||
<div *ngIf="i === 0" style="height: 25px;"></div>
|
||||
<mat-form-field>
|
||||
<input appNumberOnly matInput name="promotionName-{{i}}" #promotionName="ngModel" [(ngModel)]="item.name" disabled>
|
||||
</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="promotionValue-{{i}}" #promotionValue="ngModel" [(ngModel)]="item.value" disabled>-->
|
||||
<!-- </mat-form-field>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-span-2 md:col-span-6">-->
|
||||
<!-- <label *ngIf="i === 0">หน่วยนับ</label>-->
|
||||
<!-- <ng-select placeholder="เลือกหน่วยนับ" name="promotionUnitId-{{i}}" #promotionUnit="ngModel" [(ngModel)]="item.unit" appendTo="body" disabled>-->
|
||||
<!-- <ng-option *ngFor="let item of unitData" [value]="item">{{item}}</ng-option>-->
|
||||
<!-- </ng-select>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<div style="height: 20px;"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="dialog-footer">
|
||||
<button type="button" (click)="onClose()" class="btn btn-dialog-close">ปิด</button>
|
||||
</div>
|
||||
</div>
|
||||
75
src/app/pages/@popup/packet-view/packet-view.component.ts
Normal file
75
src/app/pages/@popup/packet-view/packet-view.component.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { ChangeDetectorRef, Component, Inject, OnInit } from "@angular/core";
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
|
||||
import { BasePopupComponent } from "../../../@common/base/base-popup.component";
|
||||
import { API, EAction, STORAGE } from "../../../@config/app";
|
||||
import { AppService } from "../../../app.service";
|
||||
import { Router } from "@angular/router";
|
||||
import { NgForOf, NgIf } from "@angular/common";
|
||||
import { AppSharedModule } from "../../../app.shared";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { NgSelectModule } from "@ng-select/ng-select";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import deepCopy from "../../../@common/utils/DeepCopy";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "app-packet-view",
|
||||
templateUrl: "./packet-view.component.html",
|
||||
styleUrls: [],
|
||||
imports: [
|
||||
NgIf,
|
||||
AppSharedModule,
|
||||
FormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
NgForOf,
|
||||
NgSelectModule
|
||||
],
|
||||
standalone: true
|
||||
})
|
||||
export class PacketViewComponent extends BasePopupComponent implements OnInit {
|
||||
|
||||
title = "รายละเอียด Packet";
|
||||
api : any = API;
|
||||
dataView: any = {};
|
||||
storage: any = STORAGE;
|
||||
|
||||
|
||||
settingInstallmentUnit: any = ["บาท", "%"];
|
||||
packetDetail: any = [];
|
||||
promotionDetail: any = [];
|
||||
promotionData: any = [];
|
||||
unitData: any = ["%"];
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<PacketViewComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public dialog: any,
|
||||
public changeDetectorRef: ChangeDetectorRef,
|
||||
public appService: AppService,
|
||||
public router: Router
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
if (this.dialog.title) this.title = this.dialog.title;
|
||||
this.promotionData = await lastValueFrom(this.appService.get(`${this.api.promotion}?showAll=true&status=true`));
|
||||
const data = deepCopy(this.dialog.data);
|
||||
this.dataView = data;
|
||||
this.packetDetail = data.packetDetail;
|
||||
this.promotionDetail = data.promotion?.promotionDetail;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async onClose() {
|
||||
this.dialogRef.close(EAction.GET);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
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,
|
||||
];
|
||||
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,391 @@
|
||||
<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>
|
||||
@@ -0,0 +1,309 @@
|
||||
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());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<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>
|
||||
@@ -0,0 +1,91 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<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>
|
||||
@@ -0,0 +1,71 @@
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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,
|
||||
];
|
||||
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,262 @@
|
||||
<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>
|
||||
@@ -0,0 +1,274 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<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>
|
||||
@@ -0,0 +1,86 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<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>
|
||||
@@ -0,0 +1,121 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
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,
|
||||
];
|
||||
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,401 @@
|
||||
<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>
|
||||
@@ -0,0 +1,283 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<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>
|
||||
@@ -0,0 +1,86 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
<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>
|
||||
@@ -0,0 +1,132 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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
|
||||
];
|
||||
16
src/app/pages/contract/approved/contract-approved.module.ts
Normal file
16
src/app/pages/contract/approved/contract-approved.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,694 @@
|
||||
<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>
|
||||
@@ -0,0 +1,187 @@
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
<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>
|
||||
@@ -0,0 +1,125 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
28
src/app/pages/contract/make/contract-make-routing.module.ts
Normal file
28
src/app/pages/contract/make/contract-make-routing.module.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
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
|
||||
];
|
||||
16
src/app/pages/contract/make/contract-make.module.ts
Normal file
16
src/app/pages/contract/make/contract-make.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
867
src/app/pages/contract/make/do/contract-make-do.component.html
Normal file
867
src/app/pages/contract/make/do/contract-make-do.component.html
Normal file
@@ -0,0 +1,867 @@
|
||||
<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>
|
||||
222
src/app/pages/contract/make/do/contract-make-do.component.ts
Normal file
222
src/app/pages/contract/make/do/contract-make-do.component.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
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"ationId=${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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<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>
|
||||
@@ -0,0 +1,131 @@
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
111
src/app/pages/contract/make/pdf/contract-make-pdf.component.ts
Normal file
111
src/app/pages/contract/make/pdf/contract-make-pdf.component.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
14
src/app/pages/dashboard/dashboard.module.ts
Normal file
14
src/app/pages/dashboard/dashboard.module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {AppSharedModule} from '../../app.shared';
|
||||
import {Components, DashboardRoutingModule} from './dashboard.routing.module';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [...Components],
|
||||
imports: [
|
||||
AppSharedModule,
|
||||
DashboardRoutingModule,
|
||||
]
|
||||
})
|
||||
export class DashboardModule {
|
||||
}
|
||||
22
src/app/pages/dashboard/dashboard.routing.module.ts
Normal file
22
src/app/pages/dashboard/dashboard.routing.module.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import {IndexComponent} from './index/index.component';
|
||||
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', component: IndexComponent},
|
||||
|
||||
];
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class DashboardRoutingModule { }
|
||||
|
||||
export const Components = [
|
||||
IndexComponent,
|
||||
|
||||
]
|
||||
4
src/app/pages/dashboard/index/index.component.html
Normal file
4
src/app/pages/dashboard/index/index.component.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<section class="section section-content">
|
||||
|
||||
</section>
|
||||
|
||||
40
src/app/pages/dashboard/index/index.component.ts
Normal file
40
src/app/pages/dashboard/index/index.component.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { AppService } from "../../../app.service";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import { API } from "../../../@config/app";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "app-index",
|
||||
templateUrl: "./index.component.html",
|
||||
styleUrls: []
|
||||
})
|
||||
export class IndexComponent implements OnInit {
|
||||
|
||||
title = "";
|
||||
auth : any = {};
|
||||
|
||||
constructor(public router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private app: AppService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.auth = this.app.auth();
|
||||
if (!this.auth) return;
|
||||
|
||||
|
||||
if (this.auth.userType === "ADMIN") {
|
||||
return this.router.navigate(["/pages/appraisal/1st-time"]);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
14
src/app/pages/errors/errors-routing.module.ts
Normal file
14
src/app/pages/errors/errors-routing.module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { IndexComponent } from './index/index.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', component: IndexComponent},
|
||||
];
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ErrorsRoutingModule { }
|
||||
10
src/app/pages/errors/errors.module.ts
Normal file
10
src/app/pages/errors/errors.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AppSharedModule } from '../../app.shared';
|
||||
import { IndexComponent } from './index/index.component';
|
||||
import { ErrorsRoutingModule } from './errors-routing.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [IndexComponent],
|
||||
imports: [AppSharedModule, ErrorsRoutingModule],
|
||||
})
|
||||
export class ErrorsModule {}
|
||||
0
src/app/pages/errors/index/index.component.html
Normal file
0
src/app/pages/errors/index/index.component.html
Normal file
15
src/app/pages/errors/index/index.component.ts
Normal file
15
src/app/pages/errors/index/index.component.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-error-index',
|
||||
templateUrl: './index.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class IndexComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
<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>
|
||||
137
src/app/pages/finance/invoice/do/finance-invoice-do.component.ts
Normal file
137
src/app/pages/finance/invoice/do/finance-invoice-do.component.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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
|
||||
];
|
||||
16
src/app/pages/finance/invoice/finance-invoice.module.ts
Normal file
16
src/app/pages/finance/invoice/finance-invoice.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,200 @@
|
||||
<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>
|
||||
@@ -0,0 +1,124 @@
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
238
src/app/pages/finance/paying/do/finance-paying-do.component.html
Normal file
238
src/app/pages/finance/paying/do/finance-paying-do.component.html
Normal file
@@ -0,0 +1,238 @@
|
||||
<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>
|
||||
147
src/app/pages/finance/paying/do/finance-paying-do.component.ts
Normal file
147
src/app/pages/finance/paying/do/finance-paying-do.component.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
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
|
||||
];
|
||||
16
src/app/pages/finance/paying/finance-paying.module.ts
Normal file
16
src/app/pages/finance/paying/finance-paying.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,209 @@
|
||||
<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>
|
||||
@@ -0,0 +1,133 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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,
|
||||
];
|
||||
16
src/app/pages/finance/payment/finance-payment.module.ts
Normal file
16
src/app/pages/finance/payment/finance-payment.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
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 {}
|
||||
@@ -0,0 +1,286 @@
|
||||
<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>
|
||||
@@ -0,0 +1,223 @@
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<mat-progress-bar *ngIf="!pdfView" mode="indeterminate"></mat-progress-bar>
|
||||
<iframe *ngIf="pdfView" [src]="pdfView"></iframe>
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<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>
|
||||
@@ -0,0 +1,128 @@
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<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>
|
||||
@@ -0,0 +1,128 @@
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<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>
|
||||
@@ -0,0 +1,145 @@
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
15
src/app/pages/page-blank/index/page-blank-index.component.ts
Normal file
15
src/app/pages/page-blank/index/page-blank-index.component.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-page-blank-index',
|
||||
templateUrl: './page-blank-index.component.html',
|
||||
styleUrls: []
|
||||
})
|
||||
export class PageBlankIndexComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
14
src/app/pages/page-blank/page-blank-routing.module.ts
Normal file
14
src/app/pages/page-blank/page-blank-routing.module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { PageBlankIndexComponent } from './index/page-blank-index.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', component: PageBlankIndexComponent},
|
||||
];
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class PageBlankRoutingModule { }
|
||||
10
src/app/pages/page-blank/page-blank.module.ts
Normal file
10
src/app/pages/page-blank/page-blank.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AppSharedModule } from '../../app.shared';
|
||||
import { PageBlankIndexComponent } from './index/page-blank-index.component';
|
||||
import { PageBlankRoutingModule } from './page-blank-routing.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [PageBlankIndexComponent],
|
||||
imports: [AppSharedModule, PageBlankRoutingModule],
|
||||
})
|
||||
export class PageBlankModule {}
|
||||
@@ -0,0 +1,58 @@
|
||||
<div class="card card-table">
|
||||
|
||||
<div class="card-filter ">
|
||||
<div class="card-filter-section grid grid-cols-12 gap-4 md:gap-2 items-center">
|
||||
<div class="col-span-3 md:col-span-12 ">
|
||||
<mat-label>วันที่กำหนดชำระ</mat-label>
|
||||
<mat-form-field>
|
||||
<input
|
||||
matInput
|
||||
name="startDateQuotationDetail"
|
||||
#startDateQuotationDetail="ngModel"
|
||||
(click)="dpkName1.open()"
|
||||
[(ngModel)]="dataFilter.startDateQuotationDetail"
|
||||
[matDatepicker]="dpkName1"
|
||||
readonly
|
||||
/>
|
||||
<mat-datepicker-toggle [for]="dpkName1" matSuffix></mat-datepicker-toggle>
|
||||
<mat-datepicker #dpkName1></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-span-3 md:col-span-12 ">
|
||||
<mat-label>ถึงวันที่</mat-label>
|
||||
<mat-form-field>
|
||||
<input
|
||||
matInput
|
||||
name="endDateQuotationDetail"
|
||||
#endDateQuotationDetail="ngModel"
|
||||
(click)="dpkName2.open()"
|
||||
[(ngModel)]="dataFilter.endDateQuotationDetail"
|
||||
[matDatepicker]="dpkName2"
|
||||
readonly
|
||||
/>
|
||||
<mat-datepicker-toggle [for]="dpkName2" matSuffix></mat-datepicker-toggle>
|
||||
<mat-datepicker #dpkName2></mat-datepicker>
|
||||
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-span-3 md:col-span-12 ">
|
||||
<mat-label>ชื่อลูกค้า</mat-label>
|
||||
<ng-select placeholder="" name="quotationDetailCustomerId" #quotationDetailCustomerId="ngModel" [(ngModel)]="dataFilter.quotationDetailCustomerId" appendTo="body" >
|
||||
<ng-option *ngFor="let item of customerData" [value]="item.id"> {{item?.prefix}} {{item?.firstName}} {{item?.lastName}} : {{item?.idCard}}</ng-option>
|
||||
</ng-select>
|
||||
|
||||
</div>
|
||||
<div class="col-span-3 md:col-span-12">
|
||||
<div style="height: 20px;"></div>
|
||||
<button type="button" class="btn btn-success-o" (click)="onExport()"><i class="bi bi-arrow-down"></i> ดาวน์โหลดรายงาน</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div style="height: 20px;"></div>
|
||||
<div class="sec-export">กดปุ่มดาวน์โหลดรายงานรูปแบบใน excel</div>
|
||||
@@ -0,0 +1,97 @@
|
||||
import {ChangeDetectorRef, Component, OnInit} from "@angular/core";
|
||||
import {BaseListComponent} from "../../../@common/base/base-list.component";
|
||||
import {lastValueFrom} from "rxjs";
|
||||
import {AppService} from "../../../app.service";
|
||||
import {API, EAction, EStatusContract, EText, PREFIX} from "../../../@config/app";
|
||||
import {ActivatedRoute} from "@angular/router";
|
||||
import {IQuotation, IQuotationDetail} from "../../../@common/interface/Quotation";
|
||||
import generateParamsValue from "../../../@common/utils/GenerateParamsValue";
|
||||
import {format, parseISO} from "date-fns";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "app-report-outstanding-accounts-receivable-index",
|
||||
templateUrl: "./outstanding-accounts-receivable-index.component.html",
|
||||
styleUrls: []
|
||||
})
|
||||
export class OutstandingAccountsReceivableIndexComponent extends BaseListComponent implements OnInit {
|
||||
|
||||
pageTitle = "รายงานลูกหนี้คงค้าง";
|
||||
apiUrl: string = API.quotation;
|
||||
api: any = API;
|
||||
customerData: any = [];
|
||||
|
||||
constructor(
|
||||
public appService: AppService,
|
||||
public activatedRoute: ActivatedRoute,
|
||||
public changeDetectorRef: ChangeDetectorRef
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.customerData = await lastValueFrom(this.appService.get(`${this.api.customer}?showAll=true&orderBy=firstName&sort=asc`));
|
||||
|
||||
}
|
||||
|
||||
|
||||
async onExport($event?: any) {
|
||||
try {
|
||||
|
||||
this.dataFilter.showAll = true;
|
||||
const filter = generateParamsValue(this.dataFilter);
|
||||
const dataSource = await lastValueFrom(this.appService.get(`${API.quotationDetail}?${filter}`));
|
||||
if (dataSource.length === 0) return this.appService.message(EAction.INFO, 'ไม่พบข้อมูล');
|
||||
|
||||
const startDateQuotationDetail = this.dataFilter.startDateQuotationDetail ? format(this.dataFilter.startDateQuotationDetail, "dd/MM/yyyy") : null;
|
||||
const endDateQuotationDetail = this.dataFilter.endDateQuotationDetail ? format(this.dataFilter.endDateQuotationDetail, "dd/MM/yyyy") : null;
|
||||
|
||||
|
||||
const datas : any = {
|
||||
due_date_from: startDateQuotationDetail,
|
||||
due_date_to: endDateQuotationDetail,
|
||||
data : []
|
||||
};
|
||||
dataSource.map((item : any) => {
|
||||
|
||||
const customerPrefix = item.quotation.customerPrefix ? item.quotation.customerPrefix : '';
|
||||
const customerName = item.quotation.customerId ? `${item.quotation.customer?.prefix} ${item.quotation.customer?.firstName} ${item.quotation.customer?.lastName}` :
|
||||
`${customerPrefix} ${item.quotation.customerFirstName} ${item.quotation.customerLastName}`;
|
||||
|
||||
|
||||
const dueDate = item.dueDate ? format(parseISO(item.dueDate), "dd/MM/yyyy") : null;
|
||||
|
||||
const map = {
|
||||
|
||||
customer_name: customerName,
|
||||
product_code: item.quotation.productNo,
|
||||
product_name: item.quotation.productName,
|
||||
brand: item.quotation.productBrandName,
|
||||
s_n: item.quotation.sellerSnProduct,
|
||||
installment: `${item.installment }/${item?.quotation?.wantToInstallmentTerm }`,
|
||||
due_date: dueDate,
|
||||
current_amount: Number(item.totalPayment),
|
||||
payment_total: Number(item.totalPayment),
|
||||
principle: Number(item.principle),
|
||||
interest: Number(item.interestTotal),
|
||||
bankfee_insurance_storage: Number(item.fee)
|
||||
}
|
||||
datas.data.push(map)
|
||||
})
|
||||
|
||||
|
||||
|
||||
const response = await lastValueFrom(this.appService.post(`${this.api.reportOutstandingAccountsReceivable}/xlsx`, datas, { responseType: "arraybuffer" }));
|
||||
const url = URL.createObjectURL(new Blob([response], { type: "application/vnd.ms-excel" }));
|
||||
|
||||
window.open(url);
|
||||
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
this.appService.message(EAction.ERROR, EText.ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user