diff --git a/frontend/src/components/admin/UserModal.jsx b/frontend/src/components/admin/UserModal.jsx
index 0219d688..9e28b5df 100644
--- a/frontend/src/components/admin/UserModal.jsx
+++ b/frontend/src/components/admin/UserModal.jsx
@@ -28,15 +28,30 @@ const UserModal = ({ isOpen, onClose, onSave, initialData = null, clinics = [] }
useEffect(() => {
if (isOpen) {
if (initialData) {
- // Om vi redigerar en veterinär, se till att fälten från vetRecord följer med in i formData
+ const role = (initialData.role || 'OWNER').replace('ROLE_', '');
setFormData({
...initialData,
+ role,
password: '',
- licenseId: initialData.vetRecord?.licenseId || '',
- specialization: initialData.vetRecord?.specialization || '',
- bookingInfo: initialData.vetRecord?.bookingInfo || '',
- clinicId: initialData.vetRecord?.clinicId || ''
+ clinicId: initialData.clinicId || '',
+ licenseId: '',
+ specialization: '',
+ bookingInfo: '',
});
+
+ if (role === 'VET') {
+ vetService.getAll().then(res => {
+ const vetRecord = res.data.find(v => v.userId === initialData.id);
+ if (vetRecord) {
+ setFormData(prev => ({
+ ...prev,
+ licenseId: vetRecord.licenseId || '',
+ specialization: vetRecord.specialization || '',
+ bookingInfo: vetRecord.bookingInfo || '',
+ }));
+ }
+ }).catch(err => console.error('Kunde inte hämta veterinärdetaljer:', err));
+ }
} else {
setFormData({
name: '', email: '', password: '',
@@ -70,12 +85,17 @@ const UserModal = ({ isOpen, onClose, onSave, initialData = null, clinics = [] }
bookingInfo: formData.bookingInfo
};
- // CodeRabbit Fix: Kolla om det redan finns en veterinärpost (Edit vs Create)
- const existingVetId = initialData?.vetRecord?.id;
-
- if (existingVetId) {
- await vetService.update(existingVetId, vetPayload);
- } else if (userId) {
+ if (initialData) {
+ try {
+ await vetService.update(userId, vetPayload);
+ } catch (err) {
+ if (err.response?.status === 404) {
+ await vetService.create(vetPayload);
+ } else {
+ throw err;
+ }
+ }
+ } else {
await vetService.create(vetPayload);
}
}
@@ -211,7 +231,7 @@ const UserModal = ({ isOpen, onClose, onSave, initialData = null, clinics = [] }
{/* VETERINÄR-DETALJER */}
{isVet && (
-
+
diff --git a/frontend/src/pages/AdminDashboard.jsx b/frontend/src/pages/AdminDashboard.jsx
index f42f6f0d..bd103d2e 100644
--- a/frontend/src/pages/AdminDashboard.jsx
+++ b/frontend/src/pages/AdminDashboard.jsx
@@ -83,7 +83,7 @@ const AdminDashboard = ({ userName, initialTab = 'USERS' }) => {
? await userService.update(selectedItem.id, userData)
: await userService.create(userData);
- fetchData();
+ await fetchData();
return response;
};
diff --git a/frontend/src/services/api.jsx b/frontend/src/services/api.jsx
index fa599f2b..224c2275 100644
--- a/frontend/src/services/api.jsx
+++ b/frontend/src/services/api.jsx
@@ -126,6 +126,7 @@ export const userService = {
export const vetService = {
create: (vetData) => api.post('/vets', vetData),
+ update: (userId, vetData) => api.put(`/vets/${userId}`, vetData),
getAll: () => api.get('/vets'),
getById: (id) => api.get(`/vets/${id}`),
};
diff --git a/src/main/java/org/example/vet1177/controller/VetController.java b/src/main/java/org/example/vet1177/controller/VetController.java
index befc856c..d8ef6edc 100644
--- a/src/main/java/org/example/vet1177/controller/VetController.java
+++ b/src/main/java/org/example/vet1177/controller/VetController.java
@@ -41,6 +41,16 @@ public ResponseEntity
createVet(
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
+ @PutMapping("/{userId}")
+ public ResponseEntity updateVet(
+ @AuthenticationPrincipal User user,
+ @PathVariable UUID userId,
+ @Valid @RequestBody VetRequest request) {
+ log.info("PUT /api/vets/{}", userId);
+ adminPolicy.requireAdmin(user);
+ return ResponseEntity.ok(vetService.updateVet(userId, request));
+ }
+
@GetMapping
public ResponseEntity> getAllVets() {
log.info("GET /api/vets");
diff --git a/src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java b/src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java
index dcc50dcb..f41e3287 100644
--- a/src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java
+++ b/src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java
@@ -2,6 +2,7 @@
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Size;
+import org.example.vet1177.entities.Role;
import java.util.UUID;
@@ -15,6 +16,8 @@ public class UserUpdateRequest {
private UUID clinicId;
+ private Role role;
+
public UUID getClinicId() {
return clinicId;
}
@@ -38,4 +41,12 @@ public String getName() {
public void setName(String name) {
this.name = name;
}
+
+ public Role getRole() {
+ return role;
+ }
+
+ public void setRole(Role role) {
+ this.role = role;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java
index 67cdddfa..1aab3da2 100644
--- a/src/main/java/org/example/vet1177/services/UserService.java
+++ b/src/main/java/org/example/vet1177/services/UserService.java
@@ -117,7 +117,14 @@ public UserResponse updateUser(UUID id, UserUpdateRequest request) {
user.setName(request.getName());
}
- if (request.getClinicId() != null) {
+ if (request.getRole() != null) {
+ user.setRole(request.getRole());
+ if (request.getRole() != Role.VET) {
+ user.setClinic(null);
+ }
+ }
+
+ if (request.getClinicId() != null && user.getRole() == Role.VET) {
applyClinicRulesForUpdate(user, request.getClinicId());
}
log.info("Updated user id={}", id);
diff --git a/src/main/java/org/example/vet1177/services/VetService.java b/src/main/java/org/example/vet1177/services/VetService.java
index ef08c7a5..737fa67e 100644
--- a/src/main/java/org/example/vet1177/services/VetService.java
+++ b/src/main/java/org/example/vet1177/services/VetService.java
@@ -66,6 +66,27 @@ public VetResponse createVet(VetRequest request) {
}
}
+ public VetResponse updateVet(UUID userId, VetRequest request) {
+ log.info("Updating vet userId={}", userId);
+ Vet vet = vetRepository.findById(userId)
+ .orElseThrow(() -> new ResourceNotFoundException("Vet", userId));
+
+ if (!vet.getLicenseId().equals(request.licenseId()) &&
+ vetRepository.existsByLicenseId(request.licenseId())) {
+ throw new BusinessRuleException("Licens-ID " + request.licenseId() + " används redan");
+ }
+
+ vet.setLicenseId(request.licenseId());
+ vet.setSpecialization(request.specialization());
+ vet.setBookingInfo(request.bookingInfo());
+
+ try {
+ return VetResponse.from(vetRepository.save(vet));
+ } catch (org.springframework.dao.DataIntegrityViolationException e) {
+ throw new BusinessRuleException("Licens-ID " + request.licenseId() + " används redan");
+ }
+ }
+
@Transactional(readOnly = true)
public List getAllVets() {
log.debug("Fetching all vets");
diff --git a/src/test/java/org/example/vet1177/services/UserServiceTest.java b/src/test/java/org/example/vet1177/services/UserServiceTest.java
index 46a64088..11ceaec8 100644
--- a/src/test/java/org/example/vet1177/services/UserServiceTest.java
+++ b/src/test/java/org/example/vet1177/services/UserServiceTest.java
@@ -316,15 +316,16 @@ void updateUser_vet_changeClinic_updatesClinic() {
}
@Test
- void updateUser_owner_setClinic_throwsBusinessRuleException() {
+ void updateUser_owner_setClinic_isIgnored() {
UserUpdateRequest request = new UserUpdateRequest();
request.setClinicId(clinicId);
when(userRepository.findById(userId)).thenReturn(Optional.of(ownerUser));
+ when(userRepository.save(ownerUser)).thenReturn(ownerUser);
- assertThatThrownBy(() -> userService.updateUser(userId, request))
- .isInstanceOf(BusinessRuleException.class)
- .hasMessageContaining("Endast veterinärer kan kopplas till en klinik");
+ userService.updateUser(userId, request);
+
+ assertThat(ownerUser.getClinic()).isNull();
}
@Test