161 lines
4.4 KiB
TypeScript
161 lines
4.4 KiB
TypeScript
/**
|
|
* Orders Domain - Validation
|
|
*
|
|
* Extended business validation rules for orders.
|
|
* These rules represent domain logic and should be reusable across frontend/backend.
|
|
*/
|
|
|
|
import { z } from "zod";
|
|
import { orderBusinessValidationSchema } from "./schema.js";
|
|
|
|
// ============================================================================
|
|
// SKU Business Rules Helpers
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Check if SKUs array contains a SIM service plan
|
|
* (excludes activation fees and addons)
|
|
*/
|
|
export function hasSimServicePlan(skus: string[]): boolean {
|
|
return skus.some(
|
|
(sku) =>
|
|
sku.toUpperCase().includes("SIM") &&
|
|
!sku.toUpperCase().includes("ACTIVATION") &&
|
|
!sku.toUpperCase().includes("ADDON")
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if SKUs array contains a SIM activation fee
|
|
*/
|
|
export function hasSimActivationFee(skus: string[]): boolean {
|
|
return skus.some(
|
|
(sku) =>
|
|
sku.toUpperCase().includes("ACTIVATION") ||
|
|
sku.toUpperCase().includes("SIM-ACTIVATION")
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if SKUs array contains a VPN activation fee
|
|
*/
|
|
export function hasVpnActivationFee(skus: string[]): boolean {
|
|
return skus.some(
|
|
(sku) =>
|
|
sku.toUpperCase().includes("VPN") &&
|
|
sku.toUpperCase().includes("ACTIVATION")
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if SKUs array contains an Internet service plan
|
|
* (excludes installation and addons)
|
|
*/
|
|
export function hasInternetServicePlan(skus: string[]): boolean {
|
|
return skus.some(
|
|
(sku) =>
|
|
sku.toUpperCase().includes("INTERNET") &&
|
|
!sku.toUpperCase().includes("INSTALL") &&
|
|
!sku.toUpperCase().includes("ADDON")
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if SKUs array contains main service SKUs for Internet orders
|
|
* (filters out installation, addons, activation fees)
|
|
*/
|
|
export function getMainServiceSkus(skus: string[]): string[] {
|
|
return skus.filter((sku) => {
|
|
const upperSku = sku.toUpperCase();
|
|
return (
|
|
!upperSku.includes("INSTALL") &&
|
|
!upperSku.includes("ADDON") &&
|
|
!upperSku.includes("ACTIVATION") &&
|
|
!upperSku.includes("FEE")
|
|
);
|
|
});
|
|
}
|
|
|
|
// ============================================================================
|
|
// Extended Order Validation with SKU Business Rules
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Complete order validation including all SKU business rules
|
|
*
|
|
* This schema delegates to the helper functions above for DRY validation.
|
|
* Helper functions are reusable in both schema refinements and imperative validation.
|
|
*
|
|
* Validates:
|
|
* - Basic order structure (from orderBusinessValidationSchema)
|
|
* - SIM orders have service plan + activation fee
|
|
* - VPN orders have activation fee
|
|
* - Internet orders have service plan
|
|
*/
|
|
export const orderWithSkuValidationSchema = orderBusinessValidationSchema
|
|
.refine(
|
|
(data) => data.orderType !== "SIM" || hasSimServicePlan(data.skus),
|
|
{
|
|
message: "SIM orders must include a SIM service plan",
|
|
path: ["skus"],
|
|
}
|
|
)
|
|
.refine(
|
|
(data) => data.orderType !== "SIM" || hasSimActivationFee(data.skus),
|
|
{
|
|
message: "SIM orders require an activation fee",
|
|
path: ["skus"],
|
|
}
|
|
)
|
|
.refine(
|
|
(data) => data.orderType !== "VPN" || hasVpnActivationFee(data.skus),
|
|
{
|
|
message: "VPN orders require an activation fee",
|
|
path: ["skus"],
|
|
}
|
|
)
|
|
.refine(
|
|
(data) => data.orderType !== "Internet" || hasInternetServicePlan(data.skus),
|
|
{
|
|
message: "Internet orders require a service plan",
|
|
path: ["skus"],
|
|
}
|
|
);
|
|
|
|
export type OrderWithSkuValidation = z.infer<typeof orderWithSkuValidationSchema>;
|
|
|
|
// ============================================================================
|
|
// Validation Error Messages
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Get specific validation error message for order type
|
|
*/
|
|
export function getOrderTypeValidationError(orderType: string, skus: string[]): string | null {
|
|
switch (orderType) {
|
|
case "SIM":
|
|
if (!hasSimServicePlan(skus)) {
|
|
return "A SIM plan must be selected";
|
|
}
|
|
if (!hasSimActivationFee(skus)) {
|
|
return "SIM orders require an activation fee";
|
|
}
|
|
break;
|
|
|
|
case "VPN":
|
|
if (!hasVpnActivationFee(skus)) {
|
|
return "VPN orders require an activation fee";
|
|
}
|
|
break;
|
|
|
|
case "Internet":
|
|
if (!hasInternetServicePlan(skus)) {
|
|
return "Internet orders require a service plan";
|
|
}
|
|
break;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|