Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Anthony Barsotti 26 posts 66 karma points
    Mar 24, 2014 @ 17:09
    Anthony Barsotti
    0

    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;

        }

      }

    }

    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?
  • Anders Burla 2560 posts 8256 karma points
    Mar 25, 2014 @ 09:52
    Anders Burla
    0

    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

Please Sign in or register to post replies

Write your reply to:

Draft