Initial commit — ACORE pharmacy network management system
Django project: employees, locations, visit_manager, it_manager, mattermost_connector and stub connectors (ad, mail, portal).
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class WorkLog(models.Model):
|
||||
WORK_TYPES = [
|
||||
('maintenance', 'Техническое обслуживание'),
|
||||
('installation', 'Установка / настройка'),
|
||||
('repair', 'Ремонт'),
|
||||
('network', 'Сетевые работы'),
|
||||
('software', 'Программное обеспечение'),
|
||||
('backup', 'Резервное копирование'),
|
||||
('other', 'Другое'),
|
||||
]
|
||||
|
||||
date = models.DateField('Дата', default=timezone.localdate, db_index=True)
|
||||
technician = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, on_delete=models.PROTECT,
|
||||
related_name='work_logs', verbose_name='Исполнитель',
|
||||
)
|
||||
location = models.ForeignKey(
|
||||
'locations.Location', on_delete=models.SET_NULL,
|
||||
null=True, blank=True,
|
||||
related_name='work_logs', verbose_name='Локация',
|
||||
)
|
||||
work_type = models.CharField('Вид работ', max_length=20, choices=WORK_TYPES, db_index=True)
|
||||
description = models.TextField('Описание работ')
|
||||
result = models.TextField('Результат', blank=True)
|
||||
hours_spent = models.DecimalField('Затрачено часов', max_digits=5, decimal_places=1,
|
||||
null=True, blank=True)
|
||||
|
||||
equipment = models.ForeignKey(
|
||||
'it_manager.Equipment', on_delete=models.SET_NULL,
|
||||
null=True, blank=True,
|
||||
related_name='work_logs', verbose_name='Оборудование',
|
||||
)
|
||||
ticket = models.ForeignKey(
|
||||
'it_manager.Ticket', on_delete=models.SET_NULL,
|
||||
null=True, blank=True,
|
||||
related_name='work_logs', verbose_name='Заявка',
|
||||
)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Выполненная работа'
|
||||
verbose_name_plural = 'Журнал выполненных работ'
|
||||
ordering = ['-date', '-created_at']
|
||||
indexes = [
|
||||
models.Index(fields=['date', 'technician']),
|
||||
models.Index(fields=['work_type']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.get_work_type_display()} — {self.technician} — {self.date:%d.%m.%Y}'
|
||||
|
||||
|
||||
class ServiceCall(models.Model):
|
||||
CHANNEL_CHOICES = [
|
||||
('phone', 'Телефон'),
|
||||
('chat', 'Чат / мессенджер'),
|
||||
('email', 'Email'),
|
||||
('personal', 'Личный визит'),
|
||||
('other', 'Другое'),
|
||||
]
|
||||
|
||||
date_time = models.DateTimeField('Дата и время', default=timezone.now, db_index=True)
|
||||
caller = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, on_delete=models.PROTECT,
|
||||
related_name='service_calls_made', verbose_name='Кто обратился',
|
||||
)
|
||||
handler = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
|
||||
null=True, blank=True,
|
||||
related_name='service_calls_handled', verbose_name='Принял обращение',
|
||||
)
|
||||
channel = models.CharField('Канал', max_length=20, choices=CHANNEL_CHOICES, db_index=True)
|
||||
location = models.ForeignKey(
|
||||
'locations.Location', on_delete=models.SET_NULL,
|
||||
null=True, blank=True,
|
||||
related_name='service_calls', verbose_name='Локация',
|
||||
)
|
||||
description = models.TextField('Описание обращения')
|
||||
resolution = models.TextField('Решение', blank=True)
|
||||
minutes_spent = models.PositiveSmallIntegerField('Затрачено минут', null=True, blank=True)
|
||||
|
||||
ticket = models.ForeignKey(
|
||||
'it_manager.Ticket', on_delete=models.SET_NULL,
|
||||
null=True, blank=True,
|
||||
related_name='service_calls', verbose_name='Связанная заявка',
|
||||
help_text='Если обращение переросло в тикет',
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Обращение'
|
||||
verbose_name_plural = 'Обращения'
|
||||
ordering = ['-date_time']
|
||||
indexes = [
|
||||
models.Index(fields=['date_time', 'handler']),
|
||||
models.Index(fields=['channel']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return (f'{self.get_channel_display()} — {self.caller} — '
|
||||
f'{self.date_time:%d.%m.%Y %H:%M}')
|
||||
|
||||
@property
|
||||
def duration_display(self):
|
||||
if not self.minutes_spent:
|
||||
return '—'
|
||||
if self.minutes_spent < 60:
|
||||
return f'{self.minutes_spent} мин.'
|
||||
h, m = divmod(self.minutes_spent, 60)
|
||||
return f'{h}ч {m}м' if m else f'{h}ч'
|
||||
Reference in New Issue
Block a user