/// <summary>
            /// This method will find all auto-charge configurations which match the combinations
            /// and info given in the ChargeProcessorArguments parameters.
            /// Then it will apply the charge calculation rules and return a collection of
            /// ChargeLines which should be applied to the transaction or line.
            /// </summary>
            /// <param name="context">The request context.</param>
            /// <param name="transaction">Transaction we will populate with charges.</param>
            /// <param name="args">Defines which combinations to look for, whether header/line charges, and transaction/line info.</param>
            /// <returns>The collection of charge lines.</returns>
            private static IEnumerable <ChargeLine> ApplyAutoCharges(RequestContext context, SalesTransaction transaction, ChargeProcessorArguments args)
            {
                // for all combinations to try, search for any matches in the data base
                var chargeConfigurations = new List <ChargeConfiguration>();

                foreach (var combo in args.CombinationsToTry)
                {
                    var header = BuildConfigurationHeader(
                        combo.Item1,
                        combo.Item2,
                        combo.Item3,
                        args.CustomerId,
                        args.CustomerChargeGroup,
                        args.ItemId,
                        args.ItemChargeGroup,
                        args.DeliveryModeId,
                        args.DeliveryModeChargeGroup);

                    GetChargeConfigurationsByHeaderDataRequest getChargeConfigurationsByHeaderDataRequest = new GetChargeConfigurationsByHeaderDataRequest(args.ChargeType, header, QueryResultSettings.AllRecords);
                    var configs = context.Execute <EntityDataServiceResponse <ChargeConfiguration> >(getChargeConfigurationsByHeaderDataRequest).PagedEntityCollection;
                    chargeConfigurations.AddRange(GetValidChargeConfigurations(configs.Results));
                }

                // try to apply all the charge configurations found above
                var orderAmount    = transaction.NetAmountWithNoTax;
                var appliedCharges = ApplyChargeConfigurations(chargeConfigurations, orderAmount);

                return(appliedCharges);
            }
            private EntityDataServiceResponse <ChargeConfiguration> GetChargeConfigurationsByHeader(GetChargeConfigurationsByHeaderDataRequest request)
            {
                ThrowIf.Null(request, "request");
                ThrowIf.Null(request.QueryResultSettings, "request.QueryResultSettings");

                ChargeL2CacheDataStoreAccessor level2CacheDataAccessor = this.GetChargeL2CacheDataStoreAccessor(request.RequestContext);

                bool   found;
                bool   updateL2Cache;
                string dataAreaId = request.RequestContext.GetChannelConfiguration().InventLocationDataAreaId;
                PagedResult <ChargeConfiguration> result = DataManager.GetDataFromCache(() => level2CacheDataAccessor.GetChargeConfigurationsByHeader(dataAreaId, request.QueryResultSettings, request.ChargeType, request.Header), out found, out updateL2Cache);

                if (!found)
                {
                    var query = new SqlPagedQuery(request.QueryResultSettings)
                    {
                        From  = ChargeConfigurationViewName,
                        Where = "DATAAREAID = @DataAreaId"
                    };

                    query.Parameters["@DataAreaId"] = dataAreaId;

                    this.FilterChargeConfigurations(query, request.ChargeType, request.Header);

                    using (DatabaseContext databaseContext = new DatabaseContext(request.RequestContext))
                    {
                        result = databaseContext.ReadEntity <ChargeConfiguration>(query);
                    }

                    updateL2Cache &= result != null;
                }

                if (updateL2Cache)
                {
                    level2CacheDataAccessor.PutChargeConfigurationsByHeader(dataAreaId, request.QueryResultSettings, request.ChargeType, request.Header, result);
                }

                return(new EntityDataServiceResponse <ChargeConfiguration>(result));
            }