diff --git a/src/modules/orders/entities/order-item.entity.ts b/src/modules/orders/entities/order-item.entity.ts index 0541125..278da53 100644 --- a/src/modules/orders/entities/order-item.entity.ts +++ b/src/modules/orders/entities/order-item.entity.ts @@ -1,7 +1,8 @@ -import { Entity, Index, ManyToOne, Property } from '@mikro-orm/core'; +import { Entity, Enum, ManyToOne, Property } from '@mikro-orm/core'; import { BaseEntity } from '../../../common/entities/base.entity'; import { Order } from './order.entity'; import { Variant } from '../../products/entities/variant.entity'; +import { OrderItemStatus } from '../enum/order-item.enum'; @Entity({ tableName: 'order_items' }) export class OrderItem extends BaseEntity { @@ -22,4 +23,7 @@ export class OrderItem extends BaseEntity { @Property({ type: 'decimal', precision: 10, scale: 0 }) totalPrice!: number; + + @Enum(() => OrderItemStatus) + status: OrderItemStatus = OrderItemStatus.normal; } diff --git a/src/modules/orders/enum/order-item.enum.ts b/src/modules/orders/enum/order-item.enum.ts new file mode 100644 index 0000000..45062d9 --- /dev/null +++ b/src/modules/orders/enum/order-item.enum.ts @@ -0,0 +1,5 @@ +export enum OrderItemStatus { + normal = 'normal', + needConfirmation = 'needConfirmation', + confirmed = 'confirmed' +} \ No newline at end of file diff --git a/src/modules/orders/interface/order.interface.ts b/src/modules/orders/interface/order.interface.ts index 01b62ee..4072900 100644 --- a/src/modules/orders/interface/order.interface.ts +++ b/src/modules/orders/interface/order.interface.ts @@ -20,6 +20,8 @@ export enum OrderStatus { SHIPPED = 'shipped', COMPLETED = 'completed', CANCELED = 'canceled', + NEED_CONFIRMATION = 'needConfirmation', + CONFIRMED = 'confirmed', } export interface OrderCouponDetail { diff --git a/src/modules/orders/providers/orders.service.ts b/src/modules/orders/providers/orders.service.ts index f3bdc7a..5ddb028 100644 --- a/src/modules/orders/providers/orders.service.ts +++ b/src/modules/orders/providers/orders.service.ts @@ -25,6 +25,7 @@ import { UserService } from 'src/modules/users/providers/user.service'; import { ShopService } from 'src/modules/shops/providers/shops.service'; import { DeliveryService } from 'src/modules/delivery/providers/delivery.service'; import { PaymentMethodService } from 'src/modules/payments/services/payment-method.service'; +import { OrderItemStatus } from '../enum/order-item.enum'; type OrderItemData = { variant: Variant; quantity: number; unitPrice: number; discount: number }; @@ -102,6 +103,7 @@ export class OrdersService { unitPrice, discount, totalPrice, + status: OrderItemStatus.normal, }); em.persist(orderItem); diff --git a/src/modules/products/dto/create-product.dto.ts b/src/modules/products/dto/create-product.dto.ts index cb58653..7a2fdfc 100644 --- a/src/modules/products/dto/create-product.dto.ts +++ b/src/modules/products/dto/create-product.dto.ts @@ -14,6 +14,8 @@ import { ValidateNested, } from 'class-validator'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { PricingType } from '../enum/pricing.enum'; +import { PurchaseUnit } from '../enum/unit.enum'; export class CreateVariantDto { @IsOptional() @@ -78,13 +80,6 @@ export class CreateProductDto { desc?: string; - @IsOptional() - @IsNumber() - @Min(0) - @Type(() => Number) - @ApiPropertyOptional({ example: 120000 }) - price?: number; - @IsOptional() @IsBoolean() @ApiPropertyOptional({ example: true }) @@ -111,6 +106,11 @@ export class CreateProductDto { @Type(() => Boolean) isSpecialOffer?: boolean; + @IsBoolean() + @ApiProperty({ example: false }) + @Type(() => Boolean) + needAdminAcceptance: boolean; + @IsOptional() @IsInt() @Min(0) @@ -124,4 +124,28 @@ export class CreateProductDto { @Type(() => Number) @ApiPropertyOptional({ description: 'Maximum quantity per order; omit or null for unlimited', example: 5 }) maxPurchaseQuantity?: number | null; + + @IsOptional() + @IsString() + @ApiPropertyOptional({ example: '1000' }) + @Type(() => String) + purchasePitch?: string | null; + + @IsNotEmpty() + @IsEnum(PricingType) + @ApiProperty({ example: PricingType.FIXED }) + pricingType: PricingType; + + @IsOptional() + @IsEnum(PurchaseUnit) + @ApiPropertyOptional({ example: PurchaseUnit.NUMBER }) + purchaseUnit?: PurchaseUnit; + + @IsOptional() + @IsInt() + @Min(1) + @Type(() => Number) + @ApiPropertyOptional({ description: 'Minimum quantity per order; omit or null for unlimited', example: 1 }) + minPurchaseQuantity?: number | null; + } diff --git a/src/modules/products/entities/product.entity.ts b/src/modules/products/entities/product.entity.ts index d73a75f..61316ea 100644 --- a/src/modules/products/entities/product.entity.ts +++ b/src/modules/products/entities/product.entity.ts @@ -1,10 +1,12 @@ -import { Cascade, Collection, Entity, Index, ManyToOne, OneToMany, Property } from '@mikro-orm/core'; +import { Cascade, Collection, Entity, Enum, Index, ManyToOne, OneToMany, Property } from '@mikro-orm/core'; import { Category } from './category.entity'; import { BaseEntity } from '../../../common/entities/base.entity'; import { Shop } from '../../../modules/shops/entities/shop.entity'; import { Review } from 'src/modules/review/entities/review.entity'; import { Favorite } from './favorite.entity'; import { Variant } from './variant.entity'; +import { PricingType } from '../enum/pricing.enum'; +import { PurchaseUnit } from '../enum/unit.enum'; @Entity({ tableName: 'products' }) @Index({ properties: ['shop', 'isActive'] }) @@ -54,10 +56,33 @@ export class Product extends BaseEntity { @Property({ type: 'boolean', default: false }) isSpecialOffer: boolean = false; - @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true }) - price?: number; /** Maximum quantity per order; null means unlimited */ @Property({ type: 'int', nullable: true, default: null }) maxPurchaseQuantity: number | null = null; + + @Property({ type: 'int', nullable: true, default: null }) + minPurchaseQuantity: number | null = null; + + // برای کالا هایی مثل گوشت متغیر میشه + @Enum(() => PricingType) + pricingType: PricingType = PricingType.FIXED; + + @Enum(() => PurchaseUnit) + purchaseUnit: PurchaseUnit = PurchaseUnit.NUMBER; + + // گام جلو رفتن برای برای کالا های مقداری + @Property({ + type: 'decimal', + precision: 10, + scale: 3, + nullable: true, + default: null, + }) + purchasePitch?: string | null = null; + + // + @Property({ type: 'boolean', default: false }) + needAdminAcceptance: boolean = false; + } diff --git a/src/modules/products/enum/pricing.enum.ts b/src/modules/products/enum/pricing.enum.ts new file mode 100644 index 0000000..daff3db --- /dev/null +++ b/src/modules/products/enum/pricing.enum.ts @@ -0,0 +1,4 @@ +export enum PricingType { + FIXED = 'fixed', + VARIABLE = 'variable', +} \ No newline at end of file diff --git a/src/modules/products/enum/unit.enum.ts b/src/modules/products/enum/unit.enum.ts new file mode 100644 index 0000000..d65cba9 --- /dev/null +++ b/src/modules/products/enum/unit.enum.ts @@ -0,0 +1,9 @@ +export enum PurchaseUnit { + NUMBER = 'number', + KILOGRAM = 'kilogram', + GRAM = 'gram', + CENTIMETER = 'centimeter', + METER = 'meter', + MILLILITER = 'milliliter', + LITER = 'liter', +} \ No newline at end of file diff --git a/src/modules/products/providers/product.service.ts b/src/modules/products/providers/product.service.ts index 3ff55ff..a47483f 100644 --- a/src/modules/products/providers/product.service.ts +++ b/src/modules/products/providers/product.service.ts @@ -13,6 +13,8 @@ import { ShopService } from 'src/modules/shops/providers/shops.service'; import { CategoryService } from './category.service'; import { User } from 'src/modules/users/entities/user.entity'; import { FavoriteRepository } from '../repositories/favorite.repository'; +import { PurchaseUnit } from '../enum/unit.enum'; +import { PricingType } from '../enum/pricing.enum'; @Injectable() export class ProductService { @@ -46,10 +48,14 @@ export class ProductService { // map single-title/content DTO to localized fields title: rest.title, attribute: rest.attribute, - + needAdminAcceptance: rest.needAdminAcceptance , images: rest.images ?? undefined, shop: shop, category: category, + pricingType: rest.pricingType , + purchaseUnit: rest.purchaseUnit ?? PurchaseUnit.NUMBER, + minPurchaseQuantity: rest.minPurchaseQuantity ?? null, + purchasePitch: rest.purchasePitch ?? null, }; const product = em.create(Product, data); diff --git a/src/seeders/products.seeder.ts b/src/seeders/products.seeder.ts index 04d2caf..2582ede 100644 --- a/src/seeders/products.seeder.ts +++ b/src/seeders/products.seeder.ts @@ -4,6 +4,8 @@ import type { Shop } from '../modules/shops/entities/shop.entity'; import type { Category } from '../modules/products/entities/category.entity'; import { productsData } from './data/products.data'; import { Variant } from 'src/modules/products/entities/variant.entity'; +import { PurchaseUnit } from 'src/modules/products/enum/unit.enum'; +import { PricingType } from 'src/modules/products/enum/pricing.enum'; export class ProductsSeeder { async run( @@ -55,6 +57,9 @@ export class ProductsSeeder { score: productData.score ?? 0, images: productData.images, isSpecialOffer: productData.isSpecialOffer ?? false, + pricingType: PricingType.FIXED, + purchaseUnit: PurchaseUnit.NUMBER, + needAdminAcceptance: false, }); productData.varrinats.forEach(variant => {