diff --git a/docs/8.0/ayanova/docs/ay-biz-admin-roles.md b/docs/8.0/ayanova/docs/ay-biz-admin-roles.md index 619a99f8..16ba49e9 100644 --- a/docs/8.0/ayanova/docs/ay-biz-admin-roles.md +++ b/docs/8.0/ayanova/docs/ay-biz-admin-roles.md @@ -1,6 +1,6 @@ # Authorization roles -Authorization roles are used to control access to AyaNova business objects and features. Roles roughly follow typical job descriptions for various departments in a company who would use that role's features. +Authorization roles are used to control access to AyaNova business objects and features. Roles roughly follow typical job descriptions for various departments in a service company. There are a total of 17 roles available, 9 major roles and 8 'restricted' versions of most of the major roles which generally means read-only access to features and objects where the main role has full read/write access. @@ -90,6 +90,32 @@ This role is intended for the Sales department staff involved in selling service `Sales - restricted` read-only rights to the above Sales role items. +### Subcontractor + +This role is for service technicians that are contracted by the service company but are not employees, however it can be also be used for *employees* that are extremely restricted in what they can do or see in AyaNova (probationary or new employees). + +This role allows a User to perform service with the lowest possible access to any unrelated data to their job. They can be scheduled on work orders and view their own schedule only as well as enter the details of work they perform where they are one of the scheduled users. + +However they can not view any prices or costs or see any other details of a work order where they are not involved. + +See the [Low permission users](svc-workorders.md/#low-permission-users) section of the work order documentation for details. + +`Subcontractor - restricted` read-only rights to the above Subcontractor role items. + +### Technician + +This role is for service technicians that are employees of the service company. Technicians can view all items in the `Customer` navigation pane but not edit them. In the `Service` pane they have full read-write access to all areas of Service work orders with the exception of any Cost fields as well as full access to Customer Units, however they do not see any Quotes or Preventive Maintenance orders and have read-only access to Customer Service Requests, Loaner items and Projects. + +They are also permitted to view read-only `Vendors` and `Accounting` navigation pane items. + +`Service technician - restricted` - this role has similar restrictions to a `Subcontractor` role [above](#subcontractor) and this role is appropriate for less trusted, probationary or new staff service technicians. + +Where restricted service technicians *differ* from a Subcontractor is that they have a full `Home` navigation pane area the same as all inside staff Users so they can send and receive Memos and make reminders etc. + +Restricted service technicians access work orders for which they are scheduled from their `Schedule` navigation item in their `Home` navigation pane item. There are no other areas of AyaNova available to restricted technicians. + +TODO: MAKE THEM RESTRICTED TO OTHER AREAS SET ROLES + ## How to set roles Roles are set through the [user edit form](adm-users.md#authorization-roles). diff --git a/docs/8.0/ayanova/docs/svc-workorders.md b/docs/8.0/ayanova/docs/svc-workorders.md index b82cd5f7..02d2362d 100644 --- a/docs/8.0/ayanova/docs/svc-workorders.md +++ b/docs/8.0/ayanova/docs/svc-workorders.md @@ -61,7 +61,7 @@ docs / sections required * Costs to restricted users are not only hidden in work order user interface but are also sent as zeros in the data from the server * Cost restrictions also apply to reporting so a report with cost fields on it will show those values as zero if the current user is restricted from seeing costs -## Sub contractors / Technician - Restricted users and Work Orders +## Low permission users If a User is set to User type of Sub contractor or if they are a Service type user and are assigned the "Technician - Restricted" role then special limitations apply to them: * Service -> Work order list navigation pane area diff --git a/server/AyaNova/biz/BizRoles.cs b/server/AyaNova/biz/BizRoles.cs index 41295bc5..96b93679 100644 --- a/server/AyaNova/biz/BizRoles.cs +++ b/server/AyaNova/biz/BizRoles.cs @@ -41,11 +41,11 @@ namespace AyaNova.Biz { Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service - | AuthorizationRoles.Sales - | AuthorizationRoles.Tech + | AuthorizationRoles.Sales | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted + | AuthorizationRoles.Tech | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All @@ -59,11 +59,11 @@ namespace AyaNova.Biz Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales - | AuthorizationRoles.Tech | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted + | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -75,12 +75,12 @@ namespace AyaNova.Biz { Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service - | AuthorizationRoles.Tech | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | AuthorizationRoles.SalesRestricted + | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -93,11 +93,11 @@ namespace AyaNova.Biz Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Sales - | AuthorizationRoles.Tech | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.SalesRestricted + | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -109,12 +109,12 @@ namespace AyaNova.Biz { Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service - | AuthorizationRoles.Tech | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | AuthorizationRoles.SalesRestricted + | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -275,12 +275,12 @@ namespace AyaNova.Biz { Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service - | AuthorizationRoles.Tech | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | AuthorizationRoles.SalesRestricted + | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -377,13 +377,13 @@ namespace AyaNova.Biz // roles.Add(AyaType.UnitModel, new BizRoleSet() { - Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Tech | AuthorizationRoles.Accounting, - ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted, + Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Accounting, + ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | AuthorizationRoles.SalesRestricted | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); //////////////////////////////////////////////////////////// - //UnitMeterReading - same as unit + //UnitMeterReading // roles.Add(AyaType.UnitMeterReading, new BizRoleSet() { @@ -397,8 +397,8 @@ namespace AyaNova.Biz // roles.Add(AyaType.Vendor, new BizRoleSet() { - Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Tech | AuthorizationRoles.Accounting | AuthorizationRoles.Inventory, - ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | AuthorizationRoles.SalesRestricted | AuthorizationRoles.TechRestricted, + Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Accounting | AuthorizationRoles.Inventory, + ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | AuthorizationRoles.SalesRestricted | AuthorizationRoles.Tech | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -421,9 +421,9 @@ namespace AyaNova.Biz // roles.Add(AyaType.WorkOrderStatus, new BizRoleSet() { - Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Tech | AuthorizationRoles.SubContractor | AuthorizationRoles.Accounting, + Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | - AuthorizationRoles.SalesRestricted | AuthorizationRoles.SubContractorRestricted | AuthorizationRoles.TechRestricted, + AuthorizationRoles.SalesRestricted | AuthorizationRoles.SubContractorRestricted | AuthorizationRoles.Tech | AuthorizationRoles.SubContractor | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -432,9 +432,9 @@ namespace AyaNova.Biz // roles.Add(AyaType.WorkOrderItemStatus, new BizRoleSet() { - Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Tech | AuthorizationRoles.SubContractor | AuthorizationRoles.Accounting, + Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | - AuthorizationRoles.SalesRestricted | AuthorizationRoles.SubContractorRestricted | AuthorizationRoles.TechRestricted, + AuthorizationRoles.SalesRestricted | AuthorizationRoles.Tech | AuthorizationRoles.SubContractor | AuthorizationRoles.SubContractorRestricted | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -443,9 +443,9 @@ namespace AyaNova.Biz // roles.Add(AyaType.WorkOrderItemPriority, new BizRoleSet() { - Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Tech | AuthorizationRoles.SubContractor | AuthorizationRoles.Accounting, + Change = AuthorizationRoles.BizAdmin | AuthorizationRoles.Service | AuthorizationRoles.Accounting, ReadFullRecord = AuthorizationRoles.BizAdminRestricted | AuthorizationRoles.ServiceRestricted | AuthorizationRoles.Sales | - AuthorizationRoles.SalesRestricted | AuthorizationRoles.SubContractorRestricted | AuthorizationRoles.TechRestricted, + AuthorizationRoles.SalesRestricted | AuthorizationRoles.Tech | AuthorizationRoles.SubContractor | AuthorizationRoles.SubContractorRestricted | AuthorizationRoles.TechRestricted, Select = AuthorizationRoles.All }); @@ -1030,7 +1030,7 @@ namespace AyaNova.Biz //ONGOING VALIDATION TO CATCH MISMATCH WHEN NEW ROLES ADDED (wont' catch changes to existing unfortunately) - var lastRoles = "{\"Customer\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"CustomerNote\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"Contract\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"HeadOffice\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"LoanUnit\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"Part\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventory\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartWarehouse\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartAssembly\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PurchaseOrder\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequest\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRestock\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequestDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"Project\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"ServiceRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TravelRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TaxCode\":{\"Change\":66,\"ReadFullRecord\":98701,\"Select\":131071},\"Unit\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"UnitModel\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"UnitMeterReading\":{\"Change\":33098,\"ReadFullRecord\":65669,\"Select\":131071},\"Vendor\":{\"Change\":33130,\"ReadFullRecord\":65669,\"Select\":131071},\"TaskGroup\":{\"Change\":10,\"ReadFullRecord\":131071,\"Select\":131071},\"WorkOrderStatus\":{\"Change\":10,\"ReadFullRecord\":131071,\"Select\":131071},\"WorkOrderItemStatus\":{\"Change\":1354,\"ReadFullRecord\":105093,\"Select\":131071},\"WorkOrderItemPriority\":{\"Change\":1354,\"ReadFullRecord\":105093,\"Select\":131071},\"WorkOrder\":{\"Change\":1994,\"ReadFullRecord\":105093,\"Select\":131071},\"WorkOrderItem\":{\"Change\":330,\"ReadFullRecord\":105093,\"Select\":131071},\"WorkOrderItemExpense\":{\"Change\":458,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLabor\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLoan\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPart\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPartRequest\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemScheduledUser\":{\"Change\":330,\"ReadFullRecord\":99973,\"Select\":131071},\"WorkOrderItemTask\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemTravel\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemUnit\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemOutsideService\":{\"Change\":330,\"ReadFullRecord\":98437,\"Select\":131071},\"Quote\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItem\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemExpense\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLabor\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLoan\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemPart\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemScheduledUser\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTask\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTravel\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemUnit\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemOutsideService\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteStatus\":{\"Change\":32778,\"ReadFullRecord\":131071,\"Select\":131071},\"PM\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItem\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemExpense\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemLabor\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemLoan\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemPart\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemScheduledUser\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemTask\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemTravel\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemUnit\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"PMItemOutsideService\":{\"Change\":10,\"ReadFullRecord\":65541,\"Select\":131071},\"Global\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"GlobalOps\":{\"Change\":16384,\"ReadFullRecord\":8192,\"Select\":0},\"User\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"UserOptions\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"ServerState\":{\"Change\":16384,\"ReadFullRecord\":131071,\"Select\":0},\"License\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"TrialSeeder\":{\"Change\":16386,\"ReadFullRecord\":8193,\"Select\":0},\"LogFile\":{\"Change\":0,\"ReadFullRecord\":24576,\"Select\":0},\"Backup\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"FileAttachment\":{\"Change\":2,\"ReadFullRecord\":3,\"Select\":0},\"ServerJob\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"OpsNotificationSettings\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"ServerMetrics\":{\"Change\":16384,\"ReadFullRecord\":24576,\"Select\":0},\"Translation\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"DataListSavedFilter\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"FormUserOptions\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"FormCustom\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"PickListTemplate\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"BizMetrics\":{\"Change\":2,\"ReadFullRecord\":98369,\"Select\":0},\"Notification\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"NotifySubscription\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"Report\":{\"Change\":3,\"ReadFullRecord\":131071,\"Select\":131071},\"CustomerServiceRequest\":{\"Change\":4106,\"ReadFullRecord\":2437,\"Select\":131071},\"Memo\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Reminder\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Review\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927}}"; + var lastRoles = "{\"Customer\":{\"Change\":32842,\"ReadFullRecord\":65925,\"Select\":131071},\"CustomerNote\":{\"Change\":32842,\"ReadFullRecord\":65925,\"Select\":131071},\"Contract\":{\"Change\":74,\"ReadFullRecord\":98693,\"Select\":131071},\"HeadOffice\":{\"Change\":32842,\"ReadFullRecord\":65925,\"Select\":131071},\"LoanUnit\":{\"Change\":74,\"ReadFullRecord\":98693,\"Select\":131071},\"Part\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventory\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartWarehouse\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartAssembly\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PurchaseOrder\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequest\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRestock\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"PartInventoryRequestDataList\":{\"Change\":98,\"ReadFullRecord\":29,\"Select\":131071},\"Project\":{\"Change\":74,\"ReadFullRecord\":98693,\"Select\":131071},\"ServiceRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TravelRate\":{\"Change\":74,\"ReadFullRecord\":33037,\"Select\":131071},\"TaxCode\":{\"Change\":66,\"ReadFullRecord\":98701,\"Select\":131071},\"Unit\":{\"Change\":330,\"ReadFullRecord\":98437,\"Select\":131071},\"UnitModel\":{\"Change\":74,\"ReadFullRecord\":98693,\"Select\":131071},\"UnitMeterReading\":{\"Change\":330,\"ReadFullRecord\":98437,\"Select\":131071},\"Vendor\":{\"Change\":106,\"ReadFullRecord\":98693,\"Select\":131071},\"TaskGroup\":{\"Change\":10,\"ReadFullRecord\":131071,\"Select\":131071},\"WorkOrderStatus\":{\"Change\":74,\"ReadFullRecord\":100229,\"Select\":131071},\"WorkOrderItemStatus\":{\"Change\":74,\"ReadFullRecord\":100229,\"Select\":131071},\"WorkOrderItemPriority\":{\"Change\":74,\"ReadFullRecord\":100229,\"Select\":131071},\"WorkOrder\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItem\":{\"Change\":330,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemExpense\":{\"Change\":458,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLabor\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemLoan\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPart\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemPartRequest\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemScheduledUser\":{\"Change\":330,\"ReadFullRecord\":99973,\"Select\":131071},\"WorkOrderItemTask\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemTravel\":{\"Change\":1994,\"ReadFullRecord\":98949,\"Select\":131071},\"WorkOrderItemUnit\":{\"Change\":330,\"ReadFullRecord\":99461,\"Select\":131071},\"WorkOrderItemOutsideService\":{\"Change\":330,\"ReadFullRecord\":98437,\"Select\":131071},\"Quote\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItem\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemExpense\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLabor\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemLoan\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemPart\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemScheduledUser\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTask\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemTravel\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemUnit\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteItemOutsideService\":{\"Change\":32842,\"ReadFullRecord\":65541,\"Select\":131071},\"QuoteStatus\":{\"Change\":32842,\"ReadFullRecord\":131071,\"Select\":131071},\"PM\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItem\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemExpense\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemLabor\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemLoan\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemPart\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemScheduledUser\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemTask\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemTravel\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemUnit\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"PMItemOutsideService\":{\"Change\":10,\"ReadFullRecord\":98309,\"Select\":131071},\"Global\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"GlobalOps\":{\"Change\":16384,\"ReadFullRecord\":8192,\"Select\":0},\"User\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"UserOptions\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"ServerState\":{\"Change\":16384,\"ReadFullRecord\":131071,\"Select\":0},\"License\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"TrialSeeder\":{\"Change\":16386,\"ReadFullRecord\":8193,\"Select\":0},\"LogFile\":{\"Change\":0,\"ReadFullRecord\":24576,\"Select\":0},\"Backup\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"FileAttachment\":{\"Change\":2,\"ReadFullRecord\":3,\"Select\":0},\"ServerJob\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"OpsNotificationSettings\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"ServerMetrics\":{\"Change\":16384,\"ReadFullRecord\":24576,\"Select\":0},\"Translation\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"DataListSavedFilter\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"FormUserOptions\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"FormCustom\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"PickListTemplate\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"BizMetrics\":{\"Change\":2,\"ReadFullRecord\":98369,\"Select\":0},\"Notification\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"NotifySubscription\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"Report\":{\"Change\":3,\"ReadFullRecord\":131071,\"Select\":131071},\"CustomerServiceRequest\":{\"Change\":4106,\"ReadFullRecord\":2437,\"Select\":131071},\"Memo\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Reminder\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Review\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927}}"; Dictionary lastRolesDeserialized = Newtonsoft.Json.JsonConvert.DeserializeObject>(lastRoles); if (lastRolesDeserialized.Count != roles.Count) {