import { PrismaClient, AdminRole, AppUserRole, CustomerType, OrderStatus, SettlementType, CheckRegistrationMode, CheckStatus, CashPaymentStatus, ShipmentStatus, InteractionType, ProductSeason, ProductUsageCategory, } from '@prisma/client'; import * as bcrypt from 'bcryptjs'; const prisma = new PrismaClient(); async function main() { const existingOrders = await prisma.order.count(); if (existingOrders > 0 && process.env.RUN_SEED !== 'force') { console.log('Seed skipped; data already exists'); return; } console.log('Seeding fabric_trade database...'); await prisma.productFavorite.deleteMany(); await prisma.reminder.deleteMany(); await prisma.meetingInteraction.deleteMany(); await prisma.orderStatusHistory.deleteMany(); await prisma.cashPaymentReceipt.deleteMany(); await prisma.check.deleteMany(); await prisma.shipment.deleteMany(); await prisma.orderItem.deleteMany(); await prisma.order.deleteMany(); await prisma.cartItem.deleteMany(); await prisma.cart.deleteMany(); await prisma.otpChallenge.deleteMany(); await prisma.customerNotification.deleteMany(); await prisma.product.deleteMany(); await prisma.bankAccount.deleteMany(); await prisma.levelBenefit.deleteMany(); await prisma.customerLevelDef.deleteMany(); await prisma.customer.deleteMany(); await prisma.company.deleteMany(); await prisma.adminUser.deleteMany(); await prisma.adminNotification.deleteMany(); await prisma.internalMessage.deleteMany(); await prisma.systemSettings.deleteMany(); const passwordHash = await bcrypt.hash('123456', 10); await prisma.adminUser.create({ data: { id: 'usr-1', fullName: 'مدیر سیستم', phone: '09128081392', email: 'admin@parche.ir', passwordHash, role: AdminRole.admin, isActive: true, }, }); await prisma.company.createMany({ data: [ { id: 'company-nademitex', name: 'نادمی تکس', slug: 'nademitex', description: 'شرکت اصلی — دریافت تمام پرداخت‌های اپ', isActive: true, displayOrder: 0, maxMeteragePerInvoice: null, cashInvoiceValidityHours: 8, cashInvoiceValidUntilHour: 17, }, { id: 'company-par', name: 'شرکت پَر', slug: 'par', description: 'تولیدکننده پارچه‌های باکیفیت', isActive: true, displayOrder: 1, maxMeteragePerInvoice: null, cashInvoiceValidityHours: 8, cashInvoiceValidUntilHour: 17, }, { id: 'company-fam-baft', name: 'فام‌بافت', slug: 'fam-baft', description: 'عرضه پارچه‌های تخصصی', isActive: true, displayOrder: 2, maxMeteragePerInvoice: null, cashInvoiceValidityHours: 8, cashInvoiceValidUntilHour: 17, }, ], }); await prisma.bankAccount.createMany({ data: [ { id: 'ba-par-1', companyId: 'company-nademitex', bankName: 'بانک ملی', accountHolder: 'نادمی تکس', accountNumber: '0123456789', cardNumber: '6037-9912-3456-7890', iban: 'IR120170000000012345678901', isActive: true, displayOrder: 1, }, { id: 'ba-par-2', companyId: 'company-nademitex', bankName: 'بانک صادرات', accountHolder: 'نادمی تکس', accountNumber: '9876543210', cardNumber: '6037-6912-3456-7891', iban: 'IR620190000000098765432101', isActive: true, displayOrder: 2, }, { id: 'ba-fam-1', companyId: 'company-nademitex', bankName: 'بانک ملت', accountHolder: 'نادمی تکس', accountNumber: '1122334455', cardNumber: '6104-3378-9012-3456', iban: 'IR450120000000011223344556', isActive: true, displayOrder: 1, }, ], }); await prisma.product.createMany({ data: [ { id: 'prod-377-blue', companyId: 'company-par', name: 'فاستونی ایتالیایی', code: '377-BL', color: 'آبی', minMeterage: 30, orderMultiplier: 10, basePrice: 185000, stock: 10000, isActive: true, usageCategory: ProductUsageCategory.suit, season: ProductSeason.winter, widthCm: 150, composition: '۸۰٪ پشم، ۲۰٪ پلی‌استر', weightGrams: 280, weaveType: 'تویل', colorsJson: ['#1e3a8a', '#111827', '#6b7280', '#92400e'], tagsJson: ['کت‌شلواری', 'زمستانه', 'رسمی'], subtitle: 'مناسب کت و شلوار رسمی', rollMeters: 50, isNew: true, }, { id: 'prod-377-black', companyId: 'company-par', name: 'پارچه مشکی رسمی', code: '377-BK', color: 'مشکی', minMeterage: 30, orderMultiplier: 10, basePrice: 192000, stock: 8000, isActive: true, usageCategory: ProductUsageCategory.trousers, season: ProductSeason.all_season, widthCm: 150, composition: '۷۰٪ پشم، ۳۰٪ پلی‌استر', weightGrams: 260, weaveType: 'ساده', colorsJson: ['#111827', '#374151'], tagsJson: ['شلواری', 'چهارفصل'], subtitle: 'شلوار رسمی روزانه', rollMeters: 50, isNew: true, }, { id: 'prod-378-blue', companyId: 'company-par', name: 'پیراهنی نخی آبی', code: '378-BL', color: 'آبی', minMeterage: 50, orderMultiplier: 10, basePrice: 200000, stock: 5000, isActive: true, usageCategory: ProductUsageCategory.shirt, season: ProductSeason.summer, widthCm: 145, composition: '۱۰۰٪ پنبه', weightGrams: 120, weaveType: 'پاپلین', colorsJson: ['#3b82f6', '#93c5fd', '#ffffff'], tagsJson: ['پیراهنی', 'تابستانه'], subtitle: 'خنک و سبک', rollMeters: 40, isNew: true, }, { id: 'prod-378-black', companyId: 'company-par', name: 'پیراهنی مشکی', code: '378-BK', color: 'مشکی', minMeterage: 50, orderMultiplier: 10, basePrice: 205000, stock: 5000, isActive: true, usageCategory: ProductUsageCategory.shirt, season: ProductSeason.all_season, widthCm: 145, composition: '۹۵٪ پنبه، ۵٪ الاستان', weightGrams: 130, colorsJson: ['#111827', '#4b5563'], tagsJson: ['پیراهنی'], subtitle: 'پیراهن اداری', rollMeters: 40, isNew: false, }, { id: 'prod-378-blue-white', companyId: 'company-par', name: 'آبی پشت سفید', code: '378-BLW', color: 'آبی پشت سفید', minMeterage: 50, orderMultiplier: 10, basePrice: 210000, stock: 3000, isActive: true, usageCategory: ProductUsageCategory.suit, season: ProductSeason.summer, widthCm: 150, composition: '۵۵٪ پشم، ۴۵٪ پلی‌استر', weightGrams: 220, colorsJson: ['#60a5fa', '#f8fafc'], tagsJson: ['کت‌شلواری', 'تابستانه'], subtitle: 'سبک تابستانه', rollMeters: 50, isNew: false, }, { id: 'prod-378-black-white', companyId: 'company-par', name: 'مشکی پشت سفید', code: '378-BKW', color: 'مشکی پشت سفید', minMeterage: 50, orderMultiplier: 10, basePrice: 215000, stock: 3000, isActive: true, usageCategory: ProductUsageCategory.trousers, season: ProductSeason.winter, widthCm: 150, composition: '۶۰٪ پشم، ۴۰٪ پلی‌استر', weightGrams: 300, colorsJson: ['#111827', '#f8fafc'], tagsJson: ['شلواری', 'زمستانه'], subtitle: 'گرم زمستانه', rollMeters: 50, isNew: false, }, { id: 'prod-fam-401-1', companyId: 'company-fam-baft', name: 'پارچه مخمل', code: '401-MV', color: 'سرمه‌ای', minMeterage: 40, orderMultiplier: 10, basePrice: 250000, stock: 6000, isActive: true, usageCategory: ProductUsageCategory.suit, season: ProductSeason.winter, widthCm: 140, composition: 'مخمل پلی‌استر', weightGrams: 320, colorsJson: ['#1e3a5f', '#7c2d12', '#365314'], tagsJson: ['کت‌شلواری', 'زمستانه'], subtitle: 'مخمل لوکس', rollMeters: 45, isNew: true, }, { id: 'prod-fam-401-2', companyId: 'company-fam-baft', name: 'پارچه کجراه', code: '401-KJ', color: 'کرم', minMeterage: 40, orderMultiplier: 10, basePrice: null, stock: 4000, isActive: true, usageCategory: ProductUsageCategory.trousers, season: ProductSeason.all_season, widthCm: 150, composition: 'کجراه پنبه‌ای', weightGrams: 240, colorsJson: ['#d6c3a8', '#8b7355'], tagsJson: ['شلواری', 'چهارفصل'], subtitle: 'روزمره', rollMeters: 50, isNew: false, }, ], }); await prisma.customerLevelDef.create({ data: { code: 'bronze', label: 'برنزی', sortOrder: 1, criteriaJson: { minSalesToman: 0 }, benefits: { create: [{ title: 'دسترسی به کاتالوگ پایه' }], }, }, }); await prisma.customerLevelDef.create({ data: { code: 'silver', label: 'نقره‌ای', sortOrder: 2, criteriaJson: { minSalesToman: 500_000_000 }, benefits: { create: [{ title: 'پشتیبانی اولویت‌دار' }], }, }, }); const goldLevel = await prisma.customerLevelDef.create({ data: { code: 'gold', label: 'طلایی', sortOrder: 3, criteriaJson: { minSalesToman: 1_500_000_000 }, benefits: { create: [{ title: 'تخفیف ویژه سفارش‌های عمده' }], }, }, }); await prisma.customerLevelDef.create({ data: { code: 'vip', label: 'VIP', sortOrder: 4, criteriaJson: { minSalesToman: 3_000_000_000 }, benefits: { create: [{ title: 'مشاوره تخصصی و ارسال سریع' }], }, }, }); await prisma.customer.create({ data: { id: 'agent-1', firstName: 'علی', lastName: 'رضایی', phone: '09121112233', nationalId: '0011111111', customerType: CustomerType.wholesale, appRole: AppUserRole.agent, agentCode: 'W-1247', levelDefId: goldLevel.id, levelLabel: 'طلایی', nextLevelLabel: 'VIP', pointsToNext: 0, levelProgress: 0, companyId: 'company-par', isActive: true, avatarLetter: 'ع', avatarColor: '#0B3D33', createdAt: new Date('2024-01-10T10:00:00'), }, }); await prisma.customer.createMany({ data: [ { id: 'cust-1', firstName: 'سارا', lastName: 'محمدی', phone: '09121234567', nationalId: '0012345678', customerType: CustomerType.wholesale, companyId: 'company-par', businessName: 'بوتیک رز', assignedAgentId: 'agent-1', levelLabel: 'نقره‌ای', avatarLetter: 'پ', avatarColor: '#f9a8d4', isActive: true, createdAt: new Date('2024-03-12T10:00:00'), }, { id: 'cust-2', firstName: 'نرگس', lastName: 'احمدی', phone: '09135551234', nationalId: '1030567890', customerType: CustomerType.wholesale, companyId: 'company-fam-baft', businessName: 'مزون الوان', assignedAgentId: 'agent-1', levelLabel: 'برنزی', avatarLetter: 'م', avatarColor: '#c4b5fd', isActive: true, createdAt: new Date('2024-05-20T14:30:00'), }, { id: 'cust-3', firstName: 'فروشگاه', lastName: 'پارچه مهر', phone: '09128877665', nationalId: '0012345679', customerType: CustomerType.retail, companyId: 'company-par', businessName: 'پارچه مهر', assignedAgentId: 'agent-1', levelLabel: 'برنزی', avatarLetter: 'م', avatarColor: '#93c5fd', isActive: true, createdAt: new Date('2024-07-08T09:15:00'), }, { id: 'cust-4', firstName: 'پوشاک', lastName: 'سپهر', phone: '09369876543', nationalId: '1050987654', customerType: CustomerType.wholesale, companyId: 'company-par', businessName: 'پوشاک سپهر', assignedAgentId: 'agent-1', levelLabel: 'برنزی', avatarLetter: 'س', avatarColor: '#fcd34d', isActive: false, createdAt: new Date('2024-08-01T11:00:00'), }, { id: 'cust-5', firstName: 'بافت', lastName: 'آسان', phone: '09121110000', nationalId: '0065432109', customerType: CustomerType.wholesale, companyId: 'company-fam-baft', businessName: 'بافت آسان', assignedAgentId: 'agent-1', levelLabel: 'نقره‌ای', avatarLetter: 'ب', avatarColor: '#6ee7b7', isActive: true, createdAt: new Date('2024-06-01T10:00:00'), }, { id: 'cust-6', firstName: 'مینا', lastName: 'کریمی', phone: '09129990001', nationalId: '0077007700', customerType: CustomerType.retail, companyId: 'company-par', businessName: 'مزون مینا', assignedAgentId: 'agent-1', levelLabel: 'برنزی', avatarLetter: 'ن', avatarColor: '#fda4af', isActive: true, createdAt: new Date('2024-09-01T10:00:00'), }, ], }); const order1 = await prisma.order.create({ data: { id: 'ord-1', orderNumber: 'ORD-1403-1256', userId: 'cust-1', companyId: 'company-par', companyName: 'شرکت پَر', settlementType: SettlementType.check, checkMode: CheckRegistrationMode.full, status: OrderStatus.awaiting_review, totalMeterage: 4250, totalAmount: 2_450_000_000, createdAt: new Date('2024-10-25T10:30:00'), items: { create: [ { id: 'oi-1', productId: 'prod-377-blue', catalogCode: '377', productName: 'پارچه آبی', productCode: '377-BL', color: 'آبی', requestedMeterage: 2000, confirmedMeterage: 2000, companyId: 'company-par', companyName: 'شرکت پَر', }, { id: 'oi-2', productId: 'prod-377-black', catalogCode: '377', productName: 'پارچه مشکی', productCode: '377-BK', color: 'مشکی', requestedMeterage: 1500, confirmedMeterage: 1000, companyId: 'company-par', companyName: 'شرکت پَر', }, { id: 'oi-3', productId: 'prod-378-blue-white', catalogCode: '378', productName: 'آبی پشت سفید', productCode: '378-BLW', color: 'آبی پشت سفید', requestedMeterage: 750, confirmedMeterage: 750, companyId: 'company-par', companyName: 'شرکت پَر', }, ], }, checks: { create: [ { id: 'chk-1', row: 1, amount: 1_000_000_000, bankName: 'ملت', sayadId: '1234567890123456', dueDate: new Date('2024-10-21'), status: CheckStatus.pending_review, mode: CheckRegistrationMode.full, }, { id: 'chk-2', row: 2, amount: 800_000_000, bankName: 'ملی', sayadId: '2345678901234567', dueDate: new Date('2024-10-26'), status: CheckStatus.pending_review, mode: CheckRegistrationMode.full, }, { id: 'chk-3', row: 3, amount: 650_000_000, bankName: 'ملت', sayadId: '3456789012345678', dueDate: new Date('2024-10-31'), status: CheckStatus.pending_review, mode: CheckRegistrationMode.full, }, ], }, statusHistory: { create: [ { fromStatus: null, toStatus: OrderStatus.submitted, changedBy: 'customer', changedAt: new Date('2024-10-25T10:30:00') }, { fromStatus: OrderStatus.submitted, toStatus: OrderStatus.awaiting_review, changedBy: 'system', changedAt: new Date('2024-10-25T10:30:01') }, ], }, }, }); await prisma.order.create({ data: { id: 'ord-2', orderNumber: 'ORD-1403-1255', userId: 'cust-2', companyId: 'company-fam-baft', companyName: 'فام‌بافت', settlementType: SettlementType.check, checkMode: CheckRegistrationMode.brief, status: OrderStatus.awaiting_check_review, totalMeterage: 3200, totalAmount: 1_850_000_000, createdAt: new Date('2024-10-24T14:15:00'), items: { create: [ { productId: 'prod-fam-401-1', catalogCode: '401', productName: 'پارچه مخمل', productCode: '401-MV', color: 'سرمه‌ای', requestedMeterage: 3200, confirmedMeterage: 3200, unitPrice: 250000, lineTotal: 800_000_000, companyId: 'company-fam-baft', companyName: 'فام‌بافت', }, ], }, cashReceipt: { create: { id: 'cp-1', amount: 1_850_000_000, paidAmount: 1_850_000_000, transferDate: new Date('2024-10-25T08:30:00'), trackingNumber: '9876543210', expiresAt: new Date('2024-10-25T17:00:00'), status: CashPaymentStatus.pending_review, submittedAt: new Date('2024-10-25T08:30:00'), }, }, statusHistory: { create: [ { fromStatus: null, toStatus: OrderStatus.submitted, changedBy: 'customer' }, { fromStatus: OrderStatus.submitted, toStatus: OrderStatus.awaiting_check_review, changedBy: 'admin' }, ], }, }, }); await prisma.order.create({ data: { id: 'ord-3', orderNumber: 'ORD-1403-1254', userId: 'cust-1', companyId: 'company-par', companyName: 'شرکت پَر', settlementType: SettlementType.cash, status: OrderStatus.final_approved, totalMeterage: 1800, totalAmount: 980_000_000, finalAmount: 980_000_000, createdAt: new Date('2024-10-23T09:00:00'), cashReceipt: { create: { id: 'cp-2', amount: 980_000_000, paidAmount: 980_000_000, transferDate: new Date('2024-10-24T15:20:00'), trackingNumber: '1234567890', destinationAccountId: 'ba-par-1', expiresAt: new Date('2024-10-24T17:00:00'), status: CashPaymentStatus.approved, submittedAt: new Date('2024-10-24T15:20:00'), }, }, }, }); await prisma.order.create({ data: { id: 'ord-4', orderNumber: 'ORD-1403-1253', userId: 'cust-5', companyId: 'company-fam-baft', companyName: 'فام‌بافت', settlementType: SettlementType.check, status: OrderStatus.check_needs_fix, totalMeterage: 5100, totalAmount: 3_200_000_000, createdAt: new Date('2024-10-22T16:45:00'), }, }); await prisma.order.create({ data: { id: 'ord-5', orderNumber: 'ORD-1403-1252', userId: 'cust-1', companyId: 'company-par', companyName: 'شرکت پَر', settlementType: SettlementType.cash, status: OrderStatus.delivered, totalMeterage: 1200, totalAmount: 750_000_000, finalAmount: 750_000_000, createdAt: new Date('2024-10-21T11:20:00'), shipment: { create: { id: 'shp-delivered-5', carrier: 'باربری تهران', trackingNumber: 'BR-1403-88001', meterage: 1200, status: ShipmentStatus.delivered, shippedAt: new Date('2024-10-19T09:00:00'), deliveredAt: new Date('2024-10-21T11:00:00'), }, }, cashReceipt: { create: { id: 'cp-3', amount: 750_000_000, paidAmount: 750_000_000, transferDate: new Date('2024-10-18T11:00:00'), trackingNumber: '5555123456', destinationAccountId: 'ba-par-2', expiresAt: new Date('2024-10-18T17:00:00'), status: CashPaymentStatus.approved, submittedAt: new Date('2024-10-18T11:00:00'), }, }, }, }); await prisma.order.create({ data: { id: 'ord-6', orderNumber: 'ORD-1403-1251', userId: 'cust-1', companyId: 'company-par', companyName: 'شرکت پَر', settlementType: SettlementType.check, status: OrderStatus.shipped, totalMeterage: 2900, totalAmount: 1_600_000_000, createdAt: new Date('2024-10-20T08:30:00'), shipment: { create: { id: 'shp-1', carrier: 'باربری تهران-اصفهان', trackingNumber: 'BR-1403-88901', meterage: 2900, status: ShipmentStatus.shipped, shippedAt: new Date('2024-10-24T09:00:00'), }, }, }, }); await prisma.order.create({ data: { id: 'ord-7', orderNumber: 'ORD-1403-1250', userId: 'cust-5', companyId: 'company-fam-baft', companyName: 'فام‌بافت', settlementType: SettlementType.check, status: OrderStatus.awaiting_check_review, totalMeterage: 3800, totalAmount: 2_100_000_000, createdAt: new Date('2024-10-19T13:00:00'), shipment: { create: { id: 'shp-2', carrier: 'باربری سریع', trackingNumber: 'BR-1403-88902', meterage: 3800, status: ShipmentStatus.ready, }, }, }, }); await prisma.order.create({ data: { id: 'ord-8', orderNumber: 'ORD-1403-1208', userId: 'cust-3', companyId: 'company-par', companyName: 'شرکت پَر', settlementType: SettlementType.cash, status: OrderStatus.preparing, totalMeterage: 950, totalAmount: 450_000_000, createdAt: new Date('2024-10-18T10:00:00'), shipment: { create: { id: 'shp-3', carrier: 'پیک داخلی', trackingNumber: 'PK-1403-0045', meterage: 950, status: ShipmentStatus.preparing, }, }, cashReceipt: { create: { id: 'cp-4', amount: 450_000_000, paidAmount: null, transferDate: null, trackingNumber: null, expiresAt: new Date('2024-10-22T17:00:00'), status: CashPaymentStatus.expired, }, }, }, }); await prisma.order.create({ data: { id: 'ord-9', orderNumber: 'ORD-1403-1199', userId: 'cust-1', companyId: 'company-par', companyName: 'شرکت پَر', settlementType: SettlementType.check, status: OrderStatus.delivered, totalMeterage: 4100, totalAmount: 2_200_000_000, createdAt: new Date('2024-10-15T10:00:00'), shipment: { create: { id: 'shp-4', carrier: 'باربری تهران-مشهد', trackingNumber: 'BR-1403-88750', meterage: 4100, status: ShipmentStatus.delivered, shippedAt: new Date('2024-10-18T10:00:00'), deliveredAt: new Date('2024-10-20T16:30:00'), }, }, }, }); await prisma.systemSettings.create({ data: { id: 'default', maxMeteragePerInvoice: 5000, cashInvoiceValidityHours: 8, defaultSettlementCheck: true, defaultSettlementCash: true, smsOrderRegistered: true, smsPaymentReminder: true, smsCheckReview: true, smsShippingUpdate: true, supportPhone: '02191000000', supportEmail: 'support@fabrictrade.ir', }, }); await prisma.meetingInteraction.createMany({ data: [ { id: 'meet-1', agentId: 'agent-1', customerId: 'cust-1', type: InteractionType.in_person, title: 'بازدید از بوتیک رز', description: 'نیاز به پارچه‌های طوسی و سرمه‌ای اعلام شد.', subject: 'بازدید حضوری', content: 'نیاز به پارچه‌های طوسی، سرمه‌ای و ذغالی با عرض مناسب.', date: '1403/03/20', time: '11:30', }, { id: 'meet-2', agentId: 'agent-1', customerId: 'cust-2', type: InteractionType.call, title: 'پیگیری موجودی', description: 'تماس برای اعلام موجودی فاستونی.', date: '1403/03/18', time: '10:00', }, ], }); await prisma.reminder.createMany({ data: [ { id: 'rem-1', ownerId: 'agent-1', customerId: 'cust-1', title: 'پیگیری موجودی پارچه فاستونی طوسی', description: 'اعلام موجودی و ارسال نمونه', note: 'تماس برای اعلام موجودی و ارسال نمونه', date: '1403/03/23', time: '10:00', interactionType: InteractionType.call, completed: false, }, { id: 'rem-2', ownerId: 'agent-1', customerId: 'cust-2', title: 'ارسال کالیته جدید', description: 'ارسال کالیته زمستانه برای مزون الوان', date: '1403/03/24', time: '14:00', interactionType: InteractionType.in_person, completed: false, }, { id: 'rem-3', ownerId: 'agent-1', customerId: 'cust-3', title: 'پیگیری سفارش قبلی', description: 'بررسی وضعیت سفارش و تسویه', date: '1403/03/10', time: '09:00', interactionType: InteractionType.note, completed: true, completedAt: new Date('2024-10-20T09:30:00'), }, ], }); void order1; console.log('Seed completed successfully.'); console.log('Admin login: 09128081392 / 123456'); console.log('Agent OTP login: 09121112233'); console.log('Customer OTP login: 09121234567'); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });