Files
cfw-autumn/shared/utils/cusEntUtils/convertCusEntUtils/cusEntsToMaxPurchase.ts
amianthus b0920f5eda feat: 🎸 boom
2026-01-06 12:38:36 +00:00

60 lines
1.5 KiB
TypeScript

import { Decimal } from "decimal.js";
import {
cusEntToIncludedUsage,
type FullCusEntWithFullCusProduct,
isPrepaidCusEnt,
notNullish,
nullish,
} from "../../../index.js";
export const cusEntsToMaxPurchase = ({
cusEnts,
entityId,
}: {
cusEnts: FullCusEntWithFullCusProduct[];
entityId?: string;
}): number | null => {
// 1. If there's usage-based cus ent, return undefined
if (
cusEnts.some(
(cusEnt) =>
cusEnt.usage_allowed && nullish(cusEnt.entitlement.usage_limit),
)
) {
return null;
}
const hasPrepaidNoLimit = cusEnts.some(
(ce) =>
isPrepaidCusEnt({ cusEnt: ce }) && nullish(ce.entitlement.usage_limit),
);
const hasPrepaid = cusEnts.some((ce) => isPrepaidCusEnt({ cusEnt: ce }));
const hasUsageBased = cusEnts.some((ce) => ce.usage_allowed);
// 2. If there's usage-based cus ent, and prepaid no limit
if (hasUsageBased && hasPrepaidNoLimit) return null;
// 3. If there's prepaid
if (hasPrepaidNoLimit) return null;
// 3. If there's no prepaid and no usage-based, return undefined (free feature)
if (!hasPrepaid && !hasUsageBased) return null;
let maxPurchase = new Decimal(0);
for (const cusEnt of cusEnts) {
const startingBalance = cusEntToIncludedUsage({
cusEnt,
entityId,
});
const usageLimit = cusEnt.entitlement.usage_limit;
if (notNullish(usageLimit) && notNullish(startingBalance)) {
maxPurchase = maxPurchase.add(
new Decimal(usageLimit).sub(startingBalance),
);
}
}
return maxPurchase.toNumber();
};