2025-08-28 16:57:57 +09:00
|
|
|
import {
|
|
|
|
|
IsString,
|
|
|
|
|
IsArray,
|
|
|
|
|
IsIn,
|
|
|
|
|
IsNotEmpty,
|
|
|
|
|
IsOptional,
|
|
|
|
|
IsObject,
|
|
|
|
|
ValidateNested,
|
|
|
|
|
} from "class-validator";
|
|
|
|
|
import { Type } from "class-transformer";
|
|
|
|
|
|
|
|
|
|
export class OrderConfigurations {
|
|
|
|
|
// Activation (All order types)
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsIn(["Immediate", "Scheduled"])
|
|
|
|
|
activationType?: "Immediate" | "Scheduled";
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
scheduledAt?: string;
|
|
|
|
|
|
|
|
|
|
// Internet specific
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsIn(["IPoE-BYOR", "IPoE-HGW", "PPPoE"])
|
|
|
|
|
accessMode?: "IPoE-BYOR" | "IPoE-HGW" | "PPPoE";
|
|
|
|
|
|
|
|
|
|
// SIM specific
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsIn(["eSIM", "Physical SIM"])
|
|
|
|
|
simType?: "eSIM" | "Physical SIM";
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
eid?: string; // Required for eSIM
|
|
|
|
|
|
|
|
|
|
// MNP/Porting
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
isMnp?: string; // "true" | "false"
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
mnpNumber?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
mnpExpiry?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
mnpPhone?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
mvnoAccountNumber?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
portingLastName?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
portingFirstName?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
portingLastNameKatakana?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
portingFirstNameKatakana?: string;
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsIn(["Male", "Female", "Corporate/Other"])
|
|
|
|
|
portingGender?: "Male" | "Female" | "Corporate/Other";
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsString()
|
|
|
|
|
portingDateOfBirth?: string;
|
|
|
|
|
|
2025-08-30 18:51:51 +09:00
|
|
|
// Address (when address is updated during checkout)
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsObject()
|
|
|
|
|
address?: {
|
|
|
|
|
street?: string | null;
|
|
|
|
|
streetLine2?: string | null;
|
|
|
|
|
city?: string | null;
|
|
|
|
|
state?: string | null;
|
|
|
|
|
postalCode?: string | null;
|
|
|
|
|
country?: string | null;
|
|
|
|
|
};
|
|
|
|
|
|
2025-08-28 16:57:57 +09:00
|
|
|
// VPN region is inferred from product VPN_Region__c field, no user input needed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class CreateOrderDto {
|
|
|
|
|
@IsString()
|
|
|
|
|
@IsNotEmpty()
|
|
|
|
|
@IsIn(["Internet", "SIM", "VPN", "Other"])
|
|
|
|
|
orderType: "Internet" | "SIM" | "VPN" | "Other";
|
|
|
|
|
|
|
|
|
|
@IsArray()
|
|
|
|
|
@IsString({ each: true })
|
|
|
|
|
@IsNotEmpty({ each: true })
|
|
|
|
|
skus: string[];
|
|
|
|
|
|
|
|
|
|
@IsOptional()
|
|
|
|
|
@IsObject()
|
|
|
|
|
@ValidateNested()
|
|
|
|
|
@Type(() => OrderConfigurations)
|
|
|
|
|
configurations?: OrderConfigurations;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Interface for service layer (extends DTO with additional fields)
|
|
|
|
|
export interface CreateOrderBody extends Omit<CreateOrderDto, "configurations"> {
|
|
|
|
|
configurations?: OrderConfigurations;
|
|
|
|
|
opportunityId?: string; // Additional field for internal use
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UserMapping {
|
|
|
|
|
sfAccountId: string;
|
|
|
|
|
whmcsClientId: number;
|
|
|
|
|
}
|