эксплуатация: показания счётчиков, энергоактивы и РРО

Конфиг счётчиков и день/ночь-тарифы, учёт энергосистем (генераторы,
инверторы), доступ к разделу РРО/ПРРО.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 18:03:44 +03:00
parent 3e969e29dc
commit 16bf2cf1c7
26 changed files with 2044 additions and 88 deletions
+109
View File
@@ -0,0 +1,109 @@
from django.contrib.auth.models import Permission
from django.test import Client, TestCase
from apps.locations.models.base import Location
from apps.power_assets.models import PowerAsset, PowerAssetService
from core.models.directories import Directory, DirectoryType
from core.test_utils import login_2fa
from core.tests_portal_access import make_employee
class PowerAssetsTests(TestCase):
def setUp(self):
self.user = make_employee(is_staff=True)
perm = Permission.objects.get(codename='access_utilities')
self.user.user_permissions.add(perm)
self.client = Client()
login_2fa(self.client, self.user)
region_type, _ = DirectoryType.objects.get_or_create(
code='location_region', defaults={'name': 'Регион'},
)
region, _ = Directory.objects.get_or_create(
directory_type=region_type, code='pwr', defaults={'name': 'PWR'},
)
self.location = Location.objects.create(
address='Аптека энерго', location_type='pharmacy',
location_region=region, is_active=True,
)
type_dt, _ = DirectoryType.objects.get_or_create(
code='power_asset_type', defaults={'name': 'Тип'},
)
status_dt, _ = DirectoryType.objects.get_or_create(
code='power_asset_status', defaults={'name': 'Статус'},
)
self.inv_type, _ = Directory.objects.get_or_create(
directory_type=type_dt, code='inverter',
defaults={'name': 'Инвертор', 'is_active': True},
)
self.gen_type, _ = Directory.objects.get_or_create(
directory_type=type_dt, code='generator',
defaults={'name': 'Генератор', 'is_active': True},
)
self.status, _ = Directory.objects.get_or_create(
directory_type=status_dt, code='active',
defaults={'name': 'В работе', 'is_active': True},
)
def test_power_tab_visible_with_utilities(self):
r = self.client.get('/accounting/?tab=power', HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
self.assertEqual(r.context['accounting_active_tab'], 'power')
tab_keys = [t[0] for t in r.context['accounting_tabs']]
self.assertIn('power', tab_keys)
def test_create_inverter_on_location(self):
r = self.client.post('/power-assets/create/', {
'asset_type': str(self.inv_type.pk),
'location_id': str(self.location.pk),
'status': str(self.status.pk),
'brand': 'Deye',
'model_name': 'SUN-8K',
'serial_number': 'INV-1',
'capacity_kw': '8',
'battery_capacity_kwh': '10',
'installed_at': '2026-01-15',
}, HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
asset = PowerAsset.objects.get(serial_number='INV-1')
self.assertEqual(asset.location_id, self.location.pk)
self.assertEqual(asset.asset_type_id, self.inv_type.pk)
self.assertEqual(str(asset.capacity_kw), '8.00')
def test_create_generator(self):
r = self.client.post('/power-assets/create/', {
'asset_type': str(self.gen_type.pk),
'location_id': str(self.location.pk),
'status': str(self.status.pk),
'brand': 'Honda',
'model_name': 'EU70is',
'fuel_type': 'бензин',
'capacity_kw': '7',
}, HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
self.assertTrue(PowerAsset.objects.filter(model_name='EU70is', fuel_type='бензин').exists())
def test_service_log_updates_next_service_date(self):
asset = PowerAsset.objects.create(
asset_type=self.gen_type,
location=self.location,
status=self.status,
model_name='EU22i',
brand='Honda',
created_by=self.user,
)
r = self.client.post(f'/power-assets/{asset.pk}/service/', {
'service_date': '2026-09-01',
'kind': 'oil_change',
'description': 'Замена масла и фильтра',
'performed_by_name': 'Иванов И.',
'engine_hours': '120.5',
'next_service_at': '2026-12-01',
}, HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
asset.refresh_from_db()
self.assertEqual(asset.last_serviced_at.isoformat(), '2026-09-01')
self.assertEqual(asset.next_service_at.isoformat(), '2026-12-01')
log = PowerAssetService.objects.get(asset=asset)
self.assertEqual(log.kind, 'oil_change')
self.assertEqual(str(log.engine_hours), '120.5')