diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index a73a51dd..9b56516e 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -61,7 +61,8 @@ namespace AyaNova.Biz UserType.Service); } - + //request cache for viz fields + private VizCache vc = new VizCache(); /* ██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ @@ -1011,43 +1012,93 @@ namespace AyaNova.Biz //Alert notes //Customer notes first then others below - var custInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == o.CustomerId).Select(x => new { x.AlertNotes, x.TechNotes, x.Name, x.Phone1, x.Phone2, x.Phone3, x.Phone4, x.Phone5, x.EmailAddress }).FirstOrDefaultAsync(); - if (!string.IsNullOrWhiteSpace(custInfo.AlertNotes)) { - o.AlertViz = $"{await Translate("Customer")} - {await Translate("AlertNotes")}\n{custInfo.AlertNotes}\n\n"; + if (vc.Get("wocustname", o.CustomerId) == null)//will always be present so no need to check other values + { + var custInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == o.CustomerId).Select(x => new { x.AlertNotes, x.TechNotes, x.Name, x.Phone1, x.Phone2, x.Phone3, x.Phone4, x.Phone5, x.EmailAddress }).FirstOrDefaultAsync(); + vc.Add(custInfo.Name, "wocustname", o.CustomerId); + if (!string.IsNullOrWhiteSpace(custInfo.AlertNotes)) + { + vc.Add($"{await Translate("Customer")} - {await Translate("AlertNotes")}\n{custInfo.AlertNotes}\n\n", "woalert", o.CustomerId); + } + else + { + vc.Add(string.Empty, "woalert", o.CustomerId); + } + + if (!string.IsNullOrWhiteSpace(custInfo.TechNotes)) + { + vc.Add($"{await Translate("CustomerTechNotes")}\n{custInfo.TechNotes}\n\n", "custtechnotes", o.CustomerId); + } + + vc.Add(custInfo.Phone1, "custphone1", o.CustomerId); + vc.Add(custInfo.Phone2, "custphone2", o.CustomerId); + vc.Add(custInfo.Phone3, "custphone3", o.CustomerId); + vc.Add(custInfo.Phone4, "custphone4", o.CustomerId); + vc.Add(custInfo.Phone5, "custphone5", o.CustomerId); + vc.Add(custInfo.EmailAddress, "custemail", o.CustomerId); + } + o.CustomerViz = vc.Get("wocustname", o.CustomerId); + o.AlertViz = vc.Get("woalert", o.CustomerId); + o.CustomerTechNotesViz = vc.Get("custtechnotes", o.CustomerId); + o.CustomerPhone1Viz = vc.Get("custphone1", o.CustomerId); + o.CustomerPhone2Viz = vc.Get("custphone2", o.CustomerId); + o.CustomerPhone3Viz = vc.Get("custphone3", o.CustomerId); + o.CustomerPhone4Viz = vc.Get("custphone4", o.CustomerId); + o.CustomerPhone5Viz = vc.Get("custphone5", o.CustomerId); + o.CustomerEmailAddressViz = vc.Get("custemail", o.CustomerId); + } - - if (!string.IsNullOrWhiteSpace(custInfo.TechNotes)) - { - o.CustomerTechNotesViz = $"{await Translate("CustomerTechNotes")}\n{custInfo.TechNotes}\n\n"; - } - - o.CustomerViz = custInfo.Name; - o.CustomerPhone1Viz = custInfo.Phone1; - o.CustomerPhone2Viz = custInfo.Phone2; - o.CustomerPhone3Viz = custInfo.Phone3; - o.CustomerPhone4Viz = custInfo.Phone4; - o.CustomerPhone5Viz = custInfo.Phone5; - o.CustomerEmailAddressViz = custInfo.EmailAddress; - if (o.ProjectId != null) - o.ProjectViz = await ct.Project.AsNoTracking().Where(x => x.Id == o.ProjectId).Select(x => x.Name).FirstOrDefaultAsync(); + { + string value = vc.Get("projname", o.ProjectId); + if (value == null) + { + value = await ct.Project.AsNoTracking().Where(x => x.Id == o.ProjectId).Select(x => x.Name).FirstOrDefaultAsync(); + vc.Add(value, "projname", o.ProjectId); + } + o.ProjectViz = value; + } if (o.ContractId != null) { - var contractVizFields = await ct.Contract.AsNoTracking().Where(x => x.Id == o.ContractId).Select(x => new { Name = x.Name, AlertNotes = x.AlertNotes }).FirstOrDefaultAsync(); - o.ContractViz = contractVizFields.Name; - if (!string.IsNullOrWhiteSpace(contractVizFields.AlertNotes)) + if (vc.Get("ctrctname", o.ContractId) == null) { - o.AlertViz += $"{await Translate("Contract")}\n{contractVizFields.AlertNotes}\n\n"; + var contractVizFields = await ct.Contract.AsNoTracking().Where(x => x.Id == o.ContractId).Select(x => new { Name = x.Name, AlertNotes = x.AlertNotes }).FirstOrDefaultAsync(); + vc.Add(contractVizFields.Name, "ctrctname", o.ContractId); + vc.Add(contractVizFields.AlertNotes, "ctrctalrt", o.ContractId); + } + o.ContractViz = vc.Get("ctrctname", o.ContractId);//contractVizFields.Name; + var alrtNotes = vc.Get("ctrctalrt", o.ContractId); + if (!string.IsNullOrWhiteSpace(alrtNotes)) + { + o.AlertViz += $"{await Translate("Contract")}\n{alrtNotes}\n\n"; } } else o.ContractViz = "-"; + if (o.FromQuoteId != null) - o.FromQuoteViz = await ct.Quote.AsNoTracking().Where(x => x.Id == o.FromQuoteId).Select(x => x.Serial.ToString()).FirstOrDefaultAsync(); + { + string value = vc.Get("woquoteserial", o.FromQuoteId); + if (value == null) + { + value = await ct.Quote.AsNoTracking().Where(x => x.Id == o.FromQuoteId).Select(x => x.Serial.ToString()).FirstOrDefaultAsync(); + vc.Add(value, "woquoteserial", o.FromQuoteId); + } + o.FromQuoteViz = value; + } + if (o.FromPMId != null) - o.FromPMViz = await ct.PM.AsNoTracking().Where(x => x.Id == o.FromPMId).Select(x => x.Serial.ToString()).FirstOrDefaultAsync(); + { + string value = vc.Get("wopmserial", o.FromPMId); + if (value == null) + { + value = await ct.PM.AsNoTracking().Where(x => x.Id == o.FromPMId).Select(x => x.Serial.ToString()).FirstOrDefaultAsync(); + vc.Add(value, "wopmserial", o.FromPMId); + } + o.FromPMViz = value; + } } @@ -2043,68 +2094,57 @@ namespace AyaNova.Biz //VIZ POPULATE // - //CACHING TEST - - private Dictionary _vizCache = new Dictionary(); - private void vizAdd(string value, string key, long? id = 0) - { - _vizCache[$"{key}{id}"] = value; - } - private string vizGet(string key, long? id = 0) - { - string value = null; - if (_vizCache.TryGetValue($"{key}{id}", out value)) - { - System.Diagnostics.Debug.WriteLine($"vizGet cache hit {key}{id}"); - return value; - } - else - { - System.Diagnostics.Debug.WriteLine($"vizGet cache miss {key}{id}"); - return null; - } - } - private async Task ItemPopulateVizFields(WorkOrderItem o, bool populateForReporting) { - // System.Diagnostics.Debug.WriteLine($"ItemPopulateVizFields nCacheTestValue is {nCacheTest}"); - if (o.FromCSRId != null) { - string value = vizGet("csr", o.FromCSRId); + string value = vc.Get("csr", o.FromCSRId); if (value == null) { value = await ct.CustomerServiceRequest.AsNoTracking().Where(x => x.Id == o.FromCSRId).Select(x => x.Name).FirstOrDefaultAsync(); - vizAdd(value, "csr", o.FromCSRId); + vc.Add(value, "csr", o.FromCSRId); } o.FromCSRViz = value; } if (o.WorkOrderItemStatusId != null) { - string value = vizGet("woistatname", o.WorkOrderItemStatusId); + string value = vc.Get("woistatname", o.WorkOrderItemStatusId); if (value == null) { var StatusInfo = await ct.WorkOrderItemStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == o.WorkOrderItemStatusId); - vizAdd(StatusInfo.Name, "woistatname", o.WorkOrderItemStatusId); - vizAdd(StatusInfo.Color, "woistatcolor", o.WorkOrderItemStatusId); + vc.Add(StatusInfo.Name, "woistatname", o.WorkOrderItemStatusId); + vc.Add(StatusInfo.Color, "woistatcolor", o.WorkOrderItemStatusId); o.WorkOrderItemStatusNameViz = StatusInfo.Name; o.WorkOrderItemStatusColorViz = StatusInfo.Color; } else { o.WorkOrderItemStatusNameViz = value; - o.WorkOrderItemStatusColorViz = vizGet("woistatcolor", o.WorkOrderItemStatusId); + o.WorkOrderItemStatusColorViz = vc.Get("woistatcolor", o.WorkOrderItemStatusId); } } if (o.WorkOrderItemPriorityId != null) { - var PriorityInfo = await ct.WorkOrderItemPriority.AsNoTracking().FirstOrDefaultAsync(x => x.Id == o.WorkOrderItemPriorityId); - o.WorkOrderItemPriorityNameViz = PriorityInfo.Name; - o.WorkOrderItemPriorityColorViz = PriorityInfo.Color; + string value = vc.Get("woipriorityname", o.WorkOrderItemPriorityId); + if (value == null) + { + var PriorityInfo = await ct.WorkOrderItemPriority.AsNoTracking().FirstOrDefaultAsync(x => x.Id == o.WorkOrderItemPriorityId); + vc.Add(PriorityInfo.Name, "woipriorityname", o.WorkOrderItemPriorityId); + vc.Add(PriorityInfo.Color, "woiprioritycolor", o.WorkOrderItemPriorityId); + + o.WorkOrderItemPriorityNameViz = PriorityInfo.Name; + o.WorkOrderItemPriorityColorViz = PriorityInfo.Color; + } + else + { + o.WorkOrderItemPriorityNameViz = value; + o.WorkOrderItemPriorityColorViz = vc.Get("woiprioritycolor", o.WorkOrderItemPriorityId); + + } } foreach (var v in o.Expenses) @@ -6140,29 +6180,81 @@ namespace AyaNova.Biz // private async Task UnitPopulateVizFields(WorkOrderItemUnit o, bool populateForReporting) { - var unitInfo = await ct.Unit.AsNoTracking() - .Where(x => x.Id == o.UnitId) - .Select(x => new { x.Serial, x.Description, x.UnitModelId, x.Address, x.City, x.Region, x.Country, x.Latitude, x.Longitude, x.Metered }) - .FirstOrDefaultAsync(); - o.UnitViz = unitInfo.Serial; - o.UnitDescriptionViz = unitInfo.Description; - o.UnitMeteredViz = unitInfo.Metered; + //see if it's in the cache already, populate the cache fully if not + bool UnitHasModel=false; + if (vc.Get("unitserial", o.UnitId) == null) + { + //cache it + var unitInfo = await ct.Unit.AsNoTracking() + .Where(x => x.Id == o.UnitId) + .Select(x => new { x.Serial, x.Description, x.UnitModelId, x.Address, x.City, x.Region, x.Country, x.Latitude, x.Longitude, x.Metered }) + .FirstOrDefaultAsync(); + vc.Add(unitInfo.Serial, "unitserial", o.UnitId); + vc.Add(unitInfo.Description, "unitdesc", o.UnitId); + vc.Add(unitInfo.Address, "unitaddr", o.UnitId); + vc.Add(unitInfo.City, "unitcity", o.UnitId); + vc.Add(unitInfo.Region, "unitregion", o.UnitId); + vc.Add(unitInfo.Country, "unitcountry", o.UnitId); + vc.Add(unitInfo.Latitude.ToString(), "unitlat", o.UnitId); + vc.Add(unitInfo.Longitude.ToString(), "unitlong", o.UnitId); + vc.Add(unitInfo.Metered.ToString(), "unitmetered", o.UnitId); + + if (unitInfo.UnitModelId != null) + { + UnitHasModel=true; + //units model name cached? (if it is then the rest will be cached as well) + if (vc.Get("unitsmodelname", o.UnitId) == null) + { + //nope, model name cached?? + if (vc.Get("unitmodelname", unitInfo.UnitModelId) == null) + { + //nope, so cache it all + var unitModelInfo = await ct.UnitModel.AsNoTracking().Where(x => x.Id == unitInfo.UnitModelId).Select(x => new { x.Name, x.VendorId }).FirstOrDefaultAsync(); + vc.Add(unitModelInfo.Name, "unitmodelname", unitInfo.UnitModelId); + vc.Add(unitModelInfo.Name, "unitsmodelname", o.UnitId); + + if (unitModelInfo.VendorId != null) + { + var ModelVendorName = vc.Get("unitsmodelvendorname", o.UnitId); + if (ModelVendorName == null) + { + ModelVendorName = vc.Get("vendorname", unitModelInfo.VendorId); + if (ModelVendorName == null) + { + ModelVendorName = await ct.Vendor.AsNoTracking().Where(x => x.Id == unitModelInfo.VendorId).Select(x => x.Name).FirstOrDefaultAsync(); + vc.Add(ModelVendorName, "vendorname", unitModelInfo.VendorId); + vc.Add(ModelVendorName, "unitsmodelvendorname", o.UnitId); + } + else + { + //cached under vendor so reuse here + vc.Add(ModelVendorName, "unitsmodelvendorname", o.UnitId); + } + } + } + } + } + } + } + //populate all fields from cache + if (UnitHasModel) + { + o.UnitModelNameViz = vc.Get("unitsmodelname", o.UnitId); + o.UnitModelVendorViz = vc.Get("unitsmodelvendorname", o.UnitId); + } + o.UnitViz = vc.Get("unitserial", o.UnitId); + o.UnitDescriptionViz = vc.Get("unitdesc", o.UnitId); + o.UnitMeteredViz = vc.GetAsBool("unitmetered", o.UnitId); + o.UnitModelNameViz = vc.Get("unitsmodelname", o.UnitId); + o.UnitModelVendorViz = vc.Get("unitsmodelvendorname", o.UnitId); if (populateForReporting) { - o.AddressViz = unitInfo.Address; - o.CityViz = unitInfo.City; - o.RegionViz = unitInfo.Region; - o.CountryViz = unitInfo.Country; - o.LatitudeViz = unitInfo.Latitude; - o.LongitudeViz = unitInfo.Longitude; - } - if (unitInfo.UnitModelId != null) - { - var unitModelInfo = await ct.UnitModel.AsNoTracking().Where(x => x.Id == unitInfo.UnitModelId).Select(x => new { x.Name, x.VendorId }).FirstOrDefaultAsync(); - o.UnitModelNameViz = unitModelInfo.Name; - - if (unitModelInfo.VendorId != null) - o.UnitModelVendorViz = await ct.Vendor.AsNoTracking().Where(x => x.Id == unitModelInfo.VendorId).Select(x => x.Name).FirstOrDefaultAsync(); + o.AddressViz = vc.Get("unitaddr", o.UnitId); + o.CityViz = vc.Get("unitcity", o.UnitId); + o.RegionViz = vc.Get("unitregion", o.UnitId); + o.CountryViz = vc.Get("unitcountry", o.UnitId); + o.LatitudeViz = vc.GetAsDecimal("unitlat", o.UnitId); + o.LongitudeViz = vc.GetAsDecimal("unitlong", o.UnitId); } } diff --git a/server/AyaNova/util/VizCache.cs b/server/AyaNova/util/VizCache.cs new file mode 100644 index 00000000..69ebac54 --- /dev/null +++ b/server/AyaNova/util/VizCache.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; + +namespace AyaNova.Util +{ + //Viz cache - used by biz objects during get report data to temporarily cache values from database for single request + //saves db calls and formatting + internal class VizCache + { + private Dictionary _vizCache = new Dictionary(); + // internal VizCache() + // { + // System.Diagnostics.Debug.WriteLine("constructing vizcache"); + // } + internal void Add(string value, string key, long? id = 0) + { + if (value == null) value = string.Empty; + _vizCache[$"{key}{id}"] = value; + System.Diagnostics.Debug.WriteLine($"ADD {key}{id} - {value}"); + } + internal string Get(string key, long? id = 0) + { + string value = null; + if (_vizCache.TryGetValue($"{key}{id}", out value)) + { + //System.Diagnostics.Debug.WriteLine($"vizGet cache hit {key}{id}"); + return value; + } + else + { + System.Diagnostics.Debug.WriteLine($"vizGet cache miss {key}{id}"); + return null; + } + } + + internal bool GetAsBool(string key, long? id = 0) + { + var s = Get(key, id); + if (string.IsNullOrWhiteSpace(s)) return false; + return bool.Parse(s); + } + + internal decimal? GetAsDecimal(string key, long? id = 0) + { + var s = Get(key, id); + if (string.IsNullOrWhiteSpace(s)) return null; + return decimal.Parse(s); + } + + }//eoc + +}//eons \ No newline at end of file