public void UpdateInventoryLevels(AcumaticaStockItem stockItem) { if (MonsterConfig.Settings.DisableShopifyPut) { _executionLogService.Log(LogBuilder.ShopifyPutDisabled()); return; } var variant = _inventoryRepository .RetrieveVariant(stockItem.MatchedVariant().ShopifyVariantId); if (variant.IsMissing) { _logger.Debug( $"Skipping Inventory Update for " + $"Variant {variant.ShopifySku} ({variant.ShopifyVariantId}) " + $"StockItem {stockItem} - reason: Missing Variant"); return; } if (variant.ShopifyProduct.IsDeleted) { _logger.Debug( $"Skipping Inventory Update for " + $"Variant {variant.ShopifySku} ({variant.ShopifyVariantId}) " + $"StockItem {stockItem} - reason: Deleted Parent Product"); return; } foreach (var level in variant.ShopifyInventoryLevels) { UpdateInventoryLevel(stockItem, level); } }
public void InsertItemSync(ShopifyVariant variant, AcumaticaStockItem stockItem, bool isSyncEnabled) { stockItem.ShopifyVariantMonsterId = variant.MonsterId; stockItem.IsSyncEnabled = isSyncEnabled; stockItem.LastUpdated = DateTime.UtcNow; Entities.SaveChanges(); }
private InventorySyncStatus MakeSyncStatus(AcumaticaStockItem input) { var settings = _settingsRepository.RetrieveSettings(); var output = new InventorySyncStatus(); output.StockItemId = input.ItemId; output.TaxCategoryId = input.AcumaticaTaxCategory; output.IsStockItemPriceSynced = input.IsVariantSynced; output.IsStockItemInventorySynced = input.AcumaticaInventories.All(x => x.IsInventorySynced); output.IsTaxCategoryValid = input.IsValidTaxCategory(settings); if (input.IsMatched()) { var variant = input.MatchedVariant(); output.ShopifyVariantId = variant.ShopifyVariantId; output.ShopifyVariantSku = variant.ShopifySku; output.IsShopifyVariantMissing = variant.IsMissing; output.ShopifyInventoryIsTracked = variant.ShopifyIsTracked; } else { output.IsShopifyVariantMissing = true; } return(output); }
public static VariantAndStockItemDto Make( AcumaticaStockItem input, Func <long, long, string> variantUrlService, Func <string, string> stockItemUrlService) { var output = new VariantAndStockItemDto(); output.MonsterVariantId = input.ShopifyVariant.MonsterId; output.ShopifyProductId = input.ShopifyVariant.ShopifyProduct.ShopifyProductId; output.ShopifyProductTitle = input.ShopifyVariant.ShopifyProduct.ShopifyTitle; output.ShopifyProductType = input.ShopifyVariant.ShopifyProduct.ShopifyProductType; output.ShopifyVendor = input.ShopifyVariant.ShopifyProduct.ShopifyVendor; output.ShopifyVariantId = input.ShopifyVariant.ShopifyVariantId; output.ShopifySku = input.ShopifyVariant.ShopifySku; output.ShopifyVariantTitle = input.ShopifyVariant.ShopifyTitle; output.ShopifyVariantUrl = variantUrlService( input.ShopifyVariant.ShopifyProduct.ShopifyProductId, input.ShopifyVariant.ShopifyVariantId); output.AcumaticaItemId = input.ItemId; output.AcumaticaDescription = input.AcumaticaDescription; output.AcumaticaStockItemUrl = stockItemUrlService(input.ItemId); output.IsSyncEnabled = input.IsSyncEnabled; return(output); }
private void UpdateShopifyVariant(AcumaticaStockItem stockItemRecord, bool setTracking) { var settings = _settingsRepository.RetrieveSettings(); var variantRecord = stockItemRecord.MatchedVariant(); var stockItemObj = _acumaticaJsonService.RetrieveStockItem(stockItemRecord.ItemId); // Build the Shopify DTO // var variantShopifyId = variantRecord.ShopifyVariantId; var variantSku = variantRecord.ShopifySku; // Push the update via Variant API // var id = variantShopifyId; var taxable = stockItemRecord.IsTaxable(settings).Value; var price = settings.InventorySyncPrice ? (decimal)stockItemObj.DefaultPrice.value : (decimal?)null; var grams = settings.InventorySyncWeight ? stockItemObj.DimensionWeight.value.ToShopifyGrams() : (int?)null; string json = VariantUpdate.Make(id, taxable, price, grams); _productApi.UpdateVariantPrice(variantShopifyId, json); using (var transaction = _syncInventoryRepository.BeginTransaction()) { var log = LogBuilder.UpdateShopifyVariantPrice(variantSku, taxable, price, grams); _executionLogService.Log(log); // Update Stock Item record // stockItemRecord.IsVariantSynced = true; stockItemRecord.LastUpdated = DateTime.UtcNow; // Update Variant record // variantRecord.ShopifyIsTaxable = taxable; if (price.HasValue) { variantRecord.ShopifyPrice = price.Value; } if (setTracking) { variantRecord.ShopifyIsTracked = true; } _syncInventoryRepository.SaveChanges(); transaction.Commit(); } }
public static AcumaticaStockItemModel Make( AcumaticaStockItem stockItem, Func <string, string> stockItemUrlBuilder) { var output = new AcumaticaStockItemModel(); output.ItemId = stockItem.ItemId; output.Description = stockItem.AcumaticaDescription; output.AcumaticaUrl = stockItemUrlBuilder(stockItem.ItemId); output.QuantityOnHand = (int)stockItem.AcumaticaInventories.Sum(x => x.AcumaticaAvailQty); return(output); }
public static bool?IsTaxable(this AcumaticaStockItem input, MonsterSetting settings) { if (input.AcumaticaTaxCategory == settings.AcumaticaTaxableCategory) { return(true); } if (input.AcumaticaTaxCategory == settings.AcumaticaTaxExemptCategory) { return(false); } return(null); }
public void UpdatePriceAndCost(AcumaticaStockItem stockItemRecord, bool setTracking = false) { if (MonsterConfig.Settings.DisableShopifyPut) { _executionLogService.Log(LogBuilder.ShopifyPutDisabled()); return; } if (!stockItemRecord.IsMatched()) { return; } UpdateShopifyVariant(stockItemRecord, setTracking); UpdateVariantCostOfGoods(stockItemRecord, setTracking); }
public void UpsertStockItemToPersist(List <StockItem> items) { foreach (var item in items) { var existingData = _inventoryRepository.RetreiveStockItem(item.InventoryID.value); using (var transaction = _inventoryRepository.BeginTransaction()) { if (existingData == null) { var newData = new AcumaticaStockItem(); newData.ItemId = item.InventoryID.value; newData.AcumaticaDescription = item.Description.value; newData.AcumaticaTaxCategory = item.TaxCategory.value; newData.AcumaticaDefaultPrice = (decimal)item.DefaultPrice.value; newData.AcumaticaLastCost = (decimal)item.LastCost.value; newData.IsVariantSynced = false; newData.DateCreated = DateTime.UtcNow; newData.LastUpdated = DateTime.UtcNow; _executionLogService.Log(LogBuilder.DetectedNewStockItem(newData)); _inventoryRepository.InsertStockItems(newData); } else { existingData.AcumaticaDescription = item.Description.value; existingData.AcumaticaTaxCategory = item.TaxCategory.value; existingData.AcumaticaDefaultPrice = (decimal)item.DefaultPrice.value; existingData.AcumaticaLastCost = (decimal)item.LastCost.value; existingData.IsVariantSynced = false; existingData.LastUpdated = DateTime.UtcNow; _executionLogService.Log(LogBuilder.DetectedChangeToStockItem(existingData)); _inventoryRepository.SaveChanges(); } _acumaticaJsonService.Upsert( AcumaticaJsonType.StockItem, item.InventoryID.value, item.SerializeToJson()); transaction.Commit(); } } }
private void UpdateInventoryLevel(AcumaticaStockItem stockItem, ShopifyInventoryLevel level) { var location = _syncInventoryRepository.RetrieveLocation(level.ShopifyLocationId); var warehouseIds = location.MatchedWarehouseIds(); var warehouseDetails = stockItem.Inventory(warehouseIds); var available = (int)warehouseDetails.Sum(x => x.AcumaticaAvailQty); var sku = level.ShopifyVariant.ShopifySku; var levelDto = new InventoryLevel { inventory_item_id = level.ShopifyInventoryItemId, available = available, location_id = location.ShopifyLocationId, }; var levelJson = levelDto.SerializeToJson(); _inventoryApi.SetInventoryLevels(levelJson); using (var transaction = _syncInventoryRepository.BeginTransaction()) { var log = $"Updated Shopify Variant {sku} " + $"in Location {location.ShopifyLocationName} to Available Qty {available}"; _executionLogService.Log(log); warehouseDetails.ForEach(x => x.IsInventorySynced = true); // Update Shopify Inventory Level records // level.ShopifyAvailableQuantity = available; level.LastUpdated = DateTime.UtcNow; _inventoryRepository.SaveChanges(); transaction.Commit(); } }
private void UpdateVariantCostOfGoods(AcumaticaStockItem stockItemRecord, bool setTracking) { var variantRecord = stockItemRecord.MatchedVariant(); var costOfGoods = stockItemRecord.AcumaticaLastCost; // Push the cost of goods via Inventory API // string content; if (setTracking) { var inventoryItem = new InventoryItem(); inventoryItem.id = variantRecord.ShopifyInventoryItemId; inventoryItem.cost = costOfGoods; inventoryItem.tracked = true; content = new { inventory_item = inventoryItem }.SerializeToJson(); } else { var inventoryItem = new InventoryItemUpdate(); inventoryItem.id = variantRecord.ShopifyInventoryItemId; inventoryItem.cost = costOfGoods; content = new { inventory_item = inventoryItem }.SerializeToJson(); } _inventoryApi.SetInventoryCost(variantRecord.ShopifyInventoryItemId, content); using (var transaction = _syncInventoryRepository.BeginTransaction()) { var log = LogBuilder.UpdateShopifyVariantCogsOfGoods(variantRecord.ShopifySku, costOfGoods); _executionLogService.Log(log); variantRecord.ShopifyCost = costOfGoods; _syncInventoryRepository.SaveChanges(); transaction.Commit(); } }
public void StockItemPush(AcumaticaStockItemImportContext context, ShopifyVariant variant) { _logService.Log(LogBuilder.CreateStockItem(variant)); var newStockItem = BuildNewStockItem(context.WarehouseId, variant); var newStockItemJson = newStockItem.SerializeToJson(); // Push to Acumatica API // var result = _distributionClient.AddNewStockItem(newStockItemJson); var item = result.DeserializeFromJson <StockItem>(); // Create Monster record // var newRecord = new AcumaticaStockItem(); newRecord.ItemId = item.InventoryID.value; _acumaticaJsonService.Upsert( AcumaticaJsonType.StockItem, item.InventoryID.value, item.SerializeToJson()); newRecord.AcumaticaDescription = item.Description.value; newRecord.AcumaticaTaxCategory = item.TaxCategory.value; newRecord.IsVariantSynced = false; newRecord.DateCreated = DateTime.UtcNow; newRecord.LastUpdated = DateTime.UtcNow; using (var transaction = _syncRepository.BeginTransaction()) { _inventoryRepository.InsertStockItems(newRecord); _syncRepository.InsertItemSync(variant, newRecord, context.IsSyncEnabled); var log = $"Created Stock Item {item.InventoryID.value} in Acumatica"; _logService.Log(log); transaction.Commit(); } }
public static string DetectedChangeToStockItem(AcumaticaStockItem item) { return($"Detected change to {item.LogDescriptor()}"); }
public static string DetectedNewStockItem(AcumaticaStockItem item) { return($"Detected new {item.LogDescriptor()}"); }
public static string LogDescriptor(this AcumaticaStockItem stockItem) { return($"Acumatica Stock Item {stockItem.ItemId}"); }
public static bool IsValidTaxCategory(this AcumaticaStockItem input, MonsterSetting settings) { return(input.IsTaxable(settings).HasValue); }
public static string UpdateShopifyPrice(AcumaticaStockItem item) { return($"Updating Shopify Price for {item.LogDescriptor()}"); }
public static string UpdateShopifyInventory(AcumaticaStockItem item) { return($"Updating {item.LogDescriptor()}"); }
public void DeleteItemSyncs(AcumaticaStockItem stockItem) { stockItem.IsSyncEnabled = false; stockItem.ShopifyVariantMonsterId = null; Entities.SaveChanges(); }
public static bool IsMatched(this AcumaticaStockItem input) { return(input.ShopifyVariant != null); }
public static ShopifyVariant MatchedVariant(this AcumaticaStockItem stockItem) { return(stockItem.ShopifyVariant); }
public void InsertStockItems(AcumaticaStockItem item) { Entities.AcumaticaStockItems.Add(item); Entities.SaveChanges(); }
public static List <AcumaticaInventory> Inventory(this AcumaticaStockItem input, List <string> warehouseIds) { return(input.AcumaticaInventories .Where(x => warehouseIds.Contains(x.AcumaticaWarehouseId.Trim())).ToList()); }