156 lines
5.2 KiB
TypeScript

/**
* Orders Domain - Salesforce Provider Mapper
*
* Transforms Salesforce Order and OrderItem records into domain contracts.
*/
import type {
OrderDetails,
OrderItemDetails,
OrderItemSummary,
OrderSummary,
} from "../../contract";
import { orderDetailsSchema, orderSummarySchema, orderItemDetailsSchema } from "../../schema";
import type {
SalesforceOrderItemRecord,
SalesforceOrderRecord,
} from "./raw.types";
/**
* Transform a Salesforce OrderItem record into domain details + summary.
*/
export function transformSalesforceOrderItem(
record: SalesforceOrderItemRecord
): { details: OrderItemDetails; summary: OrderItemSummary } {
// PricebookEntry is unknown to avoid circular dependencies between domains
const pricebookEntry = record.PricebookEntry as Record<string, any> | null | undefined;
const product = pricebookEntry?.Product2 as Record<string, any> | undefined;
const details = orderItemDetailsSchema.parse({
id: record.Id,
orderId: record.OrderId ?? "",
quantity: normalizeQuantity(record.Quantity),
unitPrice: coerceNumber(record.UnitPrice),
totalPrice: coerceNumber(record.TotalPrice),
billingCycle: record.Billing_Cycle__c ?? undefined,
product: product
? {
id: product.Id ?? undefined,
name: product.Name ?? undefined,
sku: product.StockKeepingUnit ?? undefined,
itemClass: product.Item_Class__c ?? undefined,
whmcsProductId: product.WH_Product_ID__c ? String(product.WH_Product_ID__c) : undefined,
internetOfferingType: product.Internet_Offering_Type__c ?? undefined,
internetPlanTier: product.Internet_Plan_Tier__c ?? undefined,
vpnRegion: product.VPN_Region__c ?? undefined,
}
: undefined,
});
return {
details,
summary: {
productName: details.product?.name,
name: details.product?.name,
sku: details.product?.sku,
status: undefined,
billingCycle: details.billingCycle,
itemClass: details.product?.itemClass,
quantity: details.quantity,
unitPrice: details.unitPrice,
totalPrice: details.totalPrice,
},
};
}
/**
* Transform a Salesforce Order record (with associated OrderItems) into domain OrderDetails.
*/
export function transformSalesforceOrderDetails(
order: SalesforceOrderRecord,
itemRecords: SalesforceOrderItemRecord[]
): OrderDetails {
const transformedItems = itemRecords.map(record =>
transformSalesforceOrderItem(record)
);
const items = transformedItems.map(item => item.details);
const itemsSummary = transformedItems.map(item => item.summary);
const summary = buildOrderSummary(order, itemsSummary);
return orderDetailsSchema.parse({
...summary,
accountId: order.AccountId ?? undefined,
accountName: typeof order.Account?.Name === "string" ? order.Account.Name : undefined,
pricebook2Id: order.Pricebook2Id ?? undefined,
activationType: order.Activation_Type__c ?? undefined,
activationStatus: summary.activationStatus,
activationScheduledAt: order.Activation_Scheduled_At__c ?? undefined,
activationErrorCode: order.Activation_Error_Code__c ?? undefined,
activationErrorMessage: order.Activation_Error_Message__c ?? undefined,
activatedDate: typeof order.ActivatedDate === "string" ? order.ActivatedDate : undefined,
items,
});
}
/**
* Transform a Salesforce Order record (with optional OrderItems) into domain OrderSummary.
*/
export function transformSalesforceOrderSummary(
order: SalesforceOrderRecord,
itemRecords: SalesforceOrderItemRecord[]
): OrderSummary {
const itemsSummary = itemRecords.map(record =>
transformSalesforceOrderItem(record).summary
);
return buildOrderSummary(order, itemsSummary);
}
function buildOrderSummary(
order: SalesforceOrderRecord,
itemsSummary: OrderItemSummary[]
): OrderSummary {
const effectiveDate =
ensureString(order.EffectiveDate) ??
ensureString(order.CreatedDate) ??
new Date().toISOString();
const createdDate = ensureString(order.CreatedDate) ?? effectiveDate;
const lastModifiedDate = ensureString(order.LastModifiedDate) ?? createdDate;
const totalAmount = coerceNumber(order.TotalAmount);
return orderSummarySchema.parse({
id: order.Id,
orderNumber: ensureString(order.OrderNumber) ?? order.Id,
status: ensureString(order.Status) ?? "Unknown",
orderType: order.Type ?? undefined,
effectiveDate,
totalAmount: typeof totalAmount === "number" ? totalAmount : undefined,
createdDate,
lastModifiedDate,
whmcsOrderId: order.WHMCS_Order_ID__c ?? undefined,
activationStatus: order.Activation_Status__c ?? undefined,
itemsSummary,
});
}
function ensureString(value: unknown): string | undefined {
return typeof value === "string" ? value : undefined;
}
function coerceNumber(value: unknown): number | undefined {
if (typeof value === "number") return Number.isFinite(value) ? value : undefined;
if (typeof value === "string") {
const parsed = Number.parseFloat(value);
return Number.isFinite(parsed) ? parsed : undefined;
}
return undefined;
}
function normalizeQuantity(value: unknown): number {
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
return Math.trunc(value);
}
return 1;
}