Files
X-Financial/server/src/app/repositories/employee.py

150 lines
5.2 KiB
Python
Raw Normal View History

from __future__ import annotations
from sqlalchemy import func, or_, select
from sqlalchemy.orm import Session, selectinload
from app.models.employee import Employee
from app.models.organization import OrganizationUnit
from app.models.role import Role
from app.services.pagination import PageResult, paginate_select
from app.services.tenant_registry import required_tenant_id
class EmployeeRepository:
def __init__(self, db: Session, *, tenant_id: str) -> None:
self.db = db
self.tenant_id = required_tenant_id(tenant_id)
def _list_stmt(self, status: str | None = None, keyword: str | None = None):
stmt = (
select(Employee)
.options(
selectinload(Employee.organization_unit),
selectinload(Employee.manager),
selectinload(Employee.roles),
selectinload(Employee.change_logs),
)
.where(Employee.tenant_id == self.tenant_id)
.order_by(Employee.updated_at.desc(), Employee.name.asc())
)
if status and status != "全部员工":
stmt = stmt.where(Employee.employment_status == status)
if keyword:
pattern = f"%{keyword.strip()}%"
stmt = stmt.where(
or_(
Employee.name.ilike(pattern),
Employee.employee_no.ilike(pattern),
Employee.email.ilike(pattern),
Employee.position.ilike(pattern),
)
)
return stmt
def list(self, status: str | None = None, keyword: str | None = None) -> list[Employee]:
stmt = self._list_stmt(status=status, keyword=keyword)
return list(self.db.execute(stmt).scalars().unique().all())
def list_page(
self,
*,
status: str | None = None,
keyword: str | None = None,
page: int | None,
page_size: int | None,
) -> PageResult[Employee]:
stmt = self._list_stmt(status=status, keyword=keyword)
return paginate_select(self.db, stmt, page=page, page_size=page_size, unique=True)
def get(self, employee_id: str) -> Employee | None:
stmt = (
select(Employee)
.options(
selectinload(Employee.organization_unit),
selectinload(Employee.manager),
selectinload(Employee.roles),
selectinload(Employee.change_logs),
)
.where(
Employee.tenant_id == self.tenant_id,
Employee.id == employee_id,
)
)
return self.db.execute(stmt).scalars().unique().first()
def get_by_employee_no(self, employee_no: str) -> Employee | None:
stmt = select(Employee).where(
Employee.tenant_id == self.tenant_id,
Employee.employee_no == employee_no,
)
return self.db.execute(stmt).scalars().first()
def get_by_email(self, email: str) -> Employee | None:
stmt = select(Employee).where(
Employee.tenant_id == self.tenant_id,
Employee.email == email,
)
return self.db.execute(stmt).scalars().first()
def list_roles(self) -> list[Role]:
stmt = select(Role)
return list(self.db.execute(stmt).scalars().all())
def get_role_by_code(self, role_code: str) -> Role | None:
stmt = select(Role).where(Role.role_code == role_code)
return self.db.execute(stmt).scalars().first()
def list_organization_units(self) -> list[OrganizationUnit]:
stmt = select(OrganizationUnit).where(
OrganizationUnit.tenant_id == self.tenant_id
)
return list(self.db.execute(stmt).scalars().all())
def get_organization_by_code(self, unit_code: str) -> OrganizationUnit | None:
stmt = select(OrganizationUnit).where(
OrganizationUnit.tenant_id == self.tenant_id,
OrganizationUnit.unit_code == unit_code,
)
return self.db.execute(stmt).scalars().first()
def count_employees(self) -> int:
stmt = (
select(func.count())
.select_from(Employee)
.where(Employee.tenant_id == self.tenant_id)
)
return int(self.db.execute(stmt).scalar_one())
def count_roles(self) -> int:
stmt = select(func.count()).select_from(Role)
return int(self.db.execute(stmt).scalar_one())
def count_organization_units(self) -> int:
stmt = (
select(func.count())
.select_from(OrganizationUnit)
.where(OrganizationUnit.tenant_id == self.tenant_id)
)
return int(self.db.execute(stmt).scalar_one())
def create(self, employee: Employee) -> Employee:
self._require_employee_tenant(employee)
self.db.add(employee)
self.db.commit()
self.db.refresh(employee)
return employee
def save(self, employee: Employee) -> Employee:
self._require_employee_tenant(employee)
self.db.add(employee)
self.db.commit()
self.db.refresh(employee)
return employee
def _require_employee_tenant(self, employee: Employee) -> None:
if required_tenant_id(employee.tenant_id) != self.tenant_id:
raise ValueError("员工记录不属于当前可信租户。")