diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 33e2f535..36a8b283 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -5,7 +5,7 @@ Import / export features TODO: OUTSTANDING FOR IMPORT: - Unit, Unitmodel, vendor, INVENTORY + INVENTORY HeadOffice contract code sb more like unit contract code with null vs empty handling of json CustomerBiz contract code sb mroe like unit contract and updateable (update docs too to show it can be updated currently says no) test each object diff --git a/server/AyaNova/biz/PartInventoryBiz.cs b/server/AyaNova/biz/PartInventoryBiz.cs index 22da0c77..03fd9259 100644 --- a/server/AyaNova/biz/PartInventoryBiz.cs +++ b/server/AyaNova/biz/PartInventoryBiz.cs @@ -7,10 +7,11 @@ using AyaNova.Api.ControllerHelpers; using AyaNova.Models; using Newtonsoft.Json.Linq; using System.Collections.Generic; +using Newtonsoft.Json; namespace AyaNova.Biz { - internal class PartInventoryBiz : BizObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject + internal class PartInventoryBiz : BizObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject, IImportAbleObject { internal PartInventoryBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles) { @@ -342,6 +343,87 @@ namespace AyaNova.Biz + public async Task> ImportData(AyImportData importData) + { + List ImportResult = new List(); + if (importData.DoUpdate) + { + ImportResult.Add($"❌ Inventory transactions can only be Imported, not Updated"); + return ImportResult; + } + string ImportTag = ImportUtil.GetImportTag(); + foreach (JObject j in importData.Data) + { + try + { + long ImportPartId = -1;//default meaning not included / don't set + if (j["PartViz"] != null) + { + + if (!JsonUtil.JTokenIsNullOrEmpty(j["PartViz"])) + { + //a name was specified so attempt to find it + ImportPartId = await ct.Part.AsNoTracking().Where(z => z.Name == (string)j["PartViz"]).Select(x => x.Id).FirstOrDefaultAsync(); + if (ImportPartId == 0) + AddError(ApiErrorCode.NOT_FOUND, "PartViz", $"'{(string)j["PartViz"]}'"); + } + } + else + AddError(ApiErrorCode.VALIDATION_REQUIRED, "PartViz"); + + long ImportPartWarehouseId = -1;//default meaning not included / don't set + if (j["PartWarehouseViz"] != null) + { + if (!JsonUtil.JTokenIsNullOrEmpty(j["PartWarehouseViz"])) + { + //a name was specified so attempt to find it + ImportPartWarehouseId = await ct.PartWarehouse.AsNoTracking().Where(z => z.Name == (string)j["PartWarehouseViz"]).Select(x => x.Id).FirstOrDefaultAsync(); + if (ImportPartWarehouseId == 0) + AddError(ApiErrorCode.NOT_FOUND, "PartWarehouseViz", $"'{(string)j["PartWarehouseViz"]}'"); + } + } + else + AddError(ApiErrorCode.VALIDATION_REQUIRED, "PartWarehouseViz"); + + var ImportDescription = (string)j["Description"]; + + decimal ImportQuantity = 0; + if (j["Quantity"] != null) + { + ImportQuantity = (decimal)j["Quantity"]; + } + else + AddError(ApiErrorCode.VALIDATION_REQUIRED, "Quantity"); + + //import this record + + if (string.IsNullOrWhiteSpace(ImportDescription)) + ImportDescription = ImportTag; + + var Target = new dtPartInventory() { Description = ImportDescription, PartId = ImportPartId, PartWarehouseId = ImportPartWarehouseId, Quantity = ImportQuantity }; + //var Target = j.ToObject(); + var nameviz = $"{Target.Description} - part {(string)j["PartViz"]}, quantity: {(decimal)j["Quantity"]}"; + + var res = await CreateAsync(Target); + if (res == null) + { + ImportResult.Add($"❌ {nameviz}\r\n{this.GetErrorsAsString()}"); + this.ClearErrors(); + } + else + { + ImportResult.Add($"✔️ {nameviz}"); + } + + + } + catch (Exception ex) + { + ImportResult.Add($"❌ Exception processing import\n record:{j.ToString()}\nError:{ex.Message}\nSource:{ex.Source}\nStack:{ex.StackTrace.ToString()}"); + } + } + return ImportResult; + }