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.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
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.viewmodels.AuthViewModel;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
//The login screen activity
|
||||
@AndroidEntryPoint
|
||||
@@ -37,12 +34,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
private EditText etPassword;
|
||||
private Button btnLogin;
|
||||
private TextView tvLoginStatus;
|
||||
private AuthViewModel viewModel;
|
||||
|
||||
@Inject AuthApi authApi;
|
||||
@Inject TokenManager tokenManager;
|
||||
@Inject @Named("baseUrl") String baseUrl;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
EdgeToEdge.enable(this);
|
||||
@@ -54,8 +50,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
// If a customer somehow remained logged in, clear them out
|
||||
tokenManager.clearLoginData();
|
||||
} else {
|
||||
Intent intent = new Intent(this, HomeActivity.class);
|
||||
startActivity(intent);
|
||||
startActivity(new Intent(this, HomeActivity.class));
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
@@ -99,92 +94,51 @@ public class MainActivity extends AppCompatActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
//Call login from api and get response
|
||||
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
|
||||
if ("CUSTOMER".equalsIgnoreCase(role)) {
|
||||
Toast.makeText(MainActivity.this, "Access denied: Customers are not allowed to log in.", Toast.LENGTH_LONG).show();
|
||||
tvLoginStatus.setText("Customers are not allowed to log in");
|
||||
return;
|
||||
}
|
||||
|
||||
//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());
|
||||
}
|
||||
|
||||
Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show();
|
||||
startActivity(new Intent(MainActivity.this, HomeActivity.class));
|
||||
finish();
|
||||
}
|
||||
|
||||
@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
|
||||
public void onFailure(Call<AuthDTO.LoginResponse> call, Throwable t) {
|
||||
Log.e("MainActivity", "Login request failed", t);
|
||||
|
||||
String errorMessage;
|
||||
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(MainActivity.this, errorMessage, Toast.LENGTH_LONG).show();
|
||||
tvLoginStatus.setText(errorMessage);
|
||||
}
|
||||
});
|
||||
performLogin(username, password);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
btnLogin.setEnabled(true);
|
||||
tvLoginStatus.setText("Customers are not allowed to log in");
|
||||
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();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ERROR:
|
||||
btnLogin.setEnabled(true);
|
||||
tvLoginStatus.setText(resource.message);
|
||||
Toast.makeText(this, resource.message, Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fetchUserIdAndNavigate() {
|
||||
viewModel.getMe().observe(this, resource -> {
|
||||
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||
tokenManager.saveUserId(resource.data.getId());
|
||||
}
|
||||
Toast.makeText(this, "Login successful", Toast.LENGTH_SHORT).show();
|
||||
startActivity(new Intent(this, HomeActivity.class));
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,17 +7,19 @@ import android.util.Log;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.adapters.AdoptionAdapter;
|
||||
import com.example.petstoremobile.api.AdoptionApi;
|
||||
import com.example.petstoremobile.dtos.AdoptionDTO;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
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.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.prolificinteractive.materialcalendarview.CalendarDay;
|
||||
@@ -28,10 +30,7 @@ import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.*;
|
||||
|
||||
@AndroidEntryPoint
|
||||
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> filteredList = new ArrayList<>();
|
||||
private AdoptionAdapter adapter;
|
||||
@Inject AdoptionApi api;
|
||||
private AdoptionViewModel viewModel;
|
||||
private SwipeRefreshLayout swipeRefresh;
|
||||
private EditText etSearch;
|
||||
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());
|
||||
|
||||
@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) {
|
||||
View view = inflater.inflate(R.layout.fragment_adoption, container, false);
|
||||
|
||||
@@ -177,26 +182,34 @@ public class AdoptionFragment extends Fragment implements AdoptionAdapter.OnAdop
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// Helper function to get a list of all adoptions from the backend
|
||||
private void loadAdoptions() {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
||||
api.getAllAdoptions(0, 500).enqueue(new Callback<PageResponse<AdoptionDTO>>() {
|
||||
public void onResponse(Call<PageResponse<AdoptionDTO>> c,
|
||||
Response<PageResponse<AdoptionDTO>> r) {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
if (r.isSuccessful() && r.body() != null) {
|
||||
adoptionList.clear();
|
||||
adoptionList.addAll(r.body().getContent());
|
||||
updateCalendarDecorators();
|
||||
filter(etSearch != null ? etSearch.getText().toString() : "");
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Failed to load adoptions", Toast.LENGTH_SHORT).show();
|
||||
Log.e("AdoptionFragment", "Error: " + r.message());
|
||||
}
|
||||
}
|
||||
public void onFailure(Call<PageResponse<AdoptionDTO>> c, Throwable t) {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
|
||||
Log.e("AdoptionFragment", t.getMessage());
|
||||
//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);
|
||||
break;
|
||||
case SUCCESS:
|
||||
// Hide loading indicator and display data
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
if (resource.data != null) {
|
||||
adoptionList.clear();
|
||||
adoptionList.addAll(resource.data.getContent());
|
||||
updateCalendarDecorators();
|
||||
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 adoptions: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
Log.e("AdoptionFragment", "Error loading adoptions: " + resource.message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -21,14 +23,14 @@ import android.widget.Toast;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
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.ServiceDTO;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.PetDTO;
|
||||
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.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.prolificinteractive.materialcalendarview.CalendarDay;
|
||||
@@ -45,12 +47,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
@AndroidEntryPoint
|
||||
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 AppointmentAdapter adapter;
|
||||
@Inject AppointmentApi api;
|
||||
@Inject PetApi petApi;
|
||||
@Inject ServiceApi serviceApi;
|
||||
private AppointmentViewModel appointmentViewModel;
|
||||
private PetViewModel petViewModel;
|
||||
private ServiceViewModel serviceViewModel;
|
||||
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
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());
|
||||
|
||||
@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) {
|
||||
View view = inflater.inflate(R.layout.fragment_appointment, container, false);
|
||||
|
||||
@@ -91,7 +96,6 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
|
||||
loadPets();
|
||||
loadServices();
|
||||
|
||||
|
||||
FloatingActionButton fabAdd = view.findViewById(R.id.fabAddAppointment);
|
||||
fabAdd.setOnClickListener(v -> openAppointmentDetails(-1));
|
||||
|
||||
@@ -239,76 +243,54 @@ public class AppointmentFragment extends Fragment implements AppointmentAdapter.
|
||||
openAppointmentDetails(position);
|
||||
}
|
||||
|
||||
// Helper function to get a list of all appointments from the backend
|
||||
private void loadAppointmentData() {
|
||||
if (swipeRefreshLayout != null)
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
api.getAllAppointments(0, 500).enqueue(new Callback<PageResponse<AppointmentDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<AppointmentDTO>> call,
|
||||
Response<PageResponse<AppointmentDTO>> response) {
|
||||
if (swipeRefreshLayout != null)
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
appointmentList.clear();
|
||||
appointmentList.addAll(response.body().getContent());
|
||||
updateCalendarDecorators();
|
||||
filterAppointments(etSearch != null ? etSearch.getText().toString() : "");
|
||||
} else {
|
||||
Log.e("AppointmentFragment", "Error: " + response.message());
|
||||
Toast.makeText(getContext(), "Failed to load appointments", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
//Load all appointments from the backend using viewModel
|
||||
appointmentViewModel.getAllAppointments(0, 500).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource == null) return;
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<AppointmentDTO>> call, Throwable t) {
|
||||
if (swipeRefreshLayout != null)
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
Toast.makeText(getContext(), "Network error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
Log.e("AppointmentFragment", t.getMessage());
|
||||
// Check the status to see if the resource is loaded and display the data
|
||||
switch (resource.status) {
|
||||
case LOADING:
|
||||
// Show loading indicator
|
||||
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.addAll(resource.data.getContent());
|
||||
updateCalendarDecorators();
|
||||
filterAppointments(etSearch != null ? etSearch.getText().toString() : "");
|
||||
}
|
||||
break;
|
||||
case ERROR:
|
||||
// Hide loading indicator and toast error message
|
||||
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||
Toast.makeText(getContext(), "Failed to load appointments: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
Log.e("AppointmentFragment", "Error loading appointments: " + resource.message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Load Pets
|
||||
private void loadPets() {
|
||||
petApi.getAllPets(0,100).enqueue(new Callback<PageResponse<PetDTO>>() {
|
||||
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<PetDTO>> call, Response<PageResponse<PetDTO>> response) {
|
||||
if (response.isSuccessful() && response.body() !=null) {
|
||||
petList.clear();
|
||||
petList.addAll(response.body().getContent());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<PetDTO>> call, Throwable t) {
|
||||
|
||||
Log.e("AppointmentFragment", "Pet load error:" + t.getMessage());
|
||||
|
||||
petViewModel.getAllPets(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||
petList.clear();
|
||||
petList.addAll(resource.data.getContent());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Load Services
|
||||
|
||||
private void loadServices() {
|
||||
serviceApi.getAllServices(0,100).enqueue(new Callback<PageResponse<ServiceDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<ServiceDTO>> call, Response<PageResponse<ServiceDTO>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
serviceList.clear();
|
||||
serviceList.addAll(response.body().getContent());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<ServiceDTO>> call, Throwable t) {
|
||||
Log.e("AppointmentFragmnet", "Service load error: " + t.getMessage());
|
||||
|
||||
serviceViewModel.getAllServices(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||
serviceList.clear();
|
||||
serviceList.addAll(resource.data.getContent());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -28,23 +29,16 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
|
||||
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.InventoryDTO;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
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.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
@AndroidEntryPoint
|
||||
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<CategoryDTO> categoryList = new ArrayList<>();
|
||||
private InventoryAdapter adapter;
|
||||
@Inject InventoryApi inventoryApi;
|
||||
@Inject CategoryApi categoryApi;
|
||||
private InventoryViewModel viewModel;
|
||||
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private EditText etSearch;
|
||||
@@ -82,7 +75,13 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
private boolean spinnerReady = false;
|
||||
|
||||
@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) {
|
||||
View view = inflater.inflate(R.layout.fragment_inventory, container, false);
|
||||
|
||||
@@ -117,21 +116,13 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
|
||||
// Categories
|
||||
private void loadCategories() {
|
||||
categoryApi.getAllCategories(0, 100).enqueue(new Callback<PageResponse<CategoryDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<CategoryDTO>> call,
|
||||
Response<PageResponse<CategoryDTO>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
categoryList.clear();
|
||||
categoryList.addAll(response.body().getContent());
|
||||
setupCategorySpinner();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<CategoryDTO>> call, Throwable t) {
|
||||
Log.e(TAG, "Failed to load categories", t);
|
||||
// Still setup spinner with just "All"
|
||||
viewModel.getAllCategories(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||
categoryList.clear();
|
||||
categoryList.addAll(resource.data.getContent());
|
||||
setupCategorySpinner();
|
||||
} else if (resource != null && resource.status == Resource.Status.ERROR) {
|
||||
Log.e(TAG, "Failed to load categories: " + resource.message);
|
||||
setupCategorySpinner();
|
||||
}
|
||||
});
|
||||
@@ -145,33 +136,35 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
categoryNames.add(c.getCategoryName());
|
||||
}
|
||||
|
||||
BlackTextArrayAdapter<String> spinnerAdapter = new BlackTextArrayAdapter<>(
|
||||
requireContext(),
|
||||
android.R.layout.simple_spinner_item,
|
||||
categoryNames);
|
||||
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinnerCategory.setAdapter(spinnerAdapter);
|
||||
if (getContext() != null) {
|
||||
BlackTextArrayAdapter<String> spinnerAdapter = new BlackTextArrayAdapter<>(
|
||||
requireContext(),
|
||||
android.R.layout.simple_spinner_item,
|
||||
categoryNames);
|
||||
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinnerCategory.setAdapter(spinnerAdapter);
|
||||
|
||||
spinnerCategory.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (!spinnerReady) {
|
||||
// Skip the first automatic trigger on setup
|
||||
spinnerReady = true;
|
||||
return;
|
||||
spinnerCategory.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (!spinnerReady) {
|
||||
// Skip the first automatic trigger on setup
|
||||
spinnerReady = true;
|
||||
return;
|
||||
}
|
||||
if (position == 0) {
|
||||
selectedCategory = null; // "All Categories"
|
||||
} else {
|
||||
selectedCategory = categoryList.get(position - 1).getCategoryName();
|
||||
}
|
||||
loadInventory(true);
|
||||
}
|
||||
if (position == 0) {
|
||||
selectedCategory = null; // "All Categories"
|
||||
} else {
|
||||
selectedCategory = categoryList.get(position - 1).getCategoryName();
|
||||
}
|
||||
loadInventory(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Search
|
||||
@@ -209,7 +202,7 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
|
||||
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
if (dy <= 0)
|
||||
return;
|
||||
LinearLayoutManager lm = (LinearLayoutManager) rv.getLayoutManager();
|
||||
@@ -230,11 +223,10 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> loadInventory(true));
|
||||
}
|
||||
|
||||
// Load inventory
|
||||
// Helper function to get a list of all inventory items from the backend
|
||||
private void loadInventory(boolean reset) {
|
||||
if (isLoading)
|
||||
return;
|
||||
isLoading = true;
|
||||
|
||||
if (reset) {
|
||||
currentPage = 0;
|
||||
@@ -244,39 +236,38 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
// Build query: combine search text + selected category
|
||||
String q = buildQuery();
|
||||
|
||||
inventoryApi.getAllInventory(q, currentPage, PAGE_SIZE, "inventoryId,asc")
|
||||
.enqueue(new Callback<PageResponse<InventoryDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<InventoryDTO>> call,
|
||||
Response<PageResponse<InventoryDTO>> response) {
|
||||
isLoading = false;
|
||||
if (swipeRefreshLayout != null)
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
//Load all inventory items from the backend using viewModel
|
||||
viewModel.getAllInventory(q, currentPage, PAGE_SIZE, "inventoryId,asc").observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource == null) return;
|
||||
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
PageResponse<InventoryDTO> page = response.body();
|
||||
if (reset)
|
||||
inventoryList.clear();
|
||||
inventoryList.addAll(page.getContent());
|
||||
adapter.notifyDataSetChanged();
|
||||
isLastPage = page.isLast();
|
||||
if (!isLastPage)
|
||||
currentPage++;
|
||||
} else {
|
||||
Log.e(TAG, "Error " + response.code());
|
||||
Toast.makeText(getContext(), "Failed to load inventory", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
// Check the status to see if the resource is loaded and display the data
|
||||
switch (resource.status) {
|
||||
case LOADING:
|
||||
// Show loading indicator
|
||||
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();
|
||||
isLastPage = resource.data.isLast();
|
||||
if (!isLastPage) currentPage++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<InventoryDTO>> call, Throwable t) {
|
||||
isLoading = false;
|
||||
if (swipeRefreshLayout != null)
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
Log.e(TAG, "Network error", t);
|
||||
Toast.makeText(getContext(), "Network error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
break;
|
||||
case ERROR:
|
||||
// Hide loading indicator and toast error message
|
||||
isLoading = false;
|
||||
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||
Log.e(TAG, "Error: " + resource.message);
|
||||
Toast.makeText(getContext(), "Failed to load inventory: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Combines search text and category into one query string for ?q=
|
||||
@@ -308,25 +299,18 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
}
|
||||
|
||||
private void bulkDelete(List<Long> ids) {
|
||||
inventoryApi.bulkDeleteInventory(new BulkDeleteRequest(ids))
|
||||
.enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||
if (response.isSuccessful()) {
|
||||
adapter.clearSelection();
|
||||
hideBulkDeleteBar();
|
||||
loadInventory(true);
|
||||
Toast.makeText(getContext(), ids.size() + " item(s) deleted", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Delete failed", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<Void> call, Throwable t) {
|
||||
Toast.makeText(getContext(), "Network error", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
viewModel.bulkDeleteInventory(ids).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||
if (resource.status == Resource.Status.SUCCESS) {
|
||||
adapter.clearSelection();
|
||||
hideBulkDeleteBar();
|
||||
loadInventory(true);
|
||||
Toast.makeText(getContext(), ids.size() + " item(s) deleted", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void hideBulkDeleteBar() {
|
||||
@@ -374,4 +358,4 @@ public class InventoryFragment extends Fragment implements InventoryAdapter.OnIn
|
||||
hideBulkDeleteBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -25,10 +26,10 @@ import android.widget.Toast;
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.adapters.BlackTextArrayAdapter;
|
||||
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.fragments.ListFragment;
|
||||
import com.example.petstoremobile.viewmodels.PetViewModel;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -38,9 +39,6 @@ import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
@AndroidEntryPoint
|
||||
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 ImageButton hamburger;
|
||||
private PetAdapter adapter;
|
||||
@Inject PetApi api;
|
||||
private PetViewModel viewModel;
|
||||
|
||||
@Inject @Named("baseUrl") String baseUrl;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private EditText etSearch;
|
||||
private Spinner spinnerStatus;
|
||||
|
||||
//load pet view
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
viewModel = new ViewModelProvider(this).get(PetViewModel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
@@ -67,12 +71,9 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
||||
setupStatusFilter(view);
|
||||
setupSwipeRefresh(view);
|
||||
|
||||
|
||||
//Add button to opens the add dialog
|
||||
FloatingActionButton fabAddPet = view.findViewById(R.id.fabAddPet);
|
||||
fabAddPet.setOnClickListener(v -> openPetDetails(-1));
|
||||
|
||||
//Make the hamburger button open the drawer from listFragment
|
||||
hamburger.setOnClickListener(v -> {
|
||||
Fragment parent = getParentFragment();
|
||||
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) {
|
||||
spinnerStatus = view.findViewById(R.id.spinnerStatus);
|
||||
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() {
|
||||
String query = etSearch.getText().toString().toLowerCase();
|
||||
String selectedStatus = spinnerStatus.getSelectedItem().toString();
|
||||
@@ -146,14 +145,10 @@ public class PetFragment extends Fragment implements PetAdapter.OnPetClickListen
|
||||
|
||||
private void setupSwipeRefresh(View view) {
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshPet);
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
loadPetData();
|
||||
});
|
||||
swipeRefreshLayout.setOnRefreshListener(this::loadPetData);
|
||||
}
|
||||
|
||||
//Open pet profile
|
||||
private void openPetProfile(int position) {
|
||||
//Make a bundle to pass data to the profile fragment
|
||||
Bundle args = new Bundle();
|
||||
PetDTO pet = filteredList.get(position);
|
||||
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);
|
||||
}
|
||||
|
||||
//Open the pet detail view for adding
|
||||
private void openPetDetails(int position) {
|
||||
NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail);
|
||||
}
|
||||
|
||||
// Called by PetAdapter when a row is clicked to open the details view
|
||||
@Override
|
||||
public void onPetClick(int 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
|
||||
private void loadPetData() {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
}
|
||||
api.getAllPets(0, 100).enqueue(new Callback<PageResponse<PetDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<PetDTO>> call, Response<PageResponse<PetDTO>> response) {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
petList.clear();
|
||||
petList.addAll(response.body().getContent());
|
||||
filterPets();
|
||||
|
||||
} else {
|
||||
Log.e("onResponse: ", response.message());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<PetDTO>> call, Throwable t) {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
Toast.makeText(getContext(),
|
||||
"Failed to load pets", Toast.LENGTH_SHORT).show();
|
||||
Log.e("onFailure: ", t.getMessage());
|
||||
//Load all pets from the backend using viewModel
|
||||
viewModel.getAllPets(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 (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(true);
|
||||
break;
|
||||
case SUCCESS:
|
||||
// Hide loading indicator and display data
|
||||
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||
if (resource.data != null) {
|
||||
petList.clear();
|
||||
petList.addAll(resource.data.getContent());
|
||||
filterPets();
|
||||
}
|
||||
break;
|
||||
case ERROR:
|
||||
// Hide loading indicator and toast error message
|
||||
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||
Toast.makeText(getContext(), "Failed to load pets: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
Log.e("PetFragment", "Error loading pets: " + resource.message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//set up the recyclerview and adapter
|
||||
private void setupRecyclerView(View view) {
|
||||
RecyclerView recyclerView = view.findViewById(R.id.recyclerViewPets);
|
||||
adapter = new PetAdapter(filteredList, this);
|
||||
|
||||
@@ -5,18 +5,21 @@ import android.text.*;
|
||||
import android.util.Log;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import com.example.petstoremobile.R;
|
||||
import com.example.petstoremobile.adapters.ProductAdapter;
|
||||
import com.example.petstoremobile.api.ProductApi;
|
||||
import com.example.petstoremobile.api.auth.TokenManager;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.ProductDTO;
|
||||
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 java.util.*;
|
||||
|
||||
@@ -24,7 +27,6 @@ import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.*;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class ProductFragment extends Fragment implements ProductAdapter.OnProductClickListener {
|
||||
@@ -34,13 +36,19 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
|
||||
private ProductAdapter adapter;
|
||||
private SwipeRefreshLayout swipeRefresh;
|
||||
private EditText etSearch;
|
||||
private ProductViewModel viewModel;
|
||||
|
||||
@Inject ProductApi api;
|
||||
@Inject @Named("baseUrl") String baseUrl;
|
||||
@Inject TokenManager tokenManager;
|
||||
|
||||
@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) {
|
||||
View view = inflater.inflate(R.layout.fragment_product, container, false);
|
||||
|
||||
@@ -109,27 +117,35 @@ public class ProductFragment extends Fragment implements ProductAdapter.OnProduc
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// Helper function to get a list of all products from the backend
|
||||
private void loadProducts() {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
||||
api.getAllProducts(null, 0, 100)
|
||||
.enqueue(new Callback<PageResponse<ProductDTO>>() {
|
||||
public void onResponse(Call<PageResponse<ProductDTO>> c,
|
||||
Response<PageResponse<ProductDTO>> r) {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
if (r.isSuccessful() && r.body() != null) {
|
||||
productList.clear();
|
||||
productList.addAll(r.body().getContent());
|
||||
filter();
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Failed to load products",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
//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);
|
||||
break;
|
||||
case SUCCESS:
|
||||
// Hide loading indicator and display data
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
if (resource.data != null) {
|
||||
productList.clear();
|
||||
productList.addAll(resource.data.getContent());
|
||||
filter();
|
||||
}
|
||||
public void onFailure(Call<PageResponse<ProductDTO>> c, Throwable t) {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
Log.e("ProductFragment", t.getMessage());
|
||||
}
|
||||
});
|
||||
break;
|
||||
case ERROR:
|
||||
// Hide loading indicator and toast error message
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
Toast.makeText(getContext(), "Failed to load products: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
Log.e("ProductFragment", "Error loading products: " + resource.message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void openDetail(int position) {
|
||||
|
||||
@@ -5,25 +5,24 @@ import android.text.*;
|
||||
import android.util.Log;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import com.example.petstoremobile.R;
|
||||
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.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 java.util.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.*;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class ProductSupplierFragment extends Fragment
|
||||
@@ -34,11 +33,16 @@ public class ProductSupplierFragment extends Fragment
|
||||
private ProductSupplierAdapter adapter;
|
||||
private SwipeRefreshLayout swipeRefresh;
|
||||
private EditText etSearch;
|
||||
|
||||
@Inject ProductSupplierApi api;
|
||||
private ProductSupplierViewModel viewModel;
|
||||
|
||||
@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) {
|
||||
View view = inflater.inflate(R.layout.fragment_product_supplier, container, false);
|
||||
|
||||
@@ -103,27 +107,35 @@ public class ProductSupplierFragment extends Fragment
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// Helper function to get a list of all product suppliers from the backend
|
||||
private void loadData() {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(true);
|
||||
api.getAllProductSuppliers(0, 100)
|
||||
.enqueue(new Callback<PageResponse<ProductSupplierDTO>>() {
|
||||
public void onResponse(Call<PageResponse<ProductSupplierDTO>> c,
|
||||
Response<PageResponse<ProductSupplierDTO>> r) {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
if (r.isSuccessful() && r.body() != null) {
|
||||
psList.clear();
|
||||
psList.addAll(r.body().getContent());
|
||||
filter(etSearch != null ? etSearch.getText().toString() : "");
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Failed to load",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
//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);
|
||||
break;
|
||||
case SUCCESS:
|
||||
// Hide loading indicator and display data
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
if (resource.data != null) {
|
||||
psList.clear();
|
||||
psList.addAll(resource.data.getContent());
|
||||
filter(etSearch != null ? etSearch.getText().toString() : "");
|
||||
}
|
||||
public void onFailure(Call<PageResponse<ProductSupplierDTO>> c, Throwable t) {
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
Log.e("PSFragment", t.getMessage());
|
||||
}
|
||||
});
|
||||
break;
|
||||
case ERROR:
|
||||
// Hide loading indicator and toast error message
|
||||
if (swipeRefresh != null) swipeRefresh.setRefreshing(false);
|
||||
Toast.makeText(getContext(), "Failed to load: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
Log.e("PSFragment", "Error loading: " + resource.message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void openDetail(int position) {
|
||||
@@ -141,4 +153,4 @@ public class ProductSupplierFragment extends Fragment
|
||||
|
||||
@Override
|
||||
public void onProductSupplierClick(int position) { openDetail(position); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,23 +5,23 @@ import android.text.*;
|
||||
import android.util.Log;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import com.example.petstoremobile.R;
|
||||
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.fragments.ListFragment;
|
||||
import com.example.petstoremobile.viewmodels.PurchaseOrderViewModel;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.*;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class PurchaseOrderFragment extends Fragment
|
||||
@@ -32,8 +32,13 @@ public class PurchaseOrderFragment extends Fragment
|
||||
private PurchaseOrderAdapter adapter;
|
||||
private SwipeRefreshLayout swipeRefresh;
|
||||
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
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -75,7 +80,7 @@ public class PurchaseOrderFragment extends Fragment
|
||||
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());
|
||||
}
|
||||
});
|
||||
@@ -102,31 +107,35 @@ public class PurchaseOrderFragment extends Fragment
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// Helper function to get a list of all purchase orders from the backend
|
||||
private void loadData() {
|
||||
if (swipeRefresh != null)
|
||||
swipeRefresh.setRefreshing(true);
|
||||
api.getAllPurchaseOrders(0, 100)
|
||||
.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();
|
||||
}
|
||||
}
|
||||
//Load all purchase orders from the backend using viewModel
|
||||
viewModel.getAllPurchaseOrders(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource == null) return;
|
||||
|
||||
public void onFailure(Call<PageResponse<PurchaseOrderDTO>> c, Throwable t) {
|
||||
if (swipeRefresh != null)
|
||||
swipeRefresh.setRefreshing(false);
|
||||
Log.e("POFragment", t.getMessage());
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void openDetail(int position) {
|
||||
@@ -143,4 +152,4 @@ public class PurchaseOrderFragment extends Fragment
|
||||
public void onPurchaseOrderClick(int position) {
|
||||
openDetail(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.example.petstoremobile.fragments.listfragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -22,21 +23,16 @@ import android.widget.Toast;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
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.fragments.ListFragment;
|
||||
import com.example.petstoremobile.viewmodels.ServiceViewModel;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
@AndroidEntryPoint
|
||||
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 ServiceAdapter adapter;
|
||||
private ImageButton hamburger;
|
||||
@Inject ServiceApi api;
|
||||
private ServiceViewModel viewModel;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private EditText etSearch;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
viewModel = new ViewModelProvider(this).get(ServiceViewModel.class);
|
||||
}
|
||||
|
||||
//load service view
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_service, container, false);
|
||||
|
||||
@@ -98,8 +100,8 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
||||
} else {
|
||||
String lower = query.toLowerCase();
|
||||
for (ServiceDTO s : serviceList) {
|
||||
if (s.getServiceName().toLowerCase().contains(lower)
|
||||
|| s.getServiceDesc().toLowerCase().contains(lower)) {
|
||||
if ((s.getServiceName() != null && s.getServiceName().toLowerCase().contains(lower))
|
||||
|| (s.getServiceDesc() != null && s.getServiceDesc().toLowerCase().contains(lower))) {
|
||||
filteredList.add(s);
|
||||
}
|
||||
}
|
||||
@@ -109,9 +111,7 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic
|
||||
|
||||
private void setupSwipeRefresh(View view) {
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshService);
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
loadServiceData();
|
||||
});
|
||||
swipeRefreshLayout.setOnRefreshListener(this::loadServiceData);
|
||||
}
|
||||
|
||||
//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
|
||||
private void loadServiceData() {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
}
|
||||
api.getAllServices(0, 100).enqueue(new Callback<PageResponse<ServiceDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<ServiceDTO>> call, Response<PageResponse<ServiceDTO>> response) {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
serviceList.clear();
|
||||
serviceList.addAll(response.body().getContent());
|
||||
filterServices(etSearch.getText().toString());
|
||||
//Load all services from the backend using viewModel
|
||||
viewModel.getAllServices(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource == null) return;
|
||||
|
||||
} else {
|
||||
Log.e("onResponse: ", response.message());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<ServiceDTO>> call, Throwable t) {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
if (getContext() != null) {
|
||||
Toast.makeText(getContext(),
|
||||
"Failed to load services", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
Log.e("onFailure: ", t.getMessage());
|
||||
// Check the status to see if the resource is loaded and display the data
|
||||
switch (resource.status) {
|
||||
case LOADING:
|
||||
// Show loading indicator
|
||||
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) {
|
||||
serviceList.clear();
|
||||
serviceList.addAll(resource.data.getContent());
|
||||
filterServices(etSearch != null ? etSearch.getText().toString() : "");
|
||||
}
|
||||
break;
|
||||
case ERROR:
|
||||
// Hide loading indicator and toast error message
|
||||
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||
if (getContext() != null) {
|
||||
Toast.makeText(getContext(), "Failed to load services: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
Log.e("ServiceFragment", "Error loading services: " + resource.message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -22,21 +23,16 @@ import android.widget.Toast;
|
||||
|
||||
import com.example.petstoremobile.R;
|
||||
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.fragments.ListFragment;
|
||||
import com.example.petstoremobile.viewmodels.SupplierViewModel;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
@AndroidEntryPoint
|
||||
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 SupplierAdapter adapter;
|
||||
private ImageButton hamburger;
|
||||
@Inject SupplierApi api;
|
||||
private SupplierViewModel viewModel;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private EditText etSearch;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
viewModel = new ViewModelProvider(this).get(SupplierViewModel.class);
|
||||
}
|
||||
|
||||
//load supplier view
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_supplier, container, false);
|
||||
|
||||
@@ -98,9 +100,9 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
||||
} else {
|
||||
String lower = query.toLowerCase();
|
||||
for (SupplierDTO s : supplierList) {
|
||||
if (s.getSupCompany().toLowerCase().contains(lower)
|
||||
|| s.getSupContactFirstName().toLowerCase().contains(lower)
|
||||
|| s.getSupContactLastName().toLowerCase().contains(lower)) {
|
||||
if ((s.getSupCompany() != null && s.getSupCompany().toLowerCase().contains(lower))
|
||||
|| (s.getSupContactFirstName() != null && s.getSupContactFirstName().toLowerCase().contains(lower))
|
||||
|| (s.getSupContactLastName() != null && s.getSupContactLastName().toLowerCase().contains(lower))) {
|
||||
filteredList.add(s);
|
||||
}
|
||||
}
|
||||
@@ -110,9 +112,7 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
||||
|
||||
private void setupSwipeRefresh(View view) {
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshSupplier);
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
loadSupplierData();
|
||||
});
|
||||
swipeRefreshLayout.setOnRefreshListener(this::loadSupplierData);
|
||||
}
|
||||
|
||||
//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
|
||||
private void loadSupplierData() {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
}
|
||||
api.getAllSuppliers(0, 100).enqueue(new Callback<PageResponse<SupplierDTO>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PageResponse<SupplierDTO>> call, Response<PageResponse<SupplierDTO>> response) {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
supplierList.clear();
|
||||
supplierList.addAll(response.body().getContent());
|
||||
filterSuppliers(etSearch.getText().toString());
|
||||
//Load all suppliers from the backend using viewModel
|
||||
viewModel.getAllSuppliers(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource == null) return;
|
||||
|
||||
} else {
|
||||
Log.e("onResponse: ", response.message());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<PageResponse<SupplierDTO>> call, Throwable t) {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
if (getContext() != null) {
|
||||
Toast.makeText(getContext(),
|
||||
"Failed to load suppliers", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
Log.e("onFailure: ", t.getMessage());
|
||||
// Check the status to see if the resource is loaded and display the data
|
||||
switch (resource.status) {
|
||||
case LOADING:
|
||||
// Show loading indicator
|
||||
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) {
|
||||
supplierList.clear();
|
||||
supplierList.addAll(resource.data.getContent());
|
||||
filterSuppliers(etSearch.getText().toString());
|
||||
}
|
||||
break;
|
||||
case ERROR:
|
||||
// Hide loading indicator and toast error message
|
||||
if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false);
|
||||
if (getContext() != null) {
|
||||
Toast.makeText(getContext(), "Failed to load suppliers: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
Log.e("SupplierFragment", "Error loading suppliers: " + resource.message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -184,4 +182,4 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@ import android.widget.*;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
|
||||
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.auth.TokenManager;
|
||||
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.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
@@ -41,7 +45,6 @@ import dagger.hilt.android.AndroidEntryPoint;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.RequestBody;
|
||||
import retrofit2.*;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class ProductDetailFragment extends Fragment {
|
||||
@@ -61,9 +64,8 @@ public class ProductDetailFragment extends Fragment {
|
||||
|
||||
private List<CategoryDTO> categoryList = new ArrayList<>();
|
||||
private Uri photoUri;
|
||||
private ProductViewModel viewModel;
|
||||
|
||||
@Inject ProductApi productApi;
|
||||
@Inject CategoryApi categoryApi;
|
||||
@Inject @Named("baseUrl") String baseUrl;
|
||||
@Inject TokenManager tokenManager;
|
||||
|
||||
@@ -74,12 +76,13 @@ public class ProductDetailFragment extends Fragment {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
viewModel = new ViewModelProvider(this).get(ProductViewModel.class);
|
||||
|
||||
galleryLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
result -> {
|
||||
if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
|
||||
Uri selectedImage = result.getData().getData();
|
||||
// Update image view locally
|
||||
Glide.with(this).load(selectedImage).into(ivProductImage);
|
||||
photoUri = selectedImage;
|
||||
hasImage = true;
|
||||
@@ -92,7 +95,6 @@ public class ProductDetailFragment extends Fragment {
|
||||
new ActivityResultContracts.TakePicture(),
|
||||
success -> {
|
||||
if (success) {
|
||||
// Update image view locally
|
||||
Glide.with(this).load(photoUri).into(ivProductImage);
|
||||
hasImage = true;
|
||||
isImageChanged = true;
|
||||
@@ -185,19 +187,12 @@ public class ProductDetailFragment extends Fragment {
|
||||
|
||||
// Helper function to load categories from the backend for the spinner
|
||||
private void loadCategories() {
|
||||
categoryApi.getAllCategories(0, 100)
|
||||
.enqueue(new Callback<PageResponse<CategoryDTO>>() {
|
||||
public void onResponse(Call<PageResponse<CategoryDTO>> c,
|
||||
Response<PageResponse<CategoryDTO>> r) {
|
||||
if (r.isSuccessful() && r.body() != null) {
|
||||
categoryList = r.body().getContent();
|
||||
populateCategorySpinner();
|
||||
}
|
||||
}
|
||||
public void onFailure(Call<PageResponse<CategoryDTO>> c, Throwable t) {
|
||||
Log.e("ProductDetail", "Category load failed: " + t.getMessage());
|
||||
}
|
||||
});
|
||||
viewModel.getAllCategories(0, 100).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||
categoryList = resource.data.getContent();
|
||||
populateCategorySpinner();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Helper function to populate the category spinner
|
||||
@@ -265,24 +260,19 @@ public class ProductDetailFragment extends Fragment {
|
||||
// updating/adding photo, removing photo or no change
|
||||
private void performPendingImageActions(String successMsg) {
|
||||
if (isImageRemoved) {
|
||||
//if the image is removed then delete the image
|
||||
productApi.deleteProductImage(prodId).enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||
navigateBack();
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Call<Void> call, Throwable t) {
|
||||
Toast.makeText(getContext(), successMsg + " (but image removal failed)", Toast.LENGTH_SHORT).show();
|
||||
viewModel.deleteProductImage(prodId).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||
if (resource.status == Resource.Status.SUCCESS) {
|
||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getContext(), successMsg + " (but image removal failed)", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
navigateBack();
|
||||
}
|
||||
});
|
||||
} else if (isImageChanged && photoUri != null) {
|
||||
//if the image is changed then upload it
|
||||
uploadProductImageAndNavigate(photoUri, successMsg);
|
||||
} else {
|
||||
//if no changes then navigate back
|
||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||
navigateBack();
|
||||
}
|
||||
@@ -291,61 +281,28 @@ public class ProductDetailFragment extends Fragment {
|
||||
// Helper function to upload the product image by calling the backend
|
||||
// and then navigate back to the previous screen
|
||||
private void uploadProductImageAndNavigate(Uri uri, String successMsg) {
|
||||
try {
|
||||
File file = getFileFromUri(uri);
|
||||
if (file == null) {
|
||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||
navigateBack();
|
||||
return;
|
||||
}
|
||||
|
||||
RequestBody requestFile = RequestBody.create(file, MediaType.parse(requireContext().getContentResolver().getType(uri)));
|
||||
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
|
||||
|
||||
productApi.uploadProductImage(prodId, body)
|
||||
.enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||
if (response.isSuccessful()) {
|
||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getContext(), successMsg + " (but image upload failed)", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
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);
|
||||
File file = FileUtils.getFileFromUri(requireContext(), uri);
|
||||
if (file == null) {
|
||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||
navigateBack();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
RequestBody requestFile = RequestBody.create(file, MediaType.parse(requireContext().getContentResolver().getType(uri)));
|
||||
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
|
||||
|
||||
viewModel.uploadProductImage(prodId, body).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||
if (resource.status == Resource.Status.SUCCESS) {
|
||||
Toast.makeText(getContext(), successMsg, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getContext(), successMsg + " (but image upload failed)", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
navigateBack();
|
||||
}
|
||||
outputStream.close();
|
||||
inputStream.close();
|
||||
return tempFile;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Function to save the product to the server
|
||||
private void saveProduct() {
|
||||
String name = etProductName.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);
|
||||
|
||||
if (isEditing) {
|
||||
productApi.updateProduct(prodId, dto).enqueue(new Callback<ProductDTO>() {
|
||||
@Override
|
||||
public void onResponse(Call<ProductDTO> call, Response<ProductDTO> response) {
|
||||
if (response.isSuccessful()) {
|
||||
viewModel.updateProduct(prodId, dto).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||
if (resource.status == Resource.Status.SUCCESS) {
|
||||
performPendingImageActions("Updated");
|
||||
} 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 {
|
||||
productApi.createProduct(dto).enqueue(new Callback<ProductDTO>() {
|
||||
@Override
|
||||
public void onResponse(Call<ProductDTO> call, Response<ProductDTO> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
prodId = response.body().getProdId();
|
||||
viewModel.createProduct(dto).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status != Resource.Status.LOADING) {
|
||||
if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||
prodId = resource.data.getProdId();
|
||||
performPendingImageActions("Saved");
|
||||
} 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,20 +357,17 @@ public class ProductDetailFragment extends Fragment {
|
||||
new AlertDialog.Builder(requireContext())
|
||||
.setTitle("Delete Product?")
|
||||
.setPositiveButton("Yes", (d, w) ->
|
||||
productApi.deleteProduct(prodId)
|
||||
.enqueue(new Callback<Void>() {
|
||||
public void onResponse(Call<Void> c, Response<Void> r) {
|
||||
navigateBack();
|
||||
}
|
||||
public void onFailure(Call<Void> c, Throwable t) {
|
||||
Toast.makeText(getContext(), "Delete failed",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}))
|
||||
viewModel.deleteProduct(prodId).observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status == Resource.Status.SUCCESS) {
|
||||
navigateBack();
|
||||
} else if (resource != null && resource.status == Resource.Status.ERROR) {
|
||||
Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}))
|
||||
.setNegativeButton("No", null).show();
|
||||
}
|
||||
|
||||
private void navigateBack() {
|
||||
NavHostFragment.findNavController(this).popBackStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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