コード例 #1
0
        /// <summary>
        ///     Checks whether the cache dependency has been changed from the last request.
        ///     If the current request has a different signature that the previous one, the cache will be cleared.
        /// </summary>
        public static void ClearContextDependentCache(int userId)
        {
            string cacheKeyInfoStore = "ContextDependentCacheKeyInfoStore";

            var session = System.Web.HttpContext.Current?.Session;

            string cacheKeyDependency         = userId.ToString();
            string existingCacheKeyDependency = (string)session?[cacheKeyInfoStore];

            if (!string.Equals(cacheKeyDependency, existingCacheKeyDependency, StringComparison.OrdinalIgnoreCase))
            {
                ErpResponseCache.ClearAllCaches();

                if (session != null)
                {
                    session[cacheKeyInfoStore] = cacheKeyDependency;
                }
            }
        }
コード例 #2
0
        // Fills the values from Response on the Product
        public static void FillProductValues(Product product, double quantity = 1)
        {
            if (product != null && ErpResponseCache.IsProductInCache(ProductCacheLevel, Helpers.ProductIdentifier(product)))
            {
                Dictionary <string, ProductInfo> piCache = ErpResponseCache.GetProductInfos(ProductCacheLevel);
                if (piCache.ContainsKey(Helpers.ProductIdentifier(product)))
                {
                    ProductInfo productInfo = piCache[Helpers.ProductIdentifier(product)];

                    double?newStock = (double?)productInfo["Stock"];

                    if (newStock.HasValue && product.Stock != newStock)
                    {
                        product.Stock = newStock.Value;
                        product.Save();
                        productInfo["Stock"] = null;
                    }
                    //product.Stock = (double)productInfo["Stock"];

                    FillProductPrices(product, productInfo);

                    double?priceValue = SelectPrice(productInfo, quantity) * product.GetUnitPriceMultiplier();

                    product.Price.PriceWithoutVAT = priceValue.GetValueOrDefault(); // NOTE accessing the Price property, will trigger the price provider to kick in
                    product.Price.PriceWithVAT    = priceValue.GetValueOrDefault();

                    //Update Product Custom Fields
                    if (AddProductFieldsToRequest && product.ProductFieldValues.Count > 0)
                    {
                        foreach (var pfv in product.ProductFieldValues)
                        {
                            if (productInfo.ContainsKey(pfv.ProductField.SystemName))
                            {
                                pfv.Value = productInfo[pfv.ProductField.SystemName];
                            }
                        }
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Updates an order in the ERP.
        /// </summary>
        /// <param name="order">The order that must be synced with the ERP.</param>
        /// <param name="liveIntegrationSubmitType">Determines the origin of this submit such.</param>
        /// <param name="successOrderStateId">The order state that is applied to the order when it integrates successfully.</param>
        /// <param name="failedOrderStateId">The order state that is applied to the order when an error occurred during the integration.</param>
        /// <returns>Returns null if no communication has made, or bool if order has been updated successfully or not.</returns>
        public static bool?UpdateOrder(Order order, LiveIntegrationSubmitType liveIntegrationSubmitType, string successOrderStateId = null, string failedOrderStateId = null)
        {
            if (order == null || !order.OrderLines.Any())
            {
                return(null);
            }
            if (liveIntegrationSubmitType == LiveIntegrationSubmitType.LiveOrderOrCart && !string.IsNullOrEmpty(order.IntegrationOrderId))
            {
                return(null);
            }

            var orderId = order.Id ?? "ID is null";

            Logger.Instance.Log(ErrorLevel.DebugInfo, string.Format("Updating order with ID: {0}. Complete: {1}. Order submitted from the backend: {2}. Stack trace: {3}", orderId, order.Complete, ExecutingContext.IsBackEnd(), Environment.StackTrace));

            // use current user if is not backend running or if the cart is Anonymous
            var user = (order.CustomerAccessUserId > 0 ? User.GetUserByID(order.CustomerAccessUserId) : null)
                       ?? (!ExecutingContext.IsBackEnd() ? User.GetCurrentExtranetUser() : null);

            // customization for VanBaerle branch: ERP doesn't support anonymous users and throws errors
            if (user == null)
            {
                return(null);
            }

            /* create order: if it is false, you will get a calculate order from the ERP with the total prices */
            /* if it is true, then a new order will be created in the ERP */
            bool createOrder = order.Complete;

            if (createOrder && user != null)
            {
                UserSync(user);
            }

            if (!Settings.Instance.EnableCartCommunicationForAnonymousUsers && user == null)
            {
                Logger.Instance.Log(ErrorLevel.DebugInfo, string.Format("No user is currently logged in. Anonymous user cart is not allowed. Order = {0}", orderId));
                return(null);
            }

            // default states
            if (successOrderStateId == null)
            {
                successOrderStateId = Settings.Instance.OrderStateAfterExportSucceeded;
            }
            if (failedOrderStateId == null)
            {
                failedOrderStateId = Settings.Instance.OrderStateAfterExportFailed;
            }

            var requestXml = new OrderXmlRenderer().RenderOrderXml(order, new RenderOrderSettings {
                AddOrderLineFieldsToRequest = AddOrderLineFieldsToRequest, AddOrderFieldsToRequest = AddOrderFieldsToRequest, CreateOrder = createOrder, LiveIntegrationSubmitType = liveIntegrationSubmitType, ReferenceName = "OrdersPut"
            });

            if (createOrder && SaveOrderXml && liveIntegrationSubmitType == LiveIntegrationSubmitType.LiveOrderOrCart)
            {
                SaveCopyOfXml(order.Id, requestXml);
            }

            // calculate current hash
            string currentHash = CalculateHash(requestXml);

            // get last hash
            string lastHash = GetLastOrderHash();

            if (!string.IsNullOrEmpty(lastHash) && lastHash == currentHash)
            {
                // no changes to order
                return(null);
            }
            // save this hash for next calls
            SaveOrderHash(currentHash);

            // clear all session var to avoid miss calculations
            HttpContext.Current.Session.Remove("LiveIntegrationDiscounts" + order.Id);

            Dictionary <string, XmlDocument> responsesCache = ErpResponseCache.GetWebOrdersConnectorResponses(OrderCacheLevel);

            XmlDocument response = null;

            if (!createOrder && responsesCache.ContainsKey(requestXml))
            {
                response = responsesCache[requestXml];
            }
            else
            {
                if (createOrder)
                {
                    OrderDebuggingInfo.Save(order, "Sending order to the ERP system through Live Integration.", "OrderHandler");
                }
                try
                {
                    response = Connector.CalculateOrder(requestXml, order.Id, createOrder);
                }
                catch (LiveIntegrationException ex)
                {
                    // TODO Rui, handle appropriately
                    Logger.Instance.Log(ErrorLevel.ConnectionError, ex.Message);
                }
                if (responsesCache.ContainsKey(requestXml))
                {
                    responsesCache.Remove(requestXml);
                }
                if (!string.IsNullOrWhiteSpace(response?.InnerXml))
                {
                    responsesCache.Add(requestXml, response);
                }
            }
            if (!string.IsNullOrWhiteSpace(response?.InnerXml))
            {
                bool processResponseResult = ProcessResponse(response, order, createOrder, successOrderStateId, failedOrderStateId);

                // new user sync active, sync user (Update)
                if (Settings.Instance.UpdateUserAfterNewOrder && user != null)
                {
                    user.SynchronizeUsingLiveIntegration(true, UserSyncMode.Get);
                }

                return(processResponseResult);
            }
            else
            {
                //error occurred
                CheckIfOrderShouldRevertToCart(order, createOrder);
                return(false);
            }
        }
コード例 #4
0
        public override PriceRaw FindPrice(Product product, double quantity, string variantId, Currency currency, string unitId, User user)
        {
            if (!Global.IsIntegrationActive ||
                !Settings.Instance.EnableLivePrices ||
                !Settings.Instance.LiveProductInfoForAnonymousUsers && user == null ||
                user != null && user.IsLivePricesDisabled ||
                !Connector.IsWebServiceConnectionAvailable() ||
                product == null || product.Id == "" || product.Number == "" || product.Number == null)
            {
                return(null);
            }

            try
            {
                Product requestProduct;
                if (product.VariantId == variantId || (string.IsNullOrEmpty(variantId) && string.IsNullOrEmpty(product.VariantId)))
                {
                    requestProduct = product;
                }
                else
                {
                    requestProduct           = product.Clone();
                    requestProduct.VariantId = variantId;
                }

                //Logger.Instance.Log(ErrorLevel.DebugInfo, $"Id: {requestProduct.Id}, VariantId: {requestProduct.VariantId}, Number: {requestProduct.Number} \r\n { System.Environment.StackTrace}");

                // If Product is not in the cache, then get it from Erp
                if (!ErpResponseCache.IsProductInCache(ProductCacheLevel, Helpers.ProductIdentifier(requestProduct)))
                {
                    List <Product> products = new List <Product>();
                    products.Add(requestProduct);
                    if (FetchProductInfos(products, User.GetCurrentExtranetUser()))
                    {
                        //Check if requested product was not received from response
                        if (!ErpResponseCache.IsProductInCache(ProductCacheLevel, Helpers.ProductIdentifier(requestProduct)))
                        {
                            Logger.Instance.Log(ErrorLevel.Error, string.Format("Error receiving product info for product: {0}.", Helpers.ProductIdentifier(requestProduct)));
                            return(null);
                        }
                    }
                    else
                    {
                        //no price from ERP so read DW default price
                        return(new DefaultPriceProvider().FindPrice(product, quantity, variantId, currency, unitId, user));
                    }
                }

                double?priceValue = 0.0;

                var productCache = ErpResponseCache.GetProductInfos(ProductCacheLevel);

                ProductInfo productInfo = productCache != null && productCache.TryGetValue(Helpers.ProductIdentifier(requestProduct), out productInfo)
                    ? productInfo
                    : null;

                if (productInfo != null)
                {
                    priceValue = SelectPrice(productInfo, quantity);
                }

                var price = priceValue == null
                    ? null
                    : new PriceRaw
                {
                    Price    = priceValue.Value * product.GetUnitPriceMultiplier(),
                    Currency = currency
                };

                return(price);
            }
            catch (Exception e)
            {
                Logger.Instance.Log(ErrorLevel.Error, $"Unknown error during FindPrice(). Exception: {e.Message}");
                return(null);
            }
        }
コード例 #5
0
        internal static bool FetchProductInfos(List <Product> products, User user)
        {
            // disable because if causes troubles if the product list fails (missing product) and then we enter to a product, as
            // it won't fetch its price...
            //if (LastResponseValid())
            //    // no need to read cache
            //    return false;
            //SaveLastResponse(false);

            if (products == null || products.Count == 0)
            {
                return(false);
            }

            if (!Settings.Instance.EnableLivePrices)
            {
                Logger.Instance.Log(ErrorLevel.DebugInfo, "Live Prices are Disabled");
                return(false);
            }

            if (!Connector.IsWebServiceConnectionAvailable())
            {
                Logger.Instance.Log(ErrorLevel.DebugInfo, "Live Prices are unavailable");
                return(false);
            }

            if (user == null)
            {
                user = User.GetCurrentExtranetUser();
            }
            if (!Settings.Instance.LiveProductInfoForAnonymousUsers && user == null)
            {
                Logger.Instance.Log(ErrorLevel.DebugInfo, "No user is currently logged in. Anonymous user is not allowed.");
                return(false);
            }

            if (user != null && user.IsLivePricesDisabled)
            {
                Logger.Instance.Log(ErrorLevel.DebugInfo, string.Format("Calculated prices are not allowed to the user '{0}'.", user.UserName));
                return(false);
            }

            // Check for existence of the given products in the Cache
            var productsForRequest = new List <Product>();

            foreach (var product in products)
            {
                // check for invalid products (without product id)
                if (string.IsNullOrEmpty(product.Id))
                {
                    Logger.Instance.Log(ErrorLevel.DebugInfo, string.Format("Live Prices for invalid product: [{0}]", product.PropertiesToString()));
                }
                // Check for existence of the given products in the Cache
                else if (!ErpResponseCache.IsProductInCache(ProductCacheLevel, Helpers.ProductIdentifier(product)))
                {
                    productsForRequest.Add(product);
                }
            }

            if (productsForRequest.Count == 0)
            {
                //Logger.Instance.Log(ErrorLevel.DebugInfo, "All products in cache!");
                SaveLastResponse();
                return(true);
            }

            var request = BuildProductRequest(productsForRequest);

            var response = Connector.GetProductsInfo(request);

            if (!string.IsNullOrEmpty(response?.InnerXml))
            {
                // Parse the response
                Dictionary <string, ProductInfo> prices = ProcessResponse(response);

                if (prices == null || prices.Count == 0)
                {
                    //Logger.Instance.Log(ErrorLevel.DebugInfo, "No result products!");
                    return(false);
                }

                // Cache prices
                foreach (string productKey in prices.Keys)
                {
                    Dictionary <string, ProductInfo> piCache = ErpResponseCache.GetProductInfos(ProductCacheLevel);
                    if (piCache.ContainsKey(productKey))
                    {
                        piCache.Remove(productKey);
                    }
                    piCache.Add(productKey, prices[productKey]);
                }
            }
            else    //error occurred
            {
                return(false);
            }

            SaveLastResponse();
            return(true);
        }