/// <summary> /// Find the best price given the price break /// </summary> /// <param name="offer">The offer to search within</param> /// <param name="currency">The 3 character currency code</param> /// <param name="qty">The quantity to search for (i.e. QTY required)</param> /// <returns>The minimum price available for the specified QTY</returns> public static double MinPrice(this ApiV4Schema.PartOffer offer, string currency, int qty) { // Force format optional arguments if (currency == string.Empty) { currency = "USD"; } if (qty == 0) { qty = 1; } double minprice = double.MaxValue; try { string minpricestr = ApiV4.OffersMinPrice(currency, offer, qty, true); if (!string.IsNullOrEmpty(minpricestr)) { minprice = Convert.ToDouble(minpricestr, CultureInfo.CurrentCulture); } } catch (FormatException) { /* Do nothing */ } catch (OverflowException) { /* Do nothing */ } return(minprice); }
/// <summary> /// Begins a web request and waits for the response. /// </summary> /// <remarks> /// When the data is received it is checked for errors. Only successful responses are then marked as 'Done' in the cache. /// </remarks> private void ProcessQuery() { List <CacheItem> tempList; lock (_queryList) { _queryTimer.Enabled = false; tempList = _queryList.Where(i => i.State == CacheItem.ProcessingState.Await).ToList(); tempList.ForEach(i => i.State = CacheItem.ProcessingState.Processing); } if (tempList.Count == 0) { Log.Debug("No parts to search"); return; } Log.Debug(string.Format("Performing search of {0} items", tempList.Count)); ApiV4.SearchResponse resp = ApiV4.PartsMatch(tempList.Select(i => i.Query).ToList(), ApiKey, HttpTimeout); // If proper data wasn't provided, quit if (resp == null) { Log.Error("Response error: resp == null"); tempList.ForEach(i => { i.State = CacheItem.ProcessingState.Error; i.Error = FATAL_ERROR + " (Response is null)"; }); return; } if (!string.IsNullOrEmpty(resp.ErrorMessage)) { Log.Debug("Response error:" + resp.ErrorMessage); tempList.ForEach(i => { i.State = CacheItem.ProcessingState.Error; i.Error = resp.ErrorMessage; }); return; } if (!(resp.Data is ApiV4Schema.PartsMatchResponse)) { Log.Error("Response error: resp != PartsMatchResponse"); tempList.ForEach(i => { i.State = CacheItem.ProcessingState.Error; i.Error = FATAL_ERROR + " (response is not of correct type)"; }); return; } var data = (ApiV4Schema.PartsMatchResponse)resp.Data; if ((data == null) || (data.results == null)) { Log.Error("Response error: data == null || data.results == null"); tempList.ForEach(i => { i.State = CacheItem.ProcessingState.Error; i.Error = FATAL_ERROR + " (data is not of correct type)"; }); return; } if (data.results.Count == 0) { Log.Error("Response error: data.results.count == 0"); tempList.ForEach(i => { i.State = CacheItem.ProcessingState.Error; i.Error = FATAL_ERROR + " (data does not have result)"; }); return; } // Acceptable data has been received; Include it in the cache for (int i = 0; i < data.request.queries.Count; i++) { string key = data.request.queries[i].mpn ?? string.Empty; if (!string.IsNullOrEmpty(data.results[i].error)) { Log.Debug("Repsonse Error: " + data.results[i].error); _queryList.First(item => item.Q == key).State = CacheItem.ProcessingState.Error; _queryList.First(item => item.Q == key).Error = data.results[i].error; } else if (data.results[i].items == null) { Log.Debug("data.results[i].items is null!"); _queryList.First(item => item.Q == key).State = CacheItem.ProcessingState.Error; _queryList.First(item => item.Q == key).Error = "Query did not provide an adequate response"; } else { CacheItem querypart = _queryList.First(item => item.Q == key); querypart.Parts.AddRange(data.results[i].items); querypart.Hits = data.results[i].hits; if (data.results[i].items.Count == 0) { querypart.Error = "Query did not provide a result. Please widen your search criteria."; } querypart.State = CacheItem.ProcessingState.Done; } } }