private static async Task NotWalmartAsync(UserSettingsView settings, Listing listing, List <string> notWalmartList, string token, int daysBack, List <string> response) { try { notWalmartList.Add(listing.ListingTitle); notWalmartList.Add(listing.SupplierItem.ItemURL); notWalmartList.Add(string.Empty); int cnt = CountMsgID(listing.ID, 1100, daysBack); int total = CountMsgID(listing.ID, 0, daysBack); notWalmartList.Add(string.Format("Not Walmart: {0}/{1}", cnt, total)); notWalmartList.Add(string.Empty); if (listing.Qty > 0) { listing.Qty = 0; await _repository.ListingSaveAsync(settings, listing, false, "Qty"); response = Utility.eBayItem.ReviseItem(token, listing.ListedItemID, qty: 0); } var log = new ListingLog { ListingID = listing.ID, MsgID = 1100, UserID = settings.UserID }; await _repository.ListingLogAdd(log); } catch (Exception exc) { string msg = dsutil.DSUtil.ErrMsg("NotWalmartAsync", exc); dsutil.DSUtil.WriteFile(_logfile, msg, settings.UserName); throw; } }
private static async Task ParseArrivalDateAsync(UserSettingsView settings, Listing listing, List <string> parseArrivalDateList, string token, int daysBack, List <string> response, ISupplierItem wmItem) { try { parseArrivalDateList.Add(listing.ListingTitle); parseArrivalDateList.Add(listing.SupplierItem.ItemURL); parseArrivalDateList.Add(string.Format("Code: {0}", wmItem.ArrivalDateFlag)); parseArrivalDateList.Add(string.Empty); int cnt = CountMsgID(listing.ID, 1000, daysBack); int total = CountMsgID(listing.ID, 0, daysBack); parseArrivalDateList.Add(string.Format("Parse arrival date: {0}/{1}", cnt, total)); parseArrivalDateList.Add(string.Empty); var log = new ListingLog { ListingID = listing.ID, MsgID = 1000, UserID = settings.UserID }; await _repository.ListingLogAdd(log); } catch (Exception exc) { string msg = dsutil.DSUtil.ErrMsg("ParseArrivalDateAsync", exc); dsutil.DSUtil.WriteFile(_logfile, msg, settings.UserName); throw; } }
private static async Task OutOfStockBadArrivalDateAsync(UserSettingsView settings, Listing listing, List <string> outofStockBadArrivalList, string token, int daysBack, List <string> response) { try { outofStockBadArrivalList.Add(listing.ListingTitle); outofStockBadArrivalList.Add(listing.SupplierItem.ItemURL); outofStockBadArrivalList.Add(string.Empty); if (listing.Qty > 0) { listing.Qty = 0; await _repository.ListingSaveAsync(settings, listing, false, "Qty"); response = Utility.eBayItem.ReviseItem(token, listing.ListedItemID, qty: 0); } var log = new ListingLog { ListingID = listing.ID, MsgID = 200, UserID = settings.UserID }; await _repository.ListingLogAdd(log); } catch (Exception exc) { string msg = dsutil.DSUtil.ErrMsg("OutOfStockBadArrivalDateAsync", exc); dsutil.DSUtil.WriteFile(_logfile, msg, settings.UserName); throw; } }
private static async Task SupplierPriceChange( UserSettingsView settings, Listing listing, List <string> priceChangeList, ISupplierItem wmItem, decimal wmShipping, decimal wmFreeShippingMin, string token, double eBayPct, List <string> response) { string body = null; priceChangeList.Add(listing.ListingTitle); var str = listing.ListedItemID + " db supplier price " + listing.SupplierItem.SupplierPrice.Value.ToString("c") + " different from just captured " + wmItem.SupplierPrice.Value.ToString("c"); string note = "db supplier price " + listing.SupplierItem.SupplierPrice.Value.ToString("c") + " different from just captured " + wmItem.SupplierPrice.Value.ToString("c"); priceChangeList.Add(str); Console.WriteLine("Price change."); if (wmItem.SupplierPrice < listing.SupplierItem.SupplierPrice) { str = "Supplier dropped their price."; note += " " + str; priceChangeList.Add(str); priceChangeList.Add(listing.SupplierItem.ItemURL); } else { str = "Supplier INCREASED their price!"; note += " " + str; priceChangeList.Add(str); priceChangeList.Add(listing.SupplierItem.ItemURL); } dsutil.DSUtil.WriteFile(_logfile, body, log_username); var priceProfit = wallib.wmUtility.wmNewPrice(wmItem.SupplierPrice.Value, listing.PctProfit, wmShipping, wmFreeShippingMin, eBayPct); decimal newPrice = priceProfit.ProposePrice; priceChangeList.Add(string.Format("New price: {0:c}", newPrice)); note += string.Format(" New price: {0:c}", newPrice); priceChangeList.Add(string.Empty); response = Utility.eBayItem.ReviseItem(token, listing.ListedItemID, price: (double)newPrice); await _repository.UpdatePrice(listing, (decimal)newPrice, wmItem.SupplierPrice.Value); var log = new ListingLog { ListingID = listing.ID, MsgID = 700, Note = note, UserID = settings.UserID }; await _repository.ListingLogAdd(log); }
private static async Task PutBackInStock(UserSettingsView settings, Listing listing, List <string> putBackInStockList, string token, List <string> response, ISupplierItem wmItem, decimal wmShipping, decimal wmFreeShippingMin, double eBayPct, int newListedQty, string output) { try { putBackInStockList.Add(listing.ListingTitle); putBackInStockList.Add(listing.SupplierItem.ItemURL); putBackInStockList.Add(string.Empty); var priceProfit = wallib.wmUtility.wmNewPrice(wmItem.SupplierPrice.Value, listing.PctProfit, wmShipping, wmFreeShippingMin, eBayPct); decimal newPrice = priceProfit.ProposePrice; output += string.Format(" Price: {0:0.00} ", newPrice); listing.ListingPrice = newPrice; response = Utility.eBayItem.ReviseItem(token, listing.ListedItemID, price: (double)newPrice, qty: newListedQty); if (response.Count > 0) { output += dsutil.DSUtil.ListToDelimited(response, ';'); } var log = new ListingLog { ListingID = listing.ID, MsgID = 600, UserID = settings.UserID, Note = output }; await _repository.ListingLogAdd(log); listing.Qty = newListedQty; await _repository.ListingSaveAsync(settings, listing, false, "Qty", "ListingPrice"); } catch (Exception exc) { string msg = dsutil.DSUtil.ErrMsg("PutBackInStock", exc); dsutil.DSUtil.WriteFile(_logfile, msg, settings.UserName); throw; } }
private static async Task DeliveryTooLongAsync(UserSettingsView settings, Listing listing, List <string> deliveryTooLongList, string token, int daysBack, List <string> response, int days, int allowedDeliveryDays) { try { deliveryTooLongList.Add(listing.ListingTitle); deliveryTooLongList.Add(listing.SupplierItem.ItemURL); deliveryTooLongList.Add(string.Format("{0} business days, over by {1} day(s)", days, days - allowedDeliveryDays)); var note = string.Format("{0} days", days); deliveryTooLongList.Add(string.Format("Qty was {0}", listing.Qty)); note += string.Format(" (Qty was {0})", listing.Qty); deliveryTooLongList.Add(string.Empty); int cnt = CountMsgID(listing.ID, 100, daysBack); int total = CountMsgID(listing.ID, 0, daysBack); deliveryTooLongList.Add(string.Format("Delivery too long: {0}/{1}", cnt, total)); deliveryTooLongList.Add(string.Empty); note += string.Format(" (Qty was {0})", listing.Qty); var log = new ListingLog { ListingID = listing.ID, MsgID = 100, Note = note, UserID = settings.UserID }; await _repository.ListingLogAdd(log); if (listing.Qty > 0) { listing.Qty = 0; await _repository.ListingSaveAsync(settings, listing, false, "Qty"); response = Utility.eBayItem.ReviseItem(token, listing.ListedItemID, qty: 0); } } catch (Exception exc) { string msg = dsutil.DSUtil.ErrMsg("DeliveryTooLongAsync", exc); dsutil.DSUtil.WriteFile(_logfile, msg, settings.UserName); throw; } }
/// <summary> /// Main driver to scan listings for issues. /// </summary> /// <param name="settings"></param> /// <param name="sourceID"></param> /// <param name="pctProfit"></param> /// <param name="wmShipping"></param> /// <param name="wmFreeShippingMin"></param> /// <param name="eBayPct"></param> /// <param name="imgLimit"></param> /// <returns></returns> public static async Task <int> ScanItems(UserSettingsView settings, int sourceID, decimal wmShipping, decimal wmFreeShippingMin, double eBayPct, int imgLimit, int allowedDeliveryDays, int daysBack, byte forceSendEmail) { int i = 0; int outofstock = 0; int outofstockBadArrivalDate = 0; int invalidURL = 0; int shippingNotAvailable = 0; int mispriceings = 0; int numErrors = 0; int putBackInStock = 0; int notInStockLongEnough = 0; int deliveryTooLong = 0; int parseArrivalDate = 0; int notWalmart = 0; var response = new List <string>(); string body = null; int listingID = 0; var outofStockList = new List <string>(); var outofStockBadArrivalList = new List <string>(); var priceChangeList = new List <string>(); var shipNotAvailList = new List <string>(); var invalidURLList = new List <string>(); var errors = new List <string>(); var putBackInStockList = new List <string>(); var deliveryTooLongList = new List <string>(); var parseArrivalDateList = new List <string>(); var notWalmartList = new List <string>(); var notInStockLongEnoughList = new List <string>(); try { DateTime startTime, endTime; startTime = DateTime.Now; string token = _repository.GetToken(settings); var walListings = _repository.Context.Listings .Include(d => d.SupplierItem) .Where(x => x.SupplierItem.SourceID == sourceID && x.Listed != null && x.StoreID == settings.StoreID) .ToList(); foreach (Listing listing in walListings) { try { //Random random = new Random(); //int sec = random.Next(2); //Thread.Sleep(sec * 1000); Thread.Sleep(10000); listingID = listing.ID; //if (listing.SupplierItem.ItemURL != "https://www.walmart.com/ip/Classic-Sport-Premier-Cup-II-Foosball-Table-Brown-Official-Competition-Size/592871184") //{ // continue; //} var wmItem = await wallib.wmUtility.GetDetail(listing.SupplierItem.ItemURL, imgLimit, true); Console.WriteLine((++i) + " " + listing.ListingTitle); if (wmItem == null) // could not fetch from walmart website { ++invalidURL; await InvalidURLAsync(settings, listing, invalidURLList, token, daysBack, response); } else { if (wmItem.ArrivalDateFlag == 1 || wmItem.ArrivalDateFlag == 2) { ++parseArrivalDate; await ParseArrivalDateAsync(settings, listing, parseArrivalDateList, token, daysBack, response, wmItem); } if (!wmItem.SoldAndShippedBySupplier ?? false) { ++notWalmart; await NotWalmartAsync(settings, listing, notWalmartList, token, daysBack, response); } if (wmItem.ShippingNotAvailable) { ++shippingNotAvailable; await ShipNotAvailableAsync(settings, listing, shipNotAvailList, token, daysBack, response); } if (!wmItem.ShippingNotAvailable && wmItem.OutOfStock) { ++outofstock; await OutOfStockAsync(settings, listing, outofStockList, token, daysBack, response); } if (!wmItem.OutOfStock && !wmItem.ShippingNotAvailable && !wmItem.Arrives.HasValue) { ++outofstockBadArrivalDate; await OutOfStockBadArrivalDateAsync(settings, listing, outofStockBadArrivalList, token, daysBack, response); } bool lateDelivery = false; if (wmItem.Arrives.HasValue) { int days = dsutil.DSUtil.GetBusinessDays(DateTime.Now, wmItem.Arrives.Value); if (days > allowedDeliveryDays) { lateDelivery = true; ++deliveryTooLong; await DeliveryTooLongAsync(settings, listing, deliveryTooLongList, token, daysBack, response, days, allowedDeliveryDays); } } // PUT BACK IN STOCK if (listing.Qty == 0 && !listing.InActive && wmItem.Arrives.HasValue && !wmItem.OutOfStock && !wmItem.ShippingNotAvailable && !lateDelivery && (wmItem.SoldAndShippedBySupplier ?? false)) { string msg = null; bool inStockLongEnough = InStockLongEnough(listing.ID, 1, out msg); string output = msg + " "; if (inStockLongEnough) { Console.WriteLine("Put back in stock."); int newListedQty = 1; ++putBackInStock; await PutBackInStock(settings, listing, putBackInStockList, token, response, wmItem, wmShipping, wmFreeShippingMin, eBayPct, newListedQty, output); } else { ++notInStockLongEnough; notInStockLongEnoughList.Add(listing.ListingTitle); notInStockLongEnoughList.Add(listing.SupplierItem.ItemURL); notInStockLongEnoughList.Add(string.Empty); var log = new ListingLog { ListingID = listing.ID, MsgID = 1200, UserID = settings.UserID, Note = output }; await _repository.ListingLogAdd(log); } } // inactive and might qualify to put back in stock if (listing.Qty == 0 && listing.InActive && wmItem.Arrives.HasValue && !wmItem.OutOfStock && !wmItem.ShippingNotAvailable && !lateDelivery && (wmItem.SoldAndShippedBySupplier ?? false)) { string msg = null; if (InStockLongEnough(listing.ID, 1, out msg)) { var log = new ListingLog { ListingID = listing.ID, MsgID = 1300, UserID = settings.UserID }; await _repository.ListingLogAdd(log); } else { var log = new ListingLog { ListingID = listing.ID, MsgID = 1400, UserID = settings.UserID }; await _repository.ListingLogAdd(log); } } // SUPPLIER PRICE CHANGE? if (listing.Qty > 0 && !wmItem.OutOfStock && !wmItem.ShippingNotAvailable && !lateDelivery && (wmItem.SoldAndShippedBySupplier ?? false)) { if (Math.Round(wmItem.SupplierPrice.Value, 2) != Math.Round(listing.SupplierItem.SupplierPrice.Value, 2)) { ++mispriceings; await SupplierPriceChange(settings, listing, priceChangeList, wmItem, wmShipping, wmFreeShippingMin, token, eBayPct, response); } } } } catch (Exception exc) { string msg = "ERROR IN LOOP -> " + listing.ListingTitle + " -> " + exc.Message; errors.Add(msg); dsutil.DSUtil.WriteFile(_logfile, msg, ""); ++numErrors; var log = new ListingLog { ListingID = listing.ID, MsgID = 10000, UserID = settings.UserID, Note = exc.Message }; await _repository.ListingLogAdd(log); if (listing.Qty > 0) { listing.Qty = 0; await _repository.ListingSaveAsync(settings, listing, false, "Qty"); try { response = Utility.eBayItem.ReviseItem(token, listing.ListedItemID, qty: 0); } catch { // Utility.eBayItem.ReviseItem() will log and throw its exception but we don't want to leave the for loop // so just swallow the error here } } } } // end for loop endTime = DateTime.Now; double elapsedMinutes = ((TimeSpan)(endTime - startTime)).TotalMinutes; var storeProfile = new StoreProfile { ID = settings.StoreID, RepricerLastRan = DateTime.Now, ElapsedTime = elapsedMinutes }; await _repository.StoreProfileUpdate(storeProfile, "RepricerLastRan", "ElapsedTime"); var elapsedMinutesList = new List <string>(); var elapsedTimeMsg = string.Format("Elapsed time: {0} minutes; Total scanned {1}", Math.Round(elapsedMinutes, 2), i); elapsedMinutesList.Add(elapsedTimeMsg); //SendAlertEmail(_toEmail, settings.StoreName + " ELAPSED TIME ", elapsedMinutesList); if (numErrors > 0) { SendAlertEmail(_toEmail, settings.StoreName + " TRACKER ERRORS ", errors); } var sendEmail = false; var rightNow = DateTime.Now; if ((rightNow.Hour >= 8 && rightNow.Hour < 9) || forceSendEmail == 1) { sendEmail = true; } if (sendEmail) { if (putBackInStock > 0) { SendAlertEmail(_toEmail, settings.StoreName + " RE-STOCK ", putBackInStockList); } if (notInStockLongEnough > 0) { SendAlertEmail(_toEmail, settings.StoreName + " NOT IN-STOCK LONG ENOUGH ", notInStockLongEnoughList); } if (mispriceings > 0) { SendAlertEmail(_toEmail, settings.StoreName + " PRICE CHANGE", priceChangeList); } if (outofstock > 0) { SendAlertEmail(_toEmail, settings.StoreName + " OUT OF STOCK - LABEL", outofStockList); } if (outofstockBadArrivalDate > 0) { SendAlertEmail(_toEmail, settings.StoreName + " OUT OF STOCK - Bad Arrival Date", outofStockBadArrivalList); } if (invalidURL > 0) { SendAlertEmail(_toEmail, settings.StoreName + " INVALID URL ", invalidURLList); } if (shippingNotAvailable > 0) { SendAlertEmail(_toEmail, settings.StoreName + " DELIVERY NOT AVAILABLE ", shipNotAvailList); } if (deliveryTooLong > 0) { SendAlertEmail(_toEmail, settings.StoreName + " DELIVERY TOO LONG ", deliveryTooLongList); } if (parseArrivalDate > 0) { SendAlertEmail(_toEmail, settings.StoreName + " PARSE ARRIVAL DATE - START SELENIUM ", parseArrivalDateList); } if (notWalmart > 0) { SendAlertEmail(_toEmail, settings.StoreName + " NOT SOLD & SHIPPED BY SUPPLIER ", notWalmartList); } if (mispriceings + outofstock + invalidURL + shippingNotAvailable + numErrors + putBackInStock == 0) { string ret = dsutil.DSUtil.SendMailDev(_toEmail, string.Format(settings.StoreName + "REPRICER - scanned {0} items", walListings.Count), "No issues found."); } } return(outofstock); } catch (Exception exc) { string msg = "listingID: " + listingID + " -> " + exc.Message; dsutil.DSUtil.WriteFile(_logfile, msg, ""); throw; } }