<file_sep># FirebaseExpenseApp  

## Part A: ExpenseApp screen
The main activity should start by displaying the ExpenseApp screen, with the following requirements:
1. When the app first starts, there should be no expenses added in the list. So it should
display the ExpenseApp screen with a message, “There is no expense to show,
Please add your expenses from the menu.”.  
2. The list of expenses should be stored in Firebase realtime database.  
3. The ExpenseApp screen should use a ListView/RecyclerView to display the list of
expenses.  
a) Long press on an item should delete the expense from the list. It should update
Firebase, and refresh the ListView to indicate this change. A Toast should be
displayed having the message, “Expense Deleted”.  
b) Clicking on an expense item should display the ShowExpense screen, you
should push the ExpenseApp screen on the screen stack.  
4. Clicking on the add (+) icon should start the AddExpense screen.  

## Part B: AddExpense screen  
This screen should enable user to add a new expense. You should complete the
following tasks:
1. The user should be able to enter the expense name, category and amount. The app
should take the current date as the expense date. This information should be stored
in an Expense Object.
2. The categories should be in a selection pane . The categories should include are: Groceries, Invoice, Transportation, Shopping, Rent, Trips,
Utilities and Other.  
3. Clicking on “Add Expense” button should validate the user’s input and ensure that
all the fields are provided. If any field is missing, display a Toast to indicate the
missing field. If all the fields are provided correctly, save the fields as an Expense
object, and add the new expense to Firebase. Then display the main activity with the
added expense.

## Part C: ShowExpenses screen  
Implement the following requirements:
1. When the user clicks on an expense item in the ExpenseApp screen, the
ShowExpenses screen should be started to show the details of selected expense
item.
2. If the user clicks Edit Expense button, it should start EditExpense screen with
preloaded values.
3. Upon clicking Close button, the screen should be closed and should navigate back
to the ExpenseApp screen.

## Part D: EditExpense screen  
Implement the following requirements:
1. It is identical to the Add Expense screen with preloaded values for the particular
expense.
2. If the user makes changes to the values, and clicks on Save button, it should update
the corresponding values to Firebase, and get back to the main screen with updated
values.
<file_sep>package com.example.inclass11;

import java.util.Date;
import java.util.HashMap;

public class Expense {
    String title;
    String cost;
    String category;
    String date;
    HashMap<String,Object> hmap;
    String documentId;

    public String getDocumentId() {
        return documentId;
    }

    public void setDocumentId(String documentId) {
        this.documentId = documentId;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public Expense() {
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCost() {
        return cost;
    }

    public void setCost(String cost) {
        this.cost = cost;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    @Override
    public String toString() {
        return "Expense{" +
                "title='" + title + '\'' +
                ", cost=" + cost +
                ", category='" + category + '\'' +
                ", date=" + date +
                '}';
    }

    public Expense(String title, String cost, String category, String date) {
        this.title = title;
        this.cost = cost;
        this.category = category;
        this.date = date;
    }

    HashMap<String,Object> toHashMap(){
        hmap=new HashMap<>();
        hmap.put("title",title);
        hmap.put("cost",cost);
        hmap.put("category",category);
        hmap.put("date",date);
        return hmap;
    }
}
<file_sep>package com.example.inclass11;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.net.ParseException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;

import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.firestore.FirebaseFirestore;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class EditExpense extends AppCompatActivity {
    EditText et_expense,et_amount;
    Spinner spinner;
    Button btn_add,btn_cancel;
    String category;
    private FirebaseFirestore db;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_expense);
        setTitle("Edit Expense");
        et_expense=findViewById(R.id.et_eenmae);
        et_amount=findViewById(R.id.et_eamount);
        spinner=findViewById(R.id.editspinner);
        btn_add=findViewById(R.id.btn_save);
        btn_cancel=findViewById(R.id.btn_ecancel);
        db = FirebaseFirestore.getInstance();
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(EditExpense.this,
                R.array.categories_array, android.R.layout.simple_spinner_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                category=parent.getItemAtPosition(position).toString();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        if (getIntent()!=null){
            Bundle extras=getIntent().getExtras();
            et_expense.setText(extras.getString("name"));
            et_amount.setText(String.valueOf(extras.getString("amount")));
            int position=adapter.getPosition(extras.getString("category"));
            spinner.setSelection(position);
        }
        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (et_expense.getText().toString().equals(""))
                    et_expense.setError("It can't be empty");
                else if (et_amount.getText().toString().equals(""))
                    et_amount.setError("It can't be empty");
                else {
                    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
                    Date dateobj = new Date();
                    db.collection("expenses")
                            .document(getIntent().getExtras().getString("DocumentID"))
                            .update("cost", et_amount.getText().toString(), "title", et_expense.getText().toString(), "category", category, "date", df.format(dateobj))
                            .addOnSuccessListener(new OnSuccessListener<Void>() {
                                @Override
                                public void onSuccess(Void aVoid) {
                                    Log.d("Success", "Update Success");
                                }
                            });
                    Intent i1 = new Intent(EditExpense.this, MainActivity.class);
                    startActivity(i1);
                }
            }
        });
        btn_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i2 = new Intent(EditExpense.this, MainActivity.class);
                startActivity(i2);
            }
        });


    }

}
<file_sep>/*
    Assignment: Inclass11
    Team members:
    <NAME>:801165622
    <NAME>:801164383
 */
package com.example.inclass11;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QuerySnapshot;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity implements ExpenseAdapter.InteractMainActivity {
    private FirebaseFirestore db;
    ImageView iv_add;
    TextView tv_current;
    RecyclerView recyclerView;
    ArrayList<Expense> expenses=new ArrayList<>();
    RecyclerView.LayoutManager rv_layoutManager;
    RecyclerView.Adapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("Expense App");
        db = FirebaseFirestore.getInstance();
        iv_add=findViewById(R.id.imageView);
        tv_current=findViewById(R.id.tv_expenses);
        recyclerView=findViewById(R.id.expenselist);
        recyclerView.setVisibility(View.VISIBLE);
        recyclerView.setHasFixedSize(true);
        rv_layoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(rv_layoutManager);
        iv_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i1=new Intent(MainActivity.this,ExpensesActivity.class);
                startActivity(i1);
            }
        });



//        Expense expense=new Expense("Walmart",67.00,"groceries",new Date());
//        HashMap<String,Object> toSave=expense.toHashMap();
//        CollectionReference cities = db.collection("expenses");
//        db.collection("expenses")
//                .add(toSave)
//                .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
//                    @Override
//                    public void onSuccess(DocumentReference documentReference) {
//                        Log.d("demo","OnSuccess:Succesful");
//                    }
//                })
//                .addOnFailureListener(new OnFailureListener() {
//                    @Override
//                    public void onFailure(@NonNull Exception e) {
//                        Log.d("demo","onFailure");
//                    }
//                });
        db.collection("expenses")
                .get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        for(DocumentSnapshot documentSnapshot:queryDocumentSnapshots){

                            Expense expense=documentSnapshot.toObject(Expense.class);
                            expense.setDocumentId(documentSnapshot.getId());
                            Log.d("expense:",expense.getDocumentId());
                            expenses.add(expense);
                        }
                        if(expenses.size()!=0)
                            tv_current.setVisibility(View.INVISIBLE);
                        adapter=new ExpenseAdapter(expenses,MainActivity.this);
                        recyclerView.setAdapter(adapter);
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.d("test","Failure");
                    }
                });


//        db.collection("expense").document("zzdadSXZEu26Tdcu0Faf")
//                .delete()
//                .addOnSuccessListener(new OnSuccessListener<Void>() {
//                    @Override
//                    public void onSuccess(Void aVoid) {
//                        Log.d("delete:","Succesful");
//                    }
//                })
//                .addOnFailureListener(new OnFailureListener() {
//                    @Override
//                    public void onFailure(@NonNull Exception e) {
//                        Log.d("delete:","Unsuccesful");
//                    }
//                });

    }
    @Override
    public void deleteitem(final int position, final String documentID) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Delete an item?")
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                db.collection("expenses").document(documentID)
                                        .delete()
                                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                                            @Override
                                            public void onSuccess(Void aVoid) {
                                                Log.d("test", "Delete succeeded!");
                                            }
                                        }).addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception e) {
                                        Log.e("test", "Delete unsuccessful: "+e.getMessage());
                                    }
                                });
                                expenses.remove(position);
                                if(expenses.size()==0)
                                    tv_current.setVisibility(View.VISIBLE);
                                adapter.notifyDataSetChanged();
                            }
                        }
                ).show();

    }
}
<file_sep>package com.example.inclass11;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class ShowExpenseActivity extends AppCompatActivity {
    TextView tv_name,tv_category,tv_amount,tv_date;
    Button btn_edit,btn_close;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_expense);
        setTitle("Show Expense");
        tv_name=findViewById(R.id.tv_dname);
        tv_amount=findViewById(R.id.tv_damount);
        tv_category=findViewById(R.id.tv_dcategory);
        tv_date=findViewById(R.id.tv_ddate);
        btn_edit=findViewById(R.id.btn_editexpense);
        btn_close=findViewById(R.id.btn_close);
        final Bundle extras=getIntent().getExtras();
        tv_name.setText(extras.getString("name"));
        tv_category.setText(extras.getString("category"));
        String price=extras.getString("amount");
        tv_amount.setText(String.valueOf(price));
        tv_date.setText(extras.getString("date"));
        btn_close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        btn_edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i1=new Intent(ShowExpenseActivity.this,EditExpense.class);
                i1.putExtras(extras);
                startActivity(i1);
            }
        });

    }
}
<file_sep>package com.example.inclass11;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class ExpenseAdapter extends RecyclerView.Adapter<ExpenseAdapter.ViewHolder> {
    ArrayList<Expense> expenseArrayList=new ArrayList<>();
    Context ctx;
    public static InteractMainActivity interact;

    public ExpenseAdapter(ArrayList<Expense> expenseArrayList, Context ctx) {
        this.expenseArrayList = expenseArrayList;
        this.ctx = ctx;
    }

    @NonNull

    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LinearLayout linearLayout=(LinearLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
        ViewHolder viewHolder=new ViewHolder(linearLayout);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
        interact=(InteractMainActivity)ctx;
        holder.tv_name.setText(expenseArrayList.get(position).getTitle());
        holder.tv_price.setText("$"+String.valueOf(expenseArrayList.get(position).getCost()));
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle extras=new Bundle();
                extras.putString("name",expenseArrayList.get(position).getTitle());
                extras.putString("category",expenseArrayList.get(position).getCategory());
                extras.putString("amount",expenseArrayList.get(position).getCost());
                extras.putString("date",expenseArrayList.get(position).getDate().toString());
                extras.putString("DocumentID",expenseArrayList.get(position).getDocumentId().toString());
                Intent i1=new Intent(ctx,ShowExpenseActivity.class);
                i1.putExtras(extras);
                ctx.startActivity(i1);
            }
        });
        holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {

                interact.deleteitem(position,expenseArrayList.get(position).getDocumentId().toString());
                return false;
            }
        });
    }

    @Override
    public int getItemCount() {
        return expenseArrayList.size();
    }
    public interface InteractMainActivity{
        void deleteitem(int position,String document);
    }
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView tv_name,tv_price;
        CardView cardView;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            tv_name=itemView.findViewById(R.id.tv_expensename);
            tv_price=itemView.findViewById(R.id.tv_amountmain);
            cardView=itemView.findViewById(R.id.cardView);
        }
    }
}
