Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): update orderLine on applyPriceAdjustments #2663

Open
wants to merge 1 commit into
base: minor
Choose a base branch
from

Conversation

ankitdev10
Copy link

@ankitdev10 ankitdev10 commented Feb 2, 2024

Description

This patch fixes applyPriceAdjustment method for updated order lines.

Breaking changes

Does this PR include any breaking changes we should be aware of?

NO

Screenshots

You can add screenshots here if applicable.

Checklist

馃搶 Always:

  • I have set a clear title
  • My PR is small and contains a single feature
  • I have checked my own PR

馃憤 Most of the time:

  • I have added or updated test cases
  • I have updated the README if needed

@JamesLAllen
Copy link

JamesLAllen commented Feb 3, 2024

I'm not sure how this is any different from how it currently works, is it returning a different result?

const updatedOrder = await this.orderCalculator.applyPriceAdjustments(
            ctx,
            order,
            promotions,
            updatedOrderLines ?? [],
        )

The way I read this, updatedOrder.lines would equal updatedOrderLines or [], right?

@ankitdev10
Copy link
Author

Yes, it was not working for some reason but it did when I changed exact those patched lines in this commit directly in my node_modules. I have a customField for discount on orderLines and i was using applyPriceAdjustments to trigger OrderItemPriceCalculationStrategy for price recalculation.

To further extend, price was not updated in order_line table as well. And it works now after those changes.

@michaelbromley
Copy link
Member

Hi,

It is not clear to me what the exact error is that is being fixed by this PR. Would you be able to describe the issue in more detail?

  • What you did
  • What the expected result was
  • What the actual (erroneous) result was

@ankitdev10
Copy link
Author

Hello,

So, all I was trying to do was add a customField for discount amount on orderLine because the discount depends upon the exemptions file uploaded by the customer. Admin will later apply the discount and the order price will be recalculated once discoutn is applied. I was failing to trigger price recalculation and while looking into applyPriceAdjustments I had doubt that updated order lines are not saved correctly. All these despite OrderItemPriceCalculationStrategy getting triggered correctly.
here is the link for this disccusion on help thread in vendure discord server

@michaelbromley
Copy link
Member

Hi,

the scenario you describe sounds quite complex and I think I'd need to see an actual minimal reproduction in order to properly appreciate it.

@BijanRegmi
Copy link
Contributor

So in this loop

if (updatedOrderLines?.length) {
const { orderItemPriceCalculationStrategy, changedPriceHandlingStrategy } =
this.configService.orderOptions;
for (const updatedOrderLine of updatedOrderLines) {
const variant = await this.productVariantService.applyChannelPriceAndTax(
updatedOrderLine.productVariant,
ctx,
order,
);
let priceResult = await orderItemPriceCalculationStrategy.calculateUnitPrice(
ctx,
variant,
updatedOrderLine.customFields || {},
order,
updatedOrderLine.quantity,
);
const initialListPrice = updatedOrderLine.initialListPrice ?? priceResult.price;
if (initialListPrice !== priceResult.price) {
priceResult = await changedPriceHandlingStrategy.handlePriceChange(
ctx,
priceResult,
updatedOrderLine,
order,
);
}
if (updatedOrderLine.initialListPrice == null) {
updatedOrderLine.initialListPrice = initialListPrice;
}
updatedOrderLine.listPrice = priceResult.price;
updatedOrderLine.listPriceIncludesTax = priceResult.priceIncludesTax;
}
}
all the modification to the orderLine is applied to the updatedOrderLines parameter object. This mutated updatedOrderLines object is never assigned to order.lines so when saving order.lines as in here
await this.connection.getRepository(ctx, OrderLine).save(updatedOrder.lines, { reload: false });
the changes made to the updatedOrderLines won't be saved to the db.

If you follow the call to this.orderCalculator.applyPriceAdjustments

async applyPriceAdjustments(
ctx: RequestContext,
order: Order,
promotions: Promotion[],
updatedOrderLines: OrderLine[] = [],
options?: { recalculateShipping?: boolean },
): Promise<Order> {
const { taxZoneStrategy } = this.configService.taxOptions;
// We reset the promotions array as all promotions
// must be revalidated on any changes to an Order.
order.promotions = [];
const zones = await this.zoneService.getAllWithMembers(ctx);
const activeTaxZone = await this.requestContextCache.get(ctx, 'activeTaxZone', () =>
taxZoneStrategy.determineTaxZone(ctx, zones, ctx.channel, order),
);
let taxZoneChanged = false;
if (!activeTaxZone) {
throw new InternalServerError('error.no-active-tax-zone');
}
if (!order.taxZoneId || !idsAreEqual(order.taxZoneId, activeTaxZone.id)) {
order.taxZoneId = activeTaxZone.id;
taxZoneChanged = true;
}
for (const updatedOrderLine of updatedOrderLines) {
await this.applyTaxesToOrderLine(
ctx,
order,
updatedOrderLine,
activeTaxZone,
this.createTaxRateGetter(ctx, activeTaxZone),
);
}
this.calculateOrderTotals(order);
if (order.lines.length) {
if (taxZoneChanged) {
// First apply taxes to the non-discounted prices
await this.applyTaxes(ctx, order, activeTaxZone);
}
// Then test and apply promotions
const totalBeforePromotions = order.subTotal;
await this.applyPromotions(ctx, order, promotions);
// itemsModifiedByPromotions.forEach(item => updatedOrderItems.add(item));
if (order.subTotal !== totalBeforePromotions) {
// Finally, re-calculate taxes because the promotions may have
// altered the unit prices, which in turn will alter the tax payable.
await this.applyTaxes(ctx, order, activeTaxZone);
}
}
if (options?.recalculateShipping !== false) {
await this.applyShipping(ctx, order);
await this.applyShippingPromotions(ctx, order, promotions);
}
this.calculateOrderTotals(order);
return order;
}
you will find that the updatedOrderLines is never assigned to order.lines. Hence any changes made to orderLine is lost when you just save order.lines.

@michaelbromley
Copy link
Member

Thanks for the extra explanation.

So, all I was trying to do was add a customField for discount amount on orderLine because the discount depends upon the exemptions file uploaded by the customer.

Can you please show me the actual code implementation of this part - I don't fully understand what is going on here.

@BijanRegmi
Copy link
Contributor

https://github.com/BijanRegmi/vendure-price-issue

Here's a minimal reproduction steps with a failing test case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants