feff0fa73d
- 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>
276 lines
9.5 KiB
C#
276 lines
9.5 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace PowderCoating.Application.DTOs.User;
|
|
|
|
/// <summary>
|
|
/// Full user details for company admin management
|
|
/// </summary>
|
|
public class CompanyUserDto
|
|
{
|
|
public string Id { get; set; } = string.Empty;
|
|
public string Email { get; set; } = string.Empty;
|
|
public string FirstName { get; set; } = string.Empty;
|
|
public string LastName { get; set; } = string.Empty;
|
|
public string FullName => $"{FirstName} {LastName}";
|
|
public string? EmployeeNumber { get; set; }
|
|
|
|
public string? CompanyRole { get; set; }
|
|
public string? Department { get; set; }
|
|
public string? Position { get; set; }
|
|
public string? Phone { get; set; }
|
|
|
|
public bool IsActive { get; set; }
|
|
public bool EmailConfirmed { get; set; }
|
|
|
|
public DateTime HireDate { get; set; }
|
|
public DateTime? TerminationDate { get; set; }
|
|
public DateTime? LastLoginDate { get; set; }
|
|
|
|
// Permissions
|
|
public bool CanManageJobs { get; set; }
|
|
public bool CanManageInventory { get; set; }
|
|
public bool CanManageCustomers { get; set; }
|
|
public bool CanCreateQuotes { get; set; }
|
|
public bool CanApproveQuotes { get; set; }
|
|
public bool CanManageCalendar { get; set; }
|
|
public bool CanViewCalendar { get; set; }
|
|
public bool CanManageProducts { get; set; }
|
|
public bool CanViewProducts { get; set; }
|
|
public bool CanManageEquipment { get; set; }
|
|
public bool CanManageVendors { get; set; }
|
|
public bool CanManageMaintenance { get; set; }
|
|
public bool CanManageInvoices { get; set; }
|
|
public bool CanViewReports { get; set; }
|
|
public bool CanManageBills { get; set; }
|
|
public bool CanManageAccounting { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// User list item for grid/list views
|
|
/// </summary>
|
|
public class CompanyUserListDto
|
|
{
|
|
public string Id { get; set; } = string.Empty;
|
|
public string Email { get; set; } = string.Empty;
|
|
public string FirstName { get; set; } = string.Empty;
|
|
public string LastName { get; set; } = string.Empty;
|
|
public string FullName => $"{FirstName} {LastName}";
|
|
public string? CompanyRole { get; set; }
|
|
public string? Department { get; set; }
|
|
public bool IsActive { get; set; }
|
|
public bool IsBanned { get; set; }
|
|
public DateTime HireDate { get; set; }
|
|
public DateTime? LastLoginDate { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// DTO for creating a new company user
|
|
/// </summary>
|
|
public class CreateCompanyUserDto
|
|
{
|
|
[Required(ErrorMessage = "Email is required")]
|
|
[EmailAddress(ErrorMessage = "Please enter a valid email address")]
|
|
[StringLength(200, ErrorMessage = "Email cannot exceed 200 characters")]
|
|
[Display(Name = "Email")]
|
|
public string Email { get; set; } = string.Empty;
|
|
|
|
[Required(ErrorMessage = "First name is required")]
|
|
[StringLength(100, ErrorMessage = "First name cannot exceed 100 characters")]
|
|
[Display(Name = "First Name")]
|
|
public string FirstName { get; set; } = string.Empty;
|
|
|
|
[Required(ErrorMessage = "Last name is required")]
|
|
[StringLength(100, ErrorMessage = "Last name cannot exceed 100 characters")]
|
|
[Display(Name = "Last Name")]
|
|
public string LastName { get; set; } = string.Empty;
|
|
|
|
[StringLength(50, ErrorMessage = "Employee number cannot exceed 50 characters")]
|
|
[Display(Name = "Employee Number")]
|
|
public string? EmployeeNumber { get; set; }
|
|
|
|
[Required(ErrorMessage = "Company role is required")]
|
|
[StringLength(50, ErrorMessage = "Company role cannot exceed 50 characters")]
|
|
[Display(Name = "Company Role")]
|
|
public string CompanyRole { get; set; } = "Viewer";
|
|
|
|
[StringLength(100, ErrorMessage = "Department cannot exceed 100 characters")]
|
|
[Display(Name = "Department")]
|
|
public string? Department { get; set; }
|
|
|
|
[StringLength(100, ErrorMessage = "Position cannot exceed 100 characters")]
|
|
[Display(Name = "Position")]
|
|
public string? Position { get; set; }
|
|
|
|
[Phone(ErrorMessage = "Please enter a valid phone number")]
|
|
[StringLength(20, ErrorMessage = "Phone cannot exceed 20 characters")]
|
|
[Display(Name = "Phone")]
|
|
public string? Phone { get; set; }
|
|
|
|
[Required(ErrorMessage = "Hire date is required")]
|
|
[Display(Name = "Hire Date")]
|
|
public DateTime HireDate { get; set; } = DateTime.UtcNow;
|
|
|
|
[Required(ErrorMessage = "Password is required")]
|
|
[StringLength(100, MinimumLength = 8, ErrorMessage = "Password must be at least 8 characters")]
|
|
[Display(Name = "Password")]
|
|
public string Password { get; set; } = string.Empty;
|
|
|
|
// Permissions
|
|
[Display(Name = "Can Manage Jobs")]
|
|
public bool CanManageJobs { get; set; }
|
|
|
|
[Display(Name = "Can Manage Inventory")]
|
|
public bool CanManageInventory { get; set; }
|
|
|
|
[Display(Name = "Can Manage Customers")]
|
|
public bool CanManageCustomers { get; set; }
|
|
|
|
[Display(Name = "Can Create Quotes")]
|
|
public bool CanCreateQuotes { get; set; }
|
|
|
|
[Display(Name = "Can Approve Quotes")]
|
|
public bool CanApproveQuotes { get; set; }
|
|
|
|
[Display(Name = "Can Manage Calendar")]
|
|
public bool CanManageCalendar { get; set; }
|
|
|
|
[Display(Name = "Can View Calendar")]
|
|
public bool CanViewCalendar { get; set; }
|
|
|
|
[Display(Name = "Can Manage Products")]
|
|
public bool CanManageProducts { get; set; }
|
|
|
|
[Display(Name = "Can View Products")]
|
|
public bool CanViewProducts { get; set; }
|
|
|
|
[Display(Name = "Can Manage Equipment")]
|
|
public bool CanManageEquipment { get; set; }
|
|
|
|
[Display(Name = "Can Manage Vendors")]
|
|
public bool CanManageVendors { get; set; }
|
|
|
|
[Display(Name = "Can Manage Maintenance")]
|
|
public bool CanManageMaintenance { get; set; }
|
|
|
|
[Display(Name = "Can Manage Invoices")]
|
|
public bool CanManageInvoices { get; set; }
|
|
|
|
[Display(Name = "Can View Reports")]
|
|
public bool CanViewReports { get; set; }
|
|
|
|
[Display(Name = "Can Manage Bills & AP")]
|
|
public bool CanManageBills { get; set; }
|
|
|
|
[Display(Name = "Can Manage Accounting")]
|
|
public bool CanManageAccounting { get; set; }
|
|
|
|
[Display(Name = "Send Welcome Email")]
|
|
public bool SendWelcomeEmail { get; set; } = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// DTO for updating an existing company user
|
|
/// </summary>
|
|
public class UpdateCompanyUserDto
|
|
{
|
|
[Required]
|
|
public string Id { get; set; } = string.Empty;
|
|
|
|
[Required(ErrorMessage = "Email is required")]
|
|
[EmailAddress(ErrorMessage = "Please enter a valid email address")]
|
|
[StringLength(200, ErrorMessage = "Email cannot exceed 200 characters")]
|
|
[Display(Name = "Email")]
|
|
public string Email { get; set; } = string.Empty;
|
|
|
|
[Required(ErrorMessage = "First name is required")]
|
|
[StringLength(100, ErrorMessage = "First name cannot exceed 100 characters")]
|
|
[Display(Name = "First Name")]
|
|
public string FirstName { get; set; } = string.Empty;
|
|
|
|
[Required(ErrorMessage = "Last name is required")]
|
|
[StringLength(100, ErrorMessage = "Last name cannot exceed 100 characters")]
|
|
[Display(Name = "Last Name")]
|
|
public string LastName { get; set; } = string.Empty;
|
|
|
|
[StringLength(50, ErrorMessage = "Employee number cannot exceed 50 characters")]
|
|
[Display(Name = "Employee Number")]
|
|
public string? EmployeeNumber { get; set; }
|
|
|
|
[Required(ErrorMessage = "Company role is required")]
|
|
[StringLength(50, ErrorMessage = "Company role cannot exceed 50 characters")]
|
|
[Display(Name = "Company Role")]
|
|
public string CompanyRole { get; set; } = "Viewer";
|
|
|
|
[StringLength(100, ErrorMessage = "Department cannot exceed 100 characters")]
|
|
[Display(Name = "Department")]
|
|
public string? Department { get; set; }
|
|
|
|
[StringLength(100, ErrorMessage = "Position cannot exceed 100 characters")]
|
|
[Display(Name = "Position")]
|
|
public string? Position { get; set; }
|
|
|
|
[Phone(ErrorMessage = "Please enter a valid phone number")]
|
|
[StringLength(20, ErrorMessage = "Phone cannot exceed 20 characters")]
|
|
[Display(Name = "Phone")]
|
|
public string? Phone { get; set; }
|
|
|
|
[Display(Name = "Active")]
|
|
public bool IsActive { get; set; }
|
|
|
|
[Required(ErrorMessage = "Hire date is required")]
|
|
[Display(Name = "Hire Date")]
|
|
public DateTime HireDate { get; set; }
|
|
|
|
[Display(Name = "Termination Date")]
|
|
public DateTime? TerminationDate { get; set; }
|
|
|
|
// Permissions
|
|
[Display(Name = "Can Manage Jobs")]
|
|
public bool CanManageJobs { get; set; }
|
|
|
|
[Display(Name = "Can Manage Inventory")]
|
|
public bool CanManageInventory { get; set; }
|
|
|
|
[Display(Name = "Can Manage Customers")]
|
|
public bool CanManageCustomers { get; set; }
|
|
|
|
[Display(Name = "Can Create Quotes")]
|
|
public bool CanCreateQuotes { get; set; }
|
|
|
|
[Display(Name = "Can Approve Quotes")]
|
|
public bool CanApproveQuotes { get; set; }
|
|
|
|
[Display(Name = "Can Manage Calendar")]
|
|
public bool CanManageCalendar { get; set; }
|
|
|
|
[Display(Name = "Can View Calendar")]
|
|
public bool CanViewCalendar { get; set; }
|
|
|
|
[Display(Name = "Can Manage Products")]
|
|
public bool CanManageProducts { get; set; }
|
|
|
|
[Display(Name = "Can View Products")]
|
|
public bool CanViewProducts { get; set; }
|
|
|
|
[Display(Name = "Can Manage Equipment")]
|
|
public bool CanManageEquipment { get; set; }
|
|
|
|
[Display(Name = "Can Manage Vendors")]
|
|
public bool CanManageVendors { get; set; }
|
|
|
|
[Display(Name = "Can Manage Maintenance")]
|
|
public bool CanManageMaintenance { get; set; }
|
|
|
|
[Display(Name = "Can Manage Invoices")]
|
|
public bool CanManageInvoices { get; set; }
|
|
|
|
[Display(Name = "Can View Reports")]
|
|
public bool CanViewReports { get; set; }
|
|
|
|
[Display(Name = "Can Manage Bills & AP")]
|
|
public bool CanManageBills { get; set; }
|
|
|
|
[Display(Name = "Can Manage Accounting")]
|
|
public bool CanManageAccounting { get; set; }
|
|
}
|