예제 #1
0
            /// <summary>
            /// High-level calculation method to get charges from the calculation logic
            /// and attach them to the transaction and it's lines.
            /// </summary>
            /// <param name="request">The request containing context and transaction to update.</param>
            /// <returns>
            /// Response with updated transaction.
            /// </returns>
            private static GetChargesServiceResponse CalculateCharges(GetChargesServiceRequest request)
            {
                // extract transaction we'll be populating
                var transaction = request.Transaction;

                if (request.RequestContext.GetChannelConfiguration().ChannelType == RetailChannelType.OnlineStore ||
                    request.RequestContext.GetChannelConfiguration().ChannelType == RetailChannelType.SharePointOnlineStore)
                {
                    // clear all the non-manual charges
                    ClearNonManualCharges(transaction);
                }

                // total transaction so that we have order totals and line net amounts for percentage charges and tiered fixed charges
                SalesTransactionTotaler.CalculateTotals(request.RequestContext, transaction);

                // put charges on the transaction lines
                // Consider calculable lines only. Ignore voided or return-by-receipt lines.
                foreach (var salesLine in transaction.ChargeCalculableSalesLines)
                {
                    var priceChargesPerLine = CalculatePriceCharges(salesLine, request);
                    if (priceChargesPerLine != null)
                    {
                        salesLine.ChargeLines.Add(priceChargesPerLine);
                    }
                }

                // Auto-Charges are only supported for Online stores.
                if (request.RequestContext.GetChannelConfiguration().ChannelType == RetailChannelType.OnlineStore ||
                    request.RequestContext.GetChannelConfiguration().ChannelType == RetailChannelType.SharePointOnlineStore)
                {
                    CalculateAutoCharges(request, transaction);
                }

                return(new GetChargesServiceResponse(transaction));
            }
예제 #2
0
            /// <summary>
            /// Calculates the auto charges for the transaction / sales lines.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <param name="transaction">Current sales transaction.</param>
            private static void CalculateAutoCharges(GetChargesServiceRequest request, SalesTransaction transaction)
            {
                // get customer to see their markup group
                string customerAccount     = transaction.CustomerId ?? string.Empty;
                string customerChargeGroup = string.Empty;

                if (!string.IsNullOrWhiteSpace(customerAccount))
                {
                    var getCustomerDataRequest = new GetCustomerDataRequest(customerAccount);
                    SingleEntityDataServiceResponse <Customer> getCustomerDataResponse = request.RequestContext.Execute <SingleEntityDataServiceResponse <Customer> >(getCustomerDataRequest);
                    var customer = getCustomerDataResponse.Entity;
                    customerChargeGroup = (customer != null) ? customer.ChargeGroup : string.Empty;
                }

                // get delivery mode information off the transaction
                string deliveryMode      = transaction.DeliveryMode ?? string.Empty;
                string deliveryModeGroup = GetDeliveryModeGroupFromCode(request.RequestContext, deliveryMode);

                var    channelConfiguration = request.RequestContext.GetChannelConfiguration();
                string currencyCode         = (channelConfiguration != null) ? channelConfiguration.Currency : string.Empty;

                // put charges on the transaction
                var transactionCharges = CalculateTransactionCharges(request.RequestContext, customerAccount, customerChargeGroup, deliveryMode, deliveryModeGroup, transaction);

                foreach (var charge in transactionCharges)
                {
                    transaction.ChargeLines.Add(charge);
                }

                // put charges on the transaction lines
                // Consider calculable lines only. Ignore voided or return-by-receipt lines.
                foreach (var salesLine in transaction.ChargeCalculableSalesLines)
                {
                    // get delivery mode information off the sales line
                    deliveryMode      = string.IsNullOrEmpty(salesLine.DeliveryMode) ? (transaction.DeliveryMode ?? string.Empty) : salesLine.DeliveryMode;
                    deliveryModeGroup = GetDeliveryModeGroupFromCode(request.RequestContext, deliveryMode);

                    var lineCharges = CalculateLineCharges(request.RequestContext, customerAccount, customerChargeGroup, deliveryMode, deliveryModeGroup, salesLine, transaction);

                    foreach (var charge in lineCharges)
                    {
                        salesLine.ChargeLines.Add(charge);
                    }
                }

                // now that all auto charges are on the transaction, calculate their amounts
                CalculateAutoChargeAmounts(request.RequestContext, transaction);

                // convert any charge amounts not in the channel currency
                var transactionAutoChargeLines = transaction.ChargeLines.Where(cl => cl.ChargeType == ChargeType.AutoCharge);

                // Consider calculable lines only. Ignore voided or return-by-receipt lines.
                var lineAutoChargeLines = transaction.ChargeCalculableSalesLines.SelectMany(sl => sl.ChargeLines).Where(cl => cl.ChargeType == ChargeType.AutoCharge);

                var allAutoChargeLines = transactionAutoChargeLines.Concat(lineAutoChargeLines);

                ChargeAmountsToStoreCurrency(request.RequestContext, allAutoChargeLines, currencyCode);
            }
예제 #3
0
            /// <summary>
            /// Calculates the price charges.
            /// </summary>
            /// <param name="salesLine">The sales line.</param>
            /// <param name="request">The request.</param>
            /// <returns>
            /// The miscellaneous charge line.
            /// </returns>
            private static Microsoft.Dynamics.Commerce.Runtime.DataModel.ChargeLine CalculatePriceCharges(SalesLine salesLine, GetChargesServiceRequest request)
            {
                // hook up with caching when it is in.
                var getItemsRequest = new GetItemsDataRequest(new string[] { salesLine.ItemId });

                getItemsRequest.QueryResultSettings = new QueryResultSettings(new ColumnSet("ItemId", "AllocateMarkup", "PriceQty", "Markup"), PagingInfo.AllRecords);
                var getItemsResponse = request.RequestContext.Execute <GetItemsDataResponse>(getItemsRequest);

                Item itemDetails = getItemsResponse.Items.SingleOrDefault();

                if (itemDetails != null && itemDetails.Markup != 0)
                {
                    // there is a price charge associated with the item.
                    decimal amount;

                    // check type price charge
                    if (itemDetails.AllocateMarkup)
                    {
                        // Per Unit markup
                        if (!itemDetails.PriceQuantity.HasValue || itemDetails.PriceQuantity.Value == 0M)
                        {
                            throw new DataValidationException(
                                      DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_ValueOutOfRange,
                                      string.Format("Price quantity is set to 0 for item {0}", itemDetails.ItemId));
                        }

                        amount = itemDetails.Markup / itemDetails.PriceQuantity.Value;
                    }
                    else
                    {
                        // per line markup
                        amount = itemDetails.Markup;
                    }

                    // there is a price charge associated with this item. need to update the price accordingly.
                    var priceCharge = new Microsoft.Dynamics.Commerce.Runtime.DataModel.ChargeLine
                    {
                        CalculatedAmount = amount,
                        ChargeCode       = string.Empty,
                        ItemTaxGroupId   = salesLine.ItemTaxGroupId,
                        SalesTaxGroupId  = salesLine.SalesTaxGroupId,
                        ChargeType       = ChargeType.PriceCharge,
                        ModuleType       = ChargeModule.Sales,
                    };

                    return(priceCharge);
                }

                return(null);
            }