Add Employee vs Client user type and filter time/reports by employee (#14) (#15)
Unit Tests / test (push) Successful in 16s
Unit Tests / test (push) Successful in 16s
## Summary - Adds `UserProfile` model with mutually exclusive **Employee** / **Client** types - Replaces auto-Employee signal with auto-Client profile on user creation - Data migration: users with time log entries → Employee; others → Client (orphan Employee rows removed) - Admin UI at `/financial/manage_users` to set any user's type; profile page shows current type - **Employees** can log time; **Clients** get read-only access to reports and time logs - Time logs, reports, and dashboard filter to employees only - 14 new tests covering signals, type switching, access control, and filtering ## Design decisions (from issue Q&A) 1. Client login = read-only financial access (reports + time logs, no edit/log time) 2. Employee and Client are strictly mutually exclusive 3. Admins (superusers) can change type via Manage Users 4. Bulk migration applied for existing users ## Test plan - [x] `python manage.py test financial.tests` (14 tests pass) - [x] `python manage.py test public.tests` (21 tests pass) - [ ] Run migration on staging: `python manage.py migrate` - [ ] Verify admin can set user types at `/financial/manage_users` - [ ] Verify employee can log time at `/financial/timekeeping` - [ ] Verify client sees reports/time logs read-only, cannot log time - [ ] Verify employee filter dropdown excludes clients Closes #14 Reviewed-on: #15
This commit was merged in pull request #15.
This commit is contained in:
@@ -89,9 +89,11 @@
|
||||
<li><a href="{% url 'planning:board_view' %}"
|
||||
class="{% if 'planning' in request.path %}active{% endif %}"
|
||||
data-tianji-event="nav_planning">Planning</a></li>
|
||||
<li><a href="{% url 'financial_index' %}"
|
||||
{% if has_financial_access %}
|
||||
<li><a href="{% url 'financial_home' %}"
|
||||
class="{% if 'financial' in request.path %}active{% endif %}"
|
||||
data-tianji-event="nav_financials">Financials</a></li>
|
||||
{% endif %}
|
||||
<li class="dropdown" id="user-profile-dropdown">
|
||||
<button type="button" class="profile-icon-link" aria-label="Account menu for {{ user.get_full_name|default:user.username }}"
|
||||
aria-expanded="false" aria-haspopup="true" aria-controls="profile-menu">
|
||||
@@ -103,6 +105,12 @@
|
||||
</button>
|
||||
<ul class="dropdown-content profile-dropdown-content" id="profile-menu" role="menu">
|
||||
<li class="profile-name-item">{{ user.get_full_name|default:user.username }}</li>
|
||||
{% if has_financial_access %}
|
||||
<li><a href="{% url 'profile' %}">Profile</a></li>
|
||||
{% endif %}
|
||||
{% if is_financial_admin %}
|
||||
<li><a href="{% url 'manage_users' %}">Manage Users</a></li>
|
||||
{% endif %}
|
||||
<li><a href="{% url 'change_password' %}">Change Password</a></li>
|
||||
<li>
|
||||
<form action="{% url 'logout' %}" method="post" style="margin: 0;">
|
||||
|
||||
Reference in New Issue
Block a user