diff --git a/src/seeders/categories.seeder.ts b/src/seeders/categories.seeder.ts index 28048fb..e4e80eb 100644 --- a/src/seeders/categories.seeder.ts +++ b/src/seeders/categories.seeder.ts @@ -2,24 +2,19 @@ import type { EntityManager } from '@mikro-orm/core'; import { Category } from '../modules/product/entities/category.entity'; import { categoriesData } from './data/categories.data'; - export class CategoriesSeeder { - - async run(em: EntityManager): Promise> { const categoriesMap = new Map(); for (const catData of categoriesData) { - const category = em.create(Category, { title: catData.title, isActive: true, + order: catData.order ?? null, }); em.persist(category); - - categoriesMap.set(`${catData.title}`, category); - + categoriesMap.set(catData.title, category); } await em.flush(); diff --git a/src/seeders/data/categories.data.ts b/src/seeders/data/categories.data.ts index ad97897..ae7d23e 100644 --- a/src/seeders/data/categories.data.ts +++ b/src/seeders/data/categories.data.ts @@ -1,9 +1,13 @@ - export interface CategoryData { title: string; + order?: number; } export const categoriesData: CategoryData[] = [ - { title: 'چاپ', }, - { title: 'صحافی', }, -]; \ No newline at end of file + { title: 'کارت ویزیت', order: 1 }, + { title: 'بروشور', order: 2 }, + { title: 'کاتالوگ', order: 3 }, + { title: 'پوستر', order: 4 }, + { title: 'تراکت', order: 5 }, + { title: 'بنر', order: 6 }, +]; diff --git a/src/seeders/data/product-field-options.data.ts b/src/seeders/data/product-field-options.data.ts index a4544d7..ac9e56c 100644 --- a/src/seeders/data/product-field-options.data.ts +++ b/src/seeders/data/product-field-options.data.ts @@ -1,26 +1,11 @@ - +/** + * Product field options are defined inline in `product-field.data.ts` + * (per category) and created by `ProductsFieldsSeeder`. + * Kept for backward compatibility with `FieldOptionSeeder`. + */ export interface AttributeValueData { value: string; - attributeName: string + attributeName: string; } -export const attributeValueData: AttributeValueData[] = [ - { - attributeName: 'گراماژ کاغذ', - value: '70', - - }, - { - attributeName: 'گراماژ کاغذ', - value: '80', - - }, - { - attributeName: 'رنگ', - value: 'آبی', - }, - { - attributeName: 'رنگ', - value: 'قرمز', - }, -] +export const attributeValueData: AttributeValueData[] = []; diff --git a/src/seeders/data/product-field.data.ts b/src/seeders/data/product-field.data.ts index 27a0b5b..4e26f61 100644 --- a/src/seeders/data/product-field.data.ts +++ b/src/seeders/data/product-field.data.ts @@ -1,29 +1,122 @@ -import { FieldType } from "src/modules/form-builder/interface/print"; +import { FieldType } from 'src/modules/form-builder/interface/print'; -export interface AttributeData { - - - name: string; - isRequired: boolean; - type: FieldType, +export interface ProductFieldOptionData { + value: string; + order?: number; } -export const fieldsDataData: AttributeData[] = [ +export interface ProductFieldData { + name: string; + isRequired: boolean; + type: FieldType; + order?: number; + multiple?: boolean; + options?: ProductFieldOptionData[]; +} +/** Size (and related) form-builder fields per product category. */ +export const productFieldsByCategory: Record = { + 'کارت ویزیت': [ + { + name: 'اندازه', + type: FieldType.select, + isRequired: true, + order: 1, + options: [ + { value: '۹×۵ سانتی‌متر', order: 1 }, + { value: '۸٫۵×۵٫۵ سانتی‌متر', order: 2 }, + { value: '۹×۶ سانتی‌متر', order: 3 }, + { value: 'سفارشی', order: 4 }, + ], + }, + ], + بروشور: [ + { + name: 'اندازه', + type: FieldType.select, + isRequired: true, + order: 1, + options: [ + { value: 'A4', order: 1 }, + { value: 'A5', order: 2 }, + { value: 'A3', order: 3 }, + { value: 'سفارشی', order: 4 }, + ], + }, + ], + کاتالوگ: [ + { + name: 'اندازه', + type: FieldType.select, + isRequired: true, + order: 1, + options: [ + { value: 'A4', order: 1 }, + { value: 'A5', order: 2 }, + { value: 'وزیری', order: 3 }, + { value: 'رقعی', order: 4 }, + { value: 'سفارشی', order: 5 }, + ], + }, + ], + پوستر: [ + { + name: 'اندازه', + type: FieldType.select, + isRequired: true, + order: 1, + options: [ + { value: 'A3', order: 1 }, + { value: 'A2', order: 2 }, + { value: 'A1', order: 3 }, + { value: '۵۰×۷۰ سانتی‌متر', order: 4 }, + { value: '۷۰×۱۰۰ سانتی‌متر', order: 5 }, + { value: 'سفارشی', order: 6 }, + ], + }, + ], + تراکت: [ + { + name: 'اندازه', + type: FieldType.select, + isRequired: true, + order: 1, + options: [ + { value: 'A6', order: 1 }, + { value: 'A5', order: 2 }, + { value: 'A4', order: 3 }, + { value: 'سفارشی', order: 4 }, + ], + }, + ], + بنر: [ + { + name: 'اندازه', + type: FieldType.select, + isRequired: true, + order: 1, + options: [ + { value: '۱×۱ متر', order: 1 }, + { value: '۲×۱ متر', order: 2 }, + { value: '۳×۱ متر', order: 3 }, + { value: '۳×۲ متر', order: 4 }, + { value: 'سفارشی', order: 5 }, + ], + }, + ], +}; +/** Fallback when a category has no specific field definition. */ +export const defaultProductFields: ProductFieldData[] = [ { - name: 'گراماژ کاغذ', - type: FieldType.radio, - isRequired: true, - }, - { - name: 'رنگ', + name: 'اندازه', type: FieldType.select, isRequired: true, + order: 1, + options: [ + { value: 'A4', order: 1 }, + { value: 'A5', order: 2 }, + { value: 'سفارشی', order: 3 }, + ], }, - { - name: 'ویژگی نوشتنی', - type: FieldType.text, - isRequired: true, - }, -] +]; diff --git a/src/seeders/data/product.data.ts b/src/seeders/data/product.data.ts index afa8740..be27704 100644 --- a/src/seeders/data/product.data.ts +++ b/src/seeders/data/product.data.ts @@ -1,25 +1,169 @@ - export interface productData { title: string; isActive: boolean; - categoryTitle: string, + categoryTitle: string; images: string[]; desc: string; + order?: number; } +const PLACEHOLDER_IMAGE = + 'https://dmenu.danakcorp.com/uploads/images/product/product_1715711043900.png'; + export const productsData: productData[] = [ + // کارت ویزیت { - title: 'کارت ویزیت', - desc: 'توضیح کار ویزیت', - categoryTitle: 'چاپ', + title: 'لمینت', + desc: 'کارت ویزیت با روکش لمینت', + categoryTitle: 'کارت ویزیت', isActive: true, - images: ["https://dmenu.danakcorp.com/uploads/images/product/product_1715711043900.png"], + order: 1, + images: [PLACEHOLDER_IMAGE], }, { - title: 'بروشور', - desc: 'توضیح ', - categoryTitle: 'چاپ', + title: 'مخملی', + desc: 'کارت ویزیت با روکش مخملی', + categoryTitle: 'کارت ویزیت', isActive: true, - images: ["https://dmenu.danakcorp.com/uploads/images/product/product_1715711043900.png"], - } -] + order: 2, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'سلفون مات', + desc: 'کارت ویزیت با روکش سلفون مات', + categoryTitle: 'کارت ویزیت', + isActive: true, + order: 3, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'سلفون براق', + desc: 'کارت ویزیت با روکش سلفون براق', + categoryTitle: 'کارت ویزیت', + isActive: true, + order: 4, + images: [PLACEHOLDER_IMAGE], + }, + + // بروشور + { + title: 'دو لت', + desc: 'بروشور دو لت', + categoryTitle: 'بروشور', + isActive: true, + order: 1, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'سه لت', + desc: 'بروشور سه لت', + categoryTitle: 'بروشور', + isActive: true, + order: 2, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'چهار لت', + desc: 'بروشور چهار لت', + categoryTitle: 'بروشور', + isActive: true, + order: 3, + images: [PLACEHOLDER_IMAGE], + }, + + // کاتالوگ + { + title: 'جلد نرم', + desc: 'کاتالوگ با جلد نرم', + categoryTitle: 'کاتالوگ', + isActive: true, + order: 1, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'جلد سخت', + desc: 'کاتالوگ با جلد سخت', + categoryTitle: 'کاتالوگ', + isActive: true, + order: 2, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'سیمی', + desc: 'کاتالوگ با صحافی سیمی', + categoryTitle: 'کاتالوگ', + isActive: true, + order: 3, + images: [PLACEHOLDER_IMAGE], + }, + + // پوستر + { + title: 'گلاسه', + desc: 'پوستر گلاسه', + categoryTitle: 'پوستر', + isActive: true, + order: 1, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'کتان', + desc: 'پوستر کتان', + categoryTitle: 'پوستر', + isActive: true, + order: 2, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'فوم برد', + desc: 'پوستر فوم برد', + categoryTitle: 'پوستر', + isActive: true, + order: 3, + images: [PLACEHOLDER_IMAGE], + }, + + // تراکت + { + title: 'یک رو', + desc: 'تراکت چاپ یک رو', + categoryTitle: 'تراکت', + isActive: true, + order: 1, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'دو رو', + desc: 'تراکت چاپ دو رو', + categoryTitle: 'تراکت', + isActive: true, + order: 2, + images: [PLACEHOLDER_IMAGE], + }, + + // بنر + { + title: 'فلکس', + desc: 'بنر فلکس', + categoryTitle: 'بنر', + isActive: true, + order: 1, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'مش', + desc: 'بنر مش', + categoryTitle: 'بنر', + isActive: true, + order: 2, + images: [PLACEHOLDER_IMAGE], + }, + { + title: 'استیکر', + desc: 'بنر استیکر', + categoryTitle: 'بنر', + isActive: true, + order: 3, + images: [PLACEHOLDER_IMAGE], + }, +]; diff --git a/src/seeders/product-fields.seeder.ts b/src/seeders/product-fields.seeder.ts index 66b6bb3..2cbe41b 100644 --- a/src/seeders/product-fields.seeder.ts +++ b/src/seeders/product-fields.seeder.ts @@ -1,30 +1,46 @@ import type { EntityManager } from '@mikro-orm/core'; import { Product } from '../modules/product/entities/product.entity'; -import { fieldsDataData } from './data/product-field.data'; +import { + defaultProductFields, + productFieldsByCategory, +} from './data/product-field.data'; import { Field } from 'src/modules/form-builder/entities/field.entity'; +import { FieldOption } from 'src/modules/form-builder/entities/field-option.entity'; import { EntityType } from 'src/modules/form-builder/interface/print'; -// import { Attribute } from 'src/modules/product/entities/attribute.entity'; export class ProductsFieldsSeeder { - async run( - em: EntityManager, + async run(em: EntityManager): Promise { + const products = await em.find(Product, {}, { populate: ['category'] }); - ): Promise { - const products = await em.findAll(Product) for (const product of products) { - for (const fieldData of fieldsDataData) { + const categoryTitle = product.category.title; + const fieldsData = + productFieldsByCategory[categoryTitle] ?? defaultProductFields; + for (const fieldData of fieldsData) { const field = em.create(Field, { name: fieldData.name, type: fieldData.type, isRequired: fieldData.isRequired, - order: 1, + order: fieldData.order ?? 1, entityType: EntityType.product, entityId: product.id, - multiple: false + multiple: fieldData.multiple ?? false, }); em.persist(field); + + if (fieldData.options?.length) { + for (const optionData of fieldData.options) { + const option = em.create(FieldOption, { + value: optionData.value, + order: optionData.order ?? null, + field, + }); + + em.persist(option); + } + } } } diff --git a/src/seeders/product.seeder.ts b/src/seeders/product.seeder.ts index 9f78433..548d4a3 100644 --- a/src/seeders/product.seeder.ts +++ b/src/seeders/product.seeder.ts @@ -9,13 +9,13 @@ export class ProductsSeeder { categoriesMap: Map, ): Promise { for (const productData of productsData) { - - const key = `${productData.categoryTitle}`; - - let category = categoriesMap.get(key); + const category = categoriesMap.get(productData.categoryTitle); if (!category) { - return + console.warn( + `[ProductsSeeder] Category not found: ${productData.categoryTitle} (product: ${productData.title})`, + ); + continue; } const product = em.create(Product, { @@ -23,9 +23,8 @@ export class ProductsSeeder { desc: productData.desc, category, isActive: productData.isActive, - // prepareTime: 10, images: productData.images, - order: 1 + order: productData.order ?? 1, }); em.persist(product);