Merge pull request #18 from Danakcorp/mrtz

Mrtz
This commit is contained in:
morteza-mortezai
2025-10-24 20:47:16 +03:30
committed by GitHub
6 changed files with 169 additions and 24 deletions
+4
View File
@@ -92,6 +92,7 @@ export const enum CategoryMessage {
AttAlreadyExist = "ویژگی‌های این دسته بندی قبلا ساخته شده است",
VariantCreated = "تنوع‌های دسته بندی با موفقیت ساخته شدند",
AttributeCreated = "ویژگی‌های دسته بندی با موفقیت ساخته شدند",
AttributeUpdated = "ویژگی‌های دسته بندی با موفقیت بروزرسانی شدند",
NotValidId = "آیدی کتگوری صحیح نمی باشد",
MissingColors = "داده‌های رنگ برای تم انتخاب شده موجود نیست.",
MissingSizes = "داده‌های سایز برای تم انتخاب شده موجود نیست.",
@@ -105,6 +106,9 @@ export const enum CategoryMessage {
CategoryNotValidToChose = "کتگوری برای انتخاب مجاز نمی‌باشد",
AttributeDeleted = "ویژگی با موفقیت حذف شد",
}
export const enum CategoryAttrMessage {
NotValidId = "آیدی صحیح نمی باشد",
}
export const enum BrandMessage {
NotFound = "برندی با این اسم یافت نشد",
+4 -4
View File
@@ -6,8 +6,8 @@ import mongoose from "mongoose";
import { Logger } from "../../core/logging/logger";
import { connectMongo } from "../connection";
// import { backfillHierarchy } from "./backfillHierarchy";
import { blogCategorySeeder } from "./blogCategorySeeder";
import { blogSeeder } from "./blogSeeder";
// import { blogCategorySeeder } from "./blogCategorySeeder";
// import { blogSeeder } from "./blogSeeder";
import { contractSeeder } from "./contractSeeder";
// import { seedMedia } from "./mediaSeeder";
import { seedCityAndProvince } from "./iranCityseeder";
@@ -32,8 +32,8 @@ const seedDatabase = async () => {
logger.info("connected to mongodb");
await clearDatabase(logger);
await backfillHierarchy();
await blogCategorySeeder(logger);
await blogSeeder(logger);
// await blogCategorySeeder(logger);
// await blogSeeder(logger);
await contractSeeder(logger);
await createDefaultAdmin(logger);
await seedFaqs(logger);
+19 -19
View File
@@ -6,25 +6,25 @@ import { WarrantyModel } from "../../modules/warranty/models/warranty.model";
const warrantyNames = [
"Iran Warranty Co.",
"Pars Guarantee",
"Tehran Warranty Services",
"Safir Warranty",
"Farda Warranty Solutions",
"Aryan Protection",
"Mehr Warranty",
"Saman Warranty Group",
"Persian Warranty Solutions",
"Shahab After Sales",
"Payam Warranty",
"Kavir Protection",
"Tajrish Warranty",
"Sina Warranty",
"Atlas Warranty Services",
"Sepahan Warranty",
"Kish Warranty Group",
"Navid Warranty Solutions",
"Alborz Protection Services",
"Raha Warranty Solutions",
// "Pars Guarantee",
// "Tehran Warranty Services",
// "Safir Warranty",
// "Farda Warranty Solutions",
// "Aryan Protection",
// "Mehr Warranty",
// "Saman Warranty Group",
// "Persian Warranty Solutions",
// "Shahab After Sales",
// "Payam Warranty",
// "Kavir Protection",
// "Tajrish Warranty",
// "Sina Warranty",
// "Atlas Warranty Services",
// "Sepahan Warranty",
// "Kish Warranty Group",
// "Navid Warranty Solutions",
// "Alborz Protection Services",
// "Raha Warranty Solutions",
];
export const seedWarranty = async (logger: Logger) => {
@@ -13,6 +13,7 @@ import { CreateCategoryDTO } from "../../category/DTO/CreateCategory.dto";
import { CreateCategoryAttDTO } from "../../category/DTO/createCategoryAtt.dto";
import { CreateCategoryThemeDTO, UpdateCategoryVariantDTO } from "../../category/DTO/createCategoryTheme.dto";
import { UpdateCategoryDTO } from "../../category/DTO/UpdateCategory.dto";
import { UpdateCategoryAttDTO } from "../../category/DTO/updateCategoryAtt.dto";
import { PermissionEnum } from "../models/Abstraction/IPermission";
@ApiTags("Admin Category")
@@ -122,4 +123,15 @@ export class AdminCategoryController extends BaseController {
const data = await this.categoryService.createCategoryAttributeS(createAttributeDto, catId);
return this.response({ data }, HttpStatus.Created);
}
@ApiOperation("update category attributes ")
@ApiResponse("successful", HttpStatus.Created)
@ApiModel(UpdateCategoryAttDTO)
@ApiAuth()
@ApiBody("the attribute type can be text|select|number|checkbox|input ")
@httpPatch("/attributes", Guard.authAdmin(), ValidationMiddleware.validateInput(UpdateCategoryAttDTO))
public async updateCategoryAttribute(@requestBody() createAttributeDto: UpdateCategoryAttDTO) {
const data = await this.categoryService.updateCategoryAttributeS(createAttributeDto);
return this.response({ data }, HttpStatus.Created);
}
}
@@ -0,0 +1,68 @@
import { Expose, Type } from "class-transformer";
import { ArrayMinSize, IsArray, IsBoolean, IsEnum, IsInt, IsNotEmpty, IsOptional, IsString, ValidateNested } from "class-validator";
import { ApiProperty } from "../../../common/decorator/swggerDocs";
import { IsValidId } from "../../../common/decorator/validation.decorator";
import { categoryAttType } from "../../../common/enums/category.enum";
import { CategoryAttributeModel } from "../models/CategoryAttribute.model";
class AttributeValue {
@Expose()
@IsNotEmpty()
@IsString()
@ApiProperty({ type: "string", description: "Text of the attribute value", example: "ابریشم" })
text: string;
}
export class UpdateCategoryAttDTO {
@Expose()
@IsNotEmpty()
@IsInt()
@IsValidId(CategoryAttributeModel)
@ApiProperty({ type: "number", description: "category attribute id", example: 5 })
attrId: number;
@Expose()
@IsNotEmpty()
@ApiProperty({ type: "string", description: "Title of the attribute", example: "جنس" })
title: string;
@Expose()
@IsNotEmpty()
@IsEnum(categoryAttType)
@ApiProperty({ type: "string", description: "Type of the attribute", example: "checkbox" })
type: categoryAttType;
@Expose()
@IsOptional()
@IsNotEmpty()
@IsBoolean()
@ApiProperty({ type: "boolean", description: "if this be true then attribute can be selected many times", example: false })
multiple: boolean;
@Expose()
@IsOptional()
@IsNotEmpty()
@IsString()
@ApiProperty({ type: "string", description: "hint of the attribute", example: "نوع پارچه" })
hint: string;
@Expose()
@IsNotEmpty()
@IsBoolean()
@ApiProperty({ type: "boolean", description: "Specifies if the attribute is required", example: true })
required: boolean;
@Expose()
@IsNotEmpty()
@IsArray()
@ArrayMinSize(1)
@ValidateNested({ each: true })
@Type(() => AttributeValue)
@ApiProperty({
type: "Array",
description: "If the attribute allows multiple values (e.g., checkbox or select), provide the values here",
example: [{ text: "ابریشم" }, { text: "اسفنجی" }],
})
values: AttributeValue[];
}
+62 -1
View File
@@ -23,12 +23,13 @@ import {
UpdateCategoryVariantDTO,
} from "./DTO/createCategoryTheme.dto";
import { UpdateCategoryDTO } from "./DTO/UpdateCategory.dto";
import { UpdateCategoryAttDTO } from "./DTO/updateCategoryAtt.dto";
import { IColor } from "./models/Abstraction/IColor";
import { IMeterage } from "./models/Abstraction/IMeterage";
import { ISize } from "./models/Abstraction/ISize";
import { BaseRepository } from "../../common/base/repository";
import { CategoryThemeEnum } from "../../common/enums/category.enum";
import { CategoryMessage, CommonMessage } from "../../common/enums/message.enum";
import { CategoryAttrMessage, CategoryMessage, CommonMessage } from "../../common/enums/message.enum";
import { BadRequestError, ForbiddenError } from "../../core/app/app.errors";
import { IOCTYPES } from "../../IOC/ioc.types";
import { ProductDTO } from "../product/DTO/product.dto";
@@ -289,6 +290,66 @@ class CategoryService {
}
}
async updateCategoryAttributeS(dto: UpdateCategoryAttDTO) {
const session = await startSession();
session.startTransaction();
try {
const { attrId, title, type, multiple, required, values, hint } = dto;
// Validate the existence of the category
const existCategoryAttr = await this.categoryAttRepo.findById(attrId);
if (!existCategoryAttr) {
throw new BadRequestError(CategoryAttrMessage.NotValidId);
}
// Check if attribute already exists for the category
const existAttribute = await this.categoryAttRepo.model.exists({
category: existCategoryAttr.category._id,
_id: { $ne: attrId },
title,
});
if (existAttribute) {
throw new BadRequestError(CategoryMessage.AttAlreadyExist);
}
// Create the category attribute
const updated = await this.categoryAttRepo.model.findByIdAndUpdate(
attrId,
{
category: existCategoryAttr.category._id,
title,
type,
multiple,
hint,
required,
},
{ session },
);
// delete attribute value
await this.attributeValueRepo.model.deleteMany({ attribute: attrId }, { session });
for (const value of values) {
await this.attributeValueRepo.model.create([{ text: value.text, attribute: attrId }], { session });
}
// Commit the transaction
await session.commitTransaction();
session.endSession();
return {
message: CategoryMessage.AttributeUpdated,
attribute: updated,
};
} catch (error) {
// Rollback any changes made in the transaction
await session.abortTransaction();
session.endSession();
throw error; // Re-throw the error to be handled by the calling errorHandler
}
}
async getCategoryAttributeS(catId: string) {
await this.checkCategoryId(catId);