/** * Dev helper: seed >15 mock orders per OrderStatus so the Orders UI can be inspected. * Run: npx tsx scripts/seed-mock-orders.ts */ import { OrderChannel, OrderStatus, Prisma, PrismaClient, } from '@prisma/client' const prisma = new PrismaClient() const STATUSES: OrderStatus[] = [ OrderStatus.SUSPENDED, OrderStatus.PLACED, OrderStatus.ADMIN_APPROVED, OrderStatus.SOURCING, OrderStatus.PREPARING, OrderStatus.DELIVERED_TO_AGENT, OrderStatus.DELIVERED_TO_CUSTOMER, OrderStatus.CANCELLED, ] const PER_STATUS = 18 const TAG = 'MOCK-ORD' function d(n: number | string) { return new Prisma.Decimal(n) } function orderNumber(status: OrderStatus, i: number) { // Unique, easy to spot/delete later return `${TAG}-${status.slice(0, 4)}-${String(i).padStart(3, '0')}-${Date.now().toString(36)}` } async function main() { const mobileOverride = process.env.MOCK_ORDERS_MOBILE?.trim() const customer = mobileOverride ? await prisma.customer.findUnique({ where: { mobile: mobileOverride }, select: { id: true, mobile: true, fullName: true, referredByAgentId: true }, }) : await prisma.customer.findFirst({ orderBy: { updatedAt: 'desc' }, select: { id: true, mobile: true, fullName: true, referredByAgentId: true }, }) if (!customer) { throw new Error( mobileOverride ? `No customer with mobile=${mobileOverride}` : 'No customers in DB — create/login a customer first', ) } const variants = await prisma.productVariant.findMany({ take: 30, where: { isActive: true }, include: { product: { select: { title: true } } }, }) if (variants.length === 0) { throw new Error('No product variants in DB — seed catalog first') } const branch = await prisma.branch.findFirst({ select: { id: true, name: true } }) console.log( `Seeding ${PER_STATUS} orders × ${STATUSES.length} statuses for customer ${customer.mobile} (${customer.fullName}), ${variants.length} variants` + (branch ? `, branch=${branch.name}` : ''), ) let created = 0 for (const status of STATUSES) { for (let i = 1; i <= PER_STATUS; i++) { const variant = variants[i % variants.length]! const qty = 1 + (i % 3) const rash = Number(variant.rashWeightGrams ?? 1.25) const wagePct = Number(variant.defaultWagePercent ?? 7) const discountPct = 0 const computed = rash * (1 + (wagePct - discountPct) / 100) const totalGold = computed * qty const wageWeight = totalGold - rash * qty const flatRial = i % 4 === 0 ? 150_000 * i : 0 const daysAgo = (STATUSES.indexOf(status) * PER_STATUS + i) % 40 const createdAt = new Date(Date.now() - daysAgo * 24 * 60 * 60 * 1000 - i * 60_000) const deliveredAt = status === OrderStatus.DELIVERED_TO_CUSTOMER ? new Date(createdAt.getTime() + 2 * 24 * 60 * 60 * 1000) : null // 1–2 line items so list/detail both look realistic const second = variants[(i + 3) % variants.length]! const useSecond = i % 3 === 0 const order = await prisma.order.create({ data: { orderNumber: orderNumber(status, i), customerId: customer.id, branchId: branch?.id ?? null, channel: i % 5 === 0 ? OrderChannel.WHOLESALE : OrderChannel.RETAIL, status, totalGoldWeightGrams: d( (useSecond ? totalGold + Number(second.rashWeightGrams) * (1 + Number(second.defaultWagePercent) / 100) : totalGold ).toFixed(4), ), wageWeightGrams: d(Math.max(0, wageWeight).toFixed(4)), flatRialCharge: d(flatRial), isSuspendedOverCreditLimit: status === OrderStatus.SUSPENDED, deliveredAt, salesAgentId: customer.referredByAgentId ?? null, createdAt, updatedAt: createdAt, items: { create: [ { productVariantId: variant.id, quantity: qty, rashWeightGramsSnapshot: d(rash.toFixed(4)), wagePercentSnapshot: d(wagePct.toFixed(3)), discountPercentSnapshot: d(discountPct.toFixed(3)), computedWeightGrams: d(computed.toFixed(4)), flatRialCharge: d(flatRial), }, ...(useSecond ? [ { productVariantId: second.id, quantity: 1, rashWeightGramsSnapshot: d(Number(second.rashWeightGrams).toFixed(4)), wagePercentSnapshot: d(Number(second.defaultWagePercent).toFixed(3)), discountPercentSnapshot: d(0), computedWeightGrams: d( ( Number(second.rashWeightGrams) * (1 + Number(second.defaultWagePercent) / 100) ).toFixed(4), ), flatRialCharge: d(0), }, ] : []), ], }, statusEvents: { create: [ { fromStatus: null, toStatus: OrderStatus.PLACED, note: 'mock seed: placed', createdAt, }, ...(status !== OrderStatus.PLACED ? [ { fromStatus: OrderStatus.PLACED, toStatus: status, note: `mock seed: set to ${status}`, createdAt: new Date(createdAt.getTime() + 60_000), }, ] : []), ], }, }, }) created++ if (i === 1) { console.log(` ${status}: first=${order.orderNumber}`) } } console.log(` ${status}: +${PER_STATUS}`) } const counts = await prisma.order.groupBy({ by: ['status'], _count: { _all: true }, where: { orderNumber: { startsWith: TAG } }, }) console.log(`Done. Created ${created} mock orders (tag ${TAG}).`) console.log( 'Mock counts:', Object.fromEntries(counts.map((c) => [c.status, c._count._all])), ) console.log(`Login as mobile ${customer.mobile} to see them in the app.`) } main() .catch((e) => { console.error(e) process.exit(1) }) .finally(async () => { await prisma.$disconnect() })