@@ -92,6 +92,7 @@ export const enum CategoryMessage {
|
|||||||
AttAlreadyExist = "ویژگیهای این دسته بندی قبلا ساخته شده است",
|
AttAlreadyExist = "ویژگیهای این دسته بندی قبلا ساخته شده است",
|
||||||
VariantCreated = "تنوعهای دسته بندی با موفقیت ساخته شدند",
|
VariantCreated = "تنوعهای دسته بندی با موفقیت ساخته شدند",
|
||||||
AttributeCreated = "ویژگیهای دسته بندی با موفقیت ساخته شدند",
|
AttributeCreated = "ویژگیهای دسته بندی با موفقیت ساخته شدند",
|
||||||
|
AttributeUpdated = "ویژگیهای دسته بندی با موفقیت بروزرسانی شدند",
|
||||||
NotValidId = "آیدی کتگوری صحیح نمی باشد",
|
NotValidId = "آیدی کتگوری صحیح نمی باشد",
|
||||||
MissingColors = "دادههای رنگ برای تم انتخاب شده موجود نیست.",
|
MissingColors = "دادههای رنگ برای تم انتخاب شده موجود نیست.",
|
||||||
MissingSizes = "دادههای سایز برای تم انتخاب شده موجود نیست.",
|
MissingSizes = "دادههای سایز برای تم انتخاب شده موجود نیست.",
|
||||||
@@ -105,6 +106,9 @@ export const enum CategoryMessage {
|
|||||||
CategoryNotValidToChose = "کتگوری برای انتخاب مجاز نمیباشد",
|
CategoryNotValidToChose = "کتگوری برای انتخاب مجاز نمیباشد",
|
||||||
AttributeDeleted = "ویژگی با موفقیت حذف شد",
|
AttributeDeleted = "ویژگی با موفقیت حذف شد",
|
||||||
}
|
}
|
||||||
|
export const enum CategoryAttrMessage {
|
||||||
|
NotValidId = "آیدی صحیح نمی باشد",
|
||||||
|
}
|
||||||
|
|
||||||
export const enum BrandMessage {
|
export const enum BrandMessage {
|
||||||
NotFound = "برندی با این اسم یافت نشد",
|
NotFound = "برندی با این اسم یافت نشد",
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import mongoose from "mongoose";
|
|||||||
import { Logger } from "../../core/logging/logger";
|
import { Logger } from "../../core/logging/logger";
|
||||||
import { connectMongo } from "../connection";
|
import { connectMongo } from "../connection";
|
||||||
// import { backfillHierarchy } from "./backfillHierarchy";
|
// import { backfillHierarchy } from "./backfillHierarchy";
|
||||||
import { blogCategorySeeder } from "./blogCategorySeeder";
|
// import { blogCategorySeeder } from "./blogCategorySeeder";
|
||||||
import { blogSeeder } from "./blogSeeder";
|
// import { blogSeeder } from "./blogSeeder";
|
||||||
import { contractSeeder } from "./contractSeeder";
|
import { contractSeeder } from "./contractSeeder";
|
||||||
// import { seedMedia } from "./mediaSeeder";
|
// import { seedMedia } from "./mediaSeeder";
|
||||||
import { seedCityAndProvince } from "./iranCityseeder";
|
import { seedCityAndProvince } from "./iranCityseeder";
|
||||||
@@ -32,8 +32,8 @@ const seedDatabase = async () => {
|
|||||||
logger.info("connected to mongodb");
|
logger.info("connected to mongodb");
|
||||||
await clearDatabase(logger);
|
await clearDatabase(logger);
|
||||||
await backfillHierarchy();
|
await backfillHierarchy();
|
||||||
await blogCategorySeeder(logger);
|
// await blogCategorySeeder(logger);
|
||||||
await blogSeeder(logger);
|
// await blogSeeder(logger);
|
||||||
await contractSeeder(logger);
|
await contractSeeder(logger);
|
||||||
await createDefaultAdmin(logger);
|
await createDefaultAdmin(logger);
|
||||||
await seedFaqs(logger);
|
await seedFaqs(logger);
|
||||||
|
|||||||
@@ -6,25 +6,25 @@ import { WarrantyModel } from "../../modules/warranty/models/warranty.model";
|
|||||||
|
|
||||||
const warrantyNames = [
|
const warrantyNames = [
|
||||||
"Iran Warranty Co.",
|
"Iran Warranty Co.",
|
||||||
"Pars Guarantee",
|
// "Pars Guarantee",
|
||||||
"Tehran Warranty Services",
|
// "Tehran Warranty Services",
|
||||||
"Safir Warranty",
|
// "Safir Warranty",
|
||||||
"Farda Warranty Solutions",
|
// "Farda Warranty Solutions",
|
||||||
"Aryan Protection",
|
// "Aryan Protection",
|
||||||
"Mehr Warranty",
|
// "Mehr Warranty",
|
||||||
"Saman Warranty Group",
|
// "Saman Warranty Group",
|
||||||
"Persian Warranty Solutions",
|
// "Persian Warranty Solutions",
|
||||||
"Shahab After Sales",
|
// "Shahab After Sales",
|
||||||
"Payam Warranty",
|
// "Payam Warranty",
|
||||||
"Kavir Protection",
|
// "Kavir Protection",
|
||||||
"Tajrish Warranty",
|
// "Tajrish Warranty",
|
||||||
"Sina Warranty",
|
// "Sina Warranty",
|
||||||
"Atlas Warranty Services",
|
// "Atlas Warranty Services",
|
||||||
"Sepahan Warranty",
|
// "Sepahan Warranty",
|
||||||
"Kish Warranty Group",
|
// "Kish Warranty Group",
|
||||||
"Navid Warranty Solutions",
|
// "Navid Warranty Solutions",
|
||||||
"Alborz Protection Services",
|
// "Alborz Protection Services",
|
||||||
"Raha Warranty Solutions",
|
// "Raha Warranty Solutions",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const seedWarranty = async (logger: Logger) => {
|
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 { CreateCategoryAttDTO } from "../../category/DTO/createCategoryAtt.dto";
|
||||||
import { CreateCategoryThemeDTO, UpdateCategoryVariantDTO } from "../../category/DTO/createCategoryTheme.dto";
|
import { CreateCategoryThemeDTO, UpdateCategoryVariantDTO } from "../../category/DTO/createCategoryTheme.dto";
|
||||||
import { UpdateCategoryDTO } from "../../category/DTO/UpdateCategory.dto";
|
import { UpdateCategoryDTO } from "../../category/DTO/UpdateCategory.dto";
|
||||||
|
import { UpdateCategoryAttDTO } from "../../category/DTO/updateCategoryAtt.dto";
|
||||||
import { PermissionEnum } from "../models/Abstraction/IPermission";
|
import { PermissionEnum } from "../models/Abstraction/IPermission";
|
||||||
|
|
||||||
@ApiTags("Admin Category")
|
@ApiTags("Admin Category")
|
||||||
@@ -122,4 +123,15 @@ export class AdminCategoryController extends BaseController {
|
|||||||
const data = await this.categoryService.createCategoryAttributeS(createAttributeDto, catId);
|
const data = await this.categoryService.createCategoryAttributeS(createAttributeDto, catId);
|
||||||
return this.response({ data }, HttpStatus.Created);
|
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[];
|
||||||
|
}
|
||||||
@@ -23,12 +23,13 @@ import {
|
|||||||
UpdateCategoryVariantDTO,
|
UpdateCategoryVariantDTO,
|
||||||
} from "./DTO/createCategoryTheme.dto";
|
} from "./DTO/createCategoryTheme.dto";
|
||||||
import { UpdateCategoryDTO } from "./DTO/UpdateCategory.dto";
|
import { UpdateCategoryDTO } from "./DTO/UpdateCategory.dto";
|
||||||
|
import { UpdateCategoryAttDTO } from "./DTO/updateCategoryAtt.dto";
|
||||||
import { IColor } from "./models/Abstraction/IColor";
|
import { IColor } from "./models/Abstraction/IColor";
|
||||||
import { IMeterage } from "./models/Abstraction/IMeterage";
|
import { IMeterage } from "./models/Abstraction/IMeterage";
|
||||||
import { ISize } from "./models/Abstraction/ISize";
|
import { ISize } from "./models/Abstraction/ISize";
|
||||||
import { BaseRepository } from "../../common/base/repository";
|
import { BaseRepository } from "../../common/base/repository";
|
||||||
import { CategoryThemeEnum } from "../../common/enums/category.enum";
|
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 { BadRequestError, ForbiddenError } from "../../core/app/app.errors";
|
||||||
import { IOCTYPES } from "../../IOC/ioc.types";
|
import { IOCTYPES } from "../../IOC/ioc.types";
|
||||||
import { ProductDTO } from "../product/DTO/product.dto";
|
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) {
|
async getCategoryAttributeS(catId: string) {
|
||||||
await this.checkCategoryId(catId);
|
await this.checkCategoryId(catId);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user