sales files

basic sale view and builtfiles
This commit is contained in:
Nikitha
2026-03-29 16:54:41 -06:00
parent c4775bcbfa
commit 324e5d4e17
19 changed files with 920 additions and 2 deletions

10
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/group-2-threaded-project-petshop.iml" filepath="$PROJECT_DIR$/.idea/group-2-threaded-project-petshop.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">

6
android/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@@ -0,0 +1,78 @@
package com.example.petstoremobile.adapters;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.petstoremobile.R;
import com.example.petstoremobile.models.Sale;
import java.util.List;
public class SaleAdapter extends RecyclerView.Adapter<SaleAdapter.SaleViewHolder> {
private List<Sale> saleList;
private OnSaleClickListener saleClickListener;
public interface OnSaleClickListener {
void onSaleClick(int position);
}
public SaleAdapter(List<Sale> saleList, OnSaleClickListener saleClickListener) {
this.saleList = saleList;
this.saleClickListener = saleClickListener;
}
public static class SaleViewHolder extends RecyclerView.ViewHolder {
TextView tvSaleId, tvItemName, tvEmployeeName, tvSaleDate, tvTotal, tvPaymentMethod, tvRefundBadge;
public SaleViewHolder(@NonNull View v) {
super(v);
tvSaleId = v.findViewById(R.id.tvSaleId);
tvItemName = v.findViewById(R.id.tvSaleItemName);
tvEmployeeName = v.findViewById(R.id.tvSaleEmployee);
tvSaleDate = v.findViewById(R.id.tvSaleDate);
tvTotal = v.findViewById(R.id.tvSaleTotal);
tvPaymentMethod = v.findViewById(R.id.tvSalePayment);
tvRefundBadge = v.findViewById(R.id.tvRefundBadge);
}
}
@NonNull
@Override
public SaleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_sale, parent, false);
return new SaleViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull SaleViewHolder holder, int position) {
Sale sale = saleList.get(position);
holder.tvSaleId.setText("ID: " + sale.getSaleId());
holder.tvItemName.setText(sale.getItemName());
holder.tvEmployeeName.setText("By: " + sale.getEmployeeName());
holder.tvSaleDate.setText(sale.getSaleDate());
holder.tvTotal.setText("$" + String.format("%.2f", sale.getTotal()));
holder.tvPaymentMethod.setText(sale.getPaymentMethod());
// Show refund badge if it's a refund
if (sale.isRefund()) {
holder.tvRefundBadge.setVisibility(View.VISIBLE);
holder.tvRefundBadge.setBackgroundColor(Color.parseColor("#F44336"));
holder.tvTotal.setTextColor(Color.parseColor("#F44336"));
} else {
holder.tvRefundBadge.setVisibility(View.GONE);
holder.tvTotal.setTextColor(Color.parseColor("#4CAF50"));
}
holder.itemView.setOnClickListener(v -> saleClickListener.onSaleClick(position));
}
@Override
public int getItemCount() {
return saleList.size();
}
}

View File

@@ -0,0 +1,33 @@
package com.example.petstoremobile.api;
import com.example.petstoremobile.dtos.PageResponse;
import com.example.petstoremobile.dtos.SaleDTO;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface SaleApi {
@GET("api/v1/sales")
Call<PageResponse<SaleDTO>> getAllSales(
@Query("page") int page,
@Query("size") int size);
@GET("api/v1/sales/{id}")
Call<SaleDTO> getSaleById(@Path("id") Long id);
@POST("api/v1/sales")
Call<SaleDTO> createSale(@Body SaleDTO sale);
@PUT("api/v1/sales/{id}")
Call<SaleDTO> updateSale(@Path("id") Long id, @Body SaleDTO sale);
@DELETE("api/v1/sales/{id}")
Call<Void> deleteSale(@Path("id") Long id);
}

View File

@@ -0,0 +1,82 @@
package com.example.petstoremobile.dtos;
public class SaleDTO {
private Long saleId;
private Long productId;
private String productName;
private Integer quantity;
private Double price;
private Double totalAmount;
private String saleDate;
private String customerName;
public SaleDTO() {}
public Long getSaleId() {
return saleId;
}
public void setSaleId(Long saleId) {
this.saleId = saleId;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Double getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Double totalAmount) {
this.totalAmount = totalAmount;
}
public String getSaleDate() {
return saleDate;
}
public void setSaleDate(String saleDate) {
this.saleDate = saleDate;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}

View File

@@ -0,0 +1,130 @@
package com.example.petstoremobile.fragments.listfragments;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.SaleAdapter;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.detailfragments.RefundDetailFragment;
import com.example.petstoremobile.models.Sale;
import java.util.ArrayList;
import java.util.List;
public class SaleFragment extends Fragment implements SaleAdapter.OnSaleClickListener {
private List<Sale> saleList = new ArrayList<>();
private List<Sale> filteredList = new ArrayList<>();
private SaleAdapter adapter;
private SwipeRefreshLayout swipeRefreshLayout;
private EditText etSearch;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sale, container, false);
setupRecyclerView(view);
loadSaleData();
setupSearch(view);
setupSwipeRefresh(view);
return view;
}
private void setupSearch(View view) {
etSearch = view.findViewById(R.id.etSearchSale);
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
filterSales(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void filterSales(String query) {
filteredList.clear();
if (query.isEmpty()) {
filteredList.addAll(saleList);
} else {
String lower = query.toLowerCase();
for (Sale s : saleList) {
if (s.getItemName().toLowerCase().contains(lower)
|| s.getEmployeeName().toLowerCase().contains(lower)
|| s.getSaleDate().toLowerCase().contains(lower)
|| s.getPaymentMethod().toLowerCase().contains(lower)
|| String.valueOf(s.getSaleId()).contains(lower)) {
filteredList.add(s);
}
}
}
adapter.notifyDataSetChanged();
}
private void setupSwipeRefresh(View view) {
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshSale);
swipeRefreshLayout.setOnRefreshListener(() -> {
loadSaleData();
swipeRefreshLayout.setRefreshing(false);
});
}
// When a sale row is clicked, open the refund screen for that sale
@Override
public void onSaleClick(int position) {
Sale sale = filteredList.get(position);
RefundDetailFragment refundFragment = new RefundDetailFragment();
Bundle args = new Bundle();
args.putInt("saleId", sale.getSaleId());
args.putString("saleDate", sale.getSaleDate());
args.putString("employeeName", sale.getEmployeeName());
args.putDouble("total", sale.getTotal());
args.putString("paymentMethod", sale.getPaymentMethod());
refundFragment.setArguments(args);
refundFragment.setSaleFragment(this);
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null)
listFragment.loadFragment(refundFragment);
}
public void reloadSales() {
loadSaleData();
}
// TODO: Replace with actual API call - GET v1/sales
private void loadSaleData() {
saleList.clear();
saleList.add(new Sale(1, "2026-03-01", "John Smith", "Premium Dog Food", 2, 45.99, 91.98, "Card", false));
saleList.add(new Sale(2, "2026-03-02", "Jane Doe", "Cat Toy Bundle", 1, 19.99, 19.99, "Cash", false));
saleList.add(new Sale(3, "2026-03-03", "John Smith", "Pet Shampoo", 3, 12.99, 38.97, "Card", false));
saleList.add(new Sale(4, "2026-03-04", "Jane Doe", "Dog Bed - Large", 1, 89.99, 89.99, "Cash", true));
filteredList.clear();
filteredList.addAll(saleList);
if (adapter != null)
adapter.notifyDataSetChanged();
}
private void setupRecyclerView(View view) {
RecyclerView recyclerView = view.findViewById(R.id.recyclerViewSales);
adapter = new SaleAdapter(filteredList, this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
}

View File

@@ -0,0 +1,55 @@
package com.example.petstoremobile.fragments.listfragments.detailfragments;
import android.graphics.Color;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.example.petstoremobile.R;
import com.example.petstoremobile.fragments.ListFragment;
public class PurchaseOrderDetailFragment extends Fragment {
private TextView tvId, tvSupplier, tvDate, tvStatus;
private Button btnBack;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_purchase_order_detail, container, false);
tvId = view.findViewById(R.id.tvPODetailId);
tvSupplier = view.findViewById(R.id.tvPODetailSupplier);
tvDate = view.findViewById(R.id.tvPODetailDate);
tvStatus = view.findViewById(R.id.tvPODetailStatus);
btnBack = view.findViewById(R.id.btnPOBack);
Bundle a = getArguments();
if (a != null) {
tvId.setText("PO #" + a.getLong("purchaseOrderId"));
tvSupplier.setText(a.getString("supplierName"));
tvDate.setText(a.getString("orderDate"));
String status = a.getString("status", "");
tvStatus.setText(status);
switch (status) {
case "Completed":
tvStatus.setTextColor(Color.parseColor("#4CAF50")); break;
case "Pending":
tvStatus.setTextColor(Color.parseColor("#FF9800")); break;
case "Cancelled":
tvStatus.setTextColor(Color.parseColor("#F44336")); break;
default:
tvStatus.setTextColor(Color.parseColor("#9E9E9E")); break;
}
}
btnBack.setOnClickListener(v -> {
ListFragment lf = (ListFragment) getParentFragment();
if (lf != null) lf.getChildFragmentManager().popBackStack();
});
return view;
}
}

View File

@@ -0,0 +1,135 @@
package com.example.petstoremobile.fragments.listfragments.detailfragments;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.example.petstoremobile.R;
import com.example.petstoremobile.fragments.ListFragment;
import com.example.petstoremobile.fragments.listfragments.SaleFragment;
import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.InputValidator;
public class RefundDetailFragment extends Fragment {
private EditText etRefundSaleId, etRefundReason;
private TextView tvSaleInfo;
private Spinner spinnerRefundPayment;
private Button btnLoadSale, btnProcessRefund, btnBack;
private int saleId;
private SaleFragment saleFragment;
public void setSaleFragment(SaleFragment fragment) {
this.saleFragment = fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_refund_detail, container, false);
initViews(view);
setupSpinner();
handleArguments();
btnBack.setOnClickListener(v -> goBack());
btnLoadSale.setOnClickListener(v -> loadSaleDetails());
btnProcessRefund.setOnClickListener(v -> processRefund());
return view;
}
private void loadSaleDetails() {
String idText = etRefundSaleId.getText().toString().trim();
if (idText.isEmpty()) {
Toast.makeText(getContext(), "Enter a Sale ID", Toast.LENGTH_SHORT).show();
return;
}
try {
int id = Integer.parseInt(idText);
// TODO: Replace with actual API call - GET v1/sales/{id}
// For now show placeholder info
tvSaleInfo.setText("Sale ID: " + id + " loaded. Enter reason and payment method to process refund.");
tvSaleInfo.setTextColor(getResources().getColor(android.R.color.holo_green_dark));
} catch (NumberFormatException e) {
Toast.makeText(getContext(), "Invalid Sale ID", Toast.LENGTH_SHORT).show();
}
}
private void processRefund() {
if (!InputValidator.isNotEmpty(etRefundSaleId, "Sale ID"))
return;
if (!InputValidator.isNotEmpty(etRefundReason, "Refund Reason"))
return;
String idText = etRefundSaleId.getText().toString().trim();
String reason = etRefundReason.getText().toString().trim();
String payment = spinnerRefundPayment.getSelectedItem().toString();
try {
int id = Integer.parseInt(idText);
// TODO: Replace with actual API call - POST v1/refunds
ActivityLogger.log(requireContext(), "Processed refund for Sale ID: " + id + " - Reason: " + reason);
Toast.makeText(getContext(), "Refund processed for Sale ID: " + id, Toast.LENGTH_SHORT).show();
if (saleFragment != null)
saleFragment.reloadSales();
goBack();
} catch (NumberFormatException e) {
Toast.makeText(getContext(), "Invalid Sale ID", Toast.LENGTH_SHORT).show();
}
}
private void handleArguments() {
if (getArguments() != null && getArguments().containsKey("saleId")) {
saleId = getArguments().getInt("saleId");
etRefundSaleId.setText(String.valueOf(saleId));
String info = "Sale Date: " + getArguments().getString("saleDate")
+ " | Employee: " + getArguments().getString("employeeName")
+ " | Total: $" + String.format("%.2f", getArguments().getDouble("total"))
+ " | Payment: " + getArguments().getString("paymentMethod");
tvSaleInfo.setText(info);
tvSaleInfo.setTextColor(getResources().getColor(android.R.color.holo_green_dark));
// Pre-select payment method
String payment = getArguments().getString("paymentMethod");
ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinnerRefundPayment.getAdapter();
if (adapter != null && payment != null) {
int pos = adapter.getPosition(payment);
if (pos >= 0)
spinnerRefundPayment.setSelection(pos);
}
}
}
private void goBack() {
ListFragment listFragment = (ListFragment) getParentFragment();
if (listFragment != null)
listFragment.getChildFragmentManager().popBackStack();
}
private void initViews(View view) {
etRefundSaleId = view.findViewById(R.id.etRefundSaleId);
etRefundReason = view.findViewById(R.id.etRefundReason);
tvSaleInfo = view.findViewById(R.id.tvSaleInfo);
spinnerRefundPayment = view.findViewById(R.id.spinnerRefundPayment);
btnLoadSale = view.findViewById(R.id.btnLoadSale);
btnProcessRefund = view.findViewById(R.id.btnProcessRefund);
btnBack = view.findViewById(R.id.btnRefundBack);
}
private void setupSpinner() {
ArrayAdapter<String> adapter = new ArrayAdapter<>(requireContext(),
android.R.layout.simple_spinner_item,
new String[] { "Cash", "Card", "Debit" });
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerRefundPayment.setAdapter(adapter);
}
}

View File

@@ -0,0 +1,62 @@
package com.example.petstoremobile.models;
public class Sale {
private int saleId;
private String saleDate;
private String employeeName;
private String itemName;
private int quantity;
private double unitPrice;
private double total;
private String paymentMethod;
private boolean isRefund;
public Sale(int saleId, String saleDate, String employeeName, String itemName,
int quantity, double unitPrice, double total, String paymentMethod, boolean isRefund) {
this.saleId = saleId;
this.saleDate = saleDate;
this.employeeName = employeeName;
this.itemName = itemName;
this.quantity = quantity;
this.unitPrice = unitPrice;
this.total = total;
this.paymentMethod = paymentMethod;
this.isRefund = isRefund;
}
public int getSaleId() {
return saleId;
}
public String getSaleDate() {
return saleDate;
}
public String getEmployeeName() {
return employeeName;
}
public String getItemName() {
return itemName;
}
public int getQuantity() {
return quantity;
}
public double getUnitPrice() {
return unitPrice;
}
public double getTotal() {
return total;
}
public String getPaymentMethod() {
return paymentMethod;
}
public boolean isRefund() {
return isRefund;
}
}

View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/background_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/primary_dark"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Process Refund"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/rounded_card"
android:padding="16dp"
android:layout_marginBottom="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sale ID"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/etRefundSaleId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Enter Sale ID"
android:inputType="number"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/btnLoadSale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Load"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
</LinearLayout>
<TextView
android:id="@+id/tvSaleInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Load a sale to see details"
android:textColor="#888888"
android:textSize="13sp"
android:layout_marginBottom="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refund Reason"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/etRefundReason"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter reason for refund"
android:inputType="textMultiLine"
android:lines="3"
android:layout_marginBottom="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Payment Method"
android:textColor="@color/text_dark"
android:textSize="12sp"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/spinnerRefundPayment"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white"
android:padding="16dp">
<Button
android:id="@+id/btnRefundBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="8dp"
android:text="Back"
android:backgroundTint="@color/primary_medium"
android:textColor="@color/white"/>
<Button
android:id="@+id/btnProcessRefund"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="Process Refund"
android:backgroundTint="@color/accent_coral"
android:textColor="@color/white"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_grey">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/etSearchSale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:hint="Search by item, employee or date..."
android:inputType="text"
android:drawableStart="@android:drawable/ic_menu_search"
android:drawablePadding="8dp"
android:background="@android:color/white"
android:padding="12dp"/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshSale"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewSales"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:background="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:id="@+id/tvSaleItemName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@color/text_dark"
android:textSize="18sp"
android:textStyle="bold"
android:ellipsize="end"
android:maxLines="1"
android:text="Item Name"/>
<TextView
android:id="@+id/tvRefundBadge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:text="REFUND"
android:textColor="@color/white"
android:textSize="11sp"
android:visibility="gone"/>
</LinearLayout>
<TextView
android:id="@+id/tvSaleEmployee"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="#888888"
android:textSize="13sp"
android:text="By: Employee"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="8dp"
android:gravity="center_vertical">
<TextView
android:id="@+id/tvSaleId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#888888"
android:textSize="12sp"
android:text="ID: 0"/>
<TextView
android:id="@+id/tvSaleDate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#888888"
android:textSize="12sp"
android:text="Date"/>
<TextView
android:id="@+id/tvSalePayment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#888888"
android:textSize="12sp"
android:layout_marginEnd="8dp"
android:text="Cash"/>
<TextView
android:id="@+id/tvSaleTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:text="$0.00"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#F0F0F0"
android:layout_marginTop="12dp"/>
</LinearLayout>

View File

@@ -1,6 +1,6 @@
{
"info": {
"name": "PetShop API Complete Collection",
"name": "PetShop Complete Collection",
"_postman_id": "petshop-api-complete-v1",
"description": "Complete API collection with all 95+ verified endpoints",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"