update: add company services and products
This commit is contained in:
@@ -10,8 +10,8 @@ jobs:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
DANAK_SERVER: "https://captain.dev.danakcorp.com"
|
DANAK_SERVER: "https://captain.dev.danakcorp.com"
|
||||||
APP_TOKEN: 1b5da4107e67bb72c17bcecdaea51e6ccd0c545a4e7ffbcf4fd7e2c83bfe24b0
|
APP_TOKEN: d33544dfb7c716effb5cadb16906aaab130f2573e2c431a5b194bef770297255
|
||||||
APP_NAME: danak-api
|
APP_NAME: danak-zone-api
|
||||||
GITHUB_TOKEN: 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
|
GITHUB_TOKEN: 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
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ export const enum CommonMessage {
|
|||||||
SEARCH_QUERY_STRING = "رشته جستجو باید یک رشته باشد",
|
SEARCH_QUERY_STRING = "رشته جستجو باید یک رشته باشد",
|
||||||
UPDATED = "با موفقیت آپدیت شد",
|
UPDATED = "با موفقیت آپدیت شد",
|
||||||
IS_ACTIVE_SHOULD_BE_1_0 = "وضعیت باید یکی از مقادیر ۰ و ۱ باشد",
|
IS_ACTIVE_SHOULD_BE_1_0 = "وضعیت باید یکی از مقادیر ۰ و ۱ باشد",
|
||||||
|
DATE_MUST_BE_DATE = "تاریخ باید یک تاریخ معتبر به صورت رشته باشد",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum CategoryMessage {
|
export const enum CategoryMessage {
|
||||||
@@ -476,7 +477,7 @@ export const enum InvoiceMessage {
|
|||||||
INVALID_DISCOUNT_CODE = "کد تخفیف نامعتبر است",
|
INVALID_DISCOUNT_CODE = "کد تخفیف نامعتبر است",
|
||||||
ORIGINAL_PRICE_NOT_FOUND = "قیمت اصلی صورت حساب یافت نشد",
|
ORIGINAL_PRICE_NOT_FOUND = "قیمت اصلی صورت حساب یافت نشد",
|
||||||
NOT_FOUND_BY_ID_OR_NOT_BELONG_TO_USER = "صورت حساب یافت نشد یا متعلق به کاربر نمی باشد",
|
NOT_FOUND_BY_ID_OR_NOT_BELONG_TO_USER = "صورت حساب یافت نشد یا متعلق به کاربر نمی باشد",
|
||||||
DISCOUNT_ALREADY_APPLIED = "ت`خفیف قبلا برای این صورت حساب اعمال شده است",
|
DISCOUNT_ALREADY_APPLIED = "تخفیف قبلا برای این صورت حساب اعمال شده است",
|
||||||
DISCOUNT_EXPIRED = "تخفیف منقضی شده است",
|
DISCOUNT_EXPIRED = "تخفیف منقضی شده است",
|
||||||
MAX_RECURRING_CYCLES_MUST_BE_POSITIVE = "تعداد تکرار باید بزرگتر از ۰ باشد",
|
MAX_RECURRING_CYCLES_MUST_BE_POSITIVE = "تعداد تکرار باید بزرگتر از ۰ باشد",
|
||||||
ITEMS_REQUIRED = "آیتمها مورد نیاز است",
|
ITEMS_REQUIRED = "آیتمها مورد نیاز است",
|
||||||
@@ -538,3 +539,59 @@ export const enum IndustryMessage {
|
|||||||
UPDATED_SUCCESSFULLY = "صنعت با موفقیت به روز رسانی شد",
|
UPDATED_SUCCESSFULLY = "صنعت با موفقیت به روز رسانی شد",
|
||||||
INDUSTRY_DELETED_SUCCESSFULLY = "صنعت با موفقیت حذف شد",
|
INDUSTRY_DELETED_SUCCESSFULLY = "صنعت با موفقیت حذف شد",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const enum CompanyMessage {
|
||||||
|
ADDRESS_MUST_BE_STRING = "آدرس شرکت باید یک رشته باشد",
|
||||||
|
ADDRESS_REQUIRED = "آدرس شرکت مورد نیاز است",
|
||||||
|
CHIEF_EXECUTIVE_MUST_BE_STRING = "نام مدیرعامل باید یک رشته باشد",
|
||||||
|
CHIEF_EXECUTIVE_REQUIRED = "نام مدیرعامل مورد نیاز است",
|
||||||
|
COVER_IMAGE_URL_MUST_BE_URL = "آدرس تصویر کاور شرکت باید یک URL معتبر باشد",
|
||||||
|
COVER_IMAGE_URL_REQUIRED = "آدرس تصویر کاور شرکت مورد نیاز است",
|
||||||
|
DATE_OF_ESTABLISHMENT_MUST_BE_DATE = "تاریخ تاسیس شرکت باید یک تاریخ معتبر باشد",
|
||||||
|
DATE_OF_ESTABLISHMENT_REQUIRED = "تاریخ تاسیس شرکت مورد نیاز است",
|
||||||
|
DESCRIPTION_MUST_BE_STRING = "توضیحات شرکت باید یک رشته باشد",
|
||||||
|
DESCRIPTION_REQUIRED = "توضیحات شرکت مورد نیاز است",
|
||||||
|
EMAIL_MUST_BE_VALID = "ایمیل شرکت باید معتبر باشد",
|
||||||
|
EMAIL_REQUIRED = "ایمیل شرکت مورد نیاز است",
|
||||||
|
IDENTIFICATION_NUMBER_MUST_BE_STRING = "شماره ثبت شرکت باید یک رشته باشد",
|
||||||
|
IDENTIFICATION_NUMBER_REQUIRED = "شماره ثبت شرکت مورد نیاز است",
|
||||||
|
INDUSTRY_ID_REQUIRED = "صنعت مورد نیاز است",
|
||||||
|
INDUSTRY_ID_SHOULD_BE_UUID = "شناسه صنعت باید یک UUID معتبر باشد",
|
||||||
|
IS_ACTIVE_MUST_BE_BOOLEAN = "وضعیت فعالیت شرکت باید یک مقدار بولین باشد",
|
||||||
|
IS_ACTIVE_REQUIRED = "وضعیت فعالیت شرکت مورد نیاز است",
|
||||||
|
MAP_ADDRESS_LINK_MUST_BE_URL = "لینک نقشه شرکت باید یک URL معتبر باشد",
|
||||||
|
MAP_ADDRESS_LINK_REQUIRED = "لینک نقشه شرکت مورد نیاز است",
|
||||||
|
NAME_MUST_BE_STRING = "نام شرکت باید یک رشته باشد",
|
||||||
|
NAME_REQUIRED = "نام شرکت مورد نیاز است",
|
||||||
|
PHONE_MUST_BE_STRING = "شماره تلفن شرکت باید یک رشته باشد",
|
||||||
|
PHONE_REQUIRED = "شماره تلفن شرکت مورد نیاز است",
|
||||||
|
PROFILE_IMAGE_URL_MUST_BE_URL = "آدرس تصویر پروفایل شرکت باید یک URL معتبر باشد",
|
||||||
|
PROFILE_IMAGE_URL_REQUIRED = "آدرس تصویر پروفایل شرکت مورد نیاز است",
|
||||||
|
WEBSITE_URL_MUST_BE_URL = "آدرس وبسایت شرکت باید یک URL معتبر باشد",
|
||||||
|
WEBSITE_URL_REQUIRED = "آدرس وبسایت شرکت مورد نیاز است",
|
||||||
|
NAME_LENGTH = "نام شرکت باید بین ۳ تا ۱۰۰ کاراکتر باشد",
|
||||||
|
CHIEF_EXECUTIVE_LENGTH = "نام مدیرعامل باید بین ۳ تا ۱۰۰ کاراکتر باشد",
|
||||||
|
COMPANY_CREATED_SUCCESSFULLY = "شرکت با موفقیت ایجاد شد",
|
||||||
|
COMPANY_ALREADY_EXISTS = "این شرکت قبلا ثبت شده است",
|
||||||
|
COMPANY_ALREADY_EXISTS_NAME = "این نام شرکت قبلا ثبت شده است",
|
||||||
|
COMPANY_ALREADY_EXISTS_PHONE = "این شماره تلفن قبلا ثبت شده است",
|
||||||
|
COMPANY_ALREADY_EXISTS_EMAIL = "این ایمیل قبلا ثبت شده است",
|
||||||
|
COMPANY_ALREADY_EXISTS_IDENTITY_NUMBER = "این شماره ثبت شرکت قبلا ثبت شده است",
|
||||||
|
COMPANY_NOT_FOUND = "شرکت یافت نشد",
|
||||||
|
UPDATED_SUCCESSFULLY = "با موفقیت به روز رسانی شد",
|
||||||
|
DELETED_SUCCESSFULLY = "با موفقیت حذف شد",
|
||||||
|
PRODUCT_TITLE_REQUIRED = "عنوان محصول الزامی است",
|
||||||
|
PRODUCT_TITLE_MUST_BE_STRING = "عنوان محصول باید رشته باشد",
|
||||||
|
PRODUCT_IMAGES_REQUIRED = "تصاویر محصول الزامی است",
|
||||||
|
PRODUCT_IMAGES_MUST_BE_ARRAY = "تصاویر محصول باید آرایه باشد",
|
||||||
|
PRODUCT_IMAGES_MUST_BE_URL = "تصاویر محصول باید آدرس معتبر باشد",
|
||||||
|
SERVICE_TITLE_REQUIRED = "عنوان خدمت الزامی است",
|
||||||
|
SERVICE_TITLE_MUST_BE_STRING = "عنوان خدمت باید رشته باشد",
|
||||||
|
SERVICE_IMAGES_REQUIRED = "تصاویر خدمت الزامی است",
|
||||||
|
SERVICE_IMAGES_MUST_BE_ARRAY = "تصاویر خدمت باید آرایه باشد",
|
||||||
|
SERVICE_IMAGES_MUST_BE_URL = "تصاویر خدمت باید آدرس معتبر باشد",
|
||||||
|
PRODUCTS_REQUIRED = "محصولات الزامی است",
|
||||||
|
SERVICES_REQUIRED = "خدمات الزامی است",
|
||||||
|
PRODUCTS_MUST_BE_ARRAY = "محصولات باید آرایه باشد",
|
||||||
|
SERVICES_MUST_BE_ARRAY = "خدمات باید آرایه باشد",
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { ApiPropertyOptional } from "@nestjs/swagger";
|
||||||
|
import { Type } from "class-transformer";
|
||||||
|
import { IsDateString, IsEnum, IsIn, IsOptional, IsString } from "class-validator";
|
||||||
|
|
||||||
|
import { PaginationDto } from "../../../common/DTO/pagination.dto";
|
||||||
|
import { CommonMessage, CompanyMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { CompanyStatus } from "../enums/company-status.enum";
|
||||||
|
|
||||||
|
export class CompanyListQueryDto extends PaginationDto {
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ message: CompanyMessage.NAME_MUST_BE_STRING })
|
||||||
|
@ApiPropertyOptional({ description: "نام شرکت" })
|
||||||
|
name?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ message: CompanyMessage.INDUSTRY_ID_SHOULD_BE_UUID })
|
||||||
|
@ApiPropertyOptional({ description: "شناسه صنعت" })
|
||||||
|
industryId?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@Type(() => Number)
|
||||||
|
@IsIn([1, 0], { message: CommonMessage.IS_ACTIVE_SHOULD_BE_1_0 })
|
||||||
|
@ApiPropertyOptional({ description: "ads status", example: 1 })
|
||||||
|
isActive?: number;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsEnum(CompanyStatus)
|
||||||
|
@ApiPropertyOptional({ description: "status", example: CompanyStatus.APPROVED, enum: CompanyStatus })
|
||||||
|
status?: CompanyStatus;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString({ message: CommonMessage.SEARCH_QUERY_STRING })
|
||||||
|
@ApiPropertyOptional({ description: "Search query", example: "search query" })
|
||||||
|
q?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsDateString(undefined, { message: CommonMessage.DATE_MUST_BE_DATE })
|
||||||
|
@ApiPropertyOptional({ description: "تاریخ ثبت", example: "2021-01-01" })
|
||||||
|
registrationDate?: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { IsArray, IsNotEmpty, IsString, IsUrl } from "class-validator";
|
||||||
|
|
||||||
|
import { CompanyMessage } from "../../../common/enums/message.enum";
|
||||||
|
|
||||||
|
export class CreateCompanyProductDto {
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.PRODUCT_TITLE_REQUIRED })
|
||||||
|
@IsString({ message: CompanyMessage.PRODUCT_TITLE_MUST_BE_STRING })
|
||||||
|
@ApiProperty({ description: "عنوان محصول", example: "محصول نمونه" })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.PRODUCT_IMAGES_REQUIRED })
|
||||||
|
@IsArray({ message: CompanyMessage.PRODUCT_IMAGES_MUST_BE_ARRAY })
|
||||||
|
@IsUrl({ protocols: ["http", "https"] }, { each: true, message: CompanyMessage.PRODUCT_IMAGES_MUST_BE_URL })
|
||||||
|
@ApiProperty({ description: "تصاویر محصول", example: ["https://example.com/image1.jpg", "https://example.com/image2.jpg"] })
|
||||||
|
imagesUrl: string[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { IsArray, IsNotEmpty, IsString, IsUrl } from "class-validator";
|
||||||
|
|
||||||
|
import { CompanyMessage } from "../../../common/enums/message.enum";
|
||||||
|
|
||||||
|
export class CreateCompanyServiceDto {
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.SERVICE_TITLE_REQUIRED })
|
||||||
|
@IsString({ message: CompanyMessage.SERVICE_TITLE_MUST_BE_STRING })
|
||||||
|
@ApiProperty({ description: "عنوان خدمت", example: "خدمت نمونه" })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.SERVICE_IMAGES_REQUIRED })
|
||||||
|
@IsArray({ message: CompanyMessage.SERVICE_IMAGES_MUST_BE_ARRAY })
|
||||||
|
@IsUrl({ protocols: ["http", "https"] }, { each: true, message: CompanyMessage.SERVICE_IMAGES_MUST_BE_URL })
|
||||||
|
@ApiProperty({ description: "تصاویر خدمت", example: ["https://example.com/image1.jpg", "https://example.com/image2.jpg"] })
|
||||||
|
imagesUrl: string[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
import { ApiProperty, PickType } from "@nestjs/swagger";
|
||||||
|
import { Type } from "class-transformer";
|
||||||
|
import {
|
||||||
|
ArrayMinSize,
|
||||||
|
IsArray,
|
||||||
|
IsBoolean,
|
||||||
|
IsDateString,
|
||||||
|
IsEmail,
|
||||||
|
IsNotEmpty,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
IsUUID,
|
||||||
|
IsUrl,
|
||||||
|
Length,
|
||||||
|
ValidateNested,
|
||||||
|
} from "class-validator";
|
||||||
|
|
||||||
|
import { CreateCompanyProductDto } from "./create-company-product.dto";
|
||||||
|
import { CreateCompanyServiceDto } from "./create-company-service.dto";
|
||||||
|
import { CompanyMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { CompleteRegistrationDto } from "../../auth/DTO/complete-register.dto";
|
||||||
|
|
||||||
|
export class CreateCompanyDto extends PickType(CompleteRegistrationDto, ["phone", "firstName", "lastName", "password", "nationalCode"]) {
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.NAME_REQUIRED })
|
||||||
|
@Length(3, 255, { message: CompanyMessage.NAME_LENGTH })
|
||||||
|
@IsString({ message: CompanyMessage.NAME_MUST_BE_STRING })
|
||||||
|
@ApiProperty({ description: "نام شرکت", example: "شرکت تولیدی و صنعتی کارگر" })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.EMAIL_REQUIRED })
|
||||||
|
@IsEmail(undefined, { message: CompanyMessage.EMAIL_MUST_BE_VALID })
|
||||||
|
@ApiProperty({ description: "ایمیل", example: "info@example.com" })
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.IDENTIFICATION_NUMBER_REQUIRED })
|
||||||
|
@IsString({ message: CompanyMessage.IDENTIFICATION_NUMBER_MUST_BE_STRING })
|
||||||
|
@ApiProperty({ description: "شماره ثبت", example: "1234567890" })
|
||||||
|
identificationNumber: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.DATE_OF_ESTABLISHMENT_REQUIRED })
|
||||||
|
@IsDateString(undefined, { message: CompanyMessage.DATE_OF_ESTABLISHMENT_MUST_BE_DATE })
|
||||||
|
@ApiProperty({ description: "تاریخ تاسیس", example: "2021-01-01" })
|
||||||
|
dateOfEstablishment: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.ADDRESS_REQUIRED })
|
||||||
|
@IsString({ message: CompanyMessage.ADDRESS_MUST_BE_STRING })
|
||||||
|
@ApiProperty({ description: "آدرس", example: "تهران، خیابان ولیعصر، پلاک 123" })
|
||||||
|
address: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.MAP_ADDRESS_LINK_REQUIRED })
|
||||||
|
@IsUrl({ protocols: ["http", "https"] }, { message: CompanyMessage.MAP_ADDRESS_LINK_MUST_BE_URL })
|
||||||
|
@ApiProperty({ description: "لینک آدرس", example: "https://maps.app.goo.gl/1234567890" })
|
||||||
|
mapAddressLink: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.DESCRIPTION_REQUIRED })
|
||||||
|
@IsString({ message: CompanyMessage.DESCRIPTION_MUST_BE_STRING })
|
||||||
|
@ApiProperty({ description: "توضیحات", example: "شرکت تولیدی و صنعتی کارگر" })
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.WEBSITE_URL_REQUIRED })
|
||||||
|
@IsUrl({ protocols: ["http", "https"] }, { message: CompanyMessage.WEBSITE_URL_MUST_BE_URL })
|
||||||
|
@ApiProperty({ description: "آدرس وبسایت", example: "https://www.example.com" })
|
||||||
|
websiteUrl: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.PROFILE_IMAGE_URL_REQUIRED })
|
||||||
|
@IsUrl({ protocols: ["http", "https"] }, { message: CompanyMessage.PROFILE_IMAGE_URL_MUST_BE_URL })
|
||||||
|
@ApiProperty({ description: "آدرس تصویر پروفایل", example: "https://www.example.com/profile.jpg" })
|
||||||
|
profileImageUrl: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.COVER_IMAGE_URL_REQUIRED })
|
||||||
|
@IsUrl({ protocols: ["http", "https"] }, { message: CompanyMessage.COVER_IMAGE_URL_MUST_BE_URL })
|
||||||
|
@ApiProperty({ description: "آدرس تصویر کاور", example: "https://www.example.com/cover.jpg" })
|
||||||
|
coverImageUrl: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.IS_ACTIVE_REQUIRED })
|
||||||
|
@IsBoolean({ message: CompanyMessage.IS_ACTIVE_MUST_BE_BOOLEAN })
|
||||||
|
@ApiProperty({ description: "وضعیت فعالیت", example: true })
|
||||||
|
isActive?: boolean;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.INDUSTRY_ID_REQUIRED })
|
||||||
|
@IsUUID("7", { message: CompanyMessage.INDUSTRY_ID_SHOULD_BE_UUID })
|
||||||
|
@ApiProperty({ description: "شناسه صنعت", example: "123e4567-e89b-12d3-a456-426614174000" })
|
||||||
|
industryId: string;
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.PRODUCTS_REQUIRED })
|
||||||
|
@IsArray({ message: CompanyMessage.PRODUCTS_MUST_BE_ARRAY })
|
||||||
|
@ArrayMinSize(1, { message: CompanyMessage.PRODUCTS_REQUIRED })
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => CreateCompanyProductDto)
|
||||||
|
@ApiProperty({ description: "محصولات شرکت", type: [CreateCompanyProductDto], required: false })
|
||||||
|
products: CreateCompanyProductDto[];
|
||||||
|
|
||||||
|
@IsNotEmpty({ message: CompanyMessage.SERVICES_REQUIRED })
|
||||||
|
@IsArray({ message: CompanyMessage.SERVICES_MUST_BE_ARRAY })
|
||||||
|
@ArrayMinSize(1, { message: CompanyMessage.SERVICES_REQUIRED })
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => CreateCompanyServiceDto)
|
||||||
|
@ApiProperty({ description: "خدمات شرکت", type: [CreateCompanyServiceDto], required: false })
|
||||||
|
services: CreateCompanyServiceDto[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { PartialType } from "@nestjs/swagger";
|
||||||
|
|
||||||
|
import { CreateCompanyDto } from "./create-company.dto";
|
||||||
|
|
||||||
|
export class UpdateCompanyDto extends PartialType(CreateCompanyDto) {}
|
||||||
@@ -1,4 +1,48 @@
|
|||||||
import { Controller } from "@nestjs/common";
|
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from "@nestjs/common";
|
||||||
|
import { ApiOperation } from "@nestjs/swagger";
|
||||||
|
|
||||||
|
import { CompanyListQueryDto } from "./DTO/company-list-query.dto";
|
||||||
|
import { CreateCompanyDto } from "./DTO/create-company.dto";
|
||||||
|
import { UpdateCompanyDto } from "./DTO/update-company.dto";
|
||||||
|
import { CompaniesService } from "./services/companies.service";
|
||||||
|
import { ParamDto } from "../../common/DTO/param.dto";
|
||||||
@Controller("companies")
|
@Controller("companies")
|
||||||
export class CompaniesController {}
|
export class CompaniesController {
|
||||||
|
constructor(private readonly companiesService: CompaniesService) {}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@ApiOperation({ summary: "create company (admin)" })
|
||||||
|
create(@Body() createCompanyDto: CreateCompanyDto) {
|
||||||
|
return this.companiesService.create(createCompanyDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(":id")
|
||||||
|
@ApiOperation({ summary: "update company (admin)" })
|
||||||
|
update(@Param() paramDto: ParamDto, @Body() updateCompanyDto: UpdateCompanyDto) {
|
||||||
|
return this.companiesService.updateCompanyById(paramDto.id, updateCompanyDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(":id")
|
||||||
|
@ApiOperation({ summary: "delete company (admin)" })
|
||||||
|
delete(@Param() paramDto: ParamDto) {
|
||||||
|
return this.companiesService.deleteCompanyById(paramDto.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("list")
|
||||||
|
@ApiOperation({ summary: "get companies list (admin)" })
|
||||||
|
getCompaniesList(@Query() query: CompanyListQueryDto) {
|
||||||
|
return this.companiesService.getCompaniesList(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(":id")
|
||||||
|
@ApiOperation({ summary: "get company by id" })
|
||||||
|
get(@Param() paramDto: ParamDto) {
|
||||||
|
return this.companiesService.getCompanyById(paramDto.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(":id/toggle-status")
|
||||||
|
@ApiOperation({ summary: "toggle company status (admin)" })
|
||||||
|
toggleStatus(@Param() paramDto: ParamDto) {
|
||||||
|
return this.companiesService.toggleStatus(paramDto.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,11 +2,15 @@ import { MikroOrmModule } from "@mikro-orm/nestjs";
|
|||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
import { CompaniesController } from "./companies.controller";
|
import { CompaniesController } from "./companies.controller";
|
||||||
|
import { CompanyProduct } from "./entities/company-product.entity";
|
||||||
|
import { CompanyService } from "./entities/company-service.entity";
|
||||||
import { Company } from "./entities/company.entity";
|
import { Company } from "./entities/company.entity";
|
||||||
import { CompaniesService } from "./services/companies.service";
|
import { CompaniesService } from "./services/companies.service";
|
||||||
|
import { Industry } from "../industries/entities/industry.entity";
|
||||||
|
import { UsersModule } from "../users/users.module";
|
||||||
|
import { UtilsModule } from "../utils/utils.module";
|
||||||
@Module({
|
@Module({
|
||||||
imports: [MikroOrmModule.forFeature([Company])],
|
imports: [MikroOrmModule.forFeature([Company, Industry, CompanyProduct, CompanyService]), UsersModule, UtilsModule],
|
||||||
providers: [CompaniesService],
|
providers: [CompaniesService],
|
||||||
controllers: [CompaniesController],
|
controllers: [CompaniesController],
|
||||||
exports: [CompaniesService],
|
exports: [CompaniesService],
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { Entity, ManyToOne, Property } from "@mikro-orm/core";
|
||||||
|
|
||||||
|
import { Company } from "./company.entity";
|
||||||
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class CompanyProduct extends BaseEntity {
|
||||||
|
@Property({ type: "varchar", length: 250, nullable: false })
|
||||||
|
title!: string;
|
||||||
|
|
||||||
|
@Property({ type: "array", nullable: false })
|
||||||
|
imagesUrl!: string[];
|
||||||
|
|
||||||
|
@ManyToOne(() => Company, { deleteRule: "cascade" })
|
||||||
|
company!: Company;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { Entity, ManyToOne, Property } from "@mikro-orm/core";
|
||||||
|
|
||||||
|
import { Company } from "./company.entity";
|
||||||
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class CompanyService extends BaseEntity {
|
||||||
|
@Property({ type: "varchar", length: 250, nullable: false })
|
||||||
|
title!: string;
|
||||||
|
|
||||||
|
@Property({ type: "array", nullable: false })
|
||||||
|
imagesUrl!: string[];
|
||||||
|
|
||||||
|
@ManyToOne(() => Company, { deleteRule: "cascade" })
|
||||||
|
company!: Company;
|
||||||
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
import { Entity, EntityRepositoryType, ManyToOne, Opt, Property } from "@mikro-orm/core";
|
import { Cascade, Collection, Entity, EntityRepositoryType, Enum, ManyToOne, OneToMany, Opt, Property } from "@mikro-orm/core";
|
||||||
|
|
||||||
|
import { CompanyProduct } from "./company-product.entity";
|
||||||
|
import { CompanyService } from "./company-service.entity";
|
||||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
import { Industry } from "../../industries/entities/industry.entity";
|
import { Industry } from "../../industries/entities/industry.entity";
|
||||||
|
import { User } from "../../users/entities/user.entity";
|
||||||
|
import { CompanyStatus } from "../enums/company-status.enum";
|
||||||
import { CompanyRepository } from "../repositories/company.repository";
|
import { CompanyRepository } from "../repositories/company.repository";
|
||||||
|
|
||||||
@Entity({ repository: () => CompanyRepository })
|
@Entity({ repository: () => CompanyRepository })
|
||||||
@@ -9,15 +13,6 @@ export class Company extends BaseEntity {
|
|||||||
@Property({ type: "varchar", length: 255, unique: true })
|
@Property({ type: "varchar", length: 255, unique: true })
|
||||||
name!: string;
|
name!: string;
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 255 })
|
|
||||||
chiefExecutive!: string;
|
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 255, unique: true })
|
|
||||||
phone!: string;
|
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 255, unique: true })
|
|
||||||
email!: string;
|
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 255, unique: true })
|
@Property({ type: "varchar", length: 255, unique: true })
|
||||||
identificationNumber!: string;
|
identificationNumber!: string;
|
||||||
|
|
||||||
@@ -45,8 +40,24 @@ export class Company extends BaseEntity {
|
|||||||
@Property({ type: "boolean", default: true })
|
@Property({ type: "boolean", default: true })
|
||||||
isActive!: boolean & Opt;
|
isActive!: boolean & Opt;
|
||||||
|
|
||||||
|
@Enum({ items: () => CompanyStatus, nativeEnumName: "company_status", nullable: false })
|
||||||
|
status!: CompanyStatus;
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
|
@OneToMany(() => CompanyProduct, (product) => product.company, { cascade: [Cascade.ALL] })
|
||||||
|
products = new Collection<CompanyProduct>(this);
|
||||||
|
|
||||||
|
@OneToMany(() => CompanyService, (service) => service.company, { cascade: [Cascade.ALL] })
|
||||||
|
services = new Collection<CompanyService>(this);
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
@ManyToOne(() => Industry, { deleteRule: "restrict" })
|
@ManyToOne(() => Industry, { deleteRule: "restrict" })
|
||||||
industry!: Industry;
|
industry!: Industry;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { deleteRule: "restrict" })
|
||||||
|
user!: User;
|
||||||
|
|
||||||
[EntityRepositoryType]?: CompanyRepository;
|
[EntityRepositoryType]?: CompanyRepository;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export enum CompanyStatus {
|
||||||
|
APPROVED = "APPROVED",
|
||||||
|
PENDING = "PENDING",
|
||||||
|
REJECTED = "REJECTED",
|
||||||
|
}
|
||||||
@@ -1,5 +1,25 @@
|
|||||||
import { EntityRepository } from "@mikro-orm/core";
|
import { EntityRepository } from "@mikro-orm/core";
|
||||||
|
|
||||||
|
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||||
|
import { CompanyListQueryDto } from "../DTO/company-list-query.dto";
|
||||||
import { Company } from "../entities/company.entity";
|
import { Company } from "../entities/company.entity";
|
||||||
|
|
||||||
export class CompanyRepository extends EntityRepository<Company> {}
|
export class CompanyRepository extends EntityRepository<Company> {
|
||||||
|
//
|
||||||
|
async getCompaniesListForAdmin(queryDto: CompanyListQueryDto) {
|
||||||
|
const { limit, skip } = PaginationUtils(queryDto);
|
||||||
|
|
||||||
|
return await this.findAndCount(
|
||||||
|
{
|
||||||
|
deletedAt: null,
|
||||||
|
...(queryDto.status && { status: queryDto.status }),
|
||||||
|
...(queryDto.q && { name: { $ilike: `%${queryDto.q}%` } }),
|
||||||
|
...(queryDto.industryId && { industry: { id: queryDto.industryId } }),
|
||||||
|
...(queryDto.isActive !== undefined && { isActive: queryDto.isActive === 1 }),
|
||||||
|
...(queryDto.registrationDate && { createdAt: { $gte: queryDto.registrationDate, $lte: queryDto.registrationDate } }),
|
||||||
|
...(queryDto.name && { name: { $ilike: `%${queryDto.name}%` } }),
|
||||||
|
},
|
||||||
|
{ offset: skip, limit, orderBy: { createdAt: "DESC" } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,172 @@
|
|||||||
import { Injectable } from "@nestjs/common";
|
import { Collection, EntityManager } from "@mikro-orm/postgresql";
|
||||||
|
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
import { CompanyMessage, IndustryMessage } from "../../../common/enums/message.enum";
|
||||||
|
import { Industry } from "../../industries/entities/industry.entity";
|
||||||
|
import { User } from "../../users/entities/user.entity";
|
||||||
|
import { UsersService } from "../../users/services/users.service";
|
||||||
|
import { PasswordService } from "../../utils/providers/password.service";
|
||||||
|
import { CompanyListQueryDto } from "../DTO/company-list-query.dto";
|
||||||
|
import { CreateCompanyDto } from "../DTO/create-company.dto";
|
||||||
|
import { UpdateCompanyDto } from "../DTO/update-company.dto";
|
||||||
|
import { CompanyProduct } from "../entities/company-product.entity";
|
||||||
|
import { CompanyService } from "../entities/company-service.entity";
|
||||||
|
import { Company } from "../entities/company.entity";
|
||||||
|
import { CompanyStatus } from "../enums/company-status.enum";
|
||||||
import { CompanyRepository } from "../repositories/company.repository";
|
import { CompanyRepository } from "../repositories/company.repository";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CompaniesService {
|
export class CompaniesService {
|
||||||
constructor(private readonly companyRepository: CompanyRepository) {}
|
constructor(
|
||||||
|
private readonly companyRepository: CompanyRepository,
|
||||||
|
private readonly usersService: UsersService,
|
||||||
|
private readonly passwordService: PasswordService,
|
||||||
|
private readonly em: EntityManager,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async create(createDto: CreateCompanyDto) {
|
||||||
|
const em = this.em.fork();
|
||||||
|
try {
|
||||||
|
em.begin();
|
||||||
|
|
||||||
|
const industry = await em.findOne(Industry, { id: createDto.industryId, deletedAt: null });
|
||||||
|
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
||||||
|
|
||||||
|
const [existingCompany, existIdentityNumber] = await Promise.all([
|
||||||
|
em.findOne(Company, { name: createDto.name }),
|
||||||
|
em.findOne(Company, { identificationNumber: createDto.identificationNumber }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_NAME);
|
||||||
|
if (existIdentityNumber) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_IDENTITY_NUMBER);
|
||||||
|
|
||||||
|
const hashedPassword = await this.passwordService.hashPassword(createDto.password);
|
||||||
|
const user = await this.usersService.createUser(createDto, hashedPassword, em);
|
||||||
|
|
||||||
|
const company = em.create(Company, { ...createDto, industry, status: CompanyStatus.APPROVED, user });
|
||||||
|
|
||||||
|
const products = createDto.products.map((productData) => em.create(CompanyProduct, { ...productData, company }));
|
||||||
|
company.products = new Collection(products);
|
||||||
|
|
||||||
|
const services = createDto.services.map((serviceData) => em.create(CompanyService, { ...serviceData, company }));
|
||||||
|
company.services = new Collection(services);
|
||||||
|
|
||||||
|
await em.persistAndFlush(company);
|
||||||
|
await em.commit();
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: CompanyMessage.COMPANY_CREATED_SUCCESSFULLY,
|
||||||
|
company,
|
||||||
|
user,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
await em.rollback();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
|
async updateCompanyById(id: string, updateDto: UpdateCompanyDto) {
|
||||||
|
const em = this.em.fork();
|
||||||
|
try {
|
||||||
|
em.begin();
|
||||||
|
|
||||||
|
const company = await em.findOne(Company, { id, deletedAt: null }, { populate: ["user"] });
|
||||||
|
if (!company) throw new BadRequestException(CompanyMessage.COMPANY_NOT_FOUND);
|
||||||
|
|
||||||
|
const updatedCompany = em.assign(company, updateDto);
|
||||||
|
|
||||||
|
if (updateDto.industryId) {
|
||||||
|
const industry = await em.findOne(Industry, { id: updateDto.industryId, deletedAt: null });
|
||||||
|
if (!industry) throw new BadRequestException(IndustryMessage.INDUSTRY_NOT_FOUND);
|
||||||
|
updatedCompany.industry = industry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDto.name) {
|
||||||
|
const existingCompany = await em.findOne(Company, { name: updateDto.name, deletedAt: null, id: { $ne: company.id } });
|
||||||
|
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateDto.identificationNumber) {
|
||||||
|
const existingCompany = await em.findOne(Company, {
|
||||||
|
identificationNumber: updateDto.identificationNumber,
|
||||||
|
deletedAt: null,
|
||||||
|
id: { $ne: company.id },
|
||||||
|
});
|
||||||
|
if (existingCompany) throw new BadRequestException(CompanyMessage.COMPANY_ALREADY_EXISTS_IDENTITY_NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userUpdateData: Partial<User> = {};
|
||||||
|
if (updateDto.phone) userUpdateData.phone = updateDto.phone;
|
||||||
|
if (updateDto.email) userUpdateData.email = updateDto.email;
|
||||||
|
if (updateDto.firstName) userUpdateData.firstName = updateDto.firstName;
|
||||||
|
if (updateDto.lastName) userUpdateData.lastName = updateDto.lastName;
|
||||||
|
if (updateDto.nationalCode) userUpdateData.nationalCode = updateDto.nationalCode;
|
||||||
|
|
||||||
|
if (Object.keys(userUpdateData).length > 0) await this.usersService.updateUser(company.user.id, userUpdateData, em);
|
||||||
|
|
||||||
|
await em.flush();
|
||||||
|
await em.commit();
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: CompanyMessage.UPDATED_SUCCESSFULLY,
|
||||||
|
updatedCompany,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
await em.rollback();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
|
async getCompanyById(id: string) {
|
||||||
|
const company = await this.findCompanyById(id);
|
||||||
|
return { company };
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
|
async getCompaniesList(queryDto: CompanyListQueryDto) {
|
||||||
|
const [companies, count] = await this.companyRepository.getCompaniesListForAdmin(queryDto);
|
||||||
|
return {
|
||||||
|
companies,
|
||||||
|
count,
|
||||||
|
paginate: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
|
async deleteCompanyById(id: string) {
|
||||||
|
const company = await this.findCompanyById(id);
|
||||||
|
|
||||||
|
company.deletedAt = dayjs().toDate();
|
||||||
|
|
||||||
|
await this.em.flush();
|
||||||
|
return {
|
||||||
|
message: CompanyMessage.DELETED_SUCCESSFULLY,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
|
async toggleStatus(id: string) {
|
||||||
|
const company = await this.findCompanyById(id);
|
||||||
|
|
||||||
|
company.isActive = !company.isActive;
|
||||||
|
|
||||||
|
await this.em.flush();
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: CompanyMessage.UPDATED_SUCCESSFULLY,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//-----------------------------------
|
||||||
|
private async findCompanyById(id: string) {
|
||||||
|
const company = await this.companyRepository.findOne({ id, deletedAt: null });
|
||||||
|
if (!company) throw new BadRequestException(CompanyMessage.COMPANY_NOT_FOUND);
|
||||||
|
return company;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export class IndustryRepository extends EntityRepository<Industry> {
|
|||||||
.offset(skip);
|
.offset(skip);
|
||||||
|
|
||||||
if (queryDto.q) {
|
if (queryDto.q) {
|
||||||
queryBuilder.andWhere({ name: { $ilike: `%${queryDto.q}%` } });
|
queryBuilder.andWhere({ title: { $ilike: `%${queryDto.q}%` } });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryDto.isActive !== undefined) {
|
if (queryDto.isActive !== undefined) {
|
||||||
|
|||||||
@@ -3,10 +3,17 @@ import { Collection, Entity, EntityRepositoryType, ManyToOne, OneToMany, Opt, Pr
|
|||||||
import { RefreshToken } from "./refresh-token.entity";
|
import { RefreshToken } from "./refresh-token.entity";
|
||||||
import { Role } from "./role.entity";
|
import { Role } from "./role.entity";
|
||||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
|
import { Company } from "../../companies/entities/company.entity";
|
||||||
import { UserRepository } from "../repositories/user.repository";
|
import { UserRepository } from "../repositories/user.repository";
|
||||||
|
|
||||||
@Entity({ repository: () => UserRepository })
|
@Entity({ repository: () => UserRepository })
|
||||||
export class User extends BaseEntity {
|
export class User extends BaseEntity {
|
||||||
|
@Property({ type: "varchar", length: 150 })
|
||||||
|
firstName!: string;
|
||||||
|
|
||||||
|
@Property({ type: "varchar", length: 200 })
|
||||||
|
lastName!: string;
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 150, nullable: true })
|
@Property({ type: "varchar", length: 150, nullable: true })
|
||||||
email?: string;
|
email?: string;
|
||||||
|
|
||||||
@@ -19,12 +26,6 @@ export class User extends BaseEntity {
|
|||||||
@Property({ type: "varchar", length: 150 })
|
@Property({ type: "varchar", length: 150 })
|
||||||
password!: string;
|
password!: string;
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 150 })
|
|
||||||
firstName!: string;
|
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 200 })
|
|
||||||
lastName!: string;
|
|
||||||
|
|
||||||
@Property({ type: "varchar", length: 12, nullable: true })
|
@Property({ type: "varchar", length: 12, nullable: true })
|
||||||
birthDate?: string;
|
birthDate?: string;
|
||||||
|
|
||||||
@@ -47,5 +48,8 @@ export class User extends BaseEntity {
|
|||||||
@OneToMany(() => RefreshToken, (token) => token.user)
|
@OneToMany(() => RefreshToken, (token) => token.user)
|
||||||
refreshTokens = new Collection<RefreshToken>(this);
|
refreshTokens = new Collection<RefreshToken>(this);
|
||||||
|
|
||||||
|
@OneToMany(() => Company, (company) => company.user)
|
||||||
|
companies = new Collection<Company>(this);
|
||||||
|
|
||||||
[EntityRepositoryType]?: UserRepository;
|
[EntityRepositoryType]?: UserRepository;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import slugify from "slugify";
|
|||||||
|
|
||||||
import { UserMessage } from "../../../common/enums/message.enum";
|
import { UserMessage } from "../../../common/enums/message.enum";
|
||||||
import { CompleteRegistrationDto } from "../../auth/DTO/complete-register.dto";
|
import { CompleteRegistrationDto } from "../../auth/DTO/complete-register.dto";
|
||||||
|
import { CreateCompanyDto } from "../../companies/DTO/create-company.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 { RoleEnum } from "../enums/role.enum";
|
import { RoleEnum } from "../enums/role.enum";
|
||||||
@@ -45,16 +46,22 @@ export class UsersService {
|
|||||||
|
|
||||||
/*******************************/
|
/*******************************/
|
||||||
|
|
||||||
async createUser(registerDto: CompleteRegistrationDto, hashedPassword: string, em: EntityManager) {
|
async createUser(registerDto: CompleteRegistrationDto | CreateCompanyDto, hashedPassword: string, em: EntityManager) {
|
||||||
const role = await em.findOne(Role, { name: RoleEnum.USER });
|
const [role, existPhone, existUser] = await Promise.all([
|
||||||
|
em.findOne(Role, { name: RoleEnum.USER }),
|
||||||
|
em.findOne(User, { phone: registerDto.phone }),
|
||||||
|
em.findOne(User, { nationalCode: registerDto.nationalCode }),
|
||||||
|
]);
|
||||||
|
|
||||||
if (!role) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND);
|
if (!role) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND);
|
||||||
|
|
||||||
const existPhone = await em.findOne(User, { phone: registerDto.phone });
|
|
||||||
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
|
||||||
const existUser = await em.findOne(User, { nationalCode: registerDto.nationalCode });
|
|
||||||
if (existUser) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
if (existUser) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
||||||
|
|
||||||
|
if ("email" in registerDto) {
|
||||||
|
const existEmail = await em.findOne(User, { email: registerDto.email });
|
||||||
|
if (existEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
const userName = slugify(`${registerDto.firstName} ${Date.now().toString().slice(-5)}`, { lower: true, trim: true });
|
const userName = slugify(`${registerDto.firstName} ${Date.now().toString().slice(-5)}`, { lower: true, trim: true });
|
||||||
|
|
||||||
const user = em.create(User, {
|
const user = em.create(User, {
|
||||||
@@ -76,4 +83,31 @@ export class UsersService {
|
|||||||
await this.em.flush();
|
await this.em.flush();
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************/
|
||||||
|
|
||||||
|
async updateUser(id: string, updateData: Partial<User>, em: EntityManager) {
|
||||||
|
const user = await em.findOne(User, { id, deletedAt: null });
|
||||||
|
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||||
|
|
||||||
|
if (updateData.phone) {
|
||||||
|
const existingUser = await em.findOne(User, { phone: updateData.phone, deletedAt: null, id: { $ne: id } });
|
||||||
|
if (existingUser) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateData.email) {
|
||||||
|
const existingUser = await em.findOne(User, { email: updateData.email, deletedAt: null, id: { $ne: id } });
|
||||||
|
if (existingUser) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateData.nationalCode) {
|
||||||
|
const existingUser = await em.findOne(User, { nationalCode: updateData.nationalCode, deletedAt: null, id: { $ne: id } });
|
||||||
|
if (existingUser) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
em.assign(user, updateData);
|
||||||
|
await em.flush();
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user