ae5c1f1848
Ship cash-register registry, section-based portal access, configurable dislocation columns, and trial-hire intern accounts with credentials PDF.
135 lines
5.4 KiB
Python
135 lines
5.4 KiB
Python
from datetime import date
|
|
|
|
from django.contrib.auth import get_user_model
|
|
from django.core.exceptions import ValidationError
|
|
from django.db import IntegrityError, transaction
|
|
from django.test import TestCase
|
|
|
|
from core.models import Directory, DirectoryType
|
|
from apps.locations.models import Pharmacy
|
|
from apps.rro.models import CashRegister
|
|
|
|
Employee = get_user_model()
|
|
|
|
|
|
class CashRegisterModelTests(TestCase):
|
|
@classmethod
|
|
def setUpTestData(cls):
|
|
org_type = DirectoryType.objects.create(code='organization', name='Организация')
|
|
region_type = DirectoryType.objects.create(code='region', name='Регион')
|
|
status_type, _ = DirectoryType.objects.get_or_create(
|
|
code='rro_status', defaults={'name': 'Статус РРО/ПРРО', 'hierarchy_type': 'strict'},
|
|
)
|
|
cls.status_active, _ = Directory.objects.get_or_create(
|
|
directory_type=status_type, code='active',
|
|
defaults={'name': 'Активный', 'is_active': True},
|
|
)
|
|
cls.region = Directory.objects.create(directory_type=region_type, code='od', name='Одесса')
|
|
cls.org = Directory.objects.create(directory_type=org_type, code='akc', name='АКС')
|
|
cls.pharmacy = Pharmacy.objects.create(
|
|
organization=cls.org, location_region=cls.region,
|
|
pharmacy_number=42, location_type='pharmacy',
|
|
street='Тестовая', house_number='1',
|
|
)
|
|
cls.pharmacy2 = Pharmacy.objects.create(
|
|
organization=cls.org, location_region=cls.region,
|
|
pharmacy_number=43, location_type='pharmacy',
|
|
street='Другая', house_number='2',
|
|
)
|
|
|
|
def _reg(self, **kw):
|
|
defaults = {
|
|
'pharmacy': self.pharmacy,
|
|
'kind': CashRegister.Kind.PRRO,
|
|
'fiscal_number': kw.pop('fiscal_number', f'FN-{CashRegister.objects.count()+1}'),
|
|
'status': self.status_active,
|
|
}
|
|
defaults.update(kw)
|
|
return CashRegister(**defaults)
|
|
|
|
def test_seed_statuses_exist(self):
|
|
codes = set(
|
|
Directory.objects.filter(directory_type__code='rro_status')
|
|
.values_list('code', flat=True)
|
|
)
|
|
self.assertTrue({'active', 'reserve', 'repair', 'decommissioned'} <= codes)
|
|
|
|
def test_unique_fiscal_number(self):
|
|
self._reg(fiscal_number='FN-UNIQUE').save()
|
|
with self.assertRaises(IntegrityError):
|
|
with transaction.atomic():
|
|
self._reg(fiscal_number='FN-UNIQUE', pharmacy=self.pharmacy2).save()
|
|
|
|
def test_only_one_primary_per_pharmacy(self):
|
|
a = self._reg(fiscal_number='FN-P1', is_primary=True)
|
|
a.full_clean()
|
|
a.save()
|
|
b = self._reg(fiscal_number='FN-P2', is_primary=True)
|
|
with self.assertRaises(ValidationError):
|
|
b.full_clean()
|
|
|
|
def test_primary_ok_on_different_pharmacies(self):
|
|
a = self._reg(fiscal_number='FN-A', is_primary=True)
|
|
a.full_clean()
|
|
a.save()
|
|
b = self._reg(fiscal_number='FN-B', pharmacy=self.pharmacy2, is_primary=True)
|
|
b.full_clean()
|
|
b.save()
|
|
|
|
|
|
class CashRegisterPortalTests(TestCase):
|
|
@classmethod
|
|
def setUpTestData(cls):
|
|
org_type = DirectoryType.objects.create(code='organization', name='Организация')
|
|
region_type = DirectoryType.objects.create(code='region', name='Регион')
|
|
status_type, _ = DirectoryType.objects.get_or_create(
|
|
code='rro_status', defaults={'name': 'Статус РРО/ПРРО', 'hierarchy_type': 'strict'},
|
|
)
|
|
cls.status_active, _ = Directory.objects.get_or_create(
|
|
directory_type=status_type, code='active',
|
|
defaults={'name': 'Активный', 'is_active': True},
|
|
)
|
|
region = Directory.objects.create(directory_type=region_type, code='kv', name='Киев')
|
|
org = Directory.objects.create(directory_type=org_type, code='org', name='ТестОрг')
|
|
cls.pharmacy = Pharmacy.objects.create(
|
|
organization=org, location_region=region,
|
|
pharmacy_number=7, location_type='pharmacy',
|
|
street='Главная', house_number='7',
|
|
)
|
|
CashRegister.objects.create(
|
|
pharmacy=cls.pharmacy, kind=CashRegister.Kind.RRO,
|
|
fiscal_number='FN-PORTAL-1', status=cls.status_active,
|
|
model_name='Datecs FP-700', is_primary=True,
|
|
)
|
|
cls.user = Employee.objects.create(
|
|
username='rro.staff',
|
|
email='rro.staff@company.local',
|
|
first_name='РРО',
|
|
last_name='Тест',
|
|
hire_date=date(2026, 1, 1),
|
|
user_location_type='office',
|
|
is_staff=True,
|
|
mattermost_sync_enabled=False,
|
|
ad_sync_enabled=False,
|
|
totp_enabled=True,
|
|
)
|
|
|
|
def _login(self):
|
|
self.client.force_login(self.user)
|
|
session = self.client.session
|
|
session['2fa_verified'] = True
|
|
session.save()
|
|
|
|
def test_rro_list_page(self):
|
|
self._login()
|
|
resp = self.client.get('/rro/', HTTP_HX_REQUEST='true')
|
|
self.assertEqual(resp.status_code, 200)
|
|
self.assertContains(resp, 'FN-PORTAL-1')
|
|
|
|
def test_pharmacy_detail_rro_tab(self):
|
|
self._login()
|
|
resp = self.client.get(f'/pharmacies/{self.pharmacy.pk}/', HTTP_HX_REQUEST='true')
|
|
self.assertEqual(resp.status_code, 200)
|
|
self.assertContains(resp, 'FN-PORTAL-1')
|
|
self.assertContains(resp, 'ph-panel-rro')
|