protected override string GetSalesMonth(DateTime exportDate, string filename) { //Note: This was originally written to work with both live API connections // and manually exported OrderHistory.xml, butAPI sections are now // commented out so it only works with manual exports. // The API version worked, but had to call the API too many times to get // all the orders (250 at a time) and then call again to get the details // for each order. This exceeded the API bandwidth limit for larger stores. var stopWatch = new StopWatch(true); //get daterange for this month and create query var beginDate = new DateTime(exportDate.Year, exportDate.Month, 1); var endDate = beginDate.AddMonths(1).AddDays(-1); //const string dateFormat = "ddd, dd MMM yyyy HH:mm:ss +0000"; //string query = string.Format("?min_date_created={0}&max_date_created={1}", // HttpUtility.UrlEncode(beginDate.ToString(dateFormat)), // HttpUtility.UrlEncode(endDate.ToString(dateFormat))); if (SalesHistory == null || !SalesHistory.Any()) return Environment.NewLine + "No orders in sales history"; int rows = SalesHistory.Count(); //get the order count for this month //var ordersXml = CallCartApi("orders/count" + query, "orders"); //var oCount = ordersXml.Elements("count").First().Value; var result = string.Format("{0}{1}: ", Environment.NewLine, filename); ProgressText += result; string tempDisplay = ProgressText; ProgressText += "Exporting..."; //int rows = Convert.ToInt16(rows); //int pages = (int)Math.Ceiling( (decimal)rows / (decimal)250 ); //can only get 250 products at a time int errors = 0; rows = 0; var orders = new List<SalesRecord>(); //for (int page = 1; page <= pages; page++) //{ // string paging = string.Format("&page={0}&limit=250", page); // ordersXml = CallCartApi("orders" + query + paging, "orders"); // if (ordersXml == null) break; //var orderElements = ordersXml.Elements("order"); //var orderElements = SalesHistory.Elements("order"); //if (orderElements != null) //{ // foreach (var o in orderElements) if (SalesHistory != null) { foreach (var o in SalesHistory) { IEnumerable<XElement> productsXml = null; string oCustomer = "", oDate = "", oId = ""; try { var dateVal = Client.GetValue(o, "order_date"); if (dateVal.Length < 1) continue; //no date DateTime d = DateTime.Parse(dateVal); if ((d.CompareTo(beginDate) < 0) || (d.CompareTo(endDate) > 0)) continue; oDate = d.ToShortDateString(); oCustomer = Client.GetValue(o, "customer_id"); //var dateVal = Client.GetValue(o, "date_created"); //oId = Client.GetValue(o, "id"); oId = Client.GetValue(o, "order_id"); //productsXml = CallCartApi(string.Format("orders/{0}/products", oId), "products").Elements("product"); productsXml = o.Elements().Where(x => x.Name.LocalName.Equals("product_details", StringComparison.CurrentCultureIgnoreCase)).Elements("item"); if (productsXml == null) throw new ArgumentNullException(); } catch (Exception ex) { errors++; continue; } foreach (var p in productsXml) { try { orders.Add(new SalesRecord { ProductId = Client.GetValue(p, "product_id"), CustomerId = oCustomer, //Quantity = Client.GetValue(p, "quantity"), Quantity = Client.GetValue(p, "product_qty"), Date = oDate }); } catch { errors++; } ProgressText = string.Format("{0}Extracting...{1} products, {2} errors ({3})", result, ++rows, errors, stopWatch.Lap()); } } } //} if (orders.Count < 1) return result + "(no data)"; var countDisplay = string.Format("({0} orders) ", orders.Count); ProgressText = tempDisplay + countDisplay + "Uploading..."; result += countDisplay + m_boostService.WriteTable(m_alias, filename, orders); stopWatch.Stop(); return result; }
protected override string GetCatalog() { var stopWatch = new StopWatch(true); var products = new List<ProductRecord>(); //get product count var countXml = CallCartApi("products/count", "products"); var countVal = countXml.Elements("count").First().Value; int pRows = Convert.ToInt16(countVal); //setup progress display var result = string.Format("{0}{1}: ({2} items) ", Environment.NewLine, CatalogFilename, countVal); ProgressText += result + "Extracting..."; string tempDisplay = ProgressText; //first get all the images because there can be many images for each product so record pages are not aligned countXml = CallCartApi("products/images/count", "images"); countVal = countXml.Elements("count").First().Value; int iRows = Convert.ToInt16(countVal); int pages = (int)Math.Ceiling( (decimal)iRows / (decimal)250 ); //can only get 250 products at a time var imagesXml = new List<XElement>(); //this will hold all images for entire catalog for (int page = 1; page <= pages; page++) { string paging = string.Format("?page={0}&limit=250", page); var pageXml = CallCartApi("products/images" + paging, "images"); if (pageXml == null) break; imagesXml.AddRange(pageXml.Elements("image")); ProgressText = string.Format("{1}{0}{2} Images ({3})", Environment.NewLine, tempDisplay, imagesXml.Count, stopWatch.Lap()); } tempDisplay = ProgressText; #if DEBUG if (imagesXml.Count() != iRows) { var errMsg = string.Format("Error reading BigCommerce images\nReported count = {0}, actual count = {1}", iRows, imagesXml.Count()); m_log.WriteEntry(errMsg, EventLogEntryType.Information, m_alias); } #endif //Next get all the custom fields so we don't have to make a separate call for each product countXml = CallCartApi("products/customfields/count", "customfields"); countVal = countXml.Elements("count").First().Value; iRows = Convert.ToInt16(countVal); pages = (int)Math.Ceiling((decimal)iRows / (decimal)250); //can only get 250 products at a time var customFieldXml = new List<XElement>(); //this will hold all images for entire catalog for (int page = 1; page <= pages; page++) { string paging = string.Format("?page={0}&limit=250", page); var pageXml = CallCartApi("products/customfields" + paging, "customfields"); if (pageXml == null) break; customFieldXml.AddRange(pageXml.Elements("customfield")); ProgressText = string.Format("{1}{0}{2} Custom Fields ({3})", Environment.NewLine, tempDisplay, customFieldXml.Count, stopWatch.Lap()); } tempDisplay = ProgressText; //Next get all the Categories so we can construct the tree countXml = CallCartApi("categories/count", "categories"); countVal = countXml.Elements("count").First().Value; iRows = Convert.ToInt16(countVal); pages = (int)Math.Ceiling((decimal)iRows / (decimal)250); //can only get 250 products at a time var categoryXml = new List<XElement>(); //this will hold all images for entire catalog for (int page = 1; page <= pages; page++) { string paging = string.Format("?page={0}&limit=250", page); var pageXml = CallCartApi("categories" + paging, "categories"); if (pageXml == null) break; categoryXml.AddRange(pageXml.Elements("category")); ProgressText = string.Format("{1}{0}{2} Categories ({3})", Environment.NewLine, tempDisplay, categoryXml.Count, stopWatch.Lap()); } SetCategoryParents(categoryXml); ProgressText += Environment.NewLine; tempDisplay = ProgressText; //now get each page of products pages = (int)Math.Ceiling((decimal)pRows / (decimal)250); //can only get 250 products at a time IEnumerable<XElement> productsXml = null; //this will only hold a single page of products int errors = 0; pRows = 0; for (int page = 1; page <= pages; page++) { string paging = string.Format("?page={0}&limit=250", page); productsXml = CallCartApi("products" + paging, "products"); if (productsXml == null) { errors++; //not necessarily an error break; } var productElements = productsXml.Elements("product"); foreach (var product in productElements) { try { var p = new ProductRecord { Name = Client.GetValue(product, "name"), ProductId = Client.GetValue(product, "id"), Att2Id = Client.GetValue(product, "brand_id"), Price = Client.GetValue(product, "price"), SalePrice = Client.GetValue(product, "sale_price"), Filter = string.Empty, Rating = Client.GetValue(product, "rating_total"), StandardCode = Client.GetValue(product, "upc"), Link = Client.GetValue(product, "custom_url"), ImageLink = string.Empty }; p.ImageLink = GetProductImage(imagesXml, p.ProductId); p.Att1Id = GetProductCategories(product.Element("categories")); if (p.StandardCode == null) p.StandardCode = string.Empty; #if DEBUG if (p.ProductId.Equals("11348") || p.ProductId.Equals("11012")) { var test = CallCartApi(string.Format("products/{0}/customfields", p.ProductId), "customfields"); var s = "break here"; } #endif var customFields = GetProductCustomFields(customFieldXml, p.ProductId); if (customFields.Any()) product.Add(customFields); //check category conditions, exclusions, and filters ApplyRules(ref p, product); products.Add(p); } catch { errors++; } ProgressText = string.Format("{0}{1} items completed, {2} errors ({3})", tempDisplay, ++pRows, errors, stopWatch.Lap()); } } if (products.Count < 1) return result + "(no data)"; var pCount = string.Format("({0} items) ", products.Count); ProgressText = string.Format("{0}{1} items completed ({2}){3}Uploading to server...", tempDisplay, pCount, stopWatch.Lap(), Environment.NewLine); result += m_boostService.WriteTable(m_alias, CatalogFilename, products); stopWatch.Stop(); return result; }