Order Total and Payment Total Rounding problem

Store UI, layout, design, look and feel; Discussion on the customer facing pages of your online store. Cascading Style Sheets, Themes, Scriptlets, NVelocity and the components in the ConLib directory.
Post Reply
Alan Rich
Ensign (ENS)
Ensign (ENS)
Posts: 17
Joined: Fri May 15, 2009 3:40 pm

Order Total and Payment Total Rounding problem

Post by Alan Rich » Wed Jul 28, 2010 12:51 am

Using 7.04, build 13424

I need 4 decimal places on product prices, so currency is set to 4 decimals. This causes some order totals to include fractions of a penny. I am not using OnePageCheckout because I need a custom address selection scheme. Checkout\Default.aspx uses my custom address selection page (which never references the order or basket objects) and then redirects to the ShipMethod page. Then on to the PaymentPage.aspx which shows the order total rounded to 2 decimals. When I pay by purchase order, the receipt page shows the rounded payment amount, but the order total now shows the true (unrounded) amount. So there's like a few pennies of a credit mismatch and the order status shows Payment Pending. Is this a bug? Is the basket.Items.TotalPrice() function not rounding the same way as the GetBasketSubtotal function?

I can add a miscellaneous charge of 0.0014 (or some such) and let the order complete, but this not elegant. And I do not want users to see orders and email confirmations with fractions of cents in any line or order totals. Suggestions?

-=Alan=-
Last edited by Alan Rich on Wed Jul 28, 2010 11:01 am, edited 1 time in total.

Alan Rich
Ensign (ENS)
Ensign (ENS)
Posts: 17
Joined: Fri May 15, 2009 3:40 pm

Re: Order Total and Payment Total Rounding problem

Post by Alan Rich » Wed Jul 28, 2010 1:07 am

Same thing happens with Credit Card payment (using the Ablecommerce Test Gateway)
-=A=-
Last edited by Alan Rich on Wed Jul 28, 2010 11:01 am, edited 1 time in total.

User avatar
jmestep
AbleCommerce Angel
Posts: 8164
Joined: Sun Feb 29, 2004 8:04 pm
Location: Dayton, OH
Contact:

Re: Order Total and Payemnt Total Rounding problem

Post by jmestep » Wed Jul 28, 2010 6:35 am

I had run into the problem with custom code and once I made sure my figures were rounded the way Able's were, the problem went away. I used something like this:

Code: Select all

	    Double halfPrice = Math.Round(AlwaysConvert.ToDouble(_Product.Price/2),2,MidpointRounding.AwayFromZero);
                    LSDecimal dhalfPrice = AlwaysConvert.ToDecimal(halfPrice);
                    SecondPrice.Text = dhalfPrice.ToString("ulc");
         
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx

Alan Rich
Ensign (ENS)
Ensign (ENS)
Posts: 17
Joined: Fri May 15, 2009 3:40 pm

Re: Order Total and Payment Total Rounding problem

Post by Alan Rich » Wed Jul 28, 2010 10:04 am

Thanks for the response jmestep!

However, I'm not quite sure where that code should go. Do I need to make a custom BasketTotalSummary.ascx control?
Last edited by Alan Rich on Wed Jul 28, 2010 11:02 am, edited 1 time in total.

Alan Rich
Ensign (ENS)
Ensign (ENS)
Posts: 17
Joined: Fri May 15, 2009 3:40 pm

Re: Order Total and Payment Total Rounding problem

Post by Alan Rich » Wed Jul 28, 2010 10:23 am

Nope, not BasketTotalSummary.ascx. That's simply a display widget. It's like the Basket.Recalculate function is inconsistent. (Or perhaps the Basket.Items.TotalPrice() function)

Those two are in the .dll, thus I cannot examine or update those. Hence, my suspicion of a bug. But if others are not having this problem, then my custom stuff must be the culprit.

User avatar
jmestep
AbleCommerce Angel
Posts: 8164
Joined: Sun Feb 29, 2004 8:04 pm
Location: Dayton, OH
Contact:

Re: Order Total and Payment Total Rounding problem

Post by jmestep » Wed Jul 28, 2010 12:02 pm

That code would go wherever your custom code is located. No one else is reporting the problem with standard Able code.
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx

Alan Rich
Ensign (ENS)
Ensign (ENS)
Posts: 17
Joined: Fri May 15, 2009 3:40 pm

Re: Order Total and Payment Total Rounding problem

Post by Alan Rich » Wed Jul 28, 2010 4:16 pm

Well I removed my mods, went back to OnePagecheckout and still have the same results. So, it "seems" the checkout process is recalculating the basket's total price without using GetShopExtendedPrice values, but instead is calculating a running total from (basketitem.price * basketitem.quantity). I am at a total loss as to what to do next.

Alan Rich
Ensign (ENS)
Ensign (ENS)
Posts: 17
Joined: Fri May 15, 2009 3:40 pm

Re: Order Total and Payment Total Rounding problem

Post by Alan Rich » Wed Jul 28, 2010 8:36 pm

OK. So I decided to live with an extra CHARGE or DISCOUNT order line being added to account for the rounding discrepancy. I added the following code right before the checkout occurs in the PurchaseOrderPaymentForm.ascx file:

(I'm still learning C# so it may not be the most efficient or best way, but it works.)

Right after:

Code: Select all

    protected void PurchaseOrderButton_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            //CREATE THE PAYMENT OBJECT
            Payment payment = GetPayment();
            //PROCESS CHECKING OUT EVENT
            bool checkOut = true;
            if (CheckingOut != null)
            {
                CheckingOutEventArgs c = new CheckingOutEventArgs(payment);
                CheckingOut(this, c);
                checkOut = !c.Cancel;
            }
            if (checkOut)
           {
I inserted:

Code: Select all

                // Calculate the subtotal two ways and compare. 
                //   1. subtotal = basketitem.ExtendedPrice (which rounds correctly with basket.recalculate())   
                //   2. itemsubtotal = basketitem.Quantity * basketitem.Price (does not round, apparantly the way Checkout is doing it)
                //
                //If the itemsubtotal does not equal the subtotal, it indicates that the order will be created with a total including fractions of a penny (bad)
                //so add a basket item (CHARGE or DISCOUNT) for the rounding amt so the resulting order will be rounded to 2 decimals
                
                LSDecimal subtotal = 0;
                LSDecimal itemsubtotal = 0;
                Basket basket = Token.Instance.User.Basket;
                foreach (BasketItem item in basket.Items)
                {
                    LSDecimal extendedProductPrice = item.Quantity * item.Price;
                    LSDecimal extendedPrice = item.ExtendedPrice;

                    switch (item.OrderItemType)
                    {
                        case OrderItemType.Shipping:
                        case OrderItemType.Handling:
                            break;
                        case OrderItemType.Tax:
                            break;
                        case OrderItemType.Coupon:
                            break;
                        case OrderItemType.GiftWrap:
                            break;
                        default:
                            subtotal += extendedPrice;
                            itemsubtotal += extendedProductPrice;
                            break;
                    }
                }

                if (itemsubtotal != subtotal)
                {
                    LSDecimal roundingdiff = (subtotal - itemsubtotal);
                    BasketItem _BasketItem = new BasketItem();
                    _BasketItem.BasketId = Token.Instance.User.Basket.BasketId;

                    //Determine OrderItemType to add
                    if (roundingdiff > 0)
                    {
                         //cart rounded up, Need a CHARGE +roundingdiff
                        _BasketItem.OrderItemType = OrderItemType.Charge;
                    }
                    else
                    {
                        //cart rounded down, Need a DISCOUNT (roundingdiff * -1)
                        _BasketItem.OrderItemType = OrderItemType.Discount;
                    }
                    _BasketItem.Price = roundingdiff;
                    _BasketItem.Name = "Rounding";
                    _BasketItem.Quantity = 1;
                    _BasketItem.Shippable = CommerceBuilder.Shipping.Shippable.No;
                    _BasketItem.Save();
                    Token.Instance.User.Basket.Items.Add(_BasketItem);
                    Token.Instance.User.Basket.Items.Save();                        
                }    
Which is followed by:

Code: Select all

                        
                //PROCESS THE CHECKOUT
                CheckoutRequest checkoutRequest = new CheckoutRequest(payment);
                CheckoutResponse checkoutResponse = Token.Instance.User.Basket.Checkout(checkoutRequest);
                .........

Post Reply