I have an ordercalculator that checks to see if a product has an orderline property that states that it is a donation. There is a global variable that stores the amount of the donation (which is set on the front-end by the user). The code is as follows:
//if there is a discount code and a value indicating whether or not it is a percent then we need to create a new price object to return and add an order property.
//Check for ServerSideOnly to verify that these where set on the server and not via JavaScript.
result = new Price( valueWithoutDonation + _donationAmount, newVat , valueWithoutDonation + _donationAmount + newVat ,CurrencyService.Get( order.StoreId, result.CurrencyId ) );
}
}
return result;
}
}
}
The problem with this is that if someone adds multiple donations to the cart it's only setting the amount of the last donation in the cart as the entire donation amount instead of adding each donation's amount together and setting that as the donation amount. I've changing _donationAmount = donationAmount.Value; to _donationAmount += donationAmount.Value; or _donationAmount += result.Value; but in both cases, when a discount is applied it ends up multiplying the total exponentially to the point that two $1 donations with a fixed discount of $10 (which should result in a total of $2) ends up totalling around $180. Any ideas how I can fix this or why this is happening?
Be sure to check that when you parse a string from the front end to a decimal that it is parsed correctly with decimals etc. Sometimes - 1.00 can be passed to 100 instead of 1. That might be the problem
Multiple Donations and Discounts Increase Total
I have an ordercalculator that checks to see if a product has an orderline property that states that it is a donation. There is a global variable that stores the amount of the donation (which is set on the front-end by the user). The code is as follows:
using System.Collections.Generic;
using TeaCommerce.Api.Common;
using TeaCommerce.Api.Dependency;
using TeaCommerce.Api.InformationExtractors;
using TeaCommerce.Api.Models;
using TeaCommerce.Api.PriceCalculators;
using TeaCommerce.Api.Services;
namespace Tivilon.reachoutyouthsolutions.Extensions.TeaCommerce {
[SuppressDependency( "TeaCommerce.Api.PriceCalculators.IOrderCalculator", "TeaCommerce.Api" )]
public class TeaCommerceOrderCalculator : OrderCalculator {
//used to store the donationAmount in CalculatreOrderLineUnitPrice since we will need it in CalculateOrderTotalPrice
private decimal _donationAmount;
public TeaCommerceOrderCalculator( IVatGroupService vatGroupService, ICurrencyService currencyService, IShippingMethodService shippingMethodService, IPaymentMethodService paymentMethodService,
IShippingCalculator shippingCalculator, IPaymentCalculator paymentCalculator, IProductInformationExtractor productInformationExtractor )
: base( vatGroupService, currencyService, shippingMethodService, paymentMethodService, shippingCalculator, paymentCalculator, productInformationExtractor ) {
//Doesn't extend the constructor of OrderCalculator
}
protected override decimal CalculateOrderLineUnitPrice( OriginalUnitPrice originalUnitPrice, OrderLine orderLine, Currency currency, Order order ) {
decimal? result = null;
//Check whether or not the orderline is a donation.
string isDonation = orderLine.Properties[ "donation" ];
if ( !string.IsNullOrEmpty( isDonation ) && isDonation == "1" ) {
decimal? donationAmount = orderLine.Properties[ "donationAmount" ].ParseToDecimal();
if ( donationAmount.HasValue ) {
result = donationAmount.Value;
_donationAmount = donationAmount.Value;
}
}
if ( !result.HasValue ) {
//If we get here then this orderline does not meet the requirenments of being a donation. Let OrderCalculator set the unit price,
result = base.CalculateOrderLineUnitPrice( originalUnitPrice, orderLine, currency, order );
}
return result.Value;
}
protected override Price CalculateOrderSubtotalPrice( IEnumerable orderLinesBundleTotalPrices, Currency currency, Order order ) {
Price result = base.CalculateOrderSubtotalPrice( orderLinesBundleTotalPrices, currency, order );
CustomProperty discount = order.Properties.Get( "discountValue" );
CustomProperty discountIsPercent = order.Properties.Get( "discountValueIsPercent" );
//if there is a discount code and a value indicating whether or not it is a percent then we need to create a new price object to return and add an order property.
//Check for ServerSideOnly to verify that these where set on the server and not via JavaScript.
if ( discount != null && discount.ServerSideOnly && discountIsPercent != null && discountIsPercent.ServerSideOnly ) {
decimal? discountValue = discount.Value.ParseToDecimal();
if ( discountValue.HasValue ) {
//We need to apply a discount to the order total, but not the part which is the discount.
decimal valueWithoutDonation = result.Value - _donationAmount;
decimal discountAmount;
if ( discountIsPercent.Value == "1" && discountValue.Value >= 0 && discountValue.Value <= 100 ) {
//bring the discount from it's [0-100] format to the [0-1] format
discountValue = discountValue / 100;
discountAmount = valueWithoutDonation * discountValue.Value;
valueWithoutDonation = valueWithoutDonation * ( 1 - discountValue.Value );
} else {
if ( discountValue.Value < valueWithoutDonation ) {
discountAmount = discountValue.Value;
valueWithoutDonation = valueWithoutDonation - discountValue.Value;
} else {
discountAmount = valueWithoutDonation;
valueWithoutDonation = 0;
}
}
order.Properties.AddOrUpdate( "discountAmount", discountAmount.ToString() );
decimal newVat = result.Vat - discountAmount*order.VatRate.Value;
result = new Price( valueWithoutDonation + _donationAmount, newVat , valueWithoutDonation + _donationAmount + newVat ,CurrencyService.Get( order.StoreId, result.CurrencyId ) );
}
}
return result;
}
}
}
Hi
Be sure to check that when you parse a string from the front end to a decimal that it is parsed correctly with decimals etc. Sometimes - 1.00 can be passed to 100 instead of 1. That might be the problem
Kind regards
Anders
is working on a reply...