added viewstates to Supplier and Product

This commit is contained in:
Alex
2026-04-10 00:28:01 -06:00
parent 6ece516cc6
commit 57ad824d67
7 changed files with 343 additions and 200 deletions

View File

@@ -33,11 +33,6 @@ public class AdoptionDetailFragment extends Fragment {
private FragmentAdoptionDetailBinding binding;
private AdoptionDetailViewModel viewModel;
private long preselectedPetId = -1;
private long preselectedCustomerId = -1;
private long preselectedStoreId = -1;
private long preselectedEmployeeId = -1;
private final String[] STATUSES = {"Pending", "Completed", "Cancelled"};
@Override
@@ -59,7 +54,7 @@ public class AdoptionDetailFragment extends Fragment {
setupSpinners();
setupDatePicker();
observeViewModel();
loadSpinnersData();
viewModel.loadInitialFormData();
handleArguments();
binding.btnAdoptionBack.setOnClickListener(v -> navigateBack());
@@ -68,14 +63,39 @@ public class AdoptionDetailFragment extends Fragment {
}
private void observeViewModel() {
viewModel.getPetList().observe(getViewLifecycleOwner(), list -> refreshPetSpinner());
viewModel.getCustomerList().observe(getViewLifecycleOwner(), list -> refreshCustomerSpinner());
viewModel.getStoreList().observe(getViewLifecycleOwner(), list -> refreshStoreSpinner());
viewModel.getEmployeeList().observe(getViewLifecycleOwner(), list -> refreshEmployeeSpinner());
viewModel.getViewState().observe(getViewLifecycleOwner(), this::applyViewState);
viewModel.getPetList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long petId = state != null ? state.selectedPetId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionPet, list,
DropdownDTO::getLabel, "-- Select Pet --", petId, DropdownDTO::getId);
});
viewModel.getCustomerList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long customerId = state != null ? state.selectedCustomerId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionCustomer, list,
DropdownDTO::getLabel, "-- Select Customer --", customerId, DropdownDTO::getId);
});
viewModel.getStoreList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long storeId = state != null ? state.selectedStoreId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionStore, list,
DropdownDTO::getLabel, "-- Select Store --", storeId, DropdownDTO::getId);
});
viewModel.getEmployeeList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long employeeId = state != null ? state.selectedEmployeeId : null;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionEmployee, list,
DropdownDTO::getLabel, "-- Select Staff --", employeeId, DropdownDTO::getId);
});
}
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
if (binding != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@@ -94,14 +114,7 @@ public class AdoptionDetailFragment extends Fragment {
binding.spinnerAdoptionCustomer.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (position > 0) {
UIUtils.setViewsEnabled(true, binding.spinnerAdoptionPet);
} else {
if (!viewModel.isEditing()) {
binding.spinnerAdoptionPet.setSelection(0);
UIUtils.setViewsEnabled(false, binding.spinnerAdoptionPet);
}
}
viewModel.onCustomerSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
@@ -110,12 +123,7 @@ public class AdoptionDetailFragment extends Fragment {
binding.spinnerAdoptionStore.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (position > 0 && viewModel.getStoreList().getValue() != null && position <= viewModel.getStoreList().getValue().size()) {
DropdownDTO selectedStore = viewModel.getStoreList().getValue().get(position - 1);
loadEmployees(selectedStore.getId());
} else {
viewModel.setEmployeeList(new ArrayList<>());
}
viewModel.onStoreSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
@@ -126,111 +134,64 @@ public class AdoptionDetailFragment extends Fragment {
binding.etAdoptionDate.setOnClickListener(v -> UIUtils.showDatePicker(requireContext(), binding.etAdoptionDate, null));
}
private void loadSpinnersData() {
viewModel.loadPets().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setPetList(resource.data);
}
});
viewModel.loadCustomers().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setCustomerList(resource.data);
}
});
viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setStoreList(resource.data);
}
});
}
private void refreshPetSpinner() {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionPet, viewModel.getPetList().getValue(),
DropdownDTO::getLabel, "-- Select Pet --",
preselectedPetId, DropdownDTO::getId);
}
private void refreshCustomerSpinner() {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionCustomer, viewModel.getCustomerList().getValue(),
DropdownDTO::getLabel, "-- Select Customer --",
preselectedCustomerId, DropdownDTO::getId);
}
private void refreshStoreSpinner() {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionStore, viewModel.getStoreList().getValue(),
DropdownDTO::getLabel, "-- Select Store --",
preselectedStoreId, DropdownDTO::getId);
}
private void loadEmployees(Long storeId) {
viewModel.loadEmployees(storeId).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
viewModel.setEmployeeList(resource.data);
}
});
}
private void refreshEmployeeSpinner() {
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionEmployee, viewModel.getEmployeeList().getValue(),
DropdownDTO::getLabel, "-- Select Staff --",
preselectedEmployeeId, DropdownDTO::getId);
}
private void handleArguments() {
Bundle a = getArguments();
if (a != null && a.containsKey("adoptionId")) {
long adoptionId = a.getLong("adoptionId");
viewModel.setAdoptionId(adoptionId);
binding.tvAdoptionMode.setText("Edit Adoption");
binding.tvAdoptionId.setText(DateTimeUtils.formatId(adoptionId));
binding.tvAdoptionId.setVisibility(View.VISIBLE);
binding.btnDeleteAdoption.setVisibility(View.VISIBLE);
viewModel.setAdoptionId(a.getLong("adoptionId"));
loadAdoptionData();
} else {
viewModel.setAdoptionId(-1);
binding.tvAdoptionMode.setText("Add Adoption");
binding.btnDeleteAdoption.setVisibility(View.GONE);
binding.tvAdoptionId.setVisibility(View.GONE);
UIUtils.setViewsEnabled(false, binding.spinnerAdoptionPet);
return;
}
viewModel.setAdoptionId(-1);
}
private void loadAdoptionData() {
viewModel.loadAdoption().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
AdoptionDTO a = resource.data;
preselectedPetId = a.getPetId() != null ? a.getPetId() : -1;
preselectedCustomerId = a.getCustomerId() != null ? a.getCustomerId() : -1;
preselectedStoreId = a.getSourceStoreId() != null ? a.getSourceStoreId() : -1;
preselectedEmployeeId = a.getEmployeeId() != null ? a.getEmployeeId() : -1;
binding.etAdoptionDate.setText(a.getAdoptionDate());
binding.etAdoptionFee.setText(a.getAdoptionFee() != null ? a.getAdoptionFee().toString() : "");
SpinnerUtils.setSelectionByValue(binding.spinnerAdoptionStatus, a.getAdoptionStatus());
refreshPetSpinner();
refreshCustomerSpinner();
refreshStoreSpinner();
if (preselectedCustomerId != -1) {
UIUtils.setViewsEnabled(true, binding.spinnerAdoptionPet);
}
} else if (resource.status == Resource.Status.ERROR) {
if (resource.status == Resource.Status.ERROR) {
Toast.makeText(getContext(), "Failed to load adoption: " + resource.message, Toast.LENGTH_SHORT).show();
}
});
}
private void applyViewState(AdoptionDetailViewModel.ViewState state) {
binding.tvAdoptionMode.setText(state.modeTitle);
binding.tvAdoptionId.setText(DateTimeUtils.formatId(viewModel.getAdoptionId()));
binding.tvAdoptionId.setVisibility(state.isAdoptionIdVisible ? View.VISIBLE : View.GONE);
binding.btnDeleteAdoption.setVisibility(state.isDeleteVisible ? View.VISIBLE : View.GONE);
binding.btnSaveAdoption.setText(state.saveButtonText);
UIUtils.setViewsEnabled(state.isPetEnabled, binding.spinnerAdoptionPet);
UIUtils.setViewsEnabled(state.isEmployeeEnabled, binding.spinnerAdoptionEmployee);
if (!state.adoptionDate.isEmpty()) {
binding.etAdoptionDate.setText(state.adoptionDate);
}
if (!state.adoptionFee.isEmpty()) {
binding.etAdoptionFee.setText(state.adoptionFee);
}
if (!state.adoptionStatus.isEmpty()) {
SpinnerUtils.setSelectionByValue(binding.spinnerAdoptionStatus, state.adoptionStatus);
}
// Re-populate spinners with updated preselected IDs
List<DropdownDTO> pets = viewModel.getPetList().getValue();
if (pets != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionPet,
pets, DropdownDTO::getLabel, "-- Select Pet --", state.selectedPetId, DropdownDTO::getId);
List<DropdownDTO> customers = viewModel.getCustomerList().getValue();
if (customers != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionCustomer,
customers, DropdownDTO::getLabel, "-- Select Customer --", state.selectedCustomerId, DropdownDTO::getId);
List<DropdownDTO> stores = viewModel.getStoreList().getValue();
if (stores != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionStore,
stores, DropdownDTO::getLabel, "-- Select Store --", state.selectedStoreId, DropdownDTO::getId);
List<DropdownDTO> employees = viewModel.getEmployeeList().getValue();
if (employees != null) SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionEmployee,
employees, DropdownDTO::getLabel, "-- Select Staff --", state.selectedEmployeeId, DropdownDTO::getId);
}
private void saveAdoption() {
if (!InputValidator.isSpinnerSelected(binding.spinnerAdoptionCustomer, "Customer")) return;
if (!InputValidator.isSpinnerSelected(binding.spinnerAdoptionPet, "Pet")) return;
@@ -247,24 +208,17 @@ public class AdoptionDetailFragment extends Fragment {
DropdownDTO customer = viewModel.getCustomerList().getValue().get(binding.spinnerAdoptionCustomer.getSelectedItemPosition() - 1);
DropdownDTO pet = viewModel.getPetList().getValue().get(binding.spinnerAdoptionPet.getSelectedItemPosition() - 1);
DropdownDTO store = viewModel.getStoreList().getValue().get(binding.spinnerAdoptionStore.getSelectedItemPosition() - 1);
Long employeeId = null;
if (binding.spinnerAdoptionEmployee.getSelectedItemPosition() > 0) {
if (binding.spinnerAdoptionEmployee.getSelectedItemPosition() > 0 && viewModel.getEmployeeList().getValue() != null) {
employeeId = viewModel.getEmployeeList().getValue().get(binding.spinnerAdoptionEmployee.getSelectedItemPosition() - 1).getId();
}
String adoptionDate = binding.etAdoptionDate.getText().toString().trim();
String status = STATUSES[binding.spinnerAdoptionStatus.getSelectedItemPosition()];
String adoptionDate = binding.etAdoptionDate.getText().toString().trim();
String status = STATUSES[binding.spinnerAdoptionStatus.getSelectedItemPosition()];
AdoptionDTO dto = new AdoptionDTO(
pet.getId(),
customer.getId(),
employeeId,
store.getId(),
adoptionDate,
status,
fee
);
pet.getId(), customer.getId(), employeeId, store.getId(), adoptionDate, status, fee);
viewModel.saveAdoption(dto).observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;

View File

@@ -110,7 +110,7 @@ public class ProductDetailFragment extends Fragment {
private void observeViewModel() {
viewModel.getCategoryList().observe(getViewLifecycleOwner(), list -> updateCategorySpinner());
viewModel.loadCategories().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
@@ -268,7 +268,7 @@ public class ProductDetailFragment extends Fragment {
}
private void confirmDelete() {
DialogUtils.showDeleteConfirmDialog(requireContext(), "Product", () ->
DialogUtils.showDeleteConfirmDialog(requireContext(), "Product", () ->
viewModel.deleteProduct().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);

View File

@@ -11,11 +11,13 @@ import androidx.navigation.fragment.NavHostFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import com.example.petstoremobile.databinding.FragmentSupplierDetailBinding;
import com.example.petstoremobile.dtos.SupplierDTO;
import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.Resource;
@@ -51,6 +53,7 @@ public class SupplierDetailFragment extends Fragment {
super.onViewCreated(view, savedInstanceState);
UIUtils.formatPhoneInput(binding.etSupPhone);
observeViewModel();
handleArguments();
binding.btnBack.setOnClickListener(v -> navigateBack());
@@ -58,8 +61,12 @@ public class SupplierDetailFragment extends Fragment {
binding.btnDeleteSupplier.setOnClickListener(v -> deleteSupplier());
}
private void observeViewModel() {
viewModel.getViewState().observe(getViewLifecycleOwner(), this::applyViewState);
}
private void setLoading(boolean loading) {
if (binding != null && binding.progressBar != null) {
if (binding != null) {
binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
}
}
@@ -129,36 +136,50 @@ public class SupplierDetailFragment extends Fragment {
private void handleArguments() {
if (getArguments() != null && getArguments().containsKey("supId")) {
long supId = getArguments().getLong("supId");
viewModel.setSupId(supId);
binding.tvMode.setText("Edit Supplier");
binding.tvSupId.setText("ID: " + supId);
binding.tvSupId.setVisibility(View.VISIBLE);
binding.btnDeleteSupplier.setVisibility(View.VISIBLE);
viewModel.setSupId(getArguments().getLong("supId"));
loadSupplierData();
} else {
viewModel.setSupId(-1);
binding.tvMode.setText("Add Supplier");
binding.tvSupId.setVisibility(View.GONE);
binding.btnDeleteSupplier.setVisibility(View.GONE);
binding.btnSaveSupplier.setText("Add");
return;
}
viewModel.setSupId(-1);
}
private void loadSupplierData() {
viewModel.loadSupplier().observe(getViewLifecycleOwner(), resource -> {
if (resource == null) return;
setLoading(resource.status == Resource.Status.LOADING);
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
SupplierDTO s = resource.data;
binding.etSupCompany.setText(s.getSupCompany());
binding.etSupContactFirstName.setText(s.getSupContactFirstName());
binding.etSupContactLastName.setText(s.getSupContactLastName());
binding.etSupEmail.setText(s.getSupEmail());
binding.etSupPhone.setText(s.getSupPhone());
} else if (resource.status == Resource.Status.ERROR) {
if (resource.status == Resource.Status.ERROR) {
Toast.makeText(getContext(), "Failed to load supplier: " + resource.message, Toast.LENGTH_SHORT).show();
}
});
}
private void applyViewState(SupplierDetailViewModel.ViewState state) {
binding.tvMode.setText(state.modeTitle);
binding.tvSupId.setText(DateTimeUtils.formatId(viewModel.getSupId()));
binding.tvSupId.setVisibility(state.isSupIdVisible ? View.VISIBLE : View.GONE);
binding.btnDeleteSupplier.setVisibility(state.isDeleteVisible ? View.VISIBLE : View.GONE);
binding.btnSaveSupplier.setText(state.saveButtonText);
UIUtils.setViewsEnabled(state.isFieldsEnabled,
binding.etSupCompany,
binding.etSupContactFirstName,
binding.etSupContactLastName,
binding.etSupEmail,
binding.etSupPhone);
updateIfDifferent(binding.etSupCompany, state.supCompany);
updateIfDifferent(binding.etSupContactFirstName, state.supFirstName);
updateIfDifferent(binding.etSupContactLastName, state.supLastName);
updateIfDifferent(binding.etSupEmail, state.supEmail);
updateIfDifferent(binding.etSupPhone, state.supPhone);
}
private void updateIfDifferent(EditText field, String value) {
String current = field.getText() != null ? field.getText().toString() : "";
String next = value != null ? value : "";
if (!current.equals(next)) {
field.setText(next);
}
}
}

View File

@@ -27,12 +27,12 @@ public class AdoptionDetailViewModel extends ViewModel {
private final StoreRepository storeRepository;
private long adoptionId = -1;
private boolean isEditing = false;
private final MutableLiveData<List<DropdownDTO>> petList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<List<DropdownDTO>> customerList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<List<DropdownDTO>> storeList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<List<DropdownDTO>> employeeList = new MutableLiveData<>(new ArrayList<>());
private final MutableLiveData<ViewState> viewState = new MutableLiveData<>(new ViewState());
@Inject
public AdoptionDetailViewModel(AdoptionRepository adoptionRepository, PetRepository petRepository,
@@ -45,7 +45,7 @@ public class AdoptionDetailViewModel extends ViewModel {
public void setAdoptionId(long id) {
this.adoptionId = id;
this.isEditing = id != -1;
initMode(id != -1);
}
public long getAdoptionId() {
@@ -53,50 +53,155 @@ public class AdoptionDetailViewModel extends ViewModel {
}
public boolean isEditing() {
return isEditing;
ViewState current = viewState.getValue();
return current != null && current.isEditing;
}
public LiveData<ViewState> getViewState() {
return viewState;
}
public void initMode(boolean isEditing) {
updateViewState(state -> {
state.isEditing = isEditing;
state.modeTitle = isEditing ? "Edit Adoption" : "Add Adoption";
state.saveButtonText = isEditing ? "Save" : "Add";
state.isAdoptionIdVisible = isEditing;
state.isDeleteVisible = isEditing;
state.isPetEnabled = isEditing;
state.isEmployeeEnabled = isEditing;
});
}
public void loadInitialFormData() {
petRepository.getAdoptionPets().observeForever(r -> {
if (r != null && r.status == Resource.Status.SUCCESS && r.data != null) {
petList.setValue(r.data);
}
});
customerRepository.getCustomerDropdowns().observeForever(r -> {
if (r != null && r.status == Resource.Status.SUCCESS && r.data != null) {
customerList.setValue(r.data);
}
});
storeRepository.getStoreDropdowns().observeForever(r -> {
if (r != null && r.status == Resource.Status.SUCCESS && r.data != null) {
storeList.setValue(r.data);
}
});
}
public void onCustomerSelected(int position) {
List<DropdownDTO> list = customerList.getValue();
Long customerId = (position > 0 && list != null && position <= list.size())
? list.get(position - 1).getId() : null;
updateViewState(state -> {
state.selectedCustomerId = customerId;
state.isPetEnabled = customerId != null;
if (customerId == null && !state.isEditing) {
state.selectedPetId = null;
}
});
}
public void onStoreSelected(int position) {
List<DropdownDTO> list = storeList.getValue();
if (position > 0 && list != null && position <= list.size()) {
Long storeId = list.get(position - 1).getId();
updateViewState(state -> {
state.selectedStoreId = storeId;
state.isEmployeeEnabled = true;
});
loadEmployeesForStore(storeId);
} else {
employeeList.setValue(new ArrayList<>());
updateViewState(state -> {
state.selectedStoreId = null;
state.selectedEmployeeId = null;
state.isEmployeeEnabled = false;
});
}
}
private void loadEmployeesForStore(Long storeId) {
storeRepository.getStoreEmployees(storeId).observeForever(r -> {
if (r != null && r.status == Resource.Status.SUCCESS && r.data != null) {
employeeList.setValue(r.data);
}
});
}
public LiveData<Resource<AdoptionDTO>> loadAdoption() {
return adoptionRepository.getAdoptionById(adoptionId);
}
MutableLiveData<Resource<AdoptionDTO>> result = new MutableLiveData<>();
adoptionRepository.getAdoptionById(adoptionId).observeForever(resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
AdoptionDTO a = resource.data;
updateViewState(state -> {
state.selectedPetId = a.getPetId() != null ? a.getPetId() : -1;
state.selectedCustomerId = a.getCustomerId() != null ? a.getCustomerId() : -1;
state.selectedStoreId = a.getSourceStoreId() != null ? a.getSourceStoreId() : -1;
state.selectedEmployeeId = a.getEmployeeId() != null ? a.getEmployeeId() : -1;
state.adoptionDate = a.getAdoptionDate() != null ? a.getAdoptionDate() : "";
state.adoptionFee = a.getAdoptionFee() != null ? a.getAdoptionFee().toString() : "";
state.adoptionStatus = a.getAdoptionStatus() != null ? a.getAdoptionStatus() : "";
state.isPetEnabled = state.selectedCustomerId != null && state.selectedCustomerId != -1;
state.isEmployeeEnabled = state.selectedStoreId != null && state.selectedStoreId != -1;
});
public LiveData<Resource<List<DropdownDTO>>> loadPets() {
return petRepository.getAdoptionPets();
}
public LiveData<Resource<List<DropdownDTO>>> loadCustomers() {
return customerRepository.getCustomerDropdowns();
}
public LiveData<Resource<List<DropdownDTO>>> loadStores() {
return storeRepository.getStoreDropdowns();
}
public LiveData<Resource<List<DropdownDTO>>> loadEmployees(Long storeId) {
return storeRepository.getStoreEmployees(storeId);
if (a.getSourceStoreId() != null) {
loadEmployeesForStore(a.getSourceStoreId());
}
}
result.setValue(resource);
});
return result;
}
public LiveData<Resource<AdoptionDTO>> saveAdoption(AdoptionDTO dto) {
if (isEditing) {
if (isEditing()) {
return adoptionRepository.updateAdoption(adoptionId, dto);
} else {
return adoptionRepository.createAdoption(dto);
}
return adoptionRepository.createAdoption(dto);
}
public LiveData<Resource<Void>> deleteAdoption() {
return adoptionRepository.deleteAdoption(adoptionId);
}
public void setPetList(List<DropdownDTO> list) { petList.setValue(list); }
public LiveData<List<DropdownDTO>> getPetList() { return petList; }
public void setCustomerList(List<DropdownDTO> list) { customerList.setValue(list); }
public LiveData<List<DropdownDTO>> getCustomerList() { return customerList; }
public void setStoreList(List<DropdownDTO> list) { storeList.setValue(list); }
public LiveData<List<DropdownDTO>> getStoreList() { return storeList; }
public void setEmployeeList(List<DropdownDTO> list) { employeeList.setValue(list); }
public LiveData<List<DropdownDTO>> getEmployeeList() { return employeeList; }
// Kept for backward-compatibility with any remaining direct calls
public void setEmployeeList(List<DropdownDTO> list) { employeeList.setValue(list); }
private void updateViewState(Action<ViewState> action) {
ViewState current = viewState.getValue();
if (current != null) {
action.run(current);
viewState.setValue(current);
}
}
private interface Action<T> {
void run(T target);
}
public static class ViewState {
public boolean isEditing = false;
public boolean isAdoptionIdVisible = false;
public boolean isDeleteVisible = false;
public boolean isPetEnabled = false;
public boolean isEmployeeEnabled = false;
public String modeTitle = "Add Adoption";
public String saveButtonText = "Add";
public Long selectedPetId = null;
public Long selectedCustomerId = null;
public Long selectedStoreId = null;
public Long selectedEmployeeId = null;
public String adoptionDate = "";
public String adoptionFee = "";
public String adoptionStatus = "";
}
}

View File

@@ -83,3 +83,4 @@ public class ProductDetailViewModel extends ViewModel {
return categoryList;
}
}

View File

@@ -1,6 +1,7 @@
package com.example.petstoremobile.viewmodels;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.petstoremobile.dtos.SupplierDTO;
@@ -14,8 +15,9 @@ import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class SupplierDetailViewModel extends ViewModel {
private final SupplierRepository repository;
private final MutableLiveData<ViewState> viewState = new MutableLiveData<>(new ViewState());
private long supId = -1;
private boolean isEditing = false;
@Inject
public SupplierDetailViewModel(SupplierRepository repository) {
@@ -24,7 +26,7 @@ public class SupplierDetailViewModel extends ViewModel {
public void setSupId(long id) {
this.supId = id;
this.isEditing = id != -1;
initMode(id != -1);
}
public long getSupId() {
@@ -32,23 +34,82 @@ public class SupplierDetailViewModel extends ViewModel {
}
public boolean isEditing() {
return isEditing;
ViewState current = viewState.getValue();
return current != null && current.isEditing;
}
public LiveData<ViewState> getViewState() {
return viewState;
}
public void initMode(boolean isEditing) {
updateViewState(state -> {
state.isEditing = isEditing;
state.modeTitle = isEditing ? "Edit Supplier" : "Add Supplier";
state.saveButtonText = isEditing ? "Save" : "Add";
state.isSupIdVisible = isEditing;
state.isDeleteVisible = isEditing;
state.isFieldsEnabled = true;
});
}
public LiveData<Resource<SupplierDTO>> loadSupplier() {
return repository.getSupplierById(supId);
MutableLiveData<Resource<SupplierDTO>> result = new MutableLiveData<>();
repository.getSupplierById(supId).observeForever(resource -> {
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
SupplierDTO s = resource.data;
updateViewState(state -> {
state.supCompany = safeText(s.getSupCompany());
state.supFirstName = safeText(s.getSupContactFirstName());
state.supLastName = safeText(s.getSupContactLastName());
state.supEmail = safeText(s.getSupEmail());
state.supPhone = safeText(s.getSupPhone());
});
}
result.setValue(resource);
});
return result;
}
public LiveData<Resource<SupplierDTO>> saveSupplier(SupplierDTO dto) {
if (isEditing) {
if (isEditing()) {
dto.setSupId(supId);
return repository.updateSupplier(supId, dto);
} else {
return repository.createSupplier(dto);
}
return repository.createSupplier(dto);
}
public LiveData<Resource<Void>> deleteSupplier() {
return repository.deleteSupplier(supId);
}
private String safeText(String value) {
return value == null ? "" : value.trim();
}
private void updateViewState(Action<ViewState> action) {
ViewState current = viewState.getValue();
if (current != null) {
action.run(current);
viewState.setValue(current);
}
}
private interface Action<T> {
void run(T target);
}
public static class ViewState {
public boolean isEditing = false;
public boolean isDeleteVisible = false;
public boolean isSupIdVisible = false;
public boolean isFieldsEnabled = true;
public String modeTitle = "Add Supplier";
public String saveButtonText = "Add";
public String supCompany = "";
public String supFirstName = "";
public String supLastName = "";
public String supEmail = "";
public String supPhone = "";
}
}

View File

@@ -99,6 +99,21 @@
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Store -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Source Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerAdoptionStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Employee -->
<TextView
android:layout_width="wrap_content"
@@ -114,20 +129,6 @@
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Source Store"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerAdoptionStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
<!-- Adoption Date -->
<TextView
android:layout_width="wrap_content"