88 lines
2.2 KiB
TypeScript
88 lines
2.2 KiB
TypeScript
import type { ApiSpendLimit } from "@api/billingControls";
|
|
import type { ApiSubjectV0 } from "@api/customers/apiSubjectV0";
|
|
import { apiSubjectToSpendLimit } from "@api/customers/utils/apiSubjectToSpendLimit";
|
|
import type { Feature } from "@models/featureModels/featureModels";
|
|
import { sumValues } from "@utils/utils";
|
|
import { Decimal } from "decimal.js";
|
|
import type { ApiBalanceBreakdownV1, ApiBalanceV1 } from "../../apiBalanceV1";
|
|
import { apiBalanceV1ToOverage } from "./apiBalanceV1ToOverage";
|
|
|
|
export const apiBalanceBreakdownV1ToMaxOverage = ({
|
|
apiBalanceBreakdown,
|
|
}: {
|
|
apiBalanceBreakdown: ApiBalanceBreakdownV1;
|
|
}): number | undefined => {
|
|
if (apiBalanceBreakdown.price?.billing_method === "usage_based") {
|
|
return apiBalanceBreakdown.price?.max_purchase ?? undefined;
|
|
}
|
|
|
|
return undefined;
|
|
};
|
|
|
|
export const apiBalanceV1ToMaxOverage = ({
|
|
apiBalance,
|
|
}: {
|
|
apiBalance: ApiBalanceV1;
|
|
}): number | undefined => {
|
|
const breakdownItems = apiBalance.breakdown ?? [];
|
|
|
|
const availableOverages = breakdownItems.map((item) =>
|
|
apiBalanceBreakdownV1ToMaxOverage({ apiBalanceBreakdown: item }),
|
|
);
|
|
|
|
if (availableOverages.some((overage) => overage === undefined)) {
|
|
return undefined;
|
|
}
|
|
|
|
return sumValues(
|
|
availableOverages.filter((overage) => overage !== undefined),
|
|
);
|
|
};
|
|
|
|
export type AvailableOverageResult = {
|
|
availableOverage: number | undefined;
|
|
reason?: "spend_limit" | "max_purchase";
|
|
};
|
|
|
|
export const apiBalanceV1ToAvailableOverage = ({
|
|
apiBalance,
|
|
apiSubject,
|
|
feature,
|
|
}: {
|
|
apiBalance: ApiBalanceV1;
|
|
apiSubject: ApiSubjectV0;
|
|
feature: Feature;
|
|
}): AvailableOverageResult => {
|
|
const overage = apiBalanceV1ToOverage({ apiBalance });
|
|
const spendLimit: ApiSpendLimit | undefined = apiSubject
|
|
? apiSubjectToSpendLimit({
|
|
subject: apiSubject,
|
|
feature,
|
|
})
|
|
: undefined;
|
|
|
|
if (spendLimit?.overage_limit !== undefined) {
|
|
return {
|
|
availableOverage: Math.max(
|
|
0,
|
|
new Decimal(spendLimit.overage_limit).sub(overage).toNumber(),
|
|
),
|
|
reason: "spend_limit",
|
|
};
|
|
}
|
|
|
|
const maxOverage = apiBalanceV1ToMaxOverage({ apiBalance });
|
|
|
|
if (maxOverage === undefined) {
|
|
return { availableOverage: undefined };
|
|
}
|
|
|
|
return {
|
|
availableOverage: Math.max(
|
|
0,
|
|
new Decimal(maxOverage).sub(overage).toNumber(),
|
|
),
|
|
reason: "max_purchase",
|
|
};
|
|
};
|