fixed spinners to populate the correct pets in edit mode for adoptions
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user