fixed spinners to populate the correct pets in edit mode for adoptions

This commit is contained in:
Alex
2026-04-10 02:58:14 -06:00
parent 57ad824d67
commit 5b1e0ea115
6 changed files with 75 additions and 35 deletions

View File

@@ -44,6 +44,9 @@ public interface PetApi {
@GET("api/v1/dropdowns/adoption-pets") @GET("api/v1/dropdowns/adoption-pets")
Call<List<DropdownDTO>> getAdoptionPets(); Call<List<DropdownDTO>> getAdoptionPets();
@GET("api/v1/dropdowns/pets")
Call<List<DropdownDTO>> getPetDropdowns();
// Get pet by id // Get pet by id
@GET("api/v1/pets/{id}") @GET("api/v1/pets/{id}")
Call<PetDTO> getPetById(@Path("id") Long id); Call<PetDTO> getPetById(@Path("id") Long id);

View File

@@ -54,7 +54,9 @@ public class AdoptionDetailFragment extends Fragment {
setupSpinners(); setupSpinners();
setupDatePicker(); setupDatePicker();
observeViewModel(); observeViewModel();
viewModel.loadInitialFormData(); Bundle args = getArguments();
boolean isEditing = args != null && args.containsKey("adoptionId");
viewModel.loadInitialFormData(isEditing);
handleArguments(); handleArguments();
binding.btnAdoptionBack.setOnClickListener(v -> navigateBack()); binding.btnAdoptionBack.setOnClickListener(v -> navigateBack());

View File

@@ -25,6 +25,8 @@ import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils; import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.AppointmentDetailViewModel; import com.example.petstoremobile.viewmodels.AppointmentDetailViewModel;
import java.util.List;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
/** /**
@@ -35,12 +37,6 @@ public class AppointmentDetailFragment extends Fragment {
private FragmentAppointmentDetailBinding binding; private FragmentAppointmentDetailBinding binding;
private long preselectedPetId = -1;
private long preselectedServiceId = -1;
private long preselectedCustomerId = -1;
private long preselectedStoreId = -1;
private long preselectedStaffId = -1;
private final Integer[] HOURS = {9, 10, 11, 12, 13, 14, 15, 16, 17}; private final Integer[] HOURS = {9, 10, 11, 12, 13, 14, 15, 16, 17};
private final Integer[] MINUTES = {0, 15, 30, 45}; private final Integer[] MINUTES = {0, 15, 30, 45};
@@ -125,20 +121,35 @@ public class AppointmentDetailFragment extends Fragment {
private void observeViewModel() { private void observeViewModel() {
viewModel.getViewState().observe(getViewLifecycleOwner(), this::applyViewState); viewModel.getViewState().observe(getViewLifecycleOwner(), this::applyViewState);
viewModel.getCustomers().observe(getViewLifecycleOwner(), list -> viewModel.getCustomers().observe(getViewLifecycleOwner(), list -> {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerCustomer, list, DropdownDTO::getLabel, "-- Select Customer --", preselectedCustomerId, DropdownDTO::getId)); AppointmentDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long id = state != null ? state.selectedCustomerId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerCustomer, list, DropdownDTO::getLabel, "-- Select Customer --", id, DropdownDTO::getId);
});
viewModel.getStores().observe(getViewLifecycleOwner(), list -> viewModel.getStores().observe(getViewLifecycleOwner(), list -> {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStore, list, DropdownDTO::getLabel, "-- Select Store --", preselectedStoreId, DropdownDTO::getId)); AppointmentDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long id = state != null ? state.selectedStoreId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStore, list, DropdownDTO::getLabel, "-- Select Store --", id, DropdownDTO::getId);
});
viewModel.getServices().observe(getViewLifecycleOwner(), list -> viewModel.getServices().observe(getViewLifecycleOwner(), list -> {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerService, list, ServiceDTO::getServiceName, "-- Select Service --", preselectedServiceId, ServiceDTO::getServiceId)); AppointmentDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long id = state != null ? state.selectedServiceId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerService, list, ServiceDTO::getServiceName, "-- Select Service --", id, ServiceDTO::getServiceId);
});
viewModel.getCustomerPets().observe(getViewLifecycleOwner(), list -> viewModel.getCustomerPets().observe(getViewLifecycleOwner(), list -> {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerPet, list, DropdownDTO::getLabel, "-- Select Pet --", preselectedPetId, DropdownDTO::getId)); AppointmentDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long id = state != null ? state.selectedPetId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerPet, list, DropdownDTO::getLabel, "-- Select Pet --", id, DropdownDTO::getId);
});
viewModel.getStoreEmployees().observe(getViewLifecycleOwner(), list -> viewModel.getStoreEmployees().observe(getViewLifecycleOwner(), list -> {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaff, list, DropdownDTO::getLabel, "-- Select Staff --", preselectedStaffId, DropdownDTO::getId)); AppointmentDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long id = state != null ? state.selectedStaffId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaff, list, DropdownDTO::getLabel, "-- Select Staff --", id, DropdownDTO::getId);
});
} }
private void setLoading(boolean loading) { private void setLoading(boolean loading) {
@@ -171,6 +182,27 @@ public class AppointmentDetailFragment extends Fragment {
SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerAppointmentStatus, state.availableStatuses); SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerAppointmentStatus, state.availableStatuses);
SpinnerUtils.setSelectionByValue(binding.spinnerAppointmentStatus, current); SpinnerUtils.setSelectionByValue(binding.spinnerAppointmentStatus, current);
// Re-populate dropdown spinners with current selected IDs from ViewState
List<DropdownDTO> customers = viewModel.getCustomers().getValue();
if (customers != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerCustomer,
customers, DropdownDTO::getLabel, "-- Select Customer --", state.selectedCustomerId, DropdownDTO::getId);
List<DropdownDTO> stores = viewModel.getStores().getValue();
if (stores != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStore,
stores, DropdownDTO::getLabel, "-- Select Store --", state.selectedStoreId, DropdownDTO::getId);
List<ServiceDTO> services = viewModel.getServices().getValue();
if (services != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerService,
services, ServiceDTO::getServiceName, "-- Select Service --", state.selectedServiceId, ServiceDTO::getServiceId);
List<DropdownDTO> pets = viewModel.getCustomerPets().getValue();
if (pets != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerPet,
pets, DropdownDTO::getLabel, "-- Select Pet --", state.selectedPetId, DropdownDTO::getId);
List<DropdownDTO> staff = viewModel.getStoreEmployees().getValue();
if (staff != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaff,
staff, DropdownDTO::getLabel, "-- Select Staff --", state.selectedStaffId, DropdownDTO::getId);
isUpdatingUI = false; isUpdatingUI = false;
} }
@@ -200,20 +232,15 @@ public class AppointmentDetailFragment extends Fragment {
setLoading(resource.status == Resource.Status.LOADING); setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
AppointmentDTO a = resource.data; AppointmentDTO a = resource.data;
preselectedPetId = a.getPetId() != null ? a.getPetId() : -1;
preselectedServiceId = a.getServiceId() != null ? a.getServiceId() : -1;
preselectedCustomerId = a.getCustomerId() != null ? a.getCustomerId() : -1;
preselectedStoreId = a.getStoreId() != null ? a.getStoreId() : -1;
preselectedStaffId = a.getEmployeeId() != null ? a.getEmployeeId() : -1;
binding.etAppointmentDate.setText(a.getAppointmentDate()); binding.etAppointmentDate.setText(a.getAppointmentDate());
parseAndSetTimeSpinners(a.getAppointmentTime() != null ? a.getAppointmentTime() : "09:00"); parseAndSetTimeSpinners(a.getAppointmentTime() != null ? a.getAppointmentTime() : "09:00");
String status = a.getAppointmentStatus(); String status = a.getAppointmentStatus();
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
SpinnerUtils.setSelectionByValue(binding.spinnerAppointmentStatus, DateTimeUtils.formatStatusFromBackend(status)); SpinnerUtils.setSelectionByValue(binding.spinnerAppointmentStatus, DateTimeUtils.formatStatusFromBackend(status));
} }
notifyDateTimeStatusChange(); notifyDateTimeStatusChange();
} else if (resource.status == Resource.Status.ERROR) {
Toast.makeText(getContext(), "Failed to load appointment", Toast.LENGTH_SHORT).show();
} }
}); });
} }

View File

@@ -47,6 +47,13 @@ public class PetRepository extends BaseRepository {
return executeCall(petApi.getAdoptionPets()); return executeCall(petApi.getAdoptionPets());
} }
/**
* Retrieves all pets from the dropdowns API.
*/
public LiveData<Resource<List<DropdownDTO>>> getPetDropdowns() {
return executeCall(petApi.getPetDropdowns());
}
/** /**
* Retrieves a specific pet by its ID from the API. * Retrieves a specific pet by its ID from the API.
*/ */

View File

@@ -69,12 +69,12 @@ public class AdoptionDetailViewModel extends ViewModel {
state.isAdoptionIdVisible = isEditing; state.isAdoptionIdVisible = isEditing;
state.isDeleteVisible = isEditing; state.isDeleteVisible = isEditing;
state.isPetEnabled = isEditing; state.isPetEnabled = isEditing;
state.isEmployeeEnabled = isEditing; state.isEmployeeEnabled = false;
}); });
} }
public void loadInitialFormData() { public void loadInitialFormData(boolean isEditing) {
petRepository.getAdoptionPets().observeForever(r -> { (isEditing ? petRepository.getPetDropdowns() : petRepository.getAdoptionPets()).observeForever(r -> {
if (r != null && r.status == Resource.Status.SUCCESS && r.data != null) { if (r != null && r.status == Resource.Status.SUCCESS && r.data != null) {
petList.setValue(r.data); petList.setValue(r.data);
} }

View File

@@ -41,6 +41,7 @@ public class AppointmentDetailViewModel extends ViewModel {
private final MutableLiveData<ViewState> viewState = new MutableLiveData<>(new ViewState()); private final MutableLiveData<ViewState> viewState = new MutableLiveData<>(new ViewState());
private long appointmentId = -1; private long appointmentId = -1;
private boolean isOriginallyCancel = false;
private Long currentCustomerId; private Long currentCustomerId;
private Long currentStoreId; private Long currentStoreId;
private Long currentPetId; private Long currentPetId;
@@ -229,6 +230,7 @@ public class AppointmentDetailViewModel extends ViewModel {
repository.getAppointmentById(appointmentId).observeForever(resource -> { repository.getAppointmentById(appointmentId).observeForever(resource -> {
if (resource.status == Resource.Status.SUCCESS && resource.data != null) { if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
AppointmentDTO a = resource.data; AppointmentDTO a = resource.data;
isOriginallyCancel = "CANCELLED".equalsIgnoreCase(a.getAppointmentStatus());
currentCustomerId = a.getCustomerId(); currentCustomerId = a.getCustomerId();
currentStoreId = a.getStoreId(); currentStoreId = a.getStoreId();
currentPetId = a.getPetId(); currentPetId = a.getPetId();
@@ -279,9 +281,8 @@ public class AppointmentDetailViewModel extends ViewModel {
updateViewState(s -> { updateViewState(s -> {
s.availableStatuses = calculateAvailableStatuses(s.isEditing, date, time, currentStatus); s.availableStatuses = calculateAvailableStatuses(s.isEditing, date, time, currentStatus);
boolean isPast = DateTimeUtils.isDateTimeInPast(date, time); boolean isPast = DateTimeUtils.isDateTimeInPast(date, time);
boolean isCancelled = "Cancelled".equalsIgnoreCase(currentStatus);
if (isCancelled) { if (isOriginallyCancel) {
s.isPast = true; s.isPast = true;
setAllFieldsEnabled(s, false); setAllFieldsEnabled(s, false);
s.isStatusEnabled = false; s.isStatusEnabled = false;
@@ -311,7 +312,7 @@ public class AppointmentDetailViewModel extends ViewModel {
private String[] calculateAvailableStatuses(boolean isEditing, String date, String currentTime, String currentStatus) { private String[] calculateAvailableStatuses(boolean isEditing, String date, String currentTime, String currentStatus) {
if (!isEditing) return new String[]{"Booked"}; if (!isEditing) return new String[]{"Booked"};
if (date == null || date.isEmpty()) return new String[]{}; if (date == null || date.isEmpty()) return new String[]{};
if ("Cancelled".equalsIgnoreCase(currentStatus)) return new String[]{"Cancelled"}; if (isOriginallyCancel) return new String[]{"Cancelled"};
if (DateTimeUtils.isDateTimeInPast(date, currentTime)) return new String[]{"Completed", "Missed"}; if (DateTimeUtils.isDateTimeInPast(date, currentTime)) return new String[]{"Completed", "Missed"};
return new String[]{"Booked", "Cancelled"}; return new String[]{"Booked", "Cancelled"};
} }