770 lines
19 KiB
TypeScript
770 lines
19 KiB
TypeScript
import {
|
|
AllowanceType,
|
|
AppEnv,
|
|
CusProductStatus,
|
|
Entity,
|
|
Event,
|
|
Feature,
|
|
FullCustomerEntitlement,
|
|
FullCustomerPrice,
|
|
Organization,
|
|
FullCusEntWithFullCusProduct,
|
|
BillingType,
|
|
FeatureUsageType,
|
|
} from "@autumn/shared";
|
|
import { CusEntService } from "@/internal/customers/cusProducts/cusEnts/CusEntitlementService.js";
|
|
import { Customer, FeatureType } from "@autumn/shared";
|
|
import { getCusEntsInFeatures } from "@/internal/customers/cusUtils/cusUtils.js";
|
|
import { Decimal } from "decimal.js";
|
|
import { adjustAllowance } from "./adjustAllowance.js";
|
|
import {
|
|
getMeteredDeduction,
|
|
getCreditSystemDeduction,
|
|
performDeduction,
|
|
} from "./deductUtils.js";
|
|
|
|
import { notNullish, nullish } from "@/utils/genUtils.js";
|
|
import {
|
|
creditSystemContainsFeature,
|
|
featureToCreditSystem,
|
|
} from "@/internal/features/creditSystemUtils.js";
|
|
import {
|
|
getCusEntMasterBalance,
|
|
getRelatedCusPrice,
|
|
getResetBalance,
|
|
getTotalNegativeBalance,
|
|
} from "@/internal/customers/cusProducts/cusEnts/cusEntUtils.js";
|
|
import { entityFeatureIdExists } from "@/internal/api/entities/entityUtils.js";
|
|
import { CusService } from "@/internal/customers/CusService.js";
|
|
import { DrizzleCli } from "@/db/initDrizzle.js";
|
|
import { findCusEnt } from "@/internal/customers/cusProducts/cusEnts/cusEntUtils/findCusEntUtils.js";
|
|
import {
|
|
getBillingType,
|
|
getEntOptions,
|
|
} from "@/internal/products/prices/priceUtils.js";
|
|
import { deductFromCusRollovers } from "@/internal/customers/cusProducts/cusEnts/cusRollovers/rolloverDeductionUtils.js";
|
|
import { refreshCusCache } from "@/internal/customers/cusCache/updateCachedCus.js";
|
|
import { handleThresholdReached } from "./handleThresholdReached.js";
|
|
|
|
// Decimal.set({ precision: 12 }); // 12 DP precision
|
|
|
|
export type DeductParams = {
|
|
db: DrizzleCli;
|
|
env: AppEnv;
|
|
org: Organization;
|
|
cusPrices: FullCustomerPrice[];
|
|
customer: Customer;
|
|
properties: any;
|
|
feature: Feature;
|
|
entity?: Entity;
|
|
};
|
|
|
|
export type RolloverDeductParams = {
|
|
db: DrizzleCli;
|
|
env: AppEnv;
|
|
feature: Feature;
|
|
entity?: Entity;
|
|
};
|
|
|
|
// 2. Get deductions for each feature
|
|
const getFeatureDeductions = ({
|
|
cusEnts,
|
|
event,
|
|
features,
|
|
}: {
|
|
cusEnts: FullCustomerEntitlement[];
|
|
event: Event;
|
|
features: Feature[];
|
|
}) => {
|
|
const meteredFeatures = features.filter(
|
|
(feature) => feature.type === FeatureType.Metered
|
|
);
|
|
const featureDeductions = [];
|
|
for (const feature of features) {
|
|
let deduction;
|
|
if (feature.type === FeatureType.Metered) {
|
|
deduction = getMeteredDeduction(feature, event);
|
|
} else if (feature.type === FeatureType.CreditSystem) {
|
|
deduction = getCreditSystemDeduction({
|
|
meteredFeatures: meteredFeatures,
|
|
creditSystem: feature,
|
|
event,
|
|
});
|
|
}
|
|
|
|
// Check if unlimited exists
|
|
let unlimitedExists = cusEnts.some(
|
|
(cusEnt) =>
|
|
cusEnt.entitlement.allowance_type === AllowanceType.Unlimited &&
|
|
cusEnt.entitlement.internal_feature_id == feature.internal_id
|
|
);
|
|
|
|
if (unlimitedExists || !deduction) {
|
|
continue;
|
|
}
|
|
|
|
featureDeductions.push({
|
|
feature,
|
|
deduction,
|
|
});
|
|
}
|
|
|
|
featureDeductions.sort((a, b) => {
|
|
if (
|
|
a.feature.type === FeatureType.CreditSystem &&
|
|
b.feature.type !== FeatureType.CreditSystem
|
|
) {
|
|
return 1;
|
|
}
|
|
|
|
if (
|
|
a.feature.type !== FeatureType.CreditSystem &&
|
|
b.feature.type === FeatureType.CreditSystem
|
|
) {
|
|
return -1;
|
|
}
|
|
|
|
return a.feature.id.localeCompare(b.feature.id);
|
|
});
|
|
|
|
return featureDeductions;
|
|
};
|
|
|
|
export const logBalanceUpdate = ({
|
|
timeTaken,
|
|
customer,
|
|
features,
|
|
cusEnts,
|
|
featureDeductions,
|
|
properties,
|
|
entityId,
|
|
org,
|
|
}: {
|
|
timeTaken: string;
|
|
customer: Customer;
|
|
features: Feature[];
|
|
cusEnts: FullCustomerEntitlement[];
|
|
featureDeductions: any;
|
|
properties: any;
|
|
entityId?: string | null;
|
|
org: Organization;
|
|
}) => {
|
|
console.log(
|
|
` - Customer: ${customer.id} (${customer.env}) | Org: ${
|
|
org.slug
|
|
} | Features: ${features.map((f) => f.id).join(", ")}`
|
|
);
|
|
console.log(" - Properties:", properties);
|
|
console.log(
|
|
" - CusEnts:",
|
|
cusEnts.map((cusEnt: any) => {
|
|
let balanceStr = cusEnt.balance;
|
|
|
|
if (notNullish(cusEnt.entitlement.entity_feature_id)) {
|
|
console.log(
|
|
` - Entity feature ID found for feature: ${cusEnt.feature_id}`
|
|
);
|
|
|
|
if (notNullish(entityId)) {
|
|
balanceStr = `${cusEnt.entities?.[entityId!]?.balance} [${entityId}]`;
|
|
} else {
|
|
balanceStr = `${
|
|
getCusEntMasterBalance({
|
|
cusEnt,
|
|
entities: cusEnt.customer_product?.entities,
|
|
}).balance
|
|
} [Master]`;
|
|
}
|
|
}
|
|
try {
|
|
if (cusEnt.entitlement.allowance_type === AllowanceType.Unlimited) {
|
|
balanceStr = "Unlimited";
|
|
}
|
|
} catch (error) {
|
|
balanceStr = "failed_to_get_balance";
|
|
}
|
|
|
|
return `${cusEnt.feature_id} - ${balanceStr} (${
|
|
cusEnt.customer_product ? cusEnt.customer_product.product_id : ""
|
|
})`;
|
|
}),
|
|
"| Deductions:",
|
|
featureDeductions.map((f: any) => `${f.feature.id}: ${f.deduction}`)
|
|
);
|
|
};
|
|
|
|
export const performDeductionOnCusEnt = ({
|
|
cusEnt,
|
|
toDeduct,
|
|
entityId,
|
|
allowNegativeBalance = false,
|
|
addAdjustment = false,
|
|
setZeroAdjustment = false,
|
|
blockUsageLimit = true,
|
|
}: {
|
|
cusEnt: FullCusEntWithFullCusProduct;
|
|
toDeduct: number;
|
|
entityId?: string | null;
|
|
allowNegativeBalance?: boolean;
|
|
addAdjustment?: boolean;
|
|
setZeroAdjustment?: boolean;
|
|
blockUsageLimit?: boolean;
|
|
}) => {
|
|
let newEntities = structuredClone(cusEnt.entities);
|
|
let newBalance = structuredClone(cusEnt.balance);
|
|
let newAdjustment = structuredClone(cusEnt.adjustment);
|
|
let deducted = 0;
|
|
|
|
let cusProduct = cusEnt.customer_product;
|
|
let options = notNullish(cusProduct)
|
|
? getEntOptions(cusProduct.options, cusEnt.entitlement)
|
|
: undefined;
|
|
let cusPrice = notNullish(cusProduct)
|
|
? getRelatedCusPrice(cusEnt, cusProduct.customer_prices)
|
|
: undefined;
|
|
let resetBalance = notNullish(cusProduct)
|
|
? getResetBalance({
|
|
options,
|
|
relatedPrice: cusPrice?.price,
|
|
entitlement: cusEnt.entitlement,
|
|
})
|
|
: cusEnt.entitlement.allowance || 0;
|
|
|
|
if (entityFeatureIdExists({ cusEnt })) {
|
|
if (nullish(entityId)) {
|
|
// 1. If no entity ID, deduct from all
|
|
newEntities = structuredClone(cusEnt.entities);
|
|
if (!newEntities) {
|
|
newEntities = {};
|
|
}
|
|
let toDeductCursor = toDeduct;
|
|
for (const entityId in cusEnt.entities) {
|
|
if (toDeductCursor == 0) {
|
|
break;
|
|
}
|
|
|
|
let entityBalance = cusEnt.entities[entityId].balance;
|
|
|
|
let {
|
|
newBalance: newEntityBalance,
|
|
deducted: newDeducted,
|
|
toDeduct: newToDeduct,
|
|
} = performDeduction({
|
|
cusEntBalance: new Decimal(entityBalance),
|
|
toDeduct: toDeductCursor,
|
|
allowNegativeBalance,
|
|
ent: cusEnt.entitlement,
|
|
resetBalance,
|
|
blockUsageLimit,
|
|
});
|
|
|
|
newEntities[entityId].balance = newEntityBalance!;
|
|
|
|
if (addAdjustment) {
|
|
let adjustment = newEntities![entityId!]!.adjustment || 0;
|
|
newEntities![entityId!]!.adjustment = adjustment - newDeducted!;
|
|
}
|
|
|
|
if (setZeroAdjustment) {
|
|
newEntities![entityId!]!.adjustment = 0;
|
|
}
|
|
|
|
toDeductCursor = newToDeduct!;
|
|
deducted += newDeducted!;
|
|
}
|
|
|
|
toDeduct = toDeductCursor;
|
|
} else {
|
|
// 2. If entity ID, deduct from that entity
|
|
let currentEntityBalance = cusEnt.entities?.[entityId!]?.balance;
|
|
|
|
let {
|
|
newBalance: newEntityBalance,
|
|
deducted: newDeducted,
|
|
toDeduct: newToDeduct,
|
|
} = performDeduction({
|
|
cusEntBalance: new Decimal(currentEntityBalance!),
|
|
toDeduct,
|
|
allowNegativeBalance,
|
|
ent: cusEnt.entitlement,
|
|
resetBalance,
|
|
blockUsageLimit,
|
|
});
|
|
|
|
newEntities![entityId!]!.balance = newEntityBalance!;
|
|
|
|
if (addAdjustment) {
|
|
let adjustment = newEntities![entityId!]!.adjustment || 0;
|
|
newEntities![entityId!]!.adjustment = adjustment - newDeducted!;
|
|
}
|
|
|
|
if (setZeroAdjustment) {
|
|
newEntities![entityId!]!.adjustment = 0;
|
|
}
|
|
|
|
toDeduct = newToDeduct!;
|
|
deducted += newDeducted!;
|
|
}
|
|
} else {
|
|
let {
|
|
newBalance: newBalance_,
|
|
deducted: deducted_,
|
|
toDeduct: newToDeduct_,
|
|
} = performDeduction({
|
|
cusEntBalance: new Decimal(cusEnt.balance!),
|
|
toDeduct,
|
|
allowNegativeBalance,
|
|
ent: cusEnt.entitlement,
|
|
resetBalance,
|
|
blockUsageLimit,
|
|
});
|
|
|
|
newBalance = newBalance_;
|
|
deducted = deducted_;
|
|
toDeduct = newToDeduct_;
|
|
|
|
if (addAdjustment) {
|
|
let adjustment = cusEnt.adjustment || 0;
|
|
newAdjustment = adjustment - deducted!;
|
|
}
|
|
}
|
|
return { newBalance, newEntities, deducted, toDeduct, newAdjustment };
|
|
};
|
|
|
|
export const deductAllowanceFromCusEnt = async ({
|
|
toDeduct,
|
|
deductParams,
|
|
cusEnt,
|
|
featureDeductions,
|
|
willDeductCredits = false,
|
|
setZeroAdjustment = false,
|
|
}: {
|
|
toDeduct: number;
|
|
deductParams: DeductParams;
|
|
cusEnt: FullCusEntWithFullCusProduct;
|
|
featureDeductions: any;
|
|
willDeductCredits?: boolean;
|
|
setZeroAdjustment?: boolean;
|
|
}) => {
|
|
const { db, feature, env, org, cusPrices, customer, entity } = deductParams;
|
|
|
|
if (toDeduct == 0) {
|
|
}
|
|
|
|
if (
|
|
entity &&
|
|
entityFeatureIdExists({ cusEnt }) &&
|
|
cusEnt.entitlement.entity_feature_id !== entity.feature_id
|
|
)
|
|
return toDeduct;
|
|
|
|
let {
|
|
newBalance,
|
|
newEntities,
|
|
deducted,
|
|
toDeduct: newToDeduct,
|
|
} = performDeductionOnCusEnt({
|
|
cusEnt,
|
|
toDeduct,
|
|
entityId: entity?.id,
|
|
allowNegativeBalance: false,
|
|
setZeroAdjustment,
|
|
});
|
|
|
|
let originalGrpBalance = getTotalNegativeBalance({
|
|
cusEnt,
|
|
balance: cusEnt.balance!,
|
|
entities: cusEnt.entities!,
|
|
});
|
|
|
|
let newGrpBalance = getTotalNegativeBalance({
|
|
cusEnt,
|
|
balance: newBalance!,
|
|
entities: newEntities!,
|
|
});
|
|
|
|
let updates: any = {
|
|
balance: newBalance,
|
|
entities: newEntities,
|
|
};
|
|
if (setZeroAdjustment) {
|
|
updates.adjustment = 0;
|
|
}
|
|
|
|
const { newReplaceables, deletedReplaceables } = await adjustAllowance({
|
|
db,
|
|
env,
|
|
org,
|
|
cusPrices: cusPrices as any,
|
|
customer,
|
|
affectedFeature: feature,
|
|
cusEnt: cusEnt as any,
|
|
originalBalance: originalGrpBalance,
|
|
newBalance: newGrpBalance,
|
|
logger: console,
|
|
});
|
|
|
|
if (newReplaceables && newReplaceables.length > 0) {
|
|
updates.balance = newBalance! - newReplaceables.length;
|
|
} else if (deletedReplaceables && deletedReplaceables.length > 0) {
|
|
updates.balance = newBalance! + deletedReplaceables.length;
|
|
}
|
|
|
|
await CusEntService.update({
|
|
db,
|
|
id: cusEnt.id,
|
|
updates,
|
|
});
|
|
|
|
// Deduct credit amounts too
|
|
if (feature.type === FeatureType.Metered && willDeductCredits) {
|
|
for (let i = 0; i < featureDeductions.length; i++) {
|
|
let { feature: creditSystem, deduction } = featureDeductions[i];
|
|
|
|
if (
|
|
creditSystem.type === FeatureType.CreditSystem &&
|
|
creditSystemContainsFeature({
|
|
creditSystem: creditSystem,
|
|
meteredFeatureId: feature.id!,
|
|
})
|
|
) {
|
|
// toDeduct -= deduction;
|
|
let creditAmount = featureToCreditSystem({
|
|
featureId: feature.id!,
|
|
creditSystem: creditSystem,
|
|
amount: deducted,
|
|
});
|
|
let newDeduction = new Decimal(deduction)
|
|
.minus(creditAmount)
|
|
.toNumber();
|
|
|
|
featureDeductions[i].deduction = newDeduction;
|
|
}
|
|
}
|
|
}
|
|
|
|
cusEnt.balance = newBalance;
|
|
cusEnt.entities = newEntities;
|
|
|
|
return newToDeduct;
|
|
};
|
|
|
|
export const deductFromUsageBasedCusEnt = async ({
|
|
toDeduct,
|
|
deductParams,
|
|
cusEnts,
|
|
setZeroAdjustment = false,
|
|
}: {
|
|
toDeduct: number;
|
|
deductParams: DeductParams;
|
|
cusEnts: FullCusEntWithFullCusProduct[];
|
|
setZeroAdjustment?: boolean;
|
|
}) => {
|
|
const { db, feature, env, org, cusPrices, customer, entity } = deductParams;
|
|
|
|
// Deduct from usage-based price
|
|
let usageBasedEnt = findCusEnt({
|
|
cusEnts,
|
|
feature,
|
|
entity,
|
|
onlyUsageAllowed: true,
|
|
}) as FullCusEntWithFullCusProduct;
|
|
|
|
if (
|
|
!usageBasedEnt &&
|
|
feature.config?.usage_type == FeatureUsageType.Continuous
|
|
) {
|
|
console.log(`FALLING BACK TO REGULAR CUS ENT, FEATURE: ${feature.id}`);
|
|
usageBasedEnt = findCusEnt({
|
|
cusEnts,
|
|
feature,
|
|
entity,
|
|
}) as FullCusEntWithFullCusProduct; // fallback to regular cus ent if allowed...
|
|
}
|
|
|
|
if (!usageBasedEnt) {
|
|
console.log(
|
|
` - Feature ${feature.id}, To deduct: ${toDeduct} -> no usage-based entitlement found`
|
|
);
|
|
return;
|
|
}
|
|
|
|
let cusPrice = getRelatedCusPrice(usageBasedEnt, cusPrices);
|
|
let billingType = cusPrice?.price
|
|
? getBillingType(cusPrice?.price.config!)
|
|
: undefined;
|
|
let blockUsageLimit =
|
|
billingType === BillingType.InArrearProrated ? false : true;
|
|
|
|
let { newBalance, newEntities, deducted } = performDeductionOnCusEnt({
|
|
cusEnt: usageBasedEnt,
|
|
toDeduct,
|
|
allowNegativeBalance: true,
|
|
setZeroAdjustment,
|
|
entityId: entity?.id,
|
|
blockUsageLimit,
|
|
});
|
|
|
|
let oldGrpBalance = getTotalNegativeBalance({
|
|
cusEnt: usageBasedEnt,
|
|
balance: usageBasedEnt.balance!,
|
|
entities: usageBasedEnt.entities!,
|
|
});
|
|
|
|
let newGrpBalance = getTotalNegativeBalance({
|
|
cusEnt: usageBasedEnt,
|
|
balance: newBalance!,
|
|
entities: newEntities!,
|
|
});
|
|
|
|
// Update usageBasedEnt in place with the deduction results
|
|
usageBasedEnt.balance = newBalance;
|
|
usageBasedEnt.entities = newEntities;
|
|
if (setZeroAdjustment) {
|
|
usageBasedEnt.adjustment = 0;
|
|
}
|
|
|
|
let updates: any = {
|
|
balance: newBalance,
|
|
entities: newEntities,
|
|
};
|
|
if (setZeroAdjustment) {
|
|
updates.adjustment = 0;
|
|
}
|
|
|
|
const { newReplaceables, deletedReplaceables } = await adjustAllowance({
|
|
db,
|
|
env,
|
|
affectedFeature: feature,
|
|
org,
|
|
cusEnt: usageBasedEnt as any,
|
|
cusPrices: cusPrices as any,
|
|
customer,
|
|
originalBalance: oldGrpBalance,
|
|
newBalance: newGrpBalance,
|
|
logger: console,
|
|
});
|
|
|
|
if (newReplaceables && newReplaceables.length > 0) {
|
|
const finalBalance = newBalance! - newReplaceables.length;
|
|
updates.balance = finalBalance;
|
|
usageBasedEnt.balance = finalBalance;
|
|
} else if (deletedReplaceables && deletedReplaceables.length > 0) {
|
|
const finalBalance = newBalance! + deletedReplaceables.length;
|
|
updates.balance = finalBalance;
|
|
usageBasedEnt.balance = finalBalance;
|
|
}
|
|
|
|
await CusEntService.update({
|
|
db,
|
|
id: usageBasedEnt!.id,
|
|
updates,
|
|
});
|
|
|
|
console.log("Usage based cus ent balance", usageBasedEnt.balance);
|
|
};
|
|
|
|
// Main function to update customer balance
|
|
export const updateCustomerBalance = async ({
|
|
db,
|
|
customerId,
|
|
entityId,
|
|
event,
|
|
features,
|
|
org,
|
|
env,
|
|
logger,
|
|
allFeatures,
|
|
}: {
|
|
db: DrizzleCli;
|
|
customerId: string;
|
|
entityId: string;
|
|
event: Event;
|
|
features: Feature[];
|
|
org: Organization;
|
|
env: AppEnv;
|
|
logger: any;
|
|
allFeatures: Feature[];
|
|
}) => {
|
|
const startTime = performance.now();
|
|
console.log("REVERSE DEDUCTION ORDER", org.config.reverse_deduction_order);
|
|
const customer = await CusService.getFull({
|
|
db,
|
|
idOrInternalId: customerId,
|
|
orgId: org.id,
|
|
env,
|
|
inStatuses: [CusProductStatus.Active, CusProductStatus.PastDue],
|
|
entityId,
|
|
});
|
|
|
|
const { cusEnts, cusPrices } = await getCusEntsInFeatures({
|
|
customer,
|
|
internalFeatureIds: features.map((f) => f.internal_id!),
|
|
logger,
|
|
reverseOrder: org.config.reverse_deduction_order,
|
|
});
|
|
|
|
const endTime = performance.now();
|
|
|
|
// 1. Get deductions for each feature
|
|
const featureDeductions = getFeatureDeductions({
|
|
cusEnts,
|
|
event,
|
|
features,
|
|
});
|
|
|
|
logBalanceUpdate({
|
|
timeTaken: (endTime - startTime).toFixed(2),
|
|
customer,
|
|
features,
|
|
cusEnts,
|
|
featureDeductions,
|
|
properties: event.properties,
|
|
org,
|
|
entityId: event.entity_id,
|
|
});
|
|
|
|
// 3. Return if no customer entitlements or features found
|
|
if (cusEnts.length === 0 || features.length === 0) {
|
|
console.log(" - No customer entitlements or features found");
|
|
return;
|
|
}
|
|
|
|
// 4. Perform deductions and update customer balance
|
|
for (const obj of featureDeductions) {
|
|
let { feature, deduction: toDeduct } = obj;
|
|
|
|
const originalCusEnts = structuredClone(cusEnts);
|
|
|
|
for (const cusEnt of cusEnts) {
|
|
if (cusEnt.entitlement.internal_feature_id != feature.internal_id) {
|
|
continue;
|
|
}
|
|
|
|
toDeduct = await deductFromCusRollovers({
|
|
toDeduct,
|
|
cusEnt,
|
|
deductParams: {
|
|
db,
|
|
feature,
|
|
env,
|
|
entity: customer.entity ? customer.entity : undefined,
|
|
},
|
|
});
|
|
|
|
if (toDeduct == 0) continue;
|
|
|
|
toDeduct = await deductAllowanceFromCusEnt({
|
|
toDeduct,
|
|
cusEnt,
|
|
deductParams: {
|
|
db,
|
|
feature,
|
|
env,
|
|
org,
|
|
cusPrices: cusPrices as any[],
|
|
customer,
|
|
properties: event.properties,
|
|
entity: customer.entity,
|
|
},
|
|
featureDeductions,
|
|
willDeductCredits: true,
|
|
});
|
|
}
|
|
|
|
if (toDeduct !== 0) {
|
|
await deductFromUsageBasedCusEnt({
|
|
toDeduct,
|
|
cusEnts,
|
|
deductParams: {
|
|
db,
|
|
feature,
|
|
env,
|
|
org,
|
|
cusPrices: cusPrices as any[],
|
|
customer,
|
|
properties: event.properties,
|
|
entity: customer.entity,
|
|
},
|
|
});
|
|
}
|
|
|
|
handleThresholdReached({
|
|
org,
|
|
env,
|
|
features: allFeatures,
|
|
db,
|
|
feature,
|
|
cusEnts: originalCusEnts,
|
|
newCusEnts: cusEnts,
|
|
fullCus: customer,
|
|
logger,
|
|
});
|
|
}
|
|
|
|
return cusEnts;
|
|
};
|
|
|
|
// MAIN FUNCTION
|
|
export const runUpdateBalanceTask = async ({
|
|
payload,
|
|
logger,
|
|
db,
|
|
}: {
|
|
payload: any;
|
|
logger: any;
|
|
db: DrizzleCli;
|
|
}) => {
|
|
try {
|
|
// 1. Update customer balance
|
|
const { customerId, features, event, org, env, entityId, allFeatures } =
|
|
payload;
|
|
|
|
console.log("--------------------------------");
|
|
console.log(
|
|
`UPDATING BALANCE FOR CUSTOMER (${customerId}), ORG: ${org.slug}`
|
|
);
|
|
|
|
const cusEnts: any = await updateCustomerBalance({
|
|
db,
|
|
customerId,
|
|
features,
|
|
event,
|
|
org,
|
|
env,
|
|
logger,
|
|
entityId,
|
|
allFeatures,
|
|
});
|
|
|
|
// console.time("refreshCusCache");
|
|
await refreshCusCache({
|
|
db,
|
|
customerId,
|
|
org,
|
|
env,
|
|
entityId,
|
|
});
|
|
// console.timeEnd("refreshCusCache");
|
|
|
|
if (!cusEnts || cusEnts.length === 0) {
|
|
return;
|
|
}
|
|
console.log(" ✅ Customer balance updated");
|
|
} catch (error) {
|
|
if (logger) {
|
|
logger.use((log: any) => {
|
|
return {
|
|
...log,
|
|
data: payload,
|
|
};
|
|
});
|
|
|
|
logger.error(`ERROR UPDATING BALANCE`);
|
|
logger.error(error);
|
|
} else {
|
|
console.log(error);
|
|
}
|
|
}
|
|
};
|