/// <summary>
        /// Retrieves the the redemption history for a merchant's deals.
        /// </summary>
        /// <returns>
        /// The ResultCode corresponding to the result of the operation.
        /// </returns>
        private ResultCode GetMerchantDealRedemptions()
        {
            ResultCode result = ResultCode.Success;

            // Retrieve the redemption history for the merchant's deals.
            Context.Log.Verbose("Retrieving redemption history for deals offered by merchants with partner merchant IDs listed within " +
                                "the query.");
            result = RedeemedDealOperations.RetrieveMerchantDealRedemptions();

            return(result);
        }
        /// <summary>
        /// Adds a RedeemedDeal record to the data store for the specified ClearingData record.
        /// </summary>
        /// <param name="clearingData">
        /// The ClearingData record for which to add a redeemed deal record.
        /// </param>
        /// <param name="redeemedDeal">
        /// The RedeemedDeal object to use when committing the redeemed deal record.
        /// </param>
        /// <returns>
        /// The ResultCode corresponding to the result of the operation.
        /// </returns>
        private ResultCode AddRedeemedDealRecord(ClearingData clearingData,
                                                 RedeemedDeal redeemedDeal)
        {
            ResultCode result = ResultCode.NoApplicableDealFound;

            redeemedDeal.AnalyticsEventId = Guid.NewGuid();
            Context[Key.RedeemedDeal]     = redeemedDeal;
            new MasterCard(Context).MarshalRedeemDeal(clearingData);
            Context[Key.Partner] = Partner.MasterCard;
            result = RedeemedDealOperations.AddRedeemedDeal();

            return(result);
        }
        /// <summary>
        /// Retrieves the the requested deal reports.
        /// </summary>
        /// <returns>
        /// The ResultCode corresponding to the result of the operation.
        /// </returns>
        private ResultCode RetrieveDealReports()
        {
            ResultCode result = ResultCode.Success;

            GetDealReportsResponse response = (GetDealReportsResponse)Context[Key.Response];

            Context.Log.Verbose("Retrieving requested deal reports.");
            result = RedeemedDealOperations.RetrieveDealReports();
            Context.Log.Verbose("Successfully retrieved information for {0} of the {1} requested deals.",
                                response.DealReports.Count(), DealReportsQuery.DealReportQueries.Count());

            return(result);
        }
        /// <summary>
        /// Gets the object to use to perform operations on redeemed deals.
        /// </summary>
        /// <param name="context">
        /// The context in which operations will be performed.
        /// </param>
        /// <returns>
        /// The IRedeemedDealOperations instance to use.
        /// </returns>
        public static IRedeemedDealOperations RedeemedDealOperations(CommerceContext context)
        {
            ValidateContext(context);

            IRedeemedDealOperations result = new RedeemedDealOperations();

            if (context.Config.DataStoreMockLevel != CommerceDataStoreMockLevel.None)
            {
                result = LateBinding.BuildObjectFromLateBoundAssembly <IRedeemedDealOperations>("MockRedeemedDealOperations",
                                                                                                LateBoundMocksAssemblyTypes);
            }

            result.Context = context;

            return(result);
        }
        /// <summary>
        /// Processes the rebate confirmation file.
        /// </summary>
        private void ProcessRebateConfirmation()
        {
            // Deserialize rebate confirmation file into a RebateConfirmation object.
            RebateConfirmationParser rebateConfirmationParser = new RebateConfirmationParser(Context.Log);
            RebateConfirmation       rebateConfirmation       = rebateConfirmationParser.Parse(FileName, Stream);

            if (rebateConfirmation != null)
            {
                for (int count = 0; count < rebateConfirmation.DataRecords.Count; count++)
                {
                    RebateConfirmationData rebateConfirmationData = rebateConfirmation.DataRecords[count];
                    if (rebateConfirmationData != null)
                    {
                        // Mark the redemption as RejectedByPartner.
                        Context[Key.RebateConfirmationData] = rebateConfirmationData;
                        ResultCode result = RedeemedDealOperations.MarkRejectedByMasterCard();

                        // Log warning if needed.
                        switch (result)
                        {
                        case ResultCode.MatchingRedeemedDealNotFound:
                            Context.Log.Warning("RebateConfirmationData record #{0} could not be marked RejectedByPartner, because " +
                                                "no matching redemption record could be found.", (int)result, count + 1);
                            break;

                        case ResultCode.MultipleMatchingRedeemedDealsFound:
                            Context.Log.Warning("More than one matching redemption record matched RebateConfirmationData record " +
                                                "#{0}. One of these was marked RejectedByPartner, but since the data is " +
                                                "ambiguous, it may not correspond to the correct redemption.", (int)result, count + 1);
                            break;

                        case ResultCode.RedeemedDealFoundIsInexactMatch:
                            Context.Log.Warning("A matching redemption record for RebateConfirmationData record #{0} was marked " +
                                                "RejectedByPartner, but the record was not an exact match.", (int)result, count + 1);
                            break;
                        }
                        ;
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Generates transaction report for Rewardnetwork between the given dates
        /// </summary>
        /// <param name="startDate">Start date for the transaction report</param>
        /// <param name="endDate">End date for the transaction report exclusive</param>
        public void GenerateReportForDays(DateTime startDate, DateTime endDate)
        {
            DateTime reportDate = startDate.AddDays(1);

            //Get all the transactions till the end date
            while (reportDate <= endDate)
            {
                //Get all transactions from db
                var result = RedeemedDealOperations.GetRedeemedDealTransactionInfosByDate(startDate, endDate);

                if (result == ResultCode.Success)
                {
                    List <RedeemedDealTransactionInfo> lstTransactionInfos =
                        (List <RedeemedDealTransactionInfo>)RedeemedDealOperations.Context[Key.RedeemedDealInfo];

                    List <string> lstDealGuids =
                        lstTransactionInfos.Select(redeemDealTransactionInfo => redeemDealTransactionInfo.DealId.ToString())
                        .ToList();

                    //Filter out only RN transactions
                    Dictionary <string, DotM.DataContracts.Deal> dealIdsToProviderId = GetRewardNetworkDeals(lstDealGuids);

                    Collection <TransactionRecord> lstTransactionRecords = GetTransactionRecords(lstTransactionInfos,
                                                                                                 dealIdsToProviderId);

                    //Generate the report as per RN specification
                    Tuple <string, string> reportTuple = TransactionReportBuilder.Build(lstTransactionRecords, startDate);

                    //Upload the report to RN FTP
                    UploadReport(reportTuple);

                    //Update the last successful run date in the context. This will eventually be persisted in the scheduler job details, so that we know the start date for the next run
                    Context[Key.RewardNetworkReportLastRunDate] = startDate;

                    startDate  = startDate.AddDays(1);
                    reportDate = reportDate.AddDays(1);
                }
            }
        }
        /// <summary>
        /// Process the transaction log file
        /// </summary>
        /// <returns>
        /// Async Task Wrapper
        /// </returns>
        public async Task Process()
        {
            TransactionLogParser transactionLogParser = new TransactionLogParser(Context.Log);
            TransactionLogFile   transactionLogFile   = transactionLogParser.Parse(TransactionLogFileName, TransactionLogFileStream);

            if (transactionLogFile != null)
            {
                foreach (TransactionLogDetail detail in transactionLogFile.TransactionLogRecords)
                {
                    // block the reversed transactions
                    if (TransactionIdSet.Contains(detail.TransactionId) || detail.TransactionAmount <= 0)
                    {
                        continue;
                    }

                    TransactionIdSet.Add(detail.TransactionId);

                    // 1. process the detail record here -> Insert as redeemed deal
                    RedeemedDeal redeemedDeal = new RedeemedDeal()
                    {
                        AnalyticsEventId = Guid.NewGuid()
                    };
                    Context[Key.RedeemedDeal] = redeemedDeal;
                    MarshalRedeemDeal(detail);
                    ResultCode result = RedeemedDealOperations.AddRedeemedDeal();

                    //2. If the record was processed successfully, attempt to add a redemption reward if applicable and analytics
                    if (result == ResultCode.Created)
                    {
                        RedeemedDealInfo redemptionInfo = (RedeemedDealInfo)Context[Key.RedeemedDealInfo];
                        // First add a redemption reward to the redeeming user if they're enabled.
                        if (EnableRedemptionRewards)
                        {
                            if (WorkerActions.RewardRedemption(RewardOperations, Context) == ResultCode.Success)
                            {
                                // Add job to process the reward payout.
                                ConcurrentDictionary <string, string> payload = new ConcurrentDictionary <string, string>();
                                payload[Key.RewardPayoutId.ToString()]        = ((Guid)Context[Key.RewardPayoutId]).ToString();
                                payload[Key.PartnerCardId.ToString()]         = (string)Context[Key.PartnerCardId];
                                payload[Key.PartnerRedeemedDealId.ToString()] = redemptionInfo.PartnerRedeemedDealId;

                                IScheduler scheduler = PartnerFactory.Scheduler(CommerceWorkerConfig.Instance.SchedulerQueueName,
                                                                                CommerceWorkerConfig.Instance.SchedulerTableName,
                                                                                CommerceWorkerConfig.Instance);
                                ScheduledJobDetails scheduledJobDetails = new ScheduledJobDetails
                                {
                                    JobId          = Guid.NewGuid(),
                                    JobType        = ScheduledJobType.ApplyRedemptionReward,
                                    JobDescription = redemptionInfo.GlobalUserId.ToString(),
                                    Orchestrated   = true,
                                    Payload        = payload
                                };

                                await scheduler.ScheduleJobAsync(scheduledJobDetails).ConfigureAwait(false);
                            }
                        }

                        // Then add a referred redemption reward to the user who referred the redeeming user.
                        Context[Key.RedeemedDealId] = ((RedeemedDeal)Context[Key.RedeemedDeal]).Id;
                        Context[Key.GlobalUserId]   = ((RedeemedDealInfo)Context[Key.RedeemedDealInfo]).GlobalUserId;
                        WorkerActions.RewardReferredRedemption(RewardOperations, Context);

                        // Update analytics.
                        // For FDC this happens at AUTH time
                        // Butfor Amex flow, we put analytics at the time of Transaction File Processing
                        SharedUserLogic sharedUserLogic = new SharedUserLogic(Context,
                                                                              CommerceOperationsFactory.UserOperations(Context));
                        Context[Key.GlobalUserId] = redemptionInfo.GlobalUserId;
                        User user = sharedUserLogic.RetrieveUser();
                        Analytics.AddRedemptionEvent(redemptionInfo.GlobalUserId, redeemedDeal.AnalyticsEventId, user.AnalyticsEventId,
                                                     redemptionInfo.ParentDealId, redemptionInfo.Currency,
                                                     redeemedDeal.AuthorizationAmount, redemptionInfo.DiscountAmount,
                                                     redemptionInfo.GlobalId, (string)Context[Key.PartnerMerchantId],
                                                     CommerceWorkerConfig.Instance);
                    }
                }
            }
        }