import { PlantingOrder as PrismaPlantingOrder, FundAllocation as PrismaFundAllocation, Prisma, } from '@prisma/client'; import { PlantingOrder, PlantingOrderData, } from '../../../domain/aggregates/planting-order.aggregate'; import { PlantingOrderStatus } from '../../../domain/value-objects/planting-order-status.enum'; import { FundAllocation } from '../../../domain/value-objects/fund-allocation.vo'; import { FundAllocationTargetType } from '../../../domain/value-objects/fund-allocation-target-type.enum'; type PlantingOrderWithAllocations = PrismaPlantingOrder & { fundAllocations?: PrismaFundAllocation[]; }; export class PlantingOrderMapper { static toDomain(prismaOrder: PlantingOrderWithAllocations): PlantingOrder { const data: PlantingOrderData = { id: prismaOrder.id, orderNo: prismaOrder.orderNo, userId: prismaOrder.userId, accountSequence: prismaOrder.accountSequence, treeCount: prismaOrder.treeCount, totalAmount: Number(prismaOrder.totalAmount), status: prismaOrder.status as PlantingOrderStatus, selectedProvince: prismaOrder.selectedProvince, selectedCity: prismaOrder.selectedCity, provinceCitySelectedAt: prismaOrder.provinceCitySelectedAt, provinceCityConfirmedAt: prismaOrder.provinceCityConfirmedAt, poolInjectionBatchId: prismaOrder.poolInjectionBatchId, poolInjectionScheduledTime: prismaOrder.poolInjectionScheduledTime, poolInjectionActualTime: prismaOrder.poolInjectionActualTime, poolInjectionTxHash: prismaOrder.poolInjectionTxHash, miningEnabledAt: prismaOrder.miningEnabledAt, createdAt: prismaOrder.createdAt, paidAt: prismaOrder.paidAt, fundAllocatedAt: prismaOrder.fundAllocatedAt, }; return PlantingOrder.reconstitute(data); } static toPersistence(order: PlantingOrder): { orderData: { id?: bigint; orderNo: string; userId: bigint; accountSequence: string; treeCount: number; totalAmount: Prisma.Decimal; selectedProvince: string | null; selectedCity: string | null; provinceCitySelectedAt: Date | null; provinceCityConfirmedAt: Date | null; status: string; poolInjectionBatchId: bigint | null; poolInjectionScheduledTime: Date | null; poolInjectionActualTime: Date | null; poolInjectionTxHash: string | null; miningEnabledAt: Date | null; createdAt: Date; paidAt: Date | null; fundAllocatedAt: Date | null; }; allocations: { orderId: bigint; targetType: string; amount: Prisma.Decimal; targetAccountId: string | null; metadata: Prisma.InputJsonValue | null; }[]; } { const data = order.toPersistence(); const orderData = { id: data.id, orderNo: data.orderNo, userId: data.userId, accountSequence: data.accountSequence, treeCount: data.treeCount, totalAmount: new Prisma.Decimal(data.totalAmount), selectedProvince: data.selectedProvince || null, selectedCity: data.selectedCity || null, provinceCitySelectedAt: data.provinceCitySelectedAt || null, provinceCityConfirmedAt: data.provinceCityConfirmedAt || null, status: data.status, poolInjectionBatchId: data.poolInjectionBatchId || null, poolInjectionScheduledTime: data.poolInjectionScheduledTime || null, poolInjectionActualTime: data.poolInjectionActualTime || null, poolInjectionTxHash: data.poolInjectionTxHash || null, miningEnabledAt: data.miningEnabledAt || null, createdAt: data.createdAt || new Date(), paidAt: data.paidAt || null, fundAllocatedAt: data.fundAllocatedAt || null, }; const allocations = order.fundAllocations.map((a) => ({ orderId: data.id!, targetType: a.targetType, amount: new Prisma.Decimal(a.amount), targetAccountId: a.targetAccountId, metadata: (a.metadata as Prisma.InputJsonValue) || null, })); return { orderData, allocations }; } static mapFundAllocation(prisma: PrismaFundAllocation): FundAllocation { return new FundAllocation( prisma.targetType as FundAllocationTargetType, Number(prisma.amount), prisma.targetAccountId, prisma.metadata as Record | undefined, ); } }