chore: create customer
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import Decimal from "decimal.js";
|
||||
import { FindOptionsWhere, In, IsNull } from "typeorm";
|
||||
|
||||
import { ParamDto } from "../../../common/DTO/param.dto";
|
||||
import { CategoryMessage, CommonMessage, ServiceMessage } from "../../../common/enums/message.enum";
|
||||
import { DiscountCalculationType } from "../../discounts/enums/discount-type.enum";
|
||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||
import { AddReviewDto } from "../DTO/add-review.dto";
|
||||
import { CategoryListSearchQueryDto, CategorySearchQueryDto } from "../DTO/category-search-query.dto";
|
||||
@@ -179,10 +181,34 @@ export class DanakServicesService {
|
||||
async getDanakServiceByIdWithSubs(serviceId: string, isAdmin: boolean) {
|
||||
const danakService = await this.danakServicesRepository.findOne({
|
||||
where: { id: serviceId, ...(isAdmin && { isActive: true, subscriptionPlans: { isActive: true } }) },
|
||||
relations: { images: true, subscriptionPlans: true },
|
||||
relations: { images: true, subscriptionPlans: { discounts: true } },
|
||||
});
|
||||
if (!danakService) throw new BadRequestException(ServiceMessage.SERVICE_NOT_FOUND_BY_ID);
|
||||
|
||||
const transformedSubscriptions = danakService.subscriptionPlans.map((subscription) => {
|
||||
let price = new Decimal(subscription.price);
|
||||
|
||||
if (subscription.discounts && subscription.discounts.length > 0) {
|
||||
subscription.discounts.forEach((discount) => {
|
||||
if (discount.isActive && new Date() >= discount.startDate && new Date() <= discount.endDate) {
|
||||
if (discount.calculationType === DiscountCalculationType.PERCENTAGE) {
|
||||
const discountAmount = price.mul(discount.amount).div(100);
|
||||
price = price.sub(discountAmount);
|
||||
} else if (discount.calculationType === DiscountCalculationType.FIXED) {
|
||||
price = price.sub(discount.amount);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
...subscription,
|
||||
finalPrice: price.toNumber(),
|
||||
};
|
||||
});
|
||||
|
||||
danakService.subscriptionPlans = transformedSubscriptions;
|
||||
|
||||
const reviews = await this.danakServiceReviewRepository.find({
|
||||
where: { service: { id: serviceId }, status: ReviewStatus.APPROVED },
|
||||
relations: { user: true },
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ApiProperty, PartialType } from "@nestjs/swagger";
|
||||
import { IsEmail, IsMobilePhone, IsNotEmpty, IsNumberString, IsString, Length, MinLength } from "class-validator";
|
||||
import { ApiProperty, ApiPropertyOptional, PartialType } from "@nestjs/swagger";
|
||||
import { IsEmail, IsMobilePhone, IsNotEmpty, IsNumberString, IsOptional, IsString, Length, MinLength } from "class-validator";
|
||||
|
||||
import { CreateLegalUserDto } from "./create-legal-user.dto";
|
||||
import { AuthMessage } from "../../../common/enums/message.enum";
|
||||
import { AuthMessage, FinancialMessage } from "../../../common/enums/message.enum";
|
||||
|
||||
export class CreateUserDto extends PartialType(CreateLegalUserDto) {
|
||||
export class CreateCustomerDto extends PartialType(CreateLegalUserDto) {
|
||||
@IsNotEmpty({ message: AuthMessage.PHONE_NOT_EMPTY })
|
||||
@IsMobilePhone("fa-IR", {}, { message: AuthMessage.INVALID_PHONE_FORMAT })
|
||||
@Length(11, 11, { message: AuthMessage.PHONE_SHOULD_BE_11_DIGIT })
|
||||
@@ -44,4 +44,44 @@ export class CreateUserDto extends PartialType(CreateLegalUserDto) {
|
||||
@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: "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: "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: "postalCode" })
|
||||
@IsOptional()
|
||||
@IsString({ message: FinancialMessage.NATIONAL_ID_INVALID })
|
||||
postalCode?: 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;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ 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";
|
||||
@@ -350,6 +351,69 @@ export class UsersService {
|
||||
|
||||
/************************************************************ */
|
||||
|
||||
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: {
|
||||
|
||||
@@ -7,6 +7,7 @@ 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";
|
||||
@@ -174,4 +175,14 @@ export class UsersController {
|
||||
}
|
||||
|
||||
/************************************************************ */
|
||||
|
||||
@AuthGuards()
|
||||
@ApiOperation({ summary: "Create customer" })
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@Post("customer")
|
||||
createCustomer(@Body() createDto: CreateCustomerDto) {
|
||||
return this.usersService.createCustomer(createDto);
|
||||
}
|
||||
|
||||
/************************************************************ */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user