rwadurian/backend/services/planting-service/src/infrastructure/persistence/mappers/planting-order.mapper.ts

119 lines
4.3 KiB
TypeScript

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<string, unknown> | undefined,
);
}
}