From 0fafdd7f057d75b6e661d4784d1f6ba066a64c6e Mon Sep 17 00:00:00 2001 From: Velmurugan Cithaiyan Date: Fri, 7 Feb 2025 06:37:51 +0530 Subject: [PATCH 1/5] General Reports to AMMEX #2138 Added HTML View of General Reports --- app/src/main/AndroidManifest.xml | 14 ++ .../money/manager/ex/home/MainActivity.java | 135 +++++++++++++++++ .../SmsReceiverTransactions.java | 124 ++++++++-------- .../ex/reports/GeneralReportActivity.java | 45 ++++++ .../ex/reports/GeneralReportArrayAdapter.java | 27 ++++ .../ex/reports/GeneralReportFragment.java | 138 ++++++++++++++++++ .../main/res/layout/dialog_general_report.xml | 11 ++ .../res/layout/fragment_general_report.xml | 26 ++++ app/src/main/res/menu-v14/menu_main.xml | 8 + app/src/main/res/menu/menu_main.xml | 8 + app/src/main/res/values-en-rUS/strings.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- 12 files changed, 479 insertions(+), 65 deletions(-) create mode 100644 app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java create mode 100644 app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java create mode 100644 app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java create mode 100644 app/src/main/res/layout/dialog_general_report.xml create mode 100644 app/src/main/res/layout/fragment_general_report.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c6f3064f89..18456823ec 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,6 +19,13 @@ + + + @@ -30,6 +37,10 @@ + + + + @@ -56,6 +67,9 @@ android:theme="@style/Theme.Splash" tools:replace="android:label" android:supportsRtl="true"> + + + diff --git a/app/src/main/java/com/money/manager/ex/home/MainActivity.java b/app/src/main/java/com/money/manager/ex/home/MainActivity.java index 396d0bfdea..d5201529bc 100644 --- a/app/src/main/java/com/money/manager/ex/home/MainActivity.java +++ b/app/src/main/java/com/money/manager/ex/home/MainActivity.java @@ -16,11 +16,16 @@ */ package com.money.manager.ex.home; +import android.annotation.SuppressLint; +import android.app.AlertDialog; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.database.Cursor; +import android.graphics.Color; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; @@ -34,9 +39,11 @@ import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; +import android.widget.AdapterView; import android.widget.ExpandableListView; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; @@ -47,6 +54,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import androidx.preference.PreferenceManager; +import androidx.sqlite.db.SupportSQLiteDatabase; import com.amplitude.android.Amplitude; import com.mikepenz.google_material_typeface_library.GoogleMaterial; @@ -88,6 +96,7 @@ import com.money.manager.ex.notifications.RecurringTransactionProcess; import com.money.manager.ex.scheduled.ScheduledTransactionListFragment; import com.money.manager.ex.reports.CategoriesReportActivity; +import com.money.manager.ex.reports.GeneralReportActivity; import com.money.manager.ex.reports.IncomeVsExpensesActivity; import com.money.manager.ex.reports.PayeesReportActivity; import com.money.manager.ex.search.SearchActivity; @@ -623,6 +632,8 @@ public boolean onDrawerMenuAndOptionMenuSelected(DrawerMenuItem item) { startActivity(new Intent(this, CategoriesReportActivity.class)); } else if (itemId == R.id.menu_settings) { startActivity(new Intent(MainActivity.this, SettingsActivity.class)); + } else if (itemId == R.id.menu_general_report_group) { + showGeneralReportsSelector(item.getText()); } else if (itemId == R.id.menu_report_payees) { startActivity(new Intent(this, PayeesReportActivity.class)); } else if (itemId == R.id.menu_report_where_money_goes) { @@ -887,6 +898,9 @@ private void createExpandableDrawer() { childItems.add(childReports); + // general reports + childItems.add(getGeneralReportGroupDrawerMenuItems()); + // Settings childItems.add(null); @@ -1055,6 +1069,14 @@ private ArrayList getDrawerMenuItems() { .withIconDrawable(uiHelper.getIcon(GoogleMaterial.Icon.gmd_equalizer) .color(iconColor))); // .withDivider(true)); + + // General reports + menuItems.add(new DrawerMenuItem().withId(R.id.menu_general_report_group) + .withText(getString(R.string.menu_general_report_group)) + .withIconDrawable(uiHelper.getIcon(MMXIconFont.Icon.mmx_reports) + .color(iconColor))); + // .withDivider(true)); + // Settings menuItems.add(new DrawerMenuItem().withId(R.id.menu_settings) .withText(getString(R.string.settings)) @@ -1066,6 +1088,7 @@ private ArrayList getDrawerMenuItems() { // .withIconDrawable(uiHelper.getIcon(GoogleMaterial.Icon.gmd_card_giftcard) // .color(iconColor)) // .withDivider(Boolean.TRUE)); + // Help menuItems.add(new DrawerMenuItem().withId(R.id.menu_about) .withText(getString(R.string.about)) @@ -1412,4 +1435,116 @@ private void showSelectDatabaseActivity() { intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } + + private ArrayList getGeneralReportGroupDrawerMenuItems() { + + UIHelper uiHelper = new UIHelper(this); + int iconColor = uiHelper.getSecondaryTextColor(); + ArrayList childReportGroup = new ArrayList<>(); + + // Db setup + MmxOpenHelper MmxHelper = new MmxOpenHelper(this, new AppSettings(this).getDatabaseSettings().getDatabasePath()); + SupportSQLiteDatabase db = MmxHelper.getReadableDatabase(); + + try + { + Cursor groupCursor = db.query("SELECT DISTINCT GROUPNAME FROM REPORT_V1"); + int groupIndex = 0; + + if(groupCursor.moveToFirst()) + { + while(!groupCursor.isAfterLast()){ + groupIndex = groupCursor.getColumnIndex("GROUPNAME"); + childReportGroup.add(new DrawerMenuItem().withId(R.id.menu_general_report_group) + .withText(groupCursor.getString(groupIndex)) + .withIconDrawable(uiHelper.getIcon(MMXIconFont.Icon.mmx_report_page) + .color(iconColor))); + + groupCursor.moveToNext(); + } + } + + groupCursor.close(); + + } + catch(Exception e) + { + //System.err.println("EXCEPTION:"+e); + } + + return childReportGroup; + } + + @SuppressLint("Range") + private void showGeneralReportsSelector(String groupName) { + + //added by velmuruganc + final DrawerMenuItemAdapter adapter = new DrawerMenuItemAdapter(this); + UIHelper uiHelper = new UIHelper(this); + int iconColor = uiHelper.getSecondaryTextColor(); + + // Db setup + MmxOpenHelper MmxHelper = new MmxOpenHelper(this, new AppSettings(this).getDatabaseSettings().getDatabasePath()); + SupportSQLiteDatabase db = MmxHelper.getReadableDatabase(); + + Cursor menuCursor = db.query("SELECT REPORTNAME FROM REPORT_V1 WHERE GROUPNAME = '"+ groupName +"'"); + ArrayList reportName = new ArrayList<>(); + + if(menuCursor.moveToFirst()) + { + while(!menuCursor.isAfterLast()){ + reportName.add(menuCursor.getString(menuCursor.getColumnIndex("REPORTNAME"))); + //custom report for given group + adapter.add(new DrawerMenuItem().withId(R.id.menu_general_report) + .withText(menuCursor.getString(menuCursor.getColumnIndex("REPORTNAME"))) + .withIconDrawable(uiHelper.getIcon(MMXIconFont.Icon.mmx_report_page) + .color(iconColor))); + + menuCursor.moveToNext(); + } + } + + menuCursor.close(); + + //*********** build custom dialog ************ + // Inflate the custom dialog layout + AlertDialog.Builder builder = new AlertDialog.Builder(this); + + // Create a TextView for the title with added space in place of builder.setTitle(groupName) + TextView title = new TextView(this); + title.setText(groupName); + title.setTextSize(20); + title.setPadding(40, 20, 0, 20); // Adds space above and below the title + + builder.setCustomTitle(title); + title.setTypeface(null, Typeface.BOLD); // Makes the title bold + title.setTextColor(Color.BLACK); + + // Inflate the custom layout that contains the ListView + View customView = getLayoutInflater().inflate(R.layout.dialog_general_report, null); + builder.setView(customView); + + // Set up ListView and adapter + ListView listView = customView.findViewById(R.id.listView); + + listView.setAdapter(adapter); + // Create and show the dialog + AlertDialog dialog = builder.create(); + + // Set item click listener for ListView + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //Toast.makeText(getApplicationContext(), "Item clicked: " + reportName.get(position), Toast.LENGTH_SHORT).show(); + + Intent intent = new Intent(MainActivity.this, GeneralReportActivity.class); + intent.putExtra(GeneralReportActivity.GENERAL_REPORT_NAME, reportName.get(position) ); + intent.putExtra(GeneralReportActivity.GENERAL_REPORT_GROUP_NAME, groupName ); + startActivity(intent); + dialog.dismiss(); + } + }); + + dialog.show(); + } } diff --git a/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java b/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java index 0cbe8e71b3..473d4a2d0d 100644 --- a/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java +++ b/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2018 The Android Money Manager Ex Project Team + * Copyright (C) 2012-2025 The Android Money Manager Ex Project Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -23,9 +23,11 @@ package com.money.manager.ex.notifications; +import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.*; +import android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -41,6 +43,7 @@ import androidx.sqlite.db.SupportSQLiteQueryBuilder; import android.telephony.SmsMessage; +import android.util.Log; import android.widget.Toast; import com.money.manager.ex.Constants; @@ -61,6 +64,7 @@ import com.money.manager.ex.transactions.EditTransactionActivityConstants; import com.money.manager.ex.transactions.EditTransactionCommonFunctions; import com.money.manager.ex.utils.MmxDate; +import com.money.manager.ex.utils.MmxDateTimeUtils; import com.squareup.sqlbrite3.BriteDatabase; import javax.inject.Inject; @@ -90,6 +94,7 @@ public class SmsReceiverTransactions extends BroadcastReceiver { public static String CHANNEL_ID = "SmsTransaction_NotificationChannel"; private static final long ID_NOTIFICATION = 0x000A; + @SuppressLint("SimpleDateFormat") @Override public void onReceive(Context context, Intent intent) { mContext = context.getApplicationContext(); @@ -130,13 +135,17 @@ public void onReceive(Context context, Intent intent) { msgBody += msgs[i].getMessageBody(); } - //msgSender = "AT-SIBSMS"; + msgSender = "AT-SIBSMS"; if(isTransactionSms(msgSender)) { // Transaction Sms sender will have format like this AT-SIBSMS, // Promotional sms will have sender like AT-012345 // Not sure how this format will be in out side of India. I may need to update if I get sample + // Db setup + MmxHelper = new MmxOpenHelper(mContext, app_settings.getDatabaseSettings().getDatabasePath()); + db = MmxHelper.getReadableDatabase(); + ITransactionEntity model = AccountTransaction.create(); mCommon = new EditTransactionCommonFunctions(null, model, database); @@ -191,15 +200,11 @@ public void onReceive(Context context, Intent intent) { mCommon.transactionEntity.setStatus(""); mCommon.payeeName = ""; - if (transType != "" && !msgBody.toLowerCase().contains("otp")) { // if not from blank, then nothing to do with sms + if (!transType.isEmpty() && !msgBody.toLowerCase().contains("otp")) { // if not from blank, then nothing to do with sms //Create the intent that’ll fire when the user taps the notification// Intent t_intent = new Intent(mContext, CheckingTransactionEditActivity.class); - // Db setup - MmxHelper = new MmxOpenHelper(mContext, app_settings.getDatabaseSettings().getDatabasePath()); - db = MmxHelper.getReadableDatabase(); - baseCurencyID = gen_settings.getBaseCurrencyId(); baseAccountID = gen_settings.getDefaultAccountId(); baseAccountName = ""; @@ -245,17 +250,20 @@ public void onReceive(Context context, Intent intent) { String transRefNo = extractTransRefNo(msgBody); - //set the ref no. if exists - if(!transRefNo.isEmpty()){ - mCommon.transactionEntity.setTransactionNumber(transRefNo); + //get the ref no. if doesn't exits + if(transRefNo.isEmpty()){ + transRefNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); } + //set the txn no + mCommon.transactionEntity.setTransactionNumber(transRefNo); + long txnId = getTxnId(transRefNo.trim(), mCommon.transactionEntity.getDateString()); //Update existing transaction if (txnId == 0) { //add new trnsaction - if (transType == "Transfer") //if it is transfer + if (transType.equals("Transfer")) //if it is transfer { if (!toAccountDetails[0].isEmpty()) // if id exists then considering as account transfer { @@ -356,7 +364,6 @@ public void onReceive(Context context, Intent intent) { + "Trans Amt = " + fromAccCurrencySymbl + " " + transAmount + ",\n" + "Payyee Name= " + transPayee[1] + "\n" + "Category ID = " + transPayee[2] + "\n" - + "Sub Category ID = " + transPayee[3] + "\n" + "Trans Ref No. = " + transRefNo + "\n" + "Trans Type = " + transType + "\n"; @@ -374,11 +381,14 @@ public void onReceive(Context context, Intent intent) { t_intent.putExtra(EditTransactionActivityConstants.KEY_CATEGORY_ID, String.valueOf(mCommon.transactionEntity.getCategoryId())); t_intent.putExtra(EditTransactionActivityConstants.KEY_TRANS_AMOUNT, String.valueOf(mCommon.transactionEntity.getAmount())); t_intent.putExtra(EditTransactionActivityConstants.KEY_NOTES, mCommon.transactionEntity.getNotes()); - t_intent.putExtra(EditTransactionActivityConstants.KEY_TRANS_DATE, new MmxDate().toDate()); + t_intent.putExtra(EditTransactionActivityConstants.KEY_TRANS_DATE, mCommon.transactionEntity.getDate()); t_intent.putExtra(EditTransactionActivityConstants.KEY_TRANS_NUMBER, mCommon.transactionEntity.getTransactionNumber()); // validate and save the transaction if(!skipSaveTrans) { + + t_intent.addFlags((Intent.FLAG_ACTIVITY_NEW_TASK)); // Fix for https://github.com/moneymanagerex/android-money-manager-ex/issues/2210 + if (validateData()) { if (saveTransaction()) { @@ -446,6 +456,7 @@ public void onReceive(Context context, Intent intent) { } } + @SuppressLint("Range") private static String getCurrencySymbl(long currencyID) { //Get the currency sysmbl @@ -453,15 +464,13 @@ private static String getCurrencySymbl(long currencyID) String[] reqCurrFields = {"CURRENCYID", "DECIMAL_POINT", "GROUP_SEPARATOR", "CURRENCY_SYMBOL"}; String tableName = "CURRENCYFORMATS_V1"; - String[] columns = reqCurrFields; String selection = "CURRENCYID = ?"; String[] selectionArgs = new String[]{String.valueOf(currencyID)}; - String sortOrder = null; SupportSQLiteQueryBuilder queryBuilder = SupportSQLiteQueryBuilder.builder(tableName); SupportSQLiteQuery query = queryBuilder.selection(selection, selectionArgs) - .columns(columns) - .orderBy(sortOrder) + .columns(reqCurrFields) + .orderBy(null) .create(); try { Cursor currencyCursor = db.query(query); @@ -621,7 +630,7 @@ private static String searchForAccountNum(String smsMsg, long mIndx) // - ((\s)using\scard\s(.*?)\s.emaining) added for LBP currency. Request from HussienH String[] searchFor = { - "((\\s)?((\\d+)?[X]+(\\d+))(\\s)?)", "((\\s)?((\\d+)?[x]+(\\d+))(\\s)?)", "((\\s)?((\\d+)?[\\*]+(\\d+))(\\s)?)", + "((\\s)?((\\d+)?[Xx\\*]+(\\d+))(\\s)?)", "(no\\.(.*?)\\sis)", "(for\\s(.*?)\\son)", "((\\s)?Account\\s?No(.*?)\\s?(\\d+)(\\s)?)", "((\\s)?A/.\\s?No(.*?)\\s?(\\d+)(\\s)?)", "[N-n][O-o](.)?(:)?(\\s)?'(.*?)'", "((\\s)using\\scard\\s(.*?)\\s.emaining)", "([\\(]((.*?)[@](.*?))[\\)])", "(from((.*?)@(.*?))[.])", "(linked((.*?)@(.*?))[.])", @@ -631,7 +640,7 @@ private static String searchForAccountNum(String smsMsg, long mIndx) int[] getGroup = { - 5, 5, 5, + 5, 2, 2, 4, 4, 4, 3, 2, 2, 2, @@ -731,14 +740,16 @@ private static String[] extractTransPayee(String smsMsg) { // - ((\s)at\s(.*?)\s+using) added for LBP currency. Request from HussienH String[] searchFor = { - "((\\s)at\\s(.*?)\\s+on)", "((\\s)favoring\\s(.*?)\\s+is)", + "((\\s)at\\s(.*?)\\s+(?:on|for))", "((\\s)favoring\\s(.*?)\\s+is)", "((\\s)to\\s(.*?)\\s+at)", "((\\s)to\\s(.*?)[.])", "((\\s)at\\s(.*?)[.])", "([\\*](.*?)[.])", "((\\s)FROM\\s(.*?)\\s+\\d)", "(from\\s(.*?)\\s(\\())", "(([a-zA-Z]+)(\\s)has(\\s)added)", "((\\s)paid\\s(.*?)\\s)", - "((\\s)at\\s(.*?)\\s+using)" }; + "((\\s)at\\s(.*?)\\s+using)", "(-(.*?)\\son\\s(.*?)[.])", "((\\d+)/(.*)/)", + "((\\d)\\s(?:from|FROM)\\s((.*?)\\s(.*?))(\\.))", "(\\d,(.*)(\\s)credited)", + "((?:at|on)\\s([a-zA-Z]((.*?)(\\w+)))\\.)", "(\\son(.*?)\\*(.*?)\\.)"}; - int[] getGroup = {3, 3, 3, 3, 3, 2, 3, 2, 2, 3, 3}; + int[] getGroup = {3, 3, 3, 3, 3, 2, 3, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3}; String[] reqMatch = new String[]{"", "", "", ""}; try @@ -772,14 +783,17 @@ private static String[] extractTransPayee(String smsMsg) private static String extractTransRefNo(String smsMsg) { String reqMatch = ""; - String[] searchFor = {"(Cheque\\sNo[.*?](\\d+))", "(Ref\\sno(:)?\\s(\\d+))", "(\\s(\\d+(.*?)\\d+)TXN\\s)", + String[] searchFor = {"(Cheque\\sNo[.*?](\\d+))", "(Ref\\s[Nn]o([.:])?\\s(\\d+))", "(\\s(\\d+(.*?)\\d+)TXN\\s)", "(I[D//d](.)?(:)?(\\s)?((.*?)\\w+))", "(I[D//d](.)?(:)?)(\\s)?(\\d+)", "(id(\\s)is(\\s)?(:)?(\\d+))", "((Reference:)(\\s)?(\\d+))", "([\\*](\\d+)[\\*])", "(Info(:)+(.*?)(\\d+)[:]?[-]?)", - "((reference number)(.*?)(\\d+))", "(\\s)?#(\\s?)(\\d+)(\\s?)", "(\\/+(\\d+)+\\/)"}; + "((reference number)(.*?)(\\d+))", "(\\s)?#(\\s?)(\\d+)(\\s?)", "(\\/+(\\d+)+\\/)", + "((?:UPI|IMPS)\\s?:\\s?(\\d+)\\s?)", "([\\*](.*?)(\\d+)\\s?)", "(I[Dd]\\s?([.:])\\s?((.*?)(\\d+))\\s)"}; + int[] getGroup = {2, 3, 2, 5, 5, 5, 4, 2, 4, - 4, 3, 2}; + 4, 3, 2, + 2, 3, 3}; try { @@ -806,16 +820,16 @@ private static String extractTransRefNo(String smsMsg) return reqMatch; } + @SuppressLint("Range") private static String[] getPayeeDetails(String payeeName) { - String[] payeeDetails = new String[]{"", payeeName.trim(), "", ""}; + String[] payeeDetails = new String[]{"", payeeName.trim(), ""}; try { if(!payeeName.trim().isEmpty()) { - String sql = "SELECT PAYEEID, PAYEENAME, CATEGID, SUBCATEGID " + - "FROM PAYEE_V1 " + + String sql = "SELECT PAYEEID, PAYEENAME, CATEGID FROM PAYEE_V1 " + "WHERE PAYEENAME LIKE '%" + payeeName + "%' " + "ORDER BY PAYEENAME LIMIT 1"; @@ -826,8 +840,7 @@ private static String[] getPayeeDetails(String payeeName) payeeDetails = new String[] { payeeCursor.getString(payeeCursor.getColumnIndex("PAYEEID")), payeeCursor.getString(payeeCursor.getColumnIndex("PAYEENAME")), - payeeCursor.getString(payeeCursor.getColumnIndex("CATEGID")), - payeeCursor.getString(payeeCursor.getColumnIndex("SUBCATEGID")) + payeeCursor.getString(payeeCursor.getColumnIndex("CATEGID")) }; } @@ -842,6 +855,7 @@ private static String[] getPayeeDetails(String payeeName) return payeeDetails; } + @SuppressLint("Range") private static Long getTxnId(String refNumber, String transDate) { long txnId = 0; @@ -875,6 +889,7 @@ private static Long getTxnId(String refNumber, String transDate) return txnId; } + @SuppressLint("Range") private static String[] getCategoryOrSubCategoryByName(String searchName) { String[] cTran = new String[]{"", ""}; @@ -884,37 +899,19 @@ private static String[] getCategoryOrSubCategoryByName(String searchName) if(!searchName.trim().isEmpty()) { String sql = - "SELECT c.CATEGID, c.CATEGNAME, s.SUBCATEGID, s.SUBCATEGNAME " + - "FROM CATEGORY_V1 c " + - "INNER JOIN SUBCATEGORY_V1 s ON s.CATEGID=c.CATEGID " + - "WHERE s.SUBCATEGNAME = '" + searchName + "' " + - "ORDER BY s.SUBCATEGID LIMIT 1"; + "SELECT CATEGID, CATEGNAME, PARENTID FROM CATEGORY_V1 " + + "WHERE CATEGNAME = '" + searchName + "' " + + "ORDER BY PARENTID desc, CATEGNAME asc LIMIT 1"; + //Log.d("SQL", sql); Cursor cCursor = db.query(sql); if(cCursor.moveToFirst()) { cTran = new String[]{ cCursor.getString(cCursor.getColumnIndex("CATEGID")), - cCursor.getString(cCursor.getColumnIndex("SUBCATEGID")) + cCursor.getString(cCursor.getColumnIndex("PARENTID")) }; - } else{ //search in only catogery - - sql = - "SELECT c.CATEGID, c.CATEGNAME " + - "FROM CATEGORY_V1 c " + - "WHERE c.CATEGNAME = '" + searchName + "' " + - "ORDER BY c.CATEGID LIMIT 1"; - - cCursor = db.query(sql); - - if(cCursor.moveToFirst()) - { - cTran = new String[]{ - cCursor.getString(cCursor.getColumnIndex("CATEGID")), - "-1" - }; - } } cCursor.close(); @@ -928,6 +925,7 @@ private static String[] getCategoryOrSubCategoryByName(String searchName) return cTran; } + @SuppressLint("Range") private static void getAccountDetails(String[] reqMatch) { String[] accountDetails = new String[]{"", "", "", "", "", "", ""}; @@ -986,16 +984,13 @@ private static void getAccountDetails(String[] reqMatch) public boolean validateData() { - boolean isTransfer = mCommon.transactionEntity.getTransactionType().equals(TransactionTypes.Transfer); - Core core = new Core(mContext); - - if (mCommon.transactionEntity.getAccountId() == Constants.NOT_SET) { + if (mCommon.transactionEntity.getAccountId().equals(Constants.NOT_SET)) { //Toast.makeText(mContext, "MMEX : " + (R.string.error_toaccount_not_selected), Toast.LENGTH_LONG).show(); return false; } - if (isTransfer) { - if (mCommon.transactionEntity.getAccountToId() == Constants.NOT_SET) { + if (mCommon.transactionEntity.getTransactionType().equals(TransactionTypes.Transfer)) { + if (mCommon.transactionEntity.getAccountToId().equals(Constants.NOT_SET)) { //Toast.makeText(mContext, "MMEX : " + (R.string.error_toaccount_not_selected), Toast.LENGTH_LONG).show(); return false; } @@ -1026,9 +1021,12 @@ public boolean validateData() { } // Category is required if tx is not a split or transfer. - boolean hasCategory = mCommon.transactionEntity.hasCategory(); - //Toast.makeText(mContext, "MMEX : " + (R.string.error_category_not_selected), Toast.LENGTH_LONG).show(); - return hasCategory || isTransfer; + if (!mCommon.transactionEntity.hasCategory()) { + //Toast.makeText(mContext, "MMEX : " + (R.string.error_category_not_selected), Toast.LENGTH_LONG).show(); + return false; + } + + return true; } public boolean saveTransaction() { @@ -1069,7 +1067,7 @@ private void showNotification(Intent intent, String notificationText, String msg String GROUP_KEY_AMMEX = "com.android.example.MoneyManagerEx"; int ID_NOTIFICATION = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE); - PendingIntent pendingIntent = PendingIntent.getActivity(mContext, ID_NOTIFICATION, intent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent pendingIntent = PendingIntent.getActivity(mContext, ID_NOTIFICATION, intent, PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE); NotificationManager notificationManager = (NotificationManager) mContext .getSystemService(Context.NOTIFICATION_SERVICE); diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java new file mode 100644 index 0000000000..c03b4749cb --- /dev/null +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java @@ -0,0 +1,45 @@ +package com.money.manager.ex.reports; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import androidx.appcompat.widget.Toolbar; +import com.money.manager.ex.R; +import com.money.manager.ex.common.MmxBaseFragmentActivity; +import android.text.TextUtils; +import android.view.KeyEvent; +import android.webkit.WebView; + +public class GeneralReportActivity extends MmxBaseFragmentActivity { + private WebView mWebView; + public static final String GENERAL_REPORT_NAME = "GeneralReportActivity:ReportName"; + public static final String GENERAL_REPORT_GROUP_NAME = "GeneralReportActivity:GroupName"; + public static String currentReportName = ""; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.fragment_general_report); + + if (getIntent() != null) { + if (!TextUtils.isEmpty(getIntent().getStringExtra(GENERAL_REPORT_NAME))) { + currentReportName = getIntent().getStringExtra(GENERAL_REPORT_NAME); + } + } + + Toolbar toolbar = findViewById(R.id.toolbar); + + if (toolbar != null) { + setSupportActionBar(toolbar); + // set actionbar + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setTitle(currentReportName); + } + + GeneralReportFragment fragment = new GeneralReportFragment(); + getSupportFragmentManager().beginTransaction() + .add(R.id.GeneralReportFragment, fragment, GeneralReportFragment.class.getSimpleName()) + .commit(); + + } + +} diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java new file mode 100644 index 0000000000..ec41bb8b60 --- /dev/null +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java @@ -0,0 +1,27 @@ +package com.money.manager.ex.reports; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; + +import java.util.List; + +public class GeneralReportArrayAdapter extends ArrayAdapter { + private Context context; + private List items; + + public GeneralReportArrayAdapter(Context context, List items) { + super(context, android.R.layout.simple_list_item_1, items); // Using default simple item layout + this.context = context; + this.items = items; + } + + // You can override getView if you want to customize the item layout further + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View view = super.getView(position, convertView, parent); + // Customize view if needed (e.g., add icons, change text color, etc.) + return view; + } +} diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java new file mode 100644 index 0000000000..8791b61e37 --- /dev/null +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java @@ -0,0 +1,138 @@ +package com.money.manager.ex.reports; + +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebSettings; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.Toast; + +import androidx.sqlite.db.SupportSQLiteDatabase; + +import com.money.manager.ex.R; +import com.money.manager.ex.common.MmxBaseFragmentActivity; +import com.money.manager.ex.database.MmxOpenHelper; +import com.money.manager.ex.settings.AppSettings; +import com.squareup.sqlbrite3.BriteDatabase; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentTransaction; + + +public class GeneralReportFragment extends Fragment { + + public GeneralReportFragment() { + + } + + public View onCreateView(LayoutInflater inflater, ViewGroup group, + Bundle saved) { + return inflater.inflate(R.layout.fragment_general_report, group, false); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + WebView webView = (WebView) getActivity().findViewById(R.id.GeneralReportWebView); + String htmlContent = getHtmlReport(GeneralReportActivity.currentReportName); + + webView.setWebViewClient(new WebViewClient()); + webView.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null); + //Log.d("TAG-htmlReport", htmlContent); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + getActivity().finish(); + } + + return super.onOptionsItemSelected(item); + } + + private String getHtmlReport(String reportName){ + + //Db setup + MmxOpenHelper MmxHelper = new MmxOpenHelper(getActivity(), new AppSettings(getActivity()).getDatabaseSettings().getDatabasePath()); + SupportSQLiteDatabase mDatabase = MmxHelper.getReadableDatabase(); + + String sqlQuery = "ss"; + String htmlTable = ""; + + try + { + if(!reportName.trim().isEmpty()) { + + String sql = "SELECT SQLCONTENT FROM REPORT_V1 " + + "WHERE REPORTNAME = '" + reportName + "' " + + "ORDER BY REPORTNAME LIMIT 1"; + + Cursor sqlCursor = mDatabase.query(sql, null); + + if(sqlCursor.moveToFirst()) + { + sqlQuery = sqlCursor.getString(sqlCursor.getColumnIndex("SQLCONTENT")); + } + + sqlCursor.close(); + } + + // fetch the data and generate the html table + Cursor sqlCursor = mDatabase.query(sqlQuery, null); + + htmlTable = htmlTable + ""; + + //get the clmns + for (int i = 0; i < sqlCursor.getColumnCount(); i++) + { + htmlTable = htmlTable + ""; + } + + htmlTable = htmlTable + ""; + + //get the data + for (sqlCursor.moveToFirst(); !sqlCursor.isAfterLast(); sqlCursor.moveToNext()) + { + htmlTable = htmlTable + ""; + + for (int i = 0; i < sqlCursor.getColumnCount(); i++) + { + htmlTable = htmlTable + ""; + } + + htmlTable = htmlTable + ""; + } + + htmlTable = htmlTable + "
" + sqlCursor.getColumnName(i) + "
" + + sqlCursor.getString(sqlCursor.getColumnIndex(sqlCursor.getColumnName(i))) + + "
"; + + sqlCursor.close(); + mDatabase.close(); + } + catch(Exception e) + { + //System.err.println("EXCEPTION:"+e); + } + + return htmlTable; + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_general_report.xml b/app/src/main/res/layout/dialog_general_report.xml new file mode 100644 index 0000000000..7ba57b871f --- /dev/null +++ b/app/src/main/res/layout/dialog_general_report.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_general_report.xml b/app/src/main/res/layout/fragment_general_report.xml new file mode 100644 index 0000000000..49d218e664 --- /dev/null +++ b/app/src/main/res/layout/fragment_general_report.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/menu-v14/menu_main.xml b/app/src/main/res/menu-v14/menu_main.xml index 988133fefd..bd69101410 100644 --- a/app/src/main/res/menu-v14/menu_main.xml +++ b/app/src/main/res/menu-v14/menu_main.xml @@ -129,6 +129,14 @@ android:title="@string/menu_report_cashflow"/> + + + + Difference
Month Year - Reports + Build-in Reports --> + General Reports + General Report Income Vs Expenses Total diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a1f58b2b48..630a46e6cb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -318,7 +318,9 @@ No stock data available for this account. Month Year - Reports + Build-in Reports --> + General Reports + General Report Income Vs Expenses Cash Flow Total From b736ca4d0ed4c04bceb9402e67ab80f3722999e2 Mon Sep 17 00:00:00 2001 From: Velmurugan Cithaiyan Date: Fri, 7 Feb 2025 06:38:05 +0530 Subject: [PATCH 2/5] Update MainActivity.java --- app/src/main/java/com/money/manager/ex/home/MainActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/money/manager/ex/home/MainActivity.java b/app/src/main/java/com/money/manager/ex/home/MainActivity.java index d5201529bc..0ba5d47c27 100644 --- a/app/src/main/java/com/money/manager/ex/home/MainActivity.java +++ b/app/src/main/java/com/money/manager/ex/home/MainActivity.java @@ -63,6 +63,7 @@ import com.money.manager.ex.HelpActivity; import com.money.manager.ex.MmexApplication; import com.money.manager.ex.reports.CashFlowReportActivity; +import com.money.manager.ex.database.MmxOpenHelper; import com.money.manager.ex.tag.TagListFragment; import com.money.manager.ex.nestedcategory.NestedCategoryListFragment; import com.money.manager.ex.passcode.PasscodeActivity; From 16865bb983490693ddfa0ad4acf74de18de9529d Mon Sep 17 00:00:00 2001 From: Velmurugan Cithaiyan Date: Fri, 7 Feb 2025 08:47:57 +0530 Subject: [PATCH 3/5] Made few corrections as per Codacy Static Code Analysis Made few corrections as per Codacy Static Code Analysis --- .../money/manager/ex/reports/GeneralReportActivity.java | 9 +++------ .../manager/ex/reports/GeneralReportArrayAdapter.java | 1 - .../money/manager/ex/reports/GeneralReportFragment.java | 4 ---- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java index c03b4749cb..9d161bed3c 100644 --- a/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java @@ -1,12 +1,10 @@ package com.money.manager.ex.reports; -import android.annotation.SuppressLint; import android.os.Bundle; import androidx.appcompat.widget.Toolbar; import com.money.manager.ex.R; import com.money.manager.ex.common.MmxBaseFragmentActivity; import android.text.TextUtils; -import android.view.KeyEvent; import android.webkit.WebView; public class GeneralReportActivity extends MmxBaseFragmentActivity { @@ -17,13 +15,12 @@ public class GeneralReportActivity extends MmxBaseFragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); setContentView(R.layout.fragment_general_report); - if (getIntent() != null) { - if (!TextUtils.isEmpty(getIntent().getStringExtra(GENERAL_REPORT_NAME))) { - currentReportName = getIntent().getStringExtra(GENERAL_REPORT_NAME); - } + if (getIntent() != null && !TextUtils.isEmpty(getIntent().getStringExtra(GENERAL_REPORT_NAME)) ) { + currentReportName = getIntent().getStringExtra(GENERAL_REPORT_NAME); } Toolbar toolbar = findViewById(R.id.toolbar); diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java index ec41bb8b60..ed2477098d 100644 --- a/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java @@ -10,7 +10,6 @@ public class GeneralReportArrayAdapter extends ArrayAdapter { private Context context; private List items; - public GeneralReportArrayAdapter(Context context, List items) { super(context, android.R.layout.simple_list_item_1, items); // Using default simple item layout this.context = context; diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java index 8791b61e37..2cfaf4ecac 100644 --- a/app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportFragment.java @@ -32,10 +32,6 @@ public class GeneralReportFragment extends Fragment { - public GeneralReportFragment() { - - } - public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) { return inflater.inflate(R.layout.fragment_general_report, group, false); From b23df80c21bbe144f1bd0c4c800914df0d1f8eb1 Mon Sep 17 00:00:00 2001 From: Velmurugan Cithaiyan Date: Sat, 8 Feb 2025 06:52:38 +0530 Subject: [PATCH 4/5] added fix for issue found by Codacy Static Code Analysis added fix for issue found by Codacy Static Code Analysis --- .../money/manager/ex/reports/GeneralReportActivity.java | 3 +-- .../manager/ex/reports/GeneralReportArrayAdapter.java | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java index 9d161bed3c..7648ffba20 100644 --- a/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportActivity.java @@ -5,10 +5,9 @@ import com.money.manager.ex.R; import com.money.manager.ex.common.MmxBaseFragmentActivity; import android.text.TextUtils; -import android.webkit.WebView; public class GeneralReportActivity extends MmxBaseFragmentActivity { - private WebView mWebView; + public static final String GENERAL_REPORT_NAME = "GeneralReportActivity:ReportName"; public static final String GENERAL_REPORT_GROUP_NAME = "GeneralReportActivity:GroupName"; public static String currentReportName = ""; diff --git a/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java b/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java index ed2477098d..6a9d69be19 100644 --- a/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java +++ b/app/src/main/java/com/money/manager/ex/reports/GeneralReportArrayAdapter.java @@ -8,12 +8,10 @@ import java.util.List; public class GeneralReportArrayAdapter extends ArrayAdapter { - private Context context; - private List items; + public GeneralReportArrayAdapter(Context context, List items) { - super(context, android.R.layout.simple_list_item_1, items); // Using default simple item layout - this.context = context; - this.items = items; + // Using default simple item layout + super(context, android.R.layout.simple_list_item_1, items); } // You can override getView if you want to customize the item layout further From 1945d4677e973eaa2b4bc9050830e95f0a4286df Mon Sep 17 00:00:00 2001 From: Gong Guan Date: Sat, 8 Feb 2025 15:00:12 +0800 Subject: [PATCH 5/5] directly returning the result of mCommon.transactionEntity.hasCategory() --- .../manager/ex/notifications/SmsReceiverTransactions.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java b/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java index 473d4a2d0d..8787dbd101 100644 --- a/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java +++ b/app/src/main/java/com/money/manager/ex/notifications/SmsReceiverTransactions.java @@ -1021,12 +1021,7 @@ public boolean validateData() { } // Category is required if tx is not a split or transfer. - if (!mCommon.transactionEntity.hasCategory()) { - //Toast.makeText(mContext, "MMEX : " + (R.string.error_category_not_selected), Toast.LENGTH_LONG).show(); - return false; - } - - return true; + return mCommon.transactionEntity.hasCategory(); } public boolean saveTransaction() {