import { Injectable } from "@nestjs/common"; import { CreateOrderBody, UserMapping } from "../dto/order.dto"; import { getSalesforceFieldMap } from "../../common/config/field-map"; /** * Handles building order header data from selections */ @Injectable() export class OrderBuilder { /** * Build order fields for Salesforce Order creation */ buildOrderFields( body: CreateOrderBody, userMapping: UserMapping, pricebookId: string ): Record { const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD const fields = getSalesforceFieldMap(); const orderFields: Record = { AccountId: userMapping.sfAccountId, EffectiveDate: today, Status: "Pending Review", Pricebook2Id: pricebookId, [fields.order.orderType]: body.orderType, ...(body.opportunityId ? { OpportunityId: body.opportunityId } : {}), }; // Add activation fields this.addActivationFields(orderFields, body); // Add service-specific fields (only user configuration choices) switch (body.orderType) { case "Internet": this.addInternetFields(orderFields, body); break; case "SIM": this.addSimFields(orderFields, body); break; case "VPN": this.addVpnFields(orderFields, body); break; } // Add address snapshot from WHMCS (authoritative source) // Note: We'll need to pass userId separately or get it from the userMapping // For now, skip address snapshot until we have proper user ID access return orderFields; } private addActivationFields(orderFields: Record, body: CreateOrderBody): void { const fields = getSalesforceFieldMap(); const config = body.configurations || {}; if (config.activationType) { orderFields[fields.order.activationType] = config.activationType; } if (config.scheduledAt) { orderFields[fields.order.activationScheduledAt] = config.scheduledAt; } orderFields[fields.order.activationStatus] = "Not Started"; } private addInternetFields(orderFields: Record, body: CreateOrderBody): void { const fields = getSalesforceFieldMap(); const config = body.configurations || {}; // Only store user configuration choices that cannot be derived from OrderItems if (config.accessMode) { orderFields[fields.order.accessMode] = config.accessMode; } // Note: Removed fields that can be derived from OrderItems: // - internetPlanTier: derive from service product metadata // - installationType: derive from install product name // - weekendInstall: derive from SKU analysis // - hikariDenwa: derive from SKU analysis } private addSimFields(orderFields: Record, body: CreateOrderBody): void { const fields = getSalesforceFieldMap(); const config = body.configurations || {}; // Only store user configuration choices that cannot be derived from OrderItems if (config.simType) { orderFields[fields.order.simType] = config.simType; } if (config.eid) { orderFields[fields.order.eid] = config.eid; } // Note: Removed fields that can be derived from OrderItems: // - simVoiceMail: derive from SKU analysis // - simCallWaiting: derive from SKU analysis // MNP fields if (config.isMnp === "true") { orderFields[fields.order.mnp.application] = true; if (config.mnpNumber) { orderFields[fields.order.mnp.reservationNumber] = config.mnpNumber; } if (config.mnpExpiry) { orderFields[fields.order.mnp.expiryDate] = config.mnpExpiry; } if (config.mnpPhone) { orderFields[fields.order.mnp.phoneNumber] = config.mnpPhone; } if (config.mvnoAccountNumber) { orderFields[fields.order.mnp.mvnoAccountNumber] = config.mvnoAccountNumber; } if (config.portingLastName) { orderFields[fields.order.mnp.portingLastName] = config.portingLastName; } if (config.portingFirstName) { orderFields[fields.order.mnp.portingFirstName] = config.portingFirstName; } if (config.portingLastNameKatakana) { orderFields[fields.order.mnp.portingLastNameKatakana] = config.portingLastNameKatakana; } if (config.portingFirstNameKatakana) { orderFields[fields.order.mnp.portingFirstNameKatakana] = config.portingFirstNameKatakana; } if (config.portingGender) { orderFields[fields.order.mnp.portingGender] = config.portingGender; } if (config.portingDateOfBirth) { orderFields[fields.order.mnp.portingDateOfBirth] = config.portingDateOfBirth; } } } private addVpnFields(orderFields: Record, body: CreateOrderBody): void { // Note: Removed vpnRegion field - can be derived from service product metadata in OrderItems // VPN orders only need user configuration choices (none currently defined) } }