Refactored Andriod project to use MVVM structure (Need to apply this so sales too after merge)
- Used MVVM structure so fragments are not doing all the operation from views to data and calls - organized the structure of our proejct
This commit is contained in:
@@ -14,20 +14,17 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||||||
import androidx.core.graphics.Insets;
|
import androidx.core.graphics.Insets;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.api.auth.AuthApi;
|
|
||||||
import com.example.petstoremobile.api.auth.TokenManager;
|
import com.example.petstoremobile.api.auth.TokenManager;
|
||||||
import com.example.petstoremobile.dtos.AuthDTO;
|
import com.example.petstoremobile.viewmodels.AuthViewModel;
|
||||||
import com.example.petstoremobile.dtos.UserDTO;
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
//The login screen activity
|
//The login screen activity
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
@@ -37,12 +34,11 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
private EditText etPassword;
|
private EditText etPassword;
|
||||||
private Button btnLogin;
|
private Button btnLogin;
|
||||||
private TextView tvLoginStatus;
|
private TextView tvLoginStatus;
|
||||||
|
private AuthViewModel viewModel;
|
||||||
|
|
||||||
@Inject AuthApi authApi;
|
|
||||||
@Inject TokenManager tokenManager;
|
@Inject TokenManager tokenManager;
|
||||||
@Inject @Named("baseUrl") String baseUrl;
|
@Inject @Named("baseUrl") String baseUrl;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
EdgeToEdge.enable(this);
|
EdgeToEdge.enable(this);
|
||||||
@@ -54,8 +50,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
// If a customer somehow remained logged in, clear them out
|
// If a customer somehow remained logged in, clear them out
|
||||||
tokenManager.clearLoginData();
|
tokenManager.clearLoginData();
|
||||||
} else {
|
} else {
|
||||||
Intent intent = new Intent(this, HomeActivity.class);
|
startActivity(new Intent(this, HomeActivity.class));
|
||||||
startActivity(intent);
|
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -99,92 +94,51 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Call login from api and get response
|
performLogin(username, password);
|
||||||
authApi.login(new AuthDTO.LoginRequest(username,password)).enqueue(new Callback<AuthDTO.LoginResponse>() {
|
});
|
||||||
@Override
|
}
|
||||||
public void onResponse(Call<AuthDTO.LoginResponse> call, Response<AuthDTO.LoginResponse> response) {
|
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
|
||||||
String role = response.body().getRole();
|
|
||||||
|
|
||||||
// Check if the user is a CUSTOMER and deny login if so
|
private void performLogin(String username, String password) {
|
||||||
|
viewModel.login(username, password).observe(this, resource -> {
|
||||||
|
if (resource == null) return;
|
||||||
|
|
||||||
|
switch (resource.status) {
|
||||||
|
case LOADING:
|
||||||
|
btnLogin.setEnabled(false);
|
||||||
|
tvLoginStatus.setText("Logging in...");
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
if (resource.data != null) {
|
||||||
|
String role = resource.data.getRole();
|
||||||
if ("CUSTOMER".equalsIgnoreCase(role)) {
|
if ("CUSTOMER".equalsIgnoreCase(role)) {
|
||||||
Toast.makeText(MainActivity.this, "Access denied: Customers are not allowed to log in.", Toast.LENGTH_LONG).show();
|
btnLogin.setEnabled(true);
|
||||||
tvLoginStatus.setText("Customers are not allowed to log in");
|
tvLoginStatus.setText("Customers are not allowed to log in");
|
||||||
return;
|
Toast.makeText(this, "Access denied: Customers are not allowed to log in.", Toast.LENGTH_LONG).show();
|
||||||
|
} else {
|
||||||
|
tokenManager.saveLoginData(resource.data.getToken(), resource.data.getUsername(), role);
|
||||||
|
fetchUserIdAndNavigate();
|
||||||
}
|
}
|
||||||
|
|
||||||
//save login data in shared preferences
|
|
||||||
tokenManager.saveLoginData(
|
|
||||||
response.body().getToken(),
|
|
||||||
response.body().getUsername(),
|
|
||||||
role
|
|
||||||
);
|
|
||||||
|
|
||||||
//fetch user id from api then login to home activity
|
|
||||||
authApi.getMe()
|
|
||||||
.enqueue(new Callback<UserDTO>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(Call<UserDTO> call,
|
|
||||||
Response<UserDTO> response) {
|
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
|
||||||
tokenManager.saveUserId(response.body().getId());
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show();
|
case ERROR:
|
||||||
startActivity(new Intent(MainActivity.this, HomeActivity.class));
|
btnLogin.setEnabled(true);
|
||||||
finish();
|
tvLoginStatus.setText(resource.message);
|
||||||
}
|
Toast.makeText(this, resource.message, Toast.LENGTH_LONG).show();
|
||||||
|
break;
|
||||||
@Override
|
|
||||||
public void onFailure(Call<UserDTO> call,
|
|
||||||
Throwable t) {
|
|
||||||
Log.e("MainActivity", "Failed to fetch userId", t);
|
|
||||||
|
|
||||||
Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show();
|
|
||||||
startActivity(new Intent(MainActivity.this, HomeActivity.class));
|
|
||||||
finish();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
String errorMessage;
|
|
||||||
switch (response.code()) {
|
|
||||||
case 401:
|
|
||||||
errorMessage = "Invalid username or password";
|
|
||||||
break;
|
|
||||||
case 500:
|
|
||||||
errorMessage = "Server error. Please try again later.";
|
|
||||||
break;
|
|
||||||
case 503:
|
|
||||||
errorMessage = "Service unavailable. Backend may be starting up.";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errorMessage = "Login failed (Error " + response.code() + ")";
|
|
||||||
}
|
|
||||||
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
|
|
||||||
tvLoginStatus.setText(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void fetchUserIdAndNavigate() {
|
||||||
public void onFailure(Call<AuthDTO.LoginResponse> call, Throwable t) {
|
viewModel.getMe().observe(this, resource -> {
|
||||||
Log.e("MainActivity", "Login request failed", t);
|
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||||
|
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
String errorMessage;
|
tokenManager.saveUserId(resource.data.getId());
|
||||||
if (t instanceof java.net.ConnectException ||
|
|
||||||
t instanceof java.net.SocketTimeoutException ||
|
|
||||||
t instanceof java.net.UnknownHostException) {
|
|
||||||
errorMessage = "Cannot connect to server at " + baseUrl +
|
|
||||||
". Please check if the backend is running.";
|
|
||||||
} else if (t instanceof java.io.IOException) {
|
|
||||||
errorMessage = "Network error. Please check your connection.";
|
|
||||||
} else {
|
|
||||||
errorMessage = "Login failed: " + t.getMessage();
|
|
||||||
}
|
}
|
||||||
|
Toast.makeText(this, "Login successful", Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
|
startActivity(new Intent(this, HomeActivity.class));
|
||||||
tvLoginStatus.setText(errorMessage);
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,17 +7,19 @@ import android.util.Log;
|
|||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.AdoptionAdapter;
|
import com.example.petstoremobile.adapters.AdoptionAdapter;
|
||||||
import com.example.petstoremobile.api.AdoptionApi;
|
|
||||||
import com.example.petstoremobile.dtos.AdoptionDTO;
|
import com.example.petstoremobile.dtos.AdoptionDTO;
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.AdoptionViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import com.example.petstoremobile.utils.EventDecorator;
|
import com.example.petstoremobile.utils.EventDecorator;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.prolificinteractive.materialcalendarview.CalendarDay;
|
import com.prolificinteractive.materialcalendarview.CalendarDay;
|
||||||
@@ -28,10 +30,7 @@ import java.text.ParseException;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.*;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdoptionClickListener {
|
public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdoptionClickListener {
|
||||||
@@ -39,7 +38,7 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
|
|||||||
private List<AdoptionDTO> adoptionList = new ArrayList<>();
|
private List<AdoptionDTO> adoptionList = new ArrayList<>();
|
||||||
private List<AdoptionDTO> filteredList = new ArrayList<>();
|
private List<AdoptionDTO> filteredList = new ArrayList<>();
|
||||||
private AdoptionAdapter adapter;
|
private AdoptionAdapter adapter;
|
||||||
@Inject AdoptionApi api;
|
private AdoptionViewModel viewModel;
|
||||||
private SwipeRefreshLayout swipeRefresh;
|
private SwipeRefreshLayout swipeRefresh;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
private ImageButton hamburger;
|
private ImageButton hamburger;
|
||||||
@@ -50,7 +49,13 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
|
|||||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(AdoptionViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_adoption, container, false);
|
View view = inflater.inflate(R.layout.fragment_adoption, container, false);
|
||||||
|
|
||||||
@@ -177,26 +182,34 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
|
|||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to get a list of all adoptions from the backend
|
||||||
private void loadAdoptions() {
|
private void loadAdoptions() {
|
||||||
|
//Load all adoptions from the backend using viewModel
|
||||||
|
viewModel.getAllAdoptions(0, 500).observe(getViewLifecycleOwner(), resource -> {
|
||||||
|
if (resource == null) return;
|
||||||
|
|
||||||
|
// Check the status to see if the resource is loaded and display the data
|
||||||
|
switch (resource.status) {
|
||||||
|
case LOADING:
|
||||||
|
// Show loading indicator
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
||||||
api.getAllAdoptions(0, 500).enqueue(new Callback<PageResponse<AdoptionDTO>>() {
|
break;
|
||||||
public void onResponse(Call<PageResponse<AdoptionDTO>> c,
|
case SUCCESS:
|
||||||
Response<PageResponse<AdoptionDTO>> r) {
|
// Hide loading indicator and display data
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
if (r.isSuccessful() && r.body() != null) {
|
if (resource.data != null) {
|
||||||
adoptionList.clear();
|
adoptionList.clear();
|
||||||
adoptionList.addAll(r.body().getContent());
|
adoptionList.addAll(resource.data.getContent());
|
||||||
updateCalendarDecorators();
|
updateCalendarDecorators();
|
||||||
filter(etSearch != null ? etSearch.getText().toString() : "");
|
filter(etSearch != null ? etSearch.getText().toString() : "");
|
||||||
} else {
|
|
||||||
Toast.makeText(getContext(), "Failed to load adoptions", Toast.LENGTH_SHORT).show();
|
|
||||||
Log.e("AdoptionFragment", "Error: " + r.message());
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
public void onFailure(Call<PageResponse<AdoptionDTO>> c, Throwable t) {
|
case ERROR:
|
||||||
|
// Hide loading indicator and toast error message
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Failed to load adoptions: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
Log.e("AdoptionFragment", t.getMessage());
|
Log.e("AdoptionFragment", "Error loading adoptions: " + resource.message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import android.graphics.Color;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -21,14 +23,14 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.AppointmentAdapter;
|
import com.example.petstoremobile.adapters.AppointmentAdapter;
|
||||||
import com.example.petstoremobile.api.AppointmentApi;
|
|
||||||
import com.example.petstoremobile.api.PetApi;
|
|
||||||
import com.example.petstoremobile.api.ServiceApi;
|
|
||||||
import com.example.petstoremobile.dtos.AppointmentDTO;
|
import com.example.petstoremobile.dtos.AppointmentDTO;
|
||||||
import com.example.petstoremobile.dtos.ServiceDTO;
|
import com.example.petstoremobile.dtos.ServiceDTO;
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.dtos.PetDTO;
|
import com.example.petstoremobile.dtos.PetDTO;
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.AppointmentViewModel;
|
||||||
|
import com.example.petstoremobile.viewmodels.PetViewModel;
|
||||||
|
import com.example.petstoremobile.viewmodels.ServiceViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import com.example.petstoremobile.utils.EventDecorator;
|
import com.example.petstoremobile.utils.EventDecorator;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.prolificinteractive.materialcalendarview.CalendarDay;
|
import com.prolificinteractive.materialcalendarview.CalendarDay;
|
||||||
@@ -45,12 +47,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class AppointmentFragment extends Fragment implements AppointmentAdapter.OnAppointmentClickListener {
|
public class AppointmentFragment extends Fragment implements AppointmentAdapter.OnAppointmentClickListener {
|
||||||
@@ -61,9 +58,9 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
|
|||||||
private List<ServiceDTO> serviceList = new ArrayList<>();
|
private List<ServiceDTO> serviceList = new ArrayList<>();
|
||||||
|
|
||||||
private AppointmentAdapter adapter;
|
private AppointmentAdapter adapter;
|
||||||
@Inject AppointmentApi api;
|
private AppointmentViewModel appointmentViewModel;
|
||||||
@Inject PetApi petApi;
|
private PetViewModel petViewModel;
|
||||||
@Inject ServiceApi serviceApi;
|
private ServiceViewModel serviceViewModel;
|
||||||
|
|
||||||
private SwipeRefreshLayout swipeRefreshLayout;
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
@@ -75,7 +72,15 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
|
|||||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
appointmentViewModel = new ViewModelProvider(this).get(AppointmentViewModel.class);
|
||||||
|
petViewModel = new ViewModelProvider(this).get(PetViewModel.class);
|
||||||
|
serviceViewModel = new ViewModelProvider(this).get(ServiceViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_appointment, container, false);
|
View view = inflater.inflate(R.layout.fragment_appointment, container, false);
|
||||||
|
|
||||||
@@ -91,7 +96,6 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
|
|||||||
loadPets();
|
loadPets();
|
||||||
loadServices();
|
loadServices();
|
||||||
|
|
||||||
|
|
||||||
FloatingActionButton fabAdd = view.findViewById(R.id.fabAddAppointment);
|
FloatingActionButton fabAdd = view.findViewById(R.id.fabAddAppointment);
|
||||||
fabAdd.setOnClickListener(v -> openAppointmentDetails(-1));
|
fabAdd.setOnClickListener(v -> openAppointmentDetails(-1));
|
||||||
|
|
||||||
@@ -239,76 +243,54 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
|
|||||||
openAppointmentDetails(position);
|
openAppointmentDetails(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to get a list of all appointments from the backend
|
||||||
private void loadAppointmentData() {
|
private void loadAppointmentData() {
|
||||||
if (swipeRefreshLayout != null)
|
//Load all appointments from the backend using viewModel
|
||||||
swipeRefreshLayout.setRefreshing(true);
|
appointmentViewModel.getAllAppointments(0, 500).observe(getViewLifecycleOwner(), resource -> {
|
||||||
api.getAllAppointments(0, 500).enqueue(new Callback<PageResponse<AppointmentDTO>>() {
|
if (resource == null) return;
|
||||||
@Override
|
|
||||||
public void onResponse(Call<PageResponse<AppointmentDTO>> call,
|
// Check the status to see if the resource is loaded and display the data
|
||||||
Response<PageResponse<AppointmentDTO>> response) {
|
switch (resource.status) {
|
||||||
if (swipeRefreshLayout != null)
|
case LOADING:
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
// Show loading indicator
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(true);
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
// Hide loading indicator and display data
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
|
if (resource.data != null) {
|
||||||
appointmentList.clear();
|
appointmentList.clear();
|
||||||
appointmentList.addAll(response.body().getContent());
|
appointmentList.addAll(resource.data.getContent());
|
||||||
updateCalendarDecorators();
|
updateCalendarDecorators();
|
||||||
filterAppointments(etSearch != null ? etSearch.getText().toString() : "");
|
filterAppointments(etSearch != null ? etSearch.getText().toString() : "");
|
||||||
} else {
|
|
||||||
Log.e("AppointmentFragment", "Error: " + response.message());
|
|
||||||
Toast.makeText(getContext(), "Failed to load appointments", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
case ERROR:
|
||||||
@Override
|
// Hide loading indicator and toast error message
|
||||||
public void onFailure(Call<PageResponse<AppointmentDTO>> call, Throwable t) {
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
if (swipeRefreshLayout != null)
|
Toast.makeText(getContext(), "Failed to load appointments: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
Log.e("AppointmentFragment", "Error loading appointments: " + resource.message);
|
||||||
Toast.makeText(getContext(), "Network error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
break;
|
||||||
Log.e("AppointmentFragment", t.getMessage());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Load Pets
|
// Load Pets
|
||||||
private void loadPets() {
|
private void loadPets() {
|
||||||
petApi.getAllPets(0,100).enqueue(new Callback<PageResponse<PetDTO>>() {
|
petViewModel.getAllPets(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
|
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
@Override
|
|
||||||
public void onResponse(Call<PageResponse<PetDTO>> call, Response<PageResponse<PetDTO>> response) {
|
|
||||||
if (response.isSuccessful() && response.body() !=null) {
|
|
||||||
petList.clear();
|
petList.clear();
|
||||||
petList.addAll(response.body().getContent());
|
petList.addAll(resource.data.getContent());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<PageResponse<PetDTO>> call, Throwable t) {
|
|
||||||
|
|
||||||
Log.e("AppointmentFragment", "Pet load error:" + t.getMessage());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load Services
|
// Load Services
|
||||||
|
|
||||||
private void loadServices() {
|
private void loadServices() {
|
||||||
serviceApi.getAllServices(0,100).enqueue(new Callback<PageResponse<ServiceDTO>>() {
|
serviceViewModel.getAllServices(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
@Override
|
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
public void onResponse(Call<PageResponse<ServiceDTO>> call, Response<PageResponse<ServiceDTO>> response) {
|
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
|
||||||
serviceList.clear();
|
serviceList.clear();
|
||||||
serviceList.addAll(response.body().getContent());
|
serviceList.addAll(resource.data.getContent());
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<PageResponse<ServiceDTO>> call, Throwable t) {
|
|
||||||
Log.e("AppointmentFragmnet", "Service load error: " + t.getMessage());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.widget.Toast;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -28,23 +29,16 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
|||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
|
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
|
||||||
import com.example.petstoremobile.adapters.InventoryAdapter;
|
import com.example.petstoremobile.adapters.InventoryAdapter;
|
||||||
import com.example.petstoremobile.api.CategoryApi;
|
|
||||||
import com.example.petstoremobile.api.InventoryApi;
|
|
||||||
import com.example.petstoremobile.dtos.BulkDeleteRequest;
|
|
||||||
import com.example.petstoremobile.dtos.CategoryDTO;
|
import com.example.petstoremobile.dtos.CategoryDTO;
|
||||||
import com.example.petstoremobile.dtos.InventoryDTO;
|
import com.example.petstoremobile.dtos.InventoryDTO;
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.InventoryViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class InventoryFragment extends Fragment implements InventoryAdapter.OnInventoryClickListener {
|
public class InventoryFragment extends Fragment implements InventoryAdapter.OnInventoryClickListener {
|
||||||
@@ -55,8 +49,7 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
private final List<InventoryDTO> inventoryList = new ArrayList<>();
|
private final List<InventoryDTO> inventoryList = new ArrayList<>();
|
||||||
private final List<CategoryDTO> categoryList = new ArrayList<>();
|
private final List<CategoryDTO> categoryList = new ArrayList<>();
|
||||||
private InventoryAdapter adapter;
|
private InventoryAdapter adapter;
|
||||||
@Inject InventoryApi inventoryApi;
|
private InventoryViewModel viewModel;
|
||||||
@Inject CategoryApi categoryApi;
|
|
||||||
|
|
||||||
private SwipeRefreshLayout swipeRefreshLayout;
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
@@ -82,7 +75,13 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
private boolean spinnerReady = false;
|
private boolean spinnerReady = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(InventoryViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_inventory, container, false);
|
View view = inflater.inflate(R.layout.fragment_inventory, container, false);
|
||||||
|
|
||||||
@@ -117,21 +116,13 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
|
|
||||||
// Categories
|
// Categories
|
||||||
private void loadCategories() {
|
private void loadCategories() {
|
||||||
categoryApi.getAllCategories(0, 100).enqueue(new Callback<PageResponse<CategoryDTO>>() {
|
viewModel.getAllCategories(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
@Override
|
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
public void onResponse(Call<PageResponse<CategoryDTO>> call,
|
|
||||||
Response<PageResponse<CategoryDTO>> response) {
|
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
|
||||||
categoryList.clear();
|
categoryList.clear();
|
||||||
categoryList.addAll(response.body().getContent());
|
categoryList.addAll(resource.data.getContent());
|
||||||
setupCategorySpinner();
|
setupCategorySpinner();
|
||||||
}
|
} else if (resource != null && resource.status == Resource.Status.ERROR) {
|
||||||
}
|
Log.e(TAG, "Failed to load categories: " + resource.message);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<PageResponse<CategoryDTO>> call, Throwable t) {
|
|
||||||
Log.e(TAG, "Failed to load categories", t);
|
|
||||||
// Still setup spinner with just "All"
|
|
||||||
setupCategorySpinner();
|
setupCategorySpinner();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -145,6 +136,7 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
categoryNames.add(c.getCategoryName());
|
categoryNames.add(c.getCategoryName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getContext() != null) {
|
||||||
BlackTextArrayAdapter<String> spinnerAdapter = new BlackTextArrayAdapter<>(
|
BlackTextArrayAdapter<String> spinnerAdapter = new BlackTextArrayAdapter<>(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
android.R.layout.simple_spinner_item,
|
android.R.layout.simple_spinner_item,
|
||||||
@@ -173,6 +165,7 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
|
|
||||||
@@ -209,7 +202,7 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
|
|
||||||
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||||
if (dy <= 0)
|
if (dy <= 0)
|
||||||
return;
|
return;
|
||||||
LinearLayoutManager lm = (LinearLayoutManager) rv.getLayoutManager();
|
LinearLayoutManager lm = (LinearLayoutManager) rv.getLayoutManager();
|
||||||
@@ -230,11 +223,10 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
swipeRefreshLayout.setOnRefreshListener(() -> loadInventory(true));
|
swipeRefreshLayout.setOnRefreshListener(() -> loadInventory(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load inventory
|
// Helper function to get a list of all inventory items from the backend
|
||||||
private void loadInventory(boolean reset) {
|
private void loadInventory(boolean reset) {
|
||||||
if (isLoading)
|
if (isLoading)
|
||||||
return;
|
return;
|
||||||
isLoading = true;
|
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
currentPage = 0;
|
currentPage = 0;
|
||||||
@@ -244,37 +236,36 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
// Build query: combine search text + selected category
|
// Build query: combine search text + selected category
|
||||||
String q = buildQuery();
|
String q = buildQuery();
|
||||||
|
|
||||||
inventoryApi.getAllInventory(q, currentPage, PAGE_SIZE, "inventoryId,asc")
|
//Load all inventory items from the backend using viewModel
|
||||||
.enqueue(new Callback<PageResponse<InventoryDTO>>() {
|
viewModel.getAllInventory(q, currentPage, PAGE_SIZE, "inventoryId,asc").observe(getViewLifecycleOwner(), resource -> {
|
||||||
@Override
|
if (resource == null) return;
|
||||||
public void onResponse(Call<PageResponse<InventoryDTO>> call,
|
|
||||||
Response<PageResponse<InventoryDTO>> response) {
|
|
||||||
isLoading = false;
|
|
||||||
if (swipeRefreshLayout != null)
|
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
|
||||||
|
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
// Check the status to see if the resource is loaded and display the data
|
||||||
PageResponse<InventoryDTO> page = response.body();
|
switch (resource.status) {
|
||||||
if (reset)
|
case LOADING:
|
||||||
inventoryList.clear();
|
// Show loading indicator
|
||||||
inventoryList.addAll(page.getContent());
|
isLoading = true;
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(true);
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
// Hide loading indicator and display data
|
||||||
|
isLoading = false;
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
|
if (resource.data != null) {
|
||||||
|
if (reset) inventoryList.clear();
|
||||||
|
inventoryList.addAll(resource.data.getContent());
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
isLastPage = page.isLast();
|
isLastPage = resource.data.isLast();
|
||||||
if (!isLastPage)
|
if (!isLastPage) currentPage++;
|
||||||
currentPage++;
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Error " + response.code());
|
|
||||||
Toast.makeText(getContext(), "Failed to load inventory", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
case ERROR:
|
||||||
@Override
|
// Hide loading indicator and toast error message
|
||||||
public void onFailure(Call<PageResponse<InventoryDTO>> call, Throwable t) {
|
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
if (swipeRefreshLayout != null)
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
Log.e(TAG, "Error: " + resource.message);
|
||||||
Log.e(TAG, "Network error", t);
|
Toast.makeText(getContext(), "Failed to load inventory: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(getContext(), "Network error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -308,24 +299,17 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void bulkDelete(List<Long> ids) {
|
private void bulkDelete(List<Long> ids) {
|
||||||
inventoryApi.bulkDeleteInventory(new BulkDeleteRequest(ids))
|
viewModel.bulkDeleteInventory(ids).observe(getViewLifecycleOwner(), resource -> {
|
||||||
.enqueue(new Callback<Void>() {
|
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||||
@Override
|
if (resource.status == Resource.Status.SUCCESS) {
|
||||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
|
||||||
if (response.isSuccessful()) {
|
|
||||||
adapter.clearSelection();
|
adapter.clearSelection();
|
||||||
hideBulkDeleteBar();
|
hideBulkDeleteBar();
|
||||||
loadInventory(true);
|
loadInventory(true);
|
||||||
Toast.makeText(getContext(), ids.size() + " item(s) deleted", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), ids.size() + " item(s) deleted", Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getContext(), "Delete failed", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<Void> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.os.Bundle;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -25,10 +26,10 @@ import android.widget.Toast;
|
|||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
|
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
|
||||||
import com.example.petstoremobile.adapters.PetAdapter;
|
import com.example.petstoremobile.adapters.PetAdapter;
|
||||||
import com.example.petstoremobile.api.PetApi;
|
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.dtos.PetDTO;
|
import com.example.petstoremobile.dtos.PetDTO;
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.PetViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -38,9 +39,6 @@ import javax.inject.Inject;
|
|||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class PetFragment extends Fragment implements PetAdapter.OnPetClickListener {
|
public class PetFragment extends Fragment implements PetAdapter.OnPetClickListener {
|
||||||
@@ -48,13 +46,19 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
|||||||
private List<PetDTO> filteredList = new ArrayList<>();
|
private List<PetDTO> filteredList = new ArrayList<>();
|
||||||
private ImageButton hamburger;
|
private ImageButton hamburger;
|
||||||
private PetAdapter adapter;
|
private PetAdapter adapter;
|
||||||
@Inject PetApi api;
|
private PetViewModel viewModel;
|
||||||
|
|
||||||
@Inject @Named("baseUrl") String baseUrl;
|
@Inject @Named("baseUrl") String baseUrl;
|
||||||
private SwipeRefreshLayout swipeRefreshLayout;
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
private Spinner spinnerStatus;
|
private Spinner spinnerStatus;
|
||||||
|
|
||||||
//load pet view
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(PetViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
@@ -67,12 +71,9 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
|||||||
setupStatusFilter(view);
|
setupStatusFilter(view);
|
||||||
setupSwipeRefresh(view);
|
setupSwipeRefresh(view);
|
||||||
|
|
||||||
|
|
||||||
//Add button to opens the add dialog
|
|
||||||
FloatingActionButton fabAddPet = view.findViewById(R.id.fabAddPet);
|
FloatingActionButton fabAddPet = view.findViewById(R.id.fabAddPet);
|
||||||
fabAddPet.setOnClickListener(v -> openPetDetails(-1));
|
fabAddPet.setOnClickListener(v -> openPetDetails(-1));
|
||||||
|
|
||||||
//Make the hamburger button open the drawer from listFragment
|
|
||||||
hamburger.setOnClickListener(v -> {
|
hamburger.setOnClickListener(v -> {
|
||||||
Fragment parent = getParentFragment();
|
Fragment parent = getParentFragment();
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
@@ -103,7 +104,6 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Setup the status filter spinner
|
|
||||||
private void setupStatusFilter(View view) {
|
private void setupStatusFilter(View view) {
|
||||||
spinnerStatus = view.findViewById(R.id.spinnerStatus);
|
spinnerStatus = view.findViewById(R.id.spinnerStatus);
|
||||||
String[] statuses = {"All Statuses", "Available", "Adopted"};
|
String[] statuses = {"All Statuses", "Available", "Adopted"};
|
||||||
@@ -122,7 +122,6 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to filter pets based on search and status filter
|
|
||||||
private void filterPets() {
|
private void filterPets() {
|
||||||
String query = etSearch.getText().toString().toLowerCase();
|
String query = etSearch.getText().toString().toLowerCase();
|
||||||
String selectedStatus = spinnerStatus.getSelectedItem().toString();
|
String selectedStatus = spinnerStatus.getSelectedItem().toString();
|
||||||
@@ -146,14 +145,10 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
|||||||
|
|
||||||
private void setupSwipeRefresh(View view) {
|
private void setupSwipeRefresh(View view) {
|
||||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshPet);
|
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshPet);
|
||||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
swipeRefreshLayout.setOnRefreshListener(this::loadPetData);
|
||||||
loadPetData();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Open pet profile
|
|
||||||
private void openPetProfile(int position) {
|
private void openPetProfile(int position) {
|
||||||
//Make a bundle to pass data to the profile fragment
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
PetDTO pet = filteredList.get(position);
|
PetDTO pet = filteredList.get(position);
|
||||||
args.putInt("petId", pet.getPetId().intValue());
|
args.putInt("petId", pet.getPetId().intValue());
|
||||||
@@ -172,12 +167,10 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
|||||||
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_profile, args);
|
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_profile, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Open the pet detail view for adding
|
|
||||||
private void openPetDetails(int position) {
|
private void openPetDetails(int position) {
|
||||||
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail);
|
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by PetAdapter when a row is clicked to open the details view
|
|
||||||
@Override
|
@Override
|
||||||
public void onPetClick(int position) {
|
public void onPetClick(int position) {
|
||||||
openPetProfile(position);
|
openPetProfile(position);
|
||||||
@@ -185,38 +178,35 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
|||||||
|
|
||||||
// Helper function to get a list of all pets from the backend
|
// Helper function to get a list of all pets from the backend
|
||||||
private void loadPetData() {
|
private void loadPetData() {
|
||||||
if (swipeRefreshLayout != null) {
|
//Load all pets from the backend using viewModel
|
||||||
swipeRefreshLayout.setRefreshing(true);
|
viewModel.getAllPets(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
}
|
if (resource == null) return;
|
||||||
api.getAllPets(0, 100).enqueue(new Callback<PageResponse<PetDTO>>() {
|
|
||||||
@Override
|
// Check the status to see if the resource is loaded and display the data
|
||||||
public void onResponse(Call<PageResponse<PetDTO>> call, Response<PageResponse<PetDTO>> response) {
|
switch (resource.status) {
|
||||||
if (swipeRefreshLayout != null) {
|
case LOADING:
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
// Show loading indicator
|
||||||
}
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(true);
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
// Hide loading indicator and display data
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
|
if (resource.data != null) {
|
||||||
petList.clear();
|
petList.clear();
|
||||||
petList.addAll(response.body().getContent());
|
petList.addAll(resource.data.getContent());
|
||||||
filterPets();
|
filterPets();
|
||||||
|
|
||||||
} else {
|
|
||||||
Log.e("onResponse: ", response.message());
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
case ERROR:
|
||||||
@Override
|
// Hide loading indicator and toast error message
|
||||||
public void onFailure(Call<PageResponse<PetDTO>> call, Throwable t) {
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
if (swipeRefreshLayout != null) {
|
Toast.makeText(getContext(), "Failed to load pets: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
Log.e("PetFragment", "Error loading pets: " + resource.message);
|
||||||
}
|
break;
|
||||||
Toast.makeText(getContext(),
|
|
||||||
"Failed to load pets", Toast.LENGTH_SHORT).show();
|
|
||||||
Log.e("onFailure: ", t.getMessage());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//set up the recyclerview and adapter
|
|
||||||
private void setupRecyclerView(View view) {
|
private void setupRecyclerView(View view) {
|
||||||
RecyclerView recyclerView = view.findViewById(R.id.recyclerViewPets);
|
RecyclerView recyclerView = view.findViewById(R.id.recyclerViewPets);
|
||||||
adapter = new PetAdapter(filteredList, this);
|
adapter = new PetAdapter(filteredList, this);
|
||||||
|
|||||||
@@ -5,18 +5,21 @@ import android.text.*;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.ProductAdapter;
|
import com.example.petstoremobile.adapters.ProductAdapter;
|
||||||
import com.example.petstoremobile.api.ProductApi;
|
|
||||||
import com.example.petstoremobile.api.auth.TokenManager;
|
import com.example.petstoremobile.api.auth.TokenManager;
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.dtos.ProductDTO;
|
import com.example.petstoremobile.dtos.ProductDTO;
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.ProductViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -24,7 +27,6 @@ import javax.inject.Inject;
|
|||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.*;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class ProductFragment extends Fragment implements ProductAdapter.OnProductClickListener {
|
public class ProductFragment extends Fragment implements ProductAdapter.OnProductClickListener {
|
||||||
@@ -34,13 +36,19 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
|
|||||||
private ProductAdapter adapter;
|
private ProductAdapter adapter;
|
||||||
private SwipeRefreshLayout swipeRefresh;
|
private SwipeRefreshLayout swipeRefresh;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
|
private ProductViewModel viewModel;
|
||||||
|
|
||||||
@Inject ProductApi api;
|
|
||||||
@Inject @Named("baseUrl") String baseUrl;
|
@Inject @Named("baseUrl") String baseUrl;
|
||||||
@Inject TokenManager tokenManager;
|
@Inject TokenManager tokenManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(ProductViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_product, container, false);
|
View view = inflater.inflate(R.layout.fragment_product, container, false);
|
||||||
|
|
||||||
@@ -109,25 +117,33 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
|
|||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to get a list of all products from the backend
|
||||||
private void loadProducts() {
|
private void loadProducts() {
|
||||||
|
//Load all products from the backend using viewModel
|
||||||
|
viewModel.getAllProducts(null, 0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
|
if (resource == null) return;
|
||||||
|
|
||||||
|
// Check the status to see if the resource is loaded and display the data
|
||||||
|
switch (resource.status) {
|
||||||
|
case LOADING:
|
||||||
|
// Show loading indicator
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
||||||
api.getAllProducts(null, 0, 100)
|
break;
|
||||||
.enqueue(new Callback<PageResponse<ProductDTO>>() {
|
case SUCCESS:
|
||||||
public void onResponse(Call<PageResponse<ProductDTO>> c,
|
// Hide loading indicator and display data
|
||||||
Response<PageResponse<ProductDTO>> r) {
|
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
if (r.isSuccessful() && r.body() != null) {
|
if (resource.data != null) {
|
||||||
productList.clear();
|
productList.clear();
|
||||||
productList.addAll(r.body().getContent());
|
productList.addAll(resource.data.getContent());
|
||||||
filter();
|
filter();
|
||||||
} else {
|
|
||||||
Toast.makeText(getContext(), "Failed to load products",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
public void onFailure(Call<PageResponse<ProductDTO>> c, Throwable t) {
|
case ERROR:
|
||||||
|
// Hide loading indicator and toast error message
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
Log.e("ProductFragment", t.getMessage());
|
Toast.makeText(getContext(), "Failed to load products: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
|
Log.e("ProductFragment", "Error loading products: " + resource.message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,25 +5,24 @@ import android.text.*;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.ProductSupplierAdapter;
|
import com.example.petstoremobile.adapters.ProductSupplierAdapter;
|
||||||
import com.example.petstoremobile.api.ProductSupplierApi;
|
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.dtos.ProductSupplierDTO;
|
import com.example.petstoremobile.dtos.ProductSupplierDTO;
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
import com.example.petstoremobile.fragments.listfragments.detailfragments.ProductSupplierDetailFragment;
|
import com.example.petstoremobile.viewmodels.ProductSupplierViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.*;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class ProductSupplierFragment extends Fragment
|
public class ProductSupplierFragment extends Fragment
|
||||||
@@ -34,11 +33,16 @@ public class ProductSupplierFragment extends Fragment
|
|||||||
private ProductSupplierAdapter adapter;
|
private ProductSupplierAdapter adapter;
|
||||||
private SwipeRefreshLayout swipeRefresh;
|
private SwipeRefreshLayout swipeRefresh;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
|
private ProductSupplierViewModel viewModel;
|
||||||
@Inject ProductSupplierApi api;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(ProductSupplierViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_product_supplier, container, false);
|
View view = inflater.inflate(R.layout.fragment_product_supplier, container, false);
|
||||||
|
|
||||||
@@ -103,25 +107,33 @@ public class ProductSupplierFragment extends Fragment
|
|||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to get a list of all product suppliers from the backend
|
||||||
private void loadData() {
|
private void loadData() {
|
||||||
|
//Load all product suppliers from the backend using viewModel
|
||||||
|
viewModel.getAllProductSuppliers(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
|
if (resource == null) return;
|
||||||
|
|
||||||
|
// Check the status to see if the resource is loaded and display the data
|
||||||
|
switch (resource.status) {
|
||||||
|
case LOADING:
|
||||||
|
// Show loading indicator
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
||||||
api.getAllProductSuppliers(0, 100)
|
break;
|
||||||
.enqueue(new Callback<PageResponse<ProductSupplierDTO>>() {
|
case SUCCESS:
|
||||||
public void onResponse(Call<PageResponse<ProductSupplierDTO>> c,
|
// Hide loading indicator and display data
|
||||||
Response<PageResponse<ProductSupplierDTO>> r) {
|
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
if (r.isSuccessful() && r.body() != null) {
|
if (resource.data != null) {
|
||||||
psList.clear();
|
psList.clear();
|
||||||
psList.addAll(r.body().getContent());
|
psList.addAll(resource.data.getContent());
|
||||||
filter(etSearch != null ? etSearch.getText().toString() : "");
|
filter(etSearch != null ? etSearch.getText().toString() : "");
|
||||||
} else {
|
|
||||||
Toast.makeText(getContext(), "Failed to load",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
public void onFailure(Call<PageResponse<ProductSupplierDTO>> c, Throwable t) {
|
case ERROR:
|
||||||
|
// Hide loading indicator and toast error message
|
||||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
Log.e("PSFragment", t.getMessage());
|
Toast.makeText(getContext(), "Failed to load: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
|
Log.e("PSFragment", "Error loading: " + resource.message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,23 +5,23 @@ import android.text.*;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.PurchaseOrderAdapter;
|
import com.example.petstoremobile.adapters.PurchaseOrderAdapter;
|
||||||
import com.example.petstoremobile.api.PurchaseOrderApi;
|
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.dtos.PurchaseOrderDTO;
|
import com.example.petstoremobile.dtos.PurchaseOrderDTO;
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.PurchaseOrderViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.*;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class PurchaseOrderFragment extends Fragment
|
public class PurchaseOrderFragment extends Fragment
|
||||||
@@ -32,8 +32,13 @@ public class PurchaseOrderFragment extends Fragment
|
|||||||
private PurchaseOrderAdapter adapter;
|
private PurchaseOrderAdapter adapter;
|
||||||
private SwipeRefreshLayout swipeRefresh;
|
private SwipeRefreshLayout swipeRefresh;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
|
private PurchaseOrderViewModel viewModel;
|
||||||
|
|
||||||
@Inject PurchaseOrderApi api;
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(PurchaseOrderViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
@@ -75,7 +80,7 @@ public class PurchaseOrderFragment extends Fragment
|
|||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onTextChanged(CharSequence s, int a, int b, int c) {
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
filter(s.toString());
|
filter(s.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -102,29 +107,33 @@ public class PurchaseOrderFragment extends Fragment
|
|||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to get a list of all purchase orders from the backend
|
||||||
private void loadData() {
|
private void loadData() {
|
||||||
if (swipeRefresh != null)
|
//Load all purchase orders from the backend using viewModel
|
||||||
swipeRefresh.setRefreshing(true);
|
viewModel.getAllPurchaseOrders(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
api.getAllPurchaseOrders(0, 100)
|
if (resource == null) return;
|
||||||
.enqueue(new Callback<PageResponse<PurchaseOrderDTO>>() {
|
|
||||||
public void onResponse(Call<PageResponse<PurchaseOrderDTO>> c,
|
|
||||||
Response<PageResponse<PurchaseOrderDTO>> r) {
|
|
||||||
if (swipeRefresh != null)
|
|
||||||
swipeRefresh.setRefreshing(false);
|
|
||||||
if (r.isSuccessful() && r.body() != null) {
|
|
||||||
poList.clear();
|
|
||||||
poList.addAll(r.body().getContent());
|
|
||||||
filter(etSearch != null ? etSearch.getText().toString() : "");
|
|
||||||
} else {
|
|
||||||
Toast.makeText(getContext(), "Failed to load purchase orders",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onFailure(Call<PageResponse<PurchaseOrderDTO>> c, Throwable t) {
|
// Check the status to see if the resource is loaded and display the data
|
||||||
if (swipeRefresh != null)
|
switch (resource.status) {
|
||||||
swipeRefresh.setRefreshing(false);
|
case LOADING:
|
||||||
Log.e("POFragment", t.getMessage());
|
// Show loading indicator
|
||||||
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
// Hide loading indicator and display data
|
||||||
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
|
if (resource.data != null) {
|
||||||
|
poList.clear();
|
||||||
|
poList.addAll(resource.data.getContent());
|
||||||
|
filter(etSearch != null ? etSearch.getText().toString() : "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
// Hide loading indicator and toast error message
|
||||||
|
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||||
|
Toast.makeText(getContext(), "Failed to load purchase orders: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
|
Log.e("POFragment", "Error loading purchase orders: " + resource.message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.example.petstoremobile.fragments.listfragments;
|
package com.example.petstoremobile.fragments.listfragments;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.os.Bundle;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -22,21 +23,16 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.ServiceAdapter;
|
import com.example.petstoremobile.adapters.ServiceAdapter;
|
||||||
import com.example.petstoremobile.api.ServiceApi;
|
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.dtos.ServiceDTO;
|
import com.example.petstoremobile.dtos.ServiceDTO;
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.ServiceViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class ServiceFragment extends Fragment implements ServiceAdapter.OnServiceClickListener {
|
public class ServiceFragment extends Fragment implements ServiceAdapter.OnServiceClickListener {
|
||||||
@@ -45,13 +41,19 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
|||||||
private List<ServiceDTO> filteredList = new ArrayList<>();
|
private List<ServiceDTO> filteredList = new ArrayList<>();
|
||||||
private ServiceAdapter adapter;
|
private ServiceAdapter adapter;
|
||||||
private ImageButton hamburger;
|
private ImageButton hamburger;
|
||||||
@Inject ServiceApi api;
|
private ServiceViewModel viewModel;
|
||||||
private SwipeRefreshLayout swipeRefreshLayout;
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(ServiceViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
//load service view
|
//load service view
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_service, container, false);
|
View view = inflater.inflate(R.layout.fragment_service, container, false);
|
||||||
|
|
||||||
@@ -98,8 +100,8 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
|||||||
} else {
|
} else {
|
||||||
String lower = query.toLowerCase();
|
String lower = query.toLowerCase();
|
||||||
for (ServiceDTO s : serviceList) {
|
for (ServiceDTO s : serviceList) {
|
||||||
if (s.getServiceName().toLowerCase().contains(lower)
|
if ((s.getServiceName() != null && s.getServiceName().toLowerCase().contains(lower))
|
||||||
|| s.getServiceDesc().toLowerCase().contains(lower)) {
|
|| (s.getServiceDesc() != null && s.getServiceDesc().toLowerCase().contains(lower))) {
|
||||||
filteredList.add(s);
|
filteredList.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,9 +111,7 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
|||||||
|
|
||||||
private void setupSwipeRefresh(View view) {
|
private void setupSwipeRefresh(View view) {
|
||||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshService);
|
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshService);
|
||||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
swipeRefreshLayout.setOnRefreshListener(this::loadServiceData);
|
||||||
loadServiceData();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Open the service detail view depending on the mode
|
//Open the service detail view depending on the mode
|
||||||
@@ -141,35 +141,33 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
|||||||
|
|
||||||
// Helper function to get a list of all services from the backend
|
// Helper function to get a list of all services from the backend
|
||||||
private void loadServiceData() {
|
private void loadServiceData() {
|
||||||
if (swipeRefreshLayout != null) {
|
//Load all services from the backend using viewModel
|
||||||
swipeRefreshLayout.setRefreshing(true);
|
viewModel.getAllServices(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
}
|
if (resource == null) return;
|
||||||
api.getAllServices(0, 100).enqueue(new Callback<PageResponse<ServiceDTO>>() {
|
|
||||||
@Override
|
// Check the status to see if the resource is loaded and display the data
|
||||||
public void onResponse(Call<PageResponse<ServiceDTO>> call, Response<PageResponse<ServiceDTO>> response) {
|
switch (resource.status) {
|
||||||
if (swipeRefreshLayout != null) {
|
case LOADING:
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
// Show loading indicator
|
||||||
}
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(true);
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
// Hide loading indicator and display data
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
|
if (resource.data != null) {
|
||||||
serviceList.clear();
|
serviceList.clear();
|
||||||
serviceList.addAll(response.body().getContent());
|
serviceList.addAll(resource.data.getContent());
|
||||||
filterServices(etSearch.getText().toString());
|
filterServices(etSearch != null ? etSearch.getText().toString() : "");
|
||||||
|
|
||||||
} else {
|
|
||||||
Log.e("onResponse: ", response.message());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<PageResponse<ServiceDTO>> call, Throwable t) {
|
|
||||||
if (swipeRefreshLayout != null) {
|
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
// Hide loading indicator and toast error message
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
if (getContext() != null) {
|
if (getContext() != null) {
|
||||||
Toast.makeText(getContext(),
|
Toast.makeText(getContext(), "Failed to load services: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
"Failed to load services", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
Log.e("onFailure: ", t.getMessage());
|
Log.e("ServiceFragment", "Error loading services: " + resource.message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.os.Bundle;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -22,21 +23,16 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.SupplierAdapter;
|
import com.example.petstoremobile.adapters.SupplierAdapter;
|
||||||
import com.example.petstoremobile.api.SupplierApi;
|
|
||||||
import com.example.petstoremobile.dtos.PageResponse;
|
|
||||||
import com.example.petstoremobile.dtos.SupplierDTO;
|
import com.example.petstoremobile.dtos.SupplierDTO;
|
||||||
import com.example.petstoremobile.fragments.ListFragment;
|
import com.example.petstoremobile.fragments.ListFragment;
|
||||||
|
import com.example.petstoremobile.viewmodels.SupplierViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupplierClickListener {
|
public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupplierClickListener {
|
||||||
@@ -45,13 +41,19 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
|||||||
private List<SupplierDTO> filteredList = new ArrayList<>();
|
private List<SupplierDTO> filteredList = new ArrayList<>();
|
||||||
private SupplierAdapter adapter;
|
private SupplierAdapter adapter;
|
||||||
private ImageButton hamburger;
|
private ImageButton hamburger;
|
||||||
@Inject SupplierApi api;
|
private SupplierViewModel viewModel;
|
||||||
private SwipeRefreshLayout swipeRefreshLayout;
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private EditText etSearch;
|
private EditText etSearch;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(SupplierViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
//load supplier view
|
//load supplier view
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_supplier, container, false);
|
View view = inflater.inflate(R.layout.fragment_supplier, container, false);
|
||||||
|
|
||||||
@@ -98,9 +100,9 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
|||||||
} else {
|
} else {
|
||||||
String lower = query.toLowerCase();
|
String lower = query.toLowerCase();
|
||||||
for (SupplierDTO s : supplierList) {
|
for (SupplierDTO s : supplierList) {
|
||||||
if (s.getSupCompany().toLowerCase().contains(lower)
|
if ((s.getSupCompany() != null && s.getSupCompany().toLowerCase().contains(lower))
|
||||||
|| s.getSupContactFirstName().toLowerCase().contains(lower)
|
|| (s.getSupContactFirstName() != null && s.getSupContactFirstName().toLowerCase().contains(lower))
|
||||||
|| s.getSupContactLastName().toLowerCase().contains(lower)) {
|
|| (s.getSupContactLastName() != null && s.getSupContactLastName().toLowerCase().contains(lower))) {
|
||||||
filteredList.add(s);
|
filteredList.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,9 +112,7 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
|||||||
|
|
||||||
private void setupSwipeRefresh(View view) {
|
private void setupSwipeRefresh(View view) {
|
||||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshSupplier);
|
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshSupplier);
|
||||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
swipeRefreshLayout.setOnRefreshListener(this::loadSupplierData);
|
||||||
loadSupplierData();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Open the supplier detail view depending on the mode
|
//Open the supplier detail view depending on the mode
|
||||||
@@ -144,35 +144,33 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
|||||||
|
|
||||||
// Helper function to get a list of all suppliers from the backend
|
// Helper function to get a list of all suppliers from the backend
|
||||||
private void loadSupplierData() {
|
private void loadSupplierData() {
|
||||||
if (swipeRefreshLayout != null) {
|
//Load all suppliers from the backend using viewModel
|
||||||
swipeRefreshLayout.setRefreshing(true);
|
viewModel.getAllSuppliers(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
}
|
if (resource == null) return;
|
||||||
api.getAllSuppliers(0, 100).enqueue(new Callback<PageResponse<SupplierDTO>>() {
|
|
||||||
@Override
|
// Check the status to see if the resource is loaded and display the data
|
||||||
public void onResponse(Call<PageResponse<SupplierDTO>> call, Response<PageResponse<SupplierDTO>> response) {
|
switch (resource.status) {
|
||||||
if (swipeRefreshLayout != null) {
|
case LOADING:
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
// Show loading indicator
|
||||||
}
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(true);
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
// Hide loading indicator and display data
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
|
if (resource.data != null) {
|
||||||
supplierList.clear();
|
supplierList.clear();
|
||||||
supplierList.addAll(response.body().getContent());
|
supplierList.addAll(resource.data.getContent());
|
||||||
filterSuppliers(etSearch.getText().toString());
|
filterSuppliers(etSearch.getText().toString());
|
||||||
|
|
||||||
} else {
|
|
||||||
Log.e("onResponse: ", response.message());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<PageResponse<SupplierDTO>> call, Throwable t) {
|
|
||||||
if (swipeRefreshLayout != null) {
|
|
||||||
swipeRefreshLayout.setRefreshing(false);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
// Hide loading indicator and toast error message
|
||||||
|
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||||
if (getContext() != null) {
|
if (getContext() != null) {
|
||||||
Toast.makeText(getContext(),
|
Toast.makeText(getContext(), "Failed to load suppliers: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
"Failed to load suppliers", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
Log.e("onFailure: ", t.getMessage());
|
Log.e("SupplierFragment", "Error loading suppliers: " + resource.message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import android.widget.*;
|
|||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.content.FileProvider;
|
import androidx.core.content.FileProvider;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
@@ -28,9 +30,11 @@ import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
|
|||||||
import com.example.petstoremobile.api.*;
|
import com.example.petstoremobile.api.*;
|
||||||
import com.example.petstoremobile.api.auth.TokenManager;
|
import com.example.petstoremobile.api.auth.TokenManager;
|
||||||
import com.example.petstoremobile.dtos.*;
|
import com.example.petstoremobile.dtos.*;
|
||||||
|
import com.example.petstoremobile.viewmodels.ProductViewModel;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
import com.example.petstoremobile.utils.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -41,7 +45,6 @@ import dagger.hilt.android.AndroidEntryPoint;
|
|||||||
import okhttp3.MediaType;
|
import okhttp3.MediaType;
|
||||||
import okhttp3.MultipartBody;
|
import okhttp3.MultipartBody;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import retrofit2.*;
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class ProductDetailFragment extends Fragment {
|
public class ProductDetailFragment extends Fragment {
|
||||||
@@ -61,9 +64,8 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
|
|
||||||
private List<CategoryDTO> categoryList = new ArrayList<>();
|
private List<CategoryDTO> categoryList = new ArrayList<>();
|
||||||
private Uri photoUri;
|
private Uri photoUri;
|
||||||
|
private ProductViewModel viewModel;
|
||||||
|
|
||||||
@Inject ProductApi productApi;
|
|
||||||
@Inject CategoryApi categoryApi;
|
|
||||||
@Inject @Named("baseUrl") String baseUrl;
|
@Inject @Named("baseUrl") String baseUrl;
|
||||||
@Inject TokenManager tokenManager;
|
@Inject TokenManager tokenManager;
|
||||||
|
|
||||||
@@ -74,12 +76,13 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
viewModel = new ViewModelProvider(this).get(ProductViewModel.class);
|
||||||
|
|
||||||
galleryLauncher = registerForActivityResult(
|
galleryLauncher = registerForActivityResult(
|
||||||
new ActivityResultContracts.StartActivityForResult(),
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
result -> {
|
result -> {
|
||||||
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
|
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
|
||||||
Uri selectedImage = result.getData().getData();
|
Uri selectedImage = result.getData().getData();
|
||||||
// Update image view locally
|
|
||||||
Glide.with(this).load(selectedImage).into(ivProductImage);
|
Glide.with(this).load(selectedImage).into(ivProductImage);
|
||||||
photoUri = selectedImage;
|
photoUri = selectedImage;
|
||||||
hasImage = true;
|
hasImage = true;
|
||||||
@@ -92,7 +95,6 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
new ActivityResultContracts.TakePicture(),
|
new ActivityResultContracts.TakePicture(),
|
||||||
success -> {
|
success -> {
|
||||||
if (success) {
|
if (success) {
|
||||||
// Update image view locally
|
|
||||||
Glide.with(this).load(photoUri).into(ivProductImage);
|
Glide.with(this).load(photoUri).into(ivProductImage);
|
||||||
hasImage = true;
|
hasImage = true;
|
||||||
isImageChanged = true;
|
isImageChanged = true;
|
||||||
@@ -185,18 +187,11 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
|
|
||||||
// Helper function to load categories from the backend for the spinner
|
// Helper function to load categories from the backend for the spinner
|
||||||
private void loadCategories() {
|
private void loadCategories() {
|
||||||
categoryApi.getAllCategories(0, 100)
|
viewModel.getAllCategories(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||||
.enqueue(new Callback<PageResponse<CategoryDTO>>() {
|
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
public void onResponse(Call<PageResponse<CategoryDTO>> c,
|
categoryList = resource.data.getContent();
|
||||||
Response<PageResponse<CategoryDTO>> r) {
|
|
||||||
if (r.isSuccessful() && r.body() != null) {
|
|
||||||
categoryList = r.body().getContent();
|
|
||||||
populateCategorySpinner();
|
populateCategorySpinner();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
public void onFailure(Call<PageResponse<CategoryDTO>> c, Throwable t) {
|
|
||||||
Log.e("ProductDetail", "Category load failed: " + t.getMessage());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,24 +260,19 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
// updating/adding photo, removing photo or no change
|
// updating/adding photo, removing photo or no change
|
||||||
private void performPendingImageActions(String successMsg) {
|
private void performPendingImageActions(String successMsg) {
|
||||||
if (isImageRemoved) {
|
if (isImageRemoved) {
|
||||||
//if the image is removed then delete the image
|
viewModel.deleteProductImage(prodId).observe(getViewLifecycleOwner(), resource -> {
|
||||||
productApi.deleteProductImage(prodId).enqueue(new Callback<Void>() {
|
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||||
@Override
|
if (resource.status == Resource.Status.SUCCESS) {
|
||||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
|
||||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||||
navigateBack();
|
} else {
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onFailure(Call<Void> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), successMsg + " (but image removal failed)", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), successMsg + " (but image removal failed)", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
navigateBack();
|
navigateBack();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (isImageChanged && photoUri != null) {
|
} else if (isImageChanged && photoUri != null) {
|
||||||
//if the image is changed then upload it
|
|
||||||
uploadProductImageAndNavigate(photoUri, successMsg);
|
uploadProductImageAndNavigate(photoUri, successMsg);
|
||||||
} else {
|
} else {
|
||||||
//if no changes then navigate back
|
|
||||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||||
navigateBack();
|
navigateBack();
|
||||||
}
|
}
|
||||||
@@ -291,8 +281,7 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
// Helper function to upload the product image by calling the backend
|
// Helper function to upload the product image by calling the backend
|
||||||
// and then navigate back to the previous screen
|
// and then navigate back to the previous screen
|
||||||
private void uploadProductImageAndNavigate(Uri uri, String successMsg) {
|
private void uploadProductImageAndNavigate(Uri uri, String successMsg) {
|
||||||
try {
|
File file = FileUtils.getFileFromUri(requireContext(), uri);
|
||||||
File file = getFileFromUri(uri);
|
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||||
navigateBack();
|
navigateBack();
|
||||||
@@ -302,50 +291,18 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
RequestBody requestFile = RequestBody.create(file, MediaType.parse(requireContext().getContentResolver().getType(uri)));
|
RequestBody requestFile = RequestBody.create(file, MediaType.parse(requireContext().getContentResolver().getType(uri)));
|
||||||
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
|
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
|
||||||
|
|
||||||
productApi.uploadProductImage(prodId, body)
|
viewModel.uploadProductImage(prodId, body).observe(getViewLifecycleOwner(), resource -> {
|
||||||
.enqueue(new Callback<Void>() {
|
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||||
@Override
|
if (resource.status == Resource.Status.SUCCESS) {
|
||||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
|
||||||
if (response.isSuccessful()) {
|
|
||||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getContext(), successMsg + " (but image upload failed)", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), successMsg + " (but image upload failed)", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
navigateBack();
|
navigateBack();
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void onFailure(Call<Void> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), successMsg + " (network error during upload)", Toast.LENGTH_SHORT).show();
|
|
||||||
navigateBack();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("ProductDetail", "Error uploading image", e);
|
|
||||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
|
||||||
navigateBack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to get the File from the Uri
|
|
||||||
private File getFileFromUri(Uri uri) {
|
|
||||||
try {
|
|
||||||
InputStream inputStream = requireContext().getContentResolver().openInputStream(uri);
|
|
||||||
File tempFile = new File(requireContext().getCacheDir(), "upload_product_image.jpg");
|
|
||||||
FileOutputStream outputStream = new FileOutputStream(tempFile);
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int length;
|
|
||||||
while ((length = inputStream.read(buffer)) > 0) {
|
|
||||||
outputStream.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
outputStream.close();
|
|
||||||
inputStream.close();
|
|
||||||
return tempFile;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to save the product to the server
|
|
||||||
private void saveProduct() {
|
private void saveProduct() {
|
||||||
String name = etProductName.getText().toString().trim();
|
String name = etProductName.getText().toString().trim();
|
||||||
String desc = etProductDesc.getText().toString().trim();
|
String desc = etProductDesc.getText().toString().trim();
|
||||||
@@ -372,35 +329,25 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
ProductDTO dto = new ProductDTO(name, category.getCategoryId(), desc, price);
|
ProductDTO dto = new ProductDTO(name, category.getCategoryId(), desc, price);
|
||||||
|
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
productApi.updateProduct(prodId, dto).enqueue(new Callback<ProductDTO>() {
|
viewModel.updateProduct(prodId, dto).observe(getViewLifecycleOwner(), resource -> {
|
||||||
@Override
|
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||||
public void onResponse(Call<ProductDTO> call, Response<ProductDTO> response) {
|
if (resource.status == Resource.Status.SUCCESS) {
|
||||||
if (response.isSuccessful()) {
|
|
||||||
performPendingImageActions("Updated");
|
performPendingImageActions("Updated");
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getContext(), "Error " + response.code(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Error: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void onFailure(Call<ProductDTO> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
productApi.createProduct(dto).enqueue(new Callback<ProductDTO>() {
|
viewModel.createProduct(dto).observe(getViewLifecycleOwner(), resource -> {
|
||||||
@Override
|
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||||
public void onResponse(Call<ProductDTO> call, Response<ProductDTO> response) {
|
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
prodId = resource.data.getProdId();
|
||||||
prodId = response.body().getProdId();
|
|
||||||
performPendingImageActions("Saved");
|
performPendingImageActions("Saved");
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getContext(), "Error saving", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Error saving: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void onFailure(Call<ProductDTO> call, Throwable t) {
|
|
||||||
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,14 +357,11 @@ public class ProductDetailFragment extends Fragment {
|
|||||||
new AlertDialog.Builder(requireContext())
|
new AlertDialog.Builder(requireContext())
|
||||||
.setTitle("Delete Product?")
|
.setTitle("Delete Product?")
|
||||||
.setPositiveButton("Yes", (d, w) ->
|
.setPositiveButton("Yes", (d, w) ->
|
||||||
productApi.deleteProduct(prodId)
|
viewModel.deleteProduct(prodId).observe(getViewLifecycleOwner(), resource -> {
|
||||||
.enqueue(new Callback<Void>() {
|
if (resource != null && resource.status == Resource.Status.SUCCESS) {
|
||||||
public void onResponse(Call<Void> c, Response<Void> r) {
|
|
||||||
navigateBack();
|
navigateBack();
|
||||||
}
|
} else if (resource != null && resource.status == Resource.Status.ERROR) {
|
||||||
public void onFailure(Call<Void> c, Throwable t) {
|
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(getContext(), "Delete failed",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.setNegativeButton("No", null).show();
|
.setNegativeButton("No", null).show();
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
package com.example.petstoremobile.models;
|
|
||||||
|
|
||||||
public class Adoption {
|
|
||||||
private int adoptionId;
|
|
||||||
private String adopterName;
|
|
||||||
private String adopterEmail;
|
|
||||||
private String adopterPhone;
|
|
||||||
private String petName;
|
|
||||||
private String adoptionDate;
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public Adoption(int adoptionId, String adopterName, String adopterEmail, String adopterPhone, String petName, String adoptionDate, String status) {
|
|
||||||
this.adoptionId = adoptionId;
|
|
||||||
this.adopterName = adopterName;
|
|
||||||
this.adopterEmail = adopterEmail;
|
|
||||||
this.adopterPhone = adopterPhone;
|
|
||||||
this.petName = petName;
|
|
||||||
this.adoptionDate = adoptionDate;
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters and setters
|
|
||||||
public int getAdoptionId() {
|
|
||||||
return adoptionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdoptionId(int adoptionId) {
|
|
||||||
this.adoptionId = adoptionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAdopterName() {
|
|
||||||
return adopterName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdopterName(String adopterName) {
|
|
||||||
this.adopterName = adopterName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAdopterEmail() {
|
|
||||||
return adopterEmail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdopterEmail(String adopterEmail) {
|
|
||||||
this.adopterEmail = adopterEmail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAdopterPhone() {
|
|
||||||
return adopterPhone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdopterPhone(String adopterPhone) {
|
|
||||||
this.adopterPhone = adopterPhone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPetName() {
|
|
||||||
return petName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPetName(String petName) {
|
|
||||||
this.petName = petName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAdoptionDate() {
|
|
||||||
return adoptionDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdoptionDate(String adoptionDate) {
|
|
||||||
this.adoptionDate = adoptionDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
package com.example.petstoremobile.models;
|
|
||||||
|
|
||||||
|
|
||||||
public class Appointment {
|
|
||||||
private int appointmentId;
|
|
||||||
private String customerName;
|
|
||||||
private String petName;
|
|
||||||
private String serviceType;
|
|
||||||
private String appointmentDate;
|
|
||||||
private String appointmentTime;
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public Appointment(int appointmentId, String customerName, String petName, String serviceType, String appointmentDate, String appointmentTime, String status) {
|
|
||||||
this.appointmentId = appointmentId;
|
|
||||||
this.customerName = customerName;
|
|
||||||
this.petName = petName;
|
|
||||||
this.serviceType = serviceType;
|
|
||||||
this.appointmentDate = appointmentDate;
|
|
||||||
this.appointmentTime = appointmentTime;
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters and setters
|
|
||||||
public int getAppointmentId() {
|
|
||||||
return appointmentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCustomerName() {
|
|
||||||
return customerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustomerName(String customerName) {
|
|
||||||
this.customerName = customerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPetName() {
|
|
||||||
return petName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPetName(String petName) {
|
|
||||||
this.petName = petName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getServiceType() {
|
|
||||||
return serviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setServiceType(String serviceType) {
|
|
||||||
this.serviceType = serviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAppointmentDate() {
|
|
||||||
return appointmentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAppointmentDate(String appointmentDate) {
|
|
||||||
this.appointmentDate = appointmentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAppointmentTime() {
|
|
||||||
return appointmentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAppointmentTime(String appointmentTime) {
|
|
||||||
this.appointmentTime = appointmentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package com.example.petstoremobile.models;
|
|
||||||
|
|
||||||
|
|
||||||
public class Inventory {
|
|
||||||
private int inventoryId;
|
|
||||||
private String itemName;
|
|
||||||
private String category;
|
|
||||||
private int quantity;
|
|
||||||
private double unitPrice;
|
|
||||||
private String supplier;
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public Inventory(int inventoryId, String itemName, String category, int quantity, double unitPrice, String supplier) {
|
|
||||||
this.inventoryId = inventoryId;
|
|
||||||
this.itemName = itemName;
|
|
||||||
this.category = category;
|
|
||||||
this.quantity = quantity;
|
|
||||||
this.unitPrice = unitPrice;
|
|
||||||
this.supplier = supplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters and setters
|
|
||||||
public int getInventoryId() {
|
|
||||||
return inventoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getItemName() {
|
|
||||||
return itemName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setItemName(String itemName) {
|
|
||||||
this.itemName = itemName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCategory() {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCategory(String category) {
|
|
||||||
this.category = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getQuantity() {
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQuantity(int quantity) {
|
|
||||||
this.quantity = quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getUnitPrice() {
|
|
||||||
return unitPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnitPrice(double unitPrice) {
|
|
||||||
this.unitPrice = unitPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSupplier() {
|
|
||||||
return supplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSupplier(String supplier) {
|
|
||||||
this.supplier = supplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package com.example.petstoremobile.models;
|
|
||||||
|
|
||||||
|
|
||||||
public class Product {
|
|
||||||
private int productId;
|
|
||||||
private String productName;
|
|
||||||
private String productDesc;
|
|
||||||
private String category;
|
|
||||||
private double productPrice;
|
|
||||||
private int stockQuantity;
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public Product(int productId, String productName, String productDesc, String category, double productPrice, int stockQuantity) {
|
|
||||||
this.productId = productId;
|
|
||||||
this.productName = productName;
|
|
||||||
this.productDesc = productDesc;
|
|
||||||
this.category = category;
|
|
||||||
this.productPrice = productPrice;
|
|
||||||
this.stockQuantity = stockQuantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters and setters
|
|
||||||
public int getProductId() {
|
|
||||||
return productId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProductName() {
|
|
||||||
return productName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProductName(String productName) {
|
|
||||||
this.productName = productName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProductDesc() {
|
|
||||||
return productDesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProductDesc(String productDesc) {
|
|
||||||
this.productDesc = productDesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCategory() {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCategory(String category) {
|
|
||||||
this.category = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getProductPrice() {
|
|
||||||
return productPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProductPrice(double productPrice) {
|
|
||||||
this.productPrice = productPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStockQuantity() {
|
|
||||||
return stockQuantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStockQuantity(int stockQuantity) {
|
|
||||||
this.stockQuantity = stockQuantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package com.example.petstoremobile.models;
|
|
||||||
|
|
||||||
public class ProductSupplier {
|
|
||||||
private int supId;
|
|
||||||
private int prodId;
|
|
||||||
private String supCompany;
|
|
||||||
private String prodName;
|
|
||||||
private double cost;
|
|
||||||
|
|
||||||
public ProductSupplier(int supId, int prodId, String supCompany, String prodName, double cost) {
|
|
||||||
this.supId = supId;
|
|
||||||
this.prodId = prodId;
|
|
||||||
this.supCompany = supCompany;
|
|
||||||
this.prodName = prodName;
|
|
||||||
this.cost = cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSupId() {
|
|
||||||
return supId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProdId() {
|
|
||||||
return prodId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSupCompany() {
|
|
||||||
return supCompany;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProdName() {
|
|
||||||
return prodName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getCost() {
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSupCompany(String supCompany) {
|
|
||||||
this.supCompany = supCompany;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProdName(String prodName) {
|
|
||||||
this.prodName = prodName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCost(double cost) {
|
|
||||||
this.cost = cost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package com.example.petstoremobile.models;
|
|
||||||
|
|
||||||
public class PurchaseOrder {
|
|
||||||
private int purchaseOrderId;
|
|
||||||
private String supplierName;
|
|
||||||
private String orderDate;
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
public PurchaseOrder(int purchaseOrderId, String supplierName, String orderDate, String status) {
|
|
||||||
this.purchaseOrderId = purchaseOrderId;
|
|
||||||
this.supplierName = supplierName;
|
|
||||||
this.orderDate = orderDate;
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPurchaseOrderId() {
|
|
||||||
return purchaseOrderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSupplierName() {
|
|
||||||
return supplierName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrderDate() {
|
|
||||||
return orderDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.AdoptionApi;
|
||||||
|
import com.example.petstoremobile.dtos.AdoptionDTO;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class AdoptionRepository {
|
||||||
|
private final AdoptionApi adoptionApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AdoptionRepository(AdoptionApi adoptionApi) {
|
||||||
|
this.adoptionApi = adoptionApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all adoptions from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<AdoptionDTO>>> getAllAdoptions(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<AdoptionDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
adoptionApi.getAllAdoptions(page, size).enqueue(new Callback<PageResponse<AdoptionDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<AdoptionDTO>> call, Response<PageResponse<AdoptionDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<AdoptionDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific adoption record by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AdoptionDTO>> getAdoptionById(Long id) {
|
||||||
|
MutableLiveData<Resource<AdoptionDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
adoptionApi.getAdoptionById(id).enqueue(new Callback<AdoptionDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<AdoptionDTO> call, Response<AdoptionDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<AdoptionDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new adoption record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AdoptionDTO>> createAdoption(AdoptionDTO adoption) {
|
||||||
|
MutableLiveData<Resource<AdoptionDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
adoptionApi.createAdoption(adoption).enqueue(new Callback<AdoptionDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<AdoptionDTO> call, Response<AdoptionDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<AdoptionDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing adoption record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AdoptionDTO>> updateAdoption(Long id, AdoptionDTO adoption) {
|
||||||
|
MutableLiveData<Resource<AdoptionDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
adoptionApi.updateAdoption(id, adoption).enqueue(new Callback<AdoptionDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<AdoptionDTO> call, Response<AdoptionDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<AdoptionDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific adoption record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteAdoption(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
adoptionApi.deleteAdoption(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.AppointmentApi;
|
||||||
|
import com.example.petstoremobile.dtos.AppointmentDTO;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class AppointmentRepository {
|
||||||
|
private final AppointmentApi appointmentApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AppointmentRepository(AppointmentApi appointmentApi) {
|
||||||
|
this.appointmentApi = appointmentApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all appointments from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<AppointmentDTO>>> getAllAppointments(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<AppointmentDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
appointmentApi.getAllAppointments(page, size).enqueue(new Callback<PageResponse<AppointmentDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<AppointmentDTO>> call, Response<PageResponse<AppointmentDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<AppointmentDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific appointment by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AppointmentDTO>> getAppointmentById(Long id) {
|
||||||
|
MutableLiveData<Resource<AppointmentDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
appointmentApi.getAppointmentById(id).enqueue(new Callback<AppointmentDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<AppointmentDTO> call, Response<AppointmentDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<AppointmentDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new appointment record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AppointmentDTO>> createAppointment(AppointmentDTO appointment) {
|
||||||
|
MutableLiveData<Resource<AppointmentDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
appointmentApi.createAppointment(appointment).enqueue(new Callback<AppointmentDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<AppointmentDTO> call, Response<AppointmentDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<AppointmentDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing appointment record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AppointmentDTO>> updateAppointment(Long id, AppointmentDTO appointment) {
|
||||||
|
MutableLiveData<Resource<AppointmentDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
appointmentApi.updateAppointment(id, appointment).enqueue(new Callback<AppointmentDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<AppointmentDTO> call, Response<AppointmentDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<AppointmentDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific appointment record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteAppointment(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
appointmentApi.deleteAppointment(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.auth.AuthApi;
|
||||||
|
import com.example.petstoremobile.api.auth.TokenManager;
|
||||||
|
import com.example.petstoremobile.dtos.AuthDTO;
|
||||||
|
import com.example.petstoremobile.dtos.UserDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class AuthRepository {
|
||||||
|
private final AuthApi authApi;
|
||||||
|
private final TokenManager tokenManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AuthRepository(AuthApi authApi, TokenManager tokenManager) {
|
||||||
|
this.authApi = authApi;
|
||||||
|
this.tokenManager = tokenManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates the user and saves login data (token, username, role) upon success.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AuthDTO.LoginResponse>> login(AuthDTO.LoginRequest loginRequest) {
|
||||||
|
MutableLiveData<Resource<AuthDTO.LoginResponse>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
authApi.login(loginRequest).enqueue(new Callback<AuthDTO.LoginResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<AuthDTO.LoginResponse> call, Response<AuthDTO.LoginResponse> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
tokenManager.saveLoginData(
|
||||||
|
response.body().getToken(),
|
||||||
|
response.body().getUsername(),
|
||||||
|
response.body().getRole()
|
||||||
|
);
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Login failed: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<AuthDTO.LoginResponse> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the current user's profile information from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<UserDTO>> getMe() {
|
||||||
|
MutableLiveData<Resource<UserDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
authApi.getMe().enqueue(new Callback<UserDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<UserDTO> call, Response<UserDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<UserDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current user's profile details.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<UserDTO>> updateMe(Map<String, String> updates) {
|
||||||
|
MutableLiveData<Resource<UserDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
authApi.updateMe(updates).enqueue(new Callback<UserDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<UserDTO> call, Response<UserDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<UserDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads a multipart image to be used as the current user's avatar.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<UserDTO>> uploadAvatar(MultipartBody.Part avatar) {
|
||||||
|
MutableLiveData<Resource<UserDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
authApi.uploadAvatar(avatar).enqueue(new Callback<UserDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<UserDTO> call, Response<UserDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<UserDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to remove the current user's avatar.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteAvatar() {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
authApi.deleteAvatar().enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all authentication and login data from storage.
|
||||||
|
*/
|
||||||
|
public void logout() {
|
||||||
|
tokenManager.clearLoginData();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.CategoryApi;
|
||||||
|
import com.example.petstoremobile.dtos.CategoryDTO;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class CategoryRepository {
|
||||||
|
private final CategoryApi categoryApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public CategoryRepository(CategoryApi categoryApi) {
|
||||||
|
this.categoryApi = categoryApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all product categories from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<CategoryDTO>>> getAllCategories(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<CategoryDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
categoryApi.getAllCategories(page, size).enqueue(new Callback<PageResponse<CategoryDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<CategoryDTO>> call, Response<PageResponse<CategoryDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<CategoryDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.InventoryApi;
|
||||||
|
import com.example.petstoremobile.dtos.BulkDeleteRequest;
|
||||||
|
import com.example.petstoremobile.dtos.InventoryDTO;
|
||||||
|
import com.example.petstoremobile.dtos.InventoryRequest;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class InventoryRepository {
|
||||||
|
private final InventoryApi inventoryApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InventoryRepository(InventoryApi inventoryApi) {
|
||||||
|
this.inventoryApi = inventoryApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of inventory items from the API with optional search and sort.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<InventoryDTO>>> getAllInventory(String query, int page, int size, String sort) {
|
||||||
|
MutableLiveData<Resource<PageResponse<InventoryDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
inventoryApi.getAllInventory(query, page, size, sort).enqueue(new Callback<PageResponse<InventoryDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<InventoryDTO>> call, Response<PageResponse<InventoryDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<InventoryDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific inventory item by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<InventoryDTO>> getInventoryById(Long id) {
|
||||||
|
MutableLiveData<Resource<InventoryDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
inventoryApi.getInventoryById(id).enqueue(new Callback<InventoryDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<InventoryDTO> call, Response<InventoryDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<InventoryDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new inventory record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<InventoryDTO>> createInventory(InventoryRequest request) {
|
||||||
|
MutableLiveData<Resource<InventoryDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
inventoryApi.createInventory(request).enqueue(new Callback<InventoryDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<InventoryDTO> call, Response<InventoryDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<InventoryDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing inventory record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<InventoryDTO>> updateInventory(Long id, InventoryRequest request) {
|
||||||
|
MutableLiveData<Resource<InventoryDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
inventoryApi.updateInventory(id, request).enqueue(new Callback<InventoryDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<InventoryDTO> call, Response<InventoryDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<InventoryDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific inventory record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteInventory(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
inventoryApi.deleteInventory(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete multiple inventory records at once.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> bulkDeleteInventory(BulkDeleteRequest request) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
inventoryApi.bulkDeleteInventory(request).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.PetApi;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.PetDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class PetRepository {
|
||||||
|
private final PetApi petApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PetRepository(PetApi petApi) {
|
||||||
|
this.petApi = petApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all pets from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<PetDTO>>> getAllPets(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<PetDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
petApi.getAllPets(page, size).enqueue(new Callback<PageResponse<PetDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<PetDTO>> call, Response<PageResponse<PetDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<PetDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific pet by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PetDTO>> getPetById(Long id) {
|
||||||
|
MutableLiveData<Resource<PetDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
petApi.getPetById(id).enqueue(new Callback<PetDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PetDTO> call, Response<PetDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PetDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new pet record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PetDTO>> createPet(PetDTO pet) {
|
||||||
|
MutableLiveData<Resource<PetDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
petApi.createPet(pet).enqueue(new Callback<PetDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PetDTO> call, Response<PetDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PetDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing pet record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PetDTO>> updatePet(Long id, PetDTO pet) {
|
||||||
|
MutableLiveData<Resource<PetDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
petApi.updatePet(id, pet).enqueue(new Callback<PetDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PetDTO> call, Response<PetDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PetDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific pet record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deletePet(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
petApi.deletePet(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads an image file for a specific pet via the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> uploadPetImage(Long id, MultipartBody.Part image) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
petApi.uploadPetImage(id, image).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete the image of a specific pet.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deletePetImage(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
petApi.deletePetImage(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.ProductApi;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.ProductDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class ProductRepository {
|
||||||
|
private final ProductApi productApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ProductRepository(ProductApi productApi) {
|
||||||
|
this.productApi = productApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of products from the API, filtered by an optional query.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<ProductDTO>>> getAllProducts(String query, int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<ProductDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
productApi.getAllProducts(query, page, size).enqueue(new Callback<PageResponse<ProductDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<ProductDTO>> call, Response<PageResponse<ProductDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<ProductDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific product by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductDTO>> getProductById(Long id) {
|
||||||
|
MutableLiveData<Resource<ProductDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
productApi.getProductById(id).enqueue(new Callback<ProductDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ProductDTO> call, Response<ProductDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ProductDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new product.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductDTO>> createProduct(ProductDTO product) {
|
||||||
|
MutableLiveData<Resource<ProductDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
productApi.createProduct(product).enqueue(new Callback<ProductDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ProductDTO> call, Response<ProductDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ProductDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing product by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductDTO>> updateProduct(Long id, ProductDTO product) {
|
||||||
|
MutableLiveData<Resource<ProductDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
productApi.updateProduct(id, product).enqueue(new Callback<ProductDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ProductDTO> call, Response<ProductDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ProductDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific product.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteProduct(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
productApi.deleteProduct(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads an image file for a specific product via the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> uploadProductImage(Long id, MultipartBody.Part image) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
productApi.uploadProductImage(id, image).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete the image of a specific product.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteProductImage(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
productApi.deleteProductImage(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.ProductSupplierApi;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.ProductSupplierDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class ProductSupplierRepository {
|
||||||
|
private final ProductSupplierApi api;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ProductSupplierRepository(ProductSupplierApi api) {
|
||||||
|
this.api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all product-supplier relationships from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<ProductSupplierDTO>>> getAllProductSuppliers(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<ProductSupplierDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
api.getAllProductSuppliers(page, size).enqueue(new Callback<PageResponse<ProductSupplierDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<ProductSupplierDTO>> call, Response<PageResponse<ProductSupplierDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<ProductSupplierDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new product-supplier relationship.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductSupplierDTO>> createProductSupplier(ProductSupplierDTO dto) {
|
||||||
|
MutableLiveData<Resource<ProductSupplierDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
api.createProductSupplier(dto).enqueue(new Callback<ProductSupplierDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ProductSupplierDTO> call, Response<ProductSupplierDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ProductSupplierDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing product-supplier relationship.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductSupplierDTO>> updateProductSupplier(Long productId, Long supplierId, ProductSupplierDTO dto) {
|
||||||
|
MutableLiveData<Resource<ProductSupplierDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
api.updateProductSupplier(productId, supplierId, dto).enqueue(new Callback<ProductSupplierDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ProductSupplierDTO> call, Response<ProductSupplierDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ProductSupplierDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific product-supplier relationship.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteProductSupplier(Long productId, Long supplierId) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
api.deleteProductSupplier(productId, supplierId).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.PurchaseOrderApi;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.PurchaseOrderDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class PurchaseOrderRepository {
|
||||||
|
private final PurchaseOrderApi api;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PurchaseOrderRepository(PurchaseOrderApi api) {
|
||||||
|
this.api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all purchase orders from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<PurchaseOrderDTO>>> getAllPurchaseOrders(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<PurchaseOrderDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
api.getAllPurchaseOrders(page, size).enqueue(new Callback<PageResponse<PurchaseOrderDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<PurchaseOrderDTO>> call, Response<PageResponse<PurchaseOrderDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<PurchaseOrderDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific purchase order by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PurchaseOrderDTO>> getPurchaseOrderById(Long id) {
|
||||||
|
MutableLiveData<Resource<PurchaseOrderDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
api.getPurchaseOrderById(id).enqueue(new Callback<PurchaseOrderDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PurchaseOrderDTO> call, Response<PurchaseOrderDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PurchaseOrderDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.ServiceApi;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.ServiceDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class ServiceRepository {
|
||||||
|
private final ServiceApi serviceApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ServiceRepository(ServiceApi serviceApi) {
|
||||||
|
this.serviceApi = serviceApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all services from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<ServiceDTO>>> getAllServices(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<ServiceDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
serviceApi.getAllServices(page, size).enqueue(new Callback<PageResponse<ServiceDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<ServiceDTO>> call, Response<PageResponse<ServiceDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<ServiceDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific service by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ServiceDTO>> getServiceById(Long id) {
|
||||||
|
MutableLiveData<Resource<ServiceDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
serviceApi.getServiceById(id).enqueue(new Callback<ServiceDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ServiceDTO> call, Response<ServiceDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ServiceDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new service.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ServiceDTO>> createService(ServiceDTO service) {
|
||||||
|
MutableLiveData<Resource<ServiceDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
serviceApi.createService(service).enqueue(new Callback<ServiceDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ServiceDTO> call, Response<ServiceDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ServiceDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing service by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ServiceDTO>> updateService(Long id, ServiceDTO service) {
|
||||||
|
MutableLiveData<Resource<ServiceDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
serviceApi.updateService(id, service).enqueue(new Callback<ServiceDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ServiceDTO> call, Response<ServiceDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ServiceDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific service.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteService(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
serviceApi.deleteService(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package com.example.petstoremobile.repositories;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.api.SupplierApi;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.SupplierDTO;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class SupplierRepository {
|
||||||
|
private final SupplierApi supplierApi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SupplierRepository(SupplierApi supplierApi) {
|
||||||
|
this.supplierApi = supplierApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all suppliers from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<SupplierDTO>>> getAllSuppliers(int page, int size) {
|
||||||
|
MutableLiveData<Resource<PageResponse<SupplierDTO>>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
supplierApi.getAllSuppliers(page, size).enqueue(new Callback<PageResponse<SupplierDTO>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PageResponse<SupplierDTO>> call, Response<PageResponse<SupplierDTO>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PageResponse<SupplierDTO>> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific supplier by its ID from the API.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<SupplierDTO>> getSupplierById(Long id) {
|
||||||
|
MutableLiveData<Resource<SupplierDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
supplierApi.getSupplierById(id).enqueue(new Callback<SupplierDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<SupplierDTO> call, Response<SupplierDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<SupplierDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to create a new supplier record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<SupplierDTO>> createSupplier(SupplierDTO supplier) {
|
||||||
|
MutableLiveData<Resource<SupplierDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
supplierApi.createSupplier(supplier).enqueue(new Callback<SupplierDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<SupplierDTO> call, Response<SupplierDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<SupplierDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to update an existing supplier record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<SupplierDTO>> updateSupplier(Long id, SupplierDTO supplier) {
|
||||||
|
MutableLiveData<Resource<SupplierDTO>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
supplierApi.updateSupplier(id, supplier).enqueue(new Callback<SupplierDTO>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<SupplierDTO> call, Response<SupplierDTO> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
data.setValue(Resource.success(response.body()));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<SupplierDTO> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the API to delete a specific supplier record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteSupplier(Long id) {
|
||||||
|
MutableLiveData<Resource<Void>> data = new MutableLiveData<>();
|
||||||
|
data.setValue(Resource.loading(null));
|
||||||
|
|
||||||
|
supplierApi.deleteSupplier(id).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
data.setValue(Resource.success(null));
|
||||||
|
} else {
|
||||||
|
data.setValue(Resource.error("Error: " + response.message(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<Void> call, Throwable t) {
|
||||||
|
data.setValue(Resource.error(t.getMessage(), null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.example.petstoremobile.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class FileUtils {
|
||||||
|
public static File getFileFromUri(Context context, Uri uri) {
|
||||||
|
try {
|
||||||
|
InputStream inputStream = context.getContentResolver().openInputStream(uri);
|
||||||
|
File tempFile = new File(context.getCacheDir(), "upload_image_" + System.currentTimeMillis() + ".jpg");
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(tempFile);
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = inputStream.read(buffer)) > 0) {
|
||||||
|
outputStream.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
outputStream.close();
|
||||||
|
inputStream.close();
|
||||||
|
return tempFile;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.example.petstoremobile.utils;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
public class Resource<T> {
|
||||||
|
public enum Status { SUCCESS, ERROR, LOADING }
|
||||||
|
|
||||||
|
public final Status status;
|
||||||
|
public final T data;
|
||||||
|
public final String message;
|
||||||
|
|
||||||
|
private Resource(Status status, @Nullable T data, @Nullable String message) {
|
||||||
|
this.status = status;
|
||||||
|
this.data = data;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Resource<T> success(@Nullable T data) {
|
||||||
|
return new Resource<>(Status.SUCCESS, data, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Resource<T> error(String msg, @Nullable T data) {
|
||||||
|
return new Resource<>(Status.ERROR, data, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Resource<T> loading(@Nullable T data) {
|
||||||
|
return new Resource<>(Status.LOADING, data, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.AdoptionDTO;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.repositories.AdoptionRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class AdoptionViewModel extends ViewModel {
|
||||||
|
private final AdoptionRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AdoptionViewModel(AdoptionRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a paginated list of all adoptions.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<AdoptionDTO>>> getAllAdoptions(int page, int size) {
|
||||||
|
return repository.getAllAdoptions(page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single adoption by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AdoptionDTO>> getAdoptionById(Long id) {
|
||||||
|
return repository.getAdoptionById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new adoption record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AdoptionDTO>> createAdoption(AdoptionDTO adoption) {
|
||||||
|
return repository.createAdoption(adoption);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing adoption record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AdoptionDTO>> updateAdoption(Long id, AdoptionDTO adoption) {
|
||||||
|
return repository.updateAdoption(id, adoption);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an adoption record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteAdoption(Long id) {
|
||||||
|
return repository.deleteAdoption(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.AppointmentDTO;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.repositories.AppointmentRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class AppointmentViewModel extends ViewModel {
|
||||||
|
private final AppointmentRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AppointmentViewModel(AppointmentRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a paginated list of all appointments.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<AppointmentDTO>>> getAllAppointments(int page, int size) {
|
||||||
|
return repository.getAllAppointments(page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single appointment by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AppointmentDTO>> getAppointmentById(Long id) {
|
||||||
|
return repository.getAppointmentById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new appointment.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AppointmentDTO>> createAppointment(AppointmentDTO appointment) {
|
||||||
|
return repository.createAppointment(appointment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing appointment record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AppointmentDTO>> updateAppointment(Long id, AppointmentDTO appointment) {
|
||||||
|
return repository.updateAppointment(id, appointment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an appointment record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteAppointment(Long id) {
|
||||||
|
return repository.deleteAppointment(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.AuthDTO;
|
||||||
|
import com.example.petstoremobile.dtos.UserDTO;
|
||||||
|
import com.example.petstoremobile.repositories.AuthRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class AuthViewModel extends ViewModel {
|
||||||
|
private final AuthRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AuthViewModel(AuthRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates a user with username and password.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<AuthDTO.LoginResponse>> login(String username, String password) {
|
||||||
|
return repository.login(new AuthDTO.LoginRequest(username, password));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the profile information of the currently authenticated user.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<UserDTO>> getMe() {
|
||||||
|
return repository.getMe();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the profile information of the current user.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<UserDTO>> updateMe(Map<String, String> updates) {
|
||||||
|
return repository.updateMe(updates);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads a new avatar image for the current user.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<UserDTO>> uploadAvatar(MultipartBody.Part avatar) {
|
||||||
|
return repository.uploadAvatar(avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the avatar image of the current user.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteAvatar() {
|
||||||
|
return repository.deleteAvatar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs out the current user by clearing stored credentials.
|
||||||
|
*/
|
||||||
|
public void logout() {
|
||||||
|
repository.logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.BulkDeleteRequest;
|
||||||
|
import com.example.petstoremobile.dtos.CategoryDTO;
|
||||||
|
import com.example.petstoremobile.dtos.InventoryDTO;
|
||||||
|
import com.example.petstoremobile.dtos.InventoryRequest;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.repositories.CategoryRepository;
|
||||||
|
import com.example.petstoremobile.repositories.InventoryRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class InventoryViewModel extends ViewModel {
|
||||||
|
private final InventoryRepository inventoryRepository;
|
||||||
|
private final CategoryRepository categoryRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InventoryViewModel(InventoryRepository inventoryRepository, CategoryRepository categoryRepository) {
|
||||||
|
this.inventoryRepository = inventoryRepository;
|
||||||
|
this.categoryRepository = categoryRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of inventory items, with optional filtering and sorting.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<InventoryDTO>>> getAllInventory(String query, int page, int size, String sort) {
|
||||||
|
return inventoryRepository.getAllInventory(query, page, size, sort);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single inventory item by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<InventoryDTO>> getInventoryById(Long id) {
|
||||||
|
return inventoryRepository.getInventoryById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new inventory record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<InventoryDTO>> createInventory(InventoryRequest request) {
|
||||||
|
return inventoryRepository.createInventory(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing inventory record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<InventoryDTO>> updateInventory(Long id, InventoryRequest request) {
|
||||||
|
return inventoryRepository.updateInventory(id, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an inventory record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteInventory(Long id) {
|
||||||
|
return inventoryRepository.deleteInventory(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes multiple inventory records in a single request.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> bulkDeleteInventory(List<Long> ids) {
|
||||||
|
return inventoryRepository.bulkDeleteInventory(new BulkDeleteRequest(ids));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of categories.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<CategoryDTO>>> getAllCategories(int page, int size) {
|
||||||
|
return categoryRepository.getAllCategories(page, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.PetDTO;
|
||||||
|
import com.example.petstoremobile.repositories.PetRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class PetViewModel extends ViewModel {
|
||||||
|
private final PetRepository repository;
|
||||||
|
private final MutableLiveData<Long> _petId = new MutableLiveData<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PetViewModel(PetRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a paginated list of all pets.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<PetDTO>>> getAllPets(int page, int size) {
|
||||||
|
return repository.getAllPets(page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single pet by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PetDTO>> getPetById(Long id) {
|
||||||
|
return repository.getPetById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new pet record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PetDTO>> createPet(PetDTO pet) {
|
||||||
|
return repository.createPet(pet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing pet record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PetDTO>> updatePet(Long id, PetDTO pet) {
|
||||||
|
return repository.updatePet(id, pet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a pet record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deletePet(Long id) {
|
||||||
|
return repository.deletePet(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads an image for a specific pet.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> uploadPetImage(Long id, MultipartBody.Part image) {
|
||||||
|
return repository.uploadPetImage(id, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the image associated with a specific pet.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deletePetImage(Long id) {
|
||||||
|
return repository.deletePetImage(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.ProductSupplierDTO;
|
||||||
|
import com.example.petstoremobile.repositories.ProductSupplierRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class ProductSupplierViewModel extends ViewModel {
|
||||||
|
private final ProductSupplierRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ProductSupplierViewModel(ProductSupplierRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a paginated list of all product-supplier relationships.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<ProductSupplierDTO>>> getAllProductSuppliers(int page, int size) {
|
||||||
|
return repository.getAllProductSuppliers(page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new product-supplier relationship.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductSupplierDTO>> createProductSupplier(ProductSupplierDTO dto) {
|
||||||
|
return repository.createProductSupplier(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing product-supplier relationship.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductSupplierDTO>> updateProductSupplier(Long productId, Long supplierId, ProductSupplierDTO dto) {
|
||||||
|
return repository.updateProductSupplier(productId, supplierId, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a product-supplier relationship by product and supplier IDs.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteProductSupplier(Long productId, Long supplierId) {
|
||||||
|
return repository.deleteProductSupplier(productId, supplierId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.CategoryDTO;
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.ProductDTO;
|
||||||
|
import com.example.petstoremobile.repositories.CategoryRepository;
|
||||||
|
import com.example.petstoremobile.repositories.ProductRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class ProductViewModel extends ViewModel {
|
||||||
|
private final ProductRepository productRepository;
|
||||||
|
private final CategoryRepository categoryRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ProductViewModel(ProductRepository productRepository, CategoryRepository categoryRepository) {
|
||||||
|
this.productRepository = productRepository;
|
||||||
|
this.categoryRepository = categoryRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of products, optionally filtered by a query string.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<ProductDTO>>> getAllProducts(String query, int page, int size) {
|
||||||
|
return productRepository.getAllProducts(query, page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single product by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductDTO>> getProductById(Long id) {
|
||||||
|
return productRepository.getProductById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new product.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductDTO>> createProduct(ProductDTO product) {
|
||||||
|
return productRepository.createProduct(product);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing product by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ProductDTO>> updateProduct(Long id, ProductDTO product) {
|
||||||
|
return productRepository.updateProduct(id, product);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a product by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteProduct(Long id) {
|
||||||
|
return productRepository.deleteProduct(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads an image for a specific product.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> uploadProductImage(Long id, MultipartBody.Part image) {
|
||||||
|
return productRepository.uploadProductImage(id, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the image associated with a specific product.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteProductImage(Long id) {
|
||||||
|
return productRepository.deleteProductImage(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of all product categories.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<CategoryDTO>>> getAllCategories(int page, int size) {
|
||||||
|
return categoryRepository.getAllCategories(page, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.PurchaseOrderDTO;
|
||||||
|
import com.example.petstoremobile.repositories.PurchaseOrderRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class PurchaseOrderViewModel extends ViewModel {
|
||||||
|
private final PurchaseOrderRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PurchaseOrderViewModel(PurchaseOrderRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a paginated list of all purchase orders.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<PurchaseOrderDTO>>> getAllPurchaseOrders(int page, int size) {
|
||||||
|
return repository.getAllPurchaseOrders(page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single purchase order by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PurchaseOrderDTO>> getPurchaseOrderById(Long id) {
|
||||||
|
return repository.getPurchaseOrderById(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.ServiceDTO;
|
||||||
|
import com.example.petstoremobile.repositories.ServiceRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class ServiceViewModel extends ViewModel {
|
||||||
|
private final ServiceRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ServiceViewModel(ServiceRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a paginated list of all services.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<ServiceDTO>>> getAllServices(int page, int size) {
|
||||||
|
return repository.getAllServices(page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single service by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ServiceDTO>> getServiceById(Long id) {
|
||||||
|
return repository.getServiceById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new service.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ServiceDTO>> createService(ServiceDTO service) {
|
||||||
|
return repository.createService(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing service by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<ServiceDTO>> updateService(Long id, ServiceDTO service) {
|
||||||
|
return repository.updateService(id, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a service by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteService(Long id) {
|
||||||
|
return repository.deleteService(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.example.petstoremobile.viewmodels;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.petstoremobile.dtos.PageResponse;
|
||||||
|
import com.example.petstoremobile.dtos.SupplierDTO;
|
||||||
|
import com.example.petstoremobile.repositories.SupplierRepository;
|
||||||
|
import com.example.petstoremobile.utils.Resource;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class SupplierViewModel extends ViewModel {
|
||||||
|
private final SupplierRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SupplierViewModel(SupplierRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a paginated list of all suppliers.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<PageResponse<SupplierDTO>>> getAllSuppliers(int page, int size) {
|
||||||
|
return repository.getAllSuppliers(page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single supplier by its ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<SupplierDTO>> getSupplierById(Long id) {
|
||||||
|
return repository.getSupplierById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new supplier record.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<SupplierDTO>> createSupplier(SupplierDTO supplier) {
|
||||||
|
return repository.createSupplier(supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing supplier record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<SupplierDTO>> updateSupplier(Long id, SupplierDTO supplier) {
|
||||||
|
return repository.updateSupplier(id, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a supplier record by ID.
|
||||||
|
*/
|
||||||
|
public LiveData<Resource<Void>> deleteSupplier(Long id) {
|
||||||
|
return repository.deleteSupplier(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user