public HttpResponseMessage Register(V3DealDataContract dealDataContract)
        {
            Stopwatch callTimer = Stopwatch.StartNew();

            HttpResponseMessage result;

            // Build a context object to pass down the pipeline.
            CommerceContext context = CommerceContext.BuildSynchronousRestContext("Register offer", Request,
                                                                                  new V3RegisterDealResponse(), callTimer);

            try
            {
                context.Log.Information("Processing {0} call.", context.ApiCallDescription);
                CustomIdentity clientIdentity = (CustomIdentity)Thread.CurrentPrincipal.Identity;
                context.Log.Verbose("Presented client certificate has subject \"{0}\" and thumbprint \"{1}\".",
                                    clientIdentity.Name, clientIdentity.PresentedClientToken);
                context[Key.DealDataContract] = dealDataContract;
                context.Log.Verbose("{0} request:\r\n{1}", context.ApiCallDescription, General.SerializeJson(dealDataContract));

                // Create an executor object to execute the API invocation.
                V3ServiceRegisterDealExecutor registerDealExecutor = new V3ServiceRegisterDealExecutor(context);
                registerDealExecutor.Execute();

                // Build the response from the result of API invocation.
                result = RestResponder.BuildSynchronousResponse(context);
            }
            catch (Exception ex)
            {
                result = RestResponder.BuildSynchronousResponse(context, ex);
            }

            return(result);
        }
        public V3DealDataContract BuildDealDataContractV3(Offer offer, Provider provider, IEnumerable <Merchant> merchants, int currentIndex, int maxMerchantsPerBatch, List <Merchant> lstMerchantsToUpdate)
        {
            int index            = 0;
            var dealDataContract = new V3DealDataContract
            {
                Id           = Guid.Parse(offer.Id),
                ProviderId   = provider.Id,
                ProviderName = provider.Name,
                IsNational   = provider.IsNational
            };
            var discountList = new List <V3DiscountDataContract>();

            Log.Info($"Creating {nameof(V3DiscountDataContract)} for Offer : {dealDataContract.Id}, Provider : {provider.Name}");
            if (provider.IsNational)
            {
                Dictionary <string, List <string> > partnerMerchantIds = new Dictionary <string, List <string> >();
                var discount = GetDiscountDataContract(offer, provider, null);
                while (currentIndex < merchants.Count() && index < maxMerchantsPerBatch)
                {
                    Merchant merchant = merchants.ElementAt(currentIndex);
                    if (merchant.Payments != null && merchant.Payments.Any())
                    {
                        Log.Info($"Getting Partner Mids for Provider {provider.Name}, Merchant {merchant.Name}");
                        foreach (var partnerMerchantId in GetPartnermerchantIds(merchant))
                        {
                            if (!partnerMerchantIds.ContainsKey(partnerMerchantId.Key))
                            {
                                partnerMerchantIds.Add(partnerMerchantId.Key, partnerMerchantId.Value);
                            }
                            else
                            {
                                partnerMerchantIds[partnerMerchantId.Key].AddRange(partnerMerchantId.Value);
                            }
                        }
                        lstMerchantsToUpdate.Add(merchant);
                    }
                    else
                    {
                        Log.Warn($"Payments info is missing for Merchant Id {merchant.Id} in provider {provider.Name}");
                    }
                    currentIndex++;
                    index++;
                }

                discount.PartnerMerchantIds = partnerMerchantIds.Select(kvp => new DiscountPartnerMerchantIds
                {
                    Partner     = kvp.Key,
                    MerchantIds = kvp.Value
                }).ToList();
                discountList.Add(discount);
            }
            else
            {
                while (currentIndex < merchants.Count() && index <= maxMerchantsPerBatch)
                {
                    Merchant merchant = merchants.ElementAt(currentIndex);
                    var      discount = GetDiscountDataContract(offer, provider, merchant);
                    Log.Info($"Getting Partner Mids for Provider {provider.Name}, Merchant {merchant.Name}");
                    discount.PartnerMerchantIds = GetPartnermerchantIds(merchant).Select(kvp => new DiscountPartnerMerchantIds
                    {
                        Partner     = kvp.Key,
                        MerchantIds = kvp.Value
                    }).ToList();
                    discountList.Add(discount);
                    currentIndex++;
                    lstMerchantsToUpdate.Add(merchant);
                }
            }

            dealDataContract.Discounts = discountList;

            return(dealDataContract);
        }
        private async Task <bool> RegisterOfferWithCommerceAsync(V3DealDataContract dealDataContract)
        {
            bool   bSuccess = false;
            string offerId  = dealDataContract.Id.ToString();

            Log.Info($"Calling commerce to register offer {offerId}");
            string commercePayload = JsonConvert.SerializeObject(dealDataContract);

            int  retryCount = 0;
            bool retry      = true;

            while (retry)
            {
                try
                {
                    var commerceResponse = await Task.Run(() => this.commerceService.RegisterOffer(commercePayload)).ConfigureAwait(false);

                    if (commerceResponse != null)
                    {
                        retry = false;
                        if (commerceResponse.ResultSummary != null && (commerceResponse.ResultSummary.ResultCode == "Created" ||
                                                                       commerceResponse.ResultSummary.ResultCode == "Success"))
                        {
                            bSuccess = true;
                            Log.Info(
                                $"Successfully registered offer {dealDataContract.Id.ToString()} for provider {dealDataContract.ProviderId}, {dealDataContract.ProviderName} with commerce");
                        }
                    }
                }
                catch (CryptographicException)
                {
                    Log.Error($"Error in registering offer with commerce.Unable to find commerce certificate.");
                    retry = false;
                }
                catch (WebException ex)
                {
                    Log.Error($"Unable to register the offer with commerce");
                    var response = (HttpWebResponse)ex.Response;
                    if (response != null)
                    {
                        CommerceResponse commerceResponse = ExtractCommerceResponse(response);
                        if (commerceResponse != null)
                        {
                            Log.Error($"Error is {commerceResponse.ResultSummary.ResultCode} ; {commerceResponse.ResultSummary.Explanation}");
                            retry = false;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error($"Unable to register the offer with commerce; {ex.Message}");
                }

                if (retry)
                {
                    retryCount++;
                    if (retryCount < 3)
                    {
                        int delayInterval = retryCount * 50;
                        Log.Info($"Register offer with commerce failed...Call will be retried after a delay of {delayInterval} ms");
                        await Task.Delay(delayInterval);
                    }
                    else
                    {
                        retry = false;
                    }
                }
            }

            return(bSuccess);
        }