Skip to content

Employee Tag Constraint - about employee's working state #28

@AybukeAk

Description

@AybukeAk

Hello,

We want to add another specific constraint about working status. Some employees cannot work on weekends or on specific days. In addition, there are restrictions such as pregnant, disabled and those with babies shouldn't be assigned at the weekend. We created the "Tag" class to indicate this. In our constraint list, we are using the True-False boolean values in the "working_state" variable, which indicates whether the employee can work according to employee's tag list from Employee class. (For example: "tag_list": [ "parttime","pregnant"])

class Tag:
    name: str 
    min_work_hours: int
    max_work_hours: int

    def __init__(self, name: str=None, min_work_hours: int=None, max_work_hours: int=None):
        self.name = name
        self.min_work_hours = min_work_hours
        self.max_work_hours = max_work_hours

    def __str__(self):
        return f'Tag(name={self.name}, min_work_hours = {self.min_work_hours}, max_work_hours = {self.max_work_hours})'

    def to_dict(self):
        return {
            'name': self.name,
            'min_work_hours': self.min_work_hours,
            'max_work_hours': self.max_work_hours
    }

@optapy.problem_fact
class ConstraintForTag:
    shift_id: int 
    tag: Tag
    working_state: bool 

    def __init__(self, shift_id: int=None, tag: Tag=None, working_state: bool=None):
        self.shift_id = shift_id
        self.tag = tag
        self.working_state = working_state

    def __str__(self):
        return f'ConstraintForEmployee(shift_id={self.shift_id}, tag = {self.tag}, working_state = {self.working_state})'

    def to_dict(self):
        return {
            'shift_id': self.shift_id,
            'tag': self.tag.to_dict(),
            'working_state': self.working_state
    }

And we added the "tag_constraint_for_employee" constraint as follows :

def tag_constraint_for_employee(constraint_factory: ConstraintFactory):
    return constraint_factory \
        .for_each(Shift) \
        .join(ConstraintForTag,
              Joiners.equal(lambda shift: shift.shift_id,
                            lambda constraint: constraint.shift_id)    
              ) \
             .filter(lambda shift, constraint: (constraint.tag.name in  shift.employee.tag_list) & (constraint.working_state==False)) \
        .penalize('Tag constraint for employee', HardSoftScore.ONE_HARD)`

We were using the old version of optapy before and this constraint was working without any errors, assigning employees without error or it was showing score if it brokes the constraint, now after upgrading to 8.31.1b0 we got the following error:

RuntimeError: An error occurred during solving. This can occur when functions take the wrong number of parameters (ex: a setter that does not take exactly one parameter) or by a function returning an incompatible return type (ex: returning a str in a filter, which expects a bool). This can also occur when an exception is raised when evaluating constraints/getters/setters.

Do you have any idea about how can I fix it?
Thank you in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions