chore: add business logic
This commit is contained in:
@@ -49,7 +49,6 @@
|
|||||||
"@nestjs/core": "^11.0.1",
|
"@nestjs/core": "^11.0.1",
|
||||||
"@nestjs/jwt": "^11.0.0",
|
"@nestjs/jwt": "^11.0.0",
|
||||||
"@nestjs/passport": "^11.0.5",
|
"@nestjs/passport": "^11.0.5",
|
||||||
"@nestjs/platform-express": "^11.0.1",
|
|
||||||
"@nestjs/platform-fastify": "^11.1.0",
|
"@nestjs/platform-fastify": "^11.1.0",
|
||||||
"@nestjs/swagger": "^11.2.0",
|
"@nestjs/swagger": "^11.2.0",
|
||||||
"@nestjs/throttler": "^6.4.0",
|
"@nestjs/throttler": "^6.4.0",
|
||||||
@@ -80,7 +79,6 @@
|
|||||||
"@swc/cli": "^0.6.0",
|
"@swc/cli": "^0.6.0",
|
||||||
"@swc/core": "^1.10.7",
|
"@swc/core": "^1.10.7",
|
||||||
"@types/bcrypt": "^5.0.2",
|
"@types/bcrypt": "^5.0.2",
|
||||||
"@types/express": "^5.0.0",
|
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^22.10.7",
|
"@types/node": "^22.10.7",
|
||||||
"@types/nodemailer": "^6.4.17",
|
"@types/nodemailer": "^6.4.17",
|
||||||
|
|||||||
Generated
+15
-10
@@ -65,9 +65,6 @@ importers:
|
|||||||
'@nestjs/passport':
|
'@nestjs/passport':
|
||||||
specifier: ^11.0.5
|
specifier: ^11.0.5
|
||||||
version: 11.0.5(@nestjs/common@11.1.0(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)
|
version: 11.0.5(@nestjs/common@11.1.0(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)
|
||||||
'@nestjs/platform-express':
|
|
||||||
specifier: ^11.0.1
|
|
||||||
version: 11.1.0(@nestjs/common@11.1.0(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)
|
|
||||||
'@nestjs/platform-fastify':
|
'@nestjs/platform-fastify':
|
||||||
specifier: ^11.1.0
|
specifier: ^11.1.0
|
||||||
version: 11.1.0(@fastify/static@8.1.1)(@nestjs/common@11.1.0(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)
|
version: 11.1.0(@fastify/static@8.1.1)(@nestjs/common@11.1.0(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)
|
||||||
@@ -153,9 +150,6 @@ importers:
|
|||||||
'@types/bcrypt':
|
'@types/bcrypt':
|
||||||
specifier: ^5.0.2
|
specifier: ^5.0.2
|
||||||
version: 5.0.2
|
version: 5.0.2
|
||||||
'@types/express':
|
|
||||||
specifier: ^5.0.0
|
|
||||||
version: 5.0.1
|
|
||||||
'@types/jest':
|
'@types/jest':
|
||||||
specifier: ^29.5.14
|
specifier: ^29.5.14
|
||||||
version: 29.5.14
|
version: 29.5.14
|
||||||
@@ -8048,6 +8042,7 @@ snapshots:
|
|||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@nestjs/platform-fastify@11.1.0(@fastify/static@8.1.1)(@nestjs/common@11.1.0(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)':
|
'@nestjs/platform-fastify@11.1.0(@fastify/static@8.1.1)(@nestjs/common@11.1.0(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -9423,6 +9418,7 @@ snapshots:
|
|||||||
busboy@1.6.0:
|
busboy@1.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
streamsearch: 1.1.0
|
streamsearch: 1.1.0
|
||||||
|
optional: true
|
||||||
|
|
||||||
bytes@3.1.2: {}
|
bytes@3.1.2: {}
|
||||||
|
|
||||||
@@ -9642,6 +9638,7 @@ snapshots:
|
|||||||
inherits: 2.0.4
|
inherits: 2.0.4
|
||||||
readable-stream: 2.3.8
|
readable-stream: 2.3.8
|
||||||
typedarray: 0.0.6
|
typedarray: 0.0.6
|
||||||
|
optional: true
|
||||||
|
|
||||||
concat-stream@2.0.0:
|
concat-stream@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -11165,7 +11162,8 @@ snapshots:
|
|||||||
is-docker: 2.2.1
|
is-docker: 2.2.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
isarray@1.0.0: {}
|
isarray@1.0.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
isarray@2.0.5: {}
|
isarray@2.0.5: {}
|
||||||
|
|
||||||
@@ -12302,6 +12300,7 @@ snapshots:
|
|||||||
mkdirp@0.5.6:
|
mkdirp@0.5.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
minimist: 1.2.8
|
minimist: 1.2.8
|
||||||
|
optional: true
|
||||||
|
|
||||||
mkdirp@1.0.4: {}
|
mkdirp@1.0.4: {}
|
||||||
|
|
||||||
@@ -12334,6 +12333,7 @@ snapshots:
|
|||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
type-is: 1.6.18
|
type-is: 1.6.18
|
||||||
xtend: 4.0.2
|
xtend: 4.0.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
mute-stream@2.0.0: {}
|
mute-stream@2.0.0: {}
|
||||||
|
|
||||||
@@ -12776,7 +12776,8 @@ snapshots:
|
|||||||
uuid: 9.0.1
|
uuid: 9.0.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
process-nextick-args@2.0.1: {}
|
process-nextick-args@2.0.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
process-warning@4.0.1: {}
|
process-warning@4.0.1: {}
|
||||||
|
|
||||||
@@ -12930,6 +12931,7 @@ snapshots:
|
|||||||
safe-buffer: 5.1.2
|
safe-buffer: 5.1.2
|
||||||
string_decoder: 1.1.1
|
string_decoder: 1.1.1
|
||||||
util-deprecate: 1.0.2
|
util-deprecate: 1.0.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -13066,7 +13068,8 @@ snapshots:
|
|||||||
has-symbols: 1.1.0
|
has-symbols: 1.1.0
|
||||||
isarray: 2.0.5
|
isarray: 2.0.5
|
||||||
|
|
||||||
safe-buffer@5.1.2: {}
|
safe-buffer@5.1.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
safe-buffer@5.2.1: {}
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
@@ -13290,7 +13293,8 @@ snapshots:
|
|||||||
|
|
||||||
statuses@2.0.1: {}
|
statuses@2.0.1: {}
|
||||||
|
|
||||||
streamsearch@1.1.0: {}
|
streamsearch@1.1.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
streamx@2.22.0:
|
streamx@2.22.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -13350,6 +13354,7 @@ snapshots:
|
|||||||
string_decoder@1.1.1:
|
string_decoder@1.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer: 5.1.2
|
safe-buffer: 5.1.2
|
||||||
|
optional: true
|
||||||
|
|
||||||
string_decoder@1.3.0:
|
string_decoder@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { databaseConfig } from "./configs/mikro-orm.config";
|
|||||||
import { rateLimitConfig } from "./configs/rateLimit.config";
|
import { rateLimitConfig } from "./configs/rateLimit.config";
|
||||||
import { HTTPLogger } from "./core/middlewares/logger.middleware";
|
import { HTTPLogger } from "./core/middlewares/logger.middleware";
|
||||||
import { AuthModule } from "./modules/auth/auth.module";
|
import { AuthModule } from "./modules/auth/auth.module";
|
||||||
|
import { BusinessesModule } from "./modules/businesses/businesses.module";
|
||||||
import { CompaniesModule } from "./modules/companies/companies.module";
|
import { CompaniesModule } from "./modules/companies/companies.module";
|
||||||
import { IndustriesModule } from "./modules/industries/industries.module";
|
import { IndustriesModule } from "./modules/industries/industries.module";
|
||||||
import { InvoicesModule } from "./modules/invoices/invoices.module";
|
import { InvoicesModule } from "./modules/invoices/invoices.module";
|
||||||
@@ -23,6 +24,7 @@ import { TicketsModule } from "./modules/tickets/tickets.module";
|
|||||||
import { UploaderModule } from "./modules/uploader/uploader.module";
|
import { UploaderModule } from "./modules/uploader/uploader.module";
|
||||||
import { UsersModule } from "./modules/users/users.module";
|
import { UsersModule } from "./modules/users/users.module";
|
||||||
import { UtilsModule } from "./modules/utils/utils.module";
|
import { UtilsModule } from "./modules/utils/utils.module";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({ isGlobal: true, cache: true }),
|
ConfigModule.forRoot({ isGlobal: true, cache: true }),
|
||||||
@@ -50,7 +52,14 @@ import { UtilsModule } from "./modules/utils/utils.module";
|
|||||||
UploaderModule,
|
UploaderModule,
|
||||||
TicketsModule,
|
TicketsModule,
|
||||||
InvoicesModule,
|
InvoicesModule,
|
||||||
|
BusinessesModule,
|
||||||
],
|
],
|
||||||
|
// providers: [
|
||||||
|
// {
|
||||||
|
// provide: APP_INTERCEPTOR,
|
||||||
|
// useClass: BusinessInterceptor,
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
})
|
})
|
||||||
export class AppModule implements NestModule {
|
export class AppModule implements NestModule {
|
||||||
configure(consumer: MiddlewareConsumer) {
|
configure(consumer: MiddlewareConsumer) {
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { ExecutionContext, createParamDecorator } from "@nestjs/common";
|
||||||
|
import { FastifyRequest } from "fastify";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the business ID from the request header
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* @Get()
|
||||||
|
* findAll(@BusinessIdHeader() businessId: string) {
|
||||||
|
* // Use businessId
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const BusinessIdHeader = createParamDecorator((headerName: string = "X-Business-Id", ctx: ExecutionContext) => {
|
||||||
|
const req = ctx.switchToHttp().getRequest<FastifyRequest>();
|
||||||
|
return req.headers[headerName.toLocaleLowerCase()];
|
||||||
|
});
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { ExecutionContext, createParamDecorator } from "@nestjs/common";
|
||||||
|
import { FastifyRequest } from "fastify";
|
||||||
|
|
||||||
|
import { Business } from "../../modules/businesses/entities/business.entity";
|
||||||
|
|
||||||
|
export const BusinessDec = createParamDecorator((data: keyof Business | undefined, ctx: ExecutionContext) => {
|
||||||
|
const req = ctx.switchToHttp().getRequest<FastifyRequest>();
|
||||||
|
const business = req.business;
|
||||||
|
|
||||||
|
return data ? business?.[data] : business;
|
||||||
|
});
|
||||||
@@ -597,3 +597,8 @@ export const enum CompanyMessage {
|
|||||||
COMPANY_ID_REQUIRED = "شرکت مورد نیاز است",
|
COMPANY_ID_REQUIRED = "شرکت مورد نیاز است",
|
||||||
COMPANY_ID_SHOULD_BE_A_UUID = "شناسه شرکت باید یک UUID معتبر باشد",
|
COMPANY_ID_SHOULD_BE_A_UUID = "شناسه شرکت باید یک UUID معتبر باشد",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const enum BusinessMessage {
|
||||||
|
NOT_FOUND = "کسب و کار یافت نشد",
|
||||||
|
BUSINESS_ID_REQUIRED = "شناسه کسب و کار مورد نیاز است",
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export function bullMqConfig(): SharedBullAsyncConfiguration {
|
|||||||
},
|
},
|
||||||
prefix: "dzone",
|
prefix: "dzone",
|
||||||
defaultJobOptions: {
|
defaultJobOptions: {
|
||||||
removeOnComplete: false,
|
removeOnComplete: true,
|
||||||
removeOnFail: false,
|
removeOnFail: false,
|
||||||
attempts: 5,
|
attempts: 5,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
CallHandler,
|
||||||
|
ExecutionContext,
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
Logger,
|
||||||
|
NestInterceptor,
|
||||||
|
} from "@nestjs/common";
|
||||||
|
import { FastifyRequest } from "fastify";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
import { BusinessMessage } from "../../common/enums/message.enum";
|
||||||
|
import { Business } from "../../modules/businesses/entities/business.entity";
|
||||||
|
import { BusinessService } from "../../modules/businesses/services/businesses.service";
|
||||||
|
|
||||||
|
declare module "fastify" {
|
||||||
|
interface FastifyRequest {
|
||||||
|
business?: Business;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class BusinessInterceptor implements NestInterceptor {
|
||||||
|
private readonly headerName = "x-business-id";
|
||||||
|
private readonly logger = new Logger(BusinessInterceptor.name);
|
||||||
|
|
||||||
|
constructor(private readonly businessService: BusinessService) {}
|
||||||
|
|
||||||
|
async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
|
||||||
|
const request = context.switchToHttp().getRequest<FastifyRequest>();
|
||||||
|
|
||||||
|
const businessId = request.headers[this.headerName.toLocaleLowerCase()] as string;
|
||||||
|
|
||||||
|
if (businessId) {
|
||||||
|
try {
|
||||||
|
const business = await this.businessService.getBusinessByDanakSubscriptionId(businessId);
|
||||||
|
|
||||||
|
request.business = business;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new BadRequestException(BusinessMessage.NOT_FOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new ForbiddenException(BusinessMessage.BUSINESS_ID_REQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next.handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { MikroOrmModule } from "@mikro-orm/nestjs";
|
||||||
|
import { BullModule } from "@nestjs/bullmq";
|
||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
|
import { SUBSCRIPTIONS } from "./constant";
|
||||||
|
import { Business } from "./entities/business.entity";
|
||||||
|
import { BusinessProvisioningProcessor } from "./queue/business-provisioning.processor";
|
||||||
|
import { BusinessService } from "./services/businesses.service";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
MikroOrmModule.forFeature([Business]),
|
||||||
|
BullModule.registerQueue({
|
||||||
|
name: SUBSCRIPTIONS.PROVISIONING_QUEUE_NAME,
|
||||||
|
prefix: SUBSCRIPTIONS.PROVISIONING_QUEUE_PREFIX,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
providers: [BusinessService, BusinessProvisioningProcessor],
|
||||||
|
exports: [BusinessService],
|
||||||
|
})
|
||||||
|
export class BusinessesModule {}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export const SUBSCRIPTIONS = Object.freeze({
|
||||||
|
PROVISIONING_QUEUE_PREFIX: "provisioning",
|
||||||
|
PROVISIONING_QUEUE_NAME: "provisioning",
|
||||||
|
PROVISIONING_JOB_NAME: "business.created",
|
||||||
|
|
||||||
|
//
|
||||||
|
SERVICE_SLUG: "Dzonea",
|
||||||
|
SERVICE_ID: "7e3c2f08-b7e7-4402-ae5f-fea99cff56bd",
|
||||||
|
});
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { Cascade, Collection, Entity, EntityRepositoryType, OneToMany, Property, Unique } from "@mikro-orm/core";
|
||||||
|
|
||||||
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
|
import { Company } from "../../companies/entities/company.entity";
|
||||||
|
import { Industry } from "../../industries/entities/industry.entity";
|
||||||
|
import { BusinessRepository } from "../repositories/business.repository";
|
||||||
|
|
||||||
|
@Entity({ repository: () => BusinessRepository })
|
||||||
|
export class Business extends BaseEntity {
|
||||||
|
@Unique()
|
||||||
|
@Property({ type: "uuid", nullable: false })
|
||||||
|
danakSubscriptionId!: string;
|
||||||
|
|
||||||
|
@Property({ type: "varchar", length: 255, nullable: false })
|
||||||
|
name!: string;
|
||||||
|
|
||||||
|
@Property({ type: "varchar", length: 255, nullable: true })
|
||||||
|
logoUrl?: string;
|
||||||
|
|
||||||
|
@OneToMany(() => Company, (company) => company.business, { cascade: [Cascade.ALL] })
|
||||||
|
companies = new Collection<Company>(this);
|
||||||
|
|
||||||
|
@OneToMany(() => Industry, (industry) => industry.business)
|
||||||
|
industries = new Collection<Industry>(this);
|
||||||
|
|
||||||
|
[EntityRepositoryType]?: BusinessRepository;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export interface IBusinessProvisioningJob {
|
||||||
|
subscriptionId: string;
|
||||||
|
serviceId: string;
|
||||||
|
serviceName: string;
|
||||||
|
businessName: string;
|
||||||
|
userId: string;
|
||||||
|
slug: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
// src/business/queue/business-provisioning.processor.ts
|
||||||
|
import { EntityManager } from "@mikro-orm/postgresql";
|
||||||
|
import { Processor } from "@nestjs/bullmq";
|
||||||
|
import { Logger } from "@nestjs/common";
|
||||||
|
import { Job } from "bullmq";
|
||||||
|
|
||||||
|
import { WorkerProcessor } from "../../../common/queues/worker.processor";
|
||||||
|
import { SUBSCRIPTIONS } from "../constant";
|
||||||
|
import { Business } from "../entities/business.entity";
|
||||||
|
import { IBusinessProvisioningJob } from "../interfaces/IBusiness";
|
||||||
|
|
||||||
|
@Processor(SUBSCRIPTIONS.PROVISIONING_QUEUE_NAME)
|
||||||
|
export class BusinessProvisioningProcessor extends WorkerProcessor {
|
||||||
|
protected readonly logger = new Logger(BusinessProvisioningProcessor.name);
|
||||||
|
|
||||||
|
constructor(private readonly em: EntityManager) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
async process(job: Job) {
|
||||||
|
switch (job.name) {
|
||||||
|
case SUBSCRIPTIONS.PROVISIONING_JOB_NAME:
|
||||||
|
await this.handleBusinessCreated(job);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.logger.warn(`Unknown job name: ${job.name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleBusinessCreated(job: Job<IBusinessProvisioningJob>) {
|
||||||
|
const em = this.em.fork();
|
||||||
|
const { subscriptionId, serviceId, serviceName, businessName } = job.data;
|
||||||
|
|
||||||
|
// Only act if the event is for this service
|
||||||
|
if (serviceId !== SUBSCRIPTIONS.SERVICE_ID) {
|
||||||
|
this.logger.debug(`Skipping job for service: ${serviceName}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if already exists
|
||||||
|
let business = await em.findOne(Business, { danakSubscriptionId: subscriptionId });
|
||||||
|
if (!business) {
|
||||||
|
business = em.create(Business, {
|
||||||
|
danakSubscriptionId: subscriptionId,
|
||||||
|
name: businessName,
|
||||||
|
// logoUrl: job.data.logoUrl, // Uncomment if logoUrl is provided in job data
|
||||||
|
});
|
||||||
|
await em.persistAndFlush(business);
|
||||||
|
this.logger.log(`Created business for subscription ${subscriptionId}`);
|
||||||
|
} else {
|
||||||
|
this.logger.debug(`Business already exists for subscription ${subscriptionId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { EntityRepository } from "@mikro-orm/postgresql";
|
||||||
|
|
||||||
|
import { Business } from "../entities/business.entity";
|
||||||
|
|
||||||
|
export class BusinessRepository extends EntityRepository<Business> {}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||||
|
|
||||||
|
import { BusinessMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { BusinessRepository } from "../repositories/business.repository";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class BusinessService {
|
||||||
|
constructor(private readonly businessRepository: BusinessRepository) {}
|
||||||
|
|
||||||
|
async getBusinessByDanakSubscriptionId(danakSubscriptionId: string) {
|
||||||
|
const business = await this.businessRepository.findOne({ danakSubscriptionId, deletedAt: null });
|
||||||
|
if (!business) throw new BadRequestException(BusinessMessage.NOT_FOUND);
|
||||||
|
|
||||||
|
return business;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,48 +1,52 @@
|
|||||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from "@nestjs/common";
|
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseInterceptors } from "@nestjs/common";
|
||||||
import { ApiOperation } from "@nestjs/swagger";
|
import { ApiOperation } from "@nestjs/swagger";
|
||||||
|
|
||||||
import { CompanyListQueryDto } from "./DTO/company-list-query.dto";
|
import { CompanyListQueryDto } from "./DTO/company-list-query.dto";
|
||||||
import { CreateCompanyDto } from "./DTO/create-company.dto";
|
import { CreateCompanyDto } from "./DTO/create-company.dto";
|
||||||
import { UpdateCompanyDto } from "./DTO/update-company.dto";
|
import { UpdateCompanyDto } from "./DTO/update-company.dto";
|
||||||
import { CompaniesService } from "./services/companies.service";
|
import { CompaniesService } from "./services/companies.service";
|
||||||
|
import { BusinessDec } from "../../common/decorators/business.decorator";
|
||||||
import { ParamDto } from "../../common/DTO/param.dto";
|
import { ParamDto } from "../../common/DTO/param.dto";
|
||||||
|
import { BusinessInterceptor } from "../../core/interceptors/business.interceptor";
|
||||||
|
import { Business } from "../businesses/entities/business.entity";
|
||||||
@Controller("companies")
|
@Controller("companies")
|
||||||
|
@UseInterceptors(BusinessInterceptor)
|
||||||
export class CompaniesController {
|
export class CompaniesController {
|
||||||
constructor(private readonly companiesService: CompaniesService) {}
|
constructor(private readonly companiesService: CompaniesService) {}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@ApiOperation({ summary: "create company (admin)" })
|
@ApiOperation({ summary: "create company (admin)" })
|
||||||
create(@Body() createCompanyDto: CreateCompanyDto) {
|
create(@Body() createCompanyDto: CreateCompanyDto, @BusinessDec() business: Business) {
|
||||||
return this.companiesService.create(createCompanyDto);
|
return this.companiesService.create(createCompanyDto, business);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(":id")
|
@Patch(":id")
|
||||||
@ApiOperation({ summary: "update company (admin)" })
|
@ApiOperation({ summary: "update company (admin)" })
|
||||||
update(@Param() paramDto: ParamDto, @Body() updateCompanyDto: UpdateCompanyDto) {
|
update(@Param() paramDto: ParamDto, @Body() updateCompanyDto: UpdateCompanyDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.companiesService.updateCompanyById(paramDto.id, updateCompanyDto);
|
return this.companiesService.updateCompanyById(paramDto.id, updateCompanyDto, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(":id")
|
@Delete(":id")
|
||||||
@ApiOperation({ summary: "delete company (admin)" })
|
@ApiOperation({ summary: "delete company (admin)" })
|
||||||
delete(@Param() paramDto: ParamDto) {
|
delete(@Param() paramDto: ParamDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.companiesService.deleteCompanyById(paramDto.id);
|
return this.companiesService.deleteCompanyById(paramDto.id, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("list")
|
@Get("list")
|
||||||
@ApiOperation({ summary: "get companies list (admin)" })
|
@ApiOperation({ summary: "get companies list (admin)" })
|
||||||
getCompaniesList(@Query() query: CompanyListQueryDto) {
|
getCompaniesList(@Query() query: CompanyListQueryDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.companiesService.getCompaniesList(query);
|
return this.companiesService.getCompaniesList(query, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(":id")
|
@Get(":id")
|
||||||
@ApiOperation({ summary: "get company by id" })
|
@ApiOperation({ summary: "get company by id" })
|
||||||
get(@Param() paramDto: ParamDto) {
|
get(@Param() paramDto: ParamDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.companiesService.getCompanyById(paramDto.id);
|
return this.companiesService.getCompanyById(paramDto.id, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(":id/toggle-status")
|
@Patch(":id/toggle-status")
|
||||||
@ApiOperation({ summary: "toggle company status (admin)" })
|
@ApiOperation({ summary: "toggle company status (admin)" })
|
||||||
toggleStatus(@Param() paramDto: ParamDto) {
|
toggleStatus(@Param() paramDto: ParamDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.companiesService.toggleStatus(paramDto.id);
|
return this.companiesService.toggleStatus(paramDto.id, businessId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import { CompanyProduct } from "./entities/company-product.entity";
|
|||||||
import { CompanyService } from "./entities/company-service.entity";
|
import { CompanyService } from "./entities/company-service.entity";
|
||||||
import { Company } from "./entities/company.entity";
|
import { Company } from "./entities/company.entity";
|
||||||
import { CompaniesService } from "./services/companies.service";
|
import { CompaniesService } from "./services/companies.service";
|
||||||
|
import { BusinessesModule } from "../businesses/businesses.module";
|
||||||
import { Industry } from "../industries/entities/industry.entity";
|
import { Industry } from "../industries/entities/industry.entity";
|
||||||
import { UsersModule } from "../users/users.module";
|
import { UsersModule } from "../users/users.module";
|
||||||
import { UtilsModule } from "../utils/utils.module";
|
import { UtilsModule } from "../utils/utils.module";
|
||||||
@Module({
|
@Module({
|
||||||
imports: [MikroOrmModule.forFeature([Company, Industry, CompanyProduct, CompanyService]), UsersModule, UtilsModule],
|
imports: [MikroOrmModule.forFeature([Company, Industry, CompanyProduct, CompanyService]), UsersModule, UtilsModule, BusinessesModule],
|
||||||
providers: [CompaniesService],
|
providers: [CompaniesService],
|
||||||
controllers: [CompaniesController],
|
controllers: [CompaniesController],
|
||||||
exports: [CompaniesService],
|
exports: [CompaniesService],
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Cascade, Collection, Entity, EntityRepositoryType, Enum, Formula, ManyT
|
|||||||
import { CompanyProduct } from "./company-product.entity";
|
import { CompanyProduct } from "./company-product.entity";
|
||||||
import { CompanyService } from "./company-service.entity";
|
import { CompanyService } from "./company-service.entity";
|
||||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
|
import { Business } from "../../businesses/entities/business.entity";
|
||||||
import { Industry } from "../../industries/entities/industry.entity";
|
import { Industry } from "../../industries/entities/industry.entity";
|
||||||
import { Invoice } from "../../invoices/entities/invoice.entity";
|
import { Invoice } from "../../invoices/entities/invoice.entity";
|
||||||
import { User } from "../../users/entities/user.entity";
|
import { User } from "../../users/entities/user.entity";
|
||||||
@@ -66,5 +67,8 @@ export class Company extends BaseEntity {
|
|||||||
@ManyToOne(() => User, { deleteRule: "restrict" })
|
@ManyToOne(() => User, { deleteRule: "restrict" })
|
||||||
user!: User;
|
user!: User;
|
||||||
|
|
||||||
|
@ManyToOne(() => Business, { deleteRule: "restrict" })
|
||||||
|
business!: Business;
|
||||||
|
|
||||||
[EntityRepositoryType]?: CompanyRepository;
|
[EntityRepositoryType]?: CompanyRepository;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import { Company } from "../entities/company.entity";
|
|||||||
|
|
||||||
export class CompanyRepository extends EntityRepository<Company> {
|
export class CompanyRepository extends EntityRepository<Company> {
|
||||||
//
|
//
|
||||||
async getCompaniesListForAdmin(queryDto: CompanyListQueryDto) {
|
async getCompaniesListForAdmin(queryDto: CompanyListQueryDto, businessId: string) {
|
||||||
const { limit, skip } = PaginationUtils(queryDto);
|
const { limit, skip } = PaginationUtils(queryDto);
|
||||||
|
|
||||||
const where: FilterQuery<Company> = {
|
const where: FilterQuery<Company> = {
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
|
business: { id: businessId },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (queryDto.status) {
|
if (queryDto.status) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { BadRequestException, Injectable } from "@nestjs/common";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
import { CompanyMessage, IndustryMessage } from "../../../common/enums/message.enum";
|
import { CompanyMessage, IndustryMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { Business } from "../../businesses/entities/business.entity";
|
||||||
import { Industry } from "../../industries/entities/industry.entity";
|
import { Industry } from "../../industries/entities/industry.entity";
|
||||||
import { User } from "../../users/entities/user.entity";
|
import { User } from "../../users/entities/user.entity";
|
||||||
import { UsersService } from "../../users/services/users.service";
|
import { UsersService } from "../../users/services/users.service";
|
||||||
@@ -25,7 +26,7 @@ export class CompaniesService {
|
|||||||
private readonly em: EntityManager,
|
private readonly em: EntityManager,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async create(createDto: CreateCompanyDto) {
|
async create(createDto: CreateCompanyDto, business: Business) {
|
||||||
const em = this.em.fork();
|
const em = this.em.fork();
|
||||||
try {
|
try {
|
||||||
await em.begin();
|
await em.begin();
|
||||||
@@ -34,8 +35,8 @@ export class CompaniesService {
|
|||||||
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
||||||
|
|
||||||
const [existingCompany, existIdentityNumber] = await Promise.all([
|
const [existingCompany, existIdentityNumber] = await Promise.all([
|
||||||
em.findOne(Company, { name: createDto.name }),
|
em.findOne(Company, { name: createDto.name, business: { id: business.id } }),
|
||||||
em.findOne(Company, { identificationNumber: createDto.identificationNumber }),
|
em.findOne(Company, { identificationNumber: createDto.identificationNumber, business: { id: business.id } }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_NAME);
|
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_NAME);
|
||||||
@@ -65,6 +66,7 @@ export class CompaniesService {
|
|||||||
products,
|
products,
|
||||||
services,
|
services,
|
||||||
user,
|
user,
|
||||||
|
business,
|
||||||
});
|
});
|
||||||
|
|
||||||
await em.persistAndFlush(company);
|
await em.persistAndFlush(company);
|
||||||
@@ -82,14 +84,18 @@ export class CompaniesService {
|
|||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async updateCompanyById(id: string, updateDto: UpdateCompanyDto) {
|
async updateCompanyById(id: string, updateDto: UpdateCompanyDto, businessId: string) {
|
||||||
const em = this.em.fork();
|
const em = this.em.fork();
|
||||||
try {
|
try {
|
||||||
await em.begin();
|
await em.begin();
|
||||||
|
|
||||||
const { services, products, ...rest } = updateDto;
|
const { services, products, ...rest } = updateDto;
|
||||||
|
|
||||||
const company = await em.findOne(Company, { id, deletedAt: null }, { populate: ["user", "services", "products"] });
|
const company = await em.findOne(
|
||||||
|
Company,
|
||||||
|
{ id, deletedAt: null, business: { id: businessId } },
|
||||||
|
{ populate: ["user", "services", "products"] },
|
||||||
|
);
|
||||||
if (!company) throw new BadRequestException(CompanyMessage.COMPANY_NOT_FOUND);
|
if (!company) throw new BadRequestException(CompanyMessage.COMPANY_NOT_FOUND);
|
||||||
|
|
||||||
const updatedCompany = em.assign(company, rest);
|
const updatedCompany = em.assign(company, rest);
|
||||||
@@ -101,8 +107,14 @@ export class CompaniesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (updateDto.name) {
|
if (updateDto.name) {
|
||||||
const existingCompany = await em.findOne(Company, { name: updateDto.name, deletedAt: null, id: { $ne: company.id } });
|
const existingCompany = await em.findOne(Company, {
|
||||||
|
name: updateDto.name,
|
||||||
|
deletedAt: null,
|
||||||
|
id: { $ne: company.id },
|
||||||
|
business: { id: businessId },
|
||||||
|
});
|
||||||
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_NAME);
|
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_NAME);
|
||||||
|
updatedCompany.name = updateDto.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateDto.identificationNumber) {
|
if (updateDto.identificationNumber) {
|
||||||
@@ -110,8 +122,10 @@ export class CompaniesService {
|
|||||||
identificationNumber: updateDto.identificationNumber,
|
identificationNumber: updateDto.identificationNumber,
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
id: { $ne: company.id },
|
id: { $ne: company.id },
|
||||||
|
business: { id: businessId },
|
||||||
});
|
});
|
||||||
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_IDENTITY_NUMBER);
|
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_IDENTITY_NUMBER);
|
||||||
|
updatedCompany.identificationNumber = updateDto.identificationNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
const userUpdateData: Partial<User> = {};
|
const userUpdateData: Partial<User> = {};
|
||||||
@@ -174,15 +188,15 @@ export class CompaniesService {
|
|||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async getCompanyById(id: string) {
|
async getCompanyById(id: string, businessId: string) {
|
||||||
const company = await this.findCompanyById(id);
|
const company = await this.findCompanyById(id, businessId);
|
||||||
return { company };
|
return { company };
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async getCompaniesList(queryDto: CompanyListQueryDto) {
|
async getCompaniesList(queryDto: CompanyListQueryDto, businessId: string) {
|
||||||
const [companies, count] = await this.companyRepository.getCompaniesListForAdmin(queryDto);
|
const [companies, count] = await this.companyRepository.getCompaniesListForAdmin(queryDto, businessId);
|
||||||
return {
|
return {
|
||||||
companies,
|
companies,
|
||||||
count,
|
count,
|
||||||
@@ -192,8 +206,8 @@ export class CompaniesService {
|
|||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async deleteCompanyById(id: string) {
|
async deleteCompanyById(id: string, businessId: string) {
|
||||||
const company = await this.findCompanyById(id);
|
const company = await this.findCompanyById(id, businessId);
|
||||||
|
|
||||||
company.deletedAt = dayjs().toDate();
|
company.deletedAt = dayjs().toDate();
|
||||||
|
|
||||||
@@ -205,8 +219,8 @@ export class CompaniesService {
|
|||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async toggleStatus(id: string) {
|
async toggleStatus(id: string, businessId: string) {
|
||||||
const company = await this.findCompanyById(id);
|
const company = await this.findCompanyById(id, businessId);
|
||||||
|
|
||||||
company.isActive = !company.isActive;
|
company.isActive = !company.isActive;
|
||||||
|
|
||||||
@@ -231,9 +245,9 @@ export class CompaniesService {
|
|||||||
return company;
|
return company;
|
||||||
}
|
}
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
private async findCompanyById(id: string) {
|
private async findCompanyById(id: string, businessId: string) {
|
||||||
const company = await this.companyRepository.findOne(
|
const company = await this.companyRepository.findOne(
|
||||||
{ id, deletedAt: null },
|
{ id, deletedAt: null, business: { id: businessId } },
|
||||||
{ populate: ["user", "industry", "services", "products"] },
|
{ populate: ["user", "industry", "services", "products"] },
|
||||||
);
|
);
|
||||||
if (!company) throw new BadRequestException(CompanyMessage.COMPANY_NOT_FOUND);
|
if (!company) throw new BadRequestException(CompanyMessage.COMPANY_NOT_FOUND);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Collection, Entity, EntityRepositoryType, Formula, OneToMany, Opt, Property } from "@mikro-orm/core";
|
import { Collection, Entity, EntityRepositoryType, Formula, ManyToOne, OneToMany, Opt, Property } from "@mikro-orm/core";
|
||||||
|
|
||||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
|
import { Business } from "../../businesses/entities/business.entity";
|
||||||
import { Company } from "../../companies/entities/company.entity";
|
import { Company } from "../../companies/entities/company.entity";
|
||||||
import { IndustryRepository } from "../repositories/industry.repository";
|
import { IndustryRepository } from "../repositories/industry.repository";
|
||||||
|
|
||||||
@@ -21,5 +22,8 @@ export class Industry extends BaseEntity {
|
|||||||
@OneToMany(() => Company, (company) => company.industry)
|
@OneToMany(() => Company, (company) => company.industry)
|
||||||
companies = new Collection<Company>(this);
|
companies = new Collection<Company>(this);
|
||||||
|
|
||||||
|
@ManyToOne(() => Business, { deleteRule: "restrict" })
|
||||||
|
business!: Business;
|
||||||
|
|
||||||
[EntityRepositoryType]?: IndustryRepository;
|
[EntityRepositoryType]?: IndustryRepository;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,53 @@
|
|||||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from "@nestjs/common";
|
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseInterceptors } from "@nestjs/common";
|
||||||
import { ApiOperation } from "@nestjs/swagger";
|
import { ApiOperation } from "@nestjs/swagger";
|
||||||
|
|
||||||
import { CreateIndustryDto } from "./DTO/create-industry.dto";
|
import { CreateIndustryDto } from "./DTO/create-industry.dto";
|
||||||
import { IndustryListQueryDto } from "./DTO/industry-list-query.dto";
|
import { IndustryListQueryDto } from "./DTO/industry-list-query.dto";
|
||||||
import { UpdateIndustryDto } from "./DTO/update-industry.dto";
|
import { UpdateIndustryDto } from "./DTO/update-industry.dto";
|
||||||
import { IndustriesService } from "./services/industries.service";
|
import { IndustriesService } from "./services/industries.service";
|
||||||
|
import { BusinessDec } from "../../common/decorators/business.decorator";
|
||||||
import { ParamDto } from "../../common/DTO/param.dto";
|
import { ParamDto } from "../../common/DTO/param.dto";
|
||||||
|
import { BusinessInterceptor } from "../../core/interceptors/business.interceptor";
|
||||||
|
import { Business } from "../businesses/entities/business.entity";
|
||||||
|
|
||||||
@Controller("industries")
|
@Controller("industries")
|
||||||
|
@UseInterceptors(BusinessInterceptor)
|
||||||
export class IndustriesController {
|
export class IndustriesController {
|
||||||
constructor(private readonly industriesService: IndustriesService) {}
|
constructor(private readonly industriesService: IndustriesService) {}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@ApiOperation({ summary: "create industry" })
|
@ApiOperation({ summary: "create industry" })
|
||||||
create(@Body() createIndustryDto: CreateIndustryDto) {
|
create(@Body() createIndustryDto: CreateIndustryDto, @BusinessDec() business: Business) {
|
||||||
return this.industriesService.create(createIndustryDto);
|
return this.industriesService.create(createIndustryDto, business);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(":id")
|
@Get(":id")
|
||||||
@ApiOperation({ summary: "get industry by id" })
|
@ApiOperation({ summary: "get industry by id" })
|
||||||
getIndustryById(@Param() paramDto: ParamDto) {
|
getIndustryById(@Param() paramDto: ParamDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.industriesService.getIndustriesById(paramDto.id);
|
return this.industriesService.getIndustriesById(paramDto.id, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(":id")
|
@Patch(":id")
|
||||||
@ApiOperation({ summary: "update industry" })
|
@ApiOperation({ summary: "update industry" })
|
||||||
updateIndustry(@Param() paramDto: ParamDto, @Body() updateIndustryDto: UpdateIndustryDto) {
|
updateIndustry(@Param() paramDto: ParamDto, @Body() updateIndustryDto: UpdateIndustryDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.industriesService.updateIndustry(paramDto.id, updateIndustryDto);
|
return this.industriesService.updateIndustry(paramDto.id, updateIndustryDto, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(":id")
|
@Delete(":id")
|
||||||
@ApiOperation({ summary: "delete industry" })
|
@ApiOperation({ summary: "delete industry" })
|
||||||
deleteIndustry(@Param() paramDto: ParamDto) {
|
deleteIndustry(@Param() paramDto: ParamDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.industriesService.deleteIndustry(paramDto.id);
|
return this.industriesService.deleteIndustry(paramDto.id, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("list")
|
@Get("list")
|
||||||
@ApiOperation({ summary: "get industries list for admin" })
|
@ApiOperation({ summary: "get industries list for admin" })
|
||||||
getIndustriesForAdmin(@Query() query: IndustryListQueryDto) {
|
getIndustriesForAdmin(@Query() query: IndustryListQueryDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.industriesService.getIndustriesListForAdmin(query);
|
return this.industriesService.getIndustriesListForAdmin(query, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(":id/toggle-status")
|
@Patch(":id/toggle-status")
|
||||||
@ApiOperation({ summary: "toggle industry status" })
|
@ApiOperation({ summary: "toggle industry status" })
|
||||||
toggleStatus(@Param() paramDto: ParamDto) {
|
toggleStatus(@Param() paramDto: ParamDto, @BusinessDec("id") businessId: string) {
|
||||||
return this.industriesService.toggleStatus(paramDto.id);
|
return this.industriesService.toggleStatus(paramDto.id, businessId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { MikroOrmModule } from "@mikro-orm/nestjs";
|
import { MikroOrmModule } from "@mikro-orm/nestjs";
|
||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
|
import { BusinessesModule } from "../businesses/businesses.module";
|
||||||
import { Industry } from "./entities/industry.entity";
|
import { Industry } from "./entities/industry.entity";
|
||||||
import { IndustriesController } from "./industries.controller";
|
import { IndustriesController } from "./industries.controller";
|
||||||
import { IndustriesService } from "./services/industries.service";
|
import { IndustriesService } from "./services/industries.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [MikroOrmModule.forFeature([Industry])],
|
imports: [MikroOrmModule.forFeature([Industry]), BusinessesModule],
|
||||||
controllers: [IndustriesController],
|
controllers: [IndustriesController],
|
||||||
providers: [IndustriesService],
|
providers: [IndustriesService],
|
||||||
exports: [IndustriesService],
|
exports: [IndustriesService],
|
||||||
|
|||||||
@@ -6,10 +6,14 @@ import { Industry } from "../entities/industry.entity";
|
|||||||
|
|
||||||
export class IndustryRepository extends EntityRepository<Industry> {
|
export class IndustryRepository extends EntityRepository<Industry> {
|
||||||
//
|
//
|
||||||
async getIndustriesListForAdmin(queryDto: IndustryListQueryDto) {
|
async getIndustriesListForAdmin(queryDto: IndustryListQueryDto, businessId: string) {
|
||||||
const { limit, skip } = PaginationUtils(queryDto);
|
const { limit, skip } = PaginationUtils(queryDto);
|
||||||
|
|
||||||
const queryBuilder = this.createQueryBuilder("i").where({ deletedAt: null }).orderBy({ createdAt: "DESC" }).limit(limit).offset(skip);
|
const queryBuilder = this.createQueryBuilder("i")
|
||||||
|
.where({ deletedAt: null, business: { id: businessId } })
|
||||||
|
.orderBy({ createdAt: "DESC" })
|
||||||
|
.limit(limit)
|
||||||
|
.offset(skip);
|
||||||
|
|
||||||
if (queryDto.q) {
|
if (queryDto.q) {
|
||||||
queryBuilder.andWhere({ title: { $ilike: `%${queryDto.q}%` } });
|
queryBuilder.andWhere({ title: { $ilike: `%${queryDto.q}%` } });
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { BadRequestException, Injectable } from "@nestjs/common";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
import { IndustryMessage } from "../../../common/enums/message.enum";
|
import { IndustryMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { Business } from "../../businesses/entities/business.entity";
|
||||||
import { CreateIndustryDto } from "../DTO/create-industry.dto";
|
import { CreateIndustryDto } from "../DTO/create-industry.dto";
|
||||||
import { IndustryListQueryDto } from "../DTO/industry-list-query.dto";
|
import { IndustryListQueryDto } from "../DTO/industry-list-query.dto";
|
||||||
import { UpdateIndustryDto } from "../DTO/update-industry.dto";
|
import { UpdateIndustryDto } from "../DTO/update-industry.dto";
|
||||||
@@ -17,11 +18,14 @@ export class IndustriesService {
|
|||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async create(createIndustryDto: CreateIndustryDto) {
|
async create(createIndustryDto: CreateIndustryDto, business: Business) {
|
||||||
const existingIndustry = await this.industryRepository.findOne({ title: createIndustryDto.title });
|
const existingIndustry = await this.industryRepository.findOne({
|
||||||
|
title: createIndustryDto.title,
|
||||||
|
business: { id: business.id },
|
||||||
|
});
|
||||||
if (existingIndustry) throw new BadRequestException(IndustryMessage.INDUSTRY_ALREADY_EXISTS);
|
if (existingIndustry) throw new BadRequestException(IndustryMessage.INDUSTRY_ALREADY_EXISTS);
|
||||||
|
|
||||||
const industry = this.industryRepository.create(createIndustryDto);
|
const industry = this.industryRepository.create({ ...createIndustryDto, business });
|
||||||
this.em.persistAndFlush(industry);
|
this.em.persistAndFlush(industry);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -31,16 +35,16 @@ export class IndustriesService {
|
|||||||
}
|
}
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async getIndustriesById(id: string) {
|
async getIndustriesById(id: string, businessId: string) {
|
||||||
const industry = await this.industryRepository.findOne({ id, deletedAt: null });
|
const industry = await this.industryRepository.findOne({ id, deletedAt: null, business: { id: businessId } });
|
||||||
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
||||||
|
|
||||||
return { industry };
|
return { industry };
|
||||||
}
|
}
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async updateIndustry(id: string, updateIndustryDto: UpdateIndustryDto) {
|
async updateIndustry(id: string, updateIndustryDto: UpdateIndustryDto, businessId: string) {
|
||||||
const industry = await this.industryRepository.findOne({ id, deletedAt: null });
|
const industry = await this.industryRepository.findOne({ id, deletedAt: null, business: { id: businessId } });
|
||||||
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
||||||
|
|
||||||
this.industryRepository.assign(industry, updateIndustryDto);
|
this.industryRepository.assign(industry, updateIndustryDto);
|
||||||
@@ -54,8 +58,8 @@ export class IndustriesService {
|
|||||||
|
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async deleteIndustry(id: string) {
|
async deleteIndustry(id: string, businessId: string) {
|
||||||
const industry = await this.industryRepository.findOne({ id, deletedAt: null });
|
const industry = await this.industryRepository.findOne({ id, deletedAt: null, business: { id: businessId } });
|
||||||
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
||||||
|
|
||||||
industry.deletedAt = dayjs().toDate();
|
industry.deletedAt = dayjs().toDate();
|
||||||
@@ -68,14 +72,14 @@ export class IndustriesService {
|
|||||||
}
|
}
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async getIndustriesListForAdmin(queryDto: IndustryListQueryDto) {
|
async getIndustriesListForAdmin(queryDto: IndustryListQueryDto, businessId: string) {
|
||||||
const [industries, count] = await this.industryRepository.getIndustriesListForAdmin(queryDto);
|
const [industries, count] = await this.industryRepository.getIndustriesListForAdmin(queryDto, businessId);
|
||||||
return { industries, count, paginate: true };
|
return { industries, count, paginate: true };
|
||||||
}
|
}
|
||||||
//-----------------------------------
|
//-----------------------------------
|
||||||
|
|
||||||
async toggleStatus(id: string) {
|
async toggleStatus(id: string, businessId: string) {
|
||||||
const industry = await this.industryRepository.findOne({ id, deletedAt: null });
|
const industry = await this.industryRepository.findOne({ id, deletedAt: null, business: { id: businessId } });
|
||||||
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
||||||
|
|
||||||
industry.isActive = !industry.isActive;
|
industry.isActive = !industry.isActive;
|
||||||
|
|||||||
Reference in New Issue
Block a user