/// <summary>
        /// Main function, gets a Part/Inventory/Price model for a particular part number/colour/type/condition combination. If it doesn't exist, gets it from the api and creates it.
        /// </summary>
        /// <param name="number">Part Number</param>
        /// <param name="colourId">Colour Id</param>
        /// <param name="type">Type - PART, MINIFIG, etc.</param>
        /// <param name="condition">Condition - N, U, A. A = any, prefers new and falls back to used</param>
        /// <param name="updateInv">Forces an update of the inventory item from the API. By default, it updates once a day</param>
        /// <param name="updatePrice">Forces an update of the price from the API. By default, it updates once every 14 days</param>
        /// <param name="updatePart">Forces an update of the part from the API. By default, it updates once every 14 days</param>
        /// <param name="updateInvDate">Forces an update of the inventory item if it's older than this</param>
        /// <returns>A model with an attached Part, PartInventory, PartPriceInfo</returns>
        public PartModel GetPartModel(string number, int colourId, string type, string condition = "N",
                                      bool updateInv         = false, bool updatePrice  = false, bool updatePart = false,
                                      DateTime?updateInvDate = null, string description = "")
        {
            bool   placeholder = false;
            string cond        = condition == "A" ? "N" : condition;
            var    partInv     = _partInventoryRepo.FindOne(x =>
                                                            x.Part.ItemType == type &&
                                                            x.Part.Number == number &&
                                                            x.ColourId == colourId &&
                                                            x.Condition == cond &&
                                                            x.Description == description);

            if (partInv != null)
            {
                return(UpdatedPartModel(partInv, updateInv, updatePrice, updatePart, updateInvDate));
            }

            // No part inventory - create it
            var part = GetPart(number, type);

            // Attempt to get the part from the API
            partInv = _api.UpdateInventoryFromApi(type, part.CategoryId, colourId, number, condition == "A" ? "N" : condition, description: description);

            if (partInv == null)
            {
                partInv     = PlaceHolderInventory(colourId, condition == "A" ? "N" : condition, description, type, number);
                placeholder = true;
            }

            // Quantity is 0, fall back to used if condition is set to any
            if (partInv.Quantity == 0 && condition == "A")
            {
                var usedPart = _api.UpdateInventoryFromApi(type, part.CategoryId, colourId, number, "U", description: description);
                if (usedPart.Quantity > 0)
                {
                    partInv = usedPart;
                }
            }

            if (partInv.ColourId != 0)
            {
                // Lookup colour
                partInv.ColourName = _api.GetColour(partInv.ColourId).Name;
            }

            partInv.Notes = "Added from part/colour";

            var pricing = _api.UpdatePartPricingFromApi(number, type, colourId, partInv.Condition);

            _partInventoryRepo.AddPartInv(ref partInv, ref pricing, ref part);

            return(new PartModel
            {
                Part = part,
                PartInventory = partInv,
                PartPriceInfo = pricing,
                InvIsPlaceHolder = placeholder
            });
        }
        public PricingModel GetItemsByThreshold(decimal threshold, int page, int perPage)
        {
            var items = PartsOverThreshold(threshold)
                        .OrderBy(x => x.InventoryId)
                        .Skip((page - 1) * perPage)
                        .Take(perPage)
                        .ToList()
                        .Select(x => new PricingItemModel
            {
                MyPrice          = x.MyPrice,
                AveragePrice     = x.Pricing.AveragePrice,
                Name             = WebUtility.HtmlDecode(x.Part.Name),
                Number           = x.Part.Number,
                ColourName       = x.ColourName,
                Colour           = _apiService.GetColour(x.ColourId),
                Location         = x.Location,
                PriceLastUpdated = x.Pricing.LastUpdated,
                InvLastUpdated   = x.LastUpdated,
                Image            = x.Image,
                ItemType         = x.Part.ItemType,
                Category         = x.Part.CategoryId,
                Quantity         = x.Quantity,
                InventoryId      = x.InventoryId
            })
                        .ToList();

            var pagination = new PaginationModel(PartsOverThreshold(threshold).Count(), page, perPage);

            return(new PricingModel
            {
                Items = items,
                Pagination = pagination
            });
        }