diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index a10ea197..f152c880 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -228,10 +228,10 @@ namespace AyaNova.Biz ct.WorkOrder.Remove(dbObject); await ct.SaveChangesAsync(); - await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Serial.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct); + await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, dbObject.Serial.ToString(), ct); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + await FileUtil.DeleteAttachmentsForObjectAsync(dbObject.AyaType, dbObject.Id, ct); await transaction.CommitAsync(); await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); } @@ -996,10 +996,10 @@ namespace AyaNova.Biz await ct.SaveChangesAsync(); //Log event - await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItem, dbObject.Id, "wo:" + dbObject.WorkOrderId.ToString(), ct);//FIX wo?? Not sure what is best here; revisit - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItem, ct); + await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, "wo:" + dbObject.WorkOrderId.ToString(), ct);//FIX wo?? Not sure what is best here; revisit + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + await FileUtil.DeleteAttachmentsForObjectAsync(dbObject.AyaType, dbObject.Id, ct); //all good do the commit if it's ours if (parentTransaction == null) @@ -1234,7 +1234,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//Fix?? await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + //await FileUtil.DeleteAttachmentsForObjectAsync(dbObject.AyaType, dbObject.Id, ct); if (parentTransaction == null) await transaction.CommitAsync(); await ExpenseHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); @@ -1469,7 +1469,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//Fix?? await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + // await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); if (parentTransaction == null) await transaction.CommitAsync(); await LaborHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); @@ -1627,7 +1627,7 @@ namespace AyaNova.Biz //newObject.CustomFields = JsonUtil.CompactJson(newObject.CustomFields); await ct.WorkOrderItemLoan.AddAsync(newObject); await ct.SaveChangesAsync(); - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemLoan, AyaEvent.Created), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, newObject.AyaType, AyaEvent.Created), ct); await LoanSearchIndexAsync(newObject, true); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); await LoanHandlePotentialNotificationEvent(AyaEvent.Created, newObject); @@ -1640,41 +1640,33 @@ namespace AyaNova.Biz // internal async Task LoanGetAsync(long id, bool logTheGetEvent = true) { - //Note: there could be rules checking here in future, i.e. can only get own workorder or something - //if so, then need to implement AddError and in route handle Null return with Error check just like PUT route does now - - //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.WorkOrderItemLoan - .SingleOrDefaultAsync(z => z.Id == id); + var ret = await ct.WorkOrderItemLoan.AsNoTracking().SingleOrDefaultAsync(z => z.Id == id); if (logTheGetEvent && ret != null) - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, AyaType.WorkOrderItemLoan, AyaEvent.Retrieved), ct); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, ret.AyaType, AyaEvent.Retrieved), ct); return ret; } //////////////////////////////////////////////////////////////////////////////////////////////// //UPDATE // - internal async Task LoanPutAsync(WorkOrderItemLoan dtPutObject) + internal async Task LoanPutAsync(WorkOrderItemLoan putObject) { - WorkOrderItemLoan dbObject = await ct.WorkOrderItemLoan.SingleOrDefaultAsync(z => z.Id == dtPutObject.Id); + var dbObject = await LoanGetAsync(putObject.Id, false); if (dbObject == null) { AddError(ApiErrorCode.NOT_FOUND, "id"); return null; } - - // make a snapshot of the original for validation but update the original to preserve workflow - WorkOrderItemLoan SnapshotOfOriginalDBObj = new WorkOrderItemLoan(); - CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj); - CopyObject.Copy(dtPutObject, dbObject, "Id"); + if (dbObject.Concurrency != putObject.Concurrency) + { + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } // dbObject.Tags = TagBiz.NormalizeTags(dbObject.Tags); // dbObject.CustomFields = JsonUtil.CompactJson(dbObject.CustomFields); - ct.Entry(dbObject).OriginalValues["Concurrency"] = dtPutObject.Concurrency; - await LoanValidateAsync(dbObject, SnapshotOfOriginalDBObj); + await LoanValidateAsync(putObject, dbObject); if (HasErrors) return null; try { @@ -1682,45 +1674,85 @@ namespace AyaNova.Biz } catch (DbUpdateConcurrencyException) { - if (!await LoanExistsAsync(dtPutObject.Id)) + if (!await LoanExistsAsync(putObject.Id)) AddError(ApiErrorCode.NOT_FOUND); else AddError(ApiErrorCode.CONCURRENCY_CONFLICT); return null; } - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemLoan, AyaEvent.Modified), ct); - await LoanSearchIndexAsync(dbObject, false); - //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await LoanHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); - return dbObject; + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, putObject.AyaType, AyaEvent.Modified), ct); + await LoanSearchIndexAsync(putObject, false); + //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, putObject.Tags, dbObject.Tags); + await LoanHandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject); + return putObject; } //////////////////////////////////////////////////////////////////////////////////////////////// //DELETE // - internal async Task LoanDeleteAsync(long id) + internal async Task LoanDeleteAsync(long id, Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction parentTransaction = null) { - WorkOrderItemLoan dbObject = await ct.WorkOrderItemLoan.SingleOrDefaultAsync(z => z.Id == id); - LoanValidateCanDelete(dbObject); - if (HasErrors) - return false; - ct.WorkOrderItemLoan.Remove(dbObject); - await ct.SaveChangesAsync(); + Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction transaction = null; + if (parentTransaction == null) + transaction = await ct.Database.BeginTransactionAsync(); + try + { + var dbObject = await LoanGetAsync(id,false); + LoanValidateCanDelete(dbObject); + if (HasErrors) + return false; + ct.WorkOrderItemLoan.Remove(dbObject); + await ct.SaveChangesAsync(); - //Log event - await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemLoan, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemLoan, ct); - //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await LoanHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + //Log event + await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//Fix?? + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct); + //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); + //await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + if (parentTransaction == null) + await transaction.CommitAsync(); + await LoanHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + } + catch + { + //Just re-throw for now, let exception handler deal, but in future may want to deal with this more here + throw; + } return true; } + ////////////////////////////////////////////// + //INDEXING + // + private async Task LoanSearchIndexAsync(WorkOrderItemLoan obj, bool isNew) + { + //SEARCH INDEXING + var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, obj.AyaType); + SearchParams.AddText(obj.Notes); + + if (isNew) + await Search.ProcessNewObjectKeywordsAsync(SearchParams); + else + await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams); + } + + public async Task LoanGetSearchResultSummary(long id) + { + var obj = await LoanGetAsync(id,false); + var SearchParams = new Search.SearchIndexProcessObjectParameters(); + if (obj != null) + SearchParams.AddText(obj.Notes); + return SearchParams; + } + //////////////////////////////////////////////////////////////////////////////////////////////// //VALIDATION // private async Task LoanValidateAsync(WorkOrderItemLoan proposedObj, WorkOrderItemLoan currentObj) { + //skip validation if seeding + // if (ServerBootConfig.SEEDING) return; + //run validation and biz rules bool isNew = currentObj == null; @@ -1763,30 +1795,6 @@ namespace AyaNova.Biz } - ////////////////////////////////////////////// - //INDEXING - // - private async Task LoanSearchIndexAsync(WorkOrderItemLoan obj, bool isNew) - { - //SEARCH INDEXING - var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, AyaType.WorkOrderItemLoan); - SearchParams.AddText(obj.Notes); - - if (isNew) - await Search.ProcessNewObjectKeywordsAsync(SearchParams); - else - await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams); - } - - public async Task LoanGetSearchResultSummary(long id) - { - var obj = await ct.WorkOrderItemLoan.SingleOrDefaultAsync(z => z.Id == id); - var SearchParams = new Search.SearchIndexProcessObjectParameters(); - if (obj != null) - SearchParams.AddText(obj.Notes); - return SearchParams; - } - //////////////////////////////////////////////////////////////////////////////////////////////// @@ -1852,7 +1860,7 @@ namespace AyaNova.Biz { return await ct.WorkOrderItemOutsideService.AnyAsync(z => z.Id == id); } - +HERE //////////////////////////////////////////////////////////////////////////////////////////////// //CREATE // @@ -1950,7 +1958,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemOutsideService, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//FIX why woitem, shouldn't it be outsideservice?? await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemOutsideService, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + //await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); await OutsideServiceHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2182,7 +2190,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemPart, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//FIX woitem?? await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPart, ct); // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + //await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); await PartHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2413,7 +2421,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemPartRequest, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//FIX "woitem"?? await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPartRequest, ct); // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + //await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); await PartRequestHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2621,7 +2629,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemScheduledUser, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct);//FIX woitem text?? await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemScheduledUser, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + //await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); await ScheduledUserHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2830,7 +2838,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemTask, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTask, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + //await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); await TaskHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -3062,7 +3070,7 @@ namespace AyaNova.Biz await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemTravel, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTravel, ct); // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + //await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); await TravelHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -3290,10 +3298,10 @@ namespace AyaNova.Biz await ct.SaveChangesAsync(); //Log event - await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderItemUnit, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); - await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemUnit, ct); + await EventLogProcessor.DeleteObjectLogAsync(UserId, dbObject.AyaType, dbObject.Id, "woitem:" + dbObject.WorkOrderItemId.ToString(), ct); + await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, dbObject.AyaType, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); - await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); + await FileUtil.DeleteAttachmentsForObjectAsync(dbObject.AyaType, dbObject.Id, ct); await UnitHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; }