fix: proširi bilješke na članove tima i osvježi kalendar
Some checks failed
ERP CI/CD Pipeline / test (push) Has been cancelled
ERP CI/CD Pipeline / Deploy (server git pull + compose) (push) Has been cancelled

Widget Bilješke sada omogućuje odabir više članova tima (ne samo
servisera), a backend validacija i testovi su usklađeni.

Dodatno, nakon realtime service_note notifikacije sada se osvježava
service-notes store, te create flow više ne briše lokalne bilješke kada
odgovor vrati praznu listu.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
mariomitte
2026-08-01 09:48:44 +02:00
parent 52f54e3a75
commit e7641e7be0
6 changed files with 59 additions and 20 deletions

View File

@@ -155,12 +155,12 @@ class ServiceContextNoteCreateSerializer(serializers.Serializer):
note_date = serializers.DateField(required=False, allow_null=True)
audience = serializers.ChoiceField(choices=AUDIENCE_CHOICES, default='self')
target_user = serializers.PrimaryKeyRelatedField(
queryset=User.objects.filter(is_active=True),
queryset=User.objects.filter(is_active=True, is_team_member=True),
required=False,
allow_null=True,
)
target_users = serializers.ListField(
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(is_active=True)),
child=serializers.PrimaryKeyRelatedField(queryset=User.objects.filter(is_active=True, is_team_member=True)),
required=False,
allow_empty=False,
)
@@ -203,12 +203,12 @@ class ServiceContextNoteCreateSerializer(serializers.Serializer):
if audience in {'self', 'team'} and target_user:
raise serializers.ValidationError({'target_user': 'Odabrani tip publike ne koristi ciljano polje člana tima.'})
if audience in {'self', 'team'} and len(target_users) > 0:
raise serializers.ValidationError({'target_users': 'Odabrani tip publike ne koristi listu servisera.'})
if target_user and not getattr(target_user, 'is_serviser', False):
raise serializers.ValidationError({'target_user': 'Bilješku je moguće poslati samo serviseru.'})
raise serializers.ValidationError({'target_users': 'Odabrani tip publike ne koristi listu članova tima.'})
if target_user and not getattr(target_user, 'is_team_member', False):
raise serializers.ValidationError({'target_user': 'Bilješku je moguće poslati samo članu tima.'})
for selected_user in target_users:
if not getattr(selected_user, 'is_serviser', False):
raise serializers.ValidationError({'target_users': 'Bilješku je moguće poslati samo serviserima.'})
if not getattr(selected_user, 'is_team_member', False):
raise serializers.ValidationError({'target_users': 'Bilješku je moguće poslati samo članovima tima.'})
if work_order:
if not work_order.is_active or str(work_order.status or '').lower() != 'open':

View File

@@ -41,6 +41,13 @@ class ServiceContextNotesApiTests(TestCase):
is_team_member=True,
is_serviser=True,
)
self.team_member_non_servicer = user_model.objects.create_user(
username=f'team-{suffix}',
email=f'team-{suffix}@example.test',
password='test1234',
is_team_member=True,
is_serviser=False,
)
self.vehicle = Vehicle.objects.create(
asset_type='crane',
@@ -132,3 +139,31 @@ class ServiceContextNotesApiTests(TestCase):
)
self.assertEqual(response.status_code, 201, response.content)
self.assertEqual(int(response.data.get('created_count', 0)), 2)
def test_supervisor_can_create_member_note_for_non_servicer_team_member(self):
self.client.force_authenticate(user=self.supervisor)
response = self.client.post(
reverse('service-context-note-list'),
data={
'note': 'Bilješka za team člana koji nije serviser.',
'audience': 'member',
'target_users': [str(self.team_member_non_servicer.id)],
},
format='json',
)
self.assertEqual(response.status_code, 201, response.content)
self.assertEqual(int(response.data.get('created_count', 0)), 1)
def test_member_note_rejects_non_team_member_target(self):
self.client.force_authenticate(user=self.supervisor)
response = self.client.post(
reverse('service-context-note-list'),
data={
'note': 'Bilješka ne-smije ići van tima.',
'audience': 'member',
'target_users': [str(self.other.id)],
},
format='json',
)
self.assertEqual(response.status_code, 400, response.content)
self.assertIn('target_users', response.data)