it_manager: поиск, фильтры и инвентаризация оборудования.
Добавлены фильтры списка, редактирование инв. номеров/заметок/дат, история выдачи в карточке и тесты. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user