Files
ACORE/apps/rro/models.py
T
lokses ae5c1f1848 Add RRO, portal section perms, dislocation presets, and hiring intern flow.
Ship cash-register registry, section-based portal access, configurable dislocation columns, and trial-hire intern accounts with credentials PDF.
2026-08-09 14:58:17 +03:00

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': _('На этой аптеке уже есть основной кассовый аппарат.'),
})