Exemplo n.º 1
0
            /// <summary>
            /// Calculate specific reason codes on an affiliation line and add them to the incoming collection.
            /// </summary>
            /// <param name="request">The request object.</param>
            /// <param name="requiredReasonCodes">The collection to which required reason codes are added.</param>
            /// <param name="reasonCodeRequirements">The required specific reason codes map.</param>
            /// <param name="salesAffiliationLoyaltyTier">The sales affiliation loyalty tier on which to calculate required reason codes.</param>
            private static void CalculateRequiredSpecificReasonCodesOnAffiliationLine(
                CalculateRequiredReasonCodesServiceRequest request,
                IDictionary <string, ReasonCode> requiredReasonCodes,
                HashSet <ReasonCodeRequirement> reasonCodeRequirements,
                SalesAffiliationLoyaltyTier salesAffiliationLoyaltyTier)
            {
                // Gets the affiliation according to the foreign key AffiliationId of the salesAffiliationLoyaltyTier.
                GetAffiliationByAffiliationIdDataRequest dataRequest = new GetAffiliationByAffiliationIdDataRequest(salesAffiliationLoyaltyTier.AffiliationId);
                Affiliation affiliation = request.RequestContext.Execute <SingleEntityDataServiceResponse <Affiliation> >(dataRequest).Entity;

                if (affiliation != null)
                {
                    CalculateReasonCodesSpecificToEntity(
                        request,
                        salesAffiliationLoyaltyTier.AffiliationId.ToString(CultureInfo.InvariantCulture),
                        ReasonCodeTableRefType.Affiliation,
                        affiliation.Name,
                        string.Empty,
                        string.Empty,
                        requiredReasonCodes,
                        reasonCodeRequirements,
                        salesAffiliationLoyaltyTier.ReasonCodeLines,
                        null);
                }
            }
            /// <summary>
            /// Calculates the required reason codes on an income expense line.
            /// </summary>
            /// <param name="requestContext">The request context.</param>
            /// <param name="transaction">Current transaction.</param>
            /// <param name="incomeExpenseLine">The income expense line.</param>
            /// <param name="sourceType">Type of the source.</param>
            public static void CalculateRequiredReasonCodesOnIncomeExpenseLine(RequestContext requestContext, SalesTransaction transaction, IncomeExpenseLine incomeExpenseLine, ReasonCodeSourceType sourceType)
            {
                ThrowIf.Null(requestContext, "requestContext");
                ThrowIf.Null(incomeExpenseLine, "incomeExpenseLine");

                var serviceRequest = new CalculateRequiredReasonCodesServiceRequest(transaction, sourceType, new[] { incomeExpenseLine });

                CalculateRequiredReasonCodesHelper(requestContext, serviceRequest);
            }
            /// <summary>
            /// Calculates the required reason codes on affiliation line.
            /// </summary>
            /// <param name="requestContext">The request context.</param>
            /// <param name="transaction">Current transaction.</param>
            /// <param name="salesAffiliationLoyaltyTiers">The sales affiliation lines.</param>
            /// <param name="sourceType">Type of the source.</param>
            public static void CalculateRequiredReasonCodesOnAffiliationLines(RequestContext requestContext, SalesTransaction transaction, IEnumerable <SalesAffiliationLoyaltyTier> salesAffiliationLoyaltyTiers, ReasonCodeSourceType sourceType)
            {
                ThrowIf.Null(requestContext, "requestContext");
                ThrowIf.Null(salesAffiliationLoyaltyTiers, "salesAffiliationLoyaltyTiers");

                var serviceRequest = new CalculateRequiredReasonCodesServiceRequest(transaction, sourceType, salesAffiliationLoyaltyTiers);

                CalculateRequiredReasonCodesHelper(requestContext, serviceRequest);
            }
            /// <summary>
            /// Calculates the required reason codes on tender line.
            /// </summary>
            /// <param name="requestContext">The request context.</param>
            /// <param name="transaction">Current transaction.</param>
            /// <param name="tenderLine">The tender line.</param>
            /// <param name="sourceType">Type of the source.</param>
            public static void CalculateRequiredReasonCodesOnTenderLine(RequestContext requestContext, SalesTransaction transaction, TenderLine tenderLine, ReasonCodeSourceType sourceType)
            {
                ThrowIf.Null(requestContext, "requestContext");
                ThrowIf.Null(tenderLine, "tenderLine");

                var serviceRequest = new CalculateRequiredReasonCodesServiceRequest(transaction, sourceType, new[] { tenderLine });

                CalculateRequiredReasonCodesHelper(requestContext, serviceRequest);
            }
            /// <summary>
            /// Calculates the required reason codes on the current sales transaction level.
            /// </summary>
            /// <param name="requestContext">The request context.</param>
            /// <param name="salesTransaction">The sales transaction.</param>
            /// <param name="sourceType">Type of the source.</param>
            public static void CalculateRequiredReasonCodesOnTransaction(RequestContext requestContext, SalesTransaction salesTransaction, ReasonCodeSourceType sourceType)
            {
                ThrowIf.Null(requestContext, "requestContext");
                ThrowIf.Null(salesTransaction, "salesTransaction");

                var serviceRequest = new CalculateRequiredReasonCodesServiceRequest(salesTransaction, sourceType);

                CalculateRequiredReasonCodesHelper(requestContext, serviceRequest);
            }
            /// <summary>
            /// Validates the required reason code lines filled.
            /// </summary>
            /// <param name="requestContext">The request context.</param>
            /// <param name="salesTransaction">The sales transaction.</param>
            /// <exception cref="ConfigurationException">Required Service missing.</exception>
            /// <exception cref="DataValidationException">One or more reason codes required for the transaction are missing.</exception>
            public static void ValidateRequiredReasonCodeLinesFilled(RequestContext requestContext, SalesTransaction salesTransaction)
            {
                ThrowIf.Null(requestContext, "requestContext");
                ThrowIf.Null(salesTransaction, "salesTransaction");

                var serviceRequest  = new CalculateRequiredReasonCodesServiceRequest(salesTransaction, ReasonCodeSourceType.None);
                var serviceResponse = requestContext.Execute <CalculateRequiredReasonCodesServiceResponse>(serviceRequest);

                ReasonCodesWorkflowHelper.ThrowIfRequiredReasonCodesMissing(serviceResponse);
            }
Exemplo n.º 7
0
            /// <summary>
            /// Calculates the specific reason code on an entity like sales line, tender line etc.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <param name="sourceId">The source identifier.</param>
            /// <param name="tableRefType">The table identifier for the specific reason code.</param>
            /// <param name="refRelation">The first reference relation key corresponding to the entity and table.</param>
            /// <param name="refRelation2">The second reference relation key corresponding to the entity and table.</param>
            /// <param name="refRelation3">The third reference relation key corresponding to the entity and table.</param>
            /// <param name="requiredReasonCodes">The collection to which required reason codes are added.</param>
            /// <param name="reasonCodeRequirements">The required specific reason codes map.</param>
            /// <param name="presentReasonCodeLines">The collection with the already present reason code lines.</param>
            /// <param name="salesLine">The sales line when applicable.</param>
            private static void CalculateReasonCodesSpecificToEntity(
                CalculateRequiredReasonCodesServiceRequest request,
                string sourceId,
                ReasonCodeTableRefType tableRefType,
                string refRelation,
                string refRelation2,
                string refRelation3,
                IDictionary <string, ReasonCode> requiredReasonCodes,
                HashSet <ReasonCodeRequirement> reasonCodeRequirements,
                IEnumerable <ReasonCodeLine> presentReasonCodeLines,
                SalesLine salesLine)
            {
                GetReasonCodesByTableRefTypeDataRequest getReasonCodesByTableRefTypeDataRequest = new GetReasonCodesByTableRefTypeDataRequest(tableRefType, refRelation, refRelation2, refRelation3, QueryResultSettings.AllRecords);
                IEnumerable <ReasonCode> reasonCodes = request.RequestContext.Runtime.Execute <EntityDataServiceResponse <ReasonCode> >(getReasonCodesByTableRefTypeDataRequest, request.RequestContext).PagedEntityCollection.Results;

                reasonCodes = AddLinkedReasonCodes(reasonCodes, request.RequestContext);

                var triggeredReasonCodes = CalculateTriggeredReasonCodes(reasonCodes, presentReasonCodeLines, request.RequestContext);

                reasonCodes = reasonCodes.Union(triggeredReasonCodes).Distinct();

                reasonCodes = AddLinkedReasonCodes(reasonCodes, request.RequestContext);

                foreach (var reasonCode in reasonCodes)
                {
                    if (presentReasonCodeLines.Any(rc => string.Equals(rc.ReasonCodeId, reasonCode.ReasonCodeId, StringComparison.OrdinalIgnoreCase)))
                    {
                        continue;
                    }

                    bool entitySpecificApplicability = true;

                    switch (tableRefType)
                    {
                    case ReasonCodeTableRefType.Item:
                        entitySpecificApplicability = HasSalesLineSpecificApplicability(reasonCode, salesLine);
                        break;
                    }

                    if (entitySpecificApplicability &&
                        ShouldReasonCodeBeApplied(reasonCode, request.SalesTransaction))
                    {
                        var reasonCodeRequirement = new ReasonCodeRequirement()
                        {
                            ReasonCodeId      = reasonCode.ReasonCodeId,
                            SourceId          = sourceId,
                            TableRefTypeValue = (int)tableRefType,
                        };

                        reasonCodeRequirements.Add(reasonCodeRequirement);
                        requiredReasonCodes[reasonCode.ReasonCodeId] = reasonCode;
                    }
                }
            }
Exemplo n.º 8
0
            /// <summary>
            /// Calculate specific reason codes on a tender line and add them to the incoming collection.
            /// </summary>
            /// <param name="request">The request object.</param>
            /// <param name="requiredReasonCodes">The collection to which required reason codes are added.</param>
            /// <param name="reasonCodeRequirements">The required specific reason codes map.</param>
            /// <param name="tenderLine">The tenderLine on which to calculate required reason codes.</param>
            private static void CalculateRequiredSpecificReasonCodesOnTenderLine(
                CalculateRequiredReasonCodesServiceRequest request,
                IDictionary <string, ReasonCode> requiredReasonCodes,
                HashSet <ReasonCodeRequirement> reasonCodeRequirements,
                TenderLine tenderLine)
            {
                if (tenderLine.Status == TenderLineStatus.Historical)
                {
                    return;
                }

                // if tenderline is a card, refrelation3 becomes tenderline.cardtypeid and tablerefid is creditcard
                var getChannelTenderTypesDataRequest = new GetChannelTenderTypesDataRequest(request.RequestContext.GetPrincipal().ChannelId, QueryResultSettings.AllRecords);
                var tenderTypes = request.RequestContext.Runtime.Execute <EntityDataServiceResponse <TenderType> >(getChannelTenderTypesDataRequest, request.RequestContext).PagedEntityCollection.Results;

                ReasonCodeTableRefType tableRef = ReasonCodeTableRefType.Tender;
                string refRelation3             = string.Empty;

                TenderType tenderType = tenderTypes.Where(type => type.TenderTypeId == tenderLine.TenderTypeId).SingleOrDefault();

                if (tenderType.OperationId == (int)RetailOperation.PayCard)
                {
                    refRelation3 = tenderLine.CardTypeId;
                    tableRef     = ReasonCodeTableRefType.CreditCard;
                }

                CalculateReasonCodesSpecificToEntity(
                    request,
                    tenderLine.TenderTypeId,
                    tableRef,
                    request.SalesTransaction.StoreId,
                    tenderLine.TenderTypeId,
                    refRelation3,
                    requiredReasonCodes,
                    reasonCodeRequirements,
                    tenderLine.ReasonCodeLines,
                    null);
            }
Exemplo n.º 9
0
            /// <summary>
            /// Calculates the required reason codes.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <returns>The info codes response.</returns>
            private static CalculateRequiredReasonCodesServiceResponse CalculateRequiredReasonCodes(CalculateRequiredReasonCodesServiceRequest request)
            {
                CalculateRequiredReasonCodesServiceResponse response = ReasonCodesCalculator.CalculateRequiredReasonCodes(request);

                SetProductIdsForUpsell(request.RequestContext, response.RequiredReasonCodes);

                return(response);
            }
            /// <summary>
            /// Helper methods to calculates the required reason codes.
            /// </summary>
            /// <param name="requestContext">The request context.</param>
            /// <param name="serviceRequest">The service request.</param>
            /// <exception cref="ConfigurationException">Required Service missing: {0}.</exception>
            private static void CalculateRequiredReasonCodesHelper(RequestContext requestContext, CalculateRequiredReasonCodesServiceRequest serviceRequest)
            {
                ThrowIf.Null(serviceRequest.SalesTransaction, "serviceRequest.SalesTransaction");

                // Reason codes are only calculated for retail stores and carts that are not customer orders.
                if ((requestContext.GetChannelConfiguration().ChannelType == RetailChannelType.RetailStore) &&
                    (serviceRequest.SalesTransaction.CartType != CartType.CustomerOrder))
                {
                    var serviceResponse = requestContext.Execute <CalculateRequiredReasonCodesServiceResponse>(serviceRequest);
                    ReasonCodesWorkflowHelper.ThrowIfRequiredReasonCodesMissing(serviceResponse);
                }
            }
Exemplo n.º 11
0
            /// <summary>
            /// Calculates the required reason codes.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <returns>The calculate required reason codes response.</returns>
            public static CalculateRequiredReasonCodesServiceResponse CalculateRequiredReasonCodes(CalculateRequiredReasonCodesServiceRequest request)
            {
                // Keeps track of required reason code lines added.
                Dictionary <string, ReasonCode> requiredReasonCodes    = new Dictionary <string, ReasonCode>();
                HashSet <string> transactionRequiredReasonCodeIds      = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                HashSet <ReasonCodeRequirement> reasonCodeRequirements = new HashSet <ReasonCodeRequirement>();

                // calculate reason codes for source type
                CalculateRequiredReasonCodesBySourceType(request, requiredReasonCodes, transactionRequiredReasonCodeIds, reasonCodeRequirements);

                // calculate reason codes for sales lines
                foreach (var salesLine in request.SalesLines)
                {
                    // calculate specific reason codes
                    CalculateReasonCodesSpecificToEntity(
                        request,
                        salesLine.ProductId.ToString(CultureInfo.InvariantCulture),
                        ReasonCodeTableRefType.Item,
                        salesLine.ItemId,
                        string.Empty,
                        string.Empty,
                        requiredReasonCodes,
                        reasonCodeRequirements,
                        salesLine.ReasonCodeLines,
                        salesLine);
                }

                // calculate reason codes for tender lines
                foreach (var tenderLine in request.TenderLines)
                {
                    // calculate specific reason codes
                    CalculateRequiredSpecificReasonCodesOnTenderLine(
                        request, requiredReasonCodes, reasonCodeRequirements, tenderLine);
                }

                // calculate reason codes for affiliation lines
                foreach (var salesAffiliationLoyaltyTier in request.SalesAffiliationLoyaltyTiers)
                {
                    // Calculate specific reason codes
                    CalculateRequiredSpecificReasonCodesOnAffiliationLine(
                        request, requiredReasonCodes, reasonCodeRequirements, salesAffiliationLoyaltyTier);
                }

                // calculate reason codes for income expense lines
                foreach (var incomeExpenseLine in request.SalesTransaction.IncomeExpenseLines)
                {
                    CalculateReasonCodesSpecificToEntity(
                        request,
                        System.Enum.GetName(typeof(IncomeExpenseAccountType), incomeExpenseLine.AccountType),
                        ReasonCodeTableRefType.IncomeExpense,
                        incomeExpenseLine.StoreNumber,
                        incomeExpenseLine.IncomeExpenseAccount,
                        string.Empty,
                        requiredReasonCodes,
                        reasonCodeRequirements,
                        request.SalesTransaction.ReasonCodeLines,
                        null);
                }

                // calculate reason codes for customer
                CalculateReasonCodesSpecificToEntity(
                    request,
                    request.SalesTransaction.CustomerId,
                    ReasonCodeTableRefType.Customer,
                    request.SalesTransaction.CustomerId,
                    string.Empty,
                    string.Empty,
                    requiredReasonCodes,
                    reasonCodeRequirements,
                    request.SalesTransaction.ReasonCodeLines,
                    null);

                // move the customer and income expense reason codes to transaction level.
                var ids = reasonCodeRequirements.Where(r => (r.TableRefType == ReasonCodeTableRefType.IncomeExpense || r.TableRefType == ReasonCodeTableRefType.Customer))
                          .Select(r => r.ReasonCodeId);

                transactionRequiredReasonCodeIds.AddRange(ids);

                return(new CalculateRequiredReasonCodesServiceResponse(
                           requiredReasonCodes.Values,
                           transactionRequiredReasonCodeIds,
                           reasonCodeRequirements));
            }
Exemplo n.º 12
0
            /// <summary>
            /// Calculates the required reason codes given the source type.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <param name="requiredReasonCodes">The collection to which required reason codes are added.</param>
            /// <param name="transactionRequiredReasonCodeIds">The identifiers of reason codes required at transaction level.</param>
            /// <param name="reasonCodeRequirements">The collection of reason code requirements.</param>
            private static void CalculateRequiredReasonCodesBySourceType(
                CalculateRequiredReasonCodesServiceRequest request,
                Dictionary <string, ReasonCode> requiredReasonCodes,
                HashSet <string> transactionRequiredReasonCodeIds,
                HashSet <ReasonCodeRequirement> reasonCodeRequirements)
            {
                // Look up operation level reason codes if available.
                if (request.SourceType != ReasonCodeSourceType.None)
                {
                    ReasonCodeSettings settingsDictionary = GetReasonCodeSettings(request.RequestContext);
                    string             reasonCodeId       = settingsDictionary[request.SourceType];

                    if (!string.IsNullOrWhiteSpace(reasonCodeId))
                    {
                        GetReasonCodesDataRequest getReasonCodeRequest = new GetReasonCodesDataRequest(QueryResultSettings.AllRecords, new string[] { reasonCodeId });
                        IEnumerable <ReasonCode>  reasonCodes          = request.RequestContext.Execute <EntityDataServiceResponse <ReasonCode> >(getReasonCodeRequest).PagedEntityCollection.Results;

                        foreach (var reasonCode in reasonCodes)
                        {
                            if (IsTransactionSourceType(request.SourceType) &&
                                ShouldReasonCodeBeApplied(reasonCode, request.SalesTransaction))
                            {
                                if (!ContainsReasonCode(request.SalesTransaction.ReasonCodeLines, reasonCode.ReasonCodeId))
                                {
                                    requiredReasonCodes[reasonCode.ReasonCodeId] = reasonCode;
                                    transactionRequiredReasonCodeIds.Add(reasonCode.ReasonCodeId);
                                }

                                var triggeredReasonCodes = CalculateTriggeredReasonCodes(
                                    new ReasonCode[] { reasonCode }, request.SalesTransaction.ReasonCodeLines, request.RequestContext);

                                if (triggeredReasonCodes.Any())
                                {
                                    requiredReasonCodes.AddRange(triggeredReasonCodes.ToDictionary(rc => rc.ReasonCodeId, rc => rc));
                                    transactionRequiredReasonCodeIds.AddRange(triggeredReasonCodes.Select(rc => rc.ReasonCodeId));
                                }
                            }
                            else
                            {
                                foreach (var salesLine in request.SalesLines)
                                {
                                    if (ShouldReasonCodeBeApplied(reasonCode, request.SalesTransaction))
                                    {
                                        if (!ContainsReasonCode(salesLine.ReasonCodeLines, reasonCode.ReasonCodeId))
                                        {
                                            var reasonCodeRequirement = new ReasonCodeRequirement()
                                            {
                                                ReasonCodeId      = reasonCode.ReasonCodeId,
                                                SourceId          = salesLine.ProductId.ToString(CultureInfo.InvariantCulture),
                                                TableRefTypeValue = (int)ReasonCodeTableRefType.Item,
                                            };

                                            reasonCodeRequirements.Add(reasonCodeRequirement);
                                            requiredReasonCodes[reasonCode.ReasonCodeId] = reasonCode;
                                        }

                                        var triggeredReasonCodes = CalculateTriggeredReasonCodes(
                                            new ReasonCode[] { reasonCode }, salesLine.ReasonCodeLines, request.RequestContext);

                                        if (triggeredReasonCodes.Any())
                                        {
                                            requiredReasonCodes.AddRange(triggeredReasonCodes.ToDictionary(rc => rc.ReasonCodeId, rc => rc));
                                            reasonCodeRequirements.AddRange(triggeredReasonCodes.Select(rc => new ReasonCodeRequirement()
                                            {
                                                ReasonCodeId      = rc.ReasonCodeId,
                                                SourceId          = salesLine.ProductId.ToString(CultureInfo.InvariantCulture),
                                                TableRefTypeValue = (int)ReasonCodeTableRefType.Item,
                                            }));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }