diff --git a/server/AyaNova/biz/QuoteBiz.cs b/server/AyaNova/biz/QuoteBiz.cs index 8b51176d..3d512744 100644 --- a/server/AyaNova/biz/QuoteBiz.cs +++ b/server/AyaNova/biz/QuoteBiz.cs @@ -1131,45 +1131,49 @@ namespace AyaNova.Biz // internal async Task StateCreateAsync(QuoteState newObject) { - await StatePreliminaryValidateCanAddAsync(newObject); - if (HasErrors) - return null; - else + using (var transaction = await ct.Database.BeginTransactionAsync())//case 4240 wrapped in transaction because header is updated as well as states collection so both need to be in sync { - - var quote = await ct.Quote.FirstOrDefaultAsync(x => x.Id == newObject.QuoteId); - var NewStatusInfo = await ct.QuoteStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == newObject.QuoteStatusId); - - QuoteStatus LastStatusInfo = null; - if (quote.LastStatusId != null) - LastStatusInfo = await ct.QuoteStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == quote.LastStatusId); - - //Level 2 validation - Quote status RemoveRoles, SelectRoles and User roles - - //If we have a last role, can it be removed by this User? - if (LastStatusInfo != null && CurrentUserRoles.HasAnyFlags(LastStatusInfo.RemoveRoles) == false) - { - AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:QuoteQuoteStatusType -> LT:RemoveRoles"); + await StatePreliminaryValidateCanAddAsync(newObject); + if (HasErrors) return null; - } - //Can the new role be selected by this user? - if (CurrentUserRoles.HasAnyFlags(NewStatusInfo.SelectRoles) == false) + else { - AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:QuoteQuoteStatusType -> LT:SelectRoles"); - return null; + + var quote = await ct.Quote.FirstOrDefaultAsync(x => x.Id == newObject.QuoteId); + var NewStatusInfo = await ct.QuoteStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == newObject.QuoteStatusId); + + QuoteStatus LastStatusInfo = null; + if (quote.LastStatusId != null) + LastStatusInfo = await ct.QuoteStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == quote.LastStatusId); + + //Level 2 validation - Quote status RemoveRoles, SelectRoles and User roles + + //If we have a last role, can it be removed by this User? + if (LastStatusInfo != null && CurrentUserRoles.HasAnyFlags(LastStatusInfo.RemoveRoles) == false) + { + AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:QuoteQuoteStatusType -> LT:RemoveRoles"); + return null; + } + //Can the new role be selected by this user? + if (CurrentUserRoles.HasAnyFlags(NewStatusInfo.SelectRoles) == false) + { + AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:QuoteQuoteStatusType -> LT:SelectRoles"); + return null; + } + //Seems legit, we'll allow it + + + + await ct.QuoteState.AddAsync(newObject); + quote.LastStatusId = newObject.QuoteStatusId; + await ct.SaveChangesAsync(); + newObject.NewQuoteConcurrency = quote.Concurrency; + + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.QuoteStatus, AyaEvent.Created), ct); + await transaction.CommitAsync(); + await StateHandlePotentialNotificationEvent(AyaEvent.Created, newObject); + return newObject; } - //Seems legit, we'll allow it - - - - await ct.QuoteState.AddAsync(newObject); - quote.LastStatusId = newObject.QuoteStatusId; - await ct.SaveChangesAsync(); - newObject.NewQuoteConcurrency = quote.Concurrency; - - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.QuoteStatus, AyaEvent.Created), ct); - await StateHandlePotentialNotificationEvent(AyaEvent.Created, newObject); - return newObject; } } diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 2ae45006..f6fbbc50 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -1712,54 +1712,59 @@ namespace AyaNova.Biz // internal async Task StateCreateAsync(WorkOrderState newObject) { - //first validate if this is even a possibility before getting into the further validation - //for roles can select, can remove etc - await StatePreliminaryValidateCanAddAsync(newObject); - if (HasErrors) - return null; - else + using (var transaction = await ct.Database.BeginTransactionAsync())//case 4240 wrapped in transaction because workorder header is updated as well as states collection so both need to be in sync { - if (newObject.UserId == 0) - newObject.UserId = UserId; - - var wo = await ct.WorkOrder.FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderId); - var NewStatusInfo = await ct.WorkOrderStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderStatusId); - WorkOrderStatus LastStatusInfo = null; - if (wo.LastStatusId != null) - LastStatusInfo = await ct.WorkOrderStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == wo.LastStatusId); - - //Level 2 validation - Work order status RemoveRoles, SelectRoles and User roles - - //If we have a last role, can it be removed by this User? - if (LastStatusInfo != null && CurrentUserRoles.HasAnyFlags(LastStatusInfo.RemoveRoles) == false) - { - AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:WorkOrderStatus -> LT:RemoveRoles"); + //first validate if this is even a possibility before getting into the further validation + //for roles can select, can remove etc + await StatePreliminaryValidateCanAddAsync(newObject); + if (HasErrors) return null; - } - //Can the new role be selected by this user? - if (CurrentUserRoles.HasAnyFlags(NewStatusInfo.SelectRoles) == false) + else { - AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:WorkOrderStatus -> LT:SelectRoles"); - return null; + if (newObject.UserId == 0) + newObject.UserId = UserId; + + var wo = await ct.WorkOrder.FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderId); + var NewStatusInfo = await ct.WorkOrderStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderStatusId); + WorkOrderStatus LastStatusInfo = null; + if (wo.LastStatusId != null) + LastStatusInfo = await ct.WorkOrderStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == wo.LastStatusId); + + //Level 2 validation - Work order status RemoveRoles, SelectRoles and User roles + + //If we have a last role, can it be removed by this User? + if (LastStatusInfo != null && CurrentUserRoles.HasAnyFlags(LastStatusInfo.RemoveRoles) == false) + { + AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:WorkOrderStatus -> LT:RemoveRoles"); + return null; + } + //Can the new role be selected by this user? + if (CurrentUserRoles.HasAnyFlags(NewStatusInfo.SelectRoles) == false) + { + AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "LT:WorkOrderStatus -> LT:SelectRoles"); + return null; + } + //Seems legit, we'll allow it + + + + await ct.WorkOrderState.AddAsync(newObject); + //Set duration to completed in workorder header + //Clear it if set and not completed state + //or + //Set it if not set and completed state + if (NewStatusInfo.Completed && wo.DurationToCompleted == TimeSpan.Zero) + wo.DurationToCompleted = DateTime.UtcNow - wo.CreatedDate; + else if (wo.DurationToCompleted != TimeSpan.Zero && !NewStatusInfo.Completed) + wo.DurationToCompleted = TimeSpan.Zero; + wo.LastStatusId = newObject.WorkOrderStatusId; + await ct.SaveChangesAsync(); + newObject.NewWOConcurrency = wo.Concurrency; + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderStatus, AyaEvent.Created), ct); + await transaction.CommitAsync(); + await StateHandlePotentialNotificationEvent(AyaEvent.Created, newObject); + return newObject; } - //Seems legit, we'll allow it - - await ct.WorkOrderState.AddAsync(newObject); - //Set duration to completed in workorder header - //Clear it if set and not completed state - //or - //Set it if not set and completed state - if (NewStatusInfo.Completed && wo.DurationToCompleted == TimeSpan.Zero) - wo.DurationToCompleted = DateTime.UtcNow - wo.CreatedDate; - else if (wo.DurationToCompleted != TimeSpan.Zero && !NewStatusInfo.Completed) - wo.DurationToCompleted = TimeSpan.Zero; - wo.LastStatusId = newObject.WorkOrderStatusId; - await ct.SaveChangesAsync(); - newObject.NewWOConcurrency = wo.Concurrency; - - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, AyaType.WorkOrderStatus, AyaEvent.Created), ct); - await StateHandlePotentialNotificationEvent(AyaEvent.Created, newObject); - return newObject; } }