From a76dfe4d9c21cfc1444566d65ff02b9d095cda9d Mon Sep 17 00:00:00 2001 From: Alex <78383757+Lextical@users.noreply.github.com> Date: Wed, 8 Apr 2026 03:19:16 -0600 Subject: [PATCH] updated sales to have new backend data --- .../example/petstoremobile/dtos/SaleDTO.java | 37 ++++- .../detailfragments/RefundFragment.java | 2 +- .../detailfragments/SaleDetailFragment.java | 90 ++++++----- .../main/res/layout/fragment_sale_detail.xml | 142 ++++++++++++++++-- 4 files changed, 214 insertions(+), 57 deletions(-) diff --git a/android/app/src/main/java/com/example/petstoremobile/dtos/SaleDTO.java b/android/app/src/main/java/com/example/petstoremobile/dtos/SaleDTO.java index 2de34a38..2c7189ee 100644 --- a/android/app/src/main/java/com/example/petstoremobile/dtos/SaleDTO.java +++ b/android/app/src/main/java/com/example/petstoremobile/dtos/SaleDTO.java @@ -12,9 +12,16 @@ public class SaleDTO { private Long storeId; private String storeName; private BigDecimal totalAmount; + private BigDecimal subtotalAmount; + private BigDecimal couponDiscountAmount; + private BigDecimal employeeDiscountAmount; private String paymentMethod; + private String channel; private Boolean isRefund; private Long originalSaleId; + private Long cartId; + private Long couponId; + private Integer pointsEarned; private List items; private String createdAt; @@ -60,10 +67,26 @@ public class SaleDTO { return totalAmount; } + public BigDecimal getSubtotalAmount() { + return subtotalAmount; + } + + public BigDecimal getCouponDiscountAmount() { + return couponDiscountAmount; + } + + public BigDecimal getEmployeeDiscountAmount() { + return employeeDiscountAmount; + } + public String getPaymentMethod() { return paymentMethod; } + public String getChannel() { + return channel; + } + public Boolean getIsRefund() { return isRefund; } @@ -72,6 +95,18 @@ public class SaleDTO { return originalSaleId; } + public Long getCartId() { + return cartId; + } + + public Long getCouponId() { + return couponId; + } + + public Integer getPointsEarned() { + return pointsEarned; + } + public List getItems() { return items; } @@ -118,4 +153,4 @@ public class SaleDTO { return unitPrice; } } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/RefundFragment.java b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/RefundFragment.java index a0abee8c..8d05252c 100644 --- a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/RefundFragment.java +++ b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/RefundFragment.java @@ -31,7 +31,7 @@ public class RefundFragment extends Fragment { // Items user has added to refund cart private List refundCart = new ArrayList<>(); - private final String[] PAYMENT_METHODS = {"Cash", "Card", "Debit"}; + private final String[] PAYMENT_METHODS = {"Cash", "Card"}; // Inner class to track refund items static class RefundItem { diff --git a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/SaleDetailFragment.java b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/SaleDetailFragment.java index 3667ca9c..40c7896b 100644 --- a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/SaleDetailFragment.java +++ b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/detailfragments/SaleDetailFragment.java @@ -12,6 +12,9 @@ import com.example.petstoremobile.R; import com.example.petstoremobile.databinding.FragmentSaleDetailBinding; import com.example.petstoremobile.dtos.*; import com.example.petstoremobile.viewmodels.*; +import com.example.petstoremobile.utils.SpinnerUtils; +import com.example.petstoremobile.utils.DialogUtils; +import com.example.petstoremobile.utils.Resource; import dagger.hilt.android.AndroidEntryPoint; import java.math.BigDecimal; import java.util.*; @@ -33,7 +36,7 @@ public class SaleDetailFragment extends Fragment { private List productList = new ArrayList<>(); private List cartItems = new ArrayList<>(); - private final String[] PAYMENT_METHODS = { "Cash", "Credit Card", "Debit Card", "Online" }; + private final String[] PAYMENT_METHODS = { "Cash", "Card"}; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, @@ -45,8 +48,7 @@ public class SaleDetailFragment extends Fragment { customerViewModel = new ViewModelProvider(this).get(CustomerViewModel.class); productViewModel = new ViewModelProvider(this).get(ProductViewModel.class); - binding.spinnerPaymentMethod.setAdapter(new ArrayAdapter<>(requireContext(), - android.R.layout.simple_spinner_item, PAYMENT_METHODS)); + SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerPaymentMethod, PAYMENT_METHODS); handleArguments(); @@ -81,9 +83,8 @@ public class SaleDetailFragment extends Fragment { binding.spinnerSaleStore.setEnabled(false); binding.spinnerSaleCustomer.setEnabled(false); binding.spinnerPaymentMethod.setEnabled(false); - binding.spinnerSaleProduct.setEnabled(false); - binding.etSaleQuantity.setEnabled(false); - binding.btnAddItem.setEnabled(false); + binding.llAddItemRow.setVisibility(View.GONE); + binding.llExtraInfo.setVisibility(View.VISIBLE); } // Load sale details @@ -92,6 +93,7 @@ public class SaleDetailFragment extends Fragment { binding.tvSaleMode.setText("New Sale"); binding.tvSaleDetailId.setVisibility(View.GONE); binding.btnRefundSale.setVisibility(View.GONE); + binding.llExtraInfo.setVisibility(View.GONE); } } @@ -102,27 +104,18 @@ public class SaleDetailFragment extends Fragment { } private void loadStores() { - storeViewModel.getAllStores(0, 50).observe(getViewLifecycleOwner(), resource -> { - if (resource != null && resource.status == com.example.petstoremobile.utils.Resource.Status.SUCCESS && resource.data != null) { + if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { storeList = resource.data.getContent(); - List names = new ArrayList<>(); - names.add("-- Select Store --"); - for (StoreDTO s : storeList) names.add(s.getStoreName()); if (binding != null) { - binding.spinnerSaleStore.setAdapter(new ArrayAdapter<>(requireContext(), - android.R.layout.simple_spinner_item, names)); + SpinnerUtils.populateSpinner(requireContext(), binding.spinnerSaleStore, storeList, + StoreDTO::getStoreName, "-- Select Store --", -1L, StoreDTO::getStoreId); } } else if (storeList.isEmpty()) { - // Fallback if failed or empty - storeList = new ArrayList<>(); - storeList.add(new StoreDTO(1L, "Downtown Branch")); - List names = new ArrayList<>(); - names.add("-- Select Store --"); - names.add("Downtown Branch"); + storeList = Collections.singletonList(new StoreDTO(1L, "Downtown Branch")); if (binding != null) { - binding.spinnerSaleStore.setAdapter(new ArrayAdapter<>(requireContext(), - android.R.layout.simple_spinner_item, names)); + SpinnerUtils.populateSpinner(requireContext(), binding.spinnerSaleStore, storeList, + StoreDTO::getStoreName, "-- Select Store --", -1L, StoreDTO::getStoreId); } } }); @@ -130,15 +123,11 @@ public class SaleDetailFragment extends Fragment { private void loadCustomers() { customerViewModel.getAllCustomers(0, 200).observe(getViewLifecycleOwner(), resource -> { - if (resource != null && resource.status == com.example.petstoremobile.utils.Resource.Status.SUCCESS && resource.data != null) { + if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { customerList = resource.data.getContent(); - List names = new ArrayList<>(); - names.add("-- No Customer --"); - for (CustomerDTO cu : customerList) - names.add(cu.getFirstName() + " " + cu.getLastName()); if (binding != null) { - binding.spinnerSaleCustomer.setAdapter(new ArrayAdapter<>(requireContext(), - android.R.layout.simple_spinner_item, names)); + SpinnerUtils.populateSpinner(requireContext(), binding.spinnerSaleCustomer, customerList, + CustomerDTO::getFullName, "-- No Customer --", -1L, CustomerDTO::getCustomerId); } } }); @@ -146,15 +135,11 @@ public class SaleDetailFragment extends Fragment { private void loadProducts() { productViewModel.getAllProducts(null, null, 0, 200, null).observe(getViewLifecycleOwner(), resource -> { - if (resource != null && resource.status == com.example.petstoremobile.utils.Resource.Status.SUCCESS && resource.data != null) { + if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { productList = resource.data.getContent(); - List names = new ArrayList<>(); - names.add("-- Select Product --"); - for (ProductDTO p : productList) - names.add(p.getProdName()); if (binding != null) { - binding.spinnerSaleProduct.setAdapter(new ArrayAdapter<>(requireContext(), - android.R.layout.simple_spinner_item, names)); + SpinnerUtils.populateSpinner(requireContext(), binding.spinnerSaleProduct, productList, + ProductDTO::getProdName, "Select Product", -1L, ProductDTO::getProdId); } } }); @@ -162,10 +147,31 @@ public class SaleDetailFragment extends Fragment { private void loadSaleDetails() { saleViewModel.getSaleById(saleId).observe(getViewLifecycleOwner(), resource -> { - if (resource != null && resource.status == com.example.petstoremobile.utils.Resource.Status.SUCCESS && resource.data != null) { + if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) { SaleDTO sale = resource.data; if (binding != null) { binding.tvSaleDetailTotal.setText("Total: $" + sale.getTotalAmount()); + binding.tvSaleSubtotal.setText("$" + (sale.getSubtotalAmount() != null ? sale.getSubtotalAmount() : sale.getTotalAmount())); + + if (sale.getCouponDiscountAmount() != null && sale.getCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0) { + binding.llCouponDiscount.setVisibility(View.VISIBLE); + binding.tvSaleCouponDiscount.setText("-$" + sale.getCouponDiscountAmount()); + } else { + binding.llCouponDiscount.setVisibility(View.GONE); + } + + if (sale.getEmployeeDiscountAmount() != null && sale.getEmployeeDiscountAmount().compareTo(BigDecimal.ZERO) > 0) { + binding.llEmployeeDiscount.setVisibility(View.VISIBLE); + binding.tvSaleEmployeeDiscount.setText("-$" + sale.getEmployeeDiscountAmount()); + } else { + binding.llEmployeeDiscount.setVisibility(View.GONE); + } + + binding.tvSaleChannel.setText(sale.getChannel() != null ? sale.getChannel() : "—"); + binding.tvSalePoints.setText(String.valueOf(sale.getPointsEarned() != null ? sale.getPointsEarned() : 0)); + + SpinnerUtils.setSelectionByValue(binding.spinnerPaymentMethod, sale.getPaymentMethod()); + // Display items if (sale.getItems() != null) { binding.llSaleItems.removeAllViews(); @@ -255,6 +261,7 @@ public class SaleDetailFragment extends Fragment { } } } + binding.tvSaleSubtotal.setText("$" + total); binding.tvSaleDetailTotal.setText("Total: $" + total); } @@ -295,7 +302,7 @@ public class SaleDetailFragment extends Fragment { break; case ERROR: Log.e("SALE_SAVE", "Error: " + resource.message); - Toast.makeText(getContext(), "Error: " + resource.message, Toast.LENGTH_LONG).show(); + DialogUtils.showInfoDialog(requireContext(), "Save Error", resource.message); break; } } @@ -303,9 +310,12 @@ public class SaleDetailFragment extends Fragment { } private void showRefundDialog() { - Bundle args = new Bundle(); - args.putLong("saleId", saleId); - NavHostFragment.findNavController(this).navigate(R.id.nav_refund, args); + DialogUtils.showConfirmDialog(requireContext(), "Process Refund", + "Are you sure you want to process a refund for this sale?", () -> { + Bundle args = new Bundle(); + args.putLong("saleId", saleId); + NavHostFragment.findNavController(this).navigate(R.id.nav_refund, args); + }); } private void navigateBack() { diff --git a/android/app/src/main/res/layout/fragment_sale_detail.xml b/android/app/src/main/res/layout/fragment_sale_detail.xml index 6d8ac401..6b8ddea1 100644 --- a/android/app/src/main/res/layout/fragment_sale_detail.xml +++ b/android/app/src/main/res/layout/fragment_sale_detail.xml @@ -46,7 +46,6 @@ android:orientation="vertical" android:padding="24dp"> - - - + + + + + + + + + + + + + @@ -130,8 +175,8 @@ android:textStyle="bold" android:layout_marginBottom="12dp"/> - - - - + + + android:orientation="vertical"> + + + + + + + + + + + + + + + + + +