Merge branch 'mrtz' into chatbot
merge
This commit is contained in:
@@ -71,9 +71,7 @@ export const IOCTYPES = {
|
|||||||
WarrantyRepository: Symbol.for("WarrantyRepository"),
|
WarrantyRepository: Symbol.for("WarrantyRepository"),
|
||||||
ShipmentRepository: Symbol.for("ShipmentRepository"),
|
ShipmentRepository: Symbol.for("ShipmentRepository"),
|
||||||
TokenRepository: Symbol.for("TokenRepository"),
|
TokenRepository: Symbol.for("TokenRepository"),
|
||||||
ColorRepository: Symbol.for("ColorRepository"),
|
|
||||||
SizeRepository: Symbol.for("SizeRepository"),
|
|
||||||
MeterageRepository: Symbol.for("MeterageRepository"),
|
|
||||||
ThemeRepository: Symbol.for("ThemeRepository"),
|
ThemeRepository: Symbol.for("ThemeRepository"),
|
||||||
ThemeValueRepository: Symbol.for("ThemeValueRepository"),
|
ThemeValueRepository: Symbol.for("ThemeValueRepository"),
|
||||||
QuestionRepository: Symbol.for("QuestionRepository"),
|
QuestionRepository: Symbol.for("QuestionRepository"),
|
||||||
|
|||||||
@@ -87,9 +87,7 @@ export class AdminCategoryController extends BaseController {
|
|||||||
@ApiResponse("successful", HttpStatus.Created)
|
@ApiResponse("successful", HttpStatus.Created)
|
||||||
@ApiParam("id", "id of category", true)
|
@ApiParam("id", "id of category", true)
|
||||||
@ApiModel(CreateCategoryThemeDTO)
|
@ApiModel(CreateCategoryThemeDTO)
|
||||||
@ApiBody(
|
@ApiBody("the ")
|
||||||
"the colors and sizes and meterage fields are optional and one of them should send and u can also send noColor_noSize too for no theme",
|
|
||||||
)
|
|
||||||
@ApiAuth()
|
@ApiAuth()
|
||||||
@httpPost(
|
@httpPost(
|
||||||
"/:id/variants",
|
"/:id/variants",
|
||||||
@@ -177,6 +175,7 @@ export class AdminCategoryController extends BaseController {
|
|||||||
@ApiOperation("Update a theme ==> need to login as admin")
|
@ApiOperation("Update a theme ==> need to login as admin")
|
||||||
@ApiResponse("theme updated successfully", HttpStatus.Ok)
|
@ApiResponse("theme updated successfully", HttpStatus.Ok)
|
||||||
@ApiAuth()
|
@ApiAuth()
|
||||||
|
@ApiModel(UpdateThemeDTO)
|
||||||
@httpPut(
|
@httpPut(
|
||||||
"/theme",
|
"/theme",
|
||||||
Guard.authAdmin(),
|
Guard.authAdmin(),
|
||||||
@@ -242,15 +241,17 @@ export class AdminCategoryController extends BaseController {
|
|||||||
|
|
||||||
@ApiOperation("Update a theme value ==> need to login as admin")
|
@ApiOperation("Update a theme value ==> need to login as admin")
|
||||||
@ApiResponse("theme value updated successfully", HttpStatus.Ok)
|
@ApiResponse("theme value updated successfully", HttpStatus.Ok)
|
||||||
|
@ApiParam("id", "id of the theme value", true)
|
||||||
@ApiAuth()
|
@ApiAuth()
|
||||||
|
@ApiModel(UpdateThemeValueDTO)
|
||||||
@httpPut(
|
@httpPut(
|
||||||
"/theme-value",
|
"/theme-value/:id",
|
||||||
Guard.authAdmin(),
|
Guard.authAdmin(),
|
||||||
Guard.checkAdminPermissions([PermissionEnum.ADMIN]),
|
Guard.checkAdminPermissions([PermissionEnum.ADMIN]),
|
||||||
ValidationMiddleware.validateInput(UpdateThemeValueDTO),
|
ValidationMiddleware.validateInput(UpdateThemeValueDTO),
|
||||||
)
|
)
|
||||||
public async updateThemeValue(@requestBody() updateDto: UpdateThemeValueDTO) {
|
public async updateThemeValue(@requestParam("id") id: string, @requestBody() updateDto: UpdateThemeValueDTO) {
|
||||||
const data = await this.themeService.updateThemeValue(updateDto);
|
const data = await this.themeService.updateThemeValue(id, updateDto);
|
||||||
return this.response({ data });
|
return this.response({ data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class CartRepository extends BaseRepository<ICart> {
|
|||||||
})
|
})
|
||||||
.populate({
|
.populate({
|
||||||
path: "items.variant",
|
path: "items.variant",
|
||||||
populate: ["color", "size", "meterage", "warranty", "shop"],
|
populate: [{ path: "warranty" }, { path: "shop" }, { path: "themeValue" }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,13 +231,9 @@ class CartRepository extends BaseRepository<ICart> {
|
|||||||
{ $lookup: { from: "productvariants", localField: "items.variant", foreignField: "_id", as: "variantDetails" } },
|
{ $lookup: { from: "productvariants", localField: "items.variant", foreignField: "_id", as: "variantDetails" } },
|
||||||
{ $unwind: "$variantDetails" },
|
{ $unwind: "$variantDetails" },
|
||||||
{ $lookup: { from: "warranties", localField: "variantDetails.warranty", foreignField: "_id", as: "variantDetails.warranty" } },
|
{ $lookup: { from: "warranties", localField: "variantDetails.warranty", foreignField: "_id", as: "variantDetails.warranty" } },
|
||||||
{ $lookup: { from: "colors", localField: "variantDetails.color", foreignField: "_id", as: "variantDetails.color" } },
|
{ $lookup: { from: "themeValues", localField: "variantDetails.themeValue", foreignField: "_id", as: "variantDetails.themeValue" } },
|
||||||
{ $lookup: { from: "sizes", localField: "variantDetails.size", foreignField: "_id", as: "variantDetails.size" } },
|
|
||||||
{ $lookup: { from: "meterages", localField: "variantDetails.meterage", foreignField: "_id", as: "variantDetails.meterage" } },
|
|
||||||
{ $unwind: { path: "$variantDetails.warranty", preserveNullAndEmptyArrays: true } },
|
{ $unwind: { path: "$variantDetails.warranty", preserveNullAndEmptyArrays: true } },
|
||||||
{ $unwind: { path: "$variantDetails.color", preserveNullAndEmptyArrays: true } },
|
{ $unwind: { path: "$variantDetails.themeValue", preserveNullAndEmptyArrays: true } },
|
||||||
{ $unwind: { path: "$variantDetails.size", preserveNullAndEmptyArrays: true } },
|
|
||||||
{ $unwind: { path: "$variantDetails.meterage", preserveNullAndEmptyArrays: true } },
|
|
||||||
{ $lookup: { from: "shops", localField: "variantDetails.shop", foreignField: "_id", as: "variantDetails.shop" } },
|
{ $lookup: { from: "shops", localField: "variantDetails.shop", foreignField: "_id", as: "variantDetails.shop" } },
|
||||||
{ $unwind: "$variantDetails.shop" },
|
{ $unwind: "$variantDetails.shop" },
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export class CreateCategoryDTO {
|
|||||||
@IsValidId(ThemeModel)
|
@IsValidId(ThemeModel)
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
type: "string",
|
type: "string",
|
||||||
description: "the variation theme of a category ==> should be one of Color/Size/Meterage or noColor_noSize",
|
description: "the variation theme of a category ==> ",
|
||||||
})
|
})
|
||||||
themeId: string;
|
themeId: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Expose } from "class-transformer";
|
import { Expose } from "class-transformer";
|
||||||
import { IsNotEmpty, IsString } from "class-validator";
|
import { IsNotEmpty, IsOptional, IsString } from "class-validator";
|
||||||
|
|
||||||
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
||||||
import { IsValidId } from "../../../common/decorator/validation.decorator";
|
import { IsValidId } from "../../../common/decorator/validation.decorator";
|
||||||
@@ -14,10 +14,10 @@ export class CreateThemeValueDTO {
|
|||||||
theme: string;
|
theme: string;
|
||||||
|
|
||||||
@Expose()
|
@Expose()
|
||||||
@IsNotEmpty()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
@ApiProperty({ type: "string", description: "the name of theme value", example: "Red" })
|
@ApiProperty({ type: "string", description: "the name of theme value", example: "Red", required: false })
|
||||||
name: string;
|
name?: string;
|
||||||
|
|
||||||
@Expose()
|
@Expose()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ export class UpdateCategoryDTO {
|
|||||||
@IsValidId(ThemeModel)
|
@IsValidId(ThemeModel)
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
type: "string",
|
type: "string",
|
||||||
description: "the variation theme of a category ==> should be one of Color/Size/Meterage or noColor_noSize",
|
description: "the variation theme of a category ==> ",
|
||||||
example: "Color",
|
|
||||||
})
|
})
|
||||||
themeId: string;
|
themeId: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,9 @@
|
|||||||
import { Expose } from "class-transformer";
|
import { Expose } from "class-transformer";
|
||||||
import { IsNotEmpty, IsOptional, IsString, Length } from "class-validator";
|
import { IsNotEmpty, IsOptional, IsString } from "class-validator";
|
||||||
|
|
||||||
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
||||||
import { IsValidId } from "../../../common/decorator/validation.decorator";
|
|
||||||
import { ThemeValueModel } from "../models/themeValue.model";
|
|
||||||
|
|
||||||
export class UpdateThemeValueDTO {
|
export class UpdateThemeValueDTO {
|
||||||
@Expose()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@IsString()
|
|
||||||
@Length(24, 24)
|
|
||||||
@IsValidId(ThemeValueModel)
|
|
||||||
@ApiProperty({ type: "string", description: "theme value id", example: "66f3bcaee566db722a044c62" })
|
|
||||||
themeValueId: string;
|
|
||||||
|
|
||||||
@Expose()
|
@Expose()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
|||||||
@@ -1,42 +1,17 @@
|
|||||||
import { Expose, Transform, Type, plainToInstance } from "class-transformer";
|
import { Expose, Transform, Type, plainToInstance } from "class-transformer";
|
||||||
|
|
||||||
|
import { ThemeValueDTO } from "../../product/DTO/product.dto";
|
||||||
import { ICategory } from "../models/Abstraction/ICategory";
|
import { ICategory } from "../models/Abstraction/ICategory";
|
||||||
import { ICategoryAttribute } from "../models/Abstraction/ICategoryAttributes";
|
import { ICategoryAttribute } from "../models/Abstraction/ICategoryAttributes";
|
||||||
export class Size_MeterageDTO {
|
|
||||||
@Expose()
|
|
||||||
_id: number;
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
value: string;
|
|
||||||
}
|
|
||||||
export class ColorDTO {
|
|
||||||
@Expose()
|
|
||||||
_id: number;
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
hexColor: string;
|
|
||||||
}
|
|
||||||
export class VariantDTO {
|
export class VariantDTO {
|
||||||
@Expose()
|
@Expose()
|
||||||
_id: string;
|
_id: string;
|
||||||
|
|
||||||
@Expose()
|
@Expose()
|
||||||
@Type(() => ColorDTO)
|
@Type(() => ThemeValueDTO)
|
||||||
@Transform(({ value }) => (value && value.length > 0 ? value : undefined) /*, { toClassOnly: true }*/)
|
@Transform(({ value }) => (value && value.length > 0 ? value : undefined) /*, { toClassOnly: true }*/)
|
||||||
colors: ColorDTO[];
|
themeValues: ThemeValueDTO[];
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@Type(() => Size_MeterageDTO)
|
|
||||||
@Transform(({ value }) => (value && value.length > 0 ? value : undefined) /*, { toClassOnly: true }*/)
|
|
||||||
sizes: Size_MeterageDTO[];
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@Type(() => Size_MeterageDTO)
|
|
||||||
@Transform(({ value }) => (value && value.length > 0 ? value : undefined) /*, { toClassOnly: true }*/)
|
|
||||||
meterages: Size_MeterageDTO[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CategoryVariantDTO {
|
export class CategoryVariantDTO {
|
||||||
|
|||||||
@@ -1,34 +1,11 @@
|
|||||||
import { PartialType } from "@nestjs/mapped-types";
|
import { PartialType } from "@nestjs/mapped-types";
|
||||||
import { Expose, Type } from "class-transformer";
|
import { Expose } from "class-transformer";
|
||||||
import { ArrayMinSize, IsHexColor, IsNotEmpty, IsOptional, ValidateNested } from "class-validator";
|
import { IsOptional } from "class-validator";
|
||||||
|
|
||||||
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
||||||
import { IsValidId } from "../../../common/decorator/validation.decorator";
|
import { IsValidId } from "../../../common/decorator/validation.decorator";
|
||||||
import { ThemeModel } from "../models/theme.model";
|
import { ThemeModel } from "../models/theme.model";
|
||||||
|
|
||||||
export class CreateColorDTO {
|
|
||||||
@Expose()
|
|
||||||
@IsNotEmpty()
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@IsHexColor()
|
|
||||||
hexColor: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CreateSizeDTO {
|
|
||||||
@Expose()
|
|
||||||
@IsNotEmpty()
|
|
||||||
value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CreateMeterageDTO {
|
|
||||||
@Expose()
|
|
||||||
@IsNotEmpty()
|
|
||||||
value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CreateCategoryThemeDTO {
|
export class CreateCategoryThemeDTO {
|
||||||
@Expose()
|
@Expose()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@@ -38,46 +15,6 @@ export class CreateCategoryThemeDTO {
|
|||||||
description: "theme id",
|
description: "theme id",
|
||||||
})
|
})
|
||||||
themeId?: string;
|
themeId?: string;
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@IsOptional()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ArrayMinSize(1)
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => CreateColorDTO)
|
|
||||||
@ApiProperty({
|
|
||||||
type: "Array",
|
|
||||||
required: true,
|
|
||||||
description: "the variation colors of a category theme",
|
|
||||||
example: [{ name: "مشکی", hexColor: "#000000" }],
|
|
||||||
})
|
|
||||||
colors?: CreateColorDTO[];
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@IsOptional()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ArrayMinSize(1)
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => CreateSizeDTO)
|
|
||||||
@ApiProperty({
|
|
||||||
type: "Array",
|
|
||||||
description: "the variation sizes of a category theme",
|
|
||||||
example: [{ value: "M" }, { value: "S" }, { value: "L" }],
|
|
||||||
})
|
|
||||||
sizes?: CreateSizeDTO[];
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@IsOptional()
|
|
||||||
@IsNotEmpty()
|
|
||||||
@ArrayMinSize(1)
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => CreateSizeDTO)
|
|
||||||
@ApiProperty({
|
|
||||||
type: "Array",
|
|
||||||
description: "the variation meterage of a category theme",
|
|
||||||
example: [{ value: "10" }, { value: "20" }, { value: "50" }],
|
|
||||||
})
|
|
||||||
meterages?: CreateMeterageDTO[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateCategoryVariantDTO extends PartialType(CreateCategoryThemeDTO) {}
|
export class UpdateCategoryVariantDTO extends PartialType(CreateCategoryThemeDTO) {}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class CategoryRepository extends BaseRepository<ICategory> {
|
|||||||
for (const category of categories) {
|
for (const category of categories) {
|
||||||
if (!category?.theme || !category?.variants.length) continue;
|
if (!category?.theme || !category?.variants.length) continue;
|
||||||
|
|
||||||
const theme = `${category?.theme}s`.toLowerCase(); // e.g., 'colors', 'sizes', 'meterages'
|
const theme = `${category?.theme}s`.toLowerCase();
|
||||||
|
|
||||||
if (!themeVariantsMap.has(theme)) {
|
if (!themeVariantsMap.has(theme)) {
|
||||||
themeVariantsMap.set(theme, new Set());
|
themeVariantsMap.set(theme, new Set());
|
||||||
|
|||||||
@@ -127,17 +127,20 @@ class CategoryService {
|
|||||||
createDto.title_en = slugify(createDto.title_en);
|
createDto.title_en = slugify(createDto.title_en);
|
||||||
|
|
||||||
const existTitle = await this.categoryRepository.findByTitle(createDto.title_en);
|
const existTitle = await this.categoryRepository.findByTitle(createDto.title_en);
|
||||||
|
|
||||||
const theme = await this.themeRepo.findById(createDto.themeId);
|
|
||||||
if (!theme) throw new BadRequestError(CommonMessage.NotFoundById);
|
|
||||||
|
|
||||||
if (existTitle) throw new BadRequestError(CategoryMessage.DuplicateTitle);
|
if (existTitle) throw new BadRequestError(CategoryMessage.DuplicateTitle);
|
||||||
|
|
||||||
|
let themeIdOrNull: any = null;
|
||||||
|
if (createDto.themeId) {
|
||||||
|
const themeDoc = await this.themeRepo.findById(createDto.themeId);
|
||||||
|
if (!themeDoc) throw new BadRequestError(CommonMessage.NotFoundById);
|
||||||
|
themeIdOrNull = themeDoc._id;
|
||||||
|
}
|
||||||
//if parent exist first set parent leaf false
|
//if parent exist first set parent leaf false
|
||||||
if (createDto.parent) {
|
if (createDto.parent) {
|
||||||
await this.categoryRepository.model.findByIdAndUpdate(createDto.parent, { leaf: false });
|
await this.categoryRepository.model.findByIdAndUpdate(createDto.parent, { leaf: false });
|
||||||
}
|
}
|
||||||
//we set the leaf to true
|
//we set the leaf to true
|
||||||
const category = await this.categoryRepository.model.create({ ...createDto, theme: theme._id });
|
const category = await this.categoryRepository.model.create({ ...createDto, theme: themeIdOrNull });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
message: CategoryMessage.Created,
|
message: CategoryMessage.Created,
|
||||||
@@ -388,14 +391,12 @@ class CategoryService {
|
|||||||
// get category variants
|
// get category variants
|
||||||
const categoryVariants = await this.categoryRepository.getCategoryVariants(categoryIds);
|
const categoryVariants = await this.categoryRepository.getCategoryVariants(categoryIds);
|
||||||
|
|
||||||
const colors = categoryVariants?.colors;
|
const themeValues = categoryVariants?.themeValues;
|
||||||
const sizes = categoryVariants?.sizes;
|
|
||||||
const meterages = categoryVariants?.meterages;
|
|
||||||
|
|
||||||
// fetch products from the category and its children
|
// fetch products from the category and its children
|
||||||
const { docs, count } = await this.productRepo.getProductsWithCategory(categoryIds, queries, userId);
|
const { docs, count } = await this.productRepo.getProductsWithCategory(categoryIds, queries, userId);
|
||||||
const products = docs.map((doc: IProduct) => ProductDTO.transformProduct(doc));
|
const products = docs.map((doc: IProduct) => ProductDTO.transformProduct(doc));
|
||||||
const filters = { attributes: catAttributes?.attributes, priceRange, colors, sizes, meterages };
|
const filters = { attributes: catAttributes?.attributes, priceRange, themeValues };
|
||||||
|
|
||||||
// fetch category breadcrumb
|
// fetch category breadcrumb
|
||||||
const breadcrumb = await this.getCategoryBreadcrumb(category._id.toString());
|
const breadcrumb = await this.getCategoryBreadcrumb(category._id.toString());
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ import { Types } from "mongoose";
|
|||||||
export interface IThemeValue {
|
export interface IThemeValue {
|
||||||
_id: Types.ObjectId;
|
_id: Types.ObjectId;
|
||||||
theme: Types.ObjectId;
|
theme: Types.ObjectId;
|
||||||
name: string;
|
name?: string;
|
||||||
value: string;
|
value: string | number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { IThemeValue } from "./Abstraction/IThemeValue";
|
|||||||
const themeValueSchema = new Schema<IThemeValue>(
|
const themeValueSchema = new Schema<IThemeValue>(
|
||||||
{
|
{
|
||||||
theme: { type: Schema.Types.ObjectId, ref: "Theme", required: true },
|
theme: { type: Schema.Types.ObjectId, ref: "Theme", required: true },
|
||||||
name: { type: String, required: true },
|
name: { type: String, required: false },
|
||||||
value: { type: Schema.Types.Mixed, required: true },
|
value: { type: Schema.Types.Mixed, required: true },
|
||||||
},
|
},
|
||||||
{ timestamps: true, toJSON: { virtuals: true, versionKey: false }, id: false },
|
{ timestamps: true, toJSON: { virtuals: true, versionKey: false }, id: false },
|
||||||
|
|||||||
@@ -109,10 +109,10 @@ class ThemeService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateThemeValue(updateDto: UpdateThemeValueDTO) {
|
async updateThemeValue(id: string, updateDto: UpdateThemeValueDTO) {
|
||||||
if (!isValidObjectId(updateDto.themeValueId)) throw new BadRequestError(CommonMessage.NotValidId);
|
if (!isValidObjectId(id)) throw new BadRequestError(CommonMessage.NotValidId);
|
||||||
|
|
||||||
const existingThemeValue = await this.themeValueRepository.findById(updateDto.themeValueId);
|
const existingThemeValue = await this.themeValueRepository.findById(id);
|
||||||
if (!existingThemeValue) throw new BadRequestError(CommonMessage.NotFoundById);
|
if (!existingThemeValue) throw new BadRequestError(CommonMessage.NotFoundById);
|
||||||
|
|
||||||
const updateData: Partial<{ name: string; value: string | number }> = {};
|
const updateData: Partial<{ name: string; value: string | number }> = {};
|
||||||
@@ -125,9 +125,7 @@ class ThemeService {
|
|||||||
updateData.value = updateDto.value;
|
updateData.value = updateDto.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedThemeValue = await this.themeValueRepository.model
|
const updatedThemeValue = await this.themeValueRepository.model.findByIdAndUpdate(id, updateData, { new: true }).populate("theme");
|
||||||
.findByIdAndUpdate(updateDto.themeValueId, updateData, { new: true })
|
|
||||||
.populate("theme");
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
message: CommonMessage.Updated,
|
message: CommonMessage.Updated,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { OrderItemDTO } from "./order.dto";
|
|||||||
import { OrdersStatus } from "../../../common/enums/order.enum";
|
import { OrdersStatus } from "../../../common/enums/order.enum";
|
||||||
import { TimeService } from "../../../utils/time.service";
|
import { TimeService } from "../../../utils/time.service";
|
||||||
import { PaymentDTO } from "../../payment/DTO/payment.dto";
|
import { PaymentDTO } from "../../payment/DTO/payment.dto";
|
||||||
|
import { ThemeValueDTO } from "../../product/DTO/product.dto";
|
||||||
import { UserDTO } from "../../user/DTO/user.dto";
|
import { UserDTO } from "../../user/DTO/user.dto";
|
||||||
import { IOrder } from "../models/Abstraction/IOrder";
|
import { IOrder } from "../models/Abstraction/IOrder";
|
||||||
|
|
||||||
@@ -54,6 +55,10 @@ export class UserOrderDTO {
|
|||||||
@Transform(({ value }) => TimeService.convertGregorianToPersian(new Date(value), true))
|
@Transform(({ value }) => TimeService.convertGregorianToPersian(new Date(value), true))
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
|
||||||
|
@Expose()
|
||||||
|
@Type(() => ThemeValueDTO)
|
||||||
|
themeValue: ThemeValueDTO;
|
||||||
|
|
||||||
public static transformOrder(data: IOrder): UserOrderDTO {
|
public static transformOrder(data: IOrder): UserOrderDTO {
|
||||||
const OrderDTO = plainToClass(UserOrderDTO, data, {
|
const OrderDTO = plainToClass(UserOrderDTO, data, {
|
||||||
excludeExtraneousValues: true,
|
excludeExtraneousValues: true,
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class OrderRepository extends BaseRepository<IOrder> {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return this.model.aggregate([
|
const orders = await this.model.aggregate([
|
||||||
{
|
{
|
||||||
$match: matchQuery,
|
$match: matchQuery,
|
||||||
},
|
},
|
||||||
@@ -207,6 +207,20 @@ class OrderRepository extends BaseRepository<IOrder> {
|
|||||||
{
|
{
|
||||||
$unwind: "$shipmentItemVariant",
|
$unwind: "$shipmentItemVariant",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: "themevalues",
|
||||||
|
localField: "shipmentItemVariant.themeValue",
|
||||||
|
foreignField: "_id",
|
||||||
|
as: "shipmentItemVariant.themeValue",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$unwind: {
|
||||||
|
path: "$shipmentItemVariant.themeValue",
|
||||||
|
preserveNullAndEmptyArrays: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
$group: {
|
$group: {
|
||||||
_id: "$orderItems._id",
|
_id: "$orderItems._id",
|
||||||
@@ -274,6 +288,7 @@ class OrderRepository extends BaseRepository<IOrder> {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
return orders;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserOrderDetail(orderId: number, userId: string) {
|
async getUserOrderDetail(orderId: number, userId: string) {
|
||||||
@@ -391,43 +406,15 @@ class OrderRepository extends BaseRepository<IOrder> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "orderItems.shipmentItems.variant.color",
|
localField: "orderItems.shipmentItems.variant.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "orderItems.shipmentItems.variant.color",
|
as: "orderItems.shipmentItems.variant.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$orderItems.shipmentItems.variant.color",
|
path: "$orderItems.shipmentItems.variant.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "orderItems.shipmentItems.variant.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "orderItems.shipmentItems.variant.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$orderItems.shipmentItems.variant.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "orderItems.shipmentItems.variant.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "orderItems.shipmentItems.variant.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$orderItems.shipmentItems.variant.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -566,43 +553,15 @@ class OrderItemRepo extends BaseRepository<IOrderItem> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "shipmentItems.variant.color",
|
localField: "shipmentItems.variant.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "shipmentItems.variant.color",
|
as: "shipmentItems.variant.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$shipmentItems.variant.color",
|
path: "$shipmentItems.variant.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "shipmentItems.variant.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "shipmentItems.variant.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$shipmentItems.variant.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "shipmentItems.variant.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "shipmentItems.variant.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$shipmentItems.variant.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1521,43 +1480,15 @@ class OrderItemRepo extends BaseRepository<IOrderItem> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "shipmentItems.variant.color",
|
localField: "shipmentItems.variant.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "shipmentItems.variant.color",
|
as: "shipmentItems.variant.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$shipmentItems.variant.color",
|
path: "$shipmentItems.variant.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "shipmentItems.variant.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "shipmentItems.variant.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$shipmentItems.variant.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "shipmentItems.variant.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "shipmentItems.variant.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$shipmentItems.variant.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1730,43 +1661,15 @@ class OrderItemRepo extends BaseRepository<IOrderItem> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "shipmentItems.variant.color",
|
localField: "shipmentItems.variant.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "shipmentItems.variant.color",
|
as: "shipmentItems.variant.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$shipmentItems.variant.color",
|
path: "$shipmentItems.variant.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "shipmentItems.variant.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "shipmentItems.variant.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$shipmentItems.variant.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "shipmentItems.variant.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "shipmentItems.variant.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$shipmentItems.variant.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { IsString } from "class-validator";
|
|||||||
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
import { ApiProperty } from "../../../common/decorator/swggerDocs";
|
||||||
import { ProductStatus } from "../../../common/enums/product.enum";
|
import { ProductStatus } from "../../../common/enums/product.enum";
|
||||||
import { BrandDTO } from "../../brand/DTO/brand.dto";
|
import { BrandDTO } from "../../brand/DTO/brand.dto";
|
||||||
import { CategoryTreeDTO, ColorDTO, Size_MeterageDTO } from "../../category/DTO/category.dto";
|
import { CategoryTreeDTO } from "../../category/DTO/category.dto";
|
||||||
import { ShipmentMethodDTO } from "../../shipment/DTO/shipment.dto";
|
import { ShipmentMethodDTO } from "../../shipment/DTO/shipment.dto";
|
||||||
import { ShopDTO } from "../../shop/DTO/shop.dto";
|
import { ShopDTO } from "../../shop/DTO/shop.dto";
|
||||||
import { WarrantyDTO } from "../../warranty/DTO/warranty.dto";
|
import { WarrantyDTO } from "../../warranty/DTO/warranty.dto";
|
||||||
@@ -83,6 +83,22 @@ class SaleFormatDTO {
|
|||||||
|
|
||||||
//#################################
|
//#################################
|
||||||
|
|
||||||
|
export class ThemeValueDTO {
|
||||||
|
@Expose()
|
||||||
|
_id: string;
|
||||||
|
|
||||||
|
@Expose()
|
||||||
|
theme: string;
|
||||||
|
|
||||||
|
@Expose()
|
||||||
|
name?: string;
|
||||||
|
|
||||||
|
@Expose()
|
||||||
|
value: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
|
||||||
export class ProductDetailVariantDTO {
|
export class ProductDetailVariantDTO {
|
||||||
@Expose()
|
@Expose()
|
||||||
_id: string;
|
_id: string;
|
||||||
@@ -126,16 +142,8 @@ export class ProductDetailVariantDTO {
|
|||||||
warranty: WarrantyDTO;
|
warranty: WarrantyDTO;
|
||||||
|
|
||||||
@Expose()
|
@Expose()
|
||||||
@Type(() => ColorDTO)
|
@Type(() => ThemeValueDTO)
|
||||||
color?: ColorDTO;
|
themeValue?: ThemeValueDTO;
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@Type(() => Size_MeterageDTO)
|
|
||||||
size?: Size_MeterageDTO;
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@Type(() => Size_MeterageDTO)
|
|
||||||
meterage?: Size_MeterageDTO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#################################
|
//#################################
|
||||||
@@ -282,16 +290,8 @@ export class ProductVariantDTO {
|
|||||||
saleFormat: SaleFormatDTO;
|
saleFormat: SaleFormatDTO;
|
||||||
|
|
||||||
@Expose()
|
@Expose()
|
||||||
@Type(() => ColorDTO)
|
@Type(() => ThemeValueDTO)
|
||||||
color?: ColorDTO;
|
themeValue?: ThemeValueDTO;
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@Type(() => Size_MeterageDTO)
|
|
||||||
size?: Size_MeterageDTO;
|
|
||||||
|
|
||||||
@Expose()
|
|
||||||
@Type(() => Size_MeterageDTO)
|
|
||||||
meterage?: Size_MeterageDTO;
|
|
||||||
|
|
||||||
public static transformProduct(data: IProductVariant): ProductVariantDTO {
|
public static transformProduct(data: IProductVariant): ProductVariantDTO {
|
||||||
const productVariantDTO = plainToInstance(ProductVariantDTO, data, {
|
const productVariantDTO = plainToInstance(ProductVariantDTO, data, {
|
||||||
|
|||||||
@@ -117,43 +117,15 @@ export class IncredibleOffersRepo extends BaseRepository<IncredibleOffers> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "product.default_variant.color",
|
localField: "product.default_variant.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "product.default_variant.color",
|
as: "product.default_variant.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$product.default_variant.color",
|
path: "$product.default_variant.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "product.default_variant.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "product.default_variant.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$product.default_variant.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "product.default_variant.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "product.default_variant.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$product.variant.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -251,43 +223,15 @@ export class IncredibleOffersRepo extends BaseRepository<IncredibleOffers> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "variant.color",
|
localField: "variant.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "variant.color",
|
as: "variant.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variant.color",
|
path: "$variant.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "variant.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variant.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variant.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "variant.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variant.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variant.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1320,13 +1320,13 @@ export class ProductRepository extends BaseRepository<IProduct> {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
$match: {
|
// $match: {
|
||||||
$expr: {
|
// $expr: {
|
||||||
$or: [{ $gt: [{ $size: "$variants" }, 0] }, { $eq: ["$category.theme", "noColor_noSize"] }],
|
// $or: [{ $gt: [{ $size: "$variants" }, 0] }, { $eq: ["$category.theme", "noColor_noSize"] }],
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variants",
|
path: "$variants",
|
||||||
@@ -1371,46 +1371,19 @@ export class ProductRepository extends BaseRepository<IProduct> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themevalues",
|
||||||
localField: "variants.color",
|
localField: "variants.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "variants.color",
|
as: "variants.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variants.color",
|
path: "$variants.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "variants.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "variants.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$group: {
|
$group: {
|
||||||
_id: "$_id",
|
_id: "$_id",
|
||||||
@@ -1774,48 +1747,22 @@ export class ProductRepository extends BaseRepository<IProduct> {
|
|||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "variants.color",
|
localField: "variants.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "variants.color",
|
as: "variants.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variants.color",
|
path: "$variants.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "variants.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "variants.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$group: {
|
$group: {
|
||||||
_id: "$_id",
|
_id: "$_id",
|
||||||
@@ -2064,43 +2011,15 @@ export class ProductRepository extends BaseRepository<IProduct> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "variants.color",
|
localField: "variants.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "variants.color",
|
as: "variants.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variants.color",
|
path: "$variants.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "variants.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "variants.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -2338,45 +2257,18 @@ export class ProductRepository extends BaseRepository<IProduct> {
|
|||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "variants.color",
|
localField: "variants.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "variants.color",
|
as: "variants.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variants.color",
|
path: "$variants.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "variants.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "variants.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -2513,45 +2405,18 @@ export class ProductRepository extends BaseRepository<IProduct> {
|
|||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "variants.color",
|
localField: "variants.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "variants.color",
|
as: "variants.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variants.color",
|
path: "$variants.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "variants.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "variants.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -2674,45 +2539,18 @@ export class ProductRepository extends BaseRepository<IProduct> {
|
|||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "variants.color",
|
localField: "variants.themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "variants.color",
|
as: "variants.themeValue",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$variants.color",
|
path: "$variants.themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "variants.size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "variants.meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "variants.meterage",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$variants.meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -86,28 +86,13 @@ export class ProductVariantRepository extends BaseRepository<IProductVariant> {
|
|||||||
{
|
{
|
||||||
$unwind: "$category",
|
$unwind: "$category",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "color",
|
localField: "themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "color",
|
as: "themeValue",
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "meterage",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -120,22 +105,11 @@ export class ProductVariantRepository extends BaseRepository<IProductVariant> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$color",
|
path: "$themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$addFields: {
|
$addFields: {
|
||||||
product_id: "$product._id",
|
product_id: "$product._id",
|
||||||
@@ -259,28 +233,13 @@ export class ProductVariantRepository extends BaseRepository<IProductVariant> {
|
|||||||
{
|
{
|
||||||
$unwind: "$category",
|
$unwind: "$category",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "color",
|
localField: "themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "color",
|
as: "themeValue",
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "meterage",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -293,22 +252,11 @@ export class ProductVariantRepository extends BaseRepository<IProductVariant> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$color",
|
path: "$themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$addFields: {
|
$addFields: {
|
||||||
product_id: "$product._id",
|
product_id: "$product._id",
|
||||||
@@ -400,28 +348,13 @@ export class ProductVariantRepository extends BaseRepository<IProductVariant> {
|
|||||||
{
|
{
|
||||||
$unwind: "$category",
|
$unwind: "$category",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$lookup: {
|
$lookup: {
|
||||||
from: "colors",
|
from: "themeValues",
|
||||||
localField: "color",
|
localField: "themeValue",
|
||||||
foreignField: "_id",
|
foreignField: "_id",
|
||||||
as: "color",
|
as: "themeValue",
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "sizes",
|
|
||||||
localField: "size",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "size",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$lookup: {
|
|
||||||
from: "meterages",
|
|
||||||
localField: "meterage",
|
|
||||||
foreignField: "_id",
|
|
||||||
as: "meterage",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -434,22 +367,11 @@ export class ProductVariantRepository extends BaseRepository<IProductVariant> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$unwind: {
|
$unwind: {
|
||||||
path: "$color",
|
path: "$themeValue",
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$size",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
$unwind: {
|
|
||||||
path: "$meterage",
|
|
||||||
preserveNullAndEmptyArrays: true,
|
preserveNullAndEmptyArrays: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
$addFields: {
|
$addFields: {
|
||||||
product_id: "$product._id",
|
product_id: "$product._id",
|
||||||
|
|||||||
@@ -564,14 +564,14 @@ class ProductService {
|
|||||||
// Check if a variant with the same themeValue already exists
|
// Check if a variant with the same themeValue already exists
|
||||||
// const query: FilterQuery<IProductVariant> = { product: product._id };
|
// const query: FilterQuery<IProductVariant> = { product: product._id };
|
||||||
|
|
||||||
// if (addVariantDto.themeValueId) {
|
if (addVariantDto.themeValueId) {
|
||||||
// const existingVariant = await this.productVariantRepo.model.findOne({
|
const existingVariant = await this.productVariantRepo.model.findOne({
|
||||||
// product: product._id,
|
product: product._id,
|
||||||
// themeValue: addVariantDto.themeValueId,
|
themeValue: addVariantDto.themeValueId,
|
||||||
// });
|
});
|
||||||
|
|
||||||
// if (existingVariant) throw new BadRequestError(ProductMessage.VariantAlreadyExists);
|
if (existingVariant) throw new BadRequestError(ProductMessage.VariantAlreadyExists);
|
||||||
// }
|
}
|
||||||
|
|
||||||
const productVariant = await this.createProductVariant(addVariantDto, product._id, shop._id.toString(), session);
|
const productVariant = await this.createProductVariant(addVariantDto, product._id, shop._id.toString(), session);
|
||||||
|
|
||||||
@@ -961,9 +961,7 @@ class ProductService {
|
|||||||
async getProductDetails(productId: number) {
|
async getProductDetails(productId: number) {
|
||||||
await this.validateProduct(productId);
|
await this.validateProduct(productId);
|
||||||
const docs = await this.productRepo.getProductDetails(productId);
|
const docs = await this.productRepo.getProductDetails(productId);
|
||||||
if ((!docs?.[0]?.variants || docs?.[0]?.variants.length === 0) && docs?.[0]?.category.theme !== "noColor_noSize") {
|
|
||||||
throw new BadRequestError(CommonMessage.NotEnoughVariant);
|
|
||||||
}
|
|
||||||
const product = ProductDTO.transformProduct(docs[0]);
|
const product = ProductDTO.transformProduct(docs[0]);
|
||||||
const stats = await this.commentRepo.getProductStats(productId);
|
const stats = await this.commentRepo.getProductStats(productId);
|
||||||
const categoryPath = await this.categoryRepo.getCategoryPath(product.category._id.toString());
|
const categoryPath = await this.categoryRepo.getCategoryPath(product.category._id.toString());
|
||||||
|
|||||||
Reference in New Issue
Block a user