Example #1
0
class ServiceWorkOrder(models.Model):
    STATUS_CHOICES = [('requested', 'Requested'), ('progress', 'In progress'),
                      ('completed', 'Completed'), ('authorized', 'Authorized'),
                      ('declined', 'Declined')]
    date = models.DateField()
    time = models.TimeField(
        choices=time_choices('06:00:00', '18:30:00', '00:30:00'))
    # for services done within the organization
    internal = models.BooleanField(default=False)

    works_request = models.ForeignKey('services.workorderrequest',
                                      blank=True,
                                      null=True,
                                      on_delete=models.SET_NULL)

    description = models.TextField(blank=True, default="")
    completed = models.DateTimeField(null=True, blank=True)
    expected_duration = models.DurationField(choices=time_choices('00:00:00',
                                                                  '08:00:00',
                                                                  '00:30:00',
                                                                  delta=True),
                                             null=True,
                                             blank=True)
    service_people = models.ManyToManyField('services.ServicePerson',
                                            blank=True)
    team = models.ForeignKey('services.ServiceTeam',
                             on_delete=models.SET_NULL,
                             null=True,
                             blank=True)
    status = models.CharField(max_length=16,
                              choices=STATUS_CHOICES,
                              blank=True)
    authorized_by = models.ForeignKey(
        'employees.Employee',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        limit_choices_to=Q(user__isnull=False))  #filter queryset
    notes = models.ManyToManyField('common_data.note')
    progress = models.CharField(max_length=512, blank=True, default="")

    def __str__(self):
        return "WO{}".format(self.pk)  #TODO string padding

    @property
    def procedure_pk(self):
        if self.works_request.service.procedure:
            return self.works_request.service.procedure.pk

        return None

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if self.works_request:
            self.works_request.update_status()

    @property
    def number_of_employees(self):
        direct = self.service_people.all().count()
        team = 0
        if self.team:
            team = self.team.members.all().count()

        return direct + team

    @property
    def expenses(self):
        return self.workorderexpense_set.all()

    @property
    def time_logs(self):
        # may decide to remove the .all() and use a filter of uses timesheet
        return self.timelog_set.all()

    @property
    def progress_list(self):
        pl = self.progress.split(",") if self.progress != "" else []
        return [int(i) for i in pl]

    @property
    def progress_percentage(self):
        if not self.works_request.service.procedure or \
                self.works_request.service.procedure.steps.count() ==0:
            return 100

        total_steps = self.works_request.service.procedure.steps.count()
        progress = len(self.progress_list)

        return int(float(progress) * 100.0 / float(total_steps))

    @property
    def total_normal_time(self):
        return reduce(lambda x, y: x + y, [i.normal_time \
                for i in self.time_logs], datetime.timedelta(seconds=0))

    @property
    def total_overtime(self):
        return reduce(lambda x, y: x + y, [i.overtime for i in self.time_logs],
                      datetime.timedelta(seconds=0))

    def get_absolute_url(self):
        return reverse("services:work-order-detail", kwargs={"pk": self.pk})
Example #2
0
 def test_time_choices(self):
     output = time_choices('06:00:00', '12:00:00', '00:30:00')
     self.assertEqual(len(output), 12)
     time = datetime.datetime.strptime('11:30:00', "%H:%M:%S").time()
     self.assertEqual(output[11][0], time)
Example #3
0
class Event(models.Model):
    REMINDER_CHOICES = [
        (datetime.timedelta(seconds=0), 'At event start'),
        (datetime.timedelta(minutes=15), '15 min before'),
        (datetime.timedelta(hours=1), '1 hour before'),
        (datetime.timedelta(hours=3), '3 hour before'),
        (datetime.timedelta(hours=6), '6 hours before'),
        (datetime.timedelta(days=1), '1 Day before'),
        (datetime.timedelta(days=3), '3 Days before'),
        (datetime.timedelta(days=7), '1 week before'),
        (datetime.timedelta(days=14), '2 weeks before'),
        (datetime.timedelta(days=30), '1 month before')
    ]
    
    TIME_CHOICES = time_choices('06:00:00','18:00:00','00:30:00')
    
    PRIORITY_CHOICES = [
        ('normal', 'Normal'),
        ('high', 'High'),
        ('low', 'Low')
    ]
    ICON_CHOICES = [
        ('file-chart-line', 'Report'),
        ('truck', 'Delivery'),
        ('users', 'Meeting'),
        ('stopwatch', 'Deadline'),
        ('book', 'Training'),
        ('calendar', 'Event')
    ]
    REPEAT_CHOICES = [
        (0, 'Never'),
        (1, 'Daily'),
        (2, 'Weekly'),
        (3, 'Monthly'),
        (4, 'Annually'),

    ]

    date = models.DateField()
    reminder = models.DurationField(choices=REMINDER_CHOICES, 
        default=datetime.timedelta(seconds=0))
    completed = models.BooleanField(default=False, blank=True)
    completion_time = models.DateTimeField(null=True, blank=True)
    start_time = models.TimeField(choices=TIME_CHOICES, default="06:00:00")
    end_time = models.TimeField(choices=TIME_CHOICES, default="06:00:00")
    priority = models.CharField(max_length=8, choices=PRIORITY_CHOICES, 
        default='normal')
    description = models.TextField(blank=True)
    repeat = models.PositiveSmallIntegerField(default=0, choices=REPEAT_CHOICES)
    repeat_active = models.BooleanField(default=False, blank=True)
    label = models.CharField(max_length=32, blank=True) 
    icon = models.CharField(max_length=32, blank=True, choices=ICON_CHOICES)
    owner = models.ForeignKey('auth.User', on_delete=models.SET_NULL, null=True)
    reminder_notification = models.ForeignKey('messaging.notification', 
        blank=True, null=True, on_delete=models.SET_NULL)

    def get_absolute_url(self):
        return reverse("planner:event-detail", kwargs={"pk": self.pk})
    

    @property
    def participants(self):
        return EventParticipant.objects.filter(event=self)

    def add_participant(self, evt_type, pk):
        evt_mapping = {
            'supplier': 2,
            'employee': 0,
            'customer': 1
        }
        evt_type = evt_mapping[evt_type]
        participant = None 
        if evt_type == 0:
            participant = EventParticipant.objects.create(
                event=self,
                participant_type = evt_type,
                employee=Employee.objects.get(pk=pk)
            )
        elif evt_type == 1:
            participant = EventParticipant.objects.create(
                event=self,
                participant_type = evt_type,
                customer=Customer.objects.get(pk=pk)
            )
        elif evt_type == 2:
            participant = EventParticipant.objects.create(
                event=self,
                participant_type = evt_type,
                supplier=inventory.models.Supplier.objects.get(pk=pk)
            )
        else:
            raise Exception('no type was specified')

        return participant

    
    def complete(self):
        self.completed = True
        self.completion_time = datetime.datetime.now()
        self.save()

    @property
    def repeat_string(self):
        mapping = dict(self.REPEAT_CHOICES)
        return mapping[self.repeat]

    def repeat_on_date(self, date):
        # eliminate past dates at the begining
        if self.date > date:
            return False 

        if self.repeat == 0:
            return False

        elif self.repeat == 1:
            return True

        elif self.repeat == 2:
            if self.date.weekday() == date.weekday():
                return True
            return False

        elif self.repeat == 3:
            if self.date.day == date.day:
                return True
            return False

        elif self.repeat == 4:
            if self.date.day == date.day and self.date.month == date.month:
                return True
            return False

        return False

    def __str__(self):
        return self.label
Example #4
0
class ServiceWorkOrder(models.Model):
    STATUS_CHOICES = [('requested', 'Requested'), ('progress', 'In progress'),
                      ('completed', 'Completed'), ('authorized', 'Authorized'),
                      ('declined', 'Declined')]
    date = models.DateField()
    time = models.TimeField(
        choices=time_choices('00:00:00', '23:30:00', '00:30:00'))
    # for services done within the organization
    internal = models.BooleanField(default=False)

    works_request = models.ForeignKey('services.workorderrequest',
                                      blank=True,
                                      null=True,
                                      on_delete=models.SET_NULL)

    description = models.TextField(blank=True, default="")
    completed = models.DateTimeField(null=True, blank=True)
    expected_duration = models.DurationField(choices=time_choices('00:00:00',
                                                                  '23:30:00',
                                                                  '00:30:00',
                                                                  delta=True),
                                             null=True,
                                             blank=True)
    service_people = models.ManyToManyField('services.ServicePerson',
                                            limit_choices_to=Q(active=True),
                                            blank=True)
    team = models.ForeignKey('services.ServiceTeam',
                             on_delete=models.SET_NULL,
                             null=True,
                             blank=True)
    status = models.CharField(max_length=16,
                              choices=STATUS_CHOICES,
                              blank=True)
    authorized_by = models.ForeignKey(
        'employees.Employee',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        limit_choices_to=Q(user__isnull=False))  # filter queryset
    notes = models.ManyToManyField('common_data.note')

    def __str__(self):
        return "WO{}".format(self.pk)  # TODO string padding

    @property
    def procedure_pk(self):
        if self.works_request.service.procedure:
            return self.works_request.service.procedure.pk

        return None

    @property
    def completed_tasks(self):
        return self.workordertask_set.filter(completed=True)

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if self.works_request:
            self.works_request.update_status()

            procedure = self.works_request.service.procedure
            if procedure and self.workordertask_set.all().count() == 0:
                due = datetime.date.today()
                if self.works_request.invoice:
                    due = self.works_request.invoice.due

                for step in procedure.steps:
                    WorkOrderTask.objects.create(
                        work_order=self,
                        description=step.description,
                        due=due,
                        start=due,
                    )

    @property
    def number_of_employees(self):
        direct = self.service_people.all().count()
        team = 0
        if self.team:
            team = self.team.members.all().count()

        return direct + team

    @property
    def expenses(self):
        return self.workorderexpense_set.all()

    @property
    def unbilled_expenses(self):
        return self.workorderexpense_set.filter(expense__billable=False)

    @property
    def time_logs(self):
        # may decide to remove the .all() and use a filter of uses timesheet
        return self.timelog_set.all()

    @property
    def total_normal_time(self):
        return reduce(lambda x, y: x + y,
                      [i.normal_time for i in self.time_logs],
                      datetime.timedelta(seconds=0))

    @property
    def total_overtime(self):
        return reduce(lambda x, y: x + y, [i.overtime for i in self.time_logs],
                      datetime.timedelta(seconds=0))

    def get_absolute_url(self):
        return reverse("services:work-order-detail", kwargs={"pk": self.pk})

    @property
    def status_string(self):
        return dict(self.STATUS_CHOICES)[self.status]

    @property
    def consumables_used(self):
        return ConsumablesRequisitionLine.objects.filter(
            requisition__work_order=self)

    @property
    def total_expenses(self):
        return sum([i.expense.amount for i in self.expenses])

    @property
    def total_time(self):
        return self.total_overtime + self.total_normal_time