Source code for rattail.employment

# -*- coding: utf-8; -*-
################################################################################
#
#  Rattail -- Retail Software Framework
#  Copyright © 2010-2024 Lance Edgar
#
#  This file is part of Rattail.
#
#  Rattail is free software: you can redistribute it and/or modify it under the
#  terms of the GNU General Public License as published by the Free Software
#  Foundation, either version 3 of the License, or (at your option) any later
#  version.
#
#  Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
#  details.
#
#  You should have received a copy of the GNU General Public License along with
#  Rattail.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Employment Handler
"""

from rattail.util import load_object
from rattail.app import GenericHandler


[docs] class EmploymentHandler(GenericHandler): """ Base class and default implementation for employment handlers. """ def touch_employee(self, session, employee): self.app.touch_object(session, employee) self.app.touch_object(session, employee.person) for email in employee.emails: self.app.touch_object(session, email) for phone in employee.phones: self.app.touch_object(session, phone) for store in employee._stores: self.app.touch_object(session, store) for department in employee._departments: self.app.touch_object(session, department)
[docs] def begin_employment(self, person, start_date, **kwargs): """ Begin employment for the given person. """ session = self.app.get_session(person) # make sure we have an employee record employee = self.ensure_employee(person) session.flush() # employee status is now *current* employee.status = self.enum.EMPLOYEE_STATUS_CURRENT # maybe assign/update ID employee_id = kwargs.get('employee_id') if employee_id and employee.id != employee_id: employee.id = employee_id # create new history record, with start date history = self.make_employee_history(employee, start_date) session.flush() return employee
[docs] def end_employment(self, employee, end_date, **kwargs): """ End employment for the given employee. """ session = self.app.get_session(employee) # employee status is now *former* employee.status = self.enum.EMPLOYEE_STATUS_FORMER # set end date for current history record, if present history = [h for h in employee.history if not h.end_date] if history: history = sorted(history, key=lambda h: h.start_date, reverse=True) history[0].end_date = end_date
[docs] def ensure_employee(self, person): """ Returns the employee record associated with the given person, creating it first if necessary. """ employee = self.get_employee(person) if employee: return employee session = self.app.get_session(person) employee = self.make_employee(person) session.add(employee) session.flush() return employee
[docs] def get_employee(self, obj): """ Returns the Employee associated with the given object, if any. """ model = self.model if isinstance(obj, model.Employee): return obj else: person = self.app.get_person(obj) if person: return person.employee
[docs] def make_employee(self, person): """ Create and return a new employee record. """ employee = self.model.Employee() employee.person = person return employee
[docs] def make_employee_history(self, employee, start_date): """ Create and return a new employee history record. """ history = self.model.EmployeeHistory() history.start_date = start_date employee.history.append(history) return history
[docs] def why_not_begin_employment(self, person): """ Inspect the given person and if they should not be made a current employee for any reason, return that reason as text. If it's okay for the person to be made an employee, returns ``None``. """ employee = self.get_employee(person) if employee and employee.status == self.enum.EMPLOYEE_STATUS_CURRENT: return "This person is already an employee"
[docs] def why_not_end_employment(self, person): """ Inspect the given person and if their current employment should not be ended for any reason, return that reason as text. If it's okay for the person to stop being an employee, returns ``None``. """ employee = self.get_employee(person) if not employee or employee.status != self.enum.EMPLOYEE_STATUS_CURRENT: return {'error': "This person is not currently an employee"}
[docs] def get_context_employee(self, employee): """ Return a dict of context data for the given employee. """ status_display = None if employee.status is not None: status_display = self.enum.EMPLOYEE_STATUS.get(employee.status, "??") history = employee.sorted_history(reverse=True) if history: history = history[0] return { 'uuid': employee.uuid, 'id': employee.id, 'status': employee.status, 'status_display': status_display, 'current': employee.status == self.enum.EMPLOYEE_STATUS_CURRENT, 'start_date': str(history.start_date) if history else None, 'end_date': str(history.end_date) if history and history.end_date else None, }
[docs] def get_employment_handler(config, **kwargs): """ Create and return the configured :class:`EmploymentHandler` instance. """ spec = config.get('rattail', 'employment.handler') if spec: factory = load_object(spec) else: factory = EmploymentHandler return factory(config, **kwargs)