Disallow downgrades in package shop
This commit is contained in:
@@ -1,23 +1,76 @@
|
||||
import type { Package } from '../../api';
|
||||
|
||||
export function classifyPackageTier(price: number, activePrice: number | null): {
|
||||
type PackageChange = {
|
||||
isUpgrade: boolean;
|
||||
isDowngrade: boolean;
|
||||
} {
|
||||
if (activePrice === null) {
|
||||
};
|
||||
|
||||
function collectFeatures(pkg: Package | null): Set<string> {
|
||||
if (!pkg?.features) {
|
||||
return new Set();
|
||||
}
|
||||
|
||||
return new Set(Object.entries(pkg.features).filter(([, enabled]) => enabled).map(([key]) => key));
|
||||
}
|
||||
|
||||
function compareLimit(candidate: number | null, active: number | null): number {
|
||||
if (active === null) {
|
||||
return candidate === null ? 0 : -1;
|
||||
}
|
||||
|
||||
if (candidate === null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (candidate > active) return 1;
|
||||
if (candidate < active) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function classifyPackageChange(pkg: Package, active: Package | null): PackageChange {
|
||||
if (!active) {
|
||||
return { isUpgrade: false, isDowngrade: false };
|
||||
}
|
||||
|
||||
return {
|
||||
isUpgrade: price > activePrice,
|
||||
isDowngrade: price < activePrice,
|
||||
};
|
||||
const activeFeatures = collectFeatures(active);
|
||||
const candidateFeatures = collectFeatures(pkg);
|
||||
|
||||
const hasFeatureUpgrade = Array.from(candidateFeatures).some((feature) => !activeFeatures.has(feature));
|
||||
const hasFeatureDowngrade = Array.from(activeFeatures).some((feature) => !candidateFeatures.has(feature));
|
||||
|
||||
const limitKeys: Array<keyof Package> = ['max_photos', 'max_guests', 'gallery_days'];
|
||||
let hasLimitUpgrade = false;
|
||||
let hasLimitDowngrade = false;
|
||||
|
||||
limitKeys.forEach((key) => {
|
||||
const candidateLimit = pkg[key] ?? null;
|
||||
const activeLimit = active[key] ?? null;
|
||||
const delta = compareLimit(candidateLimit, activeLimit);
|
||||
if (delta > 0) {
|
||||
hasLimitUpgrade = true;
|
||||
} else if (delta < 0) {
|
||||
hasLimitDowngrade = true;
|
||||
}
|
||||
});
|
||||
|
||||
const hasUpgrade = hasFeatureUpgrade || hasLimitUpgrade;
|
||||
const hasDowngrade = hasFeatureDowngrade || hasLimitDowngrade;
|
||||
|
||||
if (hasUpgrade) {
|
||||
return { isUpgrade: true, isDowngrade: false };
|
||||
}
|
||||
|
||||
if (hasDowngrade) {
|
||||
return { isUpgrade: false, isDowngrade: true };
|
||||
}
|
||||
|
||||
return { isUpgrade: false, isDowngrade: false };
|
||||
}
|
||||
|
||||
export function selectRecommendedPackageId(
|
||||
packages: Package[],
|
||||
feature: string | null,
|
||||
activePrice: number | null
|
||||
activePackage: Package | null
|
||||
): number | null {
|
||||
if (!feature) {
|
||||
return null;
|
||||
@@ -28,12 +81,8 @@ export function selectRecommendedPackageId(
|
||||
return null;
|
||||
}
|
||||
|
||||
const upgradeCandidates =
|
||||
activePrice === null
|
||||
? candidates
|
||||
: candidates.filter((pkg) => pkg.price > activePrice);
|
||||
|
||||
const pool = upgradeCandidates.length ? upgradeCandidates : candidates;
|
||||
const upgrades = candidates.filter((pkg) => classifyPackageChange(pkg, activePackage).isUpgrade);
|
||||
const pool = upgrades.length ? upgrades : candidates;
|
||||
const sorted = [...pool].sort((a, b) => a.price - b.price);
|
||||
|
||||
return sorted[0]?.id ?? null;
|
||||
|
||||
Reference in New Issue
Block a user