Allow staff email correction and sync linked login email
This commit is contained in:
@@ -13,6 +13,7 @@ from sqlalchemy.orm import Session, selectinload
|
||||
|
||||
from app.core.security.passwords import hash_password
|
||||
from app.modules.core.iam.models import User
|
||||
from app.modules.core.audit.service import write_audit_log
|
||||
from app.modules.alerts.service import create_alert
|
||||
from app.modules.alerts.workflow_escalations import create_workflow_escalation
|
||||
from app.modules.core.iam.scope import build_scope, list_visible_branches, list_visible_tenants, validate_branch_matches_tenant
|
||||
@@ -421,6 +422,7 @@ def update_employee(db: Session, actor: User, emp: Employee, data: dict[str, Any
|
||||
raise HTTPException(status_code=400, detail="Employee code and full name are required.")
|
||||
|
||||
user_id = cleaned.get("user_id")
|
||||
linked_user: User | None = None
|
||||
if user_id:
|
||||
linked_user = db.get(User, int(user_id))
|
||||
if not linked_user:
|
||||
@@ -433,6 +435,46 @@ def update_employee(db: Session, actor: User, emp: Employee, data: dict[str, Any
|
||||
|
||||
_ensure_unique(db, tenant_id=emp.tenant_id, employee_code=employee_code, user_id=user_id, exclude_id=emp.id)
|
||||
|
||||
old_email = (emp.email or "").strip().lower()
|
||||
requested_email = (cleaned.get("email") or "").strip().lower()
|
||||
email_changed = requested_email != old_email
|
||||
|
||||
if email_changed:
|
||||
actor_roles = _role_set(db, actor)
|
||||
if not actor_roles.intersection({"System Admin", "Firm Admin", "Partner"}):
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail="Only a Firm Admin or Partner can correct an employee email address.",
|
||||
)
|
||||
|
||||
if linked_user is not None and not requested_email:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Email cannot be blank while the employee is linked to a login user.",
|
||||
)
|
||||
|
||||
if requested_email:
|
||||
duplicate_user_stmt = select(User).where(func.lower(User.email) == requested_email)
|
||||
if linked_user is not None:
|
||||
duplicate_user_stmt = duplicate_user_stmt.where(User.id != linked_user.id)
|
||||
duplicate_user = db.execute(duplicate_user_stmt).scalar_one_or_none()
|
||||
if duplicate_user:
|
||||
raise HTTPException(status_code=409, detail="This email address is already used by another login user.")
|
||||
|
||||
duplicate_employee = db.execute(
|
||||
select(Employee).where(
|
||||
Employee.tenant_id == emp.tenant_id,
|
||||
Employee.id != emp.id,
|
||||
func.lower(Employee.email) == requested_email,
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
if duplicate_employee:
|
||||
raise HTTPException(status_code=409, detail="This email address is already used by another employee in this firm.")
|
||||
|
||||
cleaned["email"] = requested_email or None
|
||||
if linked_user is not None:
|
||||
linked_user.email = requested_email
|
||||
|
||||
update_fields = [
|
||||
"employee_code", "full_name", "email", "mobile", "alternate_mobile", "date_of_joining", "date_of_leaving",
|
||||
"employment_type", "status", "is_active", "department", "designation", "reporting_manager_user_id",
|
||||
@@ -447,7 +489,28 @@ def update_employee(db: Session, actor: User, emp: Employee, data: dict[str, Any
|
||||
emp.updated_by_user_id = actor.id
|
||||
emp.updated_at_utc = datetime.now(timezone.utc)
|
||||
_disable_relieved_employee_login(db, emp)
|
||||
db.commit()
|
||||
db.flush()
|
||||
|
||||
if email_changed:
|
||||
write_audit_log(
|
||||
db,
|
||||
action="employee.email.corrected",
|
||||
entity_type="employee",
|
||||
actor=actor,
|
||||
entity_id=emp.id,
|
||||
entity_name=emp.full_name,
|
||||
target_tenant_id=emp.tenant_id,
|
||||
target_branch_id=emp.branch_id,
|
||||
details={
|
||||
"old_email": old_email or None,
|
||||
"new_email": requested_email or None,
|
||||
"linked_user_id": linked_user.id if linked_user is not None else None,
|
||||
"login_email_synchronised": linked_user is not None,
|
||||
},
|
||||
)
|
||||
else:
|
||||
db.commit()
|
||||
|
||||
db.refresh(emp)
|
||||
return emp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user