public ConnectsterSyncJob(ConnectsterController controller, ConnectsterUser myUser, ManualResetEvent myEvent)
 {
     this.controller = controller;
     this.myUser = myUser;
     this.myEvent = myEvent;
     actionsPerformed = 0;
 }
 public List<ConnectsterProduct> GetAllShopsterifyProductsForUser(ConnectsterUser user)
 {
     return _database.SelectProductForUser(user);
 }
        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));
        }
 //here for easy calling
 public int DoSync(ConnectsterUser user)
 {
     return SyncProducts(user) + SyncOrders(user);
 }
        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;
        }