diff --git a/.github/workflows/android_ci.yml b/.github/workflows/android_ci.yml new file mode 100644 index 0000000000..55d603d1ef --- /dev/null +++ b/.github/workflows/android_ci.yml @@ -0,0 +1,48 @@ +name: Android CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: macos-latest + strategy: + matrix: + api-level: [21, 23, 29] + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: Gradle cache + uses: gradle/gradle-build-action@v2 + + - name: AVD cache + uses: actions/cache@v3 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ matrix.api-level }} + + - name: create AVD and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: false + script: echo "Generated AVD snapshot for caching." + + - name: run tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: ./gradlew connectedCheck diff --git a/README.md b/README.md index ebf306d1d7..707545945c 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,21 @@ The current implementation is non-persistent. Therefore all the account informat Your task is to make the storage of account information and transactions persistent, using an embedded database such as SQLite as the persistent storage. -In order to achieve this you should implement the two interfaces, [`AccountDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/AccountDAO.java) and [`TransactionDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/TransactionDAO.java). These two interfaces follow the “Data Access Object” Design pattern [1](http://www.oracle.com/technetwork/java/dataaccessobject-138824.html) [2](http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm). You can refer the current In-Memory implementation ([`InMemoryAccountDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryAccountDAO.java), [`InMemoryTransactionDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryTransactionDAO.java)) to get an idea of the current implementation. +In order to achieve this you should implement the two interfaces, [`AccountDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/AccountDAO.java) +and [`TransactionDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/TransactionDAO.java). +These two interfaces follow the “Data Access Object” Design pattern [1](http://www.oracle.com/technetwork/java/dataaccessobject-138824.html) +[2](http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm). +You can refer the current In-Memory implementation ([`InMemoryAccountDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryAccountDAO.java), +[`InMemoryTransactionDAO`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryTransactionDAO.java)) +to get an idea of the current implementation. -After you have implemented the two interfaces, you can use these implementations to setup the application to use the persistent storage instead of the existing in-memory storage. In order to do that you should implement the `setup()` method of the abstract class [`ExpenseManager`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/ExpenseManager.java). You can refer the current concrete implementation ([`InMemoryDemoExpenseManager`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/InMemoryDemoExpenseManager.java)) of this class to get an idea. +After you have implemented the two interfaces, you can use these implementations to setup the application to use the persistent storage instead of the existing in-memory storage. +In order to do that you should implement the `setup()` method of the abstract class [`ExpenseManager`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/ExpenseManager.java). +You can refer the current concrete implementation ([`InMemoryDemoExpenseManager`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/InMemoryDemoExpenseManager.java)) of this class to get an idea. -After you have completed implementation of the [`ExpenseManager`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/ExpenseManager.java) class, go to [`MainActivity`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/ui/MainActivity.java) class in the ui package and change the existing implementation to your implementation. +After you have completed implementation of the [`ExpenseManager`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/ExpenseManager.java) class, +go to [`MainActivity`](/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/ui/MainActivity.java) +class in the ui package and change the existing implementation to your implementation. eg: @@ -32,7 +42,8 @@ expenseManager = new PersistentExpenseManager(context); /*** END ***/ ``` -You can make improvements to the project as you require. However this project is designed to act as a skeleton and minimize involvement in other components such as the UI. Therefore your main effort should be focused on implementing the persistent storage using an embedded database. +You can make improvements to the project as you require. However this project is designed to act as a skeleton and minimize involvement in other components such as the UI. +Therefore your main effort should be focused on implementing the persistent storage using an embedded database. ## Instructions 1. Fork the GitHub project - https://github.com/GayashanNA/SimpleExpenseManager @@ -45,15 +56,15 @@ You can make improvements to the project as you require. However this project is Current implementation ```Java - /*** Begin generating dummy data for In-Memory implementation ***/ + /*** Begin generating dummy data for In-Memory implementation expenseManager = new InMemoryDemoExpenseManager(); - /*** END ***/ + END ***/ ``` Your implementation ```Java - /*** Setup the persistent storage implementation ***/ + /*** Setup the persistent storage implementation expenseManager = new PersistentExpenseManager(context); - /*** END ***/ + END ***/ ``` 6. Commit your code and push to your forked repository in GitHub. 7. Download your project as a Zip from GitHub and submit as the completed assignment. diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/PersistentDemoExpenseManager.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/PersistentDemoExpenseManager.java new file mode 100644 index 0000000000..25f6c5bb31 --- /dev/null +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/control/PersistentDemoExpenseManager.java @@ -0,0 +1,61 @@ +/* + * Copyright 2015 Department of Computer Science and Engineering, University of Moratuwa. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package lk.ac.mrt.cse.dbs.simpleexpensemanager.control; + +import android.content.Context; + +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.AccountDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.TransactionDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.impl.InMemoryAccountDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.impl.InMemoryTransactionDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.impl.PersistentAccountDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.impl.PersistentTransactionDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.model.Account; + +/** + * + */ +public class PersistentDemoExpenseManager extends ExpenseManager { + + public Context context; + public PersistentDemoExpenseManager(Context context) { + this.context = context; + setup(); + } + + @Override + public void setup() { + /*** Begin generating dummy data for In-Memory implementation ***/ + +// TransactionDAO inMemoryDAOTransactionDAO = new InMemoryTransactionDAO(); + TransactionDAO persistentTransactionDAO = new PersistentTransactionDAO(context); + setTransactionsDAO(persistentTransactionDAO); + +// AccountDAO inMemoryAccountDAO = new InMemoryAccountDAO(); + + AccountDAO persistentAccountDAO = new PersistentAccountDAO(context); + setAccountsDAO(persistentAccountDAO); + + // dummy data +// Account dummyAcct1 = new Account("12345A", "Yoda Bank", "Anakin Skywalker", 10000.0); +// Account dummyAcct2 = new Account("78945Z", "Clone BC", "Obi-Wan Kenobi", 80000.0); +// getAccountsDAO().addAccount(dummyAcct1); +// getAccountsDAO().addAccount(dummyAcct2); + + /*** End ***/ + } +} diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/AccountDAO.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/AccountDAO.java index 8eca16283c..6ac8ff47b3 100644 --- a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/AccountDAO.java +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/AccountDAO.java @@ -55,8 +55,9 @@ public interface AccountDAO { * Add an account to the accounts collection. * * @param account - the account to be added. + * @return */ - public void addAccount(Account account); + public boolean addAccount(Account account); /*** * Remove an account from the accounts collection. diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/DataBaseManager.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/DataBaseManager.java new file mode 100644 index 0000000000..f6e74f000f --- /dev/null +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/DataBaseManager.java @@ -0,0 +1,52 @@ +package lk.ac.mrt.cse.dbs.simpleexpensemanager.data; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.support.annotation.Nullable; + +public class DataBaseManager extends SQLiteOpenHelper { + + public static final String ACCOUNT_TABLE = "ACCOUNT_TABLE"; + public static final String ACCOUNT_NUMBER = "ACCOUNT_NUMBER"; + public static final String BANK_NAME = "BANK_NAME"; + public static final String ACCOUNT_HOLDER_NAME = "ACCOUNT_HOLDER_NAME"; + public static final String BALANCE = "BALANCE"; + public static final String TRANSACTION_TABLE = "TRANSACTION_TABLE"; + public static final String ID = "ID"; + public static final String TYPE = "TYPE"; + public static final String DATE = "DATE"; + public static final String AMOUNT = "AMOUNT"; + + public DataBaseManager(@Nullable Context context) { + super(context, "190482K.db", null, 1); + } + + @Override + public void onCreate(SQLiteDatabase SqLiteDb) { + String tableStatementForAddAccount = "CREATE TABLE " + + ACCOUNT_TABLE + " (" + + ACCOUNT_NUMBER + " INTEGER PRIMARY KEY AUTOINCREMENT," + + BANK_NAME + " TEXT," + + ACCOUNT_HOLDER_NAME + " TEXT," + + BALANCE + " REAL" + ")"; + + SqLiteDb.execSQL(tableStatementForAddAccount); + + String tableStatementForTransaction = "CREATE TABLE " + + TRANSACTION_TABLE + " (" + + ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + ACCOUNT_NUMBER + " INTEGER," + + TYPE + " INTEGER," + + DATE + " TEXT," + + AMOUNT + " REAL" + ")"; + + SqLiteDb.execSQL(tableStatementForTransaction); + } + + @Override + public void onUpgrade(SQLiteDatabase sqLiteDatabase, int acc_no, int type) { + + } + +} diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/TransactionDAO.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/TransactionDAO.java index b91fa047e0..8d3166fc4f 100644 --- a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/TransactionDAO.java +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/TransactionDAO.java @@ -29,13 +29,13 @@ public interface TransactionDAO { /*** * Log the transaction requested by the user. - * * @param date - date of the transaction * @param accountNo - account number involved * @param expenseType - type of the expense * @param amount - amount involved + * @return */ - public void logTransaction(Date date, String accountNo, ExpenseType expenseType, double amount); + public boolean logTransaction(Date date, String accountNo, ExpenseType expenseType, double amount); /*** * Return all the transactions logged. diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryAccountDAO.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryAccountDAO.java index 35e853569b..c7d10e5a1b 100644 --- a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryAccountDAO.java +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryAccountDAO.java @@ -30,7 +30,7 @@ * This is an In-Memory implementation of the AccountDAO interface. This is not a persistent storage. A HashMap is * used to store the account details temporarily in the memory. */ -public class InMemoryAccountDAO implements AccountDAO { +public class InMemoryAccountDAO implements AccountDAO { private final Map accounts; public InMemoryAccountDAO() { @@ -57,8 +57,9 @@ public Account getAccount(String accountNo) throws InvalidAccountException { } @Override - public void addAccount(Account account) { + public boolean addAccount(Account account) { accounts.put(account.getAccountNo(), account); + return false; } @Override diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryTransactionDAO.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryTransactionDAO.java index 387917fb1e..bfa4911c92 100644 --- a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryTransactionDAO.java +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/InMemoryTransactionDAO.java @@ -29,6 +29,7 @@ * transaction logs are stored in a LinkedList in memory. */ public class InMemoryTransactionDAO implements TransactionDAO { + private final List transactions; public InMemoryTransactionDAO() { @@ -36,9 +37,10 @@ public InMemoryTransactionDAO() { } @Override - public void logTransaction(Date date, String accountNo, ExpenseType expenseType, double amount) { + public boolean logTransaction(Date date, String accountNo, ExpenseType expenseType, double amount) { Transaction transaction = new Transaction(date, accountNo, expenseType, amount); transactions.add(transaction); + return false; } @Override diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/PersistentAccountDAO.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/PersistentAccountDAO.java new file mode 100644 index 0000000000..2976d1a477 --- /dev/null +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/PersistentAccountDAO.java @@ -0,0 +1,153 @@ +package lk.ac.mrt.cse.dbs.simpleexpensemanager.data.impl; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.support.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.AccountDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.DataBaseManager; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.exception.InvalidAccountException; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.model.Account; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.model.ExpenseType; + +/* + * Copyright 2015 Department of Computer Science and Engineering, University of Moratuwa. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +public class PersistentAccountDAO extends DataBaseManager implements AccountDAO { + +/** + * This is an Persistent implementation of the AccountDAO interface. + */ + + public PersistentAccountDAO(@Nullable Context context) { + super(context); + } + + @Override + public List getAccountNumbersList() { + List accountNumbersList = new ArrayList<>(); + String query = "SELECT ACCOUNT_NUMBER from ACCOUNT_TABLE"; + SQLiteDatabase db = this.getReadableDatabase(); + Cursor cursor = db.rawQuery(query, null); + + if (cursor.moveToFirst()) { + do { + String accountNumber = cursor.getString(0); + accountNumbersList.add(accountNumber); + } while (cursor.moveToNext()); + } + cursor.close(); + db.close(); + return accountNumbersList; + } + + @Override + public List getAccountsList() { + List accountList = new ArrayList<>(); + String query = "SELECT * from ACCOUNT_TABLE"; + SQLiteDatabase db = this.getReadableDatabase(); + Cursor cursor = db.rawQuery(query, null); + + if (cursor.moveToFirst()) { + do { + String accountNumber = cursor.getString(0); + String bankName = cursor.getString(1); + String accountHolderName = cursor.getString(2); + double balance = cursor.getDouble(3); + Account newAccount = new Account(accountNumber,bankName, accountHolderName, balance); + accountList.add(newAccount); + + } while (cursor.moveToNext()); + } + cursor.close(); + db.close(); + return accountList; + } + + @Override + public Account getAccount(String accountNumber) throws InvalidAccountException { + String query = "SELECT * from ACCOUNT_TABLE WHERE ACCOUNT_NUMBER = '"+ accountNumber + "' ;"; + SQLiteDatabase db = this.getReadableDatabase(); + Cursor cursor = db.rawQuery(query, null); + + if (cursor.moveToFirst()) { + String accountNo = cursor.getString(0); + String bankName = cursor.getString(1); + String accountHolderName = cursor.getString(2); + double balance = cursor.getDouble(3); + Account acc = new Account(accountNo,bankName, accountHolderName, balance); + cursor.close(); + db.close(); + return acc; + } + else { + String msg = "Account number is invalid."; + cursor.close(); + db.close(); + throw new InvalidAccountException(msg); + } + } + + @Override + public boolean addAccount(Account account) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues cv = new ContentValues(); + + cv.put(ACCOUNT_NUMBER, account.getAccountNo()); + cv.put(BANK_NAME, account.getBankName()); + cv.put(ACCOUNT_HOLDER_NAME, account.getAccountHolderName()); + cv.put(BALANCE, account.getBalance()); + + if (db.insert(ACCOUNT_TABLE, null, cv) == -1 ) + return false; + else + return true; + } + + @Override + public void removeAccount(String accountNumber) throws InvalidAccountException { + String query = "DELETE BALANCE from ACCOUNT_TABLE where ACCOUNT_NUMBER= '"+ accountNumber+"' ;"; + SQLiteDatabase db = this.getWritableDatabase(); + db.execSQL(query); + } + + @Override + public void updateBalance(String accountNumber, ExpenseType expenseType, double amount) throws InvalidAccountException { + SQLiteDatabase db = this.getWritableDatabase(); + String query = "select BALANCE from ACCOUNT_TABLE where ACCOUNT_NUMBER = '"+ accountNumber +"' ;"; + Cursor cursor = db.rawQuery(query,null); + + cursor.moveToFirst(); + double balance = cursor.getDouble(0); + switch (expenseType) { + case EXPENSE: + balance -= amount; + break; + case INCOME: + balance += amount; + break; + } + + String query_update = "UPDATE ACCOUNT_TABLE SET BALANCE = "+ balance +" WHERE ACCOUNT_NUMBER = '"+accountNumber+"' ;"; + db.execSQL(query_update); + cursor.close(); + db.close(); + } +} diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/PersistentTransactionDAO.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/PersistentTransactionDAO.java new file mode 100644 index 0000000000..7e22bc4eb4 --- /dev/null +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/data/impl/PersistentTransactionDAO.java @@ -0,0 +1,125 @@ +package lk.ac.mrt.cse.dbs.simpleexpensemanager.data.impl; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.DataBaseManager; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.TransactionDAO; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.model.ExpenseType; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.data.model.Transaction; + +/** + * This is an persistent implementation of TransactionDAO interface. + */ + +public class PersistentTransactionDAO extends DataBaseManager implements TransactionDAO { + + public PersistentTransactionDAO(Context context) { + super(context); + } + + @Override + public boolean logTransaction(Date date, String accountNumber, ExpenseType expenseType, double amount) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues cv = new ContentValues(); + String formattedDate = new SimpleDateFormat("dd-MM-yyyy").format(date); + + cv.put(ACCOUNT_NUMBER, accountNumber); + + cv.put(DATE, formattedDate.toString()); + cv.put(TYPE, expenseType == ExpenseType.EXPENSE ? 0 : 1); + cv.put(AMOUNT, amount); + + if (db.insert(TRANSACTION_TABLE, null, cv) == -1 ) + return false; + else + return true; + } + + @Override + public List getAllTransactionLogs() { + List transactions = new ArrayList<>(); + String queryString = "SELECT * from TRANSACTION_TABLE"; + SQLiteDatabase db = this.getReadableDatabase(); + Cursor cursor = db.rawQuery(queryString, null); + + if (cursor.moveToFirst()) { + do { + try { + Date date =new SimpleDateFormat("dd-MM-yyyy").parse(cursor.getString(1)); + String accountNo = cursor.getString(2); + String type = cursor.getString(3); + ExpenseType expenseType = null; + + if (type.equals("EXPENSE")) { + expenseType = ExpenseType.EXPENSE; + } + + else if (type.equals("INCOME")) { + expenseType = ExpenseType.INCOME; + } + + double amount = cursor.getDouble(4); + Transaction newTransaction = new Transaction(date, accountNo, expenseType, amount); + transactions.add(newTransaction); +// System.out.println(newTransaction); + + } catch (ParseException e) { + e.printStackTrace(); + } + } while (cursor.moveToNext()); + } + + cursor.close(); + db.close(); + return transactions; + } + + @Override + public List getPaginatedTransactionLogs(int limit) { + List transactions = new ArrayList<>(); + String queryString = "SELECT DATE,ACCOUNT_NUMBER,TYPE,AMOUNT from TRANSACTION_TABLE"; + SQLiteDatabase db = this.getReadableDatabase(); + Cursor cursor = db.rawQuery(queryString, null); + + if(cursor.moveToFirst()){ + int i =1; + do { + try { + Date date =new SimpleDateFormat("dd-MM-yyyy").parse(cursor.getString(0)); + String accountNumber = cursor.getString(1); + int type = cursor.getInt(2); + ExpenseType expenseType = null; + + if (type == 0) { + expenseType = ExpenseType.EXPENSE; + } + + else if (type == 1) { + expenseType = ExpenseType.INCOME; + } + + double amount = cursor.getDouble(3); + Transaction newTransaction = new Transaction(date, accountNumber, expenseType, amount); + transactions.add(newTransaction); + + } catch (ParseException e) { + e.printStackTrace(); + } + i++; + + } while (cursor.moveToNext() && i < limit); + } + cursor.close(); + db.close(); + return transactions; + } +} \ No newline at end of file diff --git a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/ui/MainActivity.java b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/ui/MainActivity.java index 46c5f78299..606a083939 100644 --- a/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/ui/MainActivity.java +++ b/app/src/main/java/lk/ac/mrt/cse/dbs/simpleexpensemanager/ui/MainActivity.java @@ -28,6 +28,7 @@ import lk.ac.mrt.cse.dbs.simpleexpensemanager.R; import lk.ac.mrt.cse.dbs.simpleexpensemanager.control.ExpenseManager; import lk.ac.mrt.cse.dbs.simpleexpensemanager.control.InMemoryDemoExpenseManager; +import lk.ac.mrt.cse.dbs.simpleexpensemanager.control.PersistentDemoExpenseManager; public class MainActivity extends AppCompatActivity { private ExpenseManager expenseManager; @@ -65,7 +66,8 @@ protected void onCreate(Bundle savedInstanceState) { tabLayout.setupWithViewPager(mViewPager); /*** Begin generating dummy data for In-Memory implementation ***/ - expenseManager = new InMemoryDemoExpenseManager(); +// expenseManager = new InMemoryDemoExpenseManager(); + expenseManager = new PersistentDemoExpenseManager(MainActivity.this); /*** END ***/ } diff --git a/build.gradle b/build.gradle index fb413901c1..05a611955c 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.2' - classpath 'com.android.tools.build:gradle:4.1.2' + classpath 'com.android.tools.build:gradle:7.1.3' + classpath 'com.android.tools.build:gradle:7.1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f6ab3d486d..f07d5637fb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Jan 31 05:00:39 IST 2021 +#Wed Apr 27 21:17:31 IST 2022 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +zipStoreBase=GRADLE_USER_HOME