private int SyncOrders(ConnectsterUser user) { int returnCount = 0; //Ask the db for credentials ShopifyStoreAuth shopifyAuth = _database.SelectShopifyUserDetails(user); ShopsterUser shopsterUser = _database.SelectShopsterUserDetails(user); var apiContext = new ConnectsterApiContext { AccessToken = shopsterUser.AuthToken, AccessTokenSecret = shopsterUser.AuthSecret }; List<ShopifyOrder> shopifyOrders = _shopifyComm.GetListAllOrders(shopifyAuth); //Think of this dictionary as Dictionary<ShopifyOrderId, ShopsterOrderId> Dictionary<int, int> shopsterifyOrderMap = _database.SelectOrderMappingsForUser(user); List<ConnectsterProduct> productMappingsList = _database.SelectProductForUser(user); var productDictionary = new Dictionary<int, int>(productMappingsList.Count); foreach (ConnectsterProduct item in productMappingsList) { productDictionary.Add(item.SourceId, item.DestinationId); } if (shopsterifyOrderMap == null || shopifyOrders == null) { //Todo Logging and fail return 0; } foreach (ShopifyOrder shopifyOrder in shopifyOrders) { if (shopsterifyOrderMap.Keys.Contains(shopifyOrder.Id)) { continue; //Skip this order, it already has been processed by shopsterify } int? newOrder; if ((newOrder = _shopsterComm.PlaceOrder(apiContext, shopifyOrder, productDictionary)) != null) { returnCount++; if (_database.CreateOrderMapping(user, shopifyOrder, (int) newOrder)) { } } } return returnCount; }
private int SyncProducts(ConnectsterUser user) { int returnCount = 0; //Ask the db for credentials ShopifyStoreAuth shopifyAuth = _database.SelectShopifyUserDetails(user); ShopsterUser shopsterUser = _database.SelectShopsterUserDetails(user); var apiContext = new ConnectsterApiContext { AccessToken = shopsterUser.AuthToken, AccessTokenSecret = shopsterUser.AuthSecret }; List<InventoryItemType> shopsterList; ConnectsterProductMap productMap; List<ShopifyProduct> shopifyItems; ShopifyMetafieldMap shopifyMapping; //Todo: Decide the lowest DetailGroup needed try { shopsterList = _shopsterComm.GetAllInventoryItemsForUser(apiContext, "All").Where( item => item.IsStoreVisible == true).Select(item => item).ToList(); productMap = new ConnectsterProductMap(user); shopifyItems = _shopifyComm.GetAllProducts(shopifyAuth); shopifyMapping = new ShopifyMetafieldMap(_shopifyComm, shopifyAuth); } catch (Exception e) { logger.FatalFormat( "ConnectsterController::SyncProducts(): Exception while creating lists. Exception is ({0}).", e.Message); return 0; //todo : throw our own exception class to the program to indicate the user should be disabled or ignored for a while. } if (shopifyItems == null) { //todo : again we need to throw our own exception class to indicate the user should be disabled or ignored for a while. return 0; } //create these lists here to reduce redundancy in proceeding calls. List<int> shopsterIds = shopsterList.Select(item => Convert.ToInt32(item.ItemId)).ToList(); List<int> shopifyIds = shopifyItems.Select(item => (int) item.Id).ToList(); _database.UpdateShopsterProductTimeStamps(shopsterList, DateTime.UtcNow); #if DEBUG //Some debugging info foreach (ConnectsterProduct mappedItem in productMap.GetMappedItems()) { logger.DebugFormat( "ConnectsterController::CreateListsAndBegin(): ShopsterifyDB has ShopsterId({0}, Date({1:yyyy-MM-dd HH:mm:ss}) \tMapped to \t ShopifyId({2}, Date({3:yyyy-MM-dd HH:mm:ss})", mappedItem.SourceId, mappedItem.SourceDate, mappedItem.DestinationId, mappedItem.DestinationDate); } foreach (ShopifyProduct item in shopifyItems) { logger.DebugFormat( "ConnectsterController::CreateListsAndBegin(): Shopify has shopifyItem({0}, Date:{1: yyyy-MM-dd HH:mm:ss})", item.Id, ((DateTime) item.Variants[0].UpdatedAt)); } foreach (ShopifyMetafieldMapping mapping in shopifyMapping.GetMappedItems()) { logger.DebugFormat("Shopify has Item({0}) --> ShopsterId({1})", mapping.SourceId, mapping.DestinationId); } #endif //Now do the actual syncronizing actions //This will ensure that all shopster products are in the db and on shopify returnCount += PushProductToShopify(shopsterList, productMap, shopifyMapping, shopifyIds, shopifyItems, shopifyAuth, apiContext); //This will clean up all the broken Maps returnCount += FixOrphanedMappings(shopsterIds, productMap, shopifyMapping, shopifyIds, shopifyAuth); //This will delete all orphaned shopify items (not mapped at all, but tagged as shopster items). return (returnCount + DeleteOrphanedShopifyProducts(shopsterList, productMap, shopifyMapping, shopifyAuth)); }
public List<InventoryItemType> GetAllInventoryItemsForUser(ConnectsterApiContext apiContext, string group) { if (apiContext == null) { throw new ArgumentException("apiContext may not be null"); } switch (group) { case "Group1": case "Group2": case "Group3": case "Group4": case "Group5": case "All": break; default: group = "All"; //Just default, no need to fail. break; } const int pageSize = 50; var returnList = new Dictionary<int, InventoryItemType>(); try { int pageNum = 0; //to keep our current page number var call = new GetInventoryItemsCall(apiContext) {Request = new GetInventoryItemsRequestType()}; do { call.Request.PageIndex = pageNum++; call.Request.PageSize = pageSize; call.Request.DetailGroups = group; call.Execute(); if (call.Response.Status == ResponseStatusType.Failed) { // Not sure what to do ApiLogger.DebugFormat( "ShopsterCommunicator::GetAllInventoryItemsForUser(): call.Response.Status == Failed. PageNum({0}), PageSize({1}), Group({2})", pageNum, pageSize, group); return null; //return null to indcate error, otherwise shopsterify will think a bunch of items have been deleted. } //TODO : handle warnings from shopsterAPI if (call.Response.Status == ResponseStatusType.Success || call.Response.Status == ResponseStatusType.SuccessWithWarnings) { foreach (InventoryItemType item in call.Response.Items) { returnList.Add(Convert.ToInt32(item.ItemId), item); } if (call.Response.Status == ResponseStatusType.SuccessWithWarnings) { int i = 0; foreach (var error in call.Response.Errors) { ApiLogger.WarnFormat( "ShopsterCommunicator::GetAllInventoryItemsForUser(): Warning/Error[{0}] for user({1}) : {2}", i, apiContext.AccessToken, error.Message); i++; } } } //Repeat the call until we have enough items (==call.Response.NumFound) or we've gone through enough pages. } while ( !(returnList.Count >= call.Response.NumFound || pageNum > ((call.Response.NumFound/pageSize) + 1))); return returnList.Count > 0 ? returnList.Values.ToList() : new List<InventoryItemType>(1); //Return the list } catch (ApiException ae) { string result = ae.Message; if (ae is ApiFaultException) { var afe = (ApiFaultException) ae; result = string.Format("({0}) {1}: {2}", afe.Error.SeverityCode, result, afe.Error.Message); ApiLogger.DebugFormat( "ShopsterCommunicator::GetAllInventoryItemsForUser(): ApiFaultException: ({0}) {1}: {2}", afe.Error.SeverityCode, result, afe.Error.Message); } return null; } //Return in either try or catch. }