/// <summary> /// Updates an existing inventory /// </summary> /// <param name="id"></param> /// <param name="request"></param> /// <param name="context"></param> /// <param name="trackingGuid"></param> /// <param name="fromController"></param> /// <returns></returns> public async Task <Tagge.Common.Models.InventoryResponse> Update(InventoryRequest request, long id, Guid trackingGuid, bool fromController = false) { var response = new Tagge.Common.Models.InventoryResponse(); var companyId = context.Security.GetCompanyId(); try { // MongoDB Settings var database = context.MongoDbSettings.Value.Databases.FirstOrDefault(x => x.Name == "DeathStar"); string collectionName = database.Collections.FirstOrDefault(x => x.Name == "PC_Inventory").Name; // Get MongoDB var db = context.Database; var inventoryCollection = db.GetCollection <Deathstar.Data.Models.PC_Inventory>(collectionName); // Filter var filters = Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.Id, id); filters = filters & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.IsActive, true); filters = filters & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.DV_CompanyId, companyId.ToString()); // Inventory table string inventoryTable = string.Empty; // Webhook Scope string scope = string.Empty; // Word var dbInventory = new Deathstar.Data.Models.PC_Inventory(); // Check to see if the Inventory exists var existsfilter = Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.DV_CompanyId, companyId.ToString()); existsfilter = existsfilter & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.Id, id); existsfilter = existsfilter & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.IsActive, true); var existsInventory = inventoryCollection.Find(existsfilter).FirstOrDefault(); if (existsInventory == null) { throw new HttpResponseException() { StatusCode = Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound, ReasonPhrase = $"Inventory not found by Id: {id}" } } ; // Validate Product/Variant and set inventory table if (existsInventory.ST_TableName == "PC_Product") { inventoryTable = "PC_ProductInventory"; scope = "product"; } else { inventoryTable = "PC_ProductVariantInventory"; scope = "product/variant"; } // Verify Locations await LocationModel.Validate(request.LocationId, context, trackingGuid); // Convert to DB Object dbInventory.ConvertToDatabaseObject(companyId.ToString(), existsInventory.ST_TableName, request); // Add Updated By & Timestamp dbInventory.UpdatedBy = context.Security.GetEmail(); dbInventory.UpdatedDateTime = DateTimeOffset.Now.ToString("yyyy/MM/dd HH:mm:ss.fff zzz"); // Custom Fields if (request.CustomFields != null && request.CustomFields.Count > 0) { dbInventory.CustomFields = await _customFieldModel.SaveOrUpdateGenericCustomFields(request.CustomFields, dbInventory.CustomFields, inventoryTable, id.ToString(), trackingGuid); } // Update var serializerSettings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore }; var update = new BsonDocument() { { "$set", BsonDocument.Parse(JsonConvert.SerializeObject(dbInventory, serializerSettings)) } }; // Update database record await inventoryCollection.UpdateOneAsync(filters, update); // Convert To Response response = dbInventory.ConvertToResponse(); // Add Id response.Id = id; // Add back the Parent Id response.ParentId = Convert.ToInt64(existsInventory.InternalId); // ExternalIds if (request.ExternalIds != null && request.ExternalIds.Count > 0) { response.ExternalIds = await _externalIdModel.SaveOrUpdateGenericExternalId(request.ExternalIds, inventoryTable, id.ToString(), trackingGuid); } // Only send webhooks when making a direct call from the controller if (fromController) { // Build the Webhook event var whRequest = new Sheev.Common.Models.WebhookResponse() { CompanyId = companyId.ToString(), Type = "Inventory", Scope = $"{scope}/inventory/updated", Id = response.Id.ToString() }; // Trigger the Webhook event await _webHookModel.FireWebhookEvent(whRequest, context, trackingGuid); } return(response); } catch (HttpResponseException webEx) { IG2000.Data.Utilities.Logging.LogTrackingEvent($"Inventory failed to save! Reason: {webEx.ReasonPhrase}", $"Status Code: {webEx.StatusCode}", LT319.Common.Utilities.Constants.TrackingStatus.Error, context, trackingGuid); throw; } catch (Exception ex) { IG2000.Data.Utilities.Logging.LogTrackingEvent($"See logs for additional details", "Failed", LT319.Common.Utilities.Constants.TrackingStatus.Error, context, trackingGuid); IG2000.Data.Utilities.ErrorLogger.Report(ex.Message, "InventoryModel.Save()", context, trackingGuid, System.Diagnostics.EventLogEntryType.Error); throw new HttpResponseException() { StatusCode = Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError, ReasonPhrase = ex.Message }; } }
/// <summary> /// Save a new inventory /// </summary> /// <param name="request"></param> /// <param name="tableName"></param> /// <param name="internalId"></param> /// <param name="trackingGuid"></param> /// <param name="context"></param> /// <param name="fromController"></param> /// <returns></returns> public async Task <Tagge.Common.Models.InventoryResponse> Save(InventoryRequest request, string tableName, string internalId, Guid trackingGuid, bool fromController = false) { var response = new Tagge.Common.Models.InventoryResponse(); var companyId = context.Security.GetCompanyId(); long id = 0; try { // MongoDB Settings var database = context.MongoDbSettings.Value.Databases.FirstOrDefault(x => x.Name == "DeathStar"); string collectionName = database.Collections.FirstOrDefault(x => x.Name == "PC_Inventory").Name; // Get MongoDB var db = context.Database; var inventoryCollection = db.GetCollection <Deathstar.Data.Models.PC_Inventory>(collectionName); var counterCollection = db.GetCollection <Deathstar.Data.Models.Counter>("Counters"); // Inventory table string inventoryTable = string.Empty; // Webhook Scope string scope = string.Empty; // Verify Locations await LocationModel.Validate(request.LocationId, context, trackingGuid); // Validate Product/Variant and set inventory table if (tableName == "PC_Product") { await ProductModel.ValidateById(internalId, context, trackingGuid); inventoryTable = "PC_ProductInventory"; scope = "product"; } else { await VariantModel.ValidateById(internalId, context, trackingGuid); inventoryTable = "PC_ProductVariantInventory"; scope = "product/variant"; } // Check to see if the Inventory exists var existsfilter = Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.DV_CompanyId, companyId.ToString()); existsfilter = existsfilter & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.InternalId, internalId); // Product/Variant Id existsfilter = existsfilter & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.PC_LocationId, request.LocationId); existsfilter = existsfilter & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.ST_TableName, inventoryTable); existsfilter = existsfilter & Builders <Deathstar.Data.Models.PC_Inventory> .Filter.Eq(x => x.IsActive, true); var dbExistingInventory = inventoryCollection.Find(existsfilter).FirstOrDefault(); if (dbExistingInventory != null) { throw new HttpResponseException() { StatusCode = Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound, ReasonPhrase = $"Inventory record already exists. Use PUT to update the inventory. (Id = {dbExistingInventory.Id})!" } } ; // Word var dbInventory = new Deathstar.Data.Models.PC_Inventory(); // Save Inventory // filter var filter = Builders <Deathstar.Data.Models.Counter> .Filter.Eq(x => x.Id, "inventory_id"); var update = Builders <Deathstar.Data.Models.Counter> .Update.Inc("Seq", 1); // Get Id id = counterCollection.FindOneAndUpdate(filter, update).Seq; // Convert request to Inventory dbInventory.ConvertToDatabaseObject(companyId.ToString(), tableName, request); // Custom Fields if (request.CustomFields != null && request.CustomFields.Count > 0) { dbInventory.CustomFields = await _customFieldModel.SaveGenericCustomField(request.CustomFields, inventoryTable, id.ToString(), trackingGuid); } // Add Id dbInventory.Id = id; // Add Product/Variant Id dbInventory.InternalId = internalId; // Add Created By & Timestamp dbInventory.CreatedBy = context.Security.GetEmail(); dbInventory.CreatedDateTime = DateTimeOffset.Now.ToString("yyyy/MM/dd HH:mm:ss.fff zzz"); dbInventory.IsActive = true; // Insert await inventoryCollection.InsertOneAsync(dbInventory); IG2000.Data.Utilities.Logging.LogTrackingEvent($"Inventory (id: {dbInventory.Id}) successfully saved.", "Save Inventory", LT319.Common.Utilities.Constants.TrackingStatus.Complete, context, trackingGuid); // Building the Response response = dbInventory.ConvertToResponse(); // ExternalIds if (request.ExternalIds != null && request.ExternalIds.Count > 0) { response.ExternalIds = await _externalIdModel.SaveOrUpdateGenericExternalId(request.ExternalIds, inventoryTable, id.ToString(), trackingGuid); } // Build the Webhook event if (fromController) { var whRequest = new Sheev.Common.Models.WebhookResponse() { CompanyId = companyId.ToString(), Type = "Inventory", Scope = $"{scope}/inventory/created", Id = response.Id.ToString() }; // Trigger the Webhook event await _webHookModel.FireWebhookEvent(whRequest, context, trackingGuid); } return(response); } catch (HttpResponseException webEx) { IG2000.Data.Utilities.Logging.LogTrackingEvent($"Inventory failed to save! Reason: {webEx.ReasonPhrase}", $"Status Code: {webEx.StatusCode}", LT319.Common.Utilities.Constants.TrackingStatus.Error, context, trackingGuid); // Rollback the inventory to a failure await RollbackInventory(id, tableName); throw; } catch (Exception ex) { IG2000.Data.Utilities.Logging.LogTrackingEvent($"See logs for additional details", "Failed", LT319.Common.Utilities.Constants.TrackingStatus.Error, context, trackingGuid); IG2000.Data.Utilities.ErrorLogger.Report(ex.Message, "InventoryModel.Save()", context, trackingGuid, System.Diagnostics.EventLogEntryType.Error); // Rollback the inventory due to a failure await RollbackInventory(id, tableName); throw new HttpResponseException() { StatusCode = Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError, ReasonPhrase = ex.Message }; } }