This commit is contained in:
2021-04-01 18:24:27 +00:00
parent 6e03ff7bf0
commit f222c9d4e2
5 changed files with 178 additions and 36 deletions

View File

@@ -12,21 +12,11 @@ using System.Collections.Generic;
namespace AyaNova.Biz namespace AyaNova.Biz
{ {
/* /*
############### ###############
MUST be able to update any section at any level independantly todo: Don't all *child items require a transaction to be passed for *any* crud op, i.e. including put and etc?
Fetch must be able to get entire graph or from any level down or single header only as required As they might be called from a parent transaction?
probably need a woheaderfetch route separately (wait until front end to decide this and do some testing etc grok it out)
*/
TODO: Routes then front end stuff can start and may god have mercy on my soul! ;)
todo: Don't all *child items require a transaction to be passed for *any* crud op, i.e. including put and etc?
As they might be called from a parent transaction?
(wait until front end to decide this and do some testing etc grok it out)
*/
internal class WorkOrderBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject internal class WorkOrderBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject
{ {
@@ -173,6 +163,8 @@ namespace AyaNova.Biz
return null; return null;
} }
putObject.Tags = TagBiz.NormalizeTags(putObject.Tags); putObject.Tags = TagBiz.NormalizeTags(putObject.Tags);
putObject.CustomFields = JsonUtil.CompactJson(putObject.CustomFields); putObject.CustomFields = JsonUtil.CompactJson(putObject.CustomFields);
await WorkOrderValidateAsync(putObject, dbObject); await WorkOrderValidateAsync(putObject, dbObject);
@@ -350,6 +342,19 @@ namespace AyaNova.Biz
//Check state if updatable right now //Check state if updatable right now
if (!isNew)
{
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if (CurrentWoStatus.Locked)
{
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
}
/* /*
@@ -1056,6 +1061,19 @@ namespace AyaNova.Biz
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderId");
} }
//Check state if updatable right now
if (!isNew)
{
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if (CurrentWoStatus.Locked)
{
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
}
//Any form customizations to validate? //Any form customizations to validate?
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItem.ToString()); var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItem.ToString());
if (FormCustomization != null) if (FormCustomization != null)
@@ -1293,6 +1311,20 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
//Check state if updatable right now
if (!isNew)
{
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if (CurrentWoStatus.Locked)
{
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
}
//Any form customizations to validate? //Any form customizations to validate?
var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItemExpense.ToString()); var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItemExpense.ToString());
if (FormCustomization != null) if (FormCustomization != null)
@@ -1530,6 +1562,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -1769,6 +1812,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -2020,6 +2074,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -2261,6 +2326,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -2476,6 +2552,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -2692,6 +2779,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -2932,6 +3030,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -3173,6 +3282,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -3414,6 +3534,17 @@ namespace AyaNova.Biz
else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId)) else if (!await ItemExistsAsync(proposedObj.WorkOrderItemId))
{ {
AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId"); AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "WorkOrderItemId");
}
//Check state if updatable right now
if(!isNew){
//Front end is coded to save the state first before any other updates if it has changed and it would not be
//a part of this header update so it's safe to check it here as it will be most up to date
var CurrentWoStatus = await GetCurrentWorkOrderStatusFromRelatedAsync(proposedObj.AyaType, proposedObj.Id);
if(CurrentWoStatus.Locked){
AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked"));
return;//this is a completely disqualifying error
}
} }
//Any form customizations to validate? //Any form customizations to validate?
@@ -3606,12 +3737,17 @@ namespace AyaNova.Biz
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
//GET UPDATEABLE STATUS FOR WORKORDER FROM DESCENDANT //GET CURRENT STATUS FOR WORKORDER FROM RELATIVE
// //
internal async Task<WorkOrderStatus> GetCurrentWorkOrderStatusFromRelatedAsync(AyaType ayaType, long id)
{
//instantiated method to save adding the context
return await GetCurrentWorkOrderStatusFromRelatedAsync(ayaType, id, ct);
}
internal static async Task<WorkOrderStatus> GetCurrentWorkOrderStatusFromRelatedAsync(AyaType ayaType, long id, AyContext ct) internal static async Task<WorkOrderStatus> GetCurrentWorkOrderStatusFromRelatedAsync(AyaType ayaType, long id, AyContext ct)
{ {
//static method
long WoId = await GetWorkOrderIdFromRelativeAsync(ayaType, id, ct); long WoId = await GetWorkOrderIdFromRelativeAsync(ayaType, id, ct);
return await ct.WorkOrderState.AsNoTracking() return await ct.WorkOrderState.AsNoTracking()
.Include(z => z.WorkOrderStatus) .Include(z => z.WorkOrderStatus)
.Where(z => z.WorkOrderId == WoId) .Where(z => z.WorkOrderId == WoId)
@@ -3619,8 +3755,10 @@ namespace AyaNova.Biz
.Select(z => z.WorkOrderStatus) .Select(z => z.WorkOrderStatus)
.Take(1) .Take(1)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
} }
#endregion utility #endregion utility

View File

@@ -2184,5 +2184,6 @@
"NextPONumber":"Nächste Bestellung", "NextPONumber":"Nächste Bestellung",
"NextQuoteNumber":"Nächste Angebotsnummer", "NextQuoteNumber":"Nächste Angebotsnummer",
"NextWorkorderNumber":"Nächster Arbeitsauftrag", "NextWorkorderNumber":"Nächster Arbeitsauftrag",
"NextPMNumber":"Nächste vorbeugende Wartung" "NextPMNumber":"Nächste vorbeugende Wartung",
"WorkOrderErrorLocked": "Der Arbeitsauftrag ist derzeit gesperrt und kann nicht geändert werden"
} }

View File

@@ -1625,8 +1625,8 @@
"WorkOrderStatusColor": "Color", "WorkOrderStatusColor": "Color",
"WorkOrderStatusSelectRoles": "Who can select", "WorkOrderStatusSelectRoles": "Who can select",
"WorkOrderStatusRemoveRoles": "Who can remove", "WorkOrderStatusRemoveRoles": "Who can remove",
"WorkOrderStatusCompleted":"Is a completed status", "WorkOrderStatusCompleted": "Is a completed status",
"WorkOrderStatusLocked":"Is a locking status", "WorkOrderStatusLocked": "Is a locking status",
"WorkOrderStatusUnderlined": "Underlined", "WorkOrderStatusUnderlined": "Underlined",
"WorkOrderSummaryTemplate": "WorkOrder Item Summary Template", "WorkOrderSummaryTemplate": "WorkOrder Item Summary Template",
"WorkOrderSummaryWorkOrderItem": "WorkOrder Item Info To Display", "WorkOrderSummaryWorkOrderItem": "WorkOrder Item Info To Display",
@@ -2170,19 +2170,20 @@
"SaveACopy": "Save a copy", "SaveACopy": "Save a copy",
"ConfirmUpdatePartCost": "Update part cost from received cost?", "ConfirmUpdatePartCost": "Update part cost from received cost?",
"AlertNotes": "Alert notes", "AlertNotes": "Alert notes",
"AuthTwoFactor":"Two-Factor Authentication", "AuthTwoFactor": "Two-Factor Authentication",
"AuthConnectAppTitle": "Connect your app", "AuthConnectAppTitle": "Connect your app",
"AuthConnectAppSubTitle": "Using an authenticator app such as Google Authenticator, Duo, Microsoft Authenticator, Authy etc, scan the QR code. It will display a 6 digit pass code which you need to enter below.", "AuthConnectAppSubTitle": "Using an authenticator app such as Google Authenticator, Duo, Microsoft Authenticator, Authy etc, scan the QR code. It will display a 6 digit pass code which you need to enter below.",
"AuthConnectAppManualEntry":"Having trouble scanning the code? Enter the following manually into your authenticator app:", "AuthConnectAppManualEntry": "Having trouble scanning the code? Enter the following manually into your authenticator app:",
"AuthEnterPin":"Enter 6-digit code", "AuthEnterPin": "Enter 6-digit code",
"AuthPinInvalid":"Code not valid", "AuthPinInvalid": "Code not valid",
"AuthConnectCompleted":"Two-Factor authentication is now enabled", "AuthConnectCompleted": "Two-Factor authentication is now enabled",
"AuthDisableTwoFactor":"Disable Two-Factor authentication", "AuthDisableTwoFactor": "Disable Two-Factor authentication",
"AuthTwoFactorDisabled":"Two-Factor authentication is now disabled", "AuthTwoFactorDisabled": "Two-Factor authentication is now disabled",
"AuthVerifyCode":"Verify code", "AuthVerifyCode": "Verify code",
"GlobalNextSeeds":"Set next seed number", "GlobalNextSeeds": "Set next seed number",
"NextPONumber":"Next purchase order", "NextPONumber": "Next purchase order",
"NextQuoteNumber":"Next quote", "NextQuoteNumber": "Next quote",
"NextWorkorderNumber":"Next work order", "NextWorkorderNumber": "Next work order",
"NextPMNumber":"Next preventive maintenance" "NextPMNumber": "Next preventive maintenance",
"WorkOrderErrorLocked": "Work order is set to a locked status and can't be changed"
} }

View File

@@ -2184,5 +2184,6 @@
"NextPONumber":"Siguiente orden de compra", "NextPONumber":"Siguiente orden de compra",
"NextQuoteNumber":"Próxima cotización", "NextQuoteNumber":"Próxima cotización",
"NextWorkorderNumber":"Siguiente orden de trabajo", "NextWorkorderNumber":"Siguiente orden de trabajo",
"NextPMNumber":"Siguiente mantenimiento preventivo" "NextPMNumber":"Siguiente mantenimiento preventivo",
"WorkOrderErrorLocked": "La orden de trabajo está actualmente configurada en un estado bloqueado y no se puede cambiar"
} }

View File

@@ -2184,5 +2184,6 @@
"NextPONumber":"Prochaine commande d'achat", "NextPONumber":"Prochaine commande d'achat",
"NextQuoteNumber":"Numéro de devis suivant", "NextQuoteNumber":"Numéro de devis suivant",
"NextWorkorderNumber":"Bon de travail suivant", "NextWorkorderNumber":"Bon de travail suivant",
"NextPMNumber":"Prochaine maintenance préventive" "NextPMNumber":"Prochaine maintenance préventive",
"WorkOrderErrorLocked": "Le bon de travail est actuellement défini sur un statut verrouillé et ne peut pas être modifié"
} }