/// <summary> /// Check if order is free shipping and customer selects free shipping methods /// </summary> /// <param name="nav">xml</param> private void CheckIfFreeShipping(XPathNavigator nav) { XmlNode orderInfoNode = GetXmlNode(nav.SelectSingleNode("Order/OrderInfo")); bool freeShipping = false; if ((CheckIfCouponApplied(orderInfoNode) || CheckIfLevelHasFreeShipping(orderInfoNode)) || (CheckIfAllDownloads(orderInfoNode) || CheckIfAllFreeShipping(orderInfoNode) || CheckIfAllSystemProducts(orderInfoNode))) { freeShipping = true; } bool customerChoseFreeShippingMethod = true; if (AppLogic.AppConfigBool("FreeShippingAllowsRateSelection")) { int shippingMethodId = XmlCommon.XmlFieldNativeInt(orderInfoNode, "ShippingMethodID"); string commaSeparatedIds = AppLogic.AppConfig("ShippingMethodIDIfFreeShippingIsOn"); customerChoseFreeShippingMethod = CommonLogic.IntegerIsInIntegerList(shippingMethodId, commaSeparatedIds); } freeShipping = freeShipping && customerChoseFreeShippingMethod; XmlNode isFreeShippingNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "IsFreeShipping", string.Empty); isFreeShippingNode.InnerText = XmlCommon.XmlEncode(freeShipping.ToString()); orderInfoNode.InsertAfter(isFreeShippingNode, orderInfoNode.LastChild); }
/// <summary> /// Check if customer level includes free shipping /// </summary> /// <param name="orderInfoNode"></param> /// <returns>returns true if customer level includes free shipping</returns> private bool CheckIfLevelHasFreeShipping(XmlNode orderInfoNode) { bool hascustomerLevel = CommonLogic.IIF(XmlCommon.XmlFieldNativeInt(orderInfoNode, "LevelID") != 0, true, false); bool levelHasFreeShipping = CommonLogic.IIF(XmlCommon.XmlFieldNativeInt(orderInfoNode, "LevelHasFreeShipping") == 1, true, false); return(hascustomerLevel && levelHasFreeShipping); }
/// <summary> /// Check in orderInfoNode if a coupon is applied /// </summary> /// <param name="orderInfoNode"></param> /// <returns>returns true if there is a couponcode and coupon includes free shipping</returns> private bool CheckIfCouponApplied(XmlNode orderInfoNode) { bool hasCouponApplied = CommonLogic.IIF(!CommonLogic.IsStringNullOrEmpty(XmlCommon.XmlField(orderInfoNode, "CouponCode")), true, false); bool couponIncludesFreeshipping = CommonLogic.IIF(XmlCommon.XmlFieldNativeInt(orderInfoNode, "CouponIncludesFreeShipping") == 1, true, false); return(hasCouponApplied && couponIncludesFreeshipping); }
/// <summary> /// Precompute the order discounts and attach it to the OrderInfo node /// </summary> /// <param name="nav">The XPathNavigator</param> private void PreComputeDiscounts(XPathNavigator nav) { // Precompute the totals XmlNode orderInfoNode = GetXmlNode(nav.SelectSingleNode("Order/OrderInfo")); decimal rawSubTotal = decimal.Zero; decimal rawSubTotalVat = decimal.Zero; XPathNodeIterator lineItemIterator = nav.Select("OrderItems/Item"); bool incVat = ThisCustomer.VATSettingReconciled == VATSettingEnum.ShowPricesInclusiveOfVAT; while (lineItemIterator.MoveNext()) { XmlNode lineItemNode = GetXmlNode(lineItemIterator.Current); rawSubTotal += XmlCommon.XmlFieldNativeDecimal(lineItemNode, "OrderedProductPrice"); if (incVat) { rawSubTotalVat += XmlCommon.XmlFieldNativeDecimal(lineItemNode, "ExtVatAmount"); } } XPathNodeIterator orderOptionIterator = nav.Select("Order/OrderInfo/OrderOptionsXml/OrderOption"); while (orderOptionIterator.MoveNext()) { XmlNode orderOptionNode = GetXmlNode(orderOptionIterator.Current); rawSubTotal += XmlCommon.XmlFieldNativeDecimal(orderOptionNode, "Price"); } decimal appliedSubTotal = rawSubTotal; decimal subTotal = XmlCommon.XmlFieldNativeDecimal(orderInfoNode, "OrderSubtotal"); XmlNode rawSubTotalNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "RawSubTotal", string.Empty); decimal actualRawSubTotal = rawSubTotal + rawSubTotalVat; rawSubTotalNode.InnerText = XmlCommon.XmlEncode(actualRawSubTotal.ToString()); orderInfoNode.InsertAfter(rawSubTotalNode, orderInfoNode.LastChild); XmlNode discountsNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "Discounts", string.Empty); orderInfoNode.InsertAfter(discountsNode, orderInfoNode.LastChild); string couponCode = XmlCommon.XmlField(orderInfoNode, "CouponCode"); int couponType = XmlCommon.XmlFieldNativeInt(orderInfoNode, "CouponType"); bool hasCouponApplied = !string.IsNullOrEmpty(couponCode) && couponType != GIFTCARD_COUPONTYPE; decimal couponDiscountPercent = XmlCommon.XmlFieldNativeDecimal(orderInfoNode, "CouponDiscountPercent"); decimal couponDiscountAmount = XmlCommon.XmlFieldNativeDecimal(orderInfoNode, "CouponDiscountAmount"); if (hasCouponApplied) { // were only interested in the amount if (couponDiscountPercent > decimal.Zero) { XmlNode discountNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "Discount", string.Empty); XmlAttribute typeAttribute = orderInfoNode.OwnerDocument.CreateAttribute("type"); typeAttribute.Value = "Coupon"; //"Coupon Percent"; discountNode.Attributes.Append(typeAttribute); decimal couponDiscountPercentAmount = decimal.Zero; // check whether the coupon type is by percent // if it is, compute by line items included only string validProductIdCommaSeparated = XmlCommon.XmlField(orderInfoNode, "ValidProductsForCoupon"); if (!string.IsNullOrEmpty(validProductIdCommaSeparated) && couponType == PRODUCT_COUPONTYPE) { string[] validProductsIds = validProductIdCommaSeparated.Split(','); foreach (string productId in validProductsIds) { // let's find the line item this product is mapped to string xpath = string.Format("OrderItems/Item[ProductID={0}]", productId); XPathNavigator validProductNav = nav.SelectSingleNode(xpath); if (validProductNav != null) { XmlNode validProductNode = GetXmlNode(validProductNav); if (validProductNode != null) { decimal lineItemExtPrice = XmlCommon.XmlFieldNativeDecimal(validProductNode, "OrderedProductPrice"); if (incVat) { lineItemExtPrice += XmlCommon.XmlFieldNativeDecimal(validProductNode, "ExtVatAmount"); } decimal lineItemCouponDiscountAmount = lineItemExtPrice * (couponDiscountPercent / 100M); couponDiscountPercentAmount += lineItemCouponDiscountAmount; } } } } else { // coupon is applied to order if (couponDiscountPercent == 100M && subTotal == decimal.Zero) { couponDiscountPercentAmount = appliedSubTotal; } else { couponDiscountPercentAmount = (appliedSubTotal * (couponDiscountPercent / 100M)); } } XmlAttribute valueAttribute = orderInfoNode.OwnerDocument.CreateAttribute("value"); valueAttribute.Value = couponDiscountPercentAmount.ToString(); discountNode.Attributes.Append(valueAttribute); discountsNode.AppendChild(discountNode); // apply the discount at this one appliedSubTotal -= couponDiscountPercentAmount; } if (couponDiscountAmount > decimal.Zero && appliedSubTotal > decimal.Zero) { // check whether the coupon type is by percent // if it is, compute by line items included only string validProductIdCommaSeparated = XmlCommon.XmlField(orderInfoNode, "ValidProductsForCoupon"); if (!string.IsNullOrEmpty(validProductIdCommaSeparated) && couponType == PRODUCT_COUPONTYPE) { string[] validProductsIds = validProductIdCommaSeparated.Split(','); foreach (string productId in validProductsIds) { // let's find the line item this product is mapped to string xpath = string.Format("OrderItems/Item[ProductID={0}]", productId); XPathNavigator validProductNav = nav.SelectSingleNode(xpath); if (validProductNav != null) { XmlNode validProductNode = GetXmlNode(validProductNav); if (validProductNode != null) { decimal lineItemExtPrice = XmlCommon.XmlFieldNativeDecimal(validProductNode, "OrderedProductPrice"); decimal lineItemDiscountAmount = couponDiscountAmount; if (couponDiscountAmount > lineItemExtPrice) { couponDiscountAmount += lineItemExtPrice; } // need to take into account the quantity int qty = XmlCommon.XmlFieldNativeInt(validProductNode, "Quantity"); couponDiscountAmount *= qty; } } } } else if (couponDiscountAmount > appliedSubTotal) { couponDiscountAmount = appliedSubTotal; } XmlNode discountNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "Discount", string.Empty); XmlAttribute typeAttribute = orderInfoNode.OwnerDocument.CreateAttribute("type"); typeAttribute.Value = "Coupon Amount"; // "Coupon Amount"; discountNode.Attributes.Append(typeAttribute); XmlAttribute valueAttribute = orderInfoNode.OwnerDocument.CreateAttribute("value"); valueAttribute.Value = couponDiscountAmount.ToString(); discountNode.Attributes.Append(valueAttribute); discountsNode.AppendChild(discountNode); appliedSubTotal -= couponDiscountAmount; } } decimal levelDiscountAmount = XmlCommon.XmlFieldNativeDecimal(orderInfoNode, "LevelDiscountAmount"); if (XmlCommon.XmlFieldNativeInt(orderInfoNode, "LevelID") > 0 && levelDiscountAmount > 0) { if (levelDiscountAmount > decimal.Zero && appliedSubTotal > decimal.Zero) { if (levelDiscountAmount > appliedSubTotal) { levelDiscountAmount = appliedSubTotal; } } // were only interested in the amount XmlNode discountNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "Discount", string.Empty); XmlAttribute typeAttribute = orderInfoNode.OwnerDocument.CreateAttribute("type"); typeAttribute.Value = "Level"; //"Level" discountNode.Attributes.Append(typeAttribute); XmlAttribute valueAttribute = orderInfoNode.OwnerDocument.CreateAttribute("value"); valueAttribute.Value = levelDiscountAmount.ToString(); discountNode.Attributes.Append(valueAttribute); discountsNode.AppendChild(discountNode); appliedSubTotal -= levelDiscountAmount; } // gift card discount{shown as payment} decimal giftCardPaymentAppliedAmount = couponDiscountAmount; // we save the applied gift card value on the coupon discount amount col bool hasGiftCardApplied = (couponType == GIFTCARD_COUPONTYPE) && giftCardPaymentAppliedAmount > decimal.Zero; decimal orderTotal = XmlCommon.XmlFieldNativeDecimal(orderInfoNode, "OrderTotal"); decimal netTotal = orderTotal; if (hasGiftCardApplied) { // we have Gift Card Applied netTotal = orderTotal - giftCardPaymentAppliedAmount; } XmlNode hasgiftCardAppliedNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "HasGiftCardApplied", string.Empty); hasgiftCardAppliedNode.InnerText = XmlCommon.XmlEncode(hasGiftCardApplied.ToString()); orderInfoNode.InsertAfter(hasgiftCardAppliedNode, orderInfoNode.LastChild); XmlNode netTotalNode = orderInfoNode.OwnerDocument.CreateNode(XmlNodeType.Element, "NetTotal", string.Empty); netTotalNode.InnerText = XmlCommon.XmlEncode(netTotal.ToString()); orderInfoNode.InsertAfter(netTotalNode, orderInfoNode.LastChild); }
/// <summary> /// Check if order is all system products /// </summary> /// <param name="orderInfoNode"></param> /// <returns>returns true if order is all system products</returns> private bool CheckIfAllSystemProducts(XmlNode orderInfoNode) { return(CommonLogic.IIF(XmlCommon.XmlFieldNativeInt(orderInfoNode, "allSystemproducts") == 1, true, false)); ; }
/// <summary> /// Check if order is all free shipping /// </summary> /// <param name="orderInfoNode"></param> /// <returns>returns true if all order is free shipping</returns> private bool CheckIfAllFreeShipping(XmlNode orderInfoNode) { return(CommonLogic.IIF(XmlCommon.XmlFieldNativeInt(orderInfoNode, "allFreeShipping") == 1, true, false)); }
/// <summary> /// Check if order is All Downloads /// </summary> /// <param name="orderInfoNode"></param> /// <returns>returns true if order is all downloads</returns> private bool CheckIfAllDownloads(XmlNode orderInfoNode) { return(CommonLogic.IIF(XmlCommon.XmlFieldNativeInt(orderInfoNode, "allDownloads") == 1, true, false)); }