add :update category attribute

This commit is contained in:
morteza-mortezai
2025-10-24 20:40:23 +03:30
parent 9027e0ac9c
commit 3c941c9fe8
4 changed files with 146 additions and 1 deletions
@@ -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);