poli_planning/polyclinic_scheduling/apps/schedule/models.py

105 lines
4.5 KiB
Python

from django.db import models
from django.utils.translation import gettext_lazy as _
from lib.models.base import MetaDataModel
from apps.employee.models import Employee
from jsonfield import JSONField
import collections
# Create your models here.
class Schedule(MetaDataModel):
"""
A model that holds the schedule information. Here we store the form data and let the Peregrine cluster make the calculations.
It will inherit the attributes :attr:`~lib.models.base.MetaDataModel.created_at` and :attr:`~lib.models.base.MetaDataModel.updated_at` from the Abstract model :class:`~lib.models.base.MetaDataModel`
Attributes
----------
employee : Employee
The employee that is the owner of this schedule.
name : str
The name of the schedule. Max length is 100 characters.
email : str
The email address where the results should be sent to. Max length is 100 characters.
status : ScheduleStatus
The status of the schedule.
"""
class Meta:
verbose_name = _('schedule')
verbose_name_plural = _('schedules')
class ScheduleStatus(models.TextChoices):
"""This is a sub class of Schedule which holds all the possible schedule statuses
.. data:: NEW
The schedule is just created and waiting to be picked up by the Peregrine scripts.
.. data:: ACCEPTED
The Peregrine scripts have accepted the new schedule job. And the input is valid.
.. data:: PROCESSING
The Peregrine job is submitted to the job queue and should be starting soon.
.. data:: PROCESSED
The Peregrine job is finished, and the results will be futher processed in order to create a new report with the outcome.
.. data:: DONE
The schedule rapport is created and uploaded to the database. The Peregrine process is done.
.. data:: INVALID
The entered data is invalid. Either directly by the posting of the form. Or when the Peregrine script could not read the input.
.. data:: FAILURE
Something when wrong on Peregrine. Look at the logging output of the Peregrine job
"""
NEW = 'new', _('New')
ACCEPTED = 'accepted', _('Accepted')
PROCESSING = 'processing', _('Processing')
PROCESSED = 'processed', _('Processed')
DONE = 'done', _('Done')
INVALID = 'invalid', _('Invalid')
FAILURE = 'failure', _('Failure')
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, help_text=_('Select the employee that is responsible for this schedule request'))
name = models.CharField(_('Name'), max_length=100, help_text=_('Name of the schedule'))
email = models.CharField(_('Email address'), max_length=100, help_text=_('Email address where the results will be sent to.'))
status = models.CharField(_('Status'), max_length=10, choices=ScheduleStatus.choices, default=ScheduleStatus.NEW, help_text=_('The status of this schedule.'), db_index=True, )
planning_source = JSONField(_('Schedule input'), blank=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}, help_text=_('The schedule input in JSON format based on the form data'))
peregrine_result = JSONField(_('Peregrine JSON output'), blank=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}, help_text=_('The results from the Peregrine job in JSON'))
output_peregrine = models.BinaryField(_('Peregrine binary output'), blank=True, help_text=_('This is the output in binary format from the Peregrine cluster'))
report_sent = models.DateTimeField(_('Report is send to user'), blank=True, null=True, help_text=_('The date and time when the report has sended to the user.'))
peregrine_output_log = models.TextField(_('Peregrine logging'), blank=True, help_text=_('Here you can see the logging of the Peregrine job.'))
@property
def done(self):
"""
Checks if the processing of this schedule is done on the Peregrine cluster. This can be either with the status:
1. :attr:`~ScheduleStatus.DONE`
2. :attr:`~ScheduleStatus.INVALID`
3. :attr:`~ScheduleStatus.FAILURE`
Returns:
boolean -- True when status is one of the above value.
"""
return self.status in [self.ScheduleStatus.DONE,self.ScheduleStatus.INVALID,self.ScheduleStatus.FAILURE]
def __str__(self):
"""str: Returns a readable name for the schedule. Format is [schedule_name] (employee_name)."""
return '{} ({})'.format(self.name, self.employee)