diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index d1850036..388b3186 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -22,9 +22,11 @@ namespace AyaNova.Biz So I guess get a minimally working backend, then a minimally working front end to just get a gist of what the path forward is and then can jump in with real world shit I guess just implementing a very simple portion like from wo down to item down to a single grandchild makes the most sense + + */ - internal class WorkOrderBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject, INotifiableObject + internal class WorkOrderBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject { // //Feature specific roles // internal static AuthorizationRoles RolesAllowedToChangeSerial = AuthorizationRoles.BizAdminFull | AuthorizationRoles.DispatchFull | AuthorizationRoles.AccountingFull; @@ -83,7 +85,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); await WorkOrderSearchIndexAsync(newObject, true); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -108,7 +110,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, AyaEvent.Created), ct); await WorkOrderSearchIndexAsync(newObject, true); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } @@ -124,6 +126,7 @@ namespace AyaNova.Biz //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() + .Include(s => s.States) .Include(w => w.Items) .ThenInclude(wi => wi.Expenses) .Include(w => w.Items) @@ -189,7 +192,7 @@ 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); - await HandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject); + await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject); return putObject; } @@ -202,7 +205,7 @@ namespace AyaNova.Biz { try { - WorkOrder dbObject = await WorkOrderGetAsync(id,false); + WorkOrder dbObject = await WorkOrderGetAsync(id, false); if (dbObject == null) { AddError(ApiErrorCode.NOT_FOUND); @@ -228,7 +231,7 @@ namespace AyaNova.Biz await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); await transaction.CommitAsync(); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await WorkOrderHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); } catch { @@ -257,53 +260,54 @@ namespace AyaNova.Biz woitemid = id; break; case AyaType.WorkOrderItemExpense: - woitemid = await ct.WorkOrderItemExpense.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemExpense.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemLabor: - woitemid = await ct.WorkOrderItemLabor.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemLabor.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemLoan: - woitemid = await ct.WorkOrderItemLoan.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemLoan.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemPart: - woitemid = await ct.WorkOrderItemPart.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemPart.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemPartRequest: - woitemid = await ct.WorkOrderItemPartRequest.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemPartRequest.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemScheduledUser: - woitemid = await ct.WorkOrderItemScheduledUser.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemScheduledUser.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemTask: - woitemid = await ct.WorkOrderItemTask.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemTask.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemTravel: - woitemid = await ct.WorkOrderItemTravel.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemTravel.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; case AyaType.WorkOrderItemOutsideService: - woitemid = await ct.WorkOrderItemOutsideService.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemOutsideService.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; + case AyaType.WorkOrderStatus: + return await ct.WorkOrderState.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderId).SingleOrDefaultAsync(); case AyaType.WorkOrderItemUnit: - woitemid = await ct.WorkOrderItemUnit.Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); + woitemid = await ct.WorkOrderItemUnit.AsNoTracking().Where(z => z.Id == id).Select(z => z.WorkOrderItemId).SingleOrDefaultAsync(); break; default: throw new System.NotSupportedException($"WorkOrderBiz::GetAncestor -> AyaType {ayaType.ToString()} is not supported"); } - return await ct.WorkOrderItem.AsNoTracking() + return await ct.WorkOrderItem.AsNoTracking() .Where(z => z.Id == woitemid) .Select(z => z.WorkOrderId) .SingleOrDefaultAsync(); } - //////////////////////////////////////////////////////////////////////////////////////////////// //SEARCH // private async Task WorkOrderSearchIndexAsync(WorkOrder obj, bool isNew) { var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType); - SearchParams.AddText(obj.Notes).AddText(obj.Serial).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields); + DigestSearchText(obj, SearchParams); if (isNew) await Search.ProcessNewObjectKeywordsAsync(SearchParams); else @@ -314,12 +318,15 @@ namespace AyaNova.Biz { var obj = await ct.WorkOrder.SingleOrDefaultAsync(z => z.Id == id); var SearchParams = new Search.SearchIndexProcessObjectParameters(); - if (obj != null) - SearchParams.AddText(obj.Notes).AddText(obj.Serial).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields); + DigestSearchText(obj, SearchParams); return SearchParams; } - + public void DigestSearchText(WorkOrder obj, Search.SearchIndexProcessObjectParameters searchParams) + { + if (obj != null) + searchParams.AddText(obj.Notes).AddText(obj.Serial).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields); + } //////////////////////////////////////////////////////////////////////////////////////////////// @@ -330,6 +337,10 @@ namespace AyaNova.Biz private async Task WorkOrderValidateAsync(WorkOrder proposedObj, WorkOrder currentObj) { + //This may become necessary for v8migrate, leaving out for now + //skip validation if seeding + //if (ServerBootConfig.SEEDING) return; + //run validation and biz rules bool isNew = currentObj == null; @@ -385,7 +396,16 @@ namespace AyaNova.Biz private void WorkOrderValidateCanDelete(WorkOrder dbObject) { - //whatever needs to be check to delete this object + //FOREIGN KEY CHECKS + //these are examples copied from customer for when other objects are actually referencing them + // if (await ct.User.AnyAsync(m => m.CustomerId == inObj.Id)) + // AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("User")); + // if (await ct.Unit.AnyAsync(m => m.CustomerId == inObj.Id)) + // AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("Unit")); + // if (await ct.CustomerServiceRequest.AnyAsync(m => m.CustomerId == inObj.Id)) + // AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("CustomerServiceRequest")); + // if (await ct.PurchaseOrder.AnyAsync(m => m.DropShipToCustomerId == inObj.Id)) + // AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "generalerror", await Translate("PurchaseOrder")); } @@ -430,7 +450,7 @@ namespace AyaNova.Biz var orderedList = from id in batch join z in batchResults on id equals z.Id select z; foreach (WorkOrder w in orderedList) { - await PopulateVizFields(w); + await WorkOrderPopulateVizFields(w); var jo = JObject.FromObject(w); if (!JsonUtil.JTokenIsNullOrEmpty(jo["CustomFields"])) jo["CustomFields"] = JObject.Parse((string)jo["CustomFields"]); @@ -442,8 +462,9 @@ namespace AyaNova.Biz //populate viz fields from provided object - private async Task PopulateVizFields(WorkOrder o) + private async Task WorkOrderPopulateVizFields(WorkOrder o) { + await Task.CompletedTask; // if (o.WorkOrderOverseerId != null) // o.WorkOrderOverseerViz = await ct.User.AsNoTracking().Where(x => x.Id == o.WorkOrderOverseerId).Select(x => x.Name).FirstOrDefaultAsync(); } @@ -572,7 +593,7 @@ namespace AyaNova.Biz //////////////////////////////////////////////////////////////////////////////////////////////// // NOTIFICATION PROCESSING // - public async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + public async Task WorkOrderHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); if (ServerBootConfig.SEEDING) return; @@ -594,6 +615,212 @@ namespace AyaNova.Biz #endregion workorder level + + /* + + ███████╗████████╗ █████╗ ████████╗███████╗███████╗ + ██╔════╝╚══██╔══╝██╔══██╗╚══██╔══╝██╔════╝██╔════╝ + ███████╗ ██║ ███████║ ██║ █████╗ ███████╗ + ╚════██║ ██║ ██╔══██║ ██║ ██╔══╝ ╚════██║ + ███████║ ██║ ██║ ██║ ██║ ███████╗███████║ + ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ + + */ + + + #region WorkOrderState level + //////////////////////////////////////////////////////////////////////////////////////////////// + //EXISTS + internal async Task StateExistsAsync(long id) + { + return await ct.WorkOrderState.AnyAsync(z => z.Id == id); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //CREATE + // + internal async Task StateCreateAsync(WorkOrderState newObject) + { + await StateValidateAsync(newObject, null); + if (HasErrors) + return null; + else + { + await ct.WorkOrderState.AddAsync(newObject); + await ct.SaveChangesAsync(); + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderStatus, AyaEvent.Created), ct); + return newObject; + } + } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // GET + // + internal async Task StateGetAsync(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.WorkOrderState.AsNoTracking().SingleOrDefaultAsync(z => z.Id == id); + if (logTheGetEvent && ret != null) + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, AyaType.WorkOrderStatus, AyaEvent.Retrieved), ct); + return ret; + } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + //UPDATE + // + internal async Task StatePutAsync(WorkOrderState putObject) + { + + WorkOrderState dbObject = await StateGetAsync(putObject.Id, false); + if (dbObject == null) + { + AddError(ApiErrorCode.NOT_FOUND, "id"); + return null; + } + if (dbObject.Concurrency != putObject.Concurrency) + { + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + await StateValidateAsync(putObject, dbObject); + if (HasErrors) return null; + ct.Replace(dbObject, putObject); + try + { + await ct.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + if (!await ItemExistsAsync(putObject.Id)) + AddError(ApiErrorCode.NOT_FOUND); + else + AddError(ApiErrorCode.CONCURRENCY_CONFLICT); + return null; + } + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderStatus, AyaEvent.Modified), ct); + + await StateHandlePotentialNotificationEvent(AyaEvent.Modified, putObject, dbObject); + return putObject; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + //DELETE + // + internal async Task StateDeleteAsync(long id, Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction parentTransaction = null) + { + Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction transaction = null; + if (parentTransaction == null) + transaction = await ct.Database.BeginTransactionAsync(); + try + { + WorkOrderState dbObject = await StateGetAsync(id, false); + StateValidateCanDelete(dbObject); + if (HasErrors) + return false; + + ct.WorkOrderState.Remove(dbObject); + await ct.SaveChangesAsync(); + + //Log event + await EventLogProcessor.DeleteObjectLogAsync(UserId, AyaType.WorkOrderStatus, dbObject.Id, "wo:" + dbObject.WorkOrderId.ToString(), ct); + + //all good do the commit if it's ours + if (parentTransaction == null) + await transaction.CommitAsync(); + await StateHandlePotentialNotificationEvent(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; + } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + //VALIDATION + // + private async Task StateValidateAsync(WorkOrderState proposedObj, WorkOrderState currentObj) + { + // //skip validation if seeding + // if (ServerBootConfig.SEEDING) return; + + //run validation and biz rules + bool isNew = currentObj == null; + + //does it have a valid workorder id + if (proposedObj.WorkOrderId == 0) + AddError(ApiErrorCode.VALIDATION_REQUIRED, "WorkOrderId"); + else if (!await WorkOrderExistsAsync(proposedObj.WorkOrderId)) + { + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderId"); + } + } + + + private void StateValidateCanDelete(WorkOrderState obj) + { + if (obj == null) + { + AddError(ApiErrorCode.NOT_FOUND, "id"); + return; + } + + //re-check rights here necessary due to traversal delete from Principle object + if (!Authorized.HasDeleteRole(CurrentUserRoles, AyaType.WorkOrderStatus)) + { + AddError(ApiErrorCode.NOT_AUTHORIZED); + return; + } + } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task StateHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderState o = (WorkOrderState)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + #endregion work order STATE level + + /* ██╗████████╗███████╗███╗ ███╗███████╗ ██║╚══██╔══╝██╔════╝████╗ ████║██╔════╝ @@ -630,7 +857,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItem, AyaEvent.Created), ct); await ItemSearchIndexAsync(newObject, true); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await ItemHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -707,7 +934,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItem, AyaEvent.Modified), ct); await ItemSearchIndexAsync(dbObject, false); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await ItemHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -778,7 +1005,7 @@ namespace AyaNova.Biz //all good do the commit if it's ours if (parentTransaction == null) await transaction.CommitAsync(); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await ItemHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); } catch { @@ -862,6 +1089,45 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Notes).AddText(obj.Wiki).AddText(obj.Tags).AddCustomFields(obj.CustomFields); return SearchParams; } + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task ItemHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItem o = (WorkOrderItem)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + + #endregion work order item level @@ -899,7 +1165,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemExpense, AyaEvent.Created), ct); await ExpenseSearchIndexAsync(newObject, true); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await ExpenseHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -960,7 +1226,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemExpense, AyaEvent.Modified), ct); await ExpenseSearchIndexAsync(dbObject, false); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await ExpenseHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -981,7 +1247,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemExpense, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await ExpenseHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -1031,7 +1297,6 @@ namespace AyaNova.Biz } } - ////////////////////////////////////////////// //INDEXING // @@ -1055,6 +1320,42 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Description).AddText(obj.Name); return SearchParams; } + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task ExpenseHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemExpense o = (WorkOrderItemExpense)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications #endregion work order item EXPENSE level @@ -1092,7 +1393,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemLabor, AyaEvent.Created), ct); await LaborSearchIndexAsync(newObject, true); // await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await LaborHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -1153,7 +1454,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemLabor, AyaEvent.Modified), ct); await LaborSearchIndexAsync(dbObject, false); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await LaborHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -1174,7 +1475,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemLabor, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await LaborHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -1248,6 +1549,43 @@ namespace AyaNova.Biz SearchParams.AddText(obj.ServiceDetails); return SearchParams; } + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task LaborHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemLabor o = (WorkOrderItemLabor)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + #endregion work order item LABOR level @@ -1284,7 +1622,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemLoan, AyaEvent.Created), ct); await LoanSearchIndexAsync(newObject, true); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await LoanHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -1345,7 +1683,7 @@ namespace AyaNova.Biz 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 HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await LoanHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -1366,7 +1704,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemLoan, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await LoanHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -1440,6 +1778,46 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Notes); return SearchParams; } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task LoanHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemLoan o = (WorkOrderItemLoan)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + #endregion work order item LOAN level @@ -1484,7 +1862,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemOutsideService, AyaEvent.Created), ct); await OutsideServiceSearchIndexAsync(newObject, true); // await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await OutsideServiceHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -1544,7 +1922,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemOutsideService, AyaEvent.Modified), ct); await OutsideServiceSearchIndexAsync(dbObject, false); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await OutsideServiceHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -1565,7 +1943,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemOutsideService, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await OutsideServiceHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -1639,6 +2017,45 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Notes).AddText(obj.RMANumber).AddText(obj.TrackingNumber); return SearchParams; } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task OutsideServiceHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemOutsideService o = (WorkOrderItemOutsideService)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + #endregion work order item OUTSIDE SERVICE level @@ -1737,7 +2154,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemPart, AyaEvent.Modified), ct); await PartSearchIndexAsync(dbObject, false); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await PartHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -1758,7 +2175,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPart, ct); // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await PartHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -1829,6 +2246,47 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Description).AddText(obj.Serials); return SearchParams; } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task PartHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemPart o = (WorkOrderItemPart)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + + #endregion work order item PARTS level @@ -1866,7 +2324,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemPartRequest, AyaEvent.Created), ct); //await PartRequestSearchIndexAsync(newObject, true); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await PartRequestHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -1927,7 +2385,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemPartRequest, AyaEvent.Modified), ct); // await PartRequestSearchIndexAsync(dbObject, false); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await PartRequestHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -1948,7 +2406,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemPartRequest, ct); // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await PartRequestHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -1999,31 +2457,44 @@ namespace AyaNova.Biz } + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task PartRequestHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemPartRequest o = (WorkOrderItemPartRequest)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications - //### NOTE: Currently there is nothing to index, no text fields - // ////////////////////////////////////////////// - // //INDEXING - // // - // private async Task PartRequestSearchIndexAsync(WorkOrderItemPartRequest obj, bool isNew) - // { - // //SEARCH INDEXING - // var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, AyaType.WorkOrderItemPartRequest); - // SearchParams.AddText(obj.).AddText(obj.Tags).AddCustomFields(obj.CustomFields); - // if (isNew) - // await Search.ProcessNewObjectKeywordsAsync(SearchParams); - // else - // await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams); - // } - // public async Task PartRequestGetSearchResultSummary(long id) - // { - // var obj = await ct.WorkOrderItemPartRequest.SingleOrDefaultAsync(z => z.Id == id); - // var SearchParams = new Search.SearchIndexProcessObjectParameters(); - // if (obj != null) - // SearchParams.AddText(obj.Notes).AddText(obj.Tags).AddCustomFields(obj.CustomFields); - // return SearchParams; - // } #endregion work order item PART REQUEST level @@ -2061,7 +2532,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemScheduledUser, AyaEvent.Created), ct); //await ScheduledUserSearchIndexAsync(newObject, true); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await ScheduledUserHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -2122,7 +2593,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemScheduledUser, AyaEvent.Modified), ct); // await ScheduledUserSearchIndexAsync(dbObject, false); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await ScheduledUserHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -2143,7 +2614,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemScheduledUser, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await ScheduledUserHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2194,31 +2665,45 @@ namespace AyaNova.Biz } - //### CUrrently nothing to index as no text fields to search - // ////////////////////////////////////////////// - // //INDEXING - // // - // private async Task ScheduledUserSearchIndexAsync(WorkOrderItemScheduledUser obj, bool isNew) - // { - // //SEARCH INDEXING - // var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, AyaType.WorkOrderItemScheduledUser); - // SearchParams.AddText(obj.).AddText(obj.Tags).AddCustomFields(obj.CustomFields); + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task ScheduledUserHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemScheduledUser o = (WorkOrderItemScheduledUser)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + - // if (isNew) - // await Search.ProcessNewObjectKeywordsAsync(SearchParams); - // else - // await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams); - // } - // public async Task ScheduledUserGetSearchResultSummary(long id) - // { - // var obj = await ct.WorkOrderItemScheduledUser.SingleOrDefaultAsync(z => z.Id == id); - // var SearchParams = new Search.SearchIndexProcessObjectParameters(); - // if (obj != null) - // SearchParams.AddText(obj.Notes).AddText(obj.Tags).AddCustomFields(obj.CustomFields); - // return SearchParams; - // } #endregion work order item SCHEDULED USER level @@ -2256,7 +2741,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemTask, AyaEvent.Created), ct); await TaskSearchIndexAsync(newObject, true); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await TaskHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -2317,7 +2802,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemTask, AyaEvent.Modified), ct); await TaskSearchIndexAsync(dbObject, false); // await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await TaskHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -2338,7 +2823,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTask, ct); //await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await TaskHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2412,6 +2897,45 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Task); return SearchParams; } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task TaskHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemTask o = (WorkOrderItemTask)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + #endregion work order item TASK level @@ -2449,7 +2973,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemTravel, AyaEvent.Created), ct); await TravelSearchIndexAsync(newObject, true); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await TravelHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -2510,7 +3034,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemTravel, AyaEvent.Modified), ct); await TravelSearchIndexAsync(dbObject, false); //await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await TravelHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -2531,7 +3055,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemTravel, ct); // await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await TravelHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2605,6 +3129,45 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Notes).AddText(obj.TravelDetails); return SearchParams; } + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task TravelHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemTravel o = (WorkOrderItemTravel)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + #endregion work order item LABOR level @@ -2642,7 +3205,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderItemUnit, AyaEvent.Created), ct); await UnitSearchIndexAsync(newObject, true); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newObject.Tags, null); - await HandlePotentialNotificationEvent(AyaEvent.Created, newObject); + await UnitHandlePotentialNotificationEvent(AyaEvent.Created, newObject); return newObject; } } @@ -2702,7 +3265,7 @@ namespace AyaNova.Biz await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObject.Id, AyaType.WorkOrderItemUnit, AyaEvent.Modified), ct); await UnitSearchIndexAsync(dbObject, false); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); - await HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); + await UnitHandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); return dbObject; } @@ -2723,7 +3286,7 @@ namespace AyaNova.Biz await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, AyaType.WorkOrderItemUnit, ct); await TagBiz.ProcessDeleteTagsInRepositoryAsync(ct, dbObject.Tags); await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct); - await HandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); + await UnitHandlePotentialNotificationEvent(AyaEvent.Deleted, dbObject); return true; } @@ -2797,6 +3360,47 @@ namespace AyaNova.Biz SearchParams.AddText(obj.Notes).AddText(obj.Tags).AddCustomFields(obj.CustomFields); return SearchParams; } + + + + //////////////////////////////////////////////////////////////////////////////////////////////// + // NOTIFICATION PROCESSING + // + public async Task UnitHandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) + { + ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); + if (ServerBootConfig.SEEDING) return; + log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{proposedObj.AyaType}, AyaEvent:{ayaEvent}]"); + + bool isNew = currentObj == null; + + + //STANDARD EVENTS FOR ALL OBJECTS + await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct); + + //SPECIFIC EVENTS FOR THIS OBJECT + WorkOrderItemUnit o = (WorkOrderItemUnit)proposedObj; + + //## DELETED EVENTS + //any event added below needs to be removed, so + //just blanket remove any event for this object of eventtype that would be added below here + //do it regardless any time there's an update and then + //let this code below handle the refreshing addition that could have changes + // await NotifyEventHelper.ClearPriorEventsForObject(ct, proposedObj.AyaType, o.Id, NotifyEventType.ContractExpiring); + + + //## CREATED / MODIFIED EVENTS + if (ayaEvent == AyaEvent.Created || ayaEvent == AyaEvent.Modified) + { + + //todo: fix etc, tons of shit here incoming + + } + + }//end of process notifications + + + #endregion work order item LABOR level diff --git a/server/AyaNova/models/AyContext.cs b/server/AyaNova/models/AyContext.cs index dc7cd293..322c518a 100644 --- a/server/AyaNova/models/AyContext.cs +++ b/server/AyaNova/models/AyContext.cs @@ -77,6 +77,7 @@ namespace AyaNova.Models //WorkOrder public virtual DbSet WorkOrder { get; set; } public virtual DbSet WorkOrderItem { get; set; } + public virtual DbSet WorkOrderState { get; set; } public virtual DbSet WorkOrderItemExpense { get; set; } public virtual DbSet WorkOrderItemLabor { get; set; } public virtual DbSet WorkOrderItemLoan { get; set; } diff --git a/server/AyaNova/models/WorkOrderState.cs b/server/AyaNova/models/WorkOrderState.cs index 19dcc149..c570127b 100644 --- a/server/AyaNova/models/WorkOrderState.cs +++ b/server/AyaNova/models/WorkOrderState.cs @@ -1,10 +1,12 @@ -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Newtonsoft.Json; +using AyaNova.Biz; namespace AyaNova.Models { - public class WorkOrderState + public class WorkOrderState : ICoreBizObjectModel { public long Id { get; set; } public uint Concurrency { get; set; } @@ -17,5 +19,8 @@ namespace AyaNova.Models [Required] public long UserId { get; set; } + [NotMapped, JsonIgnore] + public AyaType AyaType { get => AyaType.WorkOrderStatus; } + }//eoc }//eons