ae5c1f1848
Ship cash-register registry, section-based portal access, configurable dislocation columns, and trial-hire intern accounts with credentials PDF.
80 lines
3.4 KiB
Python
80 lines
3.4 KiB
Python
from django.core.exceptions import ValidationError
|
|
from django.db import models
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from core.models import BaseModel
|
|
from core.models.directories import directory_default
|
|
|
|
|
|
class CashRegister(BaseModel):
|
|
"""Кассовый аппарат (РРО) или программный РРО (ПРРО) на аптеке."""
|
|
|
|
class Kind(models.TextChoices):
|
|
RRO = 'rro', _('РРО')
|
|
PRRO = 'prro', _('ПРРО')
|
|
|
|
pharmacy = models.ForeignKey(
|
|
'locations.Pharmacy', on_delete=models.PROTECT,
|
|
related_name='cash_registers', verbose_name=_('Аптека'),
|
|
)
|
|
kind = models.CharField(
|
|
_('Тип'), max_length=10, choices=Kind.choices, default=Kind.PRRO,
|
|
)
|
|
fiscal_number = models.CharField(
|
|
_('Фискальный номер'), max_length=64, unique=True,
|
|
)
|
|
serial_number = models.CharField(
|
|
_('Заводской / серийный номер'), max_length=64, blank=True,
|
|
)
|
|
model_name = models.CharField(_('Модель'), max_length=120, blank=True)
|
|
vendor = models.ForeignKey(
|
|
'core.Directory', on_delete=models.SET_NULL,
|
|
null=True, blank=True,
|
|
limit_choices_to={'directory_type__code': 'rro_vendor', 'is_active': True},
|
|
related_name='rro_vendor_registers', verbose_name=_('Производитель / вендор'),
|
|
)
|
|
status = models.ForeignKey(
|
|
'core.Directory', on_delete=models.PROTECT,
|
|
limit_choices_to={'directory_type__code': 'rro_status', 'is_active': True},
|
|
related_name='rro_status_registers', verbose_name=_('Статус'),
|
|
default=directory_default('rro_status', 'active'),
|
|
)
|
|
registered_at = models.DateField(
|
|
_('Дата регистрации в ГНС'), null=True, blank=True,
|
|
)
|
|
cert_expires_at = models.DateField(
|
|
_('Срок сертификата / ключа'), null=True, blank=True,
|
|
help_text=_('Для ПРРО — срок действия КЭП/сертификата (задел под напоминания).'),
|
|
)
|
|
is_primary = models.BooleanField(
|
|
_('Основной на аптеке'), default=False,
|
|
)
|
|
notes = models.TextField(_('Комментарий'), blank=True)
|
|
provider = models.CharField(
|
|
_('Провайдер ПРРО'), max_length=50, blank=True,
|
|
help_text=_('Slug провайдера без интеграции: checkbox, vchasno, …'),
|
|
)
|
|
|
|
class Meta:
|
|
verbose_name = _('Кассовый аппарат')
|
|
verbose_name_plural = _('Кассовые аппараты (РРО/ПРРО)')
|
|
ordering = ['pharmacy__organization__name', 'pharmacy__pharmacy_number', 'fiscal_number']
|
|
indexes = [
|
|
models.Index(fields=['pharmacy', 'status']),
|
|
]
|
|
|
|
def __str__(self):
|
|
label = self.get_kind_display()
|
|
return f'{label} {self.fiscal_number} — {self.pharmacy}'
|
|
|
|
def clean(self):
|
|
super().clean()
|
|
if self.is_primary and self.pharmacy_id:
|
|
qs = CashRegister.objects.filter(pharmacy_id=self.pharmacy_id, is_primary=True)
|
|
if self.pk:
|
|
qs = qs.exclude(pk=self.pk)
|
|
if qs.exists():
|
|
raise ValidationError({
|
|
'is_primary': _('На этой аптеке уже есть основной кассовый аппарат.'),
|
|
})
|