Skip to content

Commit dad1d09

Browse files
Merge pull request #414 from Mkalbani/feat/asset-crud
Feat: implemented asset mgt module
2 parents 88bb52c + 0eba7b9 commit dad1d09

File tree

10 files changed

+209
-20
lines changed

10 files changed

+209
-20
lines changed

backend/src/app.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { AssetCategory } from './asset-categories/asset-category.entity';
2727
import { Department } from './departments/department.entity';
2828
import { User } from './users/entities/user.entity';
2929
import { FileUpload } from './file-uploads/entities/file-upload.entity';
30-
import { Asset } from './assets/entities/assest.entity';
30+
import { Asset } from './assets/entities/asset.entity';
3131
import { Supplier } from './suppliers/entities/supplier.entity';
3232
import { AssetCategoriesModule } from './asset-categories/asset-categories.module';
3333
import { DepartmentsModule } from './departments/departments.module';
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {
2+
Entity,
3+
Column,
4+
PrimaryGeneratedColumn,
5+
CreateDateColumn,
6+
UpdateDateColumn,
7+
DeleteDateColumn,
8+
Index,
9+
} from 'typeorm';
10+
11+
@Entity('asset_categories')
12+
@Index(['code'], { unique: true })
13+
export class AssetCategory {
14+
@PrimaryGeneratedColumn('uuid')
15+
id: string;
16+
17+
@Column({ length: 100, unique: true })
18+
code: string;
19+
20+
@Column({ length: 200 })
21+
name: string;
22+
23+
@Column({ type: 'text', nullable: true })
24+
description: string;
25+
26+
@Column({ type: 'decimal', precision: 5, scale: 2, default: 0 })
27+
depreciationRate: number;
28+
29+
@Column({ default: true })
30+
isActive: boolean;
31+
32+
@CreateDateColumn({ name: 'created_at' })
33+
createdAt: Date;
34+
35+
@UpdateDateColumn({ name: 'updated_at' })
36+
updatedAt: Date;
37+
38+
@DeleteDateColumn({ name: 'deleted_at' })
39+
deletedAt: Date;
40+
}

backend/src/assets/assets.module.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import { TypeOrmModule } from '@nestjs/typeorm';
33
import { AssetsService } from './assets.service';
44
import { AssetsController } from './assets.controller';
55
import { Asset } from './entities/asset.entity';
6-
// import { AssetCategory } from '../asset-categories/asset-category.entity';
7-
// import { Department } from '../departments/department.entity';
8-
// import { User } from '../users/entities/user.entity';
6+
import { AssetCategory } from '../asset-categories/asset-category.entity';
7+
import { Department } from '../departments/department.entity';
8+
import { Location } from '../locations/location.entity';
9+
import { User } from '../users/entities/user.entity';
910

1011
@Module({
1112
imports: [
1213
TypeOrmModule.forFeature([
1314
Asset,
14-
// AssetCategory,
15-
// Department,
16-
// User,
15+
AssetCategory,
16+
Department,
17+
Location,
18+
User,
1719
]),
1820
],
1921
controllers: [AssetsController],

backend/src/assets/assets.service.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Repository, DataSource } from 'typeorm';
1010
import { Asset, AssetStatus } from './entities/asset.entity';
1111
import { AssetCategory } from '../asset-categories/asset-category.entity';
1212
import { Department } from '../departments/department.entity';
13+
import { Location } from '../locations/location.entity';
1314
import { User } from '../users/entities/user.entity';
1415
import { CreateAssetDto, BulkCreateAssetDto } from './dto/create-asset.dto';
1516
import {
@@ -38,6 +39,8 @@ export class AssetsService {
3839
private readonly categoryRepository: Repository<AssetCategory>,
3940
@InjectRepository(Department)
4041
private readonly departmentRepository: Repository<Department>,
42+
@InjectRepository(Location)
43+
private readonly locationRepository: Repository<Location>,
4144
@InjectRepository(User)
4245
private readonly userRepository: Repository<User>,
4346
private readonly dataSource: DataSource,
@@ -67,6 +70,18 @@ export class AssetsService {
6770
);
6871
}
6972

73+
let location = null;
74+
if (createAssetDto.locationId) {
75+
location = await this.locationRepository.findOne({
76+
where: { id: createAssetDto.locationId },
77+
});
78+
if (!location) {
79+
throw new NotFoundException(
80+
`Location with ID ${createAssetDto.locationId} not found`,
81+
);
82+
}
83+
}
84+
7085
let assignedUser = null;
7186
if (createAssetDto.assignedToId) {
7287
assignedUser = await this.userRepository.findOne({
@@ -123,7 +138,7 @@ export class AssetsService {
123138
assetId,
124139
category,
125140
department,
126-
location: createAssetDto.location,
141+
location,
127142
assignedTo: assignedUser,
128143
currentValue,
129144
createdBy: creatingUser,
@@ -154,7 +169,7 @@ export class AssetsService {
154169
sortOrder = 'DESC',
155170
categoryId,
156171
departmentId,
157-
location,
172+
locationId,
158173
assignedToId,
159174
status,
160175
condition,
@@ -169,6 +184,7 @@ export class AssetsService {
169184
.createQueryBuilder('asset')
170185
.leftJoinAndSelect('asset.category', 'category')
171186
.leftJoinAndSelect('asset.department', 'department')
187+
.leftJoinAndSelect('asset.location', 'location')
172188
.leftJoinAndSelect('asset.assignedTo', 'assignedTo')
173189
.leftJoinAndSelect('asset.createdBy', 'createdBy')
174190
.leftJoinAndSelect('asset.updatedBy', 'updatedBy');
@@ -188,10 +204,8 @@ export class AssetsService {
188204
queryBuilder.andWhere('asset.departmentId = :departmentId', { departmentId });
189205
}
190206

191-
if (location) {
192-
queryBuilder.andWhere('asset.location ILIKE :location', {
193-
location: `%${location}%`,
194-
});
207+
if (locationId) {
208+
queryBuilder.andWhere('asset.locationId = :locationId', { locationId });
195209
}
196210

197211
if (assignedToId) {
@@ -302,6 +316,17 @@ export class AssetsService {
302316
}
303317
}
304318

319+
if (updateAssetDto.locationId) {
320+
const location = await this.locationRepository.findOne({
321+
where: { id: updateAssetDto.locationId },
322+
});
323+
if (!location) {
324+
throw new NotFoundException(
325+
`Location with ID ${updateAssetDto.locationId} not found`,
326+
);
327+
}
328+
}
329+
305330
if (updateAssetDto.assignedToId) {
306331
const assignedUser = await this.userRepository.findOne({
307332
where: { id: updateAssetDto.assignedToId },

backend/src/assets/dto/asset-query.dto.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ export class AssetQueryDto {
4242
departmentId?: string;
4343

4444
@IsOptional()
45-
@IsString()
46-
location?: string;
45+
@IsUUID()
46+
locationId?: string;
4747

4848
@IsOptional()
4949
@IsUUID()

backend/src/assets/dto/create-asset.dto.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,8 @@ export class CreateAssetDto {
6969
departmentId: string;
7070

7171
@IsOptional()
72-
@IsString()
73-
@MaxLength(200)
74-
location?: string;
72+
@IsUUID()
73+
locationId?: string;
7574

7675
@IsOptional()
7776
@IsUUID()

backend/src/assets/entities/asset.entity.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from 'typeorm';
1212
import { AssetCategory } from '../../asset-categories/asset-category.entity';
1313
import { Department } from '../../departments/department.entity';
14+
import { Location } from '../../locations/location.entity';
1415
import { User } from '../../users/entities/user.entity';
1516

1617
export enum AssetStatus {
@@ -96,8 +97,9 @@ export class Asset {
9697
@JoinColumn({ name: 'department_id' })
9798
department: Department;
9899

99-
@Column({ name: 'location', length: 200, nullable: true })
100-
location: string;
100+
@ManyToOne(() => Location, { eager: true, nullable: true })
101+
@JoinColumn({ name: 'location_id' })
102+
location: Location;
101103

102104
@ManyToOne(() => User, { nullable: true, eager: true })
103105
@JoinColumn({ name: 'assigned_to_id' })
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
Entity,
3+
Column,
4+
PrimaryGeneratedColumn,
5+
CreateDateColumn,
6+
UpdateDateColumn,
7+
DeleteDateColumn,
8+
Index,
9+
} from 'typeorm';
10+
11+
@Entity('departments')
12+
@Index(['code'], { unique: true })
13+
export class Department {
14+
@PrimaryGeneratedColumn('uuid')
15+
id: string;
16+
17+
@Column({ length: 100, unique: true })
18+
code: string;
19+
20+
@Column({ length: 200 })
21+
name: string;
22+
23+
@Column({ type: 'text', nullable: true })
24+
description: string;
25+
26+
@Column({ default: true })
27+
isActive: boolean;
28+
29+
@CreateDateColumn({ name: 'created_at' })
30+
createdAt: Date;
31+
32+
@UpdateDateColumn({ name: 'updated_at' })
33+
updatedAt: Date;
34+
35+
@DeleteDateColumn({ name: 'deleted_at' })
36+
deletedAt: Date;
37+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
Entity,
3+
Column,
4+
PrimaryGeneratedColumn,
5+
CreateDateColumn,
6+
UpdateDateColumn,
7+
DeleteDateColumn,
8+
Index,
9+
} from 'typeorm';
10+
11+
@Entity('locations')
12+
@Index(['code'], { unique: true })
13+
export class Location {
14+
@PrimaryGeneratedColumn('uuid')
15+
id: string;
16+
17+
@Column({ length: 100, unique: true })
18+
code: string;
19+
20+
@Column({ length: 200 })
21+
name: string;
22+
23+
@Column({ type: 'text', nullable: true })
24+
description: string;
25+
26+
@Column({ length: 100, nullable: true })
27+
building: string;
28+
29+
@Column({ length: 100, nullable: true })
30+
floor: string;
31+
32+
@Column({ default: true })
33+
isActive: boolean;
34+
35+
@CreateDateColumn({ name: 'created_at' })
36+
createdAt: Date;
37+
38+
@UpdateDateColumn({ name: 'updated_at' })
39+
updatedAt: Date;
40+
41+
@DeleteDateColumn({ name: 'deleted_at' })
42+
deletedAt: Date;
43+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {
2+
Entity,
3+
Column,
4+
PrimaryGeneratedColumn,
5+
CreateDateColumn,
6+
UpdateDateColumn,
7+
DeleteDateColumn,
8+
} from 'typeorm';
9+
10+
@Entity('users')
11+
export class User {
12+
@PrimaryGeneratedColumn('uuid')
13+
id: string;
14+
15+
@Column({ length: 100, unique: true })
16+
username: string;
17+
18+
@Column({ length: 255, unique: true })
19+
email: string;
20+
21+
@Column({ length: 100 })
22+
firstName: string;
23+
24+
@Column({ length: 100 })
25+
lastName: string;
26+
27+
@Column({ select: false, nullable: true })
28+
password: string;
29+
30+
@Column({ default: true })
31+
isActive: boolean;
32+
33+
@CreateDateColumn({ name: 'created_at' })
34+
createdAt: Date;
35+
36+
@UpdateDateColumn({ name: 'updated_at' })
37+
updatedAt: Date;
38+
39+
@DeleteDateColumn({ name: 'deleted_at' })
40+
deletedAt: Date;
41+
}

0 commit comments

Comments
 (0)