public ListingOffers(string asin, DateTime publishDateTime, IEnumerable <Offer> offers, ListingOffersSource listingOffersSource)
        {
            m_asin = asin;

            m_publishDateTime = publishDateTime;

            m_offers = offers.ToList();

            m_listingOffersSource = listingOffersSource;
        }
        private static UpdatedItemPrice CalculateNewPriceFromOffers(string sku, string asin, List <Offer> offers, DateTime publishTime, decimal minPrice, ListingOffersSource listingOffersSource)
        {
            Offer myOffer           = offers.FirstOrDefault(x => x.SellerType == SellerType.JBShop);
            Offer amazonOffer       = offers.FirstOrDefault(x => x.SellerType == SellerType.Amazon);
            Offer lowestNonFbaOffer = offers.Where(x => x.SellerType == SellerType.Other && !x.IsFba).OrderBy(x => x.LandedPrice).FirstOrDefault();
            Offer lowestFbaOffer    = offers.Where(x => x.SellerType == SellerType.Other && x.IsFba).OrderBy(x => x.LandedPrice).FirstOrDefault();

            decimal?competeWithAmazon           = CompeteWithAmazon(amazonOffer);
            decimal?competeWithOtherFbaMerchant = CompeteWithFbaMerchant(lowestFbaOffer, minPrice);

            decimal?competeWithAllFbaSellers = ReturnMinNullableDecimal(new List <decimal?> {
                competeWithAmazon, competeWithOtherFbaMerchant
            });
            decimal?competeWithNonFbaSellers = CompeteWithNonFbaMerchant(lowestNonFbaOffer);

            decimal?newPrice;

            if (competeWithAllFbaSellers.HasValue && competeWithNonFbaSellers.HasValue)
            {
                // We are competing against fba and non-fba sellers
                decimal fbaMargin    = CalculateProfitMarginFromSellingPrice(competeWithAllFbaSellers.Value, minPrice);
                decimal nonFbaMargin = CalculateProfitMarginFromSellingPrice(competeWithNonFbaSellers.Value, minPrice);

                if (nonFbaMargin < c_minMargin && fbaMargin > c_lowerMargin)                 // lets compete against the fba seller - the non-fba seller is too low for us and we are happy with the margin that the fba seller is at.
                {
                    newPrice = CalculateNewPriceAgainstFbaSeller(competeWithAllFbaSellers.Value, minPrice);
                }
                else if (competeWithAllFbaSellers.Value < competeWithNonFbaSellers.Value)                 // lets compete against the fba sellers, since they are more competitive
                {
                    newPrice = CalculateNewPriceAgainstFbaSeller(competeWithAllFbaSellers.Value, minPrice);
                }
                else                 // lets compete with the non-fba sellers, since they are more competitive
                {
                    newPrice = CalculateNewPriceAgainstNonFbaSeller(competeWithNonFbaSellers.Value, minPrice);
                }
            }
            else if (competeWithAllFbaSellers.HasValue)
            {
                // We are competing against just fba sellers
                newPrice = CalculateNewPriceAgainstFbaSeller(competeWithAllFbaSellers.Value, minPrice);
            }
            else if (competeWithNonFbaSellers.HasValue)
            {
                // We are competing against just non-fba sellers
                newPrice = CalculateNewPriceAgainstNonFbaSeller(competeWithNonFbaSellers.Value, minPrice);
            }
            else
            {
                // We are competing against nobody
                newPrice = CalculateSellingPriceFromProfitMargin(c_higherMargin, minPrice);
            }

            // There is no need to send a new price out if it matches our offer.
            if (myOffer != null && newPrice.HasValue && ArePricesTheSameWithinThreshold(myOffer.LandedPrice, newPrice.Value))
            {
                return(null);
            }

            if (newPrice.HasValue)
            {
                newPrice = decimal.Round(newPrice.Value, 2);
            }

            decimal?myOfferPrice           = myOffer != null ? myOffer.LandedPrice : (decimal?)null;
            decimal?amazonOfferPrice       = amazonOffer != null ? amazonOffer.LandedPrice : (decimal?)null;
            decimal?lowestNonFbaOfferPrice = lowestNonFbaOffer != null ? lowestNonFbaOffer.LandedPrice : (decimal?)null;
            decimal?lowestFbaOfferPrice    = lowestFbaOffer != null ? lowestFbaOffer.LandedPrice : (decimal?)null;

            if (newPrice.HasValue)
            {
                return(new UpdatedItemPrice(sku, newPrice.Value, asin, minPrice, myOfferPrice, amazonOfferPrice, lowestFbaOfferPrice, lowestNonFbaOfferPrice, publishTime, null, listingOffersSource.ToString()));
            }

            return(null);
        }