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