it_manager: поиск, фильтры и инвентаризация оборудования.

Добавлены фильтры списка, редактирование инв. номеров/заметок/дат, история выдачи в карточке и тесты.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-07 13:23:00 +03:00
parent 03019898b0
commit be7e5853cb
3 changed files with 437 additions and 31 deletions
+124
View File
@@ -269,6 +269,130 @@ class ItManagerEquipmentTests(TestCase):
EquipmentAssignment.objects.filter(equipment=unit, location=location).count(), 1,
)
def test_search_by_serial_and_inventory(self):
make_equipment(serial_number='SRCH-SN-AA', inventory_number='INV-1001')
make_equipment(serial_number='OTHER-99', inventory_number='INV-2002')
r = self.client.get('/it-manager/', {'tab': 'equipment', 'q': 'SRCH-SN'})
self.assertEqual(r.status_code, 200)
serials = [e.serial_number for e in r.context['equipment_page']]
self.assertEqual(serials, ['SRCH-SN-AA'])
r = self.client.get('/it-manager/', {'tab': 'equipment', 'q': 'INV-2002'})
self.assertEqual(r.status_code, 200)
serials = [e.serial_number for e in r.context['equipment_page']]
self.assertEqual(serials, ['OTHER-99'])
def test_filter_by_status_and_location(self):
from apps.locations.models.base import Location
from core.models.directories import DirectoryType
region_type, _ = DirectoryType.objects.get_or_create(
code='location_region', defaults={'name': 'Регион'},
)
region, _ = Directory.objects.get_or_create(
directory_type=region_type, code='eq-filt-reg', defaults={'name': 'Фильтр'},
)
loc_a = Location.objects.create(
address='Лок А', location_type='pharmacy',
location_region=region, is_active=True,
)
loc_b = Location.objects.create(
address='Лок Б', location_type='pharmacy',
location_region=region, is_active=True,
)
stock = make_equipment(serial_number='FILT-STOCK')
assigned = make_equipment(
serial_number='FILT-ASGN',
status_id=_dir_id('equipment_status', 'assigned'),
location=loc_a,
)
make_equipment(
serial_number='FILT-OTHER',
status_id=_dir_id('equipment_status', 'assigned'),
location=loc_b,
)
r = self.client.get('/it-manager/', {'tab': 'equipment', 'status': 'stock'})
self.assertEqual(r.status_code, 200)
serials = [e.serial_number for e in r.context['equipment_page']]
self.assertIn('FILT-STOCK', serials)
self.assertNotIn('FILT-ASGN', serials)
r = self.client.get('/it-manager/', {
'tab': 'equipment', 'status': 'assigned', 'location_id': str(loc_a.pk),
})
self.assertEqual(r.status_code, 200)
serials = [e.serial_number for e in r.context['equipment_page']]
self.assertEqual(serials, ['FILT-ASGN'])
self.assertEqual(stock.status.code, 'stock')
self.assertEqual(assigned.location_id, loc_a.pk)
def test_update_inventory_number_and_notes(self):
equipment = make_equipment(serial_number='INV-EDIT-1')
r = self.client.post(f'/it-manager/equipment/{equipment.id}/update/', {
'status': 'stock',
'assign_target': '',
'inventory_number': 'INV-EDIT-99',
'notes': 'Проверено на складе',
'purchase_date': '2025-06-01',
'warranty_until': '2027-06-01',
}, HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
equipment.refresh_from_db()
self.assertEqual(equipment.inventory_number, 'INV-EDIT-99')
self.assertEqual(equipment.notes, 'Проверено на складе')
self.assertEqual(str(equipment.purchase_date), '2025-06-01')
self.assertEqual(str(equipment.warranty_until), '2027-06-01')
other = make_equipment(serial_number='INV-EDIT-2', inventory_number='INV-TAKEN')
r = self.client.post(f'/it-manager/equipment/{equipment.id}/update/', {
'status': 'stock',
'assign_target': '',
'inventory_number': other.inventory_number,
'notes': equipment.notes,
}, HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
self.assertContains(r, 'уже используется')
equipment.refresh_from_db()
self.assertEqual(equipment.inventory_number, 'INV-EDIT-99')
def test_bulk_create_with_inventory_numbers(self):
model = make_equipment_model()
r = self.client.post('/it-manager/equipment/bulk-create/', {
'equipment_model_id': str(model.pk),
'serial_numbers': 'SN-INV-1\nSN-INV-2',
'inventory_numbers': 'INV-A1\nINV-A2',
}, HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
u1 = Equipment.objects.get(serial_number='SN-INV-1')
u2 = Equipment.objects.get(serial_number='SN-INV-2')
self.assertEqual(u1.inventory_number, 'INV-A1')
self.assertEqual(u2.inventory_number, 'INV-A2')
r = self.client.post('/it-manager/equipment/bulk-create/', {
'equipment_model_id': str(model.pk),
'serial_numbers': 'SN-INV-3\nSN-INV-4',
'inventory_numbers': 'INV-ONLY-ONE',
}, HTTP_HX_REQUEST='true')
self.assertEqual(r.status_code, 200)
self.assertContains(r, 'должно совпадать')
self.assertFalse(Equipment.objects.filter(serial_number='SN-INV-3').exists())
def test_assignment_history_visible_in_card(self):
equipment = make_equipment(serial_number='HIST-UI-1')
emp = make_employee(first_name='Иван', last_name='Историков')
self.client.post(f'/it-manager/equipment/{equipment.id}/update/', {
'status': 'assigned',
'assign_target': 'employee',
'assigned_to_id': emp.id,
})
r = self.client.get('/it-manager/', {'tab': 'equipment', 'q': 'HIST-UI-1'})
self.assertEqual(r.status_code, 200)
self.assertContains(r, 'История перемещений')
self.assertContains(r, 'Историков')
self.assertContains(r, 'открыта')
class ItManagerTicketTests(TestCase):