/// <summary>
            /// Get the rounded amount based on the currency code.
            /// </summary>
            /// <param name="context">The request context.</param>
            /// <param name="amount">The amount to be rounded.</param>
            /// <param name="currencyCode">The currency code.</param>
            /// <returns>The rounded value.</returns>
            private static decimal RoundAmountByCurrency(RequestContext context, decimal amount, string currencyCode)
            {
                var roundingRequest = new GetRoundedValueServiceRequest(amount, currencyCode);
                GetRoundedValueServiceResponse roundingResponse = context.Execute <GetRoundedValueServiceResponse>(roundingRequest);

                return(roundingResponse.RoundedValue);
            }
Ejemplo n.º 2
0
            /// <summary>
            /// Static entry point to calculate amount paid and due.
            /// </summary>
            /// <param name="context">The request context.</param>
            /// <param name="salesTransaction">The sales transaction.</param>
            public static void CalculateAmountPaidAndDue(RequestContext context, SalesTransaction salesTransaction)
            {
                ThrowIf.Null(context, "context");
                ThrowIf.Null(salesTransaction, "salesTransaction");

                decimal paymentRequiredAmount;

                salesTransaction.AmountPaid = SalesTransactionTotaler.GetPaymentsSum(salesTransaction.TenderLines);

                // decides what is expected to be paid for this transaction
                switch (salesTransaction.CartType)
                {
                case CartType.CustomerOrder:
                    paymentRequiredAmount = SalesTransactionTotaler.CalculateRequiredPaymentAmount(context, salesTransaction);
                    break;

                case CartType.Shopping:
                case CartType.Checkout:
                case CartType.AccountDeposit:
                    paymentRequiredAmount = salesTransaction.TotalAmount;
                    break;

                case CartType.IncomeExpense:
                    paymentRequiredAmount = salesTransaction.IncomeExpenseTotalAmount;
                    break;

                default:
                    throw new DataValidationException(
                              DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidRequest,
                              string.Format("SalesTransactionTotaler::CalculateAmountPaidAndDue: CartType '{0}' not supported.", salesTransaction.CartType));
                }

                salesTransaction.SalesPaymentDifference = paymentRequiredAmount - salesTransaction.AmountPaid;
                salesTransaction.AmountDue = paymentRequiredAmount - salesTransaction.AmountPaid;

                TenderLine lastTenderLine = null;

                if (!salesTransaction.TenderLines.IsNullOrEmpty())
                {
                    lastTenderLine = salesTransaction.ActiveTenderLines.LastOrDefault();
                }

                if (lastTenderLine != null)
                {
                    // Calculate the expected (rounded) amount due for last payment.
                    decimal amountDueBeforeLastPayment = paymentRequiredAmount - salesTransaction.ActiveTenderLines.Take(salesTransaction.ActiveTenderLines.Count - 1).Sum(t => t.Amount);
                    GetPaymentRoundedValueServiceRequest roundAmountDueBeforeLastPaymentRequest  = new GetPaymentRoundedValueServiceRequest(amountDueBeforeLastPayment, lastTenderLine.TenderTypeId, isChange: false);
                    GetRoundedValueServiceResponse       roundAmountDueBeforeLastPaymentResponse = context.Execute <GetRoundedValueServiceResponse>(roundAmountDueBeforeLastPaymentRequest);

                    // Set amont due to zero if payment amount equals to expected rounded payment amount. Otherwise another payment should be required (that could use different rounding settings).
                    if (roundAmountDueBeforeLastPaymentResponse.RoundedValue == lastTenderLine.Amount)
                    {
                        salesTransaction.AmountDue = decimal.Zero;
                    }
                }

                // When required amount is positive, amount due must be zero or negative (overtender), otherwise (e.g. for refunds or exchanges) exact amount has to refunded (zero balance).
                salesTransaction.IsRequiredAmountPaid = (paymentRequiredAmount > 0 && salesTransaction.AmountDue <= 0) ||
                                                        (paymentRequiredAmount <= 0 && salesTransaction.AmountDue == 0);
            }
            /// <summary>
            /// Round amount by tender type id.
            /// </summary>
            /// <param name="context">The request context.</param>
            /// <param name="tenderTypeId">Tender type id.</param>
            /// <param name="amount">The amount.</param>
            /// <param name="isChange">Value indicating whether this request is for change.</param>
            /// <returns>Rounded amount.</returns>
            private static decimal RoundAmountByTenderType(RequestContext context, string tenderTypeId, decimal amount, bool isChange)
            {
                ThrowIf.Null(context, "context");

                GetPaymentRoundedValueServiceRequest request  = new GetPaymentRoundedValueServiceRequest(amount, tenderTypeId, isChange);
                GetRoundedValueServiceResponse       response = context.Execute <GetRoundedValueServiceResponse>(request);

                return(response.RoundedValue);
            }
Ejemplo n.º 4
0
            /// <summary>
            /// Rounding helper method for rounding currency amounts.
            /// </summary>
            /// <param name="context">The request context.</param>
            /// <param name="amount">The amount to be rounded.</param>
            /// <returns>The rounded amount.</returns>
            private static decimal RoundCurrencyAmount(RequestContext context, decimal amount)
            {
                GetRoundedValueServiceRequest request = new GetRoundedValueServiceRequest(
                    amount,
                    context.GetChannelConfiguration().Currency,
                    numberOfDecimals: 0,
                    useSalesRounding: false);

                GetRoundedValueServiceResponse response = context.Execute <GetRoundedValueServiceResponse>(request);

                return(response.RoundedValue);
            }
Ejemplo n.º 5
0
            private static decimal RoundWithPricesRounding(RequestContext context, decimal amountToRound, string currencyCode)
            {
                GetRoundedValueServiceRequest request = new GetRoundedValueServiceRequest(
                    amountToRound,
                    currencyCode,
                    numberOfDecimals: 0,
                    useSalesRounding: false);

                GetRoundedValueServiceResponse response = context.Execute <GetRoundedValueServiceResponse>(request);

                return(response.RoundedValue);
            }