case 4232
This commit is contained in:
@@ -15,6 +15,7 @@ See the [upgrade instructions](ops-upgrade.md) section of this manual for detail
|
|||||||
#### Fixed
|
#### Fixed
|
||||||
|
|
||||||
- UI,Server: Unit Model form implemented "Workorders", "Quotes", "Preventive Maintenance" menu items features to view list of those items for the open Unit Model
|
- UI,Server: Unit Model form implemented "Workorders", "Quotes", "Preventive Maintenance" menu items features to view list of those items for the open Unit Model
|
||||||
|
- Server: Work order, Quote some Roles _with_ Role permission to do so would incorrecty get permission denied when changing status and saving
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using System.Linq;
|
|||||||
using System;
|
using System;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using EnumsNET;
|
||||||
|
|
||||||
namespace AyaNova.Biz
|
namespace AyaNova.Biz
|
||||||
{
|
{
|
||||||
@@ -1711,7 +1712,9 @@ namespace AyaNova.Biz
|
|||||||
//
|
//
|
||||||
internal async Task<WorkOrderState> StateCreateAsync(WorkOrderState newObject)
|
internal async Task<WorkOrderState> StateCreateAsync(WorkOrderState newObject)
|
||||||
{
|
{
|
||||||
await StateValidateAsync(newObject, null);
|
//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)
|
if (HasErrors)
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
@@ -1719,17 +1722,36 @@ namespace AyaNova.Biz
|
|||||||
if (newObject.UserId == 0)
|
if (newObject.UserId == 0)
|
||||||
newObject.UserId = UserId;
|
newObject.UserId = UserId;
|
||||||
|
|
||||||
await ct.WorkOrderState.AddAsync(newObject);
|
|
||||||
var wo = await ct.WorkOrder.FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderId);
|
var wo = await ct.WorkOrder.FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderId);
|
||||||
var newStatusInfo = await ct.WorkOrderStatus.AsNoTracking().FirstOrDefaultAsync(x => x.Id == newObject.WorkOrderStatusId);
|
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", "User roles don't align with status Remove roles");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//Can the new role be selected by this user?
|
||||||
|
if (CurrentUserRoles.HasAnyFlags(NewStatusInfo.SelectRoles) == false)
|
||||||
|
{
|
||||||
|
AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "User roles don't align with status Select roles");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//Seems legit, we'll allow it
|
||||||
|
|
||||||
|
await ct.WorkOrderState.AddAsync(newObject);
|
||||||
//Set duration to completed in workorder header
|
//Set duration to completed in workorder header
|
||||||
//Clear it if set and not completed state
|
//Clear it if set and not completed state
|
||||||
//or
|
//or
|
||||||
//Set it if not set and completed state
|
//Set it if not set and completed state
|
||||||
if (newStatusInfo.Completed && wo.DurationToCompleted == TimeSpan.Zero)
|
if (NewStatusInfo.Completed && wo.DurationToCompleted == TimeSpan.Zero)
|
||||||
wo.DurationToCompleted = DateTime.UtcNow - wo.CreatedDate;
|
wo.DurationToCompleted = DateTime.UtcNow - wo.CreatedDate;
|
||||||
else if (wo.DurationToCompleted != TimeSpan.Zero && !newStatusInfo.Completed)
|
else if (wo.DurationToCompleted != TimeSpan.Zero && !NewStatusInfo.Completed)
|
||||||
wo.DurationToCompleted = TimeSpan.Zero;
|
wo.DurationToCompleted = TimeSpan.Zero;
|
||||||
wo.LastStatusId = newObject.WorkOrderStatusId;
|
wo.LastStatusId = newObject.WorkOrderStatusId;
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
@@ -1806,10 +1828,14 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//VALIDATION
|
//VALIDATION
|
||||||
//
|
//
|
||||||
private async Task StateValidateAsync(WorkOrderState proposedObj, WorkOrderState currentObj)
|
//NOTE: states are only ever *added* to a work order when validation is called
|
||||||
|
//never deleted, there is deeper validation needed for states related to roles etc
|
||||||
|
//so this validation just does the preliminary check to see if a change of state is even possible
|
||||||
|
//before further processing inside the actual update code in the caller
|
||||||
|
//
|
||||||
|
private async Task StatePreliminaryValidateCanAddAsync(WorkOrderState proposedObj)
|
||||||
{
|
{
|
||||||
|
|
||||||
//of all restricted users, only a restricted tech can change status
|
//of all restricted users, only a restricted tech can change status
|
||||||
if (UserIsSubContractorFull || UserIsSubContractorRestricted)
|
if (UserIsSubContractorFull || UserIsSubContractorRestricted)
|
||||||
{
|
{
|
||||||
@@ -1817,9 +1843,6 @@ namespace AyaNova.Biz
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//run validation and biz rules
|
|
||||||
bool isNew = currentObj == null;
|
|
||||||
|
|
||||||
//does it have a valid workorder id
|
//does it have a valid workorder id
|
||||||
if (proposedObj.WorkOrderId == 0)
|
if (proposedObj.WorkOrderId == 0)
|
||||||
AddError(ApiErrorCode.VALIDATION_REQUIRED, "WorkOrderId");
|
AddError(ApiErrorCode.VALIDATION_REQUIRED, "WorkOrderId");
|
||||||
@@ -1827,6 +1850,8 @@ namespace AyaNova.Biz
|
|||||||
{
|
{
|
||||||
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderId");
|
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderId");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -7047,7 +7072,7 @@ namespace AyaNova.Biz
|
|||||||
return mCurrentWorkOrderStatus;
|
return mCurrentWorkOrderStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ namespace AyaNova.Models
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool LastStateLockedViz { get; set; }
|
public bool LastStateLockedViz { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool IsCompleteRecord { get; set; } = true;//indicates if some items were removed due to user role / type restrictions (i.e. woitems they are not scheduled on)
|
public bool IsCompleteRecord { get; set; } = true;//indicates if some items were removed due to user role / type restrictions (i.e. woitems they are not scheduled on)
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ namespace AyaNova.Models
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool LockedViz { get; set; }
|
public bool LockedViz { get; set; }
|
||||||
|
|
||||||
|
|
||||||
//workaround for notification
|
//workaround for notification
|
||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public List<string> Tags { get; set; } = new List<string>();
|
public List<string> Tags { get; set; } = new List<string>();
|
||||||
|
|||||||
Reference in New Issue
Block a user