add new field to product

This commit is contained in:
2026-06-28 09:44:09 +03:30
parent 4584a0adf6
commit 9b24061b92
10 changed files with 98 additions and 12 deletions
@@ -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;
}
@@ -0,0 +1,5 @@
export enum OrderItemStatus {
normal = 'normal',
needConfirmation = 'needConfirmation',
confirmed = 'confirmed'
}
@@ -20,6 +20,8 @@ export enum OrderStatus {
SHIPPED = 'shipped',
COMPLETED = 'completed',
CANCELED = 'canceled',
NEED_CONFIRMATION = 'needConfirmation',
CONFIRMED = 'confirmed',
}
export interface OrderCouponDetail {
@@ -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);
+31 -7
View File
@@ -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;
}
@@ -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;
}
@@ -0,0 +1,4 @@
export enum PricingType {
FIXED = 'fixed',
VARIABLE = 'variable',
}
+9
View File
@@ -0,0 +1,9 @@
export enum PurchaseUnit {
NUMBER = 'number',
KILOGRAM = 'kilogram',
GRAM = 'gram',
CENTIMETER = 'centimeter',
METER = 'meter',
MILLILITER = 'milliliter',
LITER = 'liter',
}
@@ -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);
+5
View File
@@ -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 => {