Add Accountant role and CanManageBills/CanManageAccounting permissions

- AppConstants: add Accountant to CompanyRoles; add CanManageBills and
  CanManageAccounting to Policies
- ApplicationUser: add CanManageBills and CanManageAccounting bool fields
- UserManagementDtos: expose new fields in all three DTOs
- ClaimsPrincipalFactory: emit ManageBills and ManageAccounting claims
- Program.cs: add CanManageBills and CanManageAccounting policies;
  update CanManageInvoices, CanViewReports, CanManagePurchaseOrders,
  and CanManageVendors to auto-pass for Accountant role
- BillsController: replace CanManageInventory with CanManageBills on
  all write actions (correct policy — bills are not inventory)
- BankReconciliationsController: replace CanManageJobs with
  CanManageAccounting on write actions
- CompanyUsersController: add Accountant to validCompanyRoles (both
  Create/Edit), legacyRole switch, and all permission assignment blocks
- Create/Edit views: add Accountant option to role dropdown; add
  CanManageBills and CanManageAccounting checkboxes; JS auto-checks
  financial permissions when Accountant role is selected
- Migration AddAccountantRolePermissions: adds columns + backfills
  CanManageBills=1 and CanManageAccounting=1 for all CompanyAdmin users

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 19:42:53 -04:00
parent 59beba2e15
commit feff0fa73d
12 changed files with 10850 additions and 60 deletions
+37 -3
View File
@@ -414,6 +414,9 @@ builder.Services.AddAuthorization(options =>
var user = context.User;
if (user.IsInRole(AppConstants.Roles.SuperAdmin))
return true;
var companyRole = user.FindFirst("CompanyRole")?.Value;
if (companyRole == AppConstants.CompanyRoles.Accountant)
return true;
return user.HasClaim("Permission", "ManageVendors");
}));
@@ -425,7 +428,8 @@ builder.Services.AddAuthorization(options =>
return true;
var companyRole = user.FindFirst("CompanyRole")?.Value;
if (companyRole == AppConstants.CompanyRoles.CompanyAdmin ||
companyRole == AppConstants.CompanyRoles.Manager)
companyRole == AppConstants.CompanyRoles.Manager ||
companyRole == AppConstants.CompanyRoles.Accountant)
return true;
return user.HasClaim("Permission", "ManageInventory") ||
user.HasClaim("Permission", "ManageVendors");
@@ -448,7 +452,8 @@ builder.Services.AddAuthorization(options =>
return true;
var companyRole = user.FindFirst("CompanyRole")?.Value;
if (companyRole == AppConstants.CompanyRoles.CompanyAdmin ||
companyRole == AppConstants.CompanyRoles.Manager)
companyRole == AppConstants.CompanyRoles.Manager ||
companyRole == AppConstants.CompanyRoles.Accountant)
return true;
return user.HasClaim("Permission", "ManageInvoices") ||
user.HasClaim("Permission", "ManageJobs");
@@ -462,11 +467,40 @@ builder.Services.AddAuthorization(options =>
return true;
var companyRole = user.FindFirst("CompanyRole")?.Value;
if (companyRole == AppConstants.CompanyRoles.CompanyAdmin ||
companyRole == AppConstants.CompanyRoles.Manager)
companyRole == AppConstants.CompanyRoles.Manager ||
companyRole == AppConstants.CompanyRoles.Accountant)
return true;
return user.HasClaim("Permission", "ViewReports");
}));
options.AddPolicy("CanManageBills", policy =>
policy.RequireAssertion(context =>
{
var user = context.User;
if (user.IsInRole(AppConstants.Roles.SuperAdmin))
return true;
var companyRole = user.FindFirst("CompanyRole")?.Value;
if (companyRole == AppConstants.CompanyRoles.CompanyAdmin ||
companyRole == AppConstants.CompanyRoles.Manager ||
companyRole == AppConstants.CompanyRoles.Accountant)
return true;
return user.HasClaim("Permission", "ManageBills");
}));
options.AddPolicy("CanManageAccounting", policy =>
policy.RequireAssertion(context =>
{
var user = context.User;
if (user.IsInRole(AppConstants.Roles.SuperAdmin))
return true;
var companyRole = user.FindFirst("CompanyRole")?.Value;
if (companyRole == AppConstants.CompanyRoles.CompanyAdmin ||
companyRole == AppConstants.CompanyRoles.Manager ||
companyRole == AppConstants.CompanyRoles.Accountant)
return true;
return user.HasClaim("Permission", "ManageAccounting");
}));
options.AddPolicy("CanManageUsers", policy =>
policy.RequireAssertion(context =>
{