chore: add create customer and update customer for admin
This commit is contained in:
@@ -22,7 +22,6 @@ import { ContactUsModule } from "./modules/contact-us/contact-us.module";
|
|||||||
import { CriticismModule } from "./modules/criticisms/criticisms.module";
|
import { CriticismModule } from "./modules/criticisms/criticisms.module";
|
||||||
import { DanakServicesModule } from "./modules/danak-services/danak-services.module";
|
import { DanakServicesModule } from "./modules/danak-services/danak-services.module";
|
||||||
import { DashboardModule } from "./modules/dashboards/dashboard.module";
|
import { DashboardModule } from "./modules/dashboards/dashboard.module";
|
||||||
// import { DiscountModule } from "./modules/discounts/discounts.module";
|
|
||||||
import { InvoicesModule } from "./modules/invoices/invoices.module";
|
import { InvoicesModule } from "./modules/invoices/invoices.module";
|
||||||
import { LearningModule } from "./modules/learnings/learning.module";
|
import { LearningModule } from "./modules/learnings/learning.module";
|
||||||
import { NotificationModule } from "./modules/notifications/notifications.module";
|
import { NotificationModule } from "./modules/notifications/notifications.module";
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export const enum UserMessage {
|
|||||||
PHONE_SHOULD_BE_11_DIGIT = "شماره تلفن باید ۱۱ رقم باشد",
|
PHONE_SHOULD_BE_11_DIGIT = "شماره تلفن باید ۱۱ رقم باشد",
|
||||||
FINANCIAL_TYPE_IS_LEGAL = "نوع کاربر حقوقی میباشد",
|
FINANCIAL_TYPE_IS_LEGAL = "نوع کاربر حقوقی میباشد",
|
||||||
FINANCIAL_TYPE_IS_REAL = "نوع کاربر حقیقی میباشد",
|
FINANCIAL_TYPE_IS_REAL = "نوع کاربر حقیقی میباشد",
|
||||||
|
LEGAL_DATA_NOT_FOUND = "اطلاعات حقوقی یافت نشد",
|
||||||
|
REAL_DATA_NOT_FOUND = "اطلاعات حقیقی یافت نشد",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum CommonMessage {
|
export const enum CommonMessage {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export class Announcement extends BaseEntity {
|
|||||||
@Column({ type: "text" })
|
@Column({ type: "text" })
|
||||||
content: string;
|
content: string;
|
||||||
|
|
||||||
@Column({ type: "timestamp", nullable: true, default: null })
|
@Column({ type: "timestamptz", nullable: true, default: null })
|
||||||
publishAt: Date | null;
|
publishAt: Date | null;
|
||||||
|
|
||||||
@ManyToOne(() => DanakService, (service) => service.announcements, { onDelete: "CASCADE" })
|
@ManyToOne(() => DanakService, (service) => service.announcements, { onDelete: "CASCADE" })
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ export class CompleteRegistrationDto {
|
|||||||
@ApiProperty({ description: "Last name", example: "jamshidi" })
|
@ApiProperty({ description: "Last name", example: "jamshidi" })
|
||||||
lastName: string;
|
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.BIRTH_DATE_NOT_EMPTY })
|
@IsNotEmpty({ message: AuthMessage.BIRTH_DATE_NOT_EMPTY })
|
||||||
@IsString({ message: AuthMessage.BIRTH_DATE_NOT_EMPTY })
|
@IsString({ message: AuthMessage.BIRTH_DATE_NOT_EMPTY })
|
||||||
@ApiProperty({ description: "Birth date", example: "1403/01/01" })
|
@ApiProperty({ description: "Birth date", example: "1403/01/01" })
|
||||||
|
|||||||
@@ -56,6 +56,14 @@ export class DanakServicesController {
|
|||||||
return this.danakServicesService.getCategoriesUserSide();
|
return this.danakServicesService.getCategoriesUserSide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AuthGuards()
|
||||||
|
@PermissionsDec(PermissionEnum.SERVICES)
|
||||||
|
@ApiOperation({ summary: "Get category by id => admin route" })
|
||||||
|
@Get("categories/:id")
|
||||||
|
getCategoryById(@Param() paramDto: ParamDto) {
|
||||||
|
return this.danakServicesService.getCategoryById(paramDto.id);
|
||||||
|
}
|
||||||
|
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@PermissionsDec(PermissionEnum.SERVICES)
|
@PermissionsDec(PermissionEnum.SERVICES)
|
||||||
@ApiOperation({ summary: "update category by id => admin route" })
|
@ApiOperation({ summary: "update category by id => admin route" })
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export class DanakService extends BaseEntity {
|
|||||||
@Column({ type: "varchar", length: 255, nullable: false })
|
@Column({ type: "varchar", length: 255, nullable: false })
|
||||||
author: string;
|
author: string;
|
||||||
|
|
||||||
@Column({ type: "timestamp", nullable: false, default: () => "CURRENT_TIMESTAMP" })
|
@Column({ type: "timestamptz", nullable: false, default: () => "CURRENT_TIMESTAMP" })
|
||||||
createDate: Date;
|
createDate: Date;
|
||||||
|
|
||||||
@Column({ type: "int", nullable: false, default: 0 })
|
@Column({ type: "int", nullable: false, default: 0 })
|
||||||
|
|||||||
@@ -45,6 +45,16 @@ export class DanakServicesService {
|
|||||||
}
|
}
|
||||||
/******************************************** */
|
/******************************************** */
|
||||||
|
|
||||||
|
async getCategoryById(categoryId: string) {
|
||||||
|
const category = await this.danakServicesCategoryRepository.findOneById(categoryId);
|
||||||
|
if (!category) throw new BadRequestException(CategoryMessage.CATEGORY_NOT_EXIST);
|
||||||
|
return {
|
||||||
|
category,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************** */
|
||||||
|
|
||||||
async updateCategory(categoryId: string, updateDto: UpdateCategoryDto) {
|
async updateCategory(categoryId: string, updateDto: UpdateCategoryDto) {
|
||||||
const category = await this.danakServicesCategoryRepository.findOneById(categoryId);
|
const category = await this.danakServicesCategoryRepository.findOneById(categoryId);
|
||||||
if (!category) throw new BadRequestException(CategoryMessage.CATEGORY_NOT_EXIST);
|
if (!category) throw new BadRequestException(CategoryMessage.CATEGORY_NOT_EXIST);
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ import { InvoicesService } from "../../invoices/providers/invoices.service";
|
|||||||
import { NotificationsService } from "../../notifications/providers/notifications.service";
|
import { NotificationsService } from "../../notifications/providers/notifications.service";
|
||||||
import { SubscriptionsService } from "../../subscriptions/providers/subscriptions.service";
|
import { SubscriptionsService } from "../../subscriptions/providers/subscriptions.service";
|
||||||
import { TicketsService } from "../../tickets/providers/tickets.service";
|
import { TicketsService } from "../../tickets/providers/tickets.service";
|
||||||
import { UsersService } from "../../users/providers/users.service";
|
import { CustomersService } from "../../users/providers/customers.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DashboardService {
|
export class DashboardService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly danakServicesService: DanakServicesService,
|
private readonly danakServicesService: DanakServicesService,
|
||||||
private readonly usersService: UsersService,
|
|
||||||
private readonly invoicesService: InvoicesService,
|
private readonly invoicesService: InvoicesService,
|
||||||
private readonly ticketsService: TicketsService,
|
private readonly ticketsService: TicketsService,
|
||||||
private readonly adsService: AdsService,
|
private readonly adsService: AdsService,
|
||||||
private readonly subscriptionsService: SubscriptionsService,
|
private readonly subscriptionsService: SubscriptionsService,
|
||||||
private readonly notificationsService: NotificationsService,
|
private readonly notificationsService: NotificationsService,
|
||||||
|
private readonly customersService: CustomersService,
|
||||||
// private readonly announcementService: AnnouncementService,
|
// private readonly announcementService: AnnouncementService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ export class DashboardService {
|
|||||||
//************************************ */
|
//************************************ */
|
||||||
|
|
||||||
private async getCustomersCount() {
|
private async getCustomersCount() {
|
||||||
const customersCount = await this.usersService.getCustomersCount();
|
const customersCount = await this.customersService.getCustomersCount();
|
||||||
return customersCount;
|
return customersCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ export class Invoice extends BaseEntity {
|
|||||||
@Column({ type: "enum", enum: InvoiceStatus, default: InvoiceStatus.PENDING })
|
@Column({ type: "enum", enum: InvoiceStatus, default: InvoiceStatus.PENDING })
|
||||||
status: InvoiceStatus;
|
status: InvoiceStatus;
|
||||||
|
|
||||||
@Column({ type: "timestamp", nullable: false })
|
@Column({ type: "timestamptz", nullable: false })
|
||||||
dueDate: Date;
|
dueDate: Date;
|
||||||
|
|
||||||
@Column({ type: "timestamp", nullable: true })
|
@Column({ type: "timestamptz", nullable: true })
|
||||||
paidAt: Date | null;
|
paidAt?: Date;
|
||||||
|
|
||||||
@Column({ type: "int", default: 0 })
|
@Column({ type: "decimal", precision: 16, scale: 2, nullable: false, transformer: new DecimalTransformer() })
|
||||||
tax: number;
|
tax: Decimal;
|
||||||
|
|
||||||
//---------------------------------------------
|
//---------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -187,7 +187,6 @@ export class InvoicesService {
|
|||||||
totalPrice: totalPrice,
|
totalPrice: totalPrice,
|
||||||
tax: taxAmount.toNumber(),
|
tax: taxAmount.toNumber(),
|
||||||
status: InvoiceStatus.WAIT_PAYMENT,
|
status: InvoiceStatus.WAIT_PAYMENT,
|
||||||
paidAt: new Date(),
|
|
||||||
dueDate,
|
dueDate,
|
||||||
items: [invoiceItem],
|
items: [invoiceItem],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ export class UserSubscription extends BaseEntity {
|
|||||||
@ManyToOne(() => SubscriptionPlan, (plan) => plan.userSubscriptions, { nullable: false, onDelete: "CASCADE" })
|
@ManyToOne(() => SubscriptionPlan, (plan) => plan.userSubscriptions, { nullable: false, onDelete: "CASCADE" })
|
||||||
plan: SubscriptionPlan;
|
plan: SubscriptionPlan;
|
||||||
|
|
||||||
@Column({ type: "timestamp", nullable: false })
|
@Column({ type: "timestamptz", nullable: false })
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
|
|
||||||
@Column({ type: "timestamp", nullable: false })
|
@Column({ type: "timestamptz", nullable: false })
|
||||||
endDate: Date;
|
endDate: Date;
|
||||||
|
|
||||||
@Column({ type: "varchar", length: 250, nullable: false })
|
@Column({ type: "varchar", length: 250, nullable: false })
|
||||||
|
|||||||
@@ -142,8 +142,8 @@ export class SubscriptionsService {
|
|||||||
.createQueryBuilder("subscription")
|
.createQueryBuilder("subscription")
|
||||||
.leftJoin("subscription.service", "service")
|
.leftJoin("subscription.service", "service")
|
||||||
.addSelect(["service.id"])
|
.addSelect(["service.id"])
|
||||||
.leftJoin("subscription.discounts", "discount")
|
// .leftJoin("subscription.discounts", "discount")
|
||||||
.addSelect(["discount.calculationType", "discount.amount", "discount.startDate", "discount.endDate", "discount.isActive"])
|
// .addSelect(["discount.calculationType", "discount.amount", "discount.startDate", "discount.endDate", "discount.isActive"])
|
||||||
.where("service.id = :serviceId", { serviceId });
|
.where("service.id = :serviceId", { serviceId });
|
||||||
|
|
||||||
if (queryDto.q) {
|
if (queryDto.q) {
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { IsEmail, IsMobilePhone, IsNotEmpty, IsNumberString, IsString, Length, MinLength } from "class-validator";
|
||||||
|
|
||||||
|
import { CreateLegalUserDto } from "./create-legal-user.dto";
|
||||||
|
import { IsNationalCode } from "../../../common/decorators/is-national-code.decorator";
|
||||||
|
import { AuthMessage } from "../../../common/enums/message.enum";
|
||||||
|
|
||||||
|
export class CreateCustomerDto extends CreateLegalUserDto {
|
||||||
|
@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.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.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.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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { PartialType } from "@nestjs/swagger";
|
||||||
|
|
||||||
|
import { CreateCustomerDto } from "./create-customer.dto";
|
||||||
|
|
||||||
|
export class UpdateCustomerDto extends PartialType(CreateCustomerDto) {}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||||
|
import slugify from "slugify";
|
||||||
|
import { In } from "typeorm";
|
||||||
|
|
||||||
|
import { AdminMessage, AdsMessage, UserMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||||
|
import { PasswordService } from "../../utils/providers/password.service";
|
||||||
|
import { CreateAdminDto } from "../DTO/create-admin.dto";
|
||||||
|
import { CreateRoleDto } from "../DTO/create-role.dto";
|
||||||
|
import { SearchAdminQueryDto } from "../DTO/search-admins-query.dto";
|
||||||
|
import { SearchRolesQueryDto } from "../DTO/search-roles.dto";
|
||||||
|
import { PermissionsRepository } from "../repositories/permissions.repository";
|
||||||
|
import { RoleRepository } from "../repositories/roles.repository";
|
||||||
|
import { UserRepository } from "../repositories/users.repository";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AdminsService {
|
||||||
|
constructor(
|
||||||
|
private readonly userRepository: UserRepository,
|
||||||
|
private readonly rolesRepository: RoleRepository,
|
||||||
|
private readonly permissionsRepository: PermissionsRepository,
|
||||||
|
private readonly passwordService: PasswordService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async createAdmin(createDto: CreateAdminDto) {
|
||||||
|
const existEmail = await this.userRepository.findOneBy({ email: createDto.email });
|
||||||
|
if (existEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||||
|
|
||||||
|
const existPhone = await this.userRepository.findOneBy({ phone: createDto.phone });
|
||||||
|
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
|
||||||
|
const role = await this.rolesRepository.findOne({ where: { id: createDto.roleId }, relations: { permissions: true } });
|
||||||
|
if (!role) throw new BadRequestException(AdsMessage.ROLE_NOT_FOUND);
|
||||||
|
|
||||||
|
await this.rolesRepository.save(role);
|
||||||
|
|
||||||
|
if (createDto.password !== createDto.repeatPassword) throw new BadRequestException(AdminMessage.PASSWORD_NOT_MATCH);
|
||||||
|
|
||||||
|
const hashedPassword = await this.passwordService.hashPassword(createDto.password);
|
||||||
|
|
||||||
|
const userName = slugify(`${createDto.firstName} ${Date.now().toString().slice(-5)}`, { lower: true, trim: true });
|
||||||
|
|
||||||
|
const adminUser = this.userRepository.create({ ...createDto, roles: [role], password: hashedPassword, userName });
|
||||||
|
await this.userRepository.save(adminUser);
|
||||||
|
return {
|
||||||
|
message: AdminMessage.ADMIN_CREATED,
|
||||||
|
adminUser,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async createRole(createDto: CreateRoleDto) {
|
||||||
|
const existRole = await this.rolesRepository.findOne({ where: { name: createDto.name } });
|
||||||
|
if (existRole) throw new BadRequestException(AdminMessage.ROLE_EXIST);
|
||||||
|
|
||||||
|
const permissions = await this.permissionsRepository.findBy({ id: In(createDto.permissions) });
|
||||||
|
if (permissions.length !== createDto.permissions.length) throw new BadRequestException(AdminMessage.PERMISSIONS_NOT_FOUND);
|
||||||
|
|
||||||
|
const role = this.rolesRepository.create({ ...createDto, permissions, isAdmin: true });
|
||||||
|
await this.rolesRepository.save(role);
|
||||||
|
return {
|
||||||
|
message: AdminMessage.ROLE_CREATED,
|
||||||
|
role,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async getAdmins(queryDto: SearchAdminQueryDto) {
|
||||||
|
const [users, count] = await this.userRepository.getAdmins(queryDto);
|
||||||
|
|
||||||
|
return {
|
||||||
|
users,
|
||||||
|
count,
|
||||||
|
paginate: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async getPermissions() {
|
||||||
|
const permissions = await this.permissionsRepository.find({ select: { id: true, name: true } });
|
||||||
|
return {
|
||||||
|
permissions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async getRoles(queryDto: SearchRolesQueryDto) {
|
||||||
|
const { limit, skip } = PaginationUtils(queryDto);
|
||||||
|
const queryBuilder = this.rolesRepository.createQueryBuilder("role");
|
||||||
|
|
||||||
|
queryBuilder
|
||||||
|
.where("role.isAdmin = :isAdmin", { isAdmin: true })
|
||||||
|
// .leftJoinAndSelect("role.permissions", "permissions")
|
||||||
|
.loadRelationCountAndMap("role.userCount", "role.users");
|
||||||
|
|
||||||
|
if (queryDto.q) {
|
||||||
|
queryBuilder.andWhere("role.name ILIKE :q", { q: `%${queryDto.q}%` });
|
||||||
|
}
|
||||||
|
|
||||||
|
queryBuilder.take(limit).skip(skip).orderBy("role.createdAt", "DESC");
|
||||||
|
|
||||||
|
const [roles, count] = await queryBuilder.getManyAndCount();
|
||||||
|
|
||||||
|
return {
|
||||||
|
roles,
|
||||||
|
count,
|
||||||
|
paginate: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||||
|
import { DataSource, Not } from "typeorm";
|
||||||
|
|
||||||
|
import { CommonMessage, UserMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { AddressService } from "../../address/providers/address.service";
|
||||||
|
import { UserSettingsService } from "../../settings/providers/user-settings.service";
|
||||||
|
import { PasswordService } from "../../utils/providers/password.service";
|
||||||
|
import { WalletsService } from "../../wallets/providers/wallets.service";
|
||||||
|
import { CreateCustomerDto } from "../DTO/create-customer.dto";
|
||||||
|
import { CreateLegalUserDto } from "../DTO/create-legal-user.dto";
|
||||||
|
import { CreateRealUserDto } from "../DTO/create-real-user.dto";
|
||||||
|
import { SearchCustomersDto } from "../DTO/search-customers.dto";
|
||||||
|
import { UpdateCustomerDto } from "../DTO/update-customer.dto";
|
||||||
|
import { FinancialType } from "../enums/financial-type.enum";
|
||||||
|
import { RoleEnum } from "../enums/role.enum";
|
||||||
|
import { LegalUserRepository } from "../repositories/legal-user.repository";
|
||||||
|
import { RealUserRepository } from "../repositories/real-user.repository";
|
||||||
|
import { RoleRepository } from "../repositories/roles.repository";
|
||||||
|
import { UserRepository } from "../repositories/users.repository";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CustomersService {
|
||||||
|
private readonly logger = new Logger(CustomersService.name);
|
||||||
|
constructor(
|
||||||
|
private readonly addressService: AddressService,
|
||||||
|
private readonly dataSource: DataSource,
|
||||||
|
private readonly userRepository: UserRepository,
|
||||||
|
private readonly legalUserRepository: LegalUserRepository,
|
||||||
|
private readonly realUserRepository: RealUserRepository,
|
||||||
|
private readonly passwordService: PasswordService,
|
||||||
|
private readonly userSettingsService: UserSettingsService,
|
||||||
|
private readonly rolesRepository: RoleRepository,
|
||||||
|
private readonly walletsService: WalletsService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async createCustomer(createDto: CreateCustomerDto) {
|
||||||
|
const queryRunner = this.dataSource.createQueryRunner();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
|
const [existingEmail, existingNationalCode, existingPhone, userRole] = await Promise.all([
|
||||||
|
queryRunner.manager.findOne(this.userRepository.target, { where: { email: createDto.email } }),
|
||||||
|
queryRunner.manager.findOne(this.userRepository.target, { where: { nationalCode: createDto.nationalCode } }),
|
||||||
|
queryRunner.manager.findOne(this.userRepository.target, { where: { phone: createDto.phone } }),
|
||||||
|
queryRunner.manager.findOne(this.rolesRepository.target, { where: { name: RoleEnum.USER } }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (existingEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||||
|
if (existingNationalCode) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
||||||
|
if (existingPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
if (!userRole) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND);
|
||||||
|
|
||||||
|
const user = queryRunner.manager.create(this.userRepository.target, {
|
||||||
|
...createDto,
|
||||||
|
password: await this.passwordService.hashPassword(createDto.password),
|
||||||
|
roles: [userRole],
|
||||||
|
});
|
||||||
|
await queryRunner.manager.save(user);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
this.userSettingsService.createUserSettings(user.id, queryRunner),
|
||||||
|
this.walletsService.createUserWallet(user.id, queryRunner),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await this.createLegalUserData(createDto, user.id, queryRunner);
|
||||||
|
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
return { message: CommonMessage.CREATED, user };
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
this.logger.error("Error in create customer", error);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//************************************************ */
|
||||||
|
async updateCustomer(customerId: string, updateDto: UpdateCustomerDto) {
|
||||||
|
const queryRunner = this.dataSource.createQueryRunner();
|
||||||
|
try {
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
|
||||||
|
const user = await queryRunner.manager.findOne(this.userRepository.target, { where: { id: customerId } });
|
||||||
|
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||||
|
|
||||||
|
if (updateDto.email) {
|
||||||
|
const existingEmail = await queryRunner.manager.findOne(this.userRepository.target, {
|
||||||
|
where: { email: updateDto.email, id: Not(user.id) },
|
||||||
|
});
|
||||||
|
if (existingEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDto.nationalCode) {
|
||||||
|
const existingNationalCode = await queryRunner.manager.findOne(this.userRepository.target, {
|
||||||
|
where: { nationalCode: updateDto.nationalCode, id: Not(user.id) },
|
||||||
|
});
|
||||||
|
if (existingNationalCode) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDto.phone) {
|
||||||
|
const existingPhone = await queryRunner.manager.findOne(this.userRepository.target, {
|
||||||
|
where: { phone: updateDto.phone, id: Not(user.id) },
|
||||||
|
});
|
||||||
|
if (existingPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.manager.update(this.userRepository.target, { id: customerId }, updateDto);
|
||||||
|
|
||||||
|
const legalUser = await queryRunner.manager.findOne(this.legalUserRepository.target, { where: { user: { id: customerId } } });
|
||||||
|
|
||||||
|
if (!legalUser) throw new BadRequestException(UserMessage.LEGAL_DATA_NOT_FOUND);
|
||||||
|
|
||||||
|
if (updateDto.economicCode) {
|
||||||
|
const existingEconomicCode = await queryRunner.manager.findOne(this.legalUserRepository.target, {
|
||||||
|
where: { economicCode: updateDto.economicCode, id: Not(legalUser.id) },
|
||||||
|
});
|
||||||
|
if (existingEconomicCode) throw new BadRequestException(UserMessage.ECONOMIC_CODE_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDto.registrationCode) {
|
||||||
|
const existingRegistrationCode = await queryRunner.manager.findOne(this.legalUserRepository.target, {
|
||||||
|
where: { registrationCode: updateDto.registrationCode, id: Not(legalUser.id) },
|
||||||
|
});
|
||||||
|
if (existingRegistrationCode) throw new BadRequestException(UserMessage.REGISTRATION_CODE_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDto.nationalIdentity) {
|
||||||
|
const existingNationalIdentity = await queryRunner.manager.findOne(this.legalUserRepository.target, {
|
||||||
|
where: { nationalIdentity: updateDto.nationalIdentity, id: Not(legalUser.id) },
|
||||||
|
});
|
||||||
|
if (existingNationalIdentity) throw new BadRequestException(UserMessage.NATIONAL_IDENTITY_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDto.cityId) {
|
||||||
|
const { city } = await this.addressService.getCity(+updateDto.cityId);
|
||||||
|
await queryRunner.manager.update(this.legalUserRepository.target, { id: legalUser.id }, { address: { city } });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { address, ...legalUserUpdateData } = updateDto;
|
||||||
|
await queryRunner.manager.update(this.legalUserRepository.target, { id: legalUser.id }, legalUserUpdateData);
|
||||||
|
|
||||||
|
if (address) {
|
||||||
|
await queryRunner.manager.update(this.legalUserRepository.target, { id: legalUser.id }, { address: { fullAddress: address } });
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.commitTransaction();
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: CommonMessage.UPDATE_SUCCESS,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
await queryRunner.rollbackTransaction();
|
||||||
|
this.logger.error("Error in update customer", error);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async getCustomersCount() {
|
||||||
|
const count = await this.userRepository.count({ where: { roles: { name: RoleEnum.USER } } });
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************ */
|
||||||
|
async createRealUserData(createDto: CreateRealUserDto, userId: string, queryRunner = this.dataSource.createQueryRunner()) {
|
||||||
|
let transactionStarted = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!queryRunner.isTransactionActive) {
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
transactionStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await queryRunner.manager.findOne(this.userRepository.target, { where: { id: userId } });
|
||||||
|
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||||
|
|
||||||
|
if (user.financialType && user.financialType === FinancialType.LEGAL)
|
||||||
|
throw new BadRequestException(UserMessage.FINANCIAL_TYPE_IS_LEGAL);
|
||||||
|
|
||||||
|
const existingRealUser = await queryRunner.manager.findOne(this.realUserRepository.target, { where: { user: { id: userId } } });
|
||||||
|
if (existingRealUser) throw new BadRequestException(UserMessage.REAL_DATA_EXIST);
|
||||||
|
|
||||||
|
const duplicateChecks = await Promise.all([
|
||||||
|
queryRunner.manager.findOne(this.realUserRepository.target, { where: { nationalCode: createDto.nationalCode } }),
|
||||||
|
queryRunner.manager.findOne(this.realUserRepository.target, { where: { phone: createDto.phone } }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (duplicateChecks[0]) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
||||||
|
if (duplicateChecks[1]) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
|
||||||
|
const { city } = await this.addressService.getCity(+createDto.cityId);
|
||||||
|
|
||||||
|
const realUser = queryRunner.manager.create(this.realUserRepository.target, {
|
||||||
|
...createDto,
|
||||||
|
user,
|
||||||
|
address: {
|
||||||
|
fullAddress: createDto.address,
|
||||||
|
city,
|
||||||
|
postalCode: createDto.postalCode,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryRunner.manager.save(realUser);
|
||||||
|
|
||||||
|
user.financialType = FinancialType.REAL;
|
||||||
|
await queryRunner.manager.save(user);
|
||||||
|
|
||||||
|
if (transactionStarted) await queryRunner.commitTransaction();
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: CommonMessage.CREATED,
|
||||||
|
realUser,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
if (transactionStarted) await queryRunner.rollbackTransaction();
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
if (transactionStarted) await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// /************************************************************ */
|
||||||
|
|
||||||
|
async createLegalUserData(createDto: CreateLegalUserDto, userId: string, queryRunner = this.dataSource.createQueryRunner()) {
|
||||||
|
let transactionStarted = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!queryRunner.isTransactionActive) {
|
||||||
|
await queryRunner.connect();
|
||||||
|
await queryRunner.startTransaction();
|
||||||
|
transactionStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await queryRunner.manager.findOne(this.userRepository.target, { where: { id: userId } });
|
||||||
|
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||||
|
|
||||||
|
if (user.financialType && user.financialType === FinancialType.REAL)
|
||||||
|
throw new BadRequestException(UserMessage.FINANCIAL_TYPE_IS_REAL);
|
||||||
|
|
||||||
|
const existingLegalUser = await queryRunner.manager.findOne(this.legalUserRepository.target, { where: { user: { id: user.id } } });
|
||||||
|
|
||||||
|
if (existingLegalUser) throw new BadRequestException(UserMessage.LEGAL_DATA_EXIST);
|
||||||
|
|
||||||
|
const duplicateChecks = await Promise.all([
|
||||||
|
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { economicCode: createDto.economicCode } }),
|
||||||
|
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { phone: createDto.phone } }),
|
||||||
|
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { registrationCode: createDto.registrationCode } }),
|
||||||
|
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { nationalIdentity: createDto.nationalIdentity } }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (duplicateChecks[0]) throw new BadRequestException(UserMessage.ECONOMIC_CODE_EXIST);
|
||||||
|
if (duplicateChecks[1]) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
if (duplicateChecks[2]) throw new BadRequestException(UserMessage.REGISTRATION_CODE_EXIST);
|
||||||
|
if (duplicateChecks[3]) throw new BadRequestException(UserMessage.NATIONAL_IDENTITY_EXIST);
|
||||||
|
|
||||||
|
const { city } = await this.addressService.getCity(+createDto.cityId);
|
||||||
|
|
||||||
|
const legalUser = queryRunner.manager.create(this.legalUserRepository.target, {
|
||||||
|
...createDto,
|
||||||
|
user,
|
||||||
|
address: {
|
||||||
|
fullAddress: createDto.address,
|
||||||
|
city,
|
||||||
|
postalCode: createDto.postalCode,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryRunner.manager.save(legalUser);
|
||||||
|
|
||||||
|
user.financialType = FinancialType.LEGAL;
|
||||||
|
await queryRunner.manager.save(user);
|
||||||
|
|
||||||
|
if (transactionStarted) await queryRunner.commitTransaction();
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: CommonMessage.CREATED,
|
||||||
|
legalUser,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
if (transactionStarted) await queryRunner.rollbackTransaction();
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
if (transactionStarted) await queryRunner.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async getCustomers(queryDto: SearchCustomersDto) {
|
||||||
|
const [customers, count] = await this.userRepository.getCustomer(queryDto);
|
||||||
|
|
||||||
|
return { customers, count };
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async getCustomerById(userId: string) {
|
||||||
|
const customer = await this.userRepository.findOne({
|
||||||
|
where: { id: userId, roles: { name: RoleEnum.USER } },
|
||||||
|
relations: { legalUser: true, realUser: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
return { customer };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import { FastifyReply } from "fastify";
|
|||||||
import slugify from "slugify";
|
import slugify from "slugify";
|
||||||
import { In, Not, QueryRunner } from "typeorm";
|
import { In, Not, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
import { AdminMessage, AdsMessage, AuthMessage, CommonMessage, UserMessage } from "../../../common/enums/message.enum";
|
import { AuthMessage, CommonMessage, UserMessage } from "../../../common/enums/message.enum";
|
||||||
import { AddressService } from "../../address/providers/address.service";
|
import { AddressService } from "../../address/providers/address.service";
|
||||||
import { CompleteRegistrationDto } from "../../auth/DTO/complete-register.dto";
|
import { CompleteRegistrationDto } from "../../auth/DTO/complete-register.dto";
|
||||||
import { RequestOtpDto } from "../../auth/DTO/request-otp.dto";
|
import { RequestOtpDto } from "../../auth/DTO/request-otp.dto";
|
||||||
@@ -15,31 +15,19 @@ import { UserSettingsService } from "../../settings/providers/user-settings.serv
|
|||||||
import { CacheService } from "../../utils/providers/cache.service";
|
import { CacheService } from "../../utils/providers/cache.service";
|
||||||
import { EmailService } from "../../utils/providers/email.service";
|
import { EmailService } from "../../utils/providers/email.service";
|
||||||
import { OTPService } from "../../utils/providers/otp.service";
|
import { OTPService } from "../../utils/providers/otp.service";
|
||||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
|
||||||
import { PasswordService } from "../../utils/providers/password.service";
|
|
||||||
import { SmsService } from "../../utils/providers/sms.service";
|
import { SmsService } from "../../utils/providers/sms.service";
|
||||||
import { WalletsService } from "../../wallets/providers/wallets.service";
|
import { WalletsService } from "../../wallets/providers/wallets.service";
|
||||||
import { ChangeEmailDto } from "../DTO/change-email.dto";
|
import { ChangeEmailDto } from "../DTO/change-email.dto";
|
||||||
import { CheckValidityDTO } from "../DTO/check-validity.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 { 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 { UpdateProfileDto } from "../DTO/update-profile.dto";
|
||||||
import { CreateUserGroupDto } from "../DTO/user-group.dto";
|
import { CreateUserGroupDto } from "../DTO/user-group.dto";
|
||||||
import { EmailVerifyQueryDto } from "../DTO/verify-email-query.dto";
|
import { EmailVerifyQueryDto } from "../DTO/verify-email-query.dto";
|
||||||
import { Role } from "../entities/role.entity";
|
import { Role } from "../entities/role.entity";
|
||||||
import { User } from "../entities/user.entity";
|
import { User } from "../entities/user.entity";
|
||||||
import { FinancialType } from "../enums/financial-type.enum";
|
|
||||||
import { RoleEnum } from "../enums/role.enum";
|
import { RoleEnum } from "../enums/role.enum";
|
||||||
import { ValidityType } from "../enums/validity-type.enum";
|
import { ValidityType } from "../enums/validity-type.enum";
|
||||||
import { LegalUserRepository } from "../repositories/legal-user.repository";
|
import { LegalUserRepository } from "../repositories/legal-user.repository";
|
||||||
import { PermissionsRepository } from "../repositories/permissions.repository";
|
|
||||||
import { RealUserRepository } from "../repositories/real-user.repository";
|
import { RealUserRepository } from "../repositories/real-user.repository";
|
||||||
import { RoleRepository } from "../repositories/roles.repository";
|
|
||||||
import { UserGroupRepository } from "../repositories/user-group.repository";
|
import { UserGroupRepository } from "../repositories/user-group.repository";
|
||||||
import { UserRepository } from "../repositories/users.repository";
|
import { UserRepository } from "../repositories/users.repository";
|
||||||
|
|
||||||
@@ -51,9 +39,6 @@ export class UsersService {
|
|||||||
private readonly userGroupRepository: UserGroupRepository,
|
private readonly userGroupRepository: UserGroupRepository,
|
||||||
private readonly userSettingsService: UserSettingsService,
|
private readonly userSettingsService: UserSettingsService,
|
||||||
private readonly walletsService: WalletsService,
|
private readonly walletsService: WalletsService,
|
||||||
private readonly rolesRepository: RoleRepository,
|
|
||||||
private readonly permissionsRepository: PermissionsRepository,
|
|
||||||
private readonly passwordService: PasswordService,
|
|
||||||
private readonly addressService: AddressService,
|
private readonly addressService: AddressService,
|
||||||
private readonly realUserRepository: RealUserRepository,
|
private readonly realUserRepository: RealUserRepository,
|
||||||
private readonly legalUserRepository: LegalUserRepository,
|
private readonly legalUserRepository: LegalUserRepository,
|
||||||
@@ -81,6 +66,19 @@ export class UsersService {
|
|||||||
|
|
||||||
/************************************************************ */
|
/************************************************************ */
|
||||||
|
|
||||||
|
async findOneWithEmail(email: string): Promise<User | null> {
|
||||||
|
const user = await this.userRepository.findOneWithEmail(email);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
|
async findOneWithPhone(phone: string): Promise<User | null> {
|
||||||
|
const user = await this.userRepository.findOneWithPhone(phone);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************ */
|
||||||
|
|
||||||
async getMe(userId: string) {
|
async getMe(userId: string) {
|
||||||
const user = await this.userRepository.findOne({ where: { id: userId }, relations: { roles: true } });
|
const user = await this.userRepository.findOne({ where: { id: userId }, relations: { roles: true } });
|
||||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||||
@@ -235,23 +233,13 @@ export class UsersService {
|
|||||||
|
|
||||||
/************************************************************ */
|
/************************************************************ */
|
||||||
|
|
||||||
async findOneWithEmail(email: string): Promise<User | null> {
|
|
||||||
const user = await this.userRepository.findOneWithEmail(email);
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async findOneWithPhone(phone: string): Promise<User | null> {
|
|
||||||
const user = await this.userRepository.findOneWithPhone(phone);
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async createUser(registerDto: CompleteRegistrationDto, hashedPassword: string, queryRunner: QueryRunner): Promise<User> {
|
async createUser(registerDto: CompleteRegistrationDto, hashedPassword: string, queryRunner: QueryRunner): Promise<User> {
|
||||||
const role = await queryRunner.manager.findOneBy(Role, { name: RoleEnum.USER });
|
const role = await queryRunner.manager.findOneBy(Role, { name: RoleEnum.USER });
|
||||||
if (!role) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND);
|
if (!role) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND);
|
||||||
|
|
||||||
|
const existPhone = await queryRunner.manager.findOneBy(User, { phone: registerDto.phone });
|
||||||
|
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
|
||||||
const existUser = await queryRunner.manager.findOneBy(User, { nationalCode: registerDto.nationalCode });
|
const existUser = await queryRunner.manager.findOneBy(User, { nationalCode: registerDto.nationalCode });
|
||||||
if (existUser) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
if (existUser) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
||||||
|
|
||||||
@@ -271,50 +259,6 @@ export class UsersService {
|
|||||||
|
|
||||||
/************************************************************ */
|
/************************************************************ */
|
||||||
|
|
||||||
async createAdmin(createDto: CreateAdminDto) {
|
|
||||||
const existEmail = await this.userRepository.findOneBy({ email: createDto.email });
|
|
||||||
if (existEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
|
||||||
|
|
||||||
const existPhone = await this.userRepository.findOneBy({ phone: createDto.phone });
|
|
||||||
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
|
||||||
|
|
||||||
const role = await this.rolesRepository.findOne({ where: { id: createDto.roleId }, relations: { permissions: true } });
|
|
||||||
if (!role) throw new BadRequestException(AdsMessage.ROLE_NOT_FOUND);
|
|
||||||
|
|
||||||
await this.rolesRepository.save(role);
|
|
||||||
|
|
||||||
if (createDto.password !== createDto.repeatPassword) throw new BadRequestException(AdminMessage.PASSWORD_NOT_MATCH);
|
|
||||||
|
|
||||||
const hashedPassword = await this.passwordService.hashPassword(createDto.password);
|
|
||||||
|
|
||||||
const userName = slugify(`${createDto.firstName} ${Date.now().toString().slice(-5)}`, { lower: true, trim: true });
|
|
||||||
|
|
||||||
const adminUser = this.userRepository.create({ ...createDto, roles: [role], password: hashedPassword, userName });
|
|
||||||
await this.userRepository.save(adminUser);
|
|
||||||
return {
|
|
||||||
message: AdminMessage.ADMIN_CREATED,
|
|
||||||
adminUser,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async createRole(createDto: CreateRoleDto) {
|
|
||||||
const existRole = await this.rolesRepository.findOne({ where: { name: createDto.name } });
|
|
||||||
if (existRole) throw new BadRequestException(AdminMessage.ROLE_EXIST);
|
|
||||||
|
|
||||||
const permissions = await this.permissionsRepository.findBy({ id: In(createDto.permissions) });
|
|
||||||
if (permissions.length !== createDto.permissions.length) throw new BadRequestException(AdminMessage.PERMISSIONS_NOT_FOUND);
|
|
||||||
|
|
||||||
const role = this.rolesRepository.create({ ...createDto, permissions, isAdmin: true });
|
|
||||||
await this.rolesRepository.save(role);
|
|
||||||
return {
|
|
||||||
message: AdminMessage.ROLE_CREATED,
|
|
||||||
role,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async checkValidity(checkDto: CheckValidityDTO, userId: string) {
|
async checkValidity(checkDto: CheckValidityDTO, userId: string) {
|
||||||
const { type } = checkDto;
|
const { type } = checkDto;
|
||||||
if (type === ValidityType.USERNAME) checkDto.value = slugify(checkDto.value, { lower: true, trim: true });
|
if (type === ValidityType.USERNAME) checkDto.value = slugify(checkDto.value, { lower: true, trim: true });
|
||||||
@@ -386,7 +330,7 @@ export class UsersService {
|
|||||||
|
|
||||||
async findAllUsers() {
|
async findAllUsers() {
|
||||||
const users = await this.userRepository.find({
|
const users = await this.userRepository.find({
|
||||||
relations: ["groups"],
|
relations: { groups: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
return { users };
|
return { users };
|
||||||
@@ -398,279 +342,13 @@ export class UsersService {
|
|||||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||||
return user.roles.some((role) => role.name === RoleEnum.SUPER_ADMIN);
|
return user.roles.some((role) => role.name === RoleEnum.SUPER_ADMIN);
|
||||||
}
|
}
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async getCustomers(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");
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
return { customers, count };
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
// 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 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 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.walletsService.createUserWallet(user.id, queryRunner);
|
|
||||||
|
|
||||||
// await queryRunner.commitTransaction();
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// message: CommonMessage.CREATED,
|
|
||||||
// user,
|
|
||||||
// };
|
|
||||||
// } catch (error) {
|
|
||||||
// await queryRunner.rollbackTransaction();
|
|
||||||
// throw error;
|
|
||||||
// } finally {
|
|
||||||
// await queryRunner.release();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async findOneCustomer(userId: string) {
|
|
||||||
const customer = await this.userRepository.findOne({
|
|
||||||
where: { id: userId, roles: { name: RoleEnum.USER } },
|
|
||||||
relations: { legalUser: true, realUser: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
return { customer };
|
|
||||||
}
|
|
||||||
/************************************************************ */
|
/************************************************************ */
|
||||||
|
|
||||||
async getUsersByGroup(groupId: string) {
|
async getUsersByGroup(groupId: string) {
|
||||||
const users = await this.userRepository.find({ where: { groups: { id: groupId } }, relations: { tickets: true } });
|
const users = await this.userRepository.find({ where: { groups: { id: groupId } }, relations: { tickets: true } });
|
||||||
return { users };
|
return { users };
|
||||||
}
|
}
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async getAdmins(queryDto: SearchAdminQueryDto) {
|
|
||||||
const { limit, skip } = PaginationUtils(queryDto);
|
|
||||||
const queryBuilder = this.userRepository.createQueryBuilder("user");
|
|
||||||
|
|
||||||
queryBuilder
|
|
||||||
.leftJoinAndSelect("user.roles", "role")
|
|
||||||
// .addSelect(["role.id", "role.name"])
|
|
||||||
.where("role.isAdmin = :isAdmin", { isAdmin: true })
|
|
||||||
.leftJoinAndSelect("user.groups", "groups")
|
|
||||||
.leftJoinAndSelect("role.permissions", "permissions");
|
|
||||||
// .where("permissions.name IN (:...adminPermissions)", {
|
|
||||||
// adminPermissions: [PermissionEnum.ADMINS],
|
|
||||||
// });
|
|
||||||
// .addSelect(["permissions.id", "permissions.name"]);
|
|
||||||
|
|
||||||
if (queryDto.q) {
|
|
||||||
queryBuilder.andWhere("user.firstName ILIKE :q OR user.lastName ILIKE :q OR user.userName ILIKE :q", {
|
|
||||||
q: `%${queryDto.q}%`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryDto.permission) {
|
|
||||||
queryBuilder.andWhere("permissions.name = :permName", { permName: queryDto.permission });
|
|
||||||
}
|
|
||||||
|
|
||||||
queryBuilder.take(limit).skip(skip).orderBy("user.createdAt", "DESC");
|
|
||||||
|
|
||||||
const [users, count] = await queryBuilder.getManyAndCount();
|
|
||||||
|
|
||||||
return {
|
|
||||||
users,
|
|
||||||
count,
|
|
||||||
paginate: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async getPermissions() {
|
|
||||||
const permissions = await this.permissionsRepository.find({ select: { id: true, name: true } });
|
|
||||||
return {
|
|
||||||
permissions,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async getRoles(queryDto: SearchRolesQueryDto) {
|
|
||||||
const { limit, skip } = PaginationUtils(queryDto);
|
|
||||||
const queryBuilder = this.rolesRepository.createQueryBuilder("role");
|
|
||||||
|
|
||||||
queryBuilder
|
|
||||||
.where("role.isAdmin = :isAdmin", { isAdmin: true })
|
|
||||||
// .leftJoinAndSelect("role.permissions", "permissions")
|
|
||||||
.loadRelationCountAndMap("role.userCount", "role.users");
|
|
||||||
|
|
||||||
if (queryDto.q) {
|
|
||||||
queryBuilder.andWhere("role.name ILIKE :q", { q: `%${queryDto.q}%` });
|
|
||||||
}
|
|
||||||
|
|
||||||
queryBuilder.take(limit).skip(skip).orderBy("role.createdAt", "DESC");
|
|
||||||
|
|
||||||
const [roles, count] = await queryBuilder.getManyAndCount();
|
|
||||||
|
|
||||||
return {
|
|
||||||
roles,
|
|
||||||
count,
|
|
||||||
paginate: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/************************************************************ */
|
|
||||||
//TODO:query manager
|
|
||||||
async createRealUserData(createDto: CreateRealUserDto, userId: string) {
|
|
||||||
const user = await this.userRepository.findOneBy({ id: userId });
|
|
||||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
|
||||||
|
|
||||||
if (user.financialType && user.financialType === FinancialType.LEGAL)
|
|
||||||
throw new BadRequestException(UserMessage.FINANCIAL_TYPE_IS_LEGAL);
|
|
||||||
//
|
|
||||||
const existRealUser = await this.realUserRepository.findOne({ where: { user: { id: user.id } } });
|
|
||||||
|
|
||||||
if (existRealUser) throw new BadRequestException(UserMessage.REAL_DATA_EXIST);
|
|
||||||
|
|
||||||
const { city } = await this.addressService.getCity(+createDto.cityId);
|
|
||||||
|
|
||||||
const existNationalCode = await this.realUserRepository.findOne({ where: { nationalCode: createDto.nationalCode } });
|
|
||||||
if (existNationalCode) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
|
||||||
|
|
||||||
const existPhone = await this.realUserRepository.findOne({ where: { phone: createDto.phone } });
|
|
||||||
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
|
||||||
|
|
||||||
const realUser = this.realUserRepository.create({
|
|
||||||
...createDto,
|
|
||||||
user,
|
|
||||||
address: {
|
|
||||||
fullAddress: createDto.address,
|
|
||||||
city,
|
|
||||||
postalCode: createDto.postalCode,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.realUserRepository.save(realUser);
|
|
||||||
|
|
||||||
user.financialType = FinancialType.REAL;
|
|
||||||
await this.userRepository.save(user);
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: CommonMessage.CREATED,
|
|
||||||
realUser,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// /************************************************************ */
|
|
||||||
|
|
||||||
//TODO:query manager
|
|
||||||
async createLegalUserData(createDto: CreateLegalUserDto, userId: string) {
|
|
||||||
const user = await this.userRepository.findOneBy({ id: userId });
|
|
||||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
|
||||||
|
|
||||||
if (user.financialType && user.financialType === FinancialType.REAL) throw new BadRequestException(UserMessage.FINANCIAL_TYPE_IS_REAL);
|
|
||||||
|
|
||||||
const existingLegalUser = await this.legalUserRepository.findOne({ where: { user: { id: user.id } } });
|
|
||||||
|
|
||||||
if (existingLegalUser) throw new BadRequestException(UserMessage.LEGAL_DATA_EXIST);
|
|
||||||
|
|
||||||
const existEconomicCode = await this.legalUserRepository.findOne({ where: { economicCode: createDto.economicCode } });
|
|
||||||
if (existEconomicCode) throw new BadRequestException(UserMessage.ECONOMIC_CODE_EXIST);
|
|
||||||
|
|
||||||
const existPhone = await this.legalUserRepository.findOne({ where: { phone: createDto.phone } });
|
|
||||||
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
|
||||||
|
|
||||||
const existRegistrationCode = await this.legalUserRepository.findOne({ where: { registrationCode: createDto.registrationCode } });
|
|
||||||
if (existRegistrationCode) throw new BadRequestException(UserMessage.REGISTRATION_CODE_EXIST);
|
|
||||||
|
|
||||||
const existNationalIdentity = await this.legalUserRepository.findOne({ where: { nationalIdentity: createDto.nationalIdentity } });
|
|
||||||
if (existNationalIdentity) throw new BadRequestException(UserMessage.NATIONAL_IDENTITY_EXIST);
|
|
||||||
|
|
||||||
const { city } = await this.addressService.getCity(+createDto.cityId);
|
|
||||||
|
|
||||||
const legalUser = this.legalUserRepository.create({
|
|
||||||
...createDto,
|
|
||||||
user,
|
|
||||||
address: {
|
|
||||||
fullAddress: createDto.address,
|
|
||||||
city,
|
|
||||||
postalCode: createDto.postalCode,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.legalUserRepository.save(legalUser);
|
|
||||||
|
|
||||||
user.financialType = FinancialType.LEGAL;
|
|
||||||
await this.userRepository.save(user);
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: CommonMessage.CREATED,
|
|
||||||
legalUser,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************ */
|
|
||||||
|
|
||||||
async getCustomersCount() {
|
|
||||||
const count = await this.userRepository.count({ where: { roles: { name: RoleEnum.USER } } });
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************ */
|
/************************************************************ */
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,18 @@ import { Injectable } from "@nestjs/common";
|
|||||||
import { InjectRepository } from "@nestjs/typeorm";
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
import { Repository } from "typeorm";
|
import { Repository } from "typeorm";
|
||||||
|
|
||||||
|
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||||
|
import { SearchAdminQueryDto } from "../DTO/search-admins-query.dto";
|
||||||
|
import { SearchCustomersDto } from "../DTO/search-customers.dto";
|
||||||
import { User } from "../entities/user.entity";
|
import { User } from "../entities/user.entity";
|
||||||
|
import { RoleEnum } from "../enums/role.enum";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserRepository extends Repository<User> {
|
export class UserRepository extends Repository<User> {
|
||||||
constructor(@InjectRepository(User) userRepository: Repository<User>) {
|
constructor(@InjectRepository(User) userRepository: Repository<User>) {
|
||||||
super(userRepository.target, userRepository.manager, userRepository.queryRunner);
|
super(userRepository.target, userRepository.manager, userRepository.queryRunner);
|
||||||
}
|
}
|
||||||
|
//************* */
|
||||||
async findOneWithEmail(email: string): Promise<User | null> {
|
async findOneWithEmail(email: string): Promise<User | null> {
|
||||||
return this.findOne({
|
return this.findOne({
|
||||||
where: {
|
where: {
|
||||||
@@ -22,6 +26,7 @@ export class UserRepository extends Repository<User> {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//************* */
|
||||||
|
|
||||||
async findOneWithPhone(phone: string): Promise<User | null> {
|
async findOneWithPhone(phone: string): Promise<User | null> {
|
||||||
return this.findOne({
|
return this.findOne({
|
||||||
@@ -35,6 +40,7 @@ export class UserRepository extends Repository<User> {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//************* */
|
||||||
|
|
||||||
async findOneWithUserName(userName: string): Promise<User | null> {
|
async findOneWithUserName(userName: string): Promise<User | null> {
|
||||||
return this.findOne({
|
return this.findOne({
|
||||||
@@ -48,4 +54,87 @@ export class UserRepository extends Repository<User> {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//************* */
|
||||||
|
|
||||||
|
async findOneWithId(id: string): Promise<User | null> {
|
||||||
|
return this.findOne({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
relations: {
|
||||||
|
roles: {
|
||||||
|
permissions: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//************* */
|
||||||
|
|
||||||
|
// async findOneWithRefreshToken(refreshToken: string): Promise<User | null> {
|
||||||
|
// return this.findOne({
|
||||||
|
// where: {
|
||||||
|
// refreshToken,
|
||||||
|
// },
|
||||||
|
// relations: {
|
||||||
|
// roles: {
|
||||||
|
// permissions: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
//************* */
|
||||||
|
|
||||||
|
async getCustomer(queryDto: SearchCustomersDto) {
|
||||||
|
const { limit, skip } = PaginationUtils(queryDto);
|
||||||
|
|
||||||
|
const queryBuilder = this.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}%` });
|
||||||
|
}
|
||||||
|
|
||||||
|
return await queryBuilder.skip(skip).take(limit).getManyAndCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
//************* */
|
||||||
|
async getAdmins(queryDto: SearchAdminQueryDto) {
|
||||||
|
const { limit, skip } = PaginationUtils(queryDto);
|
||||||
|
const queryBuilder = this.createQueryBuilder("user");
|
||||||
|
|
||||||
|
queryBuilder
|
||||||
|
.leftJoinAndSelect("user.roles", "role")
|
||||||
|
// .addSelect(["role.id", "role.name"])
|
||||||
|
.where("role.isAdmin = :isAdmin", { isAdmin: true })
|
||||||
|
.leftJoinAndSelect("user.groups", "groups")
|
||||||
|
.leftJoinAndSelect("role.permissions", "permissions");
|
||||||
|
// .where("permissions.name IN (:...adminPermissions)", {
|
||||||
|
// adminPermissions: [PermissionEnum.ADMINS],
|
||||||
|
// });
|
||||||
|
// .addSelect(["permissions.id", "permissions.name"]);
|
||||||
|
|
||||||
|
if (queryDto.q) {
|
||||||
|
queryBuilder.andWhere("user.firstName ILIKE :q OR user.lastName ILIKE :q OR user.userName ILIKE :q", {
|
||||||
|
q: `%${queryDto.q}%`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryDto.permission) {
|
||||||
|
queryBuilder.andWhere("permissions.name = :permName", { permName: queryDto.permission });
|
||||||
|
}
|
||||||
|
|
||||||
|
queryBuilder.take(limit).skip(skip).orderBy("user.createdAt", "DESC");
|
||||||
|
|
||||||
|
return await queryBuilder.getManyAndCount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { FastifyReply } from "fastify";
|
|||||||
import { ChangeEmailDto } from "./DTO/change-email.dto";
|
import { ChangeEmailDto } from "./DTO/change-email.dto";
|
||||||
import { CheckValidityDTO } from "./DTO/check-validity.dto";
|
import { CheckValidityDTO } from "./DTO/check-validity.dto";
|
||||||
import { CreateAdminDto } from "./DTO/create-admin.dto";
|
import { CreateAdminDto } from "./DTO/create-admin.dto";
|
||||||
|
import { CreateCustomerDto } from "./DTO/create-customer.dto";
|
||||||
import { CreateLegalUserDto } from "./DTO/create-legal-user.dto";
|
import { CreateLegalUserDto } from "./DTO/create-legal-user.dto";
|
||||||
import { CreateRealUserDto } from "./DTO/create-real-user.dto";
|
import { CreateRealUserDto } from "./DTO/create-real-user.dto";
|
||||||
import { CreateRoleDto } from "./DTO/create-role.dto";
|
import { CreateRoleDto } from "./DTO/create-role.dto";
|
||||||
@@ -15,6 +16,8 @@ import { UpdateProfileDto } from "./DTO/update-profile.dto";
|
|||||||
import { CreateUserGroupDto } from "./DTO/user-group.dto";
|
import { CreateUserGroupDto } from "./DTO/user-group.dto";
|
||||||
import { EmailVerifyQueryDto } from "./DTO/verify-email-query.dto";
|
import { EmailVerifyQueryDto } from "./DTO/verify-email-query.dto";
|
||||||
import { PermissionEnum } from "./enums/permission.enum";
|
import { PermissionEnum } from "./enums/permission.enum";
|
||||||
|
import { AdminsService } from "./providers/admins.service";
|
||||||
|
import { CustomersService } from "./providers/customers.service";
|
||||||
import { UsersService } from "./providers/users.service";
|
import { UsersService } from "./providers/users.service";
|
||||||
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||||
import { PermissionsDec } from "../../common/decorators/permission.decorator";
|
import { PermissionsDec } from "../../common/decorators/permission.decorator";
|
||||||
@@ -26,9 +29,14 @@ import { VerifyOtpDto } from "../auth/DTO/verify-otp.dto";
|
|||||||
@Controller("users")
|
@Controller("users")
|
||||||
@ApiTags("users")
|
@ApiTags("users")
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
constructor(private usersService: UsersService) {}
|
constructor(
|
||||||
|
private readonly usersService: UsersService,
|
||||||
|
private readonly adminsService: AdminsService,
|
||||||
|
private readonly customersService: CustomersService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
//----------------------- user -----------------------
|
||||||
|
|
||||||
//
|
|
||||||
@ApiOperation({ summary: "Get user profile" })
|
@ApiOperation({ summary: "Get user profile" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@Get("me")
|
@Get("me")
|
||||||
@@ -49,7 +57,21 @@ export class UsersController {
|
|||||||
getRealUserData(@UserDec("id") userId: string) {
|
getRealUserData(@UserDec("id") userId: string) {
|
||||||
return this.usersService.getRealUserData(userId);
|
return this.usersService.getRealUserData(userId);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
@ApiOperation({ summary: "Create real user data ==> user route" })
|
||||||
|
@AuthGuards()
|
||||||
|
@Post("real")
|
||||||
|
createRealUser(@Body() createDto: CreateRealUserDto, @UserDec("id") userId: string) {
|
||||||
|
return this.customersService.createRealUserData(createDto, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: "Create legal user data ==> user route" })
|
||||||
|
@AuthGuards()
|
||||||
|
@Post("legal")
|
||||||
|
createLegalUser(@Body() createDto: CreateLegalUserDto, @UserDec("id") userId: string) {
|
||||||
|
return this.customersService.createLegalUserData(createDto, userId);
|
||||||
|
}
|
||||||
|
//----------------------- profile -----------------------
|
||||||
|
|
||||||
@ApiOperation({ summary: "Update user profile" })
|
@ApiOperation({ summary: "Update user profile" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@@ -114,32 +136,43 @@ export class UsersController {
|
|||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Get()
|
@Get()
|
||||||
Users() {
|
getUsers() {
|
||||||
return this.usersService.findAllUsers();
|
return this.usersService.findAllUsers();
|
||||||
}
|
}
|
||||||
|
//----------------------- customer -----------------------
|
||||||
|
|
||||||
@ApiOperation({ summary: "get all customers ==> admin route" })
|
@ApiOperation({ summary: "Create customer" })
|
||||||
|
@AuthGuards()
|
||||||
|
@HttpCode(HttpStatus.CREATED)
|
||||||
|
@Post("customer")
|
||||||
|
createCustomer(@Body() createDto: CreateCustomerDto) {
|
||||||
|
return this.customersService.createCustomer(createDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: "get customers ==> admin route" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Get("customers")
|
@Get("customers")
|
||||||
getCustomers(@Query() queryDto: SearchCustomersDto) {
|
getCustomers(@Query() queryDto: SearchCustomersDto) {
|
||||||
return this.usersService.getCustomers(queryDto);
|
return this.customersService.getCustomers(queryDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: "get all customers ==> admin route" })
|
@ApiOperation({ summary: "get customers by id ==> admin route" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Get("customers/:id")
|
@Get("customers/:id")
|
||||||
customer(@Param() paramDto: ParamDto) {
|
getCustomerById(@Param() paramDto: ParamDto) {
|
||||||
return this.usersService.findOneCustomer(paramDto.id);
|
return this.customersService.getCustomerById(paramDto.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------- admin -----------------------
|
||||||
|
|
||||||
@ApiOperation({ summary: "get all admins ==> admin route" })
|
@ApiOperation({ summary: "get all admins ==> admin route" })
|
||||||
@AuthGuards()
|
@AuthGuards()
|
||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Get("admins")
|
@Get("admins")
|
||||||
getAdmins(@Query() queryDto: SearchAdminQueryDto) {
|
getAdmins(@Query() queryDto: SearchAdminQueryDto) {
|
||||||
return this.usersService.getAdmins(queryDto);
|
return this.adminsService.getAdmins(queryDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: "create admin ==> admin route" })
|
@ApiOperation({ summary: "create admin ==> admin route" })
|
||||||
@@ -147,7 +180,7 @@ export class UsersController {
|
|||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Post("admins")
|
@Post("admins")
|
||||||
createAdmin(@Body() createDto: CreateAdminDto) {
|
createAdmin(@Body() createDto: CreateAdminDto) {
|
||||||
return this.usersService.createAdmin(createDto);
|
return this.adminsService.createAdmin(createDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: "get all permissions ==> admin route" })
|
@ApiOperation({ summary: "get all permissions ==> admin route" })
|
||||||
@@ -155,7 +188,7 @@ export class UsersController {
|
|||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Get("permissions")
|
@Get("permissions")
|
||||||
getPermissions() {
|
getPermissions() {
|
||||||
return this.usersService.getPermissions();
|
return this.adminsService.getPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: "get all roles ==> admin route" })
|
@ApiOperation({ summary: "get all roles ==> admin route" })
|
||||||
@@ -163,7 +196,7 @@ export class UsersController {
|
|||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Get("roles")
|
@Get("roles")
|
||||||
getRoles(@Query() queryDto: SearchRolesQueryDto) {
|
getRoles(@Query() queryDto: SearchRolesQueryDto) {
|
||||||
return this.usersService.getRoles(queryDto);
|
return this.adminsService.getRoles(queryDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: "create role ==> admin route" })
|
@ApiOperation({ summary: "create role ==> admin route" })
|
||||||
@@ -171,28 +204,6 @@ export class UsersController {
|
|||||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||||
@Post("roles")
|
@Post("roles")
|
||||||
createRole(@Body() createDto: CreateRoleDto) {
|
createRole(@Body() createDto: CreateRoleDto) {
|
||||||
return this.usersService.createRole(createDto);
|
return this.adminsService.createRole(createDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation({ summary: "Create real user data ==> user route" })
|
|
||||||
@AuthGuards()
|
|
||||||
@Post("real")
|
|
||||||
createRealUser(@Body() createDto: CreateRealUserDto, @UserDec("id") userId: string) {
|
|
||||||
return this.usersService.createRealUserData(createDto, userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiOperation({ summary: "Create legal user data ==> user route" })
|
|
||||||
@AuthGuards()
|
|
||||||
@Post("legal")
|
|
||||||
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);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import { RealUser } from "./entities/real-user.entity";
|
|||||||
import { RealUserRepository } from "./repositories/real-user.repository";
|
import { RealUserRepository } from "./repositories/real-user.repository";
|
||||||
import { UsersController } from "./users.controller";
|
import { UsersController } from "./users.controller";
|
||||||
import { UtilsModule } from "../utils/utils.module";
|
import { UtilsModule } from "../utils/utils.module";
|
||||||
|
import { AdminsService } from "./providers/admins.service";
|
||||||
|
import { CustomersService } from "./providers/customers.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -32,6 +34,8 @@ import { UtilsModule } from "../utils/utils.module";
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
UsersService,
|
UsersService,
|
||||||
|
AdminsService,
|
||||||
|
CustomersService,
|
||||||
UserRepository,
|
UserRepository,
|
||||||
RoleRepository,
|
RoleRepository,
|
||||||
UserGroupRepository,
|
UserGroupRepository,
|
||||||
@@ -43,6 +47,6 @@ import { UtilsModule } from "../utils/utils.module";
|
|||||||
AddressService,
|
AddressService,
|
||||||
],
|
],
|
||||||
controllers: [UsersController],
|
controllers: [UsersController],
|
||||||
exports: [UsersService, UserRepository],
|
exports: [UsersService, UserRepository, CustomersService, AdminsService],
|
||||||
})
|
})
|
||||||
export class UsersModule {}
|
export class UsersModule {}
|
||||||
|
|||||||
Reference in New Issue
Block a user