Skip to content

Commit 3743464

Browse files
committed
#7548 PayPal Commerce plugin. Remove taxes from order items
1 parent c731a9e commit 3743464

File tree

2 files changed

+37
-55
lines changed

2 files changed

+37
-55
lines changed

src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs

Lines changed: 36 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,16 @@ private static Money PrepareMoney(decimal value, string currencyCode)
273273
};
274274
}
275275

276+
/// <summary>
277+
/// Convert money object to decimal value
278+
/// </summary>
279+
/// <param name="value">Amount value</param>
280+
/// <returns>Decimal value</returns>
281+
private static decimal ConvertMoney(Money amount)
282+
{
283+
return decimal.TryParse(amount?.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var value) ? value : decimal.Zero;
284+
}
285+
276286
/// <summary>
277287
/// Prepare order context
278288
/// </summary>
@@ -384,8 +394,6 @@ private async Task<List<Item>> PrepareOrderItemsAsync(CartDetails details)
384394
var (itemSubTotal, itemDiscount, _, _) = await _shoppingCartService.GetSubTotalAsync(item, true);
385395
var unitPrice = itemSubTotal / item.Quantity;
386396
var (unitPriceExclTax, _) = await _taxService.GetProductPriceAsync(product, unitPrice, false, details.Customer);
387-
var (unitPriceInclTax, _) = await _taxService.GetProductPriceAsync(product, unitPrice, true, details.Customer);
388-
var itemTax = unitPriceInclTax - unitPriceExclTax;
389397

390398
return new Item
391399
{
@@ -398,8 +406,7 @@ private async Task<List<Item>> PrepareOrderItemsAsync(CartDetails details)
398406
: CategoryType.PHYSICAL_GOODS.ToString().ToUpper(),
399407
Url = url,
400408
ImageUrl = imageUrl,
401-
UnitAmount = PrepareMoney(unitPriceExclTax, details.CurrencyCode),
402-
Tax = PrepareMoney(itemTax, details.CurrencyCode)
409+
UnitAmount = PrepareMoney(unitPriceExclTax, details.CurrencyCode)
403410
};
404411
}).ToListAsync();
405412

@@ -412,16 +419,13 @@ private async Task<List<Item>> PrepareOrderItemsAsync(CartDetails details)
412419
await foreach (var attributeValue in values)
413420
{
414421
var (attributePriceExclTax, _) = await _taxService.GetCheckoutAttributePriceAsync(attribute, attributeValue, false, details.Customer);
415-
var (attributePriceInclTax, _) = await _taxService.GetCheckoutAttributePriceAsync(attribute, attributeValue, true, details.Customer);
416-
var attributeTax = attributePriceInclTax - attributePriceExclTax;
417422

418423
items.Add(new()
419424
{
420425
Name = CommonHelper.EnsureMaximumLength(attribute.Name, 127),
421426
Description = CommonHelper.EnsureMaximumLength($"{attribute.Name} - {attributeValue.Name}", 127),
422427
Quantity = 1.ToString(),
423-
UnitAmount = PrepareMoney(attributePriceExclTax, details.CurrencyCode),
424-
Tax = PrepareMoney(attributeTax, details.CurrencyCode)
428+
UnitAmount = PrepareMoney(attributePriceExclTax, details.CurrencyCode)
425429
});
426430
}
427431
}
@@ -442,6 +446,7 @@ private async Task<OrderMoney> PrepareOrderMoneyAsync(CartDetails details, List<
442446
{
443447
//in some rare cases we need an additional item to adjust the order total
444448
//this can happen due to complex discounts or a large order and related to rounding in calculations
449+
//PayPal uses two decimal places, while nopCommerce can use more complex types of rounding (configured for each currency separately)
445450
var adjustmentName = await _localizationService.GetResourceAsync("Plugins.Payments.PayPalCommerce.Order.Adjustment.Name");
446451
var adjustmentDescription = await _localizationService.GetResourceAsync("Plugins.Payments.PayPalCommerce.Order.Adjustment.Description");
447452
if (items.FirstOrDefault(item => adjustmentName.Equals(item.Name) && adjustmentDescription.Equals(item.Description)) is Item adjustmentItem)
@@ -458,67 +463,52 @@ private async Task<OrderMoney> PrepareOrderMoneyAsync(CartDetails details, List<
458463
var (_, _, subTotal, _, _) = await _orderTotalCalculationService.GetShoppingCartSubTotalAsync(details.Cart, includingTax: false);
459464
total = subTotal;
460465
}
466+
var orderTotal = PrepareMoney(total.Value, details.CurrencyCode);
461467

462468
var (shippingTotal, _, _) = await _orderTotalCalculationService.GetShoppingCartShippingTotalAsync(details.Cart, includingTax: false);
463-
var (shippingTotalWithTax, _, _) = await _orderTotalCalculationService.GetShoppingCartShippingTotalAsync(details.Cart, includingTax: true);
464-
465-
var itemTotal = items
466-
.Sum(item => decimal.Parse(item.UnitAmount?.Value ?? "0", NumberStyles.Any, CultureInfo.InvariantCulture) * int.Parse(item.Quantity));
467-
var itemAdjustment = decimal.Zero;
469+
var orderShippingTotal = PrepareMoney(shippingTotal ?? decimal.Zero, details.CurrencyCode);
468470

469471
var (taxTotal, _) = await _orderTotalCalculationService.GetTaxTotalAsync(details.Cart, usePaymentMethodAdditionalFee: false);
470-
var itemTaxTotal = items
471-
.Sum(item => decimal.Parse(item.Tax?.Value ?? "0", NumberStyles.Any, CultureInfo.InvariantCulture) * int.Parse(item.Quantity));
472-
var shippingTax = (shippingTotalWithTax ?? 0) - (shippingTotal ?? 0);
473-
var taxAdjustment = taxTotal - itemTaxTotal - shippingTax;
474-
if (taxAdjustment > decimal.Zero)
475-
itemTotal += taxAdjustment;
476-
if (taxAdjustment < decimal.Zero || shippingTax > decimal.Zero)
477-
{
478-
taxAdjustment = Math.Max(taxAdjustment, decimal.Zero);
479-
foreach (var item in items)
480-
{
481-
item.Tax = null;
482-
}
483-
}
472+
var orderTaxTotal = PrepareMoney(taxTotal, details.CurrencyCode);
484473

485-
var discountTotal = itemTotal + taxTotal + (shippingTotal ?? decimal.Zero) - total.Value;
474+
var itemAdjustment = decimal.Zero;
475+
var itemTotal = items.Sum(item => ConvertMoney(item.UnitAmount) * int.Parse(item.Quantity));
476+
var discountTotal = itemTotal + ConvertMoney(orderTaxTotal) + ConvertMoney(orderShippingTotal) - ConvertMoney(orderTotal);
486477
if (discountTotal < decimal.Zero)
487478
{
488479
itemAdjustment = -discountTotal;
489480
itemTotal += itemAdjustment;
490481
discountTotal = decimal.Zero;
491482
}
483+
var orderItemTotal = PrepareMoney(itemTotal, details.CurrencyCode);
484+
var orderDiscount = PrepareMoney(discountTotal, details.CurrencyCode);
492485

493486
//set adjustment item if needed
494-
if (itemAdjustment > decimal.Zero || taxAdjustment > decimal.Zero)
487+
if (itemAdjustment > decimal.Zero)
495488
{
496-
var amount = PrepareMoney(itemAdjustment + taxAdjustment, details.CurrencyCode);
497-
if (decimal.TryParse(amount.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var value) && value > decimal.Zero)
489+
var unitAmount = PrepareMoney(itemAdjustment, details.CurrencyCode);
490+
if (ConvertMoney(unitAmount) > decimal.Zero)
498491
{
499492
items.Add(new()
500493
{
501494
Name = adjustmentName,
502495
Description = adjustmentDescription,
503496
Quantity = 1.ToString(),
504-
UnitAmount = amount,
505-
Tax = taxAdjustment > decimal.Zero && items.Any(item => item?.Tax is not null)
506-
? PrepareMoney(taxAdjustment, details.CurrencyCode)
507-
: null
497+
UnitAmount = unitAmount
508498
});
509499
}
510500
}
511501

512502
return new()
513503
{
514504
CurrencyCode = details.CurrencyCode,
515-
Value = PrepareMoney(total.Value, details.CurrencyCode).Value,
505+
Value = orderTotal.Value,
516506
Breakdown = new()
517507
{
518-
ItemTotal = PrepareMoney(itemTotal, details.CurrencyCode),
519-
TaxTotal = PrepareMoney(taxTotal, details.CurrencyCode),
520-
Shipping = PrepareMoney(shippingTotal ?? decimal.Zero, details.CurrencyCode),
521-
Discount = PrepareMoney(discountTotal, details.CurrencyCode)
508+
ItemTotal = orderItemTotal,
509+
TaxTotal = orderTaxTotal,
510+
Shipping = orderShippingTotal,
511+
Discount = orderDiscount
522512
}
523513
};
524514
}
@@ -1767,9 +1757,7 @@ await _actionContextAccessor.ActionContext.HttpContext.Session
17671757
return false;
17681758

17691759
//recalculate the total and update the items, since the shipping price may have changed
1770-
var items = unit.Items;
1771-
if (items.Any(item => item?.Tax is null))
1772-
items = await PrepareOrderItemsAsync(details);
1760+
var items = await PrepareOrderItemsAsync(details);
17731761
var orderAmount = await PrepareOrderMoneyAsync(details, items);
17741762
var cardData = new CardData
17751763
{
@@ -1896,9 +1884,7 @@ await _genericAttributeService
18961884
};
18971885

18981886
//recalculate the total and update the items, since the amounts may have changed
1899-
var items = unit.Items;
1900-
if (items.Any(item => item?.Tax is null))
1901-
items = await PrepareOrderItemsAsync(details);
1887+
var items = await PrepareOrderItemsAsync(details);
19021888
var orderAmount = await PrepareOrderMoneyAsync(details, items);
19031889
var cardData = new CardData
19041890
{
@@ -2042,8 +2028,7 @@ await _genericAttributeService.GetAttributeAsync<NopShippingOption>(customer,
20422028
//totals must match
20432029
var (cartTotal, _, _, _, _, _) = await _orderTotalCalculationService
20442030
.GetShoppingCartTotalAsync(cart, usePaymentMethodAdditionalFee: false);
2045-
decimal.TryParse(unit.Amount?.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var orderAmount);
2046-
var difference = Math.Abs(orderAmount - Math.Round(cartTotal ?? decimal.Zero, 2));
2031+
var difference = Math.Abs(ConvertMoney(unit.Amount) - Math.Round(cartTotal ?? decimal.Zero, 2));
20472032
if (difference > decimal.Zero)
20482033
throw new NopException($"Shopping cart total and approved order amount differ by {difference}");
20492034

@@ -2902,8 +2887,7 @@ await _orderService.InsertOrderNoteAsync(new()
29022887
if (!_orderProcessingService.CanMarkOrderAsAuthorized(nopOrder))
29032888
break;
29042889

2905-
decimal.TryParse(authorization.Amount?.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var authorizationAmount);
2906-
if (authorizationAmount >= Math.Round(nopOrder.OrderTotal, 2))
2890+
if (ConvertMoney(authorization.Amount) >= Math.Round(nopOrder.OrderTotal, 2))
29072891
await _orderProcessingService.MarkAsAuthorizedAsync(nopOrder);
29082892

29092893
break;
@@ -2947,8 +2931,7 @@ await _orderService.InsertOrderNoteAsync(new()
29472931
if (!_orderProcessingService.CanMarkOrderAsPaid(nopOrder))
29482932
break;
29492933

2950-
decimal.TryParse(capture.Amount?.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var captureAmount);
2951-
if (captureAmount >= Math.Round(nopOrder.OrderTotal, 2))
2934+
if (ConvertMoney(capture.Amount) >= Math.Round(nopOrder.OrderTotal, 2))
29522935
await _orderProcessingService.MarkOrderAsPaidAsync(nopOrder);
29532936

29542937
break;
@@ -3039,8 +3022,7 @@ await _orderService.InsertOrderNoteAsync(new()
30393022
nopOrder.CaptureTransactionId = orderCapture.Id;
30403023
nopOrder.CaptureTransactionResult = orderCapture.Status;
30413024

3042-
decimal.TryParse(orderCapture.Amount?.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var captureAmount);
3043-
if (captureAmount >= Math.Round(nopOrder.OrderTotal, 2))
3025+
if (ConvertMoney(orderCapture.Amount) >= Math.Round(nopOrder.OrderTotal, 2))
30443026
await _orderProcessingService.MarkOrderAsPaidAsync(nopOrder);
30453027

30463028
break;

src/Plugins/Nop.Plugin.Payments.PayPalCommerce/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"Group": "Payment methods",
33
"FriendlyName": "PayPal Commerce",
44
"SystemName": "Payments.PayPalCommerce",
5-
"Version": "4.80.12",
5+
"Version": "4.80.13",
66
"SupportedVersions": [ "4.80" ],
77
"Author": "nopCommerce team",
88
"DisplayOrder": -1,

0 commit comments

Comments
 (0)