diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 4396222b..b795ee66 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -80,7 +80,10 @@ namespace AyaNova.Biz if (newObject.Items.Count > 0)//our front end will post the header alone on new so this indicates a fully populated wo was saved { await GetCurrentContractFromContractIdAsync(newObject.ContractId); - await ProcessChangeOfContractAsync(newObject.Id); + + + if (mContractInEffect != null && mContractInEffect.ResponseTime != TimeSpan.Zero) + newObject.CompleteByDate = DateTime.UtcNow.Add(mContractInEffect.ResponseTime); //GRANDCHILD BIZ ACTIONS foreach (WorkOrderItem wi in newObject.Items) @@ -166,7 +169,7 @@ namespace AyaNova.Biz //https://docs.microsoft.com/en-us/ef/core/querying/related-data //docs say this will not query twice but will recognize the duplicate woitem bit which is required for multiple grandchild collections var ret = - await ct.WorkOrder.AsNoTracking() + await ct.WorkOrder.AsSplitQuery().AsNoTracking() .Include(s => s.States) .Include(w => w.Items.OrderBy(item => item.Sequence)) .ThenInclude(wi => wi.Expenses) @@ -190,6 +193,7 @@ namespace AyaNova.Biz .ThenInclude(wi => wi.OutsideServices) .SingleOrDefaultAsync(z => z.Id == id); + //todo: set isLocked from state var stat = await GetCurrentWorkOrderStatusFromRelatedAsync(BizType, ret.Id); ret.IsLockedAtServer = stat.Locked; @@ -235,12 +239,13 @@ namespace AyaNova.Biz return null; await WorkOrderBizActionsAsync(AyaEvent.Modified, putObject, dbObject, null); - bool contractChanged = false; long? newContractId = null; if (putObject.ContractId != dbObject.ContractId)//manual change of contract { - contractChanged = true; newContractId = putObject.ContractId; + await GetCurrentContractFromContractIdAsync(newContractId); + if (mContractInEffect != null && mContractInEffect.ResponseTime != TimeSpan.Zero) + putObject.CompleteByDate = DateTime.UtcNow.Add(mContractInEffect.ResponseTime); } ct.Replace(dbObject, putObject); @@ -259,11 +264,6 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, BizType, AyaEvent.Modified), ct); await WorkOrderSearchIndexAsync(putObject, false); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, putObject.Tags, dbObject.Tags); - if (contractChanged) - { - await GetCurrentContractFromContractIdAsync(newContractId); - await ProcessChangeOfContractAsync(putObject.Id); - } await WorkOrderPopulateVizFields(putObject, true);//doing this here ahead of notification because notification may require the viz field lookup anyway and afaict no harm in it await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject); return putObject; @@ -555,61 +555,62 @@ namespace AyaNova.Biz - //////////////////////////////////////////////////////////////////////////////////////////////// - //CONTRACT CHANGE HANDLER - // - // - private async Task ProcessChangeOfContractAsync(long woId) - { - //contract has changed, update entire graph pricing and potentially response time stuff as well here now - //iterate graph calling *SetListPrice on each item - var wo = await ct.WorkOrder - .Include(s => s.States) - .Include(w => w.Items.OrderBy(item => item.Sequence)) - .ThenInclude(wi => wi.Expenses) - .Include(w => w.Items) - .ThenInclude(wi => wi.Labors) - .Include(w => w.Items) - .ThenInclude(wi => wi.Loans) - .Include(w => w.Items) - .ThenInclude(wi => wi.Parts) - .Include(w => w.Items) - .ThenInclude(wi => wi.PartRequests) - .Include(w => w.Items) - .ThenInclude(wi => wi.ScheduledUsers) - .Include(w => w.Items) - .ThenInclude(wi => wi.Tasks.OrderBy(t => t.Sequence)) - .Include(w => w.Items) - .ThenInclude(wi => wi.Travels) - .Include(w => w.Items) - .ThenInclude(wi => wi.Units) - .Include(w => w.Items) - .ThenInclude(wi => wi.OutsideServices) - .SingleOrDefaultAsync(z => z.Id == woId); + //NOTE: REMOVED WHEN REMOVED STATIC PRICING + // //////////////////////////////////////////////////////////////////////////////////////////////// + // //CONTRACT CHANGE HANDLER + // // + // // + // private async Task ProcessChangeOfContractAsync(long woId) + // { + // //contract has changed, update entire graph pricing and potentially response time stuff as well here now + // //iterate graph calling *SetListPrice on each item + // var wo = await ct.WorkOrder.AsSplitQuery() + // .Include(s => s.States) + // .Include(w => w.Items.OrderBy(item => item.Sequence)) + // .ThenInclude(wi => wi.Expenses) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.Labors) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.Loans) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.Parts) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.PartRequests) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.ScheduledUsers) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.Tasks.OrderBy(t => t.Sequence)) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.Travels) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.Units) + // .Include(w => w.Items) + // .ThenInclude(wi => wi.OutsideServices) + // .SingleOrDefaultAsync(z => z.Id == woId); - //If Contract has response time then set CompleteByDate - if (mContractInEffect != null && mContractInEffect.ResponseTime != TimeSpan.Zero) - { - wo.CompleteByDate = DateTime.UtcNow.Add(mContractInEffect.ResponseTime); - } + // //If Contract has response time then set CompleteByDate + // if (mContractInEffect != null && mContractInEffect.ResponseTime != TimeSpan.Zero) + // { + // wo.CompleteByDate = DateTime.UtcNow.Add(mContractInEffect.ResponseTime); + // } - // //update pricing - // foreach (WorkOrderItem wi in wo.Items) - // { - // // foreach (WorkOrderItemLabor o in wi.Labors) - // // await LaborSetPrice(o, mContractInEffect); - // foreach (WorkOrderItemTravel o in wi.Travels) - // TravelSetListPrice(o, mContractInEffect); - // foreach (WorkOrderItemPart o in wi.Parts) - // PartSetListPrice(o, mContractInEffect); - // } + // // //update pricing + // // foreach (WorkOrderItem wi in wo.Items) + // // { + // // // foreach (WorkOrderItemLabor o in wi.Labors) + // // // await LaborSetPrice(o, mContractInEffect); + // // foreach (WorkOrderItemTravel o in wi.Travels) + // // TravelSetListPrice(o, mContractInEffect); + // // foreach (WorkOrderItemPart o in wi.Parts) + // // PartSetListPrice(o, mContractInEffect); + // // } - await ct.SaveChangesAsync(); - return wo; + // await ct.SaveChangesAsync(); + // return wo; - } + // } @@ -1199,7 +1200,7 @@ namespace AyaNova.Biz //https://docs.microsoft.com/en-us/ef/core/querying/related-data //docs say this will not query twice but will recognize the duplicate woitem bit which is required for multiple grandchild collections var ret = - await ct.WorkOrderItem.AsNoTracking() + await ct.WorkOrderItem.AsSplitQuery().AsNoTracking() .Include(wi => wi.Expenses) .Include(wi => wi.Labors) .Include(wi => wi.Loans) @@ -5140,7 +5141,7 @@ namespace AyaNova.Biz if (id == null) return null; if (mFetchedContractAlready == false) { - mContractInEffect = await ct.Contract.AsNoTracking() + mContractInEffect = await ct.Contract.AsSplitQuery().AsNoTracking() .Include(c => c.ServiceRateItems) .Include(c => c.TravelRateItems) .Include(c => c.ContractPartOverrideItems) diff --git a/server/AyaNova/util/Seeder.cs b/server/AyaNova/util/Seeder.cs index 0e04a972..b9ce4d76 100644 --- a/server/AyaNova/util/Seeder.cs +++ b/server/AyaNova/util/Seeder.cs @@ -243,7 +243,7 @@ namespace AyaNova.Util await SeedPartAsync(log, 20, 5); await SeedPartAssemblyAsync(log, 5); await SeedPurchaseOrderAsync(log, 20); - await SeedWorkOrderAsync(log, 20); + await SeedWorkOrderAsync(log, 3); //PERF watch.Stop(); @@ -2559,7 +2559,7 @@ namespace AyaNova.Util o.InternalReferenceNumber = "irf-" + Fake.Finance.Account(4); o.ServiceDate = woDate; - int woItemCount = Fake.Random.Int(1, 3); + int woItemCount = 10;//Fake.Random.Int(2, 10); for (int y = 0; y < woItemCount; y++) { var woItem = new WorkOrderItem()