private void CalculateAndSendNewPrice()
        {
            IReadOnlyCollection <RepricingInformation> repricingInformations = RepricingInformationCache.Instance.RepricingInformations;

            List <RepricingInformation> inStockRepricingInformations = repricingInformations
                                                                       .Where(x => InventorySupplyCache.Instance.InStockSupplyQuantity(x.SKU) > 0)
                                                                       .ToList();

            List <RepricingInformation> inStockRepricingInformationsWithoutListingOffers = inStockRepricingInformations
                                                                                           .Where(x => !ListingOffersCache.Instance.HasListingOffersForAsin(x.ASIN))
                                                                                           .ToList();

            Dictionary <string, decimal> myPricesForInStockItemsWithoutListingOffers = GetMyPrices(inStockRepricingInformationsWithoutListingOffers.Select(x => x.SKU));

            List <UpdatedItemPrice> newPrices = new List <UpdatedItemPrice>();

            foreach (RepricingInformation repricingInfo in inStockRepricingInformations)
            {
                string asin = repricingInfo.ASIN;
                string sku  = repricingInfo.SKU;

                ListingOffers listingOffers = ListingOffersCache.Instance.GetListingOffers(asin);

                decimal?myPrice = null;

                if (myPricesForInStockItemsWithoutListingOffers.ContainsKey(sku))
                {
                    myPrice = myPricesForInStockItemsWithoutListingOffers[sku];
                }

                UpdatedItemPrice updatedItemPrice = CalculatePrice.CalculateNewPrice(sku, asin, repricingInfo, listingOffers, myPrice);
                if (updatedItemPrice != null)                 // If we can't set a price, this object will be null.
                {
                    decimal newPrice  = updatedItemPrice.UpdatedPrice;
                    decimal?lastPrice = PriceHistoryCache.Instance.GetLastPrice(asin);

                    if ((newPrice > repricingInfo.MinimumPrice) && (newPrice > 4.00m) &&              //// This new price has to be greater than our minimum price and greater than $4.00
                        (!lastPrice.HasValue || lastPrice.Value != newPrice))                         //// This new price has to be not equal to our last updated price.
                    {
                        newPrices.Add(updatedItemPrice);
                    }
                }
            }

            UploadNewPrices(newPrices);
        }
        public void CacheListingOffers(ListingOffers newListingOffers)
        {
            if (newListingOffers == null || newListingOffers.Asin == null)
            {
                return;
            }

            ListingOffersLogger.Instance.SubmitListingOffers(newListingOffers);

            m_listingOffers.AddOrUpdate(
                newListingOffers.Asin,
                newListingOffers,
                (key, existingListingOffers) =>
                // Choose the newer ListingOffers
                (newListingOffers.PublishDateTime > existingListingOffers.PublishDateTime)
                // OR, replace the existing ListingOffers if the new ListingOffers originates from the SubscriptionService.
                || (newListingOffers.ListingOffersSource == ListingOffersSource.SubscriptionService && existingListingOffers.ListingOffersSource == ListingOffersSource.MwsProducts)
                                        ? newListingOffers
                                        : existingListingOffers);
        }
        private static ListingOffersLog MapToListingOffersLog(ListingOffers listingOffers)
        {
            ListingOffersLog listingOffersLog = new ListingOffersLog
            {
                ASIN                = listingOffers.Asin,
                PublishDateTime     = listingOffers.PublishDateTime,
                ListingOffersSource = listingOffers.ListingOffersSource.ToString(),
            };

            Offer ourOffer = listingOffers.Offers.FirstOrDefault(w => w.SellerType == SellerType.JBShop);

            if (ourOffer != null)
            {
                listingOffersLog.OurPrice = ourOffer.LandedPrice;
            }

            Offer lowestFbaOffer = listingOffers.Offers.Where(w => w.IsFba && w.SellerType != SellerType.JBShop).OrderBy(o => o.LandedPrice).FirstOrDefault();

            if (lowestFbaOffer != null)
            {
                listingOffersLog.LowestFbaPrice = lowestFbaOffer.LandedPrice;
            }

            Offer lowestNonFbaOffer = listingOffers.Offers.Where(w => !w.IsFba && w.SellerType != SellerType.JBShop).OrderBy(o => o.LandedPrice).FirstOrDefault();

            if (lowestNonFbaOffer != null)
            {
                listingOffersLog.LowestNonFbaPrice = lowestNonFbaOffer.LandedPrice;
            }

            Offer buyBoxOffer = listingOffers.Offers.FirstOrDefault(w => w.IsBuyBoxWinner.HasValue && w.IsBuyBoxWinner.Value);

            if (buyBoxOffer != null)
            {
                listingOffersLog.BuyBoxPrice            = buyBoxOffer.LandedPrice;
                listingOffersLog.BuyBoxWinnerSellerType = (int)buyBoxOffer.SellerType;
            }

            return(listingOffersLog);
        }
        public static UpdatedItemPrice CalculateNewPrice(string sku, string asin, RepricingInformation repricingInfo, ListingOffers listingOffers, decimal?myPrice)
        {
            UpdatedItemPrice updatedItemPrice = null;

            decimal minPrice = repricingInfo.MinimumPrice;

            if (listingOffers == null && myPrice.HasValue)
            {
                decimal newPrice = (myPrice.Value > minPrice) ? myPrice.Value + 0.01m : minPrice * 1.15m;

                newPrice = decimal.Round(newPrice, 2);

                updatedItemPrice = new UpdatedItemPrice(sku, newPrice, asin, minPrice, null, null, null, null, null, myPrice, null);
            }
            else if (listingOffers != null)
            {
                updatedItemPrice = CalculateNewPriceFromOffers(sku, asin, listingOffers.Offers, listingOffers.PublishDateTime, minPrice, listingOffers.ListingOffersSource);
            }

            return(updatedItemPrice);
        }
 public void SubmitListingOffers(ListingOffers listingOffers)
 {
     s_listingOffersLog.Add(MapToListingOffersLog(listingOffers));
 }