From 28486d64ee3374a020d53dcfe9912deb0d29d193 Mon Sep 17 00:00:00 2001 From: mahyargdz Date: Sun, 2 Mar 2025 16:28:07 +0330 Subject: [PATCH] fix: bug in thre login process --- src/app.module.ts | 3 +- .../decorators/is-national-code.decorator.ts | 41 +++ src/common/enums/message.enum.ts | 24 +- src/modules/address/address.controller.ts | 2 + .../address/entities/address.entity.ts | 18 +- src/modules/address/entities/city.entity.ts | 6 +- src/modules/auth/DTO/complete-register.dto.ts | 2 + .../DTO/discount-search-query.dto.ts | 20 +- src/modules/discounts/discounts.controller.ts | 90 +++--- src/modules/discounts/discounts.module.ts | 28 +- .../discounts/providers/discounts.service.ts | 274 +++++++++--------- .../users/DTO/create-legal-user.dto.ts | 74 ++--- src/modules/users/DTO/create-real-user.dto.ts | 51 ++-- src/modules/users/DTO/create-user.dto.ts | 152 +++++----- src/modules/users/DTO/search-customers.dto.ts | 20 +- .../users/entities/real-user.entity.ts | 34 ++- src/modules/users/entities/user.entity.ts | 17 +- src/modules/users/enums/gender-type.enum.ts | 6 +- src/modules/users/enums/nationality.enum.ts | 4 + src/modules/users/providers/users.service.ts | 268 ++++++++--------- src/modules/users/users.controller.ts | 60 ++-- 21 files changed, 606 insertions(+), 588 deletions(-) create mode 100755 src/common/decorators/is-national-code.decorator.ts create mode 100644 src/modules/users/enums/nationality.enum.ts diff --git a/src/app.module.ts b/src/app.module.ts index 048f67c..bfc63c9 100755 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -22,7 +22,7 @@ import { ContactUsModule } from "./modules/contact-us/contact-us.module"; import { CriticismModule } from "./modules/criticisms/criticisms.module"; import { DanakServicesModule } from "./modules/danak-services/danak-services.module"; import { DashboardModule } from "./modules/dashboards/dashboard.module"; -import { DiscountModule } from "./modules/discounts/discounts.module"; +// import { DiscountModule } from "./modules/discounts/discounts.module"; import { InvoicesModule } from "./modules/invoices/invoices.module"; import { LearningModule } from "./modules/learnings/learning.module"; import { NotificationModule } from "./modules/notifications/notifications.module"; @@ -59,7 +59,6 @@ import { WalletsModule } from "./modules/wallets/wallets.module"; InvoicesModule, SubscriptionsModule, LearningModule, - DiscountModule, AdsModule, AddressModule, DashboardModule, diff --git a/src/common/decorators/is-national-code.decorator.ts b/src/common/decorators/is-national-code.decorator.ts new file mode 100755 index 0000000..a72680b --- /dev/null +++ b/src/common/decorators/is-national-code.decorator.ts @@ -0,0 +1,41 @@ +import { + ValidationArguments, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, + registerDecorator, +} from "class-validator"; + +export function isValidIranianNationalCode(nationalCode: string): boolean { + if (!/^\d{10}$/.test(nationalCode)) return false; + + const digits = nationalCode.split("").map(Number); + const controlDigit = digits[9]; + const sum = digits.slice(0, 9).reduce((acc, digit, index) => acc + digit * (10 - index), 0); + const remainder = sum % 11; + + return (remainder < 2 && controlDigit === remainder) || (remainder >= 2 && controlDigit === 11 - remainder); +} + +@ValidatorConstraint({ async: false }) +export class IsNationalCodeConstraint implements ValidatorConstraintInterface { + validate(value: unknown, _args: ValidationArguments) { + return typeof value === "string" && isValidIranianNationalCode(value); + } + + defaultMessage(_args: ValidationArguments) { + return `Invalid Iranian national code :${_args.value}`; + } +} + +export function IsNationalCode(validationOptions?: ValidationOptions) { + return function (object: object, propertyName: string) { + registerDecorator({ + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + constraints: [], + validator: IsNationalCodeConstraint, + }); + }; +} diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index 5fc6de2..6a80d6d 100755 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -55,6 +55,7 @@ export const enum AuthMessage { PHONE_SHOULD_BE_11_DIGIT = "شماره تلفن باید ۱۱ رقم باشد", TIMESTAMP_NOT_EMPTY = "زمان نمی‌تواند خالی باشد", ADMIN_CAN_NOT_LOGIN = "ادمین نمی‌تواند وارد شود", + NATIONAL_CODE_INVALID = "کد ملی نامعتبر است", } export const enum UserMessage { @@ -472,21 +473,18 @@ export const enum EmailMessage { } export const enum FinancialMessage { - GENDER_TYPE_INVALID = "نوع جنسیت باید یکی از مقادیر FEMALE یا MALE باشد", - ECONOMIC_CODE_INVALID = "کد اقتصادی باید یک رشته باشد", + GENDER_TYPE_REQUIRED = "نوع جنسیت مورد نیاز است", + FATHER_NAME_REQUIRED = "نام پدر مورد نیاز است", FATHER_NAME_INVALID = "نام پدر باید یک رشته باشد", - NATIONALITY_INVALID = "ملیت باید یک رشته باشد", - REGISTRATION_ID_INVALID = "شناسه ثبت باید یک رشته باشد", - ADDRESS_ID_INVALID = "ادرس باید یک رشته باشد", - POSTALCODE_INVALID = "کد پستی باید یک رشته باشد", - NATIONAL_ID_INVALID = "شناسه ملی باید یک رشته باشد", - FIXED_PHONE_INVALID = "شماره تماس ثابت باید یک رشته باشد", - USER_ID_REQUIRED = "شناسه کاربر مورد نیاز است", + NATIONALITY_REQUIRED = "ملیت مورد نیاز است", + ADDRESS_REQUIRED = "آدرس مورد نیاز است", + ADDRESS_ID_INVALID = "شناسه آدرس باید یک UUID معتبر باشد", + POSTAL_CODE_REQUIRED = "کد پستی مورد نیاز است", CITY_ID_REQUIRED = "شناسه شهر مورد نیاز است", - USER_ID_SHOULD_BE_A_UUID = "شناسه کاربر باید یک UUID معتبر باشد", - FINANCIAL_INFO_ALREADY_EXISTS = "دیتا اطلاعات مالی وجود دارد", - FINANCIAL_INFO_NOT_FOUND = "دیتا اطلاعات مالی یافت نشد", - SEARCH_QUERY_MUST_BE_A_STRING = "رشته جستجو باید یک رشته باشد", + CITY_ID_INVALID = "شناسه شهر باید یک عددی باشد", + BIRTH_DATE_REQUIRED = "تاریخ تولد مورد نیاز است", + ADDRESS_STRING = "آدرس باید یک رشته باشد", + POSTAL_CODE_NUMBER_STRING = "کد پستی باید یک رشته عددی باشد", } export const enum AdminMessage { diff --git a/src/modules/address/address.controller.ts b/src/modules/address/address.controller.ts index 091c05c..da9bc07 100755 --- a/src/modules/address/address.controller.ts +++ b/src/modules/address/address.controller.ts @@ -4,9 +4,11 @@ import { ApiOperation } from "@nestjs/swagger"; import { SearchCitiesDto } from "./DTO/cities-search-query.dto"; import { SearchProvincesDto } from "./DTO/provinces-search-query.dto"; import { AddressService } from "./providers/address.service"; +import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; import { ParamNumberIdDto } from "../../common/DTO/param.dto"; @Controller("address") +@AuthGuards() export class AddressController { constructor(private readonly addressService: AddressService) {} diff --git a/src/modules/address/entities/address.entity.ts b/src/modules/address/entities/address.entity.ts index d296194..4851a12 100755 --- a/src/modules/address/entities/address.entity.ts +++ b/src/modules/address/entities/address.entity.ts @@ -1,20 +1,16 @@ -import { Column, Entity, ManyToOne, OneToOne } from "typeorm"; +import { Column, Entity, ManyToOne } from "typeorm"; import { City } from "./city.entity"; import { BaseEntity } from "../../../common/entities/base.entity"; -import { User } from "../../users/entities/user.entity"; @Entity() export class Address extends BaseEntity { - @Column({ type: "varchar", length: 255, nullable: true }) - address: string; - - @Column({ type: "varchar", length: 10, nullable: true }) - postalCode: string; - - @ManyToOne(() => City, (city) => city.addresses, { nullable: false }) + @ManyToOne(() => City, { eager: true, onDelete: "SET NULL" }) city: City; - @OneToOne(() => User, (user) => user.address, { onDelete: "CASCADE" }) - user: User; + @Column({ type: "varchar", length: 150 }) + postalCode: string; + + @Column({ type: "text" }) + address: string; } diff --git a/src/modules/address/entities/city.entity.ts b/src/modules/address/entities/city.entity.ts index 61b9a30..312819e 100755 --- a/src/modules/address/entities/city.entity.ts +++ b/src/modules/address/entities/city.entity.ts @@ -1,6 +1,5 @@ -import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; -import { Address } from "./address.entity"; import { Province } from "./province.entity"; @Entity() @@ -11,9 +10,6 @@ export class City { @Column({ type: "varchar", length: 255 }) name: string; - @OneToMany(() => Address, (address) => address.city) - addresses: Address[]; - @ManyToOne(() => Province, (province) => province.cities, { nullable: false }) province: Province; } diff --git a/src/modules/auth/DTO/complete-register.dto.ts b/src/modules/auth/DTO/complete-register.dto.ts index 940318c..d80b493 100755 --- a/src/modules/auth/DTO/complete-register.dto.ts +++ b/src/modules/auth/DTO/complete-register.dto.ts @@ -1,6 +1,7 @@ import { ApiProperty } from "@nestjs/swagger"; import { IsMobilePhone, IsNotEmpty, IsNumberString, IsString, Length, MinLength } from "class-validator"; +import { IsNationalCode } from "../../../common/decorators/is-national-code.decorator"; import { AuthMessage } from "../../../common/enums/message.enum"; export class CompleteRegistrationDto { @@ -41,6 +42,7 @@ export class CompleteRegistrationDto { @IsNotEmpty({ message: AuthMessage.NATIONAL_NOT_EMPTY }) @IsNumberString({ no_symbols: true }, { message: AuthMessage.NATIONAL_CODE_INCORRECT }) @Length(10, 10, { message: AuthMessage.NATIONAL_CODE_INCORRECT }) + @IsNationalCode({ message: AuthMessage.NATIONAL_CODE_INVALID }) @ApiProperty({ description: "iranian format (10 char)", example: "4569852169" }) nationalCode: string; diff --git a/src/modules/discounts/DTO/discount-search-query.dto.ts b/src/modules/discounts/DTO/discount-search-query.dto.ts index f1a1b50..ea39f3b 100755 --- a/src/modules/discounts/DTO/discount-search-query.dto.ts +++ b/src/modules/discounts/DTO/discount-search-query.dto.ts @@ -1,12 +1,12 @@ -import { ApiPropertyOptional } from "@nestjs/swagger"; -import { IsOptional, IsString } from "class-validator"; +// import { ApiPropertyOptional } from "@nestjs/swagger"; +// import { IsOptional, IsString } from "class-validator"; -import { PaginationDto } from "../../../common/DTO/pagination.dto"; -import { FinancialMessage } from "../../../common/enums/message.enum"; +// import { PaginationDto } from "../../../common/DTO/pagination.dto"; +// import { FinancialMessage } from "../../../common/enums/message.enum"; -export class SearchDiscountsDto extends PaginationDto { - @IsOptional() - @IsString({ message: FinancialMessage.SEARCH_QUERY_MUST_BE_A_STRING }) - @ApiPropertyOptional({ description: "search query", example: "search query" }) - q: string; -} +// export class SearchDiscountsDto extends PaginationDto { +// @IsOptional() +// @IsString({ message: FinancialMessage.SEARCH_QUERY_MUST_BE_A_STRING }) +// @ApiPropertyOptional({ description: "search query", example: "search query" }) +// q: string; +// } diff --git a/src/modules/discounts/discounts.controller.ts b/src/modules/discounts/discounts.controller.ts index 9fdeee6..c8a8ba5 100755 --- a/src/modules/discounts/discounts.controller.ts +++ b/src/modules/discounts/discounts.controller.ts @@ -1,58 +1,58 @@ -import { Body, Controller, Get, Param, Patch, Post, Query } from "@nestjs/common"; -import { ApiOperation, ApiTags } from "@nestjs/swagger"; +// import { Body, Controller, Get, Param, Patch, Post, Query } from "@nestjs/common"; +// import { ApiOperation, ApiTags } from "@nestjs/swagger"; -import { CreateDiscountDto } from "./DTO/create-discount.dto"; -import { SearchDiscountsDto } from "./DTO/discount-search-query.dto"; -import { DiscountService } from "./providers/discounts.service"; -import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; -import { UserDec } from "../../common/decorators/user.decorator"; -import { ParamDto } from "../../common/DTO/param.dto"; +// import { CreateDiscountDto } from "./DTO/create-discount.dto"; +// // import { SearchDiscountsDto } from "./DTO/discount-search-query.dto"; +// import { DiscountService } from "./providers/discounts.service"; +// import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; +// import { UserDec } from "../../common/decorators/user.decorator"; +// import { ParamDto } from "../../common/DTO/param.dto"; -@ApiTags("discounts") -@AuthGuards() -@Controller("discounts") -export class DiscountController { - constructor(private readonly discountService: DiscountService) {} +// @ApiTags("discounts") +// @AuthGuards() +// @Controller("discounts") +// export class DiscountController { +// constructor(private readonly discountService: DiscountService) {} - //************************************ */ +// //************************************ */ - @ApiOperation({ summary: "Create a new discount" }) - @Post() - async create(@Body() createDiscountDto: CreateDiscountDto) { - return this.discountService.create(createDiscountDto); - } +// @ApiOperation({ summary: "Create a new discount" }) +// @Post() +// async create(@Body() createDiscountDto: CreateDiscountDto) { +// return this.discountService.create(createDiscountDto); +// } - //************************************ */ +// //************************************ */ - @ApiOperation({ summary: "Retrieve all discounts" }) - @Get() - async findAll(@Query() queryDto: SearchDiscountsDto) { - return this.discountService.findAll(queryDto); - } +// @ApiOperation({ summary: "Retrieve all discounts" }) +// @Get() +// async findAll(@Query() queryDto: SearchDiscountsDto) { +// return this.discountService.findAll(queryDto); +// } - //************************************ */ +// //************************************ */ - @ApiOperation({ summary: "Retrieve a discount by ID" }) - @Get(":id") - async findOne(@Param() paramDto: ParamDto) { - return this.discountService.findOne(paramDto.id); - } +// @ApiOperation({ summary: "Retrieve a discount by ID" }) +// @Get(":id") +// async findOne(@Param() paramDto: ParamDto) { +// return this.discountService.findOne(paramDto.id); +// } - //************************************ */ +// //************************************ */ - @ApiOperation({ summary: "Retrieve a discounts by userID" }) - @Get("/user-discounts") - async findDiscountsByUsers(@Query() queryDto: SearchDiscountsDto, @UserDec("id") userId: string) { - return this.discountService.findDiscountsByUser(queryDto, userId); - } +// @ApiOperation({ summary: "Retrieve a discounts by userID" }) +// @Get("/user-discounts") +// async findDiscountsByUsers(@Query() queryDto: SearchDiscountsDto, @UserDec("id") userId: string) { +// return this.discountService.findDiscountsByUser(queryDto, userId); +// } - //************************************ */ +// //************************************ */ - @ApiOperation({ summary: "Toggle active/deactive discount" }) - @Patch(":id/toggle") - async toggleActive(@Param() paramDto: ParamDto) { - return this.discountService.toggleActive(paramDto.id); - } +// @ApiOperation({ summary: "Toggle active/deactive discount" }) +// @Patch(":id/toggle") +// async toggleActive(@Param() paramDto: ParamDto) { +// return this.discountService.toggleActive(paramDto.id); +// } - //************************************ */ -} +// //************************************ */ +// } diff --git a/src/modules/discounts/discounts.module.ts b/src/modules/discounts/discounts.module.ts index b688121..bc4d677 100755 --- a/src/modules/discounts/discounts.module.ts +++ b/src/modules/discounts/discounts.module.ts @@ -1,16 +1,16 @@ -import { Module } from "@nestjs/common"; -import { TypeOrmModule } from "@nestjs/typeorm"; +// import { Module } from "@nestjs/common"; +// import { TypeOrmModule } from "@nestjs/typeorm"; -import { DiscountController } from "./discounts.controller"; -import { Discount } from "./entities/discount.entity"; -import { DiscountService } from "./providers/discounts.service"; -import { DiscountRepository } from "./repositories/discount.repository"; -import { SubscriptionsModule } from "../subscriptions/subscriptions.module"; -import { UsersModule } from "../users/users.module"; +// import { DiscountController } from "./discounts.controller"; +// import { Discount } from "./entities/discount.entity"; +// import { DiscountService } from "./providers/discounts.service"; +// import { DiscountRepository } from "./repositories/discount.repository"; +// import { SubscriptionsModule } from "../subscriptions/subscriptions.module"; +// import { UsersModule } from "../users/users.module"; -@Module({ - imports: [TypeOrmModule.forFeature([Discount]), SubscriptionsModule, UsersModule], - providers: [DiscountService, DiscountRepository], - controllers: [DiscountController], -}) -export class DiscountModule {} +// @Module({ +// imports: [TypeOrmModule.forFeature([Discount]), SubscriptionsModule, UsersModule], +// providers: [DiscountService, DiscountRepository], +// controllers: [DiscountController], +// }) +// export class DiscountModule {} diff --git a/src/modules/discounts/providers/discounts.service.ts b/src/modules/discounts/providers/discounts.service.ts index 1b002df..6e6f858 100755 --- a/src/modules/discounts/providers/discounts.service.ts +++ b/src/modules/discounts/providers/discounts.service.ts @@ -1,182 +1,182 @@ -import { randomBytes } from "node:crypto"; +// import { randomBytes } from "node:crypto"; -import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common"; -import { In } from "typeorm"; +// import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common"; +// import { In } from "typeorm"; -import { CommonMessage, DiscountMessage, SubscriptionMessage, UserMessage } from "../../../common/enums/message.enum"; -import { SubscriptionsPlanRepository } from "../../subscriptions/repositories/subscriptions.repository"; -import { UserRepository } from "../../users/repositories/users.repository"; -import { PaginationUtils } from "../../utils/providers/pagination.utils"; -import { CreateDiscountDto } from "../DTO/create-discount.dto"; -import { SearchDiscountsDto } from "../DTO/discount-search-query.dto"; -import { DiscountRepository } from "../repositories/discount.repository"; +// import { CommonMessage, DiscountMessage, SubscriptionMessage, UserMessage } from "../../../common/enums/message.enum"; +// import { SubscriptionsPlanRepository } from "../../subscriptions/repositories/subscriptions.repository"; +// import { UserRepository } from "../../users/repositories/users.repository"; +// import { PaginationUtils } from "../../utils/providers/pagination.utils"; +// import { CreateDiscountDto } from "../DTO/create-discount.dto"; +// import { SearchDiscountsDto } from "../DTO/discount-search-query.dto"; +// import { DiscountRepository } from "../repositories/discount.repository"; -@Injectable() -export class DiscountService { - constructor( - private readonly discountRepository: DiscountRepository, - private readonly subscriptionPlanRepository: SubscriptionsPlanRepository, - private readonly userRepository: UserRepository, - ) {} +// @Injectable() +// export class DiscountService { +// constructor( +// private readonly discountRepository: DiscountRepository, +// private readonly subscriptionPlanRepository: SubscriptionsPlanRepository, +// private readonly userRepository: UserRepository, +// ) {} - /******************************************** */ +// /******************************************** */ - async create(createDiscountDto: CreateDiscountDto) { - const { subscriptionPlanIds, ...discountData } = createDiscountDto; +// async create(createDiscountDto: CreateDiscountDto) { +// const { subscriptionPlanIds, ...discountData } = createDiscountDto; - const code = await this.generateUniqueCouponCode(); +// const code = await this.generateUniqueCouponCode(); - const discount = this.discountRepository.create({ - ...discountData, - code, - }); +// const discount = this.discountRepository.create({ +// ...discountData, +// code, +// }); - if (createDiscountDto.subscriptionPlanIds && createDiscountDto.subscriptionPlanIds.length) { - const subscriptionPlans = await this.subscriptionPlanRepository.find({ - where: { id: In(createDiscountDto.subscriptionPlanIds) }, - }); +// if (createDiscountDto.subscriptionPlanIds && createDiscountDto.subscriptionPlanIds.length) { +// const subscriptionPlans = await this.subscriptionPlanRepository.find({ +// where: { id: In(createDiscountDto.subscriptionPlanIds) }, +// }); - if (subscriptionPlans.length !== createDiscountDto.subscriptionPlanIds.length) { - throw new NotFoundException(SubscriptionMessage.NOT_FOUND); - } +// if (subscriptionPlans.length !== createDiscountDto.subscriptionPlanIds.length) { +// throw new NotFoundException(SubscriptionMessage.NOT_FOUND); +// } - discount.subscriptionPlans = subscriptionPlans; - } +// discount.subscriptionPlans = subscriptionPlans; +// } - if (createDiscountDto.userIds) { - const users = await this.userRepository.find({ where: { id: In(createDiscountDto.userIds) } }); +// if (createDiscountDto.userIds) { +// const users = await this.userRepository.find({ where: { id: In(createDiscountDto.userIds) } }); - if (users.length !== createDiscountDto.userIds.length) { - throw new NotFoundException(UserMessage.USER_NOT_FOUND); - } +// if (users.length !== createDiscountDto.userIds.length) { +// throw new NotFoundException(UserMessage.USER_NOT_FOUND); +// } - discount.users = users; - } +// discount.users = users; +// } - await this.discountRepository.save(discount); +// await this.discountRepository.save(discount); - return { - message: CommonMessage.CREATED, - discount, - }; - } +// return { +// message: CommonMessage.CREATED, +// discount, +// }; +// } - /******************************************** */ +// /******************************************** */ - async findByCode(code: string) { - const discount = await this.discountRepository.findOne({ - where: { code, isActive: true }, - relations: ["subscriptionPlans"], - }); - if (!discount) { - throw new NotFoundException(DiscountMessage.NOT_FOUND); - } - return { discount }; - } +// async findByCode(code: string) { +// const discount = await this.discountRepository.findOne({ +// where: { code, isActive: true }, +// relations: ["subscriptionPlans"], +// }); +// if (!discount) { +// throw new NotFoundException(DiscountMessage.NOT_FOUND); +// } +// return { discount }; +// } - /******************************************** */ +// /******************************************** */ - async findDiscountsByUser(queryDto: SearchDiscountsDto, userId: string) { - const user = await this.userRepository.findOneBy({ - id: userId, - }); - if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND); +// async findDiscountsByUser(queryDto: SearchDiscountsDto, userId: string) { +// const user = await this.userRepository.findOneBy({ +// id: userId, +// }); +// if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND); - const { limit, skip } = PaginationUtils(queryDto); +// const { limit, skip } = PaginationUtils(queryDto); - const queryBuilder = this.discountRepository.createQueryBuilder("discount"); +// const queryBuilder = this.discountRepository.createQueryBuilder("discount"); - queryBuilder - .leftJoin("discount.users", "user") - .where("user.id = :userId", { userId: user.id }) - .leftJoinAndSelect("discount.subscriptionPlans", "subscriptionPlans") - .leftJoin("subscriptionPlans.service", "service") - .addSelect(["service.id", "service.name", "service.title", "service.link", "service.icon", "service.description"]); +// queryBuilder +// .leftJoin("discount.users", "user") +// .where("user.id = :userId", { userId: user.id }) +// .leftJoinAndSelect("discount.subscriptionPlans", "subscriptionPlans") +// .leftJoin("subscriptionPlans.service", "service") +// .addSelect(["service.id", "service.name", "service.title", "service.link", "service.icon", "service.description"]); - if (queryDto.q) { - queryBuilder.andWhere("discount.code ILIKE :q", { q: `%${queryDto.q}%` }); - } +// if (queryDto.q) { +// queryBuilder.andWhere("discount.code ILIKE :q", { q: `%${queryDto.q}%` }); +// } - queryBuilder.orderBy("discount.createdAt", "DESC").skip(skip).take(limit); +// queryBuilder.orderBy("discount.createdAt", "DESC").skip(skip).take(limit); - const [discounts, count] = await queryBuilder.getManyAndCount(); +// const [discounts, count] = await queryBuilder.getManyAndCount(); - return { - discounts, - count, - paginate: true, - }; - } +// return { +// discounts, +// count, +// paginate: true, +// }; +// } - /******************************************** */ +// /******************************************** */ - async findAll(queryDto: SearchDiscountsDto) { - const { limit, skip } = PaginationUtils(queryDto); +// async findAll(queryDto: SearchDiscountsDto) { +// const { limit, skip } = PaginationUtils(queryDto); - const queryBuilder = this.discountRepository.createQueryBuilder("discount"); +// const queryBuilder = this.discountRepository.createQueryBuilder("discount"); - queryBuilder - .leftJoinAndSelect("discount.subscriptionPlans", "subscriptionPlans") - .leftJoin("subscriptionPlans.service", "service") - .addSelect(["service.id", "service.name", "service.title", "service.link", "service.icon", "service.description"]) - .leftJoinAndSelect("discount.users", "users"); +// queryBuilder +// .leftJoinAndSelect("discount.subscriptionPlans", "subscriptionPlans") +// .leftJoin("subscriptionPlans.service", "service") +// .addSelect(["service.id", "service.name", "service.title", "service.link", "service.icon", "service.description"]) +// .leftJoinAndSelect("discount.users", "users"); - if (queryDto.q) { - queryBuilder.andWhere("discount.code ILIKE :q", { q: `%${queryDto.q}%` }); - } +// if (queryDto.q) { +// queryBuilder.andWhere("discount.code ILIKE :q", { q: `%${queryDto.q}%` }); +// } - queryBuilder.orderBy("discount.createdAt", "DESC").skip(skip).take(limit); +// queryBuilder.orderBy("discount.createdAt", "DESC").skip(skip).take(limit); - const [discounts, count] = await queryBuilder.getManyAndCount(); +// const [discounts, count] = await queryBuilder.getManyAndCount(); - return { - discounts, - count, - paginate: true, - }; - } +// return { +// discounts, +// count, +// paginate: true, +// }; +// } - /******************************************** */ +// /******************************************** */ - async findOne(id: string) { - const discount = await this.discountRepository.findOne({ - where: { id }, - relations: ["subscriptionPlans"], - }); - if (!discount) throw new BadRequestException(DiscountMessage.NOT_FOUND); - return { discount }; - } +// async findOne(id: string) { +// const discount = await this.discountRepository.findOne({ +// where: { id }, +// relations: ["subscriptionPlans"], +// }); +// if (!discount) throw new BadRequestException(DiscountMessage.NOT_FOUND); +// return { discount }; +// } - /******************************************** */ +// /******************************************** */ - async toggleActive(id: string) { - const discount = await this.discountRepository.findOne({ where: { id } }); - if (!discount) { - throw new BadRequestException(DiscountMessage.NOT_FOUND); - } +// async toggleActive(id: string) { +// const discount = await this.discountRepository.findOne({ where: { id } }); +// if (!discount) { +// throw new BadRequestException(DiscountMessage.NOT_FOUND); +// } - discount.isActive = !discount.isActive; +// discount.isActive = !discount.isActive; - const updatedDiscount = await this.discountRepository.save(discount); +// const updatedDiscount = await this.discountRepository.save(discount); - return { - message: CommonMessage.UPDATE_SUCCESS, - updatedDiscount, - }; - } +// return { +// message: CommonMessage.UPDATE_SUCCESS, +// updatedDiscount, +// }; +// } - /******************************************** */ +// /******************************************** */ - async generateUniqueCouponCode(): Promise { - const code = this.generateCouponCode(); - const exists = await this.discountRepository.findOne({ where: { code } }); - if (exists) return this.generateUniqueCouponCode(); - return code; - } +// async generateUniqueCouponCode(): Promise { +// const code = this.generateCouponCode(); +// const exists = await this.discountRepository.findOne({ where: { code } }); +// if (exists) return this.generateUniqueCouponCode(); +// return code; +// } - /******************************************** */ +// /******************************************** */ - private generateCouponCode(length = 8) { - return randomBytes(length).toString("hex").slice(0, length).toUpperCase(); - } -} +// private generateCouponCode(length = 8) { +// return randomBytes(length).toString("hex").slice(0, length).toUpperCase(); +// } +// } diff --git a/src/modules/users/DTO/create-legal-user.dto.ts b/src/modules/users/DTO/create-legal-user.dto.ts index 2446dfe..8173a63 100755 --- a/src/modules/users/DTO/create-legal-user.dto.ts +++ b/src/modules/users/DTO/create-legal-user.dto.ts @@ -1,46 +1,46 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsOptional, IsString } from "class-validator"; +// import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; +// import { IsNotEmpty, IsOptional, IsString } from "class-validator"; -import { FinancialMessage } from "../../../common/enums/message.enum"; +// import { FinancialMessage } from "../../../common/enums/message.enum"; -export class CreateLegalUserDto { - @ApiProperty({ description: "Economic code" }) - @IsOptional() - @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) - economicCode?: string; +// export class CreateLegalUserDto { +// @ApiProperty({ description: "Economic code" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) +// economicCode?: string; - @ApiProperty({ description: "Company registered name" }) - @IsOptional() - @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) - companyRegisteredName?: string; +// @ApiProperty({ description: "Company registered name" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) +// companyRegisteredName?: string; - @ApiProperty({ description: "Registration ID" }) - @IsOptional() - @IsString({ message: FinancialMessage.REGISTRATION_ID_INVALID }) - registrationId?: string; +// @ApiProperty({ description: "Registration ID" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.REGISTRATION_ID_INVALID }) +// registrationId?: string; - @ApiProperty({ description: "national Id" }) - @IsOptional() - @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) - nationalId?: string; +// @ApiProperty({ description: "national Id" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) +// nationalId?: string; - @ApiPropertyOptional({ description: "number" }) - @IsOptional() - @IsString({ message: FinancialMessage.FIXED_PHONE_INVALID }) - number?: string; +// @ApiPropertyOptional({ description: "number" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.FIXED_PHONE_INVALID }) +// number?: string; - @ApiPropertyOptional({ description: "postalCode" }) - @IsOptional() - @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) - postalCode?: string; +// @ApiPropertyOptional({ description: "postalCode" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) +// postalCode?: string; - @ApiPropertyOptional({ description: "address" }) - @IsOptional() - @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) - address?: string; +// @ApiPropertyOptional({ description: "address" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) +// address?: string; - @ApiPropertyOptional({ description: "City id", example: "1" }) - @IsOptional() - @IsNotEmpty({ message: FinancialMessage.CITY_ID_REQUIRED }) - cityId: string; -} +// @ApiPropertyOptional({ description: "City id", example: "1" }) +// @IsOptional() +// @IsNotEmpty({ message: FinancialMessage.CITY_ID_REQUIRED }) +// cityId: string; +// } diff --git a/src/modules/users/DTO/create-real-user.dto.ts b/src/modules/users/DTO/create-real-user.dto.ts index 7caca28..7a7723c 100755 --- a/src/modules/users/DTO/create-real-user.dto.ts +++ b/src/modules/users/DTO/create-real-user.dto.ts @@ -1,37 +1,38 @@ -import { ApiPropertyOptional } from "@nestjs/swagger"; -import { IsEnum, IsNotEmpty, IsOptional, IsString } from "class-validator"; +import { ApiProperty } from "@nestjs/swagger"; +import { IsEnum, IsInt, IsNotEmpty, IsNumberString, IsString } from "class-validator"; import { FinancialMessage } from "../../../common/enums/message.enum"; -import { GenderType } from "../enums/gender-type.enum"; +import { GenderEnum } from "../enums/gender-type.enum"; +import { NationalityEnum } from "../enums/nationality.enum"; export class CreateRealUserDto { - @ApiPropertyOptional({ enum: GenderType, description: "Gender type" }) - @IsOptional() - @IsEnum(GenderType, { message: FinancialMessage.GENDER_TYPE_INVALID }) - gender?: GenderType; + @IsNotEmpty({ message: FinancialMessage.GENDER_TYPE_REQUIRED }) + @IsEnum(GenderEnum) + @ApiProperty({ enum: GenderEnum, description: "Gender type", example: GenderEnum.MALE }) + gender: GenderEnum; - @ApiPropertyOptional({ description: "Father name" }) - @IsOptional() + @IsNotEmpty({ message: FinancialMessage.FATHER_NAME_REQUIRED }) @IsString({ message: FinancialMessage.FATHER_NAME_INVALID }) - fatherName?: string; + @ApiProperty({ description: "Father name" }) + fatherName: string; - @ApiPropertyOptional({ description: "nationality" }) - @IsOptional() - @IsString({ message: FinancialMessage.NATIONALITY_INVALID }) - nationality?: string; + @IsNotEmpty({ message: FinancialMessage.NATIONALITY_REQUIRED }) + @IsEnum(NationalityEnum) + @ApiProperty({ description: "Nationality" }) + nationality: string; - @ApiPropertyOptional({ description: "Address" }) - @IsOptional() - @IsString({ message: FinancialMessage.ADDRESS_ID_INVALID }) - address?: string; + @IsNotEmpty({ message: FinancialMessage.ADDRESS_REQUIRED }) + @IsString({ message: FinancialMessage.ADDRESS_STRING }) + @ApiProperty({ description: "Address" }) + address: string; - @ApiPropertyOptional({ description: "PostalCode" }) - @IsOptional() - @IsString({ message: FinancialMessage.ADDRESS_ID_INVALID }) - postalCode?: string; + @IsNotEmpty({ message: FinancialMessage.POSTAL_CODE_REQUIRED }) + @IsNumberString({ no_symbols: true }, { message: FinancialMessage.POSTAL_CODE_NUMBER_STRING }) + @ApiProperty({ description: "Postal code", example: "1234567890" }) + postalCode: string; - @ApiPropertyOptional({ description: "City id", example: "1" }) - @IsOptional() @IsNotEmpty({ message: FinancialMessage.CITY_ID_REQUIRED }) - cityId: string; + @IsInt({ message: FinancialMessage.CITY_ID_INVALID }) + @ApiProperty({ description: "City ID", example: "1" }) + cityId: number; } diff --git a/src/modules/users/DTO/create-user.dto.ts b/src/modules/users/DTO/create-user.dto.ts index 1848584..b961560 100755 --- a/src/modules/users/DTO/create-user.dto.ts +++ b/src/modules/users/DTO/create-user.dto.ts @@ -1,92 +1,94 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsEmail, IsMobilePhone, IsNotEmpty, IsNumberString, IsOptional, IsString, IsUrl, Length, MinLength } from "class-validator"; +// import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; +// import { IsEmail, IsMobilePhone, IsNotEmpty, IsNumberString, IsOptional, IsString, IsUrl, Length, MinLength } from "class-validator"; -import { AuthMessage, FinancialMessage, UserMessage } from "../../../common/enums/message.enum"; +// import { IsNationalCode } from "../../../common/decorators/is-national-code.decorator"; +// import { AuthMessage, FinancialMessage, UserMessage } from "../../../common/enums/message.enum"; -export class CreateCustomerDto { - @IsNotEmpty({ message: AuthMessage.PHONE_NOT_EMPTY }) - @IsMobilePhone("fa-IR", {}, { message: AuthMessage.INVALID_PHONE_FORMAT }) - @Length(11, 11, { message: AuthMessage.PHONE_SHOULD_BE_11_DIGIT }) - @ApiProperty({ description: "phone number", default: "09922320740" }) - phone: string; +// export class CreateCustomerDto { +// @IsNotEmpty({ message: AuthMessage.PHONE_NOT_EMPTY }) +// @IsMobilePhone("fa-IR", {}, { message: AuthMessage.INVALID_PHONE_FORMAT }) +// @Length(11, 11, { message: AuthMessage.PHONE_SHOULD_BE_11_DIGIT }) +// @ApiProperty({ description: "phone number", default: "09922320740" }) +// phone: string; - @IsNotEmpty({ message: AuthMessage.FIRST_NAME_NOT_EMPTY }) - @IsString({ message: AuthMessage.FIRST_NAME_NOT_EMPTY }) - @Length(2, 50, { message: AuthMessage.FIRST_NAME_SHOULD_BE_BETWEEN_2_AND_50 }) - @ApiProperty({ description: "First name", example: "mahyar" }) - firstName: string; +// @IsNotEmpty({ message: AuthMessage.FIRST_NAME_NOT_EMPTY }) +// @IsString({ message: AuthMessage.FIRST_NAME_NOT_EMPTY }) +// @Length(2, 50, { message: AuthMessage.FIRST_NAME_SHOULD_BE_BETWEEN_2_AND_50 }) +// @ApiProperty({ description: "First name", example: "mahyar" }) +// firstName: string; - @IsNotEmpty({ message: AuthMessage.LAST_NAME_NOT_EMPTY }) - @IsString({ message: AuthMessage.LAST_NAME_NOT_EMPTY }) - @Length(2, 50, { message: AuthMessage.LAST_NAME_SHOULD_BE_BETWEEN_2_AND_50 }) - @ApiProperty({ description: "Last name", example: "jamshidi" }) - lastName: string; +// @IsNotEmpty({ message: AuthMessage.LAST_NAME_NOT_EMPTY }) +// @IsString({ message: AuthMessage.LAST_NAME_NOT_EMPTY }) +// @Length(2, 50, { message: AuthMessage.LAST_NAME_SHOULD_BE_BETWEEN_2_AND_50 }) +// @ApiProperty({ description: "Last name", example: "jamshidi" }) +// lastName: string; - @IsNotEmpty({ message: AuthMessage.EMAIL_NOT_EMPTY }) - @IsEmail({}, { message: AuthMessage.INVALID_EMAIL_FORMAT }) - @ApiProperty({ description: "Email", example: "ma@gmail.com" }) - email: string; +// @IsNotEmpty({ message: AuthMessage.EMAIL_NOT_EMPTY }) +// @IsEmail({}, { message: AuthMessage.INVALID_EMAIL_FORMAT }) +// @ApiProperty({ description: "Email", example: "ma@gmail.com" }) +// email: string; - @IsNotEmpty({ message: AuthMessage.BIRTH_DATE_NOT_EMPTY }) - @IsString({ message: AuthMessage.BIRTH_DATE_NOT_EMPTY }) - @ApiProperty({ description: "Birth date", example: "1403/01/01" }) - birthDate: string; +// @IsNotEmpty({ message: AuthMessage.BIRTH_DATE_NOT_EMPTY }) +// @IsString({ message: AuthMessage.BIRTH_DATE_NOT_EMPTY }) +// @ApiProperty({ description: "Birth date", example: "1403/01/01" }) +// birthDate: string; - @IsNotEmpty({ message: AuthMessage.NATIONAL_NOT_EMPTY }) - @IsNumberString({ no_symbols: true }, { message: AuthMessage.NATIONAL_CODE_INCORRECT }) - @Length(10, 10, { message: AuthMessage.NATIONAL_CODE_INCORRECT }) - @ApiProperty({ description: "iranian format (10 char)", example: "4569852169" }) - nationalCode: string; +// @IsNotEmpty({ message: AuthMessage.NATIONAL_NOT_EMPTY }) +// @IsNumberString({ no_symbols: true }, { message: AuthMessage.NATIONAL_CODE_INCORRECT }) +// @Length(10, 10, { message: AuthMessage.NATIONAL_CODE_INCORRECT }) +// @IsNationalCode({ message: AuthMessage.NATIONAL_CODE_INVALID }) +// @ApiProperty({ description: "iranian format (10 char)", example: "4569852169" }) +// nationalCode: string; - @IsNotEmpty({ message: AuthMessage.PASSWORD_NOT_EMPTY }) - @IsString({ message: AuthMessage.PASSWORD_FORMAT_INVALID }) - @ApiProperty({ description: "password", example: "12S345SS678" }) - @MinLength(8, { message: AuthMessage.PASSWORD_LENGTH }) - password: string; +// @IsNotEmpty({ message: AuthMessage.PASSWORD_NOT_EMPTY }) +// @IsString({ message: AuthMessage.PASSWORD_FORMAT_INVALID }) +// @ApiProperty({ description: "password", example: "12S345SS678" }) +// @MinLength(8, { message: AuthMessage.PASSWORD_LENGTH }) +// password: string; - @ApiPropertyOptional({ description: "Economic code" }) - @IsOptional() - @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) - economicCode?: string; +// @ApiPropertyOptional({ description: "Economic code" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) +// economicCode?: string; - @ApiPropertyOptional({ description: "Company registered name" }) - @IsOptional() - @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) - companyRegisteredName?: string; +// @ApiPropertyOptional({ description: "Company registered name" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.ECONOMIC_CODE_INVALID }) +// companyRegisteredName?: string; - @ApiPropertyOptional({ description: "Registration ID" }) - @IsOptional() - @IsString({ message: FinancialMessage.REGISTRATION_ID_INVALID }) - registrationId?: string; +// @ApiPropertyOptional({ description: "Registration ID" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.REGISTRATION_ID_INVALID }) +// registrationId?: string; - @ApiPropertyOptional({ description: "national Id" }) - @IsOptional() - @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) - nationalId?: string; +// @ApiPropertyOptional({ description: "national Id" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) +// nationalId?: string; - @ApiPropertyOptional({ description: "number" }) - @IsOptional() - @IsString({ message: FinancialMessage.FIXED_PHONE_INVALID }) - number?: string; +// @ApiPropertyOptional({ description: "number" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.FIXED_PHONE_INVALID }) +// number?: string; - @ApiPropertyOptional({ description: "postalCode" }) - @IsOptional() - @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) - postalCode?: string; +// @ApiPropertyOptional({ description: "postalCode" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) +// postalCode?: string; - @ApiPropertyOptional({ description: "address" }) - @IsOptional() - @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) - address?: string; +// @ApiPropertyOptional({ description: "address" }) +// @IsOptional() +// @IsString({ message: FinancialMessage.NATIONAL_ID_INVALID }) +// address?: string; - @ApiPropertyOptional({ description: "City id", example: "1" }) - @IsOptional() - @IsNotEmpty({ message: FinancialMessage.CITY_ID_REQUIRED }) - cityId: string; +// @ApiPropertyOptional({ description: "City id", example: "1" }) +// @IsOptional() +// @IsNotEmpty({ message: FinancialMessage.CITY_ID_REQUIRED }) +// cityId: string; - @IsOptional() - @IsNotEmpty({ message: UserMessage.PROFILE_PIC_REQUIRED }) - @IsUrl({ protocols: ["http", "https"], require_protocol: true }, { message: UserMessage.PROFILE_PIC_URL }) - @ApiPropertyOptional({ description: "Profile picture", example: "https://www.google.com" }) - profilePic: string; -} +// @IsOptional() +// @IsNotEmpty({ message: UserMessage.PROFILE_PIC_REQUIRED }) +// @IsUrl({ protocols: ["http", "https"], require_protocol: true }, { message: UserMessage.PROFILE_PIC_URL }) +// @ApiPropertyOptional({ description: "Profile picture", example: "https://www.google.com" }) +// profilePic: string; +// } diff --git a/src/modules/users/DTO/search-customers.dto.ts b/src/modules/users/DTO/search-customers.dto.ts index 7987e61..7e8e13e 100755 --- a/src/modules/users/DTO/search-customers.dto.ts +++ b/src/modules/users/DTO/search-customers.dto.ts @@ -1,12 +1,12 @@ -import { ApiPropertyOptional } from "@nestjs/swagger"; -import { IsOptional, IsString } from "class-validator"; +// import { ApiPropertyOptional } from "@nestjs/swagger"; +// import { IsOptional, IsString } from "class-validator"; -import { PaginationDto } from "../../../common/DTO/pagination.dto"; -import { FinancialMessage } from "../../../common/enums/message.enum"; +// import { PaginationDto } from "../../../common/DTO/pagination.dto"; +// import { FinancialMessage } from "../../../common/enums/message.enum"; -export class SearchCustomersDto extends PaginationDto { - @IsOptional() - @IsString({ message: FinancialMessage.SEARCH_QUERY_MUST_BE_A_STRING }) - @ApiPropertyOptional({ description: "search query", example: "search query" }) - q: string; -} +// export class SearchCustomersDto extends PaginationDto { +// @IsOptional() +// @IsString({ message: FinancialMessage.SEARCH_QUERY_MUST_BE_A_STRING }) +// @ApiPropertyOptional({ description: "search query", example: "search query" }) +// q: string; +// } diff --git a/src/modules/users/entities/real-user.entity.ts b/src/modules/users/entities/real-user.entity.ts index 12bb7b2..ce173bb 100755 --- a/src/modules/users/entities/real-user.entity.ts +++ b/src/modules/users/entities/real-user.entity.ts @@ -3,29 +3,41 @@ import { Column, Entity, JoinColumn, OneToOne, Unique } from "typeorm"; import { User } from "./user.entity"; import { BaseEntity } from "../../../common/entities/base.entity"; import { Address } from "../../address/entities/address.entity"; -import { GenderType } from "../enums/gender-type.enum"; +import { GenderEnum } from "../enums/gender-type.enum"; +import { NationalityEnum } from "../enums/nationality.enum"; @Unique(["user"]) @Entity() export class RealUser extends BaseEntity { - @Column({ - type: "enum", - enum: GenderType, - nullable: true, - }) - gender: GenderType; + @Column({ type: "varchar", length: 150 }) + firstName: string; - @Column({ nullable: true }) + @Column({ type: "varchar", length: 200 }) + lastName: string; + + @Column({ type: "varchar", length: 100 }) fatherName: string; - @Column({ nullable: true }) - nationality: string; + @Column({ type: "varchar", length: 12, nullable: true }) + birthDate: string; + + @Column({ type: "varchar", length: 100, unique: true }) + nationalCode: string; + + @Column({ type: "varchar", length: 11, unique: true, nullable: false }) + phone: string; + + @Column({ type: "enum", enum: GenderEnum }) + gender: GenderEnum; + + @Column({ type: "enum", enum: NationalityEnum }) + nationality: NationalityEnum; @OneToOne(() => Address, { nullable: false, cascade: true }) @JoinColumn() address: Address; - @OneToOne(() => User, (user) => user.realUser, { onDelete: "CASCADE" }) + @OneToOne(() => User, (user) => user.realUser, { onDelete: "CASCADE", nullable: false }) @JoinColumn() user: User; } diff --git a/src/modules/users/entities/user.entity.ts b/src/modules/users/entities/user.entity.ts index 33517bb..5bb4929 100755 --- a/src/modules/users/entities/user.entity.ts +++ b/src/modules/users/entities/user.entity.ts @@ -1,13 +1,11 @@ import { Exclude } from "class-transformer"; -import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToMany, OneToOne } from "typeorm"; +import { Column, Entity, JoinTable, ManyToMany, OneToMany, OneToOne } from "typeorm"; import { LegalUser } from "./legal-user.entity"; import { RealUser } from "./real-user.entity"; import { Role } from "./role.entity"; import { UserGroup } from "./user-group.entity"; import { BaseEntity } from "../../../common/entities/base.entity"; -import { Address } from "../../address/entities/address.entity"; -import { City } from "../../address/entities/city.entity"; import { UserAnnouncement } from "../../announcements/entities/user-announcement.entity"; import { Criticism } from "../../criticisms/entities/criticism.entity"; import { DanakServiceReview } from "../../danak-services/entities/danak-service-review.entity"; @@ -57,17 +55,8 @@ export class User extends BaseEntity { @Column({ type: "boolean", default: false }) emailVerified: boolean; - @Column({ type: "varchar", length: 255, nullable: true }) - userAddress: string; - - @Column({ type: "varchar", length: 10, nullable: true }) - postalCode: string; //----------------------------------------- - @ManyToOne(() => City, { eager: true, nullable: true }) - city: City; - // @ManyToOne(() => Role, { eager: true, onDelete: "RESTRICT", nullable: false }) - // role: Role; @ManyToMany(() => Role, (role) => role.users) @JoinTable({ name: "user_role_relation" }) roles: Role[]; @@ -119,10 +108,6 @@ export class User extends BaseEntity { @OneToOne(() => LegalUser, (legalUser) => legalUser.user, { cascade: true, nullable: true }) legalUser: LegalUser; - @OneToOne(() => Address, (address) => address.user, { cascade: true, nullable: true }) - @JoinColumn() - address: Address; - @ManyToMany(() => UsageDiscount, (usageDiscount) => usageDiscount.users) usageDiscounts: UsageDiscount[]; diff --git a/src/modules/users/enums/gender-type.enum.ts b/src/modules/users/enums/gender-type.enum.ts index 4c4f4ee..b0724ed 100755 --- a/src/modules/users/enums/gender-type.enum.ts +++ b/src/modules/users/enums/gender-type.enum.ts @@ -1,4 +1,4 @@ -export enum GenderType { - MALE = "male", - FEMALE = "female", +export enum GenderEnum { + MALE = "MALE", + FEMALE = "FEMALE", } diff --git a/src/modules/users/enums/nationality.enum.ts b/src/modules/users/enums/nationality.enum.ts new file mode 100644 index 0000000..2701345 --- /dev/null +++ b/src/modules/users/enums/nationality.enum.ts @@ -0,0 +1,4 @@ +export enum NationalityEnum { + IRANIAN = "IRANIAN", + FOREIGN = "FOREIGN", +} diff --git a/src/modules/users/providers/users.service.ts b/src/modules/users/providers/users.service.ts index f33f421..8748e2a 100755 --- a/src/modules/users/providers/users.service.ts +++ b/src/modules/users/providers/users.service.ts @@ -6,15 +6,7 @@ import { FastifyReply } from "fastify"; import slugify from "slugify"; import { In, Not, QueryRunner } from "typeorm"; -import { - AdminMessage, - AdsMessage, - AuthMessage, - CommonMessage, - LegalUserMessage, - RealUserMessage, - UserMessage, -} from "../../../common/enums/message.enum"; +import { AdminMessage, AdsMessage, AuthMessage, CommonMessage, UserMessage } from "../../../common/enums/message.enum"; import { AddressService } from "../../address/providers/address.service"; import { CompleteRegistrationDto } from "../../auth/DTO/complete-register.dto"; import { RequestOtpDto } from "../../auth/DTO/request-otp.dto"; @@ -30,12 +22,8 @@ import { WalletsService } from "../../wallets/providers/wallets.service"; import { ChangeEmailDto } from "../DTO/change-email.dto"; import { CheckValidityDTO } from "../DTO/check-validity.dto"; import { CreateAdminDto } from "../DTO/create-admin.dto"; -import { CreateLegalUserDto } from "../DTO/create-legal-user.dto"; -import { CreateRealUserDto } from "../DTO/create-real-user.dto"; import { CreateRoleDto } from "../DTO/create-role.dto"; -import { CreateCustomerDto } from "../DTO/create-user.dto"; import { SearchAdminQueryDto } from "../DTO/search-admins-query.dto"; -import { SearchCustomersDto } from "../DTO/search-customers.dto"; import { SearchRolesQueryDto } from "../DTO/search-roles.dto"; import { UpdateProfileDto } from "../DTO/update-profile.dto"; import { CreateUserGroupDto } from "../DTO/user-group.dto"; @@ -44,9 +32,7 @@ import { Role } from "../entities/role.entity"; import { User } from "../entities/user.entity"; import { RoleEnum } from "../enums/role.enum"; import { ValidityType } from "../enums/validity-type.enum"; -import { LegalUserRepository } from "../repositories/legal-user.repository"; import { PermissionsRepository } from "../repositories/permissions.repository"; -import { RealUserRepository } from "../repositories/real-user.repository"; import { RoleRepository } from "../repositories/roles.repository"; import { UserGroupRepository } from "../repositories/user-group.repository"; import { UserRepository } from "../repositories/users.repository"; @@ -62,8 +48,6 @@ export class UsersService { private readonly rolesRepository: RoleRepository, private readonly permissionsRepository: PermissionsRepository, private readonly passwordService: PasswordService, - private readonly realUserRepository: RealUserRepository, - private readonly legalUserRepository: LegalUserRepository, private readonly addressService: AddressService, private readonly emailService: EmailService, private readonly configService: ConfigService, @@ -90,7 +74,7 @@ export class UsersService { /************************************************************ */ async getMe(userId: string) { - const user = await this.userRepository.findOne({ where: { id: userId }, relations: { roles: true, city: { province: true } } }); + const user = await this.userRepository.findOne({ where: { id: userId }, relations: { roles: true } }); if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND); return { user }; } @@ -405,93 +389,93 @@ export class UsersService { /************************************************************ */ - async findAllCustomers(queryDto: SearchCustomersDto) { - const { limit, skip } = PaginationUtils(queryDto); + // async findAllCustomers(queryDto: SearchCustomersDto) { + // const { limit, skip } = PaginationUtils(queryDto); - const queryBuilder = this.userRepository - .createQueryBuilder("user") - .leftJoin("user.roles", "role") - .where("role.name = :roleName", { roleName: RoleEnum.USER }) - .leftJoin("user.groups", "groups") - .addSelect(["groups.id", "groups.name"]) - .loadRelationCountAndMap("user.invoicesCount", "user.invoices") - .loadRelationCountAndMap("user.subscriptionsCount", "user.subscriptions") - .loadRelationCountAndMap("user.ticketsCount", "user.tickets"); + // const queryBuilder = this.userRepository + // .createQueryBuilder("user") + // .leftJoin("user.roles", "role") + // .where("role.name = :roleName", { roleName: RoleEnum.USER }) + // .leftJoin("user.groups", "groups") + // .addSelect(["groups.id", "groups.name"]) + // .loadRelationCountAndMap("user.invoicesCount", "user.invoices") + // .loadRelationCountAndMap("user.subscriptionsCount", "user.subscriptions") + // .loadRelationCountAndMap("user.ticketsCount", "user.tickets"); - if (queryDto.q) { - queryBuilder - .orWhere("user.firstName ILIKE :search", { search: `%${queryDto.q}%` }) - .orWhere("user.lastName ILIKE :search", { search: `%${queryDto.q}%` }) - .orWhere("user.userName ILIKE :search", { search: `%${queryDto.q}%` }); - } + // if (queryDto.q) { + // queryBuilder + // .orWhere("user.firstName ILIKE :search", { search: `%${queryDto.q}%` }) + // .orWhere("user.lastName ILIKE :search", { search: `%${queryDto.q}%` }) + // .orWhere("user.userName ILIKE :search", { search: `%${queryDto.q}%` }); + // } - const [customers, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount(); + // const [customers, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount(); - return { customers, count }; - } + // return { customers, count }; + // } /************************************************************ */ - async createCustomer(createDto: CreateCustomerDto) { - const { cityId, address, postalCode, economicCode, companyRegisteredName, registrationId, nationalId, number, ...userData } = createDto; + // async createCustomer(createDto: CreateCustomerDto) { + // const { cityId, address, postalCode, economicCode, companyRegisteredName, registrationId, nationalId, number, ...userData } = createDto; - const queryRunner = this.userRepository.manager.connection.createQueryRunner(); - await queryRunner.connect(); - await queryRunner.startTransaction(); + // const queryRunner = this.userRepository.manager.connection.createQueryRunner(); + // await queryRunner.connect(); + // await queryRunner.startTransaction(); - try { - const existUser = await queryRunner.manager.findOneBy(User, { email: createDto.email }); - if (existUser) throw new BadRequestException(UserMessage.EMAIL_EXIST); + // try { + // const existUser = await queryRunner.manager.findOneBy(User, { email: createDto.email }); + // if (existUser) throw new BadRequestException(UserMessage.EMAIL_EXIST); - const role = await queryRunner.manager.findOneBy(Role, { name: RoleEnum.USER }); - if (!role) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND); + // const role = await queryRunner.manager.findOneBy(Role, { name: RoleEnum.USER }); + // if (!role) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND); - const hashedPassword = await this.passwordService.hashPassword(createDto.password); + // const hashedPassword = await this.passwordService.hashPassword(createDto.password); - const legalUserData = economicCode - ? { - economicCode, - companyRegisteredName, - registrationId, - nationalId, - number, - address: { - address, - city: cityId - ? { - id: +cityId, - } - : undefined, - postalCode, - }, - } - : undefined; + // const legalUserData = economicCode + // ? { + // economicCode, + // companyRegisteredName, + // registrationId, + // nationalId, + // number, + // address: { + // address, + // city: cityId + // ? { + // id: +cityId, + // } + // : undefined, + // postalCode, + // }, + // } + // : undefined; - const user = queryRunner.manager.create(User, { - ...userData, - password: hashedPassword, - roles: [role], - legalUser: legalUserData, - }); - await queryRunner.manager.save(user); + // const user = queryRunner.manager.create(User, { + // ...userData, + // password: hashedPassword, + // roles: [role], + // legalUser: legalUserData, + // }); + // await queryRunner.manager.save(user); - await this.userSettingsService.createUserSettings(user.id, queryRunner); + // await this.userSettingsService.createUserSettings(user.id, queryRunner); - await this.walletsService.createUserWallet(user.id, queryRunner); + // await this.walletsService.createUserWallet(user.id, queryRunner); - await queryRunner.commitTransaction(); + // await queryRunner.commitTransaction(); - return { - message: CommonMessage.CREATED, - user, - }; - } catch (error) { - await queryRunner.rollbackTransaction(); - throw error; - } finally { - await queryRunner.release(); - } - } + // return { + // message: CommonMessage.CREATED, + // user, + // }; + // } catch (error) { + // await queryRunner.rollbackTransaction(); + // throw error; + // } finally { + // await queryRunner.release(); + // } + // } /************************************************************ */ @@ -581,74 +565,74 @@ export class UsersService { } /************************************************************ */ - async createRealUserData(createDto: CreateRealUserDto, userId: string) { - const userExist = await this.userRepository.findOneBy({ - id: userId, - }); - if (!userExist) throw new BadRequestException(UserMessage.USER_NOT_FOUND); - console.log(userExist); - const existingRealUser = await this.realUserRepository.findOne({ - where: { user: { id: userExist.id } }, - }); - console.log(existingRealUser); + // async createRealUserData(createDto: CreateRealUserDto, userId: string) { + // const userExist = await this.userRepository.findOneBy({ + // id: userId, + // }); + // if (!userExist) throw new BadRequestException(UserMessage.USER_NOT_FOUND); + // console.log(userExist); + // const existingRealUser = await this.realUserRepository.findOne({ + // where: { user: { id: userExist.id } }, + // }); + // console.log(existingRealUser); - if (existingRealUser) throw new BadRequestException(RealUserMessage.REAL_DATA_EXIST); + // if (existingRealUser) throw new BadRequestException(RealUserMessage.REAL_DATA_EXIST); - const { city } = await this.addressService.getCity(+createDto.cityId); + // const { city } = await this.addressService.getCity(+createDto.cityId); - const realUser = this.realUserRepository.create({ - ...createDto, - user: userExist, - address: { - address: createDto.address, - city, - postalCode: createDto.postalCode, - user: userExist, - }, - }); + // const realUser = this.realUserRepository.create({ + // ...createDto, + // user: userExist, + // address: { + // address: createDto.address, + // city, + // postalCode: createDto.postalCode, + // user: userExist, + // }, + // }); - await this.realUserRepository.save(realUser); + // await this.realUserRepository.save(realUser); - return { - message: CommonMessage.CREATED, - realUser, - }; - } + // return { + // message: CommonMessage.CREATED, + // realUser, + // }; + // } // /************************************************************ */ - async createLegalUserData(createDto: CreateLegalUserDto, userId: string) { - const userExist = await this.userRepository.findOneBy({ - id: userId, - }); - if (!userExist) throw new BadRequestException(UserMessage.USER_NOT_FOUND); + // async createLegalUserData(createDto: CreateLegalUserDto, userId: string) { + // const userExist = await this.userRepository.findOneBy({ + // id: userId, + // }); + // if (!userExist) throw new BadRequestException(UserMessage.USER_NOT_FOUND); - const existingLegalUser = await this.legalUserRepository.findOne({ - where: { user: { id: userExist.id } }, - }); + // const existingLegalUser = await this.legalUserRepository.findOne({ + // where: { user: { id: userExist.id } }, + // }); - if (existingLegalUser) throw new BadRequestException(LegalUserMessage.LEGAL_DATA_EXIST); + // if (existingLegalUser) throw new BadRequestException(LegalUserMessage.LEGAL_DATA_EXIST); - const { city } = await this.addressService.getCity(+createDto.cityId); + // const { city } = await this.addressService.getCity(+createDto.cityId); - const legalUser = this.legalUserRepository.create({ - ...createDto, - user: userExist, - address: { - address: createDto.address, - city, - postalCode: createDto.postalCode, - user: userExist, - }, - }); + // const legalUser = this.legalUserRepository.create({ + // ...createDto, + // user: userExist, + // address: { + // address: createDto.address, + // city, + // postalCode: createDto.postalCode, + // user: userExist, + // }, + // }); - await this.legalUserRepository.save(legalUser); + // await this.legalUserRepository.save(legalUser); - return { - message: CommonMessage.CREATED, - legalUser, - }; - } + // return { + // message: CommonMessage.CREATED, + // legalUser, + // }; + // } /************************************************************ */ diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts index 1c8756f..db5266c 100755 --- a/src/modules/users/users.controller.ts +++ b/src/modules/users/users.controller.ts @@ -5,12 +5,8 @@ import { FastifyReply } from "fastify"; import { ChangeEmailDto } from "./DTO/change-email.dto"; import { CheckValidityDTO } from "./DTO/check-validity.dto"; import { CreateAdminDto } from "./DTO/create-admin.dto"; -import { CreateLegalUserDto } from "./DTO/create-legal-user.dto"; -import { CreateRealUserDto } from "./DTO/create-real-user.dto"; import { CreateRoleDto } from "./DTO/create-role.dto"; -import { CreateCustomerDto } from "./DTO/create-user.dto"; import { SearchAdminQueryDto } from "./DTO/search-admins-query.dto"; -import { SearchCustomersDto } from "./DTO/search-customers.dto"; import { SearchRolesQueryDto } from "./DTO/search-roles.dto"; import { UpdateProfileDto } from "./DTO/update-profile.dto"; import { CreateUserGroupDto } from "./DTO/user-group.dto"; @@ -112,13 +108,13 @@ export class UsersController { return this.usersService.findAllUsers(); } - @ApiOperation({ summary: "get all customers ==> admin route" }) - @AuthGuards() - @PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS) - @Get("customers") - customers(@Query() queryDto: SearchCustomersDto) { - return this.usersService.findAllCustomers(queryDto); - } + // @ApiOperation({ summary: "get all customers ==> admin route" }) + // @AuthGuards() + // @PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS) + // @Get("customers") + // customers(@Query() queryDto: SearchCustomersDto) { + // return this.usersService.findAllCustomers(queryDto); + // } @ApiOperation({ summary: "get all customers ==> admin route" }) @AuthGuards() @@ -169,27 +165,27 @@ export class UsersController { } // - @ApiOperation({ summary: "Create real user data" }) - @AuthGuards() - @HttpCode(HttpStatus.CREATED) - @Post("real-user") - createRealUser(@Body() createDto: CreateRealUserDto, @UserDec("id") userId: string) { - return this.usersService.createRealUserData(createDto, userId); - } + // @ApiOperation({ summary: "Create real user data" }) + // @AuthGuards() + // @HttpCode(HttpStatus.CREATED) + // @Post("real-user") + // createRealUser(@Body() createDto: CreateRealUserDto, @UserDec("id") userId: string) { + // return this.usersService.createRealUserData(createDto, userId); + // } - @ApiOperation({ summary: "Create legal user data" }) - @AuthGuards() - @HttpCode(HttpStatus.CREATED) - @Post("legal-user") - createLegalUser(@Body() createDto: CreateLegalUserDto, @UserDec("id") userId: string) { - return this.usersService.createLegalUserData(createDto, userId); - } + // @ApiOperation({ summary: "Create legal user data" }) + // @AuthGuards() + // @HttpCode(HttpStatus.CREATED) + // @Post("legal-user") + // createLegalUser(@Body() createDto: CreateLegalUserDto, @UserDec("id") userId: string) { + // return this.usersService.createLegalUserData(createDto, userId); + // } - @ApiOperation({ summary: "Create customer" }) - @AuthGuards() - @HttpCode(HttpStatus.CREATED) - @Post("customer") - createCustomer(@Body() createDto: CreateCustomerDto) { - return this.usersService.createCustomer(createDto); - } + // @ApiOperation({ summary: "Create customer" }) + // @AuthGuards() + // @HttpCode(HttpStatus.CREATED) + // @Post("customer") + // createCustomer(@Body() createDto: CreateCustomerDto) { + // return this.usersService.createCustomer(createDto); + // } }