This commit is contained in:
@@ -2,24 +2,19 @@ import type { EntityManager } from '@mikro-orm/core';
|
|||||||
import { Category } from '../modules/product/entities/category.entity';
|
import { Category } from '../modules/product/entities/category.entity';
|
||||||
import { categoriesData } from './data/categories.data';
|
import { categoriesData } from './data/categories.data';
|
||||||
|
|
||||||
|
|
||||||
export class CategoriesSeeder {
|
export class CategoriesSeeder {
|
||||||
|
|
||||||
|
|
||||||
async run(em: EntityManager): Promise<Map<string, Category>> {
|
async run(em: EntityManager): Promise<Map<string, Category>> {
|
||||||
const categoriesMap = new Map<string, Category>();
|
const categoriesMap = new Map<string, Category>();
|
||||||
|
|
||||||
for (const catData of categoriesData) {
|
for (const catData of categoriesData) {
|
||||||
|
|
||||||
const category = em.create(Category, {
|
const category = em.create(Category, {
|
||||||
title: catData.title,
|
title: catData.title,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
order: catData.order ?? null,
|
||||||
});
|
});
|
||||||
|
|
||||||
em.persist(category);
|
em.persist(category);
|
||||||
|
categoriesMap.set(catData.title, category);
|
||||||
categoriesMap.set(`${catData.title}`, category);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await em.flush();
|
await em.flush();
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
|
||||||
export interface CategoryData {
|
export interface CategoryData {
|
||||||
title: string;
|
title: string;
|
||||||
|
order?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const categoriesData: CategoryData[] = [
|
export const categoriesData: CategoryData[] = [
|
||||||
{ title: 'چاپ', },
|
{ title: 'کارت ویزیت', order: 1 },
|
||||||
{ title: 'صحافی', },
|
{ title: 'بروشور', order: 2 },
|
||||||
|
{ title: 'کاتالوگ', order: 3 },
|
||||||
|
{ title: 'پوستر', order: 4 },
|
||||||
|
{ title: 'تراکت', order: 5 },
|
||||||
|
{ title: 'بنر', order: 6 },
|
||||||
];
|
];
|
||||||
@@ -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 {
|
export interface AttributeValueData {
|
||||||
value: string;
|
value: string;
|
||||||
attributeName: string
|
attributeName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const attributeValueData: AttributeValueData[] = [
|
export const attributeValueData: AttributeValueData[] = [];
|
||||||
{
|
|
||||||
attributeName: 'گراماژ کاغذ',
|
|
||||||
value: '70',
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
attributeName: 'گراماژ کاغذ',
|
|
||||||
value: '80',
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
attributeName: 'رنگ',
|
|
||||||
value: 'آبی',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
attributeName: 'رنگ',
|
|
||||||
value: 'قرمز',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -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 {
|
export interface ProductFieldOptionData {
|
||||||
|
value: string;
|
||||||
|
order?: number;
|
||||||
name: string;
|
|
||||||
isRequired: boolean;
|
|
||||||
type: FieldType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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<string, ProductFieldData[]> = {
|
||||||
|
'کارت ویزیت': [
|
||||||
{
|
{
|
||||||
name: 'گراماژ کاغذ',
|
name: 'اندازه',
|
||||||
type: FieldType.radio,
|
|
||||||
isRequired: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'رنگ',
|
|
||||||
type: FieldType.select,
|
type: FieldType.select,
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
|
order: 1,
|
||||||
|
options: [
|
||||||
|
{ value: '۹×۵ سانتیمتر', order: 1 },
|
||||||
|
{ value: '۸٫۵×۵٫۵ سانتیمتر', order: 2 },
|
||||||
|
{ value: '۹×۶ سانتیمتر', order: 3 },
|
||||||
|
{ value: 'سفارشی', order: 4 },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
بروشور: [
|
||||||
{
|
{
|
||||||
name: 'ویژگی نوشتنی',
|
name: 'اندازه',
|
||||||
type: FieldType.text,
|
type: FieldType.select,
|
||||||
isRequired: true,
|
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.select,
|
||||||
|
isRequired: true,
|
||||||
|
order: 1,
|
||||||
|
options: [
|
||||||
|
{ value: 'A4', order: 1 },
|
||||||
|
{ value: 'A5', order: 2 },
|
||||||
|
{ value: 'سفارشی', order: 3 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|||||||
@@ -1,25 +1,169 @@
|
|||||||
|
|
||||||
export interface productData {
|
export interface productData {
|
||||||
title: string;
|
title: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
categoryTitle: string,
|
categoryTitle: string;
|
||||||
images: string[];
|
images: string[];
|
||||||
desc: string;
|
desc: string;
|
||||||
|
order?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PLACEHOLDER_IMAGE =
|
||||||
|
'https://dmenu.danakcorp.com/uploads/images/product/product_1715711043900.png';
|
||||||
|
|
||||||
export const productsData: productData[] = [
|
export const productsData: productData[] = [
|
||||||
|
// کارت ویزیت
|
||||||
{
|
{
|
||||||
title: 'کارت ویزیت',
|
title: 'لمینت',
|
||||||
desc: 'توضیح کار ویزیت',
|
desc: 'کارت ویزیت با روکش لمینت',
|
||||||
categoryTitle: 'چاپ',
|
categoryTitle: 'کارت ویزیت',
|
||||||
isActive: true,
|
isActive: true,
|
||||||
images: ["https://dmenu.danakcorp.com/uploads/images/product/product_1715711043900.png"],
|
order: 1,
|
||||||
|
images: [PLACEHOLDER_IMAGE],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'بروشور',
|
title: 'مخملی',
|
||||||
desc: 'توضیح ',
|
desc: 'کارت ویزیت با روکش مخملی',
|
||||||
categoryTitle: 'چاپ',
|
categoryTitle: 'کارت ویزیت',
|
||||||
isActive: true,
|
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],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|||||||
@@ -1,30 +1,46 @@
|
|||||||
import type { EntityManager } from '@mikro-orm/core';
|
import type { EntityManager } from '@mikro-orm/core';
|
||||||
import { Product } from '../modules/product/entities/product.entity';
|
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 { 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 { EntityType } from 'src/modules/form-builder/interface/print';
|
||||||
// import { Attribute } from 'src/modules/product/entities/attribute.entity';
|
|
||||||
|
|
||||||
export class ProductsFieldsSeeder {
|
export class ProductsFieldsSeeder {
|
||||||
async run(
|
async run(em: EntityManager): Promise<void> {
|
||||||
em: EntityManager,
|
const products = await em.find(Product, {}, { populate: ['category'] });
|
||||||
|
|
||||||
): Promise<void> {
|
|
||||||
const products = await em.findAll(Product)
|
|
||||||
for (const product of products) {
|
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, {
|
const field = em.create(Field, {
|
||||||
name: fieldData.name,
|
name: fieldData.name,
|
||||||
type: fieldData.type,
|
type: fieldData.type,
|
||||||
isRequired: fieldData.isRequired,
|
isRequired: fieldData.isRequired,
|
||||||
order: 1,
|
order: fieldData.order ?? 1,
|
||||||
entityType: EntityType.product,
|
entityType: EntityType.product,
|
||||||
entityId: product.id,
|
entityId: product.id,
|
||||||
multiple: false
|
multiple: fieldData.multiple ?? false,
|
||||||
});
|
});
|
||||||
|
|
||||||
em.persist(field);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ export class ProductsSeeder {
|
|||||||
categoriesMap: Map<string, Category>,
|
categoriesMap: Map<string, Category>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
for (const productData of productsData) {
|
for (const productData of productsData) {
|
||||||
|
const category = categoriesMap.get(productData.categoryTitle);
|
||||||
const key = `${productData.categoryTitle}`;
|
|
||||||
|
|
||||||
let category = categoriesMap.get(key);
|
|
||||||
|
|
||||||
if (!category) {
|
if (!category) {
|
||||||
return
|
console.warn(
|
||||||
|
`[ProductsSeeder] Category not found: ${productData.categoryTitle} (product: ${productData.title})`,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const product = em.create(Product, {
|
const product = em.create(Product, {
|
||||||
@@ -23,9 +23,8 @@ export class ProductsSeeder {
|
|||||||
desc: productData.desc,
|
desc: productData.desc,
|
||||||
category,
|
category,
|
||||||
isActive: productData.isActive,
|
isActive: productData.isActive,
|
||||||
// prepareTime: 10,
|
|
||||||
images: productData.images,
|
images: productData.images,
|
||||||
order: 1
|
order: productData.order ?? 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
em.persist(product);
|
em.persist(product);
|
||||||
|
|||||||
Reference in New Issue
Block a user