Merge pull request #146 from RecentRunner/AttachmentsToChat
AttachmentsToChat
This commit is contained in:
@@ -57,7 +57,7 @@ public class AdoptionAdapter extends RecyclerView.Adapter<AdoptionAdapter.Adopti
|
|||||||
holder.tvStatus.setText(status);
|
holder.tvStatus.setText(status);
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "Approved":
|
case "Completed":
|
||||||
holder.tvStatus.setBackgroundColor(Color.parseColor("#4CAF50"));
|
holder.tvStatus.setBackgroundColor(Color.parseColor("#4CAF50"));
|
||||||
break;
|
break;
|
||||||
case "Pending":
|
case "Pending":
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.example.petstoremobile.api;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.UserDTO;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Query;
|
||||||
|
|
||||||
|
public interface UserApi {
|
||||||
|
@GET("api/v1/users")
|
||||||
|
Call<PageResponse<UserDTO>> getUsers(@Query("role") String role, @Query("page") int page, @Query("size") int size);
|
||||||
|
}
|
||||||
@@ -173,4 +173,10 @@ public class NetworkModule {
|
|||||||
public static CategoryApi provideCategoryApi(Retrofit retrofit) {
|
public static CategoryApi provideCategoryApi(Retrofit retrofit) {
|
||||||
return retrofit.create(CategoryApi.class);
|
return retrofit.create(CategoryApi.class);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public static UserApi provideUserApi(Retrofit retrofit) {
|
||||||
|
return retrofit.create(UserApi.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,20 +10,27 @@ public class AdoptionDTO {
|
|||||||
private String customerName;
|
private String customerName;
|
||||||
private Long employeeId;
|
private Long employeeId;
|
||||||
private String employeeName;
|
private String employeeName;
|
||||||
|
private Long sourceStoreId;
|
||||||
|
private String sourceStoreName;
|
||||||
private String adoptionDate;
|
private String adoptionDate;
|
||||||
private String adoptionStatus;
|
private String adoptionStatus;
|
||||||
private BigDecimal adoptionFee;
|
private BigDecimal adoptionFee;
|
||||||
private String createdAt;
|
private String createdAt;
|
||||||
private String updatedAt;
|
private String updatedAt;
|
||||||
|
|
||||||
public AdoptionDTO(Long petId, Long customerId, String adoptionDate, String adoptionStatus) {
|
public AdoptionDTO(Long petId, Long customerId, Long sourceStoreId, String adoptionDate, String adoptionStatus) {
|
||||||
this(petId, customerId, null, adoptionDate, adoptionStatus);
|
this.petId = petId;
|
||||||
|
this.customerId = customerId;
|
||||||
|
this.sourceStoreId = sourceStoreId;
|
||||||
|
this.adoptionDate = adoptionDate;
|
||||||
|
this.adoptionStatus = adoptionStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AdoptionDTO(Long petId, Long customerId, Long employeeId, String adoptionDate, String adoptionStatus) {
|
public AdoptionDTO(Long petId, Long customerId, Long employeeId, Long sourceStoreId, String adoptionDate, String adoptionStatus) {
|
||||||
this.petId = petId;
|
this.petId = petId;
|
||||||
this.customerId = customerId;
|
this.customerId = customerId;
|
||||||
this.employeeId = employeeId;
|
this.employeeId = employeeId;
|
||||||
|
this.sourceStoreId = sourceStoreId;
|
||||||
this.adoptionDate = adoptionDate;
|
this.adoptionDate = adoptionDate;
|
||||||
this.adoptionStatus = adoptionStatus;
|
this.adoptionStatus = adoptionStatus;
|
||||||
}
|
}
|
||||||
@@ -56,6 +63,14 @@ public class AdoptionDTO {
|
|||||||
return employeeName;
|
return employeeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getSourceStoreId() {
|
||||||
|
return sourceStoreId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSourceStoreName() {
|
||||||
|
return sourceStoreName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAdoptionDate() {
|
public String getAdoptionDate() {
|
||||||
return adoptionDate;
|
return adoptionDate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import com.example.petstoremobile.utils.SpinnerUtils;
|
|||||||
import com.example.petstoremobile.viewmodels.AdoptionViewModel;
|
import com.example.petstoremobile.viewmodels.AdoptionViewModel;
|
||||||
import com.example.petstoremobile.viewmodels.CustomerViewModel;
|
import com.example.petstoremobile.viewmodels.CustomerViewModel;
|
||||||
import com.example.petstoremobile.viewmodels.PetViewModel;
|
import com.example.petstoremobile.viewmodels.PetViewModel;
|
||||||
|
import com.example.petstoremobile.viewmodels.StoreViewModel;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -35,15 +36,18 @@ public class AdoptionDetailFragment extends Fragment {
|
|||||||
private boolean isEditing = false;
|
private boolean isEditing = false;
|
||||||
private long preselectedPetId = -1;
|
private long preselectedPetId = -1;
|
||||||
private long preselectedCustomerId = -1;
|
private long preselectedCustomerId = -1;
|
||||||
|
private long preselectedStoreId = -1;
|
||||||
|
|
||||||
private List<PetDTO> petList = new ArrayList<>();
|
private List<PetDTO> petList = new ArrayList<>();
|
||||||
private List<CustomerDTO> customerList = new ArrayList<>();
|
private List<CustomerDTO> customerList = new ArrayList<>();
|
||||||
|
private List<StoreDTO> storeList = new ArrayList<>();
|
||||||
|
|
||||||
private final String[] STATUSES = {"Pending", "Approved", "Rejected"};
|
private final String[] STATUSES = {"Pending", "Completed", "Cancelled"};
|
||||||
|
|
||||||
private AdoptionViewModel adoptionViewModel;
|
private AdoptionViewModel adoptionViewModel;
|
||||||
private PetViewModel petViewModel;
|
private PetViewModel petViewModel;
|
||||||
private CustomerViewModel customerViewModel;
|
private CustomerViewModel customerViewModel;
|
||||||
|
private StoreViewModel storeViewModel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -51,6 +55,7 @@ public class AdoptionDetailFragment extends Fragment {
|
|||||||
adoptionViewModel = new ViewModelProvider(this).get(AdoptionViewModel.class);
|
adoptionViewModel = new ViewModelProvider(this).get(AdoptionViewModel.class);
|
||||||
petViewModel = new ViewModelProvider(this).get(PetViewModel.class);
|
petViewModel = new ViewModelProvider(this).get(PetViewModel.class);
|
||||||
customerViewModel = new ViewModelProvider(this).get(CustomerViewModel.class);
|
customerViewModel = new ViewModelProvider(this).get(CustomerViewModel.class);
|
||||||
|
storeViewModel = new ViewModelProvider(this).get(StoreViewModel.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -107,6 +112,7 @@ public class AdoptionDetailFragment extends Fragment {
|
|||||||
private void loadSpinnersData() {
|
private void loadSpinnersData() {
|
||||||
loadPets();
|
loadPets();
|
||||||
loadCustomers();
|
loadCustomers();
|
||||||
|
loadStores();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,6 +158,27 @@ public class AdoptionDetailFragment extends Fragment {
|
|||||||
preselectedCustomerId, CustomerDTO::getCustomerId);
|
preselectedCustomerId, CustomerDTO::getCustomerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the list of stores from the API.
|
||||||
|
*/
|
||||||
|
private void loadStores() {
|
||||||
|
storeViewModel.getAllStores(0, 200).observe(getViewLifecycleOwner(), resource -> {
|
||||||
|
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
|
storeList = resource.data.getContent();
|
||||||
|
refreshStoreSpinner();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the store selection spinner with data.
|
||||||
|
*/
|
||||||
|
private void refreshStoreSpinner() {
|
||||||
|
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerAdoptionStore, storeList,
|
||||||
|
StoreDTO::getStoreName, "-- Select Store --",
|
||||||
|
preselectedStoreId, StoreDTO::getStoreId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles arguments to determine if the fragment is in edit or add mode.
|
* Handles arguments to determine if the fragment is in edit or add mode.
|
||||||
*/
|
*/
|
||||||
@@ -182,11 +209,13 @@ public class AdoptionDetailFragment extends Fragment {
|
|||||||
AdoptionDTO a = resource.data;
|
AdoptionDTO a = resource.data;
|
||||||
preselectedPetId = a.getPetId() != null ? a.getPetId() : -1;
|
preselectedPetId = a.getPetId() != null ? a.getPetId() : -1;
|
||||||
preselectedCustomerId = a.getCustomerId() != null ? a.getCustomerId() : -1;
|
preselectedCustomerId = a.getCustomerId() != null ? a.getCustomerId() : -1;
|
||||||
|
preselectedStoreId = a.getSourceStoreId() != null ? a.getSourceStoreId() : -1;
|
||||||
binding.etAdoptionDate.setText(a.getAdoptionDate());
|
binding.etAdoptionDate.setText(a.getAdoptionDate());
|
||||||
SpinnerUtils.setSelectionByValue(binding.spinnerAdoptionStatus, a.getAdoptionStatus());
|
SpinnerUtils.setSelectionByValue(binding.spinnerAdoptionStatus, a.getAdoptionStatus());
|
||||||
|
|
||||||
refreshPetSpinner();
|
refreshPetSpinner();
|
||||||
refreshCustomerSpinner();
|
refreshCustomerSpinner();
|
||||||
|
refreshStoreSpinner();
|
||||||
} else if (resource.status == Resource.Status.ERROR) {
|
} else if (resource.status == Resource.Status.ERROR) {
|
||||||
Toast.makeText(getContext(), "Failed to load adoption: " + resource.message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Failed to load adoption: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
@@ -203,6 +232,9 @@ public class AdoptionDetailFragment extends Fragment {
|
|||||||
if (binding.spinnerAdoptionPet.getSelectedItemPosition() == 0) {
|
if (binding.spinnerAdoptionPet.getSelectedItemPosition() == 0) {
|
||||||
Toast.makeText(getContext(), "Select a pet", Toast.LENGTH_SHORT).show(); return;
|
Toast.makeText(getContext(), "Select a pet", Toast.LENGTH_SHORT).show(); return;
|
||||||
}
|
}
|
||||||
|
if (binding.spinnerAdoptionStore.getSelectedItemPosition() == 0) {
|
||||||
|
Toast.makeText(getContext(), "Select a store", Toast.LENGTH_SHORT).show(); return;
|
||||||
|
}
|
||||||
String date = binding.etAdoptionDate.getText().toString().trim();
|
String date = binding.etAdoptionDate.getText().toString().trim();
|
||||||
if (date.isEmpty()) {
|
if (date.isEmpty()) {
|
||||||
Toast.makeText(getContext(), "Select a date", Toast.LENGTH_SHORT).show(); return;
|
Toast.makeText(getContext(), "Select a date", Toast.LENGTH_SHORT).show(); return;
|
||||||
@@ -210,11 +242,13 @@ public class AdoptionDetailFragment extends Fragment {
|
|||||||
|
|
||||||
CustomerDTO customer = customerList.get(binding.spinnerAdoptionCustomer.getSelectedItemPosition() - 1);
|
CustomerDTO customer = customerList.get(binding.spinnerAdoptionCustomer.getSelectedItemPosition() - 1);
|
||||||
PetDTO pet = petList.get(binding.spinnerAdoptionPet.getSelectedItemPosition() - 1);
|
PetDTO pet = petList.get(binding.spinnerAdoptionPet.getSelectedItemPosition() - 1);
|
||||||
|
StoreDTO store = storeList.get(binding.spinnerAdoptionStore.getSelectedItemPosition() - 1);
|
||||||
String status = STATUSES[binding.spinnerAdoptionStatus.getSelectedItemPosition()];
|
String status = STATUSES[binding.spinnerAdoptionStatus.getSelectedItemPosition()];
|
||||||
|
|
||||||
AdoptionDTO dto = new AdoptionDTO(
|
AdoptionDTO dto = new AdoptionDTO(
|
||||||
pet.getPetId(),
|
pet.getPetId(),
|
||||||
customer.getCustomerId(),
|
customer.getCustomerId(),
|
||||||
|
store.getStoreId(),
|
||||||
date,
|
date,
|
||||||
status
|
status
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.example.petstoremobile.viewmodels.CustomerViewModel;
|
|||||||
import com.example.petstoremobile.viewmodels.PetViewModel;
|
import com.example.petstoremobile.viewmodels.PetViewModel;
|
||||||
import com.example.petstoremobile.viewmodels.ServiceViewModel;
|
import com.example.petstoremobile.viewmodels.ServiceViewModel;
|
||||||
import com.example.petstoremobile.viewmodels.StoreViewModel;
|
import com.example.petstoremobile.viewmodels.StoreViewModel;
|
||||||
|
import com.example.petstoremobile.viewmodels.UserViewModel;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -40,11 +41,13 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
private long preselectedServiceId = -1;
|
private long preselectedServiceId = -1;
|
||||||
private long preselectedCustomerId = -1;
|
private long preselectedCustomerId = -1;
|
||||||
private long preselectedStoreId = -1;
|
private long preselectedStoreId = -1;
|
||||||
|
private long preselectedStaffId = -1;
|
||||||
|
|
||||||
private List<PetDTO> petList = new ArrayList<>();
|
private List<PetDTO> petList = new ArrayList<>();
|
||||||
private List<ServiceDTO> serviceList = new ArrayList<>();
|
private List<ServiceDTO> serviceList = new ArrayList<>();
|
||||||
private List<CustomerDTO> customerList = new ArrayList<>();
|
private List<CustomerDTO> customerList = new ArrayList<>();
|
||||||
private List<StoreDTO> storeList = new ArrayList<>();
|
private List<StoreDTO> storeList = new ArrayList<>();
|
||||||
|
private List<UserDTO> staffList = new ArrayList<>();
|
||||||
|
|
||||||
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};
|
||||||
@@ -54,6 +57,7 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
private ServiceViewModel serviceViewModel;
|
private ServiceViewModel serviceViewModel;
|
||||||
private StoreViewModel storeViewModel;
|
private StoreViewModel storeViewModel;
|
||||||
private CustomerViewModel customerViewModel;
|
private CustomerViewModel customerViewModel;
|
||||||
|
private UserViewModel userViewModel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -63,6 +67,7 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
serviceViewModel = new ViewModelProvider(this).get(ServiceViewModel.class);
|
serviceViewModel = new ViewModelProvider(this).get(ServiceViewModel.class);
|
||||||
storeViewModel = new ViewModelProvider(this).get(StoreViewModel.class);
|
storeViewModel = new ViewModelProvider(this).get(StoreViewModel.class);
|
||||||
customerViewModel = new ViewModelProvider(this).get(CustomerViewModel.class);
|
customerViewModel = new ViewModelProvider(this).get(CustomerViewModel.class);
|
||||||
|
userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -128,6 +133,7 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
loadServices();
|
loadServices();
|
||||||
loadCustomers();
|
loadCustomers();
|
||||||
loadStores();
|
loadStores();
|
||||||
|
loadStaff();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,6 +221,27 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
preselectedStoreId, StoreDTO::getStoreId);
|
preselectedStoreId, StoreDTO::getStoreId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the list of staff from the API.
|
||||||
|
*/
|
||||||
|
private void loadStaff() {
|
||||||
|
userViewModel.getUsers("STAFF", 0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
|
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
|
staffList = resource.data.getContent();
|
||||||
|
refreshStaffSpinner();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the staff selection spinner.
|
||||||
|
*/
|
||||||
|
private void refreshStaffSpinner() {
|
||||||
|
SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaff, staffList,
|
||||||
|
UserDTO::getFullName, "-- Select Staff --",
|
||||||
|
preselectedStaffId, UserDTO::getId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles arguments to determine if the fragment is in edit or add mode.
|
* Handles arguments to determine if the fragment is in edit or add mode.
|
||||||
*/
|
*/
|
||||||
@@ -247,6 +274,7 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
preselectedServiceId = (a.getServiceId() != null) ? a.getServiceId() : -1;
|
preselectedServiceId = (a.getServiceId() != null) ? a.getServiceId() : -1;
|
||||||
preselectedCustomerId = (a.getCustomerId() != null) ? a.getCustomerId() : -1;
|
preselectedCustomerId = (a.getCustomerId() != null) ? a.getCustomerId() : -1;
|
||||||
preselectedStoreId = (a.getStoreId() != null) ? a.getStoreId() : -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());
|
||||||
|
|
||||||
@@ -276,6 +304,7 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
refreshServiceSpinner();
|
refreshServiceSpinner();
|
||||||
refreshCustomerSpinner();
|
refreshCustomerSpinner();
|
||||||
refreshStoreSpinner();
|
refreshStoreSpinner();
|
||||||
|
refreshStaffSpinner();
|
||||||
} else if (resource.status == Resource.Status.ERROR) {
|
} else if (resource.status == Resource.Status.ERROR) {
|
||||||
Toast.makeText(getContext(), "Failed to load appointment: " + resource.message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Failed to load appointment: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
@@ -307,6 +336,11 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
StoreDTO store = storeList.get(binding.spinnerStore.getSelectedItemPosition() - 1);
|
StoreDTO store = storeList.get(binding.spinnerStore.getSelectedItemPosition() - 1);
|
||||||
PetDTO pet = petList.get(binding.spinnerPet.getSelectedItemPosition() - 1);
|
PetDTO pet = petList.get(binding.spinnerPet.getSelectedItemPosition() - 1);
|
||||||
ServiceDTO service = serviceList.get(binding.spinnerService.getSelectedItemPosition() - 1);
|
ServiceDTO service = serviceList.get(binding.spinnerService.getSelectedItemPosition() - 1);
|
||||||
|
|
||||||
|
Long employeeId = null;
|
||||||
|
if (binding.spinnerStaff.getSelectedItemPosition() > 0) {
|
||||||
|
employeeId = staffList.get(binding.spinnerStaff.getSelectedItemPosition() - 1).getId();
|
||||||
|
}
|
||||||
|
|
||||||
String time = String.format("%02d:%02d",
|
String time = String.format("%02d:%02d",
|
||||||
HOURS[binding.spinnerHour.getSelectedItemPosition()],
|
HOURS[binding.spinnerHour.getSelectedItemPosition()],
|
||||||
@@ -346,6 +380,7 @@ public class AppointmentDetailFragment extends Fragment {
|
|||||||
customer.getCustomerId(),
|
customer.getCustomerId(),
|
||||||
store.getStoreId(),
|
store.getStoreId(),
|
||||||
service.getServiceId(),
|
service.getServiceId(),
|
||||||
|
employeeId,
|
||||||
date,
|
date,
|
||||||
time,
|
time,
|
||||||
status,
|
status,
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.UserApi;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.UserDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class UserRepository extends BaseRepository {
|
||||||
|
private final UserApi userApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public UserRepository(UserApi userApi) {
|
||||||
|
super("UserRepository");
|
||||||
|
this.userApi = userApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Resource<PageResponse<UserDTO>>> getUsers(String role, int page, int size) {
|
||||||
|
return executeCall(userApi.getUsers(role, page, size));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.UserDTO;
|
||||||
|
import com.example.petstoremobile.repositories.UserRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class UserViewModel extends ViewModel {
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public UserViewModel(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Resource<PageResponse<UserDTO>>> getUsers(String role, int page, int size) {
|
||||||
|
return userRepository.getUsers(role, page, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -95,6 +95,20 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"/>
|
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 -->
|
<!-- Adoption Date -->
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -165,4 +179,4 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -124,15 +124,27 @@
|
|||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
android:layout_marginBottom="4dp"/>
|
android:layout_marginBottom="4dp"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
android:id="@+id/spinnerService"
|
android:id="@+id/spinnerService"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"/>
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
|
<!-- Staff -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Staff"
|
||||||
|
android:textColor="@color/text_dark"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:layout_marginBottom="4dp"/>
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinnerStaff"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
<!-- Appointment Date -->
|
<!-- Appointment Date -->
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public class AdoptionController {
|
|||||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||||
public ResponseEntity<Page<AdoptionResponse>> getAllAdoptions(
|
public ResponseEntity<Page<AdoptionResponse>> getAllAdoptions(
|
||||||
@RequestParam(required = false) String q,
|
@RequestParam(required = false) String q,
|
||||||
|
@RequestParam(required = false) Long customerId,
|
||||||
|
@RequestParam(required = false) String status,
|
||||||
Pageable pageable) {
|
Pageable pageable) {
|
||||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
String role = authentication.getAuthorities().stream()
|
String role = authentication.getAuthorities().stream()
|
||||||
@@ -40,13 +42,13 @@ public class AdoptionController {
|
|||||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
Long customerId = null;
|
Long effectiveCustomerId = customerId;
|
||||||
if (role != null && role.equals("CUSTOMER")) {
|
if (role != null && role.equals("CUSTOMER")) {
|
||||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||||
customerId = user.getId();
|
effectiveCustomerId = user.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResponseEntity.ok(adoptionService.getAllAdoptions(q, pageable, customerId));
|
return ResponseEntity.ok(adoptionService.getAllAdoptions(q, effectiveCustomerId, status, pageable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
|
|||||||
@@ -14,18 +14,18 @@ import java.util.Optional;
|
|||||||
public interface AdoptionRepository extends JpaRepository<Adoption, Long> {
|
public interface AdoptionRepository extends JpaRepository<Adoption, Long> {
|
||||||
|
|
||||||
@Query("SELECT a FROM Adoption a WHERE " +
|
@Query("SELECT a FROM Adoption a WHERE " +
|
||||||
|
"(:q IS NULL OR (" +
|
||||||
"LOWER(a.customer.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
"LOWER(a.customer.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||||
"LOWER(a.customer.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
"LOWER(a.customer.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||||
"LOWER(a.pet.petName) LIKE LOWER(CONCAT('%', :q, '%'))")
|
"LOWER(a.pet.petName) LIKE LOWER(CONCAT('%', :q, '%'))" +
|
||||||
Page<Adoption> searchAdoptions(@Param("q") String query, Pageable pageable);
|
")) AND " +
|
||||||
|
"(:customerId IS NULL OR a.customer.id = :customerId) AND " +
|
||||||
Page<Adoption> findByCustomerId(Long customerId, Pageable pageable);
|
"(:status IS NULL OR LOWER(a.adoptionStatus) = LOWER(:status))")
|
||||||
|
Page<Adoption> searchAdoptions(
|
||||||
@Query("SELECT a FROM Adoption a WHERE a.customer.id = :customerId AND (" +
|
@Param("q") String query,
|
||||||
"LOWER(a.customer.firstName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
@Param("customerId") Long customerId,
|
||||||
"LOWER(a.customer.lastName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
@Param("status") String status,
|
||||||
"LOWER(a.pet.petName) LIKE LOWER(CONCAT('%', :q, '%')))")
|
Pageable pageable);
|
||||||
Page<Adoption> searchAdoptionsByCustomer(@Param("customerId") Long customerId, @Param("q") String query, Pageable pageable);
|
|
||||||
|
|
||||||
Optional<Adoption> findFirstByPet_IdAndAdoptionStatusOrderByAdoptionDateDesc(Long petId, String adoptionStatus);
|
Optional<Adoption> findFirstByPet_IdAndAdoptionStatusOrderByAdoptionDateDesc(Long petId, String adoptionStatus);
|
||||||
|
|
||||||
|
|||||||
@@ -38,22 +38,16 @@ public class AdoptionService {
|
|||||||
this.storeRepository = storeRepository;
|
this.storeRepository = storeRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Page<AdoptionResponse> getAllAdoptions(String query, Pageable pageable, Long customerId) {
|
public Page<AdoptionResponse> getAllAdoptions(String query, Long customerId, String status, Pageable pageable) {
|
||||||
Page<Adoption> adoptions;
|
String normalizedQuery = normalizeFilter(query);
|
||||||
|
String normalizedStatus = normalizeFilter(status);
|
||||||
|
|
||||||
if (customerId != null) {
|
Page<Adoption> adoptions = adoptionRepository.searchAdoptions(
|
||||||
if (query != null && !query.trim().isEmpty()) {
|
normalizedQuery,
|
||||||
adoptions = adoptionRepository.searchAdoptionsByCustomer(customerId, query, pageable);
|
customerId,
|
||||||
} else {
|
normalizedStatus,
|
||||||
adoptions = adoptionRepository.findByCustomerId(customerId, pageable);
|
pageable
|
||||||
}
|
);
|
||||||
} else {
|
|
||||||
if (query != null && !query.trim().isEmpty()) {
|
|
||||||
adoptions = adoptionRepository.searchAdoptions(query, pageable);
|
|
||||||
} else {
|
|
||||||
adoptions = adoptionRepository.findAll(pageable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return adoptions.map(this::mapToResponse);
|
return adoptions.map(this::mapToResponse);
|
||||||
}
|
}
|
||||||
@@ -140,6 +134,14 @@ public class AdoptionService {
|
|||||||
adoptionRepository.deleteAllById(request.getIds());
|
adoptionRepository.deleteAllById(request.getIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String normalizeFilter(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String trimmed = value.trim();
|
||||||
|
return trimmed.isEmpty() ? null : trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
private AdoptionResponse mapToResponse(Adoption adoption) {
|
private AdoptionResponse mapToResponse(Adoption adoption) {
|
||||||
StoreLocation sourceStore = adoption.getSourceStore();
|
StoreLocation sourceStore = adoption.getSourceStore();
|
||||||
return new AdoptionResponse(
|
return new AdoptionResponse(
|
||||||
|
|||||||
Reference in New Issue
Block a user