Модель компании/сотрудника

У меня есть следующая система сотрудников/компаний с классами данных Employee а также Company. Существует также LeaveApplication, Hirer а также EmployeePromoter которые находятся в модели на основе композиции с компанией для выполнения функций. Наконец, есть два Enum называется CompanyRoles а также CompanyTeams.

Мне нужен совет по следующему:

  • Будь то LeaveApplication действительно должен быть отдельный класс, так как он становится грязным
  • Если я должен создавать методы give_leaves_employee а также hire_employee в компании, как и другие методы в компании. Я могу позже сослаться на них от нанимателя.
  • Если есть более чистый способ воспроизвести мою систему продвижения без двух списков.

Я чувствую, что мой код становится беспорядочным здесь с композиционной моделью с такими функциями, как продвижение_employee() в компании и наличие отдельного класса, accept_resign() и fire_employee() только в компании, а Hire_employee() и give_leaves() только в классах, основанных на композиции . Был бы лучший и более читаемый способ структурировать. Я планирую позже реализовать весь этот код в интерфейсе командной строки в отдельном файле, куда будут импортированы все классы

from dataclasses import dataclass, field
from enum import Enum, auto


class CompanyRoles(Enum):
    MANAGER = auto()
    LEAD = auto()
    WORKER = auto()
    INTERN = auto()


class CompanyTeams(Enum):
    MARKETING = auto()
    PRODUCT = auto()
    DESIGN = auto()
    SALES = auto()
    FINANCE = auto()

class EmployeePromoter:
    def __init__(self):
        self.employee_hierarchy = [
            CompanyRoles.INTERN,
            CompanyRoles.WORKER,
            CompanyRoles.LEAD,
            CompanyRoles.MANAGER
        ]

        self.role_salary_increment = [
            0,  
            5000,
            15000,
            25000
        ]
    
    def promote_employee(self, employee):
        employee_role_idx = self.employee_hierarchy.index(employee.role)
        employee.role = self.employee_hierarchy[employee_role_idx + 1]
        employee.salary_dollars += self.role_salary_increment[employee_role_idx + 1]
        print(f"{employee.name} was promoted to a package of {employee.salary_dollars}.")

class Hirer:
    def __init__(self, company) -> None:
        self.company = company

    def employee_eligible(self, employee, role, team):
        employee_has_work_experience = employee.work_experience_years >= self.company.minimum_work_experience
        employee_has_good_grades = employee.grades_percent_average >= self.company.minimum_hiring_grades
        if self.company.role_occupied(role, team):
            return False
        elif not employee_has_work_experience and not employee_has_good_grades:
            return False
        return True

    def hire_employee(self, applicant, role, team) -> bool:
        if not self.employee_eligible(applicant, role, team):
            print("You did not meet our requirements")
            return False
        self.company.add_employee(applicant)
        self.company.employees = [employee.name for employee in self.company.employee_base]  
        return True    

class LeaveApplication:
    def __init__(self, company) -> None:
        self.company = company

    def give_leaves_employee(self, employee, leaves_required) -> bool:
        ineligible_leaves = leaves_required <= 3 and employee.available_leaves - leaves_required <= 0
        if ineligible_leaves:
            print("Leaves can't be granted.")
            return False
        print("Leaves are granted.")
        return True
    

@dataclass
class Company():

    name : str
    minimum_hiring_grades : int
    minimum_work_experience : int
    employee_leaves : int
    employee_bonus_percent : int
    employee_working_days : int
    employees : list = field(init = False, default_factory = list)
    employee_base : list = field(init = False, default_factory = list)


    def __post_init__(self) -> None:
        '''Creates Hirer object as it can't be created without `self`'''
        self.promoter : object = field(init = False, default = EmployeePromoter())
        self.leave_app : object = field(init = False, default = LeaveApplication(self))
        self.hirer : object = Hirer(self)

    #Database Functions
    def add_employee(self, employee) -> None:
        self.employee_base.append(employee)

    def delete_employee(self, employee) -> None:
        self.employee_base.remove(employee)

    def role_occupied(self, role, team) -> bool:
        return bool([employee.role for employee in self.employee_base if role == employee.role and team == employee.team])

    def promote_employee(self, employee) -> None:
        self.promoter.promote_employee(employee)

    def fire_employee(self, employee) -> None:
        if employee in self.employee_base:
            employee.self_delete_attr()
            self.employee_base.remove(employee)
            self.employees = [employee.name for employee in self.employee_base]  
            print(f"{employee.name} is fired from {self.name}")
        else:
            print(f"{employee.name} is not in the company.")

    def accept_resignation(self, employee) -> None:
        self.employee_base.remove(employee)
        self.employees = [employee.name for employee in self.employee_base]  
        print(f"{employee.name} has now left the company")

    def print_self_employees(self) -> None:
        print(self.employees)




@dataclass
class Employee:
    name : str
    grades_percent_average : int
    work_experience_years : int
    role : Enum = field(init = False, default = None)
    team : Enum = field(init = False, default = None)
    company : object = field(init = False, default= None)
    working_days : int = field(init = False, default= 0)
    bonus_percent : int = field(init = False, default= 0)
    has_job : bool = field(init = False, default= False)
    id : object = field(init = False, default= None)


    def apply_in_company(self, company, role, team) -> None:
        accepted = company.hirer.hire_employee(self, role, team)
        if accepted:
            self.company = company
            self.has_job = True
            self.working_days = company.employee_working_days
            self.bonus_percent = company.employee_bonus_percent
            self.available_leaves = company.employee_leaves
            self.salary_dollars = (self.grades_percent_average + self.work_experience_years) * 1000
            self.role = role
            self.team = team
            self.id = self
    
    def ask_for_leaves(self, leaves_required ) -> None:
        if self.has_job:
            leaves_granted = self.company.leave_app.give_leaves_employee(self, leaves_required) 
            if leaves_granted:
                self.available_leaves -= leaves_required
                self.working_days -= leaves_required
        else:
            print("You do not have a job!")


    def resign_company(self) -> None:
        if self.has_job:
            self.company.accept_resignation(self)
            self.self_delete_attr()
             
        else:
            print("You do not have a job!")

    def self_delete_attr(self) -> None:
        self.company = None
        self.salary_dollars = None
        self.id = None
        self.has_job = False


b = Company(name ="b", minimum_hiring_grades = 90, minimum_work_experience = 5, employee_leaves = 30, employee_bonus_percent = 25, employee_working_days = 300)
arham = Employee(name = "Arham", grades_percent_average = 92, work_experience_years = 5)
rajeev = Employee(name = "Rajeev", grades_percent_average = 91, work_experience_years = 5)
arham.apply_in_company(b, CompanyRoles.WORKER, CompanyTeams.FINANCE)
rajeev.apply_in_company(b, CompanyRoles.WORKER, CompanyTeams.DESIGN)
arham.resign_company()
b.print_self_employees()
```

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *