update seeder
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
2026-07-20 23:26:27 +03:30
parent 2aefeb97d9
commit a69b75ccdd
7 changed files with 317 additions and 81 deletions
+2 -7
View File
@@ -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<Map<string, Category>> {
const categoriesMap = new Map<string, Category>();
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();
+8 -4
View File
@@ -1,9 +1,13 @@
export interface CategoryData {
title: string;
order?: number;
}
export const categoriesData: CategoryData[] = [
{ title: 'چاپ', },
{ title: 'صحافی', },
];
{ title: 'کارت ویزیت', order: 1 },
{ title: 'بروشور', order: 2 },
{ title: 'کاتالوگ', order: 3 },
{ title: 'پوستر', order: 4 },
{ title: 'تراکت', order: 5 },
{ title: 'بنر', order: 6 },
];
+7 -22
View File
@@ -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[] = [];
+113 -20
View File
@@ -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<string, ProductFieldData[]> = {
'کارت ویزیت': [
{
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,
},
]
];
+156 -12
View File
@@ -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],
},
];
+25 -9
View File
@@ -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<void> {
const products = await em.find(Product, {}, { populate: ['category'] });
): Promise<void> {
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);
}
}
}
}
+6 -7
View File
@@ -9,13 +9,13 @@ export class ProductsSeeder {
categoriesMap: Map<string, Category>,
): Promise<void> {
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);