Files
cfw-autumn/shared/utils/cusUtils/fullCusUtils/fullCustomerToSpendLimit.ts
2026-04-24 21:12:04 +01:00

87 lines
2.5 KiB
TypeScript

import type { DbSpendLimit } from "@models/cusModels/billingControls/customerBillingControls.js";
import type { FullCustomer } from "@models/cusModels/fullCusModel.js";
import { cusEntToCusPrice } from "@utils/cusEntUtils";
import { isPayPerUsePrice } from "@utils/productUtils/priceUtils/index";
import { fullCustomerToCustomerEntitlements } from "./fullCustomerToCustomerEntitlements";
/**
* Extract enabled spend limits for the requested features from a FullCustomer.
*
* Entity inherits from the customer per feature_id: entity's entry wins when
* present, customer's entry fills any gaps.
*/
export const fullCustomerToSpendLimitByFeatureId = ({
fullCustomer,
featureIds,
internalEntityId,
}: {
fullCustomer: FullCustomer;
featureIds: string[];
internalEntityId?: string;
}): Record<string, DbSpendLimit> => {
const entity = internalEntityId
? fullCustomer.entities?.find(
(candidate) => candidate.internal_id === internalEntityId,
)
: fullCustomer.entity;
const entitySpendLimits = entity?.spend_limits ?? [];
const customerSpendLimits = fullCustomer.spend_limits ?? [];
const spendLimitByFeatureId: Record<string, DbSpendLimit> = {};
const uniqueFeatureIds = [...new Set(featureIds)];
for (const featureId of uniqueFeatureIds) {
const isMatch = (candidate: DbSpendLimit) =>
candidate.feature_id === featureId &&
candidate.enabled &&
candidate.overage_limit !== undefined;
const spendLimit =
entitySpendLimits.find(isMatch) ?? customerSpendLimits.find(isMatch);
if (spendLimit) {
spendLimitByFeatureId[featureId] = spendLimit;
}
}
return spendLimitByFeatureId;
};
export const fullCustomerToUsageBasedCusEntsByFeatureId = ({
fullCustomer,
featureIds,
internalEntityId,
}: {
fullCustomer: FullCustomer;
featureIds: string[];
internalEntityId?: string;
}): Record<string, string[]> => {
const entity = internalEntityId
? fullCustomer.entities?.find(
(candidate) => candidate.internal_id === internalEntityId,
)
: fullCustomer.entity;
const cusEnts = fullCustomerToCustomerEntitlements({
fullCustomer,
featureIds,
entity,
});
const usageBasedCusEntsByFeatureId: Record<string, string[]> = {};
for (const cusEnt of cusEnts) {
const cusPrice = cusEntToCusPrice({ cusEnt });
if (!cusPrice || !isPayPerUsePrice({ price: cusPrice.price })) {
continue;
}
if (!usageBasedCusEntsByFeatureId[cusEnt.feature_id]) {
usageBasedCusEntsByFeatureId[cusEnt.feature_id] = [];
}
usageBasedCusEntsByFeatureId[cusEnt.feature_id].push(cusEnt.id);
}
return usageBasedCusEntsByFeatureId;
};