Open JeffYYW opened 9 months ago
+1
@JeffYYW You can use Medusa cache module to not create a calculation every time, here is an example:
class TaxCalculationStrategy implements ITaxCalculationStrategy {
protected readonly logger: Logger;
protected readonly stripeService_: StripeService;
protected readonly cacheService_: ICacheService;
constructor({ logger, stripeService, cacheService }) {
this.logger = logger;
this.stripeService_ = stripeService;
this.cacheService_ = cacheService;
}
private deepSortObject = (obj: Record<string, any>) => {
if (Array.isArray(obj)) {
return _.sortBy(obj.map(this.deepSortObject), JSON.stringify);
} else if (_.isObject(obj)) {
const sortedEntries = _.toPairs(obj).sort();
const sortedObject = {};
sortedEntries.forEach(([key, value]) => {
sortedObject[key] = this.deepSortObject(value);
});
return sortedObject;
}
return obj;
};
private serializeCalculationContext(context: Record<string, any>) {
const sortedContext = this.deepSortObject(context);
return JSON.stringify(sortedContext);
}
private generateCartHash(input: string) {
return crypto.createHash("sha256").update(input).digest("hex");
}
async calculate(
items: LineItem[],
taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[],
calculationContext: TaxCalculationContext
): Promise<number> {
const { shipping_address, region } = calculationContext;
const context = {
currency: region.currency_code,
line_items: items,
shipping_address: shipping_address,
};
// Get neccessary data from the calculation context
const transformedContext =
this.stripeService_.getTranformedCalculationContext(context);
// Serialize the context to a string
const serializedCart = this.serializeCalculationContext(transformedContext);
// Generate a hash from the serialized context
const cacheKey = this.generateCartHash(serializedCart);
// Check if the hash exists in the cache
const cached: { value: number } = await this.cacheService_.get(cacheKey);
if (cached) {
return cached.value;
}
const calculatedTax = await this.stripeService_.calculateTax(context);
await this.cacheService_.set(cacheKey, { value: calculatedTax }, 60);
return calculatedTax;
}
}
Bug report
Describe the bug
I'm looking to override the tax calculation strategy as referenced in this guide to integrate a third-party service (Stripe Tax).
The issue is that the calculate method seems to get called 30+ times when I visit and refresh the 'orders' page in the admin at
app/a/orders
System information
Medusa version (including plugins):
Node.js version:
21.1.0
Database: PostGres Operating system: MacOS Browser (if relevant):Steps to reproduce the behavior
src/strategies/tax-calculation.ts
calculate
method as in code snippet below/app/a/orders
calculate
method in server logsExpected behavior
TaxCalculationStrategy override should not be called when viewing the admin dashboard.
Screenshots
Code snippets
src/strategies/tax-calculation.ts
Additional context
I'd be looking to do something like below and call the Stripe Tax calculation API