251223:1649 On going update to 1.7.0: Refoctory drawing Module & document number Module
Spec Validation / validate-markdown (push) Has been cancelled
Spec Validation / validate-diagrams (push) Has been cancelled
Spec Validation / check-todos (push) Has been cancelled

This commit is contained in:
admin
2025-12-23 16:49:16 +07:00
parent 0d6432ab83
commit 7db6a003db
81 changed files with 4703 additions and 1449 deletions
@@ -2,7 +2,6 @@ import {
Injectable,
NotFoundException,
ConflictException,
InternalServerErrorException,
Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
@@ -73,8 +72,9 @@ export class ContractDrawingService {
projectId: createDto.projectId,
contractDrawingNo: createDto.contractDrawingNo,
title: createDto.title,
subCategoryId: createDto.subCategoryId,
mapCatId: createDto.mapCatId, // Updated
volumeId: createDto.volumeId,
volumePage: createDto.volumePage, // Updated
updatedBy: user.user_id,
attachments: attachments,
});
@@ -111,7 +111,7 @@ export class ContractDrawingService {
const {
projectId,
volumeId,
subCategoryId,
mapCatId,
search,
page = 1,
limit = 20,
@@ -129,11 +129,9 @@ export class ContractDrawingService {
query.andWhere('drawing.volumeId = :volumeId', { volumeId });
}
// Filter by SubCategory
if (subCategoryId) {
query.andWhere('drawing.subCategoryId = :subCategoryId', {
subCategoryId,
});
// Filter by Map Category (Updated)
if (mapCatId) {
query.andWhere('drawing.mapCatId = :mapCatId', { mapCatId });
}
// Search Text (No. or Title)
@@ -198,8 +196,10 @@ export class ContractDrawingService {
if (updateDto.title) drawing.title = updateDto.title;
if (updateDto.volumeId !== undefined)
drawing.volumeId = updateDto.volumeId;
if (updateDto.subCategoryId !== undefined)
drawing.subCategoryId = updateDto.subCategoryId;
if (updateDto.volumePage !== undefined)
drawing.volumePage = updateDto.volumePage;
if (updateDto.mapCatId !== undefined)
drawing.mapCatId = updateDto.mapCatId;
drawing.updatedBy = user.user_id;
@@ -11,6 +11,8 @@ import { ContractDrawingVolume } from './entities/contract-drawing-volume.entity
import { ContractDrawingSubCategory } from './entities/contract-drawing-sub-category.entity';
// Entities (Master Data - Shop Drawing) - ✅ เพิ่มใหม่
import { ContractDrawingSubcatCatMap } from './entities/contract-drawing-subcat-cat-map.entity';
import { ContractDrawingCategory } from './entities/contract-drawing-category.entity';
import { ShopDrawingMainCategory } from './entities/shop-drawing-main-category.entity';
import { ShopDrawingSubCategory } from './entities/shop-drawing-sub-category.entity';
@@ -40,6 +42,8 @@ import { UserModule } from '../user/user.module';
// Master Data
ContractDrawingVolume,
ContractDrawingSubCategory,
ContractDrawingSubcatCatMap,
ContractDrawingCategory,
ShopDrawingMainCategory, // ✅
ShopDrawingSubCategory, // ✅
@@ -21,12 +21,16 @@ export class CreateContractDrawingDto {
@IsInt()
@IsOptional()
subCategoryId?: number; // ✅ ใส่ ?
mapCatId?: number; // ✅ ใส่ ?
@IsInt()
@IsOptional()
volumeId?: number; // ✅ ใส่ ?
@IsInt()
@IsOptional()
volumePage?: number;
@IsArray()
@IsInt({ each: true })
@IsOptional()
@@ -10,6 +10,13 @@ export class CreateShopDrawingRevisionDto {
@IsString()
revisionLabel!: string; // จำเป็น: ใส่ !
@IsString()
title!: string; // Add title
@IsString()
@IsOptional()
legacyDrawingNumber?: string;
@IsDateString()
@IsOptional()
revisionDate?: string; // Optional: ใส่ ?
@@ -14,8 +14,8 @@ export class SearchContractDrawingDto {
@IsOptional()
@IsInt()
@Type(() => Number)
subCategoryId?: number; // Optional: ใส่ ?
@IsOptional()
mapCatId?: number; // Optional: ใส่ ?
@IsOptional()
@IsString()
@@ -0,0 +1,74 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
ManyToOne,
JoinColumn,
ManyToMany,
JoinTable,
} from 'typeorm';
import { AsBuiltDrawing } from './asbuilt-drawing.entity';
import { ShopDrawingRevision } from './shop-drawing-revision.entity';
import { Attachment } from '../../../common/file-storage/entities/attachment.entity';
@Entity('asbuilt_drawing_revisions')
export class AsBuiltDrawingRevision {
@PrimaryGeneratedColumn()
id!: number;
@Column({ name: 'asbuilt_drawing_id' })
asBuiltDrawingId!: number;
@Column({ name: 'revision_number' })
revisionNumber!: number;
@Column({ name: 'title', length: 255 })
title!: string;
@Column({ name: 'revision_label', length: 10, nullable: true })
revisionLabel?: string;
@Column({ name: 'revision_date', type: 'date', nullable: true })
revisionDate?: Date;
@Column({ type: 'text', nullable: true })
description?: string;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date;
// Relations
@ManyToOne(() => AsBuiltDrawing, (drawing) => drawing.revisions, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'asbuilt_drawing_id' })
asBuiltDrawing!: AsBuiltDrawing;
// Relation to Shop Drawing Revisions (M:N)
@ManyToMany(() => ShopDrawingRevision)
@JoinTable({
name: 'asbuilt_revision_shop_revisions_refs',
joinColumn: {
name: 'asbuilt_drawing_revision_id',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'shop_drawing_revision_id',
referencedColumnName: 'id',
},
})
shopDrawingRevisions!: ShopDrawingRevision[];
// Attachments (M:N)
@ManyToMany(() => Attachment)
@JoinTable({
name: 'asbuilt_drawing_revision_attachments',
joinColumn: {
name: 'asbuilt_drawing_revision_id',
referencedColumnName: 'id',
},
inverseJoinColumn: { name: 'attachment_id', referencedColumnName: 'id' },
})
attachments!: Attachment[];
}
@@ -0,0 +1,56 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
ManyToOne,
OneToMany,
JoinColumn,
} from 'typeorm';
import { Project } from '../../project/entities/project.entity';
import { AsBuiltDrawingRevision } from './asbuilt-drawing-revision.entity';
import { User } from '../../user/entities/user.entity';
@Entity('asbuilt_drawings')
export class AsBuiltDrawing {
@PrimaryGeneratedColumn()
id!: number;
@Column({ name: 'project_id' })
projectId!: number;
@Column({ name: 'drawing_number', length: 100, unique: true })
drawingNumber!: string;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt!: Date;
@DeleteDateColumn({ name: 'deleted_at' })
deletedAt?: Date;
@Column({ name: 'updated_by', nullable: true })
updatedBy?: number;
// Relations
@ManyToOne(() => Project)
@JoinColumn({ name: 'project_id' })
project!: Project;
@ManyToOne(() => User)
@JoinColumn({ name: 'updated_by' })
updater?: User;
@OneToMany(
() => AsBuiltDrawingRevision,
(revision) => revision.asBuiltDrawing,
{
cascade: true,
}
)
revisions!: AsBuiltDrawingRevision[];
}
@@ -0,0 +1,41 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { Project } from '../../project/entities/project.entity';
@Entity('contract_drawing_cats')
export class ContractDrawingCategory {
@PrimaryGeneratedColumn()
id!: number;
@Column({ name: 'project_id' })
projectId!: number;
@Column({ name: 'cat_code', length: 50 })
catCode!: string;
@Column({ name: 'cat_name', length: 255 })
catName!: string;
@Column({ type: 'text', nullable: true })
description?: string;
@Column({ name: 'sort_order', default: 0 })
sortOrder!: number;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt!: Date;
@ManyToOne(() => Project)
@JoinColumn({ name: 'project_id' })
project!: Project;
}
@@ -0,0 +1,37 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { Project } from '../../project/entities/project.entity';
import { ContractDrawingCategory } from './contract-drawing-category.entity';
import { ContractDrawingSubCategory } from './contract-drawing-sub-category.entity';
@Entity('contract_drawing_subcat_cat_maps')
export class ContractDrawingSubcatCatMap {
@PrimaryGeneratedColumn()
id!: number;
@Column({ name: 'project_id', nullable: true })
projectId?: number;
@Column({ name: 'sub_cat_id', nullable: true })
subCategoryId?: number;
@Column({ name: 'cat_id', nullable: true })
categoryId?: number;
@ManyToOne(() => Project)
@JoinColumn({ name: 'project_id' })
project?: Project;
@ManyToOne(() => ContractDrawingSubCategory)
@JoinColumn({ name: 'sub_cat_id' })
subCategory?: ContractDrawingSubCategory;
@ManyToOne(() => ContractDrawingCategory)
@JoinColumn({ name: 'cat_id' })
category?: ContractDrawingCategory;
}
@@ -13,7 +13,7 @@ import {
import { Project } from '../../project/entities/project.entity';
import { User } from '../../user/entities/user.entity';
import { Attachment } from '../../../common/file-storage/entities/attachment.entity';
import { ContractDrawingSubCategory } from './contract-drawing-sub-category.entity';
import { ContractDrawingSubcatCatMap } from './contract-drawing-subcat-cat-map.entity';
import { ContractDrawingVolume } from './contract-drawing-volume.entity';
@Entity('contract_drawings')
@@ -30,12 +30,15 @@ export class ContractDrawing {
@Column({ length: 255 })
title!: string; // ! ห้ามว่าง
@Column({ name: 'sub_cat_id', nullable: true })
subCategoryId?: number; // ? ว่างได้ (Nullable)
@Column({ name: 'map_cat_id', nullable: true })
mapCatId?: number; // ? ว่างได้ (Nullable)
@Column({ name: 'volume_id', nullable: true })
volumeId?: number; // ? ว่างได้ (Nullable)
@Column({ name: 'volume_page', nullable: true })
volumePage?: number;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date; // ! ห้ามว่าง
@@ -58,9 +61,9 @@ export class ContractDrawing {
@JoinColumn({ name: 'updated_by' })
updater?: User; // ? ว่างได้
@ManyToOne(() => ContractDrawingSubCategory)
@JoinColumn({ name: 'sub_cat_id' })
subCategory?: ContractDrawingSubCategory; // ? ว่างได้ (สัมพันธ์กับ subCategoryId)
@ManyToOne(() => ContractDrawingSubcatCatMap)
@JoinColumn({ name: 'map_cat_id' })
mapCategory?: ContractDrawingSubcatCatMap;
@ManyToOne(() => ContractDrawingVolume)
@JoinColumn({ name: 'volume_id' })
@@ -11,6 +11,9 @@ export class ShopDrawingMainCategory {
@PrimaryGeneratedColumn()
id!: number; // เติม !
@Column({ name: 'project_id' })
projectId!: number; // เติม !
@Column({ name: 'main_category_code', length: 50, unique: true })
mainCategoryCode!: string; // เติม !
@@ -23,6 +23,12 @@ export class ShopDrawingRevision {
@Column({ name: 'revision_number' })
revisionNumber!: number; // เติม !
@Column({ name: 'title', length: 255 })
title!: string; // เติม !
@Column({ name: 'legacy_drawing_number', length: 100, nullable: true })
legacyDrawingNumber?: string;
@Column({ name: 'revision_label', length: 10, nullable: true })
revisionLabel?: string; // nullable ใช้ ?
@@ -4,25 +4,22 @@ import {
Column,
CreateDateColumn,
UpdateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { ShopDrawingMainCategory } from './shop-drawing-main-category.entity';
@Entity('shop_drawing_sub_categories')
export class ShopDrawingSubCategory {
@PrimaryGeneratedColumn()
id!: number; // เติม ! (ตัวที่ error)
@Column({ name: 'project_id' })
projectId!: number; // เติม !
@Column({ name: 'sub_category_code', length: 50, unique: true })
subCategoryCode!: string; // เติม !
@Column({ name: 'sub_category_name', length: 255 })
subCategoryName!: string; // เติม !
@Column({ name: 'main_category_id' })
mainCategoryId!: number; // เติม !
@Column({ type: 'text', nullable: true })
description?: string; // nullable ใช้ ?
@@ -37,9 +34,4 @@ export class ShopDrawingSubCategory {
@UpdateDateColumn({ name: 'updated_at' })
updatedAt!: Date; // เติม !
// Relation to Main Category
@ManyToOne(() => ShopDrawingMainCategory)
@JoinColumn({ name: 'main_category_id' })
mainCategory!: ShopDrawingMainCategory; // เติม !
}
@@ -25,9 +25,6 @@ export class ShopDrawing {
@Column({ name: 'drawing_number', length: 100, unique: true })
drawingNumber!: string; // เติม !
@Column({ length: 500 })
title!: string; // เติม !
@Column({ name: 'main_category_id' })
mainCategoryId!: number; // เติม !
@@ -5,7 +5,7 @@ import {
Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource, In, Brackets } from 'typeorm';
import { Repository, DataSource, In } from 'typeorm';
// Entities
import { ShopDrawing } from './entities/shop-drawing.entity';
@@ -77,7 +77,6 @@ export class ShopDrawingService {
const shopDrawing = queryRunner.manager.create(ShopDrawing, {
projectId: createDto.projectId,
drawingNumber: createDto.drawingNumber,
title: createDto.title,
mainCategoryId: createDto.mainCategoryId,
subCategoryId: createDto.subCategoryId,
updatedBy: user.user_id,
@@ -89,6 +88,7 @@ export class ShopDrawingService {
shopDrawingId: savedShopDrawing.id,
revisionNumber: 0,
revisionLabel: createDto.revisionLabel || '0',
title: createDto.title, // Add title to revision
revisionDate: createDto.revisionDate
? new Date(createDto.revisionDate)
: new Date(),
@@ -175,6 +175,8 @@ export class ShopDrawingService {
shopDrawingId,
revisionNumber: nextRevNum,
revisionLabel: createDto.revisionLabel,
title: createDto.title, // Add title from DTO
legacyDrawingNumber: createDto.legacyDrawingNumber, // Add legacy number
revisionDate: createDto.revisionDate
? new Date(createDto.revisionDate)
: new Date(),
@@ -226,13 +228,9 @@ export class ShopDrawingService {
}
if (search) {
query.andWhere(
new Brackets((qb) => {
qb.where('sd.drawingNumber LIKE :search', {
search: `%${search}%`,
}).orWhere('sd.title LIKE :search', { search: `%${search}%` });
})
);
query.andWhere('sd.drawingNumber LIKE :search', {
search: `%${search}%`,
});
}
query.orderBy('sd.updatedAt', 'DESC');