Fixed minor bugs

- in sales we can no longer select 0 product for a sale
- ActivityLogFragment is locked to admin
- Spinners are loaded aftrer a selection if the spinner depends on a parent spinner
This commit is contained in:
Alex
2026-04-12 18:34:43 -06:00
parent b493357f31
commit e4e04940a9
4 changed files with 55 additions and 4 deletions

View File

@@ -11,7 +11,12 @@ import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.widget.Toast;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.adapters.ActivityLogAdapter;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.databinding.FragmentActivityLogBinding;
import com.example.petstoremobile.dtos.ActivityLogDTO;
import com.example.petstoremobile.dtos.DropdownDTO;
@@ -19,6 +24,8 @@ import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.ActivityLogListViewModel;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@@ -32,10 +39,19 @@ public class ActivityLogFragment extends Fragment {
private final List<ActivityLogDTO> logList = new ArrayList<>();
private List<DropdownDTO> storeList = new ArrayList<>();
@Inject TokenManager tokenManager;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentActivityLogBinding.inflate(inflater, container, false);
if (!"ADMIN".equalsIgnoreCase(tokenManager.getRole())) {
Toast.makeText(requireContext(), "Access denied", Toast.LENGTH_SHORT).show();
NavHostFragment.findNavController(this).popBackStack();
return binding.getRoot();
}
viewModel = new ViewModelProvider(this).get(ActivityLogListViewModel.class);
setupRecyclerView();

View File

@@ -74,29 +74,42 @@ public class AdoptionDetailFragment extends Fragment {
viewModel.getPetList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long petId = state != null ? state.selectedPetId : null;
isUpdatingUI = true;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionPet, list,
DropdownDTO::getLabel, "-- Select Pet --", petId, DropdownDTO::getId);
isUpdatingUI = false;
});
viewModel.getCustomerList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long customerId = state != null ? state.selectedCustomerId : null;
isUpdatingUI = true;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionCustomer, list,
DropdownDTO::getLabel, "-- Select Customer --", customerId, DropdownDTO::getId);
isUpdatingUI = false;
});
viewModel.getStoreList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long storeId = isStaff() ? tokenManager.getPrimaryStoreId() : (state != null ? state.selectedStoreId : null);
isUpdatingUI = true;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionStore, list,
DropdownDTO::getLabel, "-- Select Store --", storeId, DropdownDTO::getId);
isUpdatingUI = false;
if (isStaff() && storeId != null) {
int position = binding.spinnerAdoptionStore.getSelectedItemPosition();
if (position > 0) viewModel.onStoreSelected(position);
}
});
viewModel.getEmployeeList().observe(getViewLifecycleOwner(), list -> {
AdoptionDetailViewModel.ViewState state = viewModel.getViewState().getValue();
Long employeeId = state != null ? state.selectedEmployeeId : null;
isUpdatingUI = true;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionEmployee, list,
DropdownDTO::getLabel, "-- Select Staff --", employeeId, DropdownDTO::getId);
isUpdatingUI = false;
});
}

View File

@@ -70,11 +70,15 @@ public class SaleDetailFragment extends Fragment {
private void observeViewModel() {
viewModel.getStoreList().observe(getViewLifecycleOwner(), list -> {
Long selectedStoreId = isStaff() ? tokenManager.getPrimaryStoreId() : -1L;
Long primaryStoreId = tokenManager.getPrimaryStoreId();
Long selectedStoreId = isStaff() ? primaryStoreId : -1L;
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerSaleStore, list,
DropdownDTO::getLabel, "-- Select Store --", selectedStoreId, DropdownDTO::getId);
if (isStaff()) {
binding.spinnerSaleStore.setEnabled(false);
UIUtils.setViewsEnabled(false, binding.spinnerSaleStore);
if (primaryStoreId == null) {
Toast.makeText(requireContext(), "No store assigned to your account. Contact an admin.", Toast.LENGTH_LONG).show();
}
}
});
@@ -275,7 +279,7 @@ public class SaleDetailFragment extends Fragment {
private void setupAddItem() {
binding.btnAddItem.setOnClickListener(v -> {
if (!InputValidator.isSpinnerSelected(binding.spinnerSaleProduct, "Product")) return;
if (!InputValidator.isPositiveInteger(binding.etSaleQuantity, "Quantity")) return;
if (!InputValidator.isAtLeastOne(binding.etSaleQuantity, "Quantity")) return;
int qty = Integer.parseInt(binding.etSaleQuantity.getText().toString().trim());
ProductDTO product = viewModel.getProductList().getValue().get(binding.spinnerSaleProduct.getSelectedItemPosition() - 1);

View File

@@ -17,7 +17,7 @@ public class InputValidator {
return true;
}
// Checks if the value is a positive integer
// Checks if the value is a positive integer (>= 0)
public static boolean isPositiveInteger(EditText field, String fieldName) {
String value = field.getText().toString().trim();
try {
@@ -35,6 +35,24 @@ public class InputValidator {
}
}
// Checks if the value is a whole number of at least 1
public static boolean isAtLeastOne(EditText field, String fieldName) {
String value = field.getText().toString().trim();
try {
int num = Integer.parseInt(value);
if (num < 1) {
field.setError(fieldName + " must be at least 1");
field.requestFocus();
return false;
}
return true;
} catch (NumberFormatException e) {
field.setError(fieldName + " must be a whole number");
field.requestFocus();
return false;
}
}
// Checks if the value is a positive decimal number greater than 0
public static boolean isGreaterThanZero(EditText field, String fieldName) {
String value = field.getText().toString().trim();