From f7e2f5c5acd2f6c5e7f919056290a296098f013d Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Mon, 12 Jul 2021 19:28:18 +0000 Subject: [PATCH] --- .vscode/launch.json | 2 +- docs/8.0/ayanova/docs/api-response-format.md | 2 +- docs/8.0/ayanova/docs/ops-backup.md | 4 +- server/AyaNova/biz/BizRoles.cs | 2 +- server/AyaNova/biz/PrimeData.cs | 2 +- server/AyaNova/biz/ReviewBiz.cs | 2 +- server/AyaNova/biz/ServiceBankBiz.cs | 2 +- server/AyaNova/biz/WorkOrderBiz.cs | 69 ++++++++++++++++++-- server/AyaNova/models/WorkOrderItemLabor.cs | 2 + server/AyaNova/util/DbUtil.cs | 10 +-- 10 files changed, 80 insertions(+), 17 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 03869ca9..2d033870 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -53,7 +53,7 @@ "AYANOVA_FOLDER_USER_FILES": "c:\\temp\\RavenTestData\\userfiles", "AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles", "AYANOVA_FOLDER_TEMPORARY_SERVER_FILES": "c:\\temp\\RavenTestData\\tempfiles", - "AYANOVA_SERVER_TEST_MODE": "false", + "AYANOVA_SERVER_TEST_MODE": "true", "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "large", "AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-7", "AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_13\\bin\\" diff --git a/docs/8.0/ayanova/docs/api-response-format.md b/docs/8.0/ayanova/docs/api-response-format.md index 66e182b4..d6812ecf 100644 --- a/docs/8.0/ayanova/docs/api-response-format.md +++ b/docs/8.0/ayanova/docs/api-response-format.md @@ -64,7 +64,7 @@ Response: "v": true }, { - "v": "Doug Effertz 17 - OpsAdminFull", + "v": "Doug Effertz 17 - OpsAdmin", "i": 18 } ], diff --git a/docs/8.0/ayanova/docs/ops-backup.md b/docs/8.0/ayanova/docs/ops-backup.md index 2526a463..cfbab009 100644 --- a/docs/8.0/ayanova/docs/ops-backup.md +++ b/docs/8.0/ayanova/docs/ops-backup.md @@ -4,8 +4,8 @@ ROLES AND RIGHTS: Modify automated backup settings Trigger backup DownloadBackup file - OpsFull + Ops View Backup settings - OpsFull, opslimited + Ops, opsrestricted diff --git a/server/AyaNova/biz/BizRoles.cs b/server/AyaNova/biz/BizRoles.cs index 2428ea1b..3ed044cb 100644 --- a/server/AyaNova/biz/BizRoles.cs +++ b/server/AyaNova/biz/BizRoles.cs @@ -793,7 +793,7 @@ namespace AyaNova.Biz // roles.Add(AyaType.FormCustom, new BizRoleSet() { - //Only BizAdminFull can modify forms + //Only BizAdmin can modify forms Change = AuthorizationRoles.BizAdmin, //Anyone can read it because they need to to open a form, but also in UI //only the BizAdminRestricted actually gets a link to see the customization page diff --git a/server/AyaNova/biz/PrimeData.cs b/server/AyaNova/biz/PrimeData.cs index 435ed7e5..81b4034c 100644 --- a/server/AyaNova/biz/PrimeData.cs +++ b/server/AyaNova/biz/PrimeData.cs @@ -25,7 +25,7 @@ namespace AyaNova.Biz u.Salt = Hasher.GenerateSalt(); u.Login = "superuser"; u.Password = Hasher.hash(u.Salt, "l3tm3in"); - u.Roles = AuthorizationRoles.All;//AuthorizationRoles.BizAdminFull | AuthorizationRoles.OpsAdminFull | AuthorizationRoles.ServiceFull | AuthorizationRoles.InventoryFull; + u.Roles = AuthorizationRoles.All; u.UserType = UserType.NotService; diff --git a/server/AyaNova/biz/ReviewBiz.cs b/server/AyaNova/biz/ReviewBiz.cs index b4ca2c53..182c1966 100644 --- a/server/AyaNova/biz/ReviewBiz.cs +++ b/server/AyaNova/biz/ReviewBiz.cs @@ -227,7 +227,7 @@ namespace AyaNova.Biz private async Task ValidateAsync(Review proposedObj, Review currentObj) { /* - - RULE Roles: BizAdminFull, ServiceFull, InventoryFull, Accounting, SalesFull can create and assign to anyone else. + - RULE Roles: BizAdmin, Service, Inventory, Accounting, Sales can create and assign to anyone else. - RULE Any other inside role can create for themselves only. (outside roles have no rights to this object so no need to check) - RULE Restricted roles can only set completed date and enter completion notes not otherwise change or create or delete. - BIZ RULE users with more than restricted roles can assign other users diff --git a/server/AyaNova/biz/ServiceBankBiz.cs b/server/AyaNova/biz/ServiceBankBiz.cs index 760ff3bf..e4cfd912 100644 --- a/server/AyaNova/biz/ServiceBankBiz.cs +++ b/server/AyaNova/biz/ServiceBankBiz.cs @@ -27,7 +27,7 @@ // if (httpContext != null) // return new ServiceBankBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items)); // else -// return new ServiceBankBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdminFull); +// return new ServiceBankBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin); // } // //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/server/AyaNova/biz/WorkOrderBiz.cs b/server/AyaNova/biz/WorkOrderBiz.cs index 0f2f835d..51738ab1 100644 --- a/server/AyaNova/biz/WorkOrderBiz.cs +++ b/server/AyaNova/biz/WorkOrderBiz.cs @@ -17,7 +17,6 @@ namespace AyaNova.Biz internal class WorkOrderBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject { // //Feature specific roles - // internal static AuthorizationRoles RolesAllowedToChangeSerial = AuthorizationRoles.BizAdminFull | AuthorizationRoles.ServiceFull | AuthorizationRoles.AccountingFull; internal WorkOrderBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles) { @@ -2150,6 +2149,9 @@ namespace AyaNova.Biz } } + if (string.IsNullOrWhiteSpace(proposedObj.Notes))//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Notes"); + //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItem.ToString()); if (FormCustomization != null) @@ -3022,6 +3024,24 @@ namespace AyaNova.Biz } + //Start date AND end date must both be null or both contain values + if (proposedObj.ServiceStartDate == null && proposedObj.ServiceStopDate != null) + AddError(ApiErrorCode.VALIDATION_REQUIRED, "ServiceStartDate"); + + if (proposedObj.ServiceStartDate != null && proposedObj.ServiceStopDate == null) + AddError(ApiErrorCode.VALIDATION_REQUIRED, "ServiceStopDate"); + + //Start date before end date + if (proposedObj.ServiceStartDate != null && proposedObj.ServiceStopDate != null) + if (proposedObj.ServiceStartDate > proposedObj.ServiceStopDate) + AddError(ApiErrorCode.VALIDATION_STARTDATE_AFTER_ENDDATE, "ServiceStartDate"); + + if (proposedObj.ServiceRateQuantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "ServiceRateQuantity"); + + if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItemLabor.ToString()); if (FormCustomization != null) @@ -3399,6 +3419,8 @@ namespace AyaNova.Biz if (proposedObj.LoanUnitId < 1 || !await ct.LoanUnit.AnyAsync(x => x.Id == proposedObj.LoanUnitId)) AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "LoanUnitId"); + if (proposedObj.Quantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); //Any form customizations to validate? @@ -3714,6 +3736,7 @@ namespace AyaNova.Biz if (proposedObj.UnitId < 1 || !await ct.Unit.AnyAsync(x => x.Id == proposedObj.UnitId)) AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "UnitId"); + //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItemOutsideService.ToString()); if (FormCustomization != null) @@ -4440,9 +4463,17 @@ namespace AyaNova.Biz AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked")); return;//this is a completely disqualifying error } - } + if (!await BizObjectExistsInDatabase.ExistsAsync(AyaType.Part, proposedObj.PartId, ct)) + { + AddError(ApiErrorCode.NOT_FOUND, "PartId"); + return; + } + + if (proposedObj.Quantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); + //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItemPart.ToString()); if (FormCustomization != null) @@ -4692,9 +4723,18 @@ namespace AyaNova.Biz AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked")); return;//this is a completely disqualifying error } - } + if (!await BizObjectExistsInDatabase.ExistsAsync(AyaType.Part, proposedObj.PartId, ct)) + { + AddError(ApiErrorCode.NOT_FOUND, "PartId"); + return; + } + + if (proposedObj.Quantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Quantity"); + + //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItemPartRequest.ToString()); if (FormCustomization != null) @@ -4933,6 +4973,22 @@ namespace AyaNova.Biz } } + if (proposedObj.EstimatedQuantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "EstimatedQuantity"); + + + //Start date AND end date must both be null or both contain values + if (proposedObj.StartDate == null && proposedObj.StopDate != null) + AddError(ApiErrorCode.VALIDATION_REQUIRED, "StopDate"); + + if (proposedObj.StartDate != null && proposedObj.StopDate == null) + AddError(ApiErrorCode.VALIDATION_REQUIRED, "StopDate"); + + //Start date before end date + if (proposedObj.StartDate != null && proposedObj.StopDate != null) + if (proposedObj.StartDate > proposedObj.StopDate) + AddError(ApiErrorCode.VALIDATION_STARTDATE_AFTER_ENDDATE, "StartDate"); + //Scheduling conflict? if (!AyaNova.Util.ServerGlobalBizSettings.Cache.AllowScheduleConflicts && proposedObj.UserId != null @@ -5793,9 +5849,14 @@ namespace AyaNova.Biz AddError(ApiErrorCode.VALIDATION_NOT_CHANGEABLE, "generalerror", await Translate("WorkOrderErrorLocked")); return;//this is a completely disqualifying error } - } + if (proposedObj.TravelRateQuantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "TravelRateQuantity"); + + if (proposedObj.NoChargeQuantity < 0)//negative quantities are not allowed + AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "NoChargeQuantity"); + //Any form customizations to validate? var FormCustomization = await ct.FormCustom.AsNoTracking().SingleOrDefaultAsync(z => z.FormKey == AyaType.WorkOrderItemTravel.ToString()); if (FormCustomization != null) diff --git a/server/AyaNova/models/WorkOrderItemLabor.cs b/server/AyaNova/models/WorkOrderItemLabor.cs index 6b2a6a7f..53ae16d2 100644 --- a/server/AyaNova/models/WorkOrderItemLabor.cs +++ b/server/AyaNova/models/WorkOrderItemLabor.cs @@ -22,7 +22,9 @@ namespace AyaNova.Models [NotMapped] public string ServiceRateViz { get; set; } public string ServiceDetails { get; set; } + [Required] public decimal ServiceRateQuantity { get; set; } + [Required] public decimal NoChargeQuantity { get; set; } //public long? ServiceBankId { get; set; } public long? TaxCodeSaleId { get; set; } diff --git a/server/AyaNova/util/DbUtil.cs b/server/AyaNova/util/DbUtil.cs index dd133dc0..62d5d37f 100644 --- a/server/AyaNova/util/DbUtil.cs +++ b/server/AyaNova/util/DbUtil.cs @@ -529,7 +529,7 @@ namespace AyaNova.Util /////////////////////////////////////////// // Check if DB has evaluation user accounts - // CALLED BY by login ping from licent via notify controller + // CALLED BY by login ping from client via notify controller internal static async Task DBHasTrialUsersAsync(AyContext ct, ILogger _log) { _log.LogDebug("DB trial users presence check"); @@ -539,11 +539,11 @@ namespace AyaNova.Util //just check for a few for testing if (await ct.User.AsNoTracking() .Where(z => - z.Login == "BizAdminFull" || - z.Login == "ServiceFull" || - z.Login == "InventoryFull" || + z.Login == "BizAdmin" || + z.Login == "Service" || + z.Login == "Inventory" || z.Login == "Accounting" || - z.Login == "TechFull" + z.Login == "Tech" ).LongCountAsync() < 5) return false; return true;